diff --git a/.gitignore b/.gitignore index b07cfee88..e8642c1dc 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ src/zcash-cli src/zcash-gtest src/zcash-tx src/test/test_bitcoin +src/BitcoinZWallet.jar *zcashTest.pk *zcashTest.vk diff --git a/Makefile.am b/Makefile.am index 22755f2e2..a5040733c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,10 @@ +# Copyright (c) 2017-2020 The BitcoinZ community +# Copyright (c) 2016-2019 The Zcash developers +# Copyright (c) 2013-2019 The Bitcoin Core developers +# Copyright (c) 2013-2019 Bitcoin Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + ACLOCAL_AMFLAGS = -I build-aux/m4 SUBDIRS = src if ENABLE_MAN diff --git a/README.md b/README.md index 205973650..375da8198 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# BitcoinZ +# BitcoinZ 2.0.7 **Keep running wallet to strengthen the BitcoinZ network. Backup your wallet in many locations & keep your coins wallet offline.** ### Ports: diff --git a/autogen.sh b/autogen.sh index 3e26a1830..77dac7475 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,4 +1,11 @@ #!/bin/sh +# Copyright (c) 2017-2020 The BitcoinZ community +# Copyright (c) 2016-2019 The Zcash developers +# Copyright (c) 2013-2019 The Bitcoin Core developers +# Copyright (c) 2013-2019 Bitcoin Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + set -e srcdir="$(dirname $0)" cd "$srcdir" diff --git a/build-aux/m4/l_atomic.m4 b/build-aux/m4/l_atomic.m4 index 906724b64..e7a3d2fc4 100644 --- a/build-aux/m4/l_atomic.m4 +++ b/build-aux/m4/l_atomic.m4 @@ -1,3 +1,9 @@ +dnl Copyright (c) 2015 Tim Kosse +dnl Copying and distribution of this file, with or without modification, are +dnl permitted in any medium without royalty provided the copyright notice +dnl and this notice are preserved. This file is offered as-is, without any +dnl warranty + # Some versions of gcc/libstdc++ require linking with -latomic if # using the C++ atomic library. # @@ -32,7 +38,7 @@ AC_DEFUN([CHECK_ATOMIC], [ AC_MSG_RESULT([yes]) ],[ AC_MSG_RESULT([no]) - AC_MSG_FAILURE([cannot figure our how to use std::atomic]) + AC_MSG_FAILURE([cannot figure out how to use std::atomic]) ]) ]) diff --git a/configure.ac b/configure.ac index 53d85ce17..4b40a35cc 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 2) define(_CLIENT_VERSION_MINOR, 0) -define(_CLIENT_VERSION_REVISION, 6) +define(_CLIENT_VERSION_REVISION, 7) define(_CLIENT_VERSION_BUILD, 50) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) diff --git a/contrib/amqp/amqp_sub.py b/contrib/amqp/amqp_sub.py index bc51e8428..8218b0aba 100644 --- a/contrib/amqp/amqp_sub.py +++ b/contrib/amqp/amqp_sub.py @@ -1,7 +1,8 @@ #!/usr/bin/env python2 -# Copyright (c) 2017 The Zcash developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# Copyright (c) 2017-2020 The BitcoinZ Community +# Copyright (c) 2017-2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # file COPYING or https://www.opensource.org/licenses/mit-license.php . # Requirements: # pip install python-qpid-proton @@ -45,4 +46,3 @@ def on_message(self, event): Container(Server("127.0.0.1:%i" % port)).run() except KeyboardInterrupt: pass - diff --git a/contrib/bitcoinz-cli.bash-completion b/contrib/bitcoinz-cli.bash-completion index 521f81191..f1ce244ad 100644 --- a/contrib/bitcoinz-cli.bash-completion +++ b/contrib/bitcoinz-cli.bash-completion @@ -1,9 +1,9 @@ # bash programmable completion for bitcoinz-cli(1) -# Copyright (c) 2017-2018 The BitcoinZ Community -# Copyright (c) 2016-2017 The Zcash developers +# Copyright (c) 2017-2020 The BitcoinZ community +# Copyright (c) 2016-2019 The Zcash developers # Copyright (c) 2012-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # call $bitcoinz-cli for RPC _bitcoinz_rpc() { diff --git a/contrib/bitcoinz-tx.bash-completion b/contrib/bitcoinz-tx.bash-completion index fb030c2c8..20160be62 100644 --- a/contrib/bitcoinz-tx.bash-completion +++ b/contrib/bitcoinz-tx.bash-completion @@ -1,9 +1,9 @@ # bash programmable completion for bitcoinz-tx(1) # Copyright (c) 2017-2018 The BitcoinZ Community -# Copyright (c) 2016-2017 The Zcash developers +# Copyright (c) 2016-2019 The Zcash developers # Copyright (c) 2012-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . _bitcoinz_tx() { local cur prev words=() cword diff --git a/contrib/bitcoinzd.bash-completion b/contrib/bitcoinzd.bash-completion index 64b320d55..229b9059e 100644 --- a/contrib/bitcoinzd.bash-completion +++ b/contrib/bitcoinzd.bash-completion @@ -1,9 +1,9 @@ # bash programmable completion for bitcoinzd(1) -# Copyright (c) 2017-2018 The BitcoinZ Community -# Copyright (c) 2016-2017 The Zcash developers +# Copyright (c) 2017-2020 The BitcoinZ community +# Copyright (c) 2016-2019 The Zcash developers # Copyright (c) 2012-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . _bitcoinzd() { local cur prev words=() cword diff --git a/contrib/debian/changelog b/contrib/debian/changelog index 5f2f494fb..6f01b38ce 100644 --- a/contrib/debian/changelog +++ b/contrib/debian/changelog @@ -1,3 +1,15 @@ +bitcoinz (2.0.7) stable; urgency=high + + * 2.0.7 release. + + -- The BitcoinZ Community Nov 2020 + +bitcoinz (2.0.6) stable; urgency=high + + * 2.0.6 release. + + -- The BitcoinZ Community Mar 2020 + bitcoinz (2.0.5) stable; urgency=high * 2.0.5 release. diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 3983e73ec..d381d0092 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -1,7 +1,7 @@ #!/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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . ''' A script to check that the (Linux) executables produced by gitian only contain allowed gcc, glibc and libstdc++ version symbols. This makes sure they are diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 157a3c9d6..61fd58fb6 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,9 +1,10 @@ --- -name: "bitcoinz-2.0.6" +name: "bitcoinz-2.0.7" enable_cache: true distro: "debian" suites: - "jessie" +- "stretch" architectures: - "amd64" packages: diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py index 8badb4b31..7bc7eb023 100755 --- a/contrib/linearize/linearize-data.py +++ b/contrib/linearize/linearize-data.py @@ -4,7 +4,7 @@ # # Copyright (c) 2013-2014 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # from __future__ import print_function, division diff --git a/contrib/linearize/linearize-hashes.py b/contrib/linearize/linearize-hashes.py index 7e9cf8898..68da06188 100755 --- a/contrib/linearize/linearize-hashes.py +++ b/contrib/linearize/linearize-hashes.py @@ -4,7 +4,7 @@ # # Copyright (c) 2013-2014 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # from __future__ import print_function diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index b0506bba3..9ab6c3a4f 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -1,7 +1,7 @@ #!/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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . ''' Script to generate list of seed nodes for chainparams.cpp. diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index 10ff907fb..6df3e0838 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -1,7 +1,7 @@ #!/usr/bin/env python2 # Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import array import binascii diff --git a/depends/Makefile b/depends/Makefile index 5c1fb9fdd..aa07755f0 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -4,7 +4,7 @@ SOURCES_PATH ?= $(BASEDIR)/sources BASE_CACHE ?= $(BASEDIR)/built SDK_PATH ?= $(BASEDIR)/SDKs NO_WALLET ?= -PRIORITY_DOWNLOAD_PATH ?= https://z.cash/depends-sources +PRIORITY_DOWNLOAD_PATH ?= https://download.z.cash/depends-sources BUILD ?= $(shell ./config.guess) HOST ?= $(BUILD) diff --git a/doc/init.md b/doc/init.md index fba4b5411..794b827d0 100644 --- a/doc/init.md +++ b/doc/init.md @@ -1,4 +1,4 @@ -*** Warning: This document has not been updated for Zcash and may be inaccurate. *** +*** Warning: This document has not been updated for BitcoinZ and may be inaccurate. *** Sample init scripts and service configuration for bitcoind ========================================================== @@ -99,4 +99,3 @@ setting the BITCOIND and FLAGS environment variables in the file Auto respawning is currently only configured for Upstart and systemd. Reasonable defaults have been chosen but YMMV. - diff --git a/doc/man/bitcoinz-cli.1 b/doc/man/bitcoinz-cli.1 index 4682b9fd6..03cb4f4cd 100644 --- a/doc/man/bitcoinz-cli.1 +++ b/doc/man/bitcoinz-cli.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6. -.TH BITCOINZ-CLI "1" "May 2019" "bitcoinz-cli v2.0.5" "User Commands" +.TH BITCOINZ-CLI "1" "May 2019" "bitcoinz-cli v2.0.7" "User Commands" .SH NAME -bitcoinz-cli \- manual page for bitcoinz-cli v2.0.5 +bitcoinz-cli \- manual page for bitcoinz-cli v2.0.7 .SH DESCRIPTION -BitcoinZ RPC client version v2.0.5 +BitcoinZ RPC client version v2.0.7 .PP In order to ensure you are adequately protecting your privacy when using BitcoinZ, please see . @@ -82,7 +82,7 @@ Copyright (C) 2017-2019 The BitcoinZ Community This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or . +or . This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written diff --git a/doc/man/bitcoinz-tx.1 b/doc/man/bitcoinz-tx.1 index c1f5c0b16..4321da3a2 100644 --- a/doc/man/bitcoinz-tx.1 +++ b/doc/man/bitcoinz-tx.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6. -.TH BITCOINZ-TX "1" "May 2019" "bitcoinz-tx v2.0.5" "User Commands" +.TH BITCOINZ-TX "1" "May 2019" "bitcoinz-tx v2.0.7" "User Commands" .SH NAME -bitcoinz-tx \- manual page for bitcoinz-tx v2.0.5 +bitcoinz-tx \- manual page for bitcoinz-tx v2.0.7 .SH DESCRIPTION -BitcoinZ bitcoinz\-tx utility version v2.0.5 +BitcoinZ bitcoinz\-tx utility version v2.0.7 .SS "Usage:" .TP bitcoinz\-tx [options] [commands] @@ -95,7 +95,7 @@ Copyright (C) 2017-2019 The BitcoinZ Community This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or . +or . This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written diff --git a/doc/man/bitcoinzd.1 b/doc/man/bitcoinzd.1 index 98e144dc0..2a39e0506 100644 --- a/doc/man/bitcoinzd.1 +++ b/doc/man/bitcoinzd.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6. -.TH BITCOINZD "1" "May 2019" "bitcoinzd v2.0.5" "User Commands" +.TH BITCOINZD "1" "May 2019" "bitcoinzd v2.0.7" "User Commands" .SH NAME -bitcoinzd \- manual page for bitcoinzd v2.0.5 +bitcoinzd \- manual page for bitcoinzd v2.0.7 .SH DESCRIPTION -BitcoinZ Daemon version v2.0.5 +BitcoinZ Daemon version v2.0.7 .PP In order to ensure you are adequately protecting your privacy when using BitcoinZ, please see . @@ -495,7 +495,7 @@ Copyright (C) 2017-2019 The BitcoinZ Community This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or . +or . This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written diff --git a/doc/release-notes/release-notes-2.0.7.md b/doc/release-notes/release-notes-2.0.7.md new file mode 100644 index 000000000..08e20c285 --- /dev/null +++ b/doc/release-notes/release-notes-2.0.7.md @@ -0,0 +1,504 @@ +Notable changes +=============== + + +This release fixes a security issue described at +https://z.cash/support/security/announcements/security-announcement-2019-09-24/ . + +The service period of this release is shorter than normal due to the upcoming +v2.1.0 Blossom release. The End-of-Service of v2.0.7 will occur at block height +775000, expected to be on mid AUG-2020. + + +Debian Stretch is now a Supported Platform +------------------------------------------ + +We now provide reproducible builds for Stretch as well as for Jessie. + + +Fixed a bug in ``z_mergetoaddress`` +----------------------------------- + +We fixed a bug which prevented users sending from ``ANY_SPROUT`` or ``ANY_SAPLING`` +with ``z_mergetoaddress`` when a wallet contained both Sprout and Sapling notes. + + +Insight Explorer +---------------- + +We have been incorporating changes to support the Insight explorer directly from +``bitcoinzd``. v2.0.6 includes the first change to an RPC method. If ``bitcoinzd`` is +run with the flag ``--insightexplorer``` (this requires an index rebuild), the +RPC method ``getrawtransaction`` will now return additional information about +spend indices. + + +Shorter Block Times +------------------- + +Shorter block times are coming to BitcoinZ! In the v2.0.7 release we have implemented [ZIP208](https://github.com/zcash/zips/blob/master/zip-0208.rst) which will take effect when Blossom activates. Upon activation, the block times for BitcoinZ will decrease from 150 seconds to 75 seconds, and the block reward will decrease accordingly. This affects at what block height halving events will occur, but should not affect the overall rate at which BitcoinZ is mined. The total Community' reward stays the same, and the total supply of BitcoinZ is decreased only microscopically due to rounding. The BitcoinZ community has not yet made the decision when Blossom will be activated. + + +Blossom Activation on Testnet +----------------------------- +The v2.0.7 release includes Blossom activation on testnet, bringing shorter block times. The testnet Blossom activation height is not defined yet. + + +Insight Explorer +---------------- +Changes needed for the Insight explorer have been incorporated into BitcoinZ. *This is an experimental feature* and therefore is subject to change. To enable, add the `experimentalfeatures=1`, `txindex=1`, and `insightexplorer=1` flags to `bitcoinz.conf`. This feature adds several RPCs to `bitcoinzd` which allow the user to run an Insight explorer. + + +Testnet Blossom Rewind +---------------------- + +Testnet users needed to upgrade to 2.0.7 before Blossom activated. The amount +of notice given to these users was brief, so many were not able to upgrade in +time. These users may now be on the wrong branch. v2.0.7-1 adds an "intended +rewind" to prevent having to manually reindex when reconnecting to the correct +chain. + + +Insight Explorer Logging Fix +---------------------------- + +Fixed an issue where `ERROR: spent index not enabled` would be logged unnecessarily. + + + +Pre-Blossom EOS Halt +-------------------- + +v2.0.7-2 contains a shortened EOS halt so that is in alignment with v2.0.7. + + + +Shrinking of debug.log files is temporarily disabled +---------------------------------------------------- + +In previous versions, `bitcoinzd` would shrink the `debug.log` file to 200 KB on +startup if it was larger than 10 MB. This behaviour, and the `-shrinkdebugfile` +option that controlled it, has been disabled. + + +Changelog +========= + +Marcelus (1) + Incorporation of changes into BTCZ + +Charlie O'Keefe (1): + Add stretch to list of suites in gitian linux descriptors + +Daira Hopwood (9): + Closes #3992. Remove obsolete warning message. + make-release.py: Versioning changes for 2.0.6-rc1. + make-release.py: Updated manpages for 2.0.6-rc1. + make-release.py: Updated release notes and changelog for 2.0.6-rc1. + ld --version doesn't work on macOS. + Tweak author aliases. + Add coding declaration to zcutil/release-notes.py + make-release.py: Versioning changes for 2.0.6. + make-release.py: Updated manpages for 2.0.6. + +Daniel Kraft (1): + Add some const declarations where they are appropriate. + +Eirik Ogilvie-Wigley (1): + Notable changes for 2.0.6 + +Eirik Ogilvie-Wigley (7): + Fix tree depth in comment + Update author aliases + Remove old mergetoaddress RPC test + Replace CSproutNotePlaintextEntry with SproutNoteEntry to match Sapling + z_getmigrationstatus help message wording change + Fix z_mergetoaddress sending from ANY_SPROUT/ANY_SAPLING when the wallet contains both note types + Clarify what combinations of from addresses can be used in z_mergetoaddress + +Jack Grigg (10): + Move Equihash parameters into consensus params + Globals: Remove Zcash-specific Params() calls from main.cpp + Globals: Explicitly pass const CChainParams& to IsStandardTx() + Globals: Explicit const CChainParams& arg for main: + Globals: Explicitly pass const CChainParams& to ContextualCheckTransaction() + Globals: Explicit const CChainParams& arg for main: + Globals: Explicitly pass const CChainParams& to DisconnectBlock() + Consistently use chainparams and consensusParams + Globals: Explicitly pass const CChainParams& to IsInitialBlockDownload() + Globals: Explicitly pass const CChainParams& to ReceivedBlockTransactions() + +Jorge Timón (6): + Globals: Explicit Consensus::Params arg for main: + Globals: Make AcceptBlockHeader static (Fix #6163) + Chainparams: Explicit CChainParams arg for main (pre miner): + Chainparams: Explicit CChainParams arg for miner: + Globals: Remove a bunch of Params() calls from main.cpp: + Globals: Explicitly pass const CChainParams& to UpdateTip() + +Larry Ruane (1): + add spentindex to getrawtransaction RPC results + +Marco Falke (1): + [doc] Fix doxygen comments for members + +Mary Moore-Simmons (1): + Fixes issue #3504: Changes to --version and adds a couple other useful commands. + +Peter Todd (1): + Improve block validity/ConnectBlock() comments + +Simon Liu (1): + Fix typo and clean up help message for RPC z_getmigrationstatus. + +Wladimir J. van der Laan (1): + Break circular dependency main ↔ txdb + +face (2): + Pass CChainParams to DisconnectTip() + Explicitly pass CChainParams to ConnectBlock + +Benjamin Winston (1): + Fixes #4013, added BitcoinABC as a disclosure partner + +Daira Hopwood (3): + Closes #3992. Remove obsolete warning message. + + +Daniel Kraft (1): + Add some const declarations where they are appropriate. + +Eirik Ogilvie-Wigley (7): + Fix tree depth in comment + Update author aliases + Remove old mergetoaddress RPC test + Replace CSproutNotePlaintextEntry with SproutNoteEntry to match Sapling + z_getmigrationstatus help message wording change + Fix z_mergetoaddress sending from ANY_SPROUT/ANY_SAPLING when the wallet contains both note types + Clarify what combinations of from addresses can be used in z_mergetoaddress + +Jack Grigg (10): + Move Equihash parameters into consensus params + Globals: Remove Zcash-specific Params() calls from main.cpp + Globals: Explicitly pass const CChainParams& to IsStandardTx() + Globals: Explicit const CChainParams& arg for main: + Globals: Explicitly pass const CChainParams& to ContextualCheckTransaction() + Globals: Explicit const CChainParams& arg for main: + Globals: Explicitly pass const CChainParams& to DisconnectBlock() + Consistently use chainparams and consensusParams + Globals: Explicitly pass const CChainParams& to IsInitialBlockDownload() + Globals: Explicitly pass const CChainParams& to ReceivedBlockTransactions() + +Jorge Timón (6): + Globals: Explicit Consensus::Params arg for main: + Globals: Make AcceptBlockHeader static (Fix #6163) + Chainparams: Explicit CChainParams arg for main (pre miner): + Chainparams: Explicit CChainParams arg for miner: + Globals: Remove a bunch of Params() calls from main.cpp: + Globals: Explicitly pass const CChainParams& to UpdateTip() + +Larry Ruane (1): + add spentindex to getrawtransaction RPC results + +MarcoFalke (1): + [doc] Fix doxygen comments for members + +Peter Todd (1): + Improve block validity/ConnectBlock() comments + +Simon Liu (1): + Fix typo and clean up help message for RPC z_getmigrationstatus. + +Wladimir J. van der Laan (1): + Break circular dependency main ↔ txdb + +face (2): + Pass CChainParams to DisconnectTip() + Explicitly pass CChainParams to ConnectBlock + +Benjamin Winston (1): + Fixes #4013, added BitcoinABC as a disclosure partner + +Daira Hopwood (10): + Add MIT license to Makefiles + Add MIT license to build-aux/m4/bitcoin_* scripts, and a permissive license to build-aux/m4/l_atomic.m4 . + Update copyright information for Zcash, leveldb, and libsnark. + Add license information for Autoconf macros. refs #2827 + Update contrib/debian/copyright for ax_boost_thread.m4 + Replace http with https: in links to the MIT license. Also change MIT/X11 to just MIT, since no distinction was intended. + qa/zcash/checksec.sh is under a BSD license, with a specialized non-endorsement clause. + Link to ticket #2827 using URL + Release process doc: add step to set the gpg key id. + Release process doc: mention the commit message. + +Dimitris Apostolou (5): + Rename vjoinsplit to vJoinSplit + Fix naming inconsistency + Rename joinsplit to shielded + Rename FindWalletTx to FindWalletTxToZap + Fix RPC undefined behavior. + +Eirik Ogilvie-Wigley (47): + Make nextHeight required in CalculateNextWorkRequired + Fix nondeterministic failure in sapling migration test + Clean up and fix typo + Apply suggestions from code review + Shorter block times rpc test + Update pow_tests for shorter block times + Update test_pow for shorter block times + Update block subsidy halving for zip208 + Make NetworkUpgradeAvailable a method of Params + Temporarily disable test + Simplify PartitionCheck + Use static_assert + Add missing new line at end of file + pow test cleanup + Add message to static_assert + Update expiry height for shorter block times + Fix zip208 founders reward calculation and update test + PartitionCheck tests for shorter block times + Add test for Blossom default tx expiry delta + Update metrics block height estimation for shorter block times + Do not create transactions that will expire after the next epoch + Do not send migration transactions that would expire after a network upgrade + Fix integer truncation in Blossom halving calculation + Update main_tests for shorter block times + Use pre-Blossom max FR height when calculating address change interval + Make founders reward tests pass before and after Blossom activation height is set + Extract Halvings method and add tests + Add comments and fix typos + Improve EstimateNetHeight calculation + Fix check transaction tests + Make sure to deactivate blossom in test case + Fix parsing txexpirydelta argument + Do not add expiring soon threshold to expiry height of txs near NU activation + Fix/update comments + Make sure that expiry height is not less than height + Clarify documentation + Update PoW related assertions + Remove DefaultExpiryDelta method + Algebraic improvements related to halving + Distinguish between height and current header height on metrics screen + Test clean up and fixes + Add copyright info + NPE defense in metrics screen + Do not estimate height if there is no best header + Rename method and use int64_t + make-release.py: Versioning changes for 2.0.7-rc1. + make-release.py: Updated manpages for 2.0.7-rc1. + +Eirik Ogilvie-Wigley (8): + Use CommitTransaction() rather than sendrawtransaction() + Move reused async rpc send logic to separate file + Move reused sign and send logic + Do not shadow the return value when testmode is true + Inline sign_send_raw_transaction + Allow passing optional reserve key as a parameter to SendTransaction + Use reserve key for transparent change when sending to Sapling + Fix comment in mergetoaddress RPC test + +Jack Grigg (4): + test: Check for change t-addr reuse in z_sendmany + Use reserve key for transparent change when sending to Sprout + test: Fix permissions on wallet_changeaddresses RPC test + test: Fix pyflakes warnings + +Larry Ruane (6): + add addressindex related RPCs + add spentindex RPC for bitcore block explorer + add timestampindex related RPC getblockhashes + fix getblockdeltas documentation formatting + insightexplorer minor bug fixes + insightexplorer fix LogPrintf + +Luke Dashjr (2): + Add MIT license to autogen.sh and share/genbuild.sh + Trivial: build-aux/m4/l_atomic: Fix typo + +Simon Liu (8): + Redefine PoW functions to accept height parameter. + Remove use of redundant member nPowTargetSpacing. + Replace nPoWTargetSpacing -> PoWTargetSpacing() + Update PoW function calls to pass in height. + Update GetBlockTimeout() to take height parameter. + Replace nPoWTargetSpacing -> PoWTargetSpacing() in ProcessMessage() + Replace nPoWTargetSpacing -> PoWTargetSpacing() in tests + Modify PartitionCheck to be aware of pre & post Blossom target spacing. + +William M Peaster (1): + Handful of copyedits to README.md + +codetriage-readme-bot (1): + Link to development guidelines in CONTRIBUTING.md + +Jack Grigg (1): + Update README.md + +Daira Hopwood (11): + Add MIT license to Makefiles + Add MIT license to build-aux/m4/bitcoin_* scripts, and a permissive license to build-aux/m4/l_atomic.m4 . + Update copyright information for Zcash, leveldb, and libsnark. + Add license information for Autoconf macros. refs #2827 + Update contrib/debian/copyright for ax_boost_thread.m4 + Replace http with https: in links to the MIT license. Also change MIT/X11 to just MIT, since no distinction was intended. + qa/zcash/checksec.sh is under a BSD license, with a specialized non-endorsement clause. + Link to ticket #2827 using URL + Release process doc: add step to set the gpg key id. + Release process doc: mention the commit message. + Add RPC test and test framework constants for Sapling->Blossom activation. + +Dimitris Apostolou (5): + Rename vjoinsplit to vJoinSplit + Fix naming inconsistency + Rename joinsplit to shielded + Rename FindWalletTx to FindWalletTxToZap + Fix RPC undefined behavior. + +Eirik Ogilvie-Wigley (56): + Make nextHeight required in CalculateNextWorkRequired + Fix nondeterministic failure in sapling migration test + Clean up and fix typo + Apply suggestions from code review + Shorter block times rpc test + Update pow_tests for shorter block times + Update test_pow for shorter block times + Update block subsidy halving for zip208 + Make NetworkUpgradeAvailable a method of Params + Temporarily disable test + Simplify PartitionCheck + Use static_assert + Add missing new line at end of file + pow test cleanup + Add message to static_assert + Update expiry height for shorter block times + Fix zip208 founders reward calculation and update test + PartitionCheck tests for shorter block times + Add test for Blossom default tx expiry delta + Update metrics block height estimation for shorter block times + Do not create transactions that will expire after the next epoch + Do not send migration transactions that would expire after a network upgrade + Fix integer truncation in Blossom halving calculation + Update main_tests for shorter block times + Use pre-Blossom max FR height when calculating address change interval + Make founders reward tests pass before and after Blossom activation height is set + Extract Halvings method and add tests + Add comments and fix typos + Improve EstimateNetHeight calculation + Fix check transaction tests + Make sure to deactivate blossom in test case + Fix parsing txexpirydelta argument + Do not add expiring soon threshold to expiry height of txs near NU activation + Fix/update comments + Make sure that expiry height is not less than height + Clarify documentation + Update PoW related assertions + Remove DefaultExpiryDelta method + Algebraic improvements related to halving + Distinguish between height and current header height on metrics screen + Test clean up and fixes + Add copyright info + NPE defense in metrics screen + Do not estimate height if there is no best header + Rename method and use int64_t + make-release.py: Versioning changes for 2.0.7-rc1. + make-release.py: Updated manpages for 2.0.7-rc1. + make-release.py: Updated release notes and changelog for 2.0.7-rc1. + Update download path + Set testnet Blossom activation height + Notable changes for v2.0.7 + Enable shorter block times rpc test + Grammatical fixes and improvements + Remove constant + make-release.py: Versioning changes for 2.0.7. + make-release.py: Updated manpages for 2.0.7. + +Eirik Ogilvie-Wigley (8): + Use CommitTransaction() rather than sendrawtransaction() + Move reused async rpc send logic to separate file + Move reused sign and send logic + Do not shadow the return value when testmode is true + Inline sign_send_raw_transaction + Allow passing optional reserve key as a parameter to SendTransaction + Use reserve key for transparent change when sending to Sapling + Fix comment in mergetoaddress RPC test + +Jack Grigg (5): + test: Check for change t-addr reuse in z_sendmany + Use reserve key for transparent change when sending to Sprout + test: Fix permissions on wallet_changeaddresses RPC test + test: Fix pyflakes warnings + test: Fix AuthServiceProxy closed conn detection + +Larry Ruane (6): + add addressindex related RPCs + add spentindex RPC for bitcore block explorer + add timestampindex related RPC getblockhashes + fix getblockdeltas documentation formatting + insightexplorer minor bug fixes + insightexplorer fix LogPrintf + +Luke Dashjr (2): + Add MIT license to autogen.sh and share/genbuild.sh + Trivial: build-aux/m4/l_atomic: Fix typo + +Simon Liu (8): + Redefine PoW functions to accept height parameter. + Remove use of redundant member nPowTargetSpacing. + Replace nPoWTargetSpacing -> PoWTargetSpacing() + Update PoW function calls to pass in height. + Update GetBlockTimeout() to take height parameter. + Replace nPoWTargetSpacing -> PoWTargetSpacing() in ProcessMessage() + Replace nPoWTargetSpacing -> PoWTargetSpacing() in tests + Modify PartitionCheck to be aware of pre & post Blossom target spacing. + +William M Peaster (1): + Handful of copyedits to README.md + +codetriage-readme-bot (1): + Link to development guidelines in CONTRIBUTING.md + +Jack Grigg (1): + Update README.md + +Benjamin Winston (3): + Updated location to new download server + Fixes 4097, improves caching on parameter downloads + Updated location to new download server, fixing #4100 + +Alex Tsankov (2): + Update INSTALL + Typo Fix + +Daira Hopwood (1): + Add intended rewind for Blossom on testnet. + +Eirik Ogilvie-Wigley (6): + Notable changes for v2.0.7-1 + fix typo + Add note about logging fix + Better wording in release notes + make-release.py: Versioning changes for 2.0.7-1. + make-release.py: Updated manpages for 2.0.7-1. + +Larry Ruane (2): + #4114 don't call error() from GetSpentIndex() + better fix: make GetSpentIndex() consistent with others... + +Eirik Ogilvie-Wigley (3): + Notable changes for v2.0.7-2 + make-release.py: Versioning changes for 2.0.7-2. + make-release.py: Updated manpages for 2.0.7-2. + +Daira Hopwood (4): + Add hotfix release notes. + Make a note of the shorter service period in the release notes. + make-release.py: Versioning changes for 2.0.7-3. + make-release.py: Updated manpages for 2.0.7-3. + +Jack Grigg (6): + Disable -shrinkdebugfile command + SetMerkleBranch: remove unused code, remove cs_main lock requirement + Remove cs_main lock requirement from CWallet::SyncTransaction + Ignore exceptions when deserializing note plaintexts + Move mempool SyncWithWallets call into its own thread + Enable RPC tests to wait on mempool notifications diff --git a/qa/bitcoinz/create_benchmark_archive.py b/qa/bitcoinz/create_benchmark_archive.py index 2d15027b4..bb02a40de 100644 --- a/qa/bitcoinz/create_benchmark_archive.py +++ b/qa/bitcoinz/create_benchmark_archive.py @@ -165,7 +165,7 @@ def create_benchmark_archive(blk_hash): txs = [json.loads(subprocess.check_output([BITCOINZ_CLI, 'getrawtransaction', tx, '1']) ) for tx in blk['tx']] - js_txs = len([tx for tx in txs if len(tx['vjoinsplit']) > 0]) + js_txs = len([tx for tx in txs if len(tx['vJoinSplit']) > 0]) if js_txs: print 'Block contains %d JoinSplit-containing transactions' % js_txs return diff --git a/qa/bitcoinz/create_wallet_200k_utxos.py b/qa/bitcoinz/create_wallet_200k_utxos.py index d7f2d10eb..f07fdab30 100644 --- a/qa/bitcoinz/create_wallet_200k_utxos.py +++ b/qa/bitcoinz/create_wallet_200k_utxos.py @@ -1,7 +1,8 @@ #!/usr/bin/env python +# Copyright (c) 2020 The BitcoinZ Community # Copyright (c) 2017 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Create a large wallet diff --git a/qa/bitcoinz/test-depends-sources-mirror.py b/qa/bitcoinz/test-depends-sources-mirror.py index e09c2c238..5f36a3d59 100644 --- a/qa/bitcoinz/test-depends-sources-mirror.py +++ b/qa/bitcoinz/test-depends-sources-mirror.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2 -# This script tests that the package mirror at https://z.cash/depends-sources/ +# This script tests that the package mirror at https://download.z.cash/depends-sources/ # contains all of the packages required to build this version of Zcash. # # This script assumes you've just built Zcash, and that as a result of that @@ -12,7 +12,7 @@ import os import requests -MIRROR_URL_DIR="https://z.cash/depends-sources/" +MIRROR_URL_DIR="https://download.z.cash/depends-sources/" DEPENDS_SOURCES_DIR=os.path.realpath(os.path.join( os.path.dirname(__file__), "..", "..", "depends", "sources" diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index b2d49f80c..4ab7fc3b9 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -15,6 +15,7 @@ testScripts=( 'prioritisetransaction.py' 'wallet_treestate.py' 'wallet_anchorfork.py' + 'wallet_changeaddresses.py' 'wallet_changeindicator.py' 'wallet_import_export.py' 'wallet_protectcoinbase.py' @@ -31,12 +32,14 @@ testScripts=( 'wallet_listnotes.py' 'mergetoaddress_sprout.py' 'mergetoaddress_sapling.py' + 'mergetoaddress_mixednotes.py' 'listtransactions.py' 'mempool_resurrect_test.py' 'txn_doublespend.py' 'txn_doublespend.py --mineblock' 'getchaintips.py' 'rawtransactions.py' + 'getrawtransaction_insight.py' 'rest.py' 'mempool_spendcoinbase.py' 'mempool_coinbase_spends.py' @@ -52,6 +55,9 @@ testScripts=( 'key_import_export.py' 'nodehandling.py' # 'reindex.py' + 'addressindex.py' + 'spentindex.py' + 'timestampindex.py' 'decodescript.py' 'blockchain.py' 'disablewallet.py' @@ -68,6 +74,7 @@ testScripts=( 'p2p_node_bloom.py' 'regtest_signrawtransaction.py' 'finalsaplingroot.py' + 'shorter_block_times.py' 'sprout_sapling_migration.py' 'turnstile.py' ); diff --git a/qa/pull-tester/run-bitcoind-for-test.sh.in b/qa/pull-tester/run-bitcoind-for-test.sh.in index 4a8177d0d..faf8a4c83 100755 --- a/qa/pull-tester/run-bitcoind-for-test.sh.in +++ b/qa/pull-tester/run-bitcoind-for-test.sh.in @@ -1,7 +1,7 @@ #!/bin/bash # Copyright (c) 2013-2014 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # ZCASH_LOAD_TIMEOUT=500 DATADIR="@abs_top_builddir@/.zcash" diff --git a/qa/pull-tester/tests-config.sh.in b/qa/pull-tester/tests-config.sh.in index 65ac618b9..66dcdbc8e 100755 --- a/qa/pull-tester/tests-config.sh.in +++ b/qa/pull-tester/tests-config.sh.in @@ -1,7 +1,7 @@ #!/bin/bash # Copyright (c) 2013-2014 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . BUILDDIR="@abs_top_builddir@" EXEEXT="@EXEEXT@" diff --git a/qa/rpc-tests/README.md b/qa/rpc-tests/README.md index 3affd50fc..ebc69454f 100644 --- a/qa/rpc-tests/README.md +++ b/qa/rpc-tests/README.md @@ -18,15 +18,15 @@ Possible options: ``` -h, --help show this help message and exit - --nocleanup Leave zcashds and test.* datadir on exit or error + --nocleanup Leave bitcoinzds and test.* datadir on exit or error --noshutdown Don't stop bitcoinds after the test execution - --srcdir=SRCDIR Source directory containing zcashd/zcash-cli (default: + --srcdir=SRCDIR Source directory containing bitcoinzd/bitcoinz-cli (default: ../../src) --tmpdir=TMPDIR Root directory for datadirs --tracerpc Print out all RPC calls as they are made ``` -If you set the environment variable `PYTHON_DEBUG=1` you will get some debug output (example: `PYTHON_DEBUG=1 qa/pull-tester/rpc-tests.sh wallet`). +If you set the environment variable `PYTHON_DEBUG=1` you will get some debug output (example: `PYTHON_DEBUG=1 qa/pull-tester/rpc-tests.sh wallet`). A 200-block -regtest blockchain and wallets for four nodes is created the first time a regression test is run and @@ -42,5 +42,5 @@ to recover with: ```bash rm -rf cache -killall zcashd +killall bitcoinzd ``` diff --git a/qa/rpc-tests/addressindex.py b/qa/rpc-tests/addressindex.py new file mode 100755 index 000000000..023fb0155 --- /dev/null +++ b/qa/rpc-tests/addressindex.py @@ -0,0 +1,363 @@ +#!/usr/bin/env python +# Copyright (c) 2020 The BitcoinZ Community +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test addressindex generation and fetching for insightexplorer +# +# RPCs tested here: +# +# getaddresstxids +# getaddressbalance +# getaddressdeltas +# getaddressutxos +# getaddressmempool +# + +import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." + +from test_framework.test_framework import BitcoinTestFramework + + +from test_framework.util import ( + assert_equal, + initialize_chain_clean, + start_nodes, + stop_nodes, + connect_nodes, +) + +from test_framework.util import wait_bitcoinds + +from test_framework.script import ( + CScript, + OP_HASH160, + OP_EQUAL, + OP_DUP, + OP_DROP, +) + +from test_framework.mininode import COIN, CTransaction +from test_framework.mininode import CTxIn, CTxOut, COutPoint + +from binascii import hexlify + + +class AddressIndexTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 3) + + def setup_network(self): + # -insightexplorer causes addressindex to be enabled (fAddressIndex = true) + args = ('-debug', '-txindex', '-experimentalfeatures', '-insightexplorer') + self.nodes = start_nodes(3, self.options.tmpdir, [args] * 3) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + + # helper functions + def getaddresstxids(node_index, addresses, start, end): + return self.nodes[node_index].getaddresstxids({ + 'addresses': addresses, + 'start': start, + 'end': end + }) + + def getaddressdeltas(node_index, addresses, start, end, chainInfo=None): + params = { + 'addresses': addresses, + 'start': start, + 'end': end, + } + if chainInfo is not None: + params.update({'chainInfo': chainInfo}) + return self.nodes[node_index].getaddressdeltas(params) + + # default received value is the balance value + def check_balance(node_index, address, expected_balance, expected_received=None): + if isinstance(address, list): + bal = self.nodes[node_index].getaddressbalance({'addresses': address}) + else: + bal = self.nodes[node_index].getaddressbalance(address) + assert_equal(bal['balance'], expected_balance) + if expected_received is None: + expected_received = expected_balance + assert_equal(bal['received'], expected_received) + + # begin test + + self.nodes[0].generate(105) + self.sync_all() + assert_equal(self.nodes[0].getbalance(), 5 * 10) + assert_equal(self.nodes[1].getblockcount(), 105) + assert_equal(self.nodes[1].getbalance(), 0) + + # only the oldest 5; subsequent are not yet mature + unspent_txids = [ u['txid'] for u in self.nodes[0].listunspent() ] + + # Currently our only unspents are coinbase transactions, choose any one + tx = self.nodes[0].getrawtransaction(unspent_txids[0], 1) + + # It just so happens that the first output is the mining reward, + # which has type pay-to-public-key-hash, and the second output + # is the founders' reward, which has type pay-to-script-hash. + addr_p2pkh = tx['vout'][0]['scriptPubKey']['addresses'][0] + addr_p2sh = tx['vout'][1]['scriptPubKey']['addresses'][0] + + # Check that balances from mining are correct (105 blocks mined); in + # regtest, all mining rewards from a single call to generate() are sent + # to the same pair of addresses. + check_balance(1, addr_p2pkh, 105 * 10 * COIN) + check_balance(1, addr_p2sh, 105 * 2.5 * COIN) + + # Multiple address arguments, results are the sum + check_balance(1, [addr_p2sh, addr_p2pkh], 105 * 12.5 * COIN) + + assert_equal(len(self.nodes[1].getaddresstxids(addr_p2pkh)), 105) + assert_equal(len(self.nodes[1].getaddresstxids(addr_p2sh)), 105) + + # only the oldest 5 transactions are in the unspent list, + # dup addresses are ignored + height_txids = getaddresstxids(1, [addr_p2pkh, addr_p2pkh], 1, 5) + assert_equal(sorted(height_txids), sorted(unspent_txids)) + + height_txids = getaddresstxids(1, [addr_p2sh], 1, 5) + assert_equal(sorted(height_txids), sorted(unspent_txids)) + + # each txid should appear only once + height_txids = getaddresstxids(1, [addr_p2pkh, addr_p2sh], 1, 5) + assert_equal(sorted(height_txids), sorted(unspent_txids)) + + # do some transfers, make sure balances are good + txids_a1 = [] + addr1 = self.nodes[1].getnewaddress() + expected = 0 + expected_deltas = [] # for checking getaddressdeltas (below) + for i in range(5): + # first transaction happens at height 105, mined in block 106 + txid = self.nodes[0].sendtoaddress(addr1, i + 1) + txids_a1.append(txid) + self.nodes[0].generate(1) + self.sync_all() + expected += i + 1 + expected_deltas.append({ + 'height': 106 + i, + 'satoshis': (i + 1) * COIN, + 'txid': txid, + }) + check_balance(1, addr1, expected * COIN) + assert_equal(sorted(self.nodes[0].getaddresstxids(addr1)), sorted(txids_a1)) + assert_equal(sorted(self.nodes[1].getaddresstxids(addr1)), sorted(txids_a1)) + + # Restart all nodes to ensure indices are saved to disk and recovered + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + bal = self.nodes[1].getaddressbalance(addr1) + assert_equal(bal['balance'], expected * COIN) + assert_equal(bal['received'], expected * COIN) + assert_equal(sorted(self.nodes[0].getaddresstxids(addr1)), sorted(txids_a1)) + assert_equal(sorted(self.nodes[1].getaddresstxids(addr1)), sorted(txids_a1)) + + # Send 3 from addr1, but -- subtlety alert! -- addr1 at this + # time has 4 UTXOs, with values 1, 2, 3, 4. Sending value 3 requires + # using up the value 4 UTXO, because of the tx fee + # (the 3 UTXO isn't quite large enough). + # + # The txid from sending *from* addr1 is also added to the list of + # txids associated with that address (test will verify below). + + addr2 = self.nodes[2].getnewaddress() + txid = self.nodes[1].sendtoaddress(addr2, 3) + self.sync_all() + + # the one tx in the mempool refers to addresses addr1 and addr2, + # check that duplicate addresses are processed correctly + mempool = self.nodes[0].getaddressmempool({'addresses': [addr2, addr1, addr2]}) + assert_equal(len(mempool), 3) + + # addr2 (first arg) + assert_equal(mempool[0]['address'], addr2) + assert_equal(mempool[0]['satoshis'], 3 * COIN) + assert_equal(mempool[0]['txid'], txid) + + # addr1 (second arg) + assert_equal(mempool[1]['address'], addr1) + assert_equal(mempool[1]['satoshis'], (-4) * COIN) + assert_equal(mempool[1]['txid'], txid) + + # addr2 (third arg) + assert_equal(mempool[2]['address'], addr2) + assert_equal(mempool[2]['satoshis'], 3 * COIN) + assert_equal(mempool[2]['txid'], txid) + + # a single address can be specified as a string (not json object) + assert_equal([mempool[1]], self.nodes[0].getaddressmempool(addr1)) + + tx = self.nodes[0].getrawtransaction(txid, 1) + assert_equal(tx['vin'][0]['address'], addr1) + assert_equal(tx['vin'][0]['value'], 4) + assert_equal(tx['vin'][0]['valueSat'], 4 * COIN) + + txids_a1.append(txid) + expected_deltas.append({ + 'height': 111, + 'satoshis': (-4) * COIN, + 'txid': txid, + }) + self.sync_all() # ensure transaction is included in the next block + self.nodes[0].generate(1) + self.sync_all() + + # the send to addr2 tx is now in a mined block, no longer in the mempool + mempool = self.nodes[0].getaddressmempool({'addresses': [addr2, addr1]}) + assert_equal(len(mempool), 0) + + # Test DisconnectBlock() by invalidating the most recent mined block + tip = self.nodes[1].getchaintips()[0] + for i in range(3): + node = self.nodes[i] + # the value 4 UTXO is no longer in our balance + check_balance(i, addr1, (expected - 4) * COIN, expected * COIN) + check_balance(i, addr2, 3 * COIN) + + assert_equal(node.getblockcount(), 111) + node.invalidateblock(tip['hash']) + assert_equal(node.getblockcount(), 110) + + mempool = node.getaddressmempool({'addresses': [addr2, addr1]}) + assert_equal(len(mempool), 2) + + check_balance(i, addr1, expected * COIN) + check_balance(i, addr2, 0) + + # now re-mine the addr1 to addr2 send + self.nodes[0].generate(1) + self.sync_all() + for node in self.nodes: + assert_equal(node.getblockcount(), 111) + + mempool = self.nodes[0].getaddressmempool({'addresses': [addr2, addr1]}) + assert_equal(len(mempool), 0) + + # the value 4 UTXO is no longer in our balance + check_balance(2, addr1, (expected - 4) * COIN, expected * COIN) + + # Ensure the change from that transaction appears + tx = self.nodes[0].getrawtransaction(txid, 1) + change_vout = filter(lambda v: v['valueZat'] != 3 * COIN, tx['vout']) + change = change_vout[0]['scriptPubKey']['addresses'][0] + bal = self.nodes[2].getaddressbalance(change) + assert(bal['received'] > 0) + # the inequality is due to randomness in the tx fee + assert(bal['received'] < (4 - 3) * COIN) + assert_equal(bal['received'], bal['balance']) + assert_equal(self.nodes[2].getaddresstxids(change), [txid]) + + # Further checks that limiting by height works + + # various ranges + for i in range(5): + height_txids = getaddresstxids(1, [addr1], 106, 106 + i) + assert_equal(height_txids, txids_a1[0:i+1]) + + height_txids = getaddresstxids(1, [addr1], 1, 108) + assert_equal(height_txids, txids_a1[0:3]) + + # Further check specifying multiple addresses + txids_all = list(txids_a1) + txids_all += self.nodes[1].getaddresstxids(addr_p2pkh) + txids_all += self.nodes[1].getaddresstxids(addr_p2sh) + multitxids = self.nodes[1].getaddresstxids({ + 'addresses': [addr1, addr_p2sh, addr_p2pkh] + }) + # No dups in return list from getaddresstxids + assert_equal(len(multitxids), len(set(multitxids))) + + # set(txids_all) removes its (expected) duplicates + assert_equal(set(multitxids), set(txids_all)) + + deltas = self.nodes[1].getaddressdeltas({'addresses': [addr1]}) + assert_equal(len(deltas), len(expected_deltas)) + for i in range(len(deltas)): + assert_equal(deltas[i]['address'], addr1) + assert_equal(deltas[i]['height'], expected_deltas[i]['height']) + assert_equal(deltas[i]['satoshis'], expected_deltas[i]['satoshis']) + assert_equal(deltas[i]['txid'], expected_deltas[i]['txid']) + + # 106-111 is the full range (also the default) + deltas_limited = getaddressdeltas(1, [addr1], 106, 111) + assert_equal(deltas_limited, deltas) + + # only the first element missing + deltas_limited = getaddressdeltas(1, [addr1], 107, 111) + assert_equal(deltas_limited, deltas[1:]) + + deltas_limited = getaddressdeltas(1, [addr1], 109, 109) + assert_equal(deltas_limited, deltas[3:4]) + + # the full range (also the default) + deltas_info = getaddressdeltas(1, [addr1], 106, 111, chainInfo=True) + assert_equal(deltas_info['deltas'], deltas) + + # check the additional items returned by chainInfo + assert_equal(deltas_info['start']['height'], 106) + block_hash = self.nodes[1].getblockhash(106) + assert_equal(deltas_info['start']['hash'], block_hash) + + assert_equal(deltas_info['end']['height'], 111) + block_hash = self.nodes[1].getblockhash(111) + assert_equal(deltas_info['end']['hash'], block_hash) + + # Test getaddressutxos by comparing results with deltas + utxos = self.nodes[1].getaddressutxos(addr1) + + # The value 4 note was spent, so won't show up in the utxo list, + # so for comparison, remove the 4 (and -4 for output) from the + # deltas list + deltas = self.nodes[1].getaddressdeltas({'addresses': [addr1]}) + deltas = filter(lambda d: abs(d['satoshis']) != 4 * COIN, deltas) + assert_equal(len(utxos), len(deltas)) + for i in range(len(utxos)): + assert_equal(utxos[i]['address'], addr1) + assert_equal(utxos[i]['height'], deltas[i]['height']) + assert_equal(utxos[i]['satoshis'], deltas[i]['satoshis']) + assert_equal(utxos[i]['txid'], deltas[i]['txid']) + + # Check that outputs with the same address in the same tx return one txid + # (can't use createrawtransaction() as it combines duplicate addresses) + addr = "t2LMJ6Arw9UWBMWvfUr2QLHM4Xd9w53FftS" + addressHash = "97643ce74b188f4fb6bbbb285e067a969041caf2".decode('hex') + scriptPubKey = CScript([OP_HASH160, addressHash, OP_EQUAL]) + # Add an unrecognized script type to vout[], a legal script that pays, + # but won't modify the addressindex (since the address can't be extracted). + # (This extra output has no effect on the rest of the test.) + scriptUnknown = CScript([OP_HASH160, OP_DUP, OP_DROP, addressHash, OP_EQUAL]) + unspent = filter(lambda u: u['amount'] >= 4, self.nodes[0].listunspent()) + tx = CTransaction() + tx.vin = [CTxIn(COutPoint(int(unspent[0]['txid'], 16), unspent[0]['vout']))] + tx.vout = [ + CTxOut(1 * COIN, scriptPubKey), + CTxOut(2 * COIN, scriptPubKey), + CTxOut(7 * COIN, scriptUnknown), + ] + tx = self.nodes[0].signrawtransaction(hexlify(tx.serialize()).decode('utf-8')) + txid = self.nodes[0].sendrawtransaction(tx['hex'], True) + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(self.nodes[1].getaddresstxids(addr), [txid]) + check_balance(2, addr, 3 * COIN) + + +if __name__ == '__main__': + AddressIndexTest().main() diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index 3daff0a37..254c075c3 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index 163933ab0..7eca0404d 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index 22dd299ec..acd04d842 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test RPC calls related to blockchain state. Tests correspond to code in diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index ea4916b06..042591455 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index e43a9519f..f665902ef 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Exercise API with -disablewallet. diff --git a/qa/rpc-tests/finalsaplingroot.py b/qa/rpc-tests/finalsaplingroot.py index 4298ec20b..6d66cd83a 100755 --- a/qa/rpc-tests/finalsaplingroot.py +++ b/qa/rpc-tests/finalsaplingroot.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index 4386f246d..8bfab5961 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test -alertnotify diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index a7962d2f9..17d2bc5cf 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/getblocktemplate.py b/qa/rpc-tests/getblocktemplate.py index 96fd73083..1a7205f5a 100755 --- a/qa/rpc-tests/getblocktemplate.py +++ b/qa/rpc-tests/getblocktemplate.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2016 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py index 748c547e5..beccce881 100755 --- a/qa/rpc-tests/getblocktemplate_longpoll.py +++ b/qa/rpc-tests/getblocktemplate_longpoll.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index 771e8b091..a14e409f7 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/getchaintips.py b/qa/rpc-tests/getchaintips.py index 7bbb921ca..8215ce0b5 100755 --- a/qa/rpc-tests/getchaintips.py +++ b/qa/rpc-tests/getchaintips.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # Exercise the getchaintips API. We introduce a network split, work # on chains of different lengths, and join the network together again. diff --git a/qa/rpc-tests/getrawtransaction_insight.py b/qa/rpc-tests/getrawtransaction_insight.py new file mode 100755 index 000000000..62d258680 --- /dev/null +++ b/qa/rpc-tests/getrawtransaction_insight.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python2 +# Copyright (c) 2020 The BitcoinZ Community +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test the new fields added to the output of getrawtransaction +# RPC for the Insight Explorer by the new spentindex +# + +from test_framework.test_framework import BitcoinTestFramework + +from test_framework.util import assert_equal +from test_framework.util import initialize_chain_clean +from test_framework.util import start_nodes, stop_nodes, connect_nodes +from test_framework.util import wait_bitcoinds + +from test_framework.mininode import COIN + + +class GetrawtransactionTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self): + # -insightexplorer causes spentindex to be enabled (fSpentIndex = true) + + self.nodes = start_nodes(3, self.options.tmpdir, + [['-debug', '-txindex', '-experimentalfeatures', '-insightexplorer']]*3) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + self.nodes[0].generate(105) + self.sync_all() + + chain_height = self.nodes[1].getblockcount() + assert_equal(chain_height, 105) + + # Test getrawtransaction changes and the getspentinfo RPC + + # send coinbase to address a + a = self.nodes[1].getnewaddress() + txid_a = self.nodes[0].sendtoaddress(a, 2) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # send from a to b + # (the only utxo on node 1 is from address a) + b = self.nodes[2].getnewaddress() + txid_b = self.nodes[1].sendtoaddress(b, 1) + self.sync_all() + + # a to b transaction is not confirmed, so it has no height + tx_b = self.nodes[2].getrawtransaction(txid_b, 1) + assert('height' not in tx_b) + + self.sync_all() + tx_a = self.nodes[2].getrawtransaction(txid_a, 1) + + # txid_b is not yet confirmed, so height is invalid (-1) + vout = filter(lambda o: o['value'] == 2, tx_a['vout']) + assert_equal(vout[0]['spentTxId'], txid_b) + assert_equal(vout[0]['spentIndex'], 0) + assert_equal(vout[0]['spentHeight'], -1) + + # confirm txid_b (a to b transaction) + self.nodes[0].generate(1) + self.sync_all() + + # Restart all nodes to ensure index files are saved to disk and recovered + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # Check new fields added to getrawtransaction + tx_a = self.nodes[2].getrawtransaction(txid_a, 1) + assert_equal(tx_a['vin'][0]['value'], 10) # coinbase + assert_equal(tx_a['vin'][0]['valueSat'], 10*COIN) + # we want the non-change (payment) output + vout = filter(lambda o: o['value'] == 2, tx_a['vout']) + assert_equal(vout[0]['spentTxId'], txid_b) + assert_equal(vout[0]['spentIndex'], 0) + assert_equal(vout[0]['spentHeight'], 107) + assert_equal(tx_a['height'], 106) + + tx_b = self.nodes[2].getrawtransaction(txid_b, 1) + assert_equal(tx_b['vin'][0]['address'], a) + assert_equal(tx_b['vin'][0]['value'], 2) + assert_equal(tx_b['vin'][0]['valueSat'], 2*COIN) + # since this transaction's outputs haven't yet been + # spent, these fields should not be present + assert('spentTxId' not in tx_b['vout'][0]) + assert('spentIndex' not in tx_b['vout'][0]) + assert('spentHeight' not in tx_b['vout'][0]) + assert_equal(tx_b['height'], 107) + +if __name__ == '__main__': + GetrawtransactionTest().main() diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index ca5924c90..11e2c1385 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test rpc http basics diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py index ab0ba4a69..069f8ace8 100755 --- a/qa/rpc-tests/invalidateblock.py +++ b/qa/rpc-tests/invalidateblock.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test InvalidateBlock code diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index 6e8895f1d..d27feccd6 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/key_import_export.py b/qa/rpc-tests/key_import_export.py index 02638e6a8..66fc7ef04 100755 --- a/qa/rpc-tests/key_import_export.py +++ b/qa/rpc-tests/key_import_export.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2017 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index b538742a4..ddebf3a55 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # Exercise the wallet keypool, and interaction with wallet encryption/locking diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 3f508c603..28764cd28 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # Exercise the listtransactions API diff --git a/qa/rpc-tests/maxblocksinflight.py b/qa/rpc-tests/maxblocksinflight.py index 6ba67940e..c56cd608c 100755 --- a/qa/rpc-tests/maxblocksinflight.py +++ b/qa/rpc-tests/maxblocksinflight.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/mempool_coinbase_spends.py b/qa/rpc-tests/mempool_coinbase_spends.py index f5b012f33..6b9df7d35 100644 --- a/qa/rpc-tests/mempool_coinbase_spends.py +++ b/qa/rpc-tests/mempool_coinbase_spends.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test re-org scenarios with a mempool that contains transactions diff --git a/qa/rpc-tests/mempool_nu_activation.py b/qa/rpc-tests/mempool_nu_activation.py index ed55dcfc0..20d435f95 100755 --- a/qa/rpc-tests/mempool_nu_activation.py +++ b/qa/rpc-tests/mempool_nu_activation.py @@ -1,14 +1,18 @@ #!/usr/bin/env python +# Copyright (c) 2020 The BitcoinZ Community # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, initialize_chain_clean, \ - start_node, connect_nodes, wait_and_assert_operationid_status, \ + +from test_framework.util import ( + start_node, connect_nodes, wait_and_assert_operationid_status, get_coinbase_address +) + from test_framework.authproxy import JSONRPCException from decimal import Decimal @@ -22,6 +26,7 @@ def setup_network(self): args = ["-checkmempool", "-debug=mempool", "-blockmaxsize=4000", "-nuparams=5ba81b19:200", # Overwinter "-nuparams=76b809bb:210", # Sapling + "-nuparams=2bb40e60:220", # Blossom ] self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, args)) @@ -72,10 +77,11 @@ def nu_activation_checks(): while self.nodes[1].getmempoolinfo()['bytes'] < 2 * 4000: try: x_txids.append(self.nodes[1].sendtoaddress(node0_taddr, Decimal('0.001'))) - assert_equal(chaintip_branchid, "00000000") + except JSONRPCException: # This fails due to expiring soon threshold, which applies from Overwinter onwards. - assert_equal(info["upgrades"][chaintip_branchid]["name"], "Overwinter") + upgrade_name = info["upgrades"][chaintip_branchid]["name"] + assert_true(upgrade_name in ("Overwinter", "Sapling"), upgrade_name) break self.sync_all() @@ -155,6 +161,13 @@ def nu_activation_checks(): # Current height = 207 nu_activation_checks() # Current height = 215 + self.nodes[0].generate(2) + self.sync_all() + + print('Testing Sapling -> Blossom activation boundary') + # Current height = 217 + nu_activation_checks() + # Current height = 225 if __name__ == '__main__': MempoolUpgradeActivationTest().main() diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 78d2eb23f..b72bc19c5 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test resurrection of mined transactions when diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index 9e213ce2f..2a999e8e1 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test spending coinbase transactions. diff --git a/qa/rpc-tests/mempool_tx_expiry.py b/qa/rpc-tests/mempool_tx_expiry.py index af84ff3a7..7d66fd0e9 100755 --- a/qa/rpc-tests/mempool_tx_expiry.py +++ b/qa/rpc-tests/mempool_tx_expiry.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test proper expiry for transactions >= version 3 diff --git a/qa/rpc-tests/mempool_tx_input_limit.py b/qa/rpc-tests/mempool_tx_input_limit.py index 7d0ba00e6..0e9ea786a 100755 --- a/qa/rpc-tests/mempool_tx_input_limit.py +++ b/qa/rpc-tests/mempool_tx_input_limit.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2017 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/mergetoaddress_helper.py b/qa/rpc-tests/mergetoaddress_helper.py index cc829f8b8..973800104 100755 --- a/qa/rpc-tests/mergetoaddress_helper.py +++ b/qa/rpc-tests/mergetoaddress_helper.py @@ -1,6 +1,6 @@ # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Common code for testing z_mergetoaddress before and after sapling activation @@ -17,11 +17,12 @@ def assert_mergetoaddress_exception(expected_error_msg, merge_to_address_lambda): try: merge_to_address_lambda() - fail("Expected exception: %s" % expected_error_msg) except JSONRPCException as e: assert_equal(expected_error_msg, e.error['message']) except Exception as e: fail("Expected JSONRPCException. Found %s" % repr(e)) + else: + fail("Expected exception: %s" % expected_error_msg) class MergeToAddressHelper: @@ -152,6 +153,11 @@ def run_test(self, test): "Destination address is also the only source address, and all its funds are already merged.", lambda: test.nodes[0].z_mergetoaddress([mytaddr], mytaddr)) + # Merging will fail if we try to specify from Sprout AND Sapling + assert_mergetoaddress_exception( + "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress", + lambda: test.nodes[0].z_mergetoaddress(["ANY_SPROUT", "ANY_SAPLING"], mytaddr)) + # Merge UTXOs from node 0 of value 30, standard fee of 0.00010000 result = test.nodes[0].z_mergetoaddress([mytaddr, mytaddr2, mytaddr3], myzaddr) wait_and_assert_operationid_status(test.nodes[0], result['opid']) diff --git a/qa/rpc-tests/mergetoaddress_mixednotes.py b/qa/rpc-tests/mergetoaddress_mixednotes.py new file mode 100755 index 000000000..1aa59db97 --- /dev/null +++ b/qa/rpc-tests/mergetoaddress_mixednotes.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# Copyright (c) 2020 The BitcoinZ Community +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." + +from decimal import Decimal +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, get_coinbase_address, \ + initialize_chain_clean, start_nodes, wait_and_assert_operationid_status +from mergetoaddress_helper import assert_mergetoaddress_exception + + +class MergeToAddressMixedNotes(BitcoinTestFramework): + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir, [[ + '-nuparams=5ba81b19:100', # Overwinter + '-nuparams=76b809bb:100', # Sapling + '-experimentalfeatures', '-zmergetoaddress' + ]] * 4) + + def setup_chain(self): + print("Initializing test directory " + self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def run_test(self): + print "Mining blocks..." + self.nodes[0].generate(102) + self.sync_all() + + # Send some ZEC to Sprout/Sapling addresses + coinbase_addr = get_coinbase_address(self.nodes[0]) + sproutAddr = self.nodes[0].z_getnewaddress('sprout') + saplingAddr = self.nodes[0].z_getnewaddress('sapling') + t_addr = self.nodes[1].getnewaddress() + + opid = self.nodes[0].z_sendmany(coinbase_addr, [{"address": sproutAddr, "amount": Decimal('10')}], 1, 0) + wait_and_assert_operationid_status(self.nodes[0], opid) + self.nodes[0].generate(1) + self.sync_all() + assert_equal(self.nodes[0].z_getbalance(sproutAddr), Decimal('10')) + assert_equal(self.nodes[0].z_getbalance(saplingAddr), Decimal('0')) + assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('0')) + # Make sure we cannot use "ANY_SPROUT" and "ANY_SAPLING" even if we only have Sprout Notes + assert_mergetoaddress_exception( + "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress", + lambda: self.nodes[0].z_mergetoaddress(["ANY_SPROUT", "ANY_SAPLING"], t_addr)) + opid = self.nodes[0].z_sendmany(coinbase_addr, [{"address": saplingAddr, "amount": Decimal('10')}], 1, 0) + wait_and_assert_operationid_status(self.nodes[0], opid) + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('0')) + + # Merge Sprout -> taddr + result = self.nodes[0].z_mergetoaddress(["ANY_SPROUT"], t_addr, 0) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].z_getbalance(sproutAddr), Decimal('0')) + assert_equal(self.nodes[0].z_getbalance(saplingAddr), Decimal('10')) + assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('10')) + + # Make sure we cannot use "ANY_SPROUT" and "ANY_SAPLING" even if we only have Sapling Notes + assert_mergetoaddress_exception( + "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress", + lambda: self.nodes[0].z_mergetoaddress(["ANY_SPROUT", "ANY_SAPLING"], t_addr)) + # Merge Sapling -> taddr + result = self.nodes[0].z_mergetoaddress(["ANY_SAPLING"], t_addr, 0) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].z_getbalance(sproutAddr), Decimal('0')) + assert_equal(self.nodes[0].z_getbalance(saplingAddr), Decimal('0')) + assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('20')) + + +if __name__ == '__main__': + MergeToAddressMixedNotes().main() diff --git a/qa/rpc-tests/mergetoaddress_sapling.py b/qa/rpc-tests/mergetoaddress_sapling.py index 1ab8e61e9..72ca6929a 100755 --- a/qa/rpc-tests/mergetoaddress_sapling.py +++ b/qa/rpc-tests/mergetoaddress_sapling.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/mergetoaddress_sprout.py b/qa/rpc-tests/mergetoaddress_sprout.py index 88a821ac2..8d3e2cbec 100755 --- a/qa/rpc-tests/mergetoaddress_sprout.py +++ b/qa/rpc-tests/mergetoaddress_sprout.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index 88d97b293..f6d1ce3d2 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test merkleblock fetch/validation diff --git a/qa/rpc-tests/nodehandling.py b/qa/rpc-tests/nodehandling.py index fd7d8356b..7ab65f664 100755 --- a/qa/rpc-tests/nodehandling.py +++ b/qa/rpc-tests/nodehandling.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test node handling diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py index 3f89d786f..61474d516 100755 --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/p2p_node_bloom.py b/qa/rpc-tests/p2p_node_bloom.py index 9a520c4ed..dd8709c04 100755 --- a/qa/rpc-tests/p2p_node_bloom.py +++ b/qa/rpc-tests/p2p_node_bloom.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/p2p_nu_peer_management.py b/qa/rpc-tests/p2p_nu_peer_management.py index aee5bfe18..cbb8a3082 100755 --- a/qa/rpc-tests/p2p_nu_peer_management.py +++ b/qa/rpc-tests/p2p_nu_peer_management.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/p2p_txexpiringsoon.py b/qa/rpc-tests/p2p_txexpiringsoon.py index 37465cddf..bd631a5ad 100755 --- a/qa/rpc-tests/p2p_txexpiringsoon.py +++ b/qa/rpc-tests/p2p_txexpiringsoon.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/p2p_txexpiry_dos.py b/qa/rpc-tests/p2p_txexpiry_dos.py index 7927f9189..e51bf2cb6 100755 --- a/qa/rpc-tests/p2p_txexpiry_dos.py +++ b/qa/rpc-tests/p2p_txexpiry_dos.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/paymentdisclosure.py b/qa/rpc-tests/paymentdisclosure.py index 9ce823164..a2e37e733 100755 --- a/qa/rpc-tests/paymentdisclosure.py +++ b/qa/rpc-tests/paymentdisclosure.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2017 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." @@ -74,7 +74,7 @@ def run_test (self): txid = wait_and_assert_operationid_status(self.nodes[0], myopid) # Check the tx has joinsplits - assert( len(self.nodes[0].getrawtransaction("" + txid, 1)["vjoinsplit"]) > 0 ) + assert( len(self.nodes[0].getrawtransaction("" + txid, 1)["vJoinSplit"]) > 0 ) # Sync mempools self.sync_all() diff --git a/qa/rpc-tests/prioritisetransaction.py b/qa/rpc-tests/prioritisetransaction.py index 131644d80..cdb5f5858 100755 --- a/qa/rpc-tests/prioritisetransaction.py +++ b/qa/rpc-tests/prioritisetransaction.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2017 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/proton_test.py b/qa/rpc-tests/proton_test.py index 20c152199..820a9d7be 100755 --- a/qa/rpc-tests/proton_test.py +++ b/qa/rpc-tests/proton_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2017 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test Proton interface (provides AMQP 1.0 messaging support). diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py index fec14833c..8db56c5cb 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/qa/rpc-tests/proxy_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index d49cc5812..f10011f9f 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test pruning code diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index 801487907..6deaafad1 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test re-org scenarios with a mempool that contains transactions diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py index 1a52efce9..dcce3831f 100755 --- a/qa/rpc-tests/receivedby.py +++ b/qa/rpc-tests/receivedby.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # Exercise the listreceivedbyaddress API diff --git a/qa/rpc-tests/regtest_signrawtransaction.py b/qa/rpc-tests/regtest_signrawtransaction.py index 9854cf96f..4b2b524bc 100755 --- a/qa/rpc-tests/regtest_signrawtransaction.py +++ b/qa/rpc-tests/regtest_signrawtransaction.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index c11314a9f..c19d9c1f5 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test -reindex with CheckBlockIndex diff --git a/qa/rpc-tests/reorg_limit.py b/qa/rpc-tests/reorg_limit.py index 5c46e6d6d..7eec27ee4 100755 --- a/qa/rpc-tests/reorg_limit.py +++ b/qa/rpc-tests/reorg_limit.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2017 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test reorg limit diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index 475f0f5fa..63e9f0fa8 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test REST interface diff --git a/qa/rpc-tests/rewind_index.py b/qa/rpc-tests/rewind_index.py index 96072098e..9a30f393c 100755 --- a/qa/rpc-tests/rewind_index.py +++ b/qa/rpc-tests/rewind_index.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 4a6d25463..e192004d6 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # Test for -rpcbind, as well as -rpcallowip and -rpcconnect diff --git a/qa/rpc-tests/script_test.py b/qa/rpc-tests/script_test.py index 1bbeb2cfc..433683231 100755 --- a/qa/rpc-tests/script_test.py +++ b/qa/rpc-tests/script_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # ''' diff --git a/qa/rpc-tests/shorter_block_times.py b/qa/rpc-tests/shorter_block_times.py new file mode 100755 index 000000000..4c059aed6 --- /dev/null +++ b/qa/rpc-tests/shorter_block_times.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# Copyright (c) 2020 The BitcoinZ Community +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." + +from decimal import Decimal +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + get_coinbase_address, + initialize_chain_clean, + start_nodes, + wait_and_assert_operationid_status, +) + + +class ShorterBlockTimes(BitcoinTestFramework): + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir, [[ + '-nuparams=5ba81b19:0', # Overwinter + '-nuparams=76b809bb:0', # Sapling + '-nuparams=2bb40e60:106', # Blossom + ]] * 4) + + def setup_chain(self): + print("Initializing test directory " + self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def run_test(self): + print "Mining blocks..." + self.nodes[0].generate(101) + self.sync_all() + + # Sanity-check the block height + assert_equal(self.nodes[0].getblockcount(), 101) + + node0_taddr = get_coinbase_address(self.nodes[0]) + node0_zaddr = self.nodes[0].z_getnewaddress('sapling') + recipients = [{'address': node0_zaddr, 'amount': Decimal('10')}] + myopid = self.nodes[0].z_sendmany(node0_taddr, recipients, 1, Decimal('0')) + txid = wait_and_assert_operationid_status(self.nodes[0], myopid) + assert_equal(105, self.nodes[0].getrawtransaction(txid, 1)['expiryheight']) # Blossom activation - 1 + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + assert_equal(10, Decimal(self.nodes[0].z_gettotalbalance()['private'])) + + self.nodes[0].generate(2) + self.sync_all() + print "Mining last pre-Blossom blocks" + # Activate blossom + self.nodes[1].generate(1) + self.sync_all() + # Check that we received a pre-Blossom mining reward + assert_equal(10, Decimal(self.nodes[1].getwalletinfo()['immature_balance'])) + + # After blossom activation the block reward will be halved + print "Mining first Blossom block" + self.nodes[1].generate(1) + self.sync_all() + # Check that we received an additional Blossom mining reward + assert_equal(15, self.nodes[1].getwalletinfo()['immature_balance']) + + # Send and mine a transaction after activation + myopid = self.nodes[0].z_sendmany(node0_taddr, recipients, 1, Decimal('0')) + txid = wait_and_assert_operationid_status(self.nodes[0], myopid) + assert_equal(147, self.nodes[0].getrawtransaction(txid, 1)['expiryheight']) # height + 1 + 40 + self.nodes[1].generate(1) + self.sync_all() + assert_equal(20, Decimal(self.nodes[0].z_gettotalbalance()['private'])) + + +if __name__ == '__main__': + ShorterBlockTimes().main() diff --git a/qa/rpc-tests/signrawtransactions.py b/qa/rpc-tests/signrawtransactions.py index 51f2eac3e..e6eff05ed 100755 --- a/qa/rpc-tests/signrawtransactions.py +++ b/qa/rpc-tests/signrawtransactions.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index 168c1699b..073e7e86e 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test fee estimation code diff --git a/qa/rpc-tests/spentindex.py b/qa/rpc-tests/spentindex.py new file mode 100755 index 000000000..13a71714f --- /dev/null +++ b/qa/rpc-tests/spentindex.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python +# Copyright (c) 2020 The BitcoinZ Community +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test spentindex generation and fetching +# + +import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException + +from test_framework.util import assert_equal +from test_framework.util import initialize_chain_clean +from test_framework.util import start_nodes, stop_nodes, connect_nodes +from test_framework.util import wait_bitcoinds +from test_framework.util import fail + +from test_framework.mininode import COIN + +class SpentIndexTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 3) + + def setup_network(self): + # -insightexplorer causes spentindex to be enabled (fSpentIndex = true) + + self.nodes = start_nodes(3, self.options.tmpdir, + [['-debug', '-txindex', '-experimentalfeatures', '-insightexplorer']]*3) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + self.nodes[0].generate(105) + self.sync_all() + + chain_height = self.nodes[1].getblockcount() + assert_equal(chain_height, 105) + + # Test getrawtransaction changes and the getspentinfo RPC + + # send coinbase to address addr1 + addr1 = self.nodes[1].getnewaddress() + txid1 = self.nodes[0].sendtoaddress(addr1, 2) + self.sync_all() + block_hash1 = self.nodes[0].generate(1) + self.sync_all() + + # send from addr1 to addr2 + # (the only utxo on node 1 is from address addr1) + addr2 = self.nodes[2].getnewaddress() + txid2 = self.nodes[1].sendtoaddress(addr2, 1) + self.sync_all() + + # addr1 to addr2 transaction is not confirmed, so it has no height + tx2 = self.nodes[2].getrawtransaction(txid2, 1) + assert('height' not in tx2) + + # confirm addr1 to addr2 transaction + block_hash2 = self.nodes[0].generate(1) + self.sync_all() + + # Restart all nodes to ensure index files are saved to disk and recovered + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # Check new fields added to getrawtransaction + tx1 = self.nodes[2].getrawtransaction(txid1, 1) + assert_equal(tx1['vin'][0]['value'], 10) # coinbase + assert_equal(tx1['vin'][0]['valueSat'], 10*COIN) + # we want the non-change (payment) output + vout = filter(lambda o: o['value'] == 2, tx1['vout']) + n = vout[0]['n'] + assert_equal(vout[0]['spentTxId'], txid2) + assert_equal(vout[0]['spentIndex'], 0) + assert_equal(vout[0]['spentHeight'], 107) + assert_equal(tx1['height'], 106) + + tx2 = self.nodes[2].getrawtransaction(txid2, 1) + assert_equal(tx2['vin'][0]['address'], addr1) + assert_equal(tx2['vin'][0]['value'], 2) + assert_equal(tx2['vin'][0]['valueSat'], 2*COIN) + # since this transaction's outputs haven't yet been + # spent, these fields should not be present + assert('spentTxId' not in tx2['vout'][0]) + assert('spentIndex' not in tx2['vout'][0]) + assert('spentHeight' not in tx2['vout'][0]) + assert_equal(tx2['height'], 107) + + # Given a transaction output, getspentinfo() returns a reference + # to the (later, confirmed) transaction that spent that output, + # that is, the transaction that used this output as an input. + spentinfo = self.nodes[2].getspentinfo({'txid': txid1, 'index': n}) + assert_equal(spentinfo['height'], 107) + assert_equal(spentinfo['index'], 0) + assert_equal(spentinfo['txid'], txid2) + + # specifying an output that hasn't been spent should fail + try: + self.nodes[1].getspentinfo({'txid': txid2, 'index': 0}) + fail('getspentinfo should have thrown an exception') + except JSONRPCException, e: + assert_equal(e.error['message'], "Unable to get spent info") + + block_hash_next = self.nodes[0].generate(1) + self.sync_all() + + # Test the getblockdeltas RPC + blockdeltas = self.nodes[2].getblockdeltas(block_hash1[0]) + assert_equal(blockdeltas['confirmations'], 3) + assert_equal(blockdeltas['height'], 106) + assert_equal(blockdeltas['version'], 4) + assert_equal(blockdeltas['hash'], block_hash1[0]) + assert_equal(blockdeltas['nextblockhash'], block_hash2[0]) + deltas = blockdeltas['deltas'] + # block contains two transactions, coinbase, and earlier coinbase to addr1 + assert_equal(len(deltas), 2) + coinbase_tx = deltas[0] + assert_equal(coinbase_tx['index'], 0) + assert_equal(len(coinbase_tx['inputs']), 0) + assert_equal(len(coinbase_tx['outputs']), 2) + assert_equal(coinbase_tx['outputs'][0]['index'], 0) + assert_equal(coinbase_tx['outputs'][1]['index'], 1) + assert_equal(coinbase_tx['outputs'][1]['satoshis'], 2.5*COIN) + + to_a_tx = deltas[1] + assert_equal(to_a_tx['index'], 1) + assert_equal(to_a_tx['txid'], txid1) + + assert_equal(len(to_a_tx['inputs']), 1) + assert_equal(to_a_tx['inputs'][0]['index'], 0) + assert_equal(to_a_tx['inputs'][0]['prevout'], 0) + assert_equal(to_a_tx['inputs'][0]['satoshis'], -10*COIN) + + assert_equal(len(to_a_tx['outputs']), 2) + # find the nonchange output, which is the payment to addr1 + out = filter(lambda o: o['satoshis'] == 2*COIN, to_a_tx['outputs']) + assert_equal(len(out), 1) + assert_equal(out[0]['address'], addr1) + + blockdeltas = self.nodes[2].getblockdeltas(block_hash2[0]) + assert_equal(blockdeltas['confirmations'], 2) + assert_equal(blockdeltas['height'], 107) + assert_equal(blockdeltas['version'], 4) + assert_equal(blockdeltas['hash'], block_hash2[0]) + assert_equal(blockdeltas['previousblockhash'], block_hash1[0]) + assert_equal(blockdeltas['nextblockhash'], block_hash_next[0]) + deltas = blockdeltas['deltas'] + assert_equal(len(deltas), 2) + coinbase_tx = deltas[0] + assert_equal(coinbase_tx['index'], 0) + assert_equal(len(coinbase_tx['inputs']), 0) + assert_equal(len(coinbase_tx['outputs']), 2) + assert_equal(coinbase_tx['outputs'][0]['index'], 0) + assert_equal(coinbase_tx['outputs'][1]['index'], 1) + assert_equal(coinbase_tx['outputs'][1]['satoshis'], 2.5*COIN) + + to_b_tx = deltas[1] + assert_equal(to_b_tx['index'], 1) + assert_equal(to_b_tx['txid'], txid2) + + assert_equal(len(to_b_tx['inputs']), 1) + assert_equal(to_b_tx['inputs'][0]['index'], 0) + assert_equal(to_b_tx['inputs'][0]['prevtxid'], txid1) + assert_equal(to_b_tx['inputs'][0]['satoshis'], -2*COIN) + + assert_equal(len(to_b_tx['outputs']), 2) + # find the nonchange output, which is the payment to addr2 + out = filter(lambda o: o['satoshis'] == 1*COIN, to_b_tx['outputs']) + assert_equal(len(out), 1) + assert_equal(out[0]['address'], addr2) + +if __name__ == '__main__': + SpentIndexTest().main() diff --git a/qa/rpc-tests/sprout_sapling_migration.py b/qa/rpc-tests/sprout_sapling_migration.py index 03e1ccde7..29d045e9f 100755 --- a/qa/rpc-tests/sprout_sapling_migration.py +++ b/qa/rpc-tests/sprout_sapling_migration.py @@ -1,7 +1,8 @@ #!/usr/bin/env python +# Copyright (c) 2020 The BitcoinZ Community # Copyright (c) 2019 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." @@ -14,25 +15,39 @@ SAPLING_ADDR = 'zregtestsapling1ssqj3f3majnl270985gqcdqedd9t4nlttjqskccwevj2v20sc25deqspv3masufnwcdy67cydyy' SAPLING_KEY = 'secret-extended-key-regtest1qv62zt2fqyqqpqrh2qzc08h7gncf4447jh9kvnnnhjg959fkwt7mhw9j8e9at7attx8z6u3953u86vcnsujdc2ckdlcmztjt44x3uxpah5mxtncxd0mqcnz9eq8rghh5m4j44ep5d9702sdvvwawqassulktfegrcp4twxgqdxx4eww3lau0mywuaeztpla2cmvagr5nj98elt45zh6fjznadl6wz52n2uyhdwcm2wlsu8fnxstrk6s4t55t8dy6jkgx5g0cwpchh5qffp8x5' +DISABLED_NO_FUNDS = 0 +ENABLED_NO_FUNDS = 1 +DISABLED_BEFORE_MIGRATION = 2 +ENABLED_BEFORE_MIGRATION = 3 +DURING_MIGRATION = 4 +AFTER_MIGRATION = 5 +ALL_MIGRATION_STATES = [DISABLED_NO_FUNDS, ENABLED_NO_FUNDS, DISABLED_BEFORE_MIGRATION, ENABLED_BEFORE_MIGRATION, DURING_MIGRATION, AFTER_MIGRATION] -def check_migration_status( - node, - enabled, - destination_address, - non_zero_unmigrated_amount, - non_zero_unfinalized_migrated_amount, - non_zero_finalized_migrated_amount, - finalized_migration_transactions, - len_migration_txids -): +def check_migration_status(node, destination_address, migration_state): status = node.z_getmigrationstatus() - assert_equal(enabled, status['enabled']) - assert_equal(destination_address, status['destination_address']) + assert_equal(destination_address, status['destination_address'], "Migration destination address; status=%r" % status) + assert_equal(destination_address, status['destination_address']) assert_true(migration_state in ALL_MIGRATION_STATES, "Unexpected migration state %r" % migration_state) assert_equal(non_zero_unmigrated_amount, Decimal(status['unmigrated_amount']) > Decimal('0.00')) - assert_equal(non_zero_unfinalized_migrated_amount, Decimal(status['unfinalized_migrated_amount']) > Decimal('0')) - assert_equal(non_zero_finalized_migrated_amount, Decimal(status['finalized_migrated_amount']) > Decimal('0')) - assert_equal(finalized_migration_transactions, status['finalized_migration_transactions']) - assert_equal(len_migration_txids, len(status['migration_txids'])) + assert_equal(non_zero_unfinalized_migrated_amount, Decimal(status['unfinalized_migrated_amount']) > Decimal('0')) expected_enabled = migration_state not in [DISABLED_NO_FUNDS, DISABLED_BEFORE_MIGRATION] + assert_equal(non_zero_finalized_migrated_amount, Decimal(status['finalized_migrated_amount']) > Decimal('0')) expected_sprout_funds = migration_state in [DISABLED_BEFORE_MIGRATION, ENABLED_BEFORE_MIGRATION] + assert_equal(finalized_migration_transactions, status['finalized_migration_transactions']) positive_unfinalized_amount = migration_state == DURING_MIGRATION + assert_equal(len_migration_txids, len(status['migration_txids'])) positive_finalized_amount = migration_state == AFTER_MIGRATION + num_migration_txids = 1 if migration_state in [DURING_MIGRATION, AFTER_MIGRATION] else 0 + num_finalized_migration_transactions = 1 if migration_state == AFTER_MIGRATION else 0 + + assert_equal(expected_enabled, status['enabled'], "Expected enabled: %s" % expected_enabled) + # During and after the migration there may be no remaining sprout funds if + # we have randomly picked to migrate them all at once, so we only check + # this field in the one case. + if expected_sprout_funds: + assert_true(Decimal(status['unmigrated_amount']) > Decimal('0.00'), "Expected sprout funds; status=%r" % (status,)) + # For the other two amount fields we know whether or not they will be positive + unfinalized_msg = "Positive unfinalized amount: %s; status=%r " % (positive_unfinalized_amount, status) + assert_equal(positive_unfinalized_amount, Decimal(status['unfinalized_migrated_amount']) > Decimal('0'), unfinalized_msg) + finalized_msg = "Positive finalized amount: %s; status=%r " % (positive_finalized_amount, status) + assert_equal(positive_finalized_amount, Decimal(status['finalized_migrated_amount']) > Decimal('0'), finalized_msg) + assert_equal(num_finalized_migration_transactions, status['finalized_migration_transactions'], "Num finalized transactions; status=%r" % (status,)) + assert_equal(num_migration_txids, len(status['migration_txids']), "Num migration txids; status=%r" % (status,)) class SproutSaplingMigration(BitcoinTestFramework): @@ -61,7 +76,7 @@ def run_migration_test(self, node, sproutAddr, saplingAddr, target_height): assert_equal(102, node.getblockcount() % 500, "Should be at block 102 % 500") assert_equal(node.z_getbalance(sproutAddr), Decimal('10')) assert_equal(node.z_getbalance(saplingAddr), Decimal('0')) - check_migration_status(node, False, saplingAddr, True, False, False, 0, 0) + check_migration_status(node, saplingAddr, DISABLED_BEFORE_MIGRATION) # Migrate node.z_setmigration(True) @@ -71,7 +86,7 @@ def run_migration_test(self, node, sproutAddr, saplingAddr, target_height): # At 494 % 500 we should have no async operations assert_equal(0, len(node.z_getoperationstatus()), "num async operations at 494 % 500") - check_migration_status(node, True, saplingAddr, True, False, False, 0, 0) + check_migration_status(node, saplingAddr, ENABLED_BEFORE_MIGRATION) node.generate(1) self.sync_all() @@ -135,11 +150,11 @@ def run_migration_test(self, node, sproutAddr, saplingAddr, target_height): assert_true(sapling_balance > Decimal('0'), "Should have more Sapling funds") assert_true(sprout_balance + sapling_balance, Decimal('9.9999')) - check_migration_status(node, True, saplingAddr, True, True, False, 0, 1) + check_migration_status(node, saplingAddr, DURING_MIGRATION) # At 10 % 500 the transactions will be considered 'finalized' node.generate(10) self.sync_all() - check_migration_status(node, True, saplingAddr, True, False, True, 1, 1) + check_migration_status(node, saplingAddr, AFTER_MIGRATION) # Check exact migration status amounts to make sure we account for fee status = node.z_getmigrationstatus() assert_equal(sprout_balance, Decimal(status['unmigrated_amount'])) @@ -154,9 +169,9 @@ def send_to_sprout_zaddr(self, tAddr, sproutAddr): def run_test(self): # Check enabling via '-migration' and disabling via rpc - check_migration_status(self.nodes[0], True, SAPLING_ADDR, False, False, False, 0, 0) + check_migration_status(self.nodes[0], SAPLING_ADDR, ENABLED_NO_FUNDS) self.nodes[0].z_setmigration(False) - check_migration_status(self.nodes[0], False, SAPLING_ADDR, False, False, False, 0, 0) + check_migration_status(self.nodes[0], SAPLING_ADDR, DISABLED_NO_FUNDS) # 1. Test using self.nodes[0] which has the parameter print("Running test using '-migrationdestaddress'...") diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index 28b33e286..c3b3e7eb3 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -120,10 +120,12 @@ def _request(self, method, path, postdata): return self._get_response() except Exception as e: # If connection was closed, try again. + # Python 2.7 error message was changed in https://github.com/python/cpython/pull/2825 # Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset. # ConnectionResetError happens on FreeBSD with Python 3.4. # These classes don't exist in Python 2.x, so we can't refer to them directly. - if ((isinstance(e, httplib.BadStatusLine) and e.line == "''") + if ((isinstance(e, httplib.BadStatusLine) + and e.line in ("''", "No status line received - the server has closed the connection")) or e.__class__.__name__ in ('BrokenPipeError', 'ConnectionResetError')): self.__conn.close() self.__conn.request(method, path, postdata, headers) diff --git a/qa/rpc-tests/test_framework/bignum.py b/qa/rpc-tests/test_framework/bignum.py index b0c58ccd4..ddc00cf19 100644 --- a/qa/rpc-tests/test_framework/bignum.py +++ b/qa/rpc-tests/test_framework/bignum.py @@ -5,7 +5,7 @@ # This file is copied from python-bitcoinlib. # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # """Bignum routines""" diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index 1fe2a5dda..e1b4321de 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -1,7 +1,7 @@ # blocktools.py - utilities for manipulating blocks and transactions # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # from mininode import CBlock, CTransaction, CTxIn, CTxOut, COutPoint diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index 7f9a97d68..a6ae9e623 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -1,7 +1,7 @@ #!/usr/bin/env python2 # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # from mininode import CBlock, CTransaction, CInv, NodeConn, NodeConnCB, \ diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 93d4769c1..5e3c25d3d 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1,7 +1,7 @@ # mininode.py - Bitcoin P2P network half-a-node # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # This python code was modified from ArtForz' public domain half-a-node, as # found in the mini-node branch of http://github.com/jgarzik/pynode. @@ -41,10 +41,21 @@ BIP0031_VERSION = 60000 SPROUT_PROTO_VERSION = 170002 # past bip-31 for ping/pong +OVERWINTER_PROTO_VERSION = 170003 SAPLING_PROTO_VERSION = 170006 +BLOSSOM_PROTO_VERSION = 170008 + MY_SUBVERSION = "/python-mininode-tester:0.0.1/" +SPROUT_VERSION_GROUP_ID = 0x00000000 OVERWINTER_VERSION_GROUP_ID = 0x03C48270 +SAPLING_VERSION_GROUP_ID = 0x892F2085 +# No transaction format change in Blossom. + +SPROUT_BRANCH_ID = 0x00000000 +OVERWINTER_BRANCH_ID = 0x5BA81B19 +SAPLING_BRANCH_ID = 0x76B809BB +BLOSSOM_BRANCH_ID = 0x2BB40E60 MAX_INV_SZ = 50000 @@ -574,7 +585,7 @@ def __init__(self, tx=None): self.vout = [] self.nLockTime = 0 self.nExpiryHeight = 0 - self.vjoinsplit = [] + self.vJoinSplit = [] self.joinSplitPubKey = None self.joinSplitSig = None self.sha256 = None @@ -587,7 +598,7 @@ def __init__(self, tx=None): self.vout = copy.deepcopy(tx.vout) self.nLockTime = tx.nLockTime self.nExpiryHeight = tx.nExpiryHeight - self.vjoinsplit = copy.deepcopy(tx.vjoinsplit) + self.vJoinSplit = copy.deepcopy(tx.vJoinSplit) self.joinSplitPubKey = tx.joinSplitPubKey self.joinSplitSig = tx.joinSplitSig self.sha256 = None @@ -611,8 +622,8 @@ def deserialize(self, f): self.nExpiryHeight = struct.unpack("= 2: - self.vjoinsplit = deser_vector(f, JSDescription) - if len(self.vjoinsplit) > 0: + self.vJoinSplit = deser_vector(f, JSDescription) + if len(self.vJoinSplit) > 0: self.joinSplitPubKey = deser_uint256(f) self.joinSplitSig = f.read(64) @@ -635,8 +646,8 @@ def serialize(self): if isOverwinterV3: r += struct.pack("= 2: - r += ser_vector(self.vjoinsplit) - if len(self.vjoinsplit) > 0: + r += ser_vector(self.vJoinSplit) + if len(self.vJoinSplit) > 0: r += ser_uint256(self.joinSplitPubKey) r += self.joinSplitSig return r @@ -663,8 +674,8 @@ def __repr__(self): % (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: + r += " vJoinSplit=%s" % repr(self.vJoinSplit) + if len(self.vJoinSplit) > 0: r += " joinSplitPubKey=%064x joinSplitSig=%064x" \ (self.joinSplitPubKey, self.joinSplitSig) r += ")" diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py index b30a88a4f..25ce069e4 100644 --- a/qa/rpc-tests/test_framework/netutil.py +++ b/qa/rpc-tests/test_framework/netutil.py @@ -1,7 +1,7 @@ #!/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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # Linux network utilities import sys diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index 55a7f8e51..a5afe22a3 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -4,7 +4,7 @@ # This file is modified from python-bitcoinlib. # # Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # """Scripts diff --git a/qa/rpc-tests/test_framework/socks5.py b/qa/rpc-tests/test_framework/socks5.py index 1dbfb98d5..813654e52 100644 --- a/qa/rpc-tests/test_framework/socks5.py +++ b/qa/rpc-tests/test_framework/socks5.py @@ -1,6 +1,6 @@ # Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . ''' Dummy Socks5 server for testing. ''' diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index f5159fd6a..06ba57790 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -1,7 +1,7 @@ #!/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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # Base class for RPC testing diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 27e66c95a..eaabd31e1 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -1,6 +1,6 @@ # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # @@ -57,7 +57,7 @@ def sync_blocks(rpc_connections, wait=1): def sync_mempools(rpc_connections, wait=1): """ Wait until everybody has the same transactions in their memory - pools + pools, and has notified all internal listeners of them """ while True: pool = set(rpc_connections[0].getrawmempool()) @@ -69,6 +69,14 @@ def sync_mempools(rpc_connections, wait=1): break time.sleep(wait) + # Now that the mempools are in sync, wait for the internal + # notifications to finish + while True: + notified = [ x.getmempoolinfo()['fullyNotified'] for x in rpc_connections ] + if notified == [ True ] * len(notified): + break + time.sleep(wait) + bitcoind_processes = {} def initialize_datadir(dirname, n): @@ -354,13 +362,13 @@ def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants): def assert_equal(expected, actual, message=""): if expected != actual: if message: - message = "; %s" % message + message = "; %s" % message raise AssertionError("(left == right)%s\n left: <%s>\n right: <%s>" % (message, str(expected), str(actual))) def assert_true(condition, message = ""): if not condition: raise AssertionError(message) - + def assert_false(condition, message = ""): assert_true(not condition, message) diff --git a/qa/rpc-tests/timestampindex.py b/qa/rpc-tests/timestampindex.py new file mode 100755 index 000000000..c5e18b578 --- /dev/null +++ b/qa/rpc-tests/timestampindex.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# Copyright (c) 2020 The BitcoinZ Community +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +# +# Test timestampindex generation and fetching for insightexplorer + +import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." + +import time + +from test_framework.test_framework import BitcoinTestFramework + +from test_framework.util import ( + assert_equal, + initialize_chain_clean, + start_nodes, + stop_nodes, + connect_nodes, + wait_bitcoinds, +) + + +class TimestampIndexTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 3) + + def setup_network(self): + # -insightexplorer causes spentindex to be enabled (fSpentIndex = true) + + self.nodes = start_nodes( + 3, self.options.tmpdir, + [['-debug', '-txindex', '-experimentalfeatures', '-insightexplorer']]*3) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + blockhashes = [] + print "Mining blocks..." + for _ in range(8): + blockhashes.extend(self.nodes[0].generate(1)) + time.sleep(1) + self.sync_all() + times = [self.nodes[1].getblock(b)['time'] for b in blockhashes] + assert_equal(blockhashes, self.nodes[1].getblockhashes(times[0]+100, 0)) + # test various ranges; the api returns blocks have times LESS THAN + # 'high' (first argument), not less than or equal, hence the +1 + assert_equal(blockhashes[0:8], self.nodes[1].getblockhashes(times[8-1]+1, times[0])) + assert_equal(blockhashes[2:6], self.nodes[1].getblockhashes(times[6-1]+1, times[2])) + assert_equal(blockhashes[5:8], self.nodes[1].getblockhashes(times[8-1]+1, times[5])) + assert_equal(blockhashes[6:7], self.nodes[1].getblockhashes(times[7-1]+1, times[6])) + assert_equal(blockhashes[4:6], self.nodes[1].getblockhashes(times[6-1]+1, times[4])) + assert_equal(blockhashes[1:1], self.nodes[1].getblockhashes(times[1-1]+1, times[1])) + + # Restart all nodes to ensure indices are saved to disk and recovered + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # generating multiple blocks within the same second should + # result in timestamp index entries with unique times + # (not realistic but there is logic to ensure this) + blockhashes = self.nodes[0].generate(10) + self.sync_all() + firsttime = self.nodes[1].getblock(blockhashes[0])['time'] + assert_equal(blockhashes, self.nodes[1].getblockhashes(firsttime+10+1, firsttime)) + + # the api can also return 'logical' times, which is the key of the + # timestamp index (the content being blockhash). Logical times are + # block times when possible, but since keys must be unique, and the + # previous 10 block were generated in much less than 10 seconds, + # each logical time should be one greater than the previous. + results = self.nodes[1].getblockhashes( + firsttime+10+1, firsttime, + {'logicalTimes': True}) + ltimes = [r['logicalts'] for r in results] + assert_equal(ltimes, range(firsttime, firsttime+10)) + + # there's also a flag to exclude orphaned blocks; results should + # be the same in this test + assert_equal( + results, + self.nodes[1].getblockhashes( + firsttime+10+1, firsttime, + {'logicalTimes': True, 'noOrphans': True})) + + +if __name__ == '__main__': + TimestampIndexTest().main() diff --git a/qa/rpc-tests/turnstile.py b/qa/rpc-tests/turnstile.py index 89d680f0b..129a91ee5 100755 --- a/qa/rpc-tests/turnstile.py +++ b/qa/rpc-tests/turnstile.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2019 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test Sprout and Sapling turnstile violations diff --git a/qa/rpc-tests/tx_expiry_helper.py b/qa/rpc-tests/tx_expiry_helper.py index 3831a3a35..36d1b2a4f 100755 --- a/qa/rpc-tests/tx_expiry_helper.py +++ b/qa/rpc-tests/tx_expiry_helper.py @@ -1,6 +1,6 @@ # Copyright (c) 2019 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Common code for testing transaction expiry diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index 6323245ce..da0b2c7be 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test proper accounting with malleable transactions diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index a53898d79..aafc67aed 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." @@ -279,8 +279,8 @@ def run_test (self): assert_equal(mybalance, Decimal('12500.0')) mytxdetails = self.nodes[2].gettransaction(mytxid) - myvjoinsplits = mytxdetails["vjoinsplit"] - assert_equal(0, len(myvjoinsplits)) + myvJoinSplits = mytxdetails["vJoinSplit"] + assert_equal(0, len(myvJoinSplits)) # z_sendmany is expected to fail if tx size breaks limit myzaddr = self.nodes[0].z_getnewaddress('sprout') @@ -375,11 +375,11 @@ def run_test (self): # there should be at least one joinsplit mytxdetails = self.nodes[2].gettransaction(mytxid) - myvjoinsplits = mytxdetails["vjoinsplit"] - assert_greater_than(len(myvjoinsplits), 0) + myvJoinSplits = mytxdetails["vJoinSplit"] + assert_greater_than(len(myvJoinSplits), 0) # the first (probably only) joinsplit should take in all the public value - myjoinsplit = self.nodes[2].getrawtransaction(mytxid, 1)["vjoinsplit"][0] + myjoinsplit = self.nodes[2].getrawtransaction(mytxid, 1)["vJoinSplit"][0] assert_equal(myjoinsplit["vpub_old"], zsendmanynotevalue) assert_equal(myjoinsplit["vpub_new"], 0) assert("onetimePubKey" in myjoinsplit.keys()) diff --git a/qa/rpc-tests/wallet_1941.py b/qa/rpc-tests/wallet_1941.py index 68938c970..4df88b050 100755 --- a/qa/rpc-tests/wallet_1941.py +++ b/qa/rpc-tests/wallet_1941.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2016 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # This is a regression test for #1941. diff --git a/qa/rpc-tests/wallet_addresses.py b/qa/rpc-tests/wallet_addresses.py index ef0e0bde7..c9a6ab7c3 100755 --- a/qa/rpc-tests/wallet_addresses.py +++ b/qa/rpc-tests/wallet_addresses.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_anchorfork.py b/qa/rpc-tests/wallet_anchorfork.py index f136498b1..177f8e490 100755 --- a/qa/rpc-tests/wallet_anchorfork.py +++ b/qa/rpc-tests/wallet_anchorfork.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_changeaddresses.py b/qa/rpc-tests/wallet_changeaddresses.py new file mode 100755 index 000000000..746002734 --- /dev/null +++ b/qa/rpc-tests/wallet_changeaddresses.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# Copyright (c) 2020 The BitcoinZ Community +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + connect_nodes_bi, + get_coinbase_address, + initialize_chain_clean, + start_node, + wait_and_assert_operationid_status, +) + +from decimal import Decimal + +# Test wallet change address behaviour +class WalletChangeAddressesTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory " + self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 2) + + def setup_network(self): + args = [ + '-nuparams=5ba81b19:1', # Overwinter + '-nuparams=76b809bb:1', # Sapling + '-txindex', # Avoid JSONRPC error: No information available about transaction + '-experimentalfeatures', '-zmergetoaddress', + ] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.nodes.append(start_node(1, self.options.tmpdir, args)) + connect_nodes_bi(self.nodes,0,1) + self.is_network_split=False + self.sync_all() + + def run_test(self): + self.nodes[0].generate(110) + + # Obtain some transparent funds + midAddr = self.nodes[0].z_getnewaddress('sapling') + myopid = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), midAddr, 0)['opid'] + wait_and_assert_operationid_status(self.nodes[0], myopid) + self.nodes[1].generate(1) + self.sync_all() + taddrSource = self.nodes[0].getnewaddress() + for _ in range(6): + recipients = [{"address": taddrSource, "amount": Decimal('2')}] + myopid = self.nodes[0].z_sendmany(midAddr, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], myopid) + self.nodes[1].generate(1) + self.sync_all() + + def check_change_taddr_reuse(target): + recipients = [{"address": target, "amount": Decimal('1')}] + + # Send funds to recipient address twice + myopid = self.nodes[0].z_sendmany(taddrSource, recipients, 1, 0) + txid1 = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.nodes[1].generate(1) + self.sync_all() + myopid = self.nodes[0].z_sendmany(taddrSource, recipients, 1, 0) + txid2 = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.nodes[1].generate(1) + self.sync_all() + + # Verify that the two transactions used different change addresses + tx1 = self.nodes[0].getrawtransaction(txid1, 1) + tx2 = self.nodes[0].getrawtransaction(txid2, 1) + for i in range(len(tx1['vout'])): + tx1OutAddrs = tx1['vout'][i]['scriptPubKey']['addresses'] + tx2OutAddrs = tx2['vout'][i]['scriptPubKey']['addresses'] + if tx1OutAddrs != [target]: + print('Source address: %s' % taddrSource) + print('TX1 change address: %s' % tx1OutAddrs[0]) + print('TX2 change address: %s' % tx2OutAddrs[0]) + assert(tx1OutAddrs != tx2OutAddrs) + + taddr = self.nodes[0].getnewaddress() + saplingAddr = self.nodes[0].z_getnewaddress('sapling') + sproutAddr = self.nodes[0].z_getnewaddress('sprout') + + print + print('Checking z_sendmany(taddr->Sapling)') + check_change_taddr_reuse(saplingAddr) + print + print('Checking z_sendmany(taddr->Sprout)') + check_change_taddr_reuse(sproutAddr) + print + print('Checking z_sendmany(taddr->taddr)') + check_change_taddr_reuse(taddr) + +if __name__ == '__main__': + WalletChangeAddressesTest().main() diff --git a/qa/rpc-tests/wallet_changeindicator.py b/qa/rpc-tests/wallet_changeindicator.py index 0a8c2bdbd..940e31426 100755 --- a/qa/rpc-tests/wallet_changeindicator.py +++ b/qa/rpc-tests/wallet_changeindicator.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_import_export.py b/qa/rpc-tests/wallet_import_export.py index 57f69aee5..e4a6dd6a9 100755 --- a/qa/rpc-tests/wallet_import_export.py +++ b/qa/rpc-tests/wallet_import_export.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_listnotes.py b/qa/rpc-tests/wallet_listnotes.py index ad2d56e1f..9f9b09937 100755 --- a/qa/rpc-tests/wallet_listnotes.py +++ b/qa/rpc-tests/wallet_listnotes.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_listreceived.py b/qa/rpc-tests/wallet_listreceived.py index d5faa3d0a..16b384ab8 100755 --- a/qa/rpc-tests/wallet_listreceived.py +++ b/qa/rpc-tests/wallet_listreceived.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_mergetoaddress.py b/qa/rpc-tests/wallet_mergetoaddress.py deleted file mode 100755 index 3c2f84aa8..000000000 --- a/qa/rpc-tests/wallet_mergetoaddress.py +++ /dev/null @@ -1,368 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2017 The Zcash developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import JSONRPCException -from test_framework.util import assert_equal, initialize_chain_clean, \ - start_node, connect_nodes_bi, sync_blocks, sync_mempools, \ - wait_and_assert_operationid_status - -from decimal import Decimal - -class WalletMergeToAddressTest (BitcoinTestFramework): - - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 4) - - def setup_network(self, split=False): - args = ['-debug=zrpcunsafe', '-experimentalfeatures', '-zmergetoaddress'] - self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, args)) - self.nodes.append(start_node(1, self.options.tmpdir, args)) - args2 = ['-debug=zrpcunsafe', '-experimentalfeatures', '-zmergetoaddress', '-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) - connect_nodes_bi(self.nodes,0,2) - self.is_network_split=False - self.sync_all() - - def run_test (self): - print "Mining blocks..." - - self.nodes[0].generate(1) - do_not_shield_taddr = self.nodes[0].getnewaddress() - - self.nodes[0].generate(4) - walletinfo = self.nodes[0].getwalletinfo() - assert_equal(walletinfo['immature_balance'], 50) - assert_equal(walletinfo['balance'], 0) - self.sync_all() - self.nodes[2].generate(1) - self.nodes[2].getnewaddress() - self.nodes[2].generate(1) - self.nodes[2].getnewaddress() - self.nodes[2].generate(1) - self.sync_all() - self.nodes[1].generate(101) - self.sync_all() - assert_equal(self.nodes[0].getbalance(), 50) - assert_equal(self.nodes[1].getbalance(), 10) - assert_equal(self.nodes[2].getbalance(), 30) - - # Shield the coinbase - myzaddr = self.nodes[0].z_getnewaddress('sprout') - result = self.nodes[0].z_shieldcoinbase("*", myzaddr, 0) - wait_and_assert_operationid_status(self.nodes[0], result['opid']) - self.sync_all() - self.nodes[1].generate(1) - self.sync_all() - - # Prepare some UTXOs and notes for merging - mytaddr = self.nodes[0].getnewaddress() - mytaddr2 = self.nodes[0].getnewaddress() - mytaddr3 = self.nodes[0].getnewaddress() - result = self.nodes[0].z_sendmany(myzaddr, [ - {'address': do_not_shield_taddr, 'amount': 10}, - {'address': mytaddr, 'amount': 10}, - {'address': mytaddr2, 'amount': 10}, - {'address': mytaddr3, 'amount': 10}, - ], 1, 0) - wait_and_assert_operationid_status(self.nodes[0], result) - self.sync_all() - self.nodes[1].generate(1) - self.sync_all() - - # Merging will fail because from arguments need to be in an array - try: - self.nodes[0].z_mergetoaddress("*", myzaddr) - assert(False) - except JSONRPCException,e: - errorString = e.error['message'] - assert_equal("JSON value is not an array as expected" in errorString, True) - - # Merging will fail when trying to spend from watch-only address - self.nodes[2].importaddress(mytaddr) - try: - self.nodes[2].z_mergetoaddress([mytaddr], myzaddr) - assert(False) - except JSONRPCException,e: - errorString = e.error['message'] - assert_equal("Could not find any funds to merge" in errorString, True) - - # Merging will fail because fee is negative - try: - self.nodes[0].z_mergetoaddress(["*"], myzaddr, -1) - assert(False) - except JSONRPCException,e: - errorString = e.error['message'] - assert_equal("Amount out of range" in errorString, True) - - # Merging will fail because fee is larger than MAX_MONEY - try: - self.nodes[0].z_mergetoaddress(["*"], myzaddr, Decimal('21000000.00000001')) - assert(False) - except JSONRPCException,e: - errorString = e.error['message'] - assert_equal("Amount out of range" in errorString, True) - - # Merging will fail because fee is larger than sum of UTXOs - try: - self.nodes[0].z_mergetoaddress(["*"], myzaddr, 999) - assert(False) - except JSONRPCException,e: - errorString = e.error['message'] - assert_equal("Insufficient funds" in errorString, True) - - # Merging will fail because transparent limit parameter must be at least 0 - try: - self.nodes[0].z_mergetoaddress(["*"], myzaddr, Decimal('0.001'), -1) - assert(False) - except JSONRPCException,e: - errorString = e.error['message'] - assert_equal("Limit on maximum number of UTXOs cannot be negative" in errorString, True) - - # Merging will fail because transparent limit parameter is absurdly large - try: - self.nodes[0].z_mergetoaddress(["*"], myzaddr, Decimal('0.001'), 99999999999999) - assert(False) - except JSONRPCException,e: - errorString = e.error['message'] - assert_equal("JSON integer out of range" in errorString, True) - - # Merging will fail because shielded limit parameter must be at least 0 - try: - self.nodes[0].z_mergetoaddress(["*"], myzaddr, Decimal('0.001'), 50, -1) - assert(False) - except JSONRPCException,e: - errorString = e.error['message'] - assert_equal("Limit on maximum number of notes cannot be negative" in errorString, True) - - # Merging will fail because shielded limit parameter is absurdly large - try: - self.nodes[0].z_mergetoaddress(["*"], myzaddr, Decimal('0.001'), 50, 99999999999999) - assert(False) - except JSONRPCException,e: - errorString = e.error['message'] - assert_equal("JSON integer out of range" in errorString, True) - - # Merging will fail for this specific case where it would spend a fee and do nothing - try: - self.nodes[0].z_mergetoaddress([mytaddr], mytaddr) - assert(False) - except JSONRPCException,e: - errorString = e.error['message'] - assert_equal("Destination address is also the only source address, and all its funds are already merged" in errorString, True) - - # Merge UTXOs from node 0 of value 30, standard fee of 0.00010000 - result = self.nodes[0].z_mergetoaddress([mytaddr, mytaddr2, mytaddr3], myzaddr) - wait_and_assert_operationid_status(self.nodes[0], result['opid']) - self.sync_all() - self.nodes[1].generate(1) - self.sync_all() - - # Confirm balances and that do_not_shield_taddr containing funds of 10 was left alone - assert_equal(self.nodes[0].getbalance(), 10) - assert_equal(self.nodes[0].z_getbalance(do_not_shield_taddr), Decimal('10.0')) - assert_equal(self.nodes[0].z_getbalance(myzaddr), Decimal('39.99990000')) - assert_equal(self.nodes[1].getbalance(), 40) - assert_equal(self.nodes[2].getbalance(), 30) - - # Shield all notes to another z-addr - myzaddr2 = self.nodes[0].z_getnewaddress('sprout') - result = self.nodes[0].z_mergetoaddress(["ANY_ZADDR"], myzaddr2, 0) - assert_equal(result["mergingUTXOs"], Decimal('0')) - assert_equal(result["remainingUTXOs"], Decimal('0')) - assert_equal(result["mergingNotes"], Decimal('2')) - assert_equal(result["remainingNotes"], Decimal('0')) - wait_and_assert_operationid_status(self.nodes[0], result['opid']) - self.sync_all() - blockhash = self.nodes[1].generate(1) - self.sync_all() - - assert_equal(len(self.nodes[0].getblock(blockhash[0])['tx']), 2) - assert_equal(self.nodes[0].z_getbalance(myzaddr), 0) - assert_equal(self.nodes[0].z_getbalance(myzaddr2), Decimal('39.99990000')) - - # Shield coinbase UTXOs from any node 2 taddr, and set fee to 0 - result = self.nodes[2].z_shieldcoinbase("*", myzaddr, 0) - wait_and_assert_operationid_status(self.nodes[2], result['opid']) - self.sync_all() - self.nodes[1].generate(1) - self.sync_all() - - assert_equal(self.nodes[0].getbalance(), 10) - assert_equal(self.nodes[0].z_getbalance(myzaddr), Decimal('30')) - assert_equal(self.nodes[0].z_getbalance(myzaddr2), Decimal('39.99990000')) - assert_equal(self.nodes[1].getbalance(), 60) - assert_equal(self.nodes[2].getbalance(), 0) - - # Merge all notes from node 0 into a node 0 taddr, and set fee to 0 - result = self.nodes[0].z_mergetoaddress(["ANY_ZADDR"], mytaddr, 0) - wait_and_assert_operationid_status(self.nodes[0], result['opid']) - self.sync_all() - self.nodes[1].generate(1) - self.sync_all() - - assert_equal(self.nodes[0].getbalance(), Decimal('79.99990000')) - assert_equal(self.nodes[0].z_getbalance(do_not_shield_taddr), Decimal('10.0')) - assert_equal(self.nodes[0].z_getbalance(mytaddr), Decimal('69.99990000')) - assert_equal(self.nodes[0].z_getbalance(myzaddr), 0) - assert_equal(self.nodes[0].z_getbalance(myzaddr2), 0) - assert_equal(self.nodes[1].getbalance(), 70) - assert_equal(self.nodes[2].getbalance(), 0) - - # Merge all node 0 UTXOs together into a node 1 taddr, and set fee to 0 - self.nodes[1].getnewaddress() # Ensure we have an empty address - n1taddr = self.nodes[1].getnewaddress() - result = self.nodes[0].z_mergetoaddress(["ANY_TADDR"], n1taddr, 0) - wait_and_assert_operationid_status(self.nodes[0], result['opid']) - self.sync_all() - self.nodes[1].generate(1) - self.sync_all() - - assert_equal(self.nodes[0].getbalance(), 0) - assert_equal(self.nodes[0].z_getbalance(do_not_shield_taddr), 0) - assert_equal(self.nodes[0].z_getbalance(mytaddr), 0) - assert_equal(self.nodes[0].z_getbalance(myzaddr), 0) - assert_equal(self.nodes[1].getbalance(), Decimal('159.99990000')) - assert_equal(self.nodes[1].z_getbalance(n1taddr), Decimal('79.99990000')) - assert_equal(self.nodes[2].getbalance(), 0) - - # Generate 800 regular UTXOs on node 0, and 20 regular UTXOs on node 2 - mytaddr = self.nodes[0].getnewaddress() - n2taddr = self.nodes[2].getnewaddress() - self.nodes[1].generate(1000) - self.sync_all() - for i in range(800): - self.nodes[1].sendtoaddress(mytaddr, 1) - for i in range(20): - self.nodes[1].sendtoaddress(n2taddr, 1) - self.nodes[1].generate(1) - self.sync_all() - - # Merging the 800 UTXOs will occur over two transactions, since max tx size is 100,000 bytes. - # We don't verify mergingTransparentValue as UTXOs are not selected in any specific order, so value can change on each test run. - # We set an unrealistically high limit parameter of 99999, to verify that max tx size will constrain the number of UTXOs. - result = self.nodes[0].z_mergetoaddress([mytaddr], myzaddr, 0, 99999) - assert_equal(result["mergingUTXOs"], Decimal('662')) - assert_equal(result["remainingUTXOs"], Decimal('138')) - assert_equal(result["mergingNotes"], Decimal('0')) - assert_equal(result["mergingShieldedValue"], Decimal('0')) - assert_equal(result["remainingNotes"], Decimal('0')) - assert_equal(result["remainingShieldedValue"], Decimal('0')) - remainingTransparentValue = result["remainingTransparentValue"] - opid1 = result['opid'] - - # Verify that UTXOs are locked (not available for selection) by queuing up another merging operation - result = self.nodes[0].z_mergetoaddress([mytaddr], myzaddr, 0, 0) - assert_equal(result["mergingUTXOs"], Decimal('138')) - assert_equal(result["mergingTransparentValue"], Decimal(remainingTransparentValue)) - assert_equal(result["remainingUTXOs"], Decimal('0')) - assert_equal(result["remainingTransparentValue"], Decimal('0')) - assert_equal(result["mergingNotes"], Decimal('0')) - assert_equal(result["mergingShieldedValue"], Decimal('0')) - assert_equal(result["remainingNotes"], Decimal('0')) - assert_equal(result["remainingShieldedValue"], Decimal('0')) - 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) - - # sync_all() invokes sync_mempool() but node 2's mempool limit will cause tx1 and tx2 to be rejected. - # So instead, we sync on blocks and mempool for node 0 and node 1, and after a new block is generated - # which mines tx1 and tx2, all nodes will have an empty mempool which can then be synced. - sync_blocks(self.nodes[:2]) - sync_mempools(self.nodes[:2]) - # Generate enough blocks to ensure all transactions are mined - while self.nodes[1].getmempoolinfo()['size'] > 0: - 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. - result = self.nodes[2].z_mergetoaddress([n2taddr], myzaddr, Decimal('0.0001'), 0) - assert_equal(result["mergingUTXOs"], Decimal('7')) - assert_equal(result["remainingUTXOs"], Decimal('13')) - assert_equal(result["mergingNotes"], Decimal('0')) - assert_equal(result["remainingNotes"], Decimal('0')) - 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 - mytaddr = self.nodes[0].getnewaddress() - for i in range(100): - self.nodes[1].sendtoaddress(mytaddr, 1) - self.nodes[1].generate(1) - self.sync_all() - result = self.nodes[0].z_mergetoaddress([mytaddr], myzaddr, Decimal('0.0001')) - assert_equal(result["mergingUTXOs"], Decimal('50')) - assert_equal(result["remainingUTXOs"], Decimal('50')) - assert_equal(result["mergingNotes"], Decimal('0')) - # Remaining notes are only counted if we are trying to merge any notes - assert_equal(result["remainingNotes"], Decimal('0')) - wait_and_assert_operationid_status(self.nodes[0], result['opid']) - - # Verify maximum number of UTXOs which node 0 can shield can be set by the limit parameter - result = self.nodes[0].z_mergetoaddress([mytaddr], myzaddr, Decimal('0.0001'), 33) - assert_equal(result["mergingUTXOs"], Decimal('33')) - assert_equal(result["remainingUTXOs"], Decimal('17')) - assert_equal(result["mergingNotes"], Decimal('0')) - # Remaining notes are only counted if we are trying to merge any notes - assert_equal(result["remainingNotes"], Decimal('0')) - wait_and_assert_operationid_status(self.nodes[0], result['opid']) - # Don't sync node 2 which rejects the tx due to its mempooltxinputlimit - sync_blocks(self.nodes[:2]) - sync_mempools(self.nodes[:2]) - self.nodes[1].generate(1) - self.sync_all() - - # Verify maximum number of notes which node 0 can shield can be set by the limit parameter - # Also check that we can set off a second merge before the first one is complete - - # myzaddr has 5 notes at this point - result1 = self.nodes[0].z_mergetoaddress([myzaddr], myzaddr, 0.0001, 50, 2) - result2 = self.nodes[0].z_mergetoaddress([myzaddr], myzaddr, 0.0001, 50, 2) - - # First merge should select from all notes - assert_equal(result1["mergingUTXOs"], Decimal('0')) - # Remaining UTXOs are only counted if we are trying to merge any UTXOs - assert_equal(result1["remainingUTXOs"], Decimal('0')) - assert_equal(result1["mergingNotes"], Decimal('2')) - assert_equal(result1["remainingNotes"], Decimal('3')) - - # Second merge should ignore locked notes - assert_equal(result2["mergingUTXOs"], Decimal('0')) - assert_equal(result2["remainingUTXOs"], Decimal('0')) - assert_equal(result2["mergingNotes"], Decimal('2')) - assert_equal(result2["remainingNotes"], Decimal('1')) - wait_and_assert_operationid_status(self.nodes[0], result1['opid']) - wait_and_assert_operationid_status(self.nodes[0], result2['opid']) - - self.sync_all() - self.nodes[1].generate(1) - self.sync_all() - - # Shield both UTXOs and notes to a z-addr - result = self.nodes[0].z_mergetoaddress(["*"], myzaddr, 0, 10, 2) - assert_equal(result["mergingUTXOs"], Decimal('10')) - assert_equal(result["remainingUTXOs"], Decimal('7')) - assert_equal(result["mergingNotes"], Decimal('2')) - assert_equal(result["remainingNotes"], Decimal('1')) - wait_and_assert_operationid_status(self.nodes[0], result['opid']) - # Don't sync node 2 which rejects the tx due to its mempooltxinputlimit - sync_blocks(self.nodes[:2]) - sync_mempools(self.nodes[:2]) - self.nodes[1].generate(1) - self.sync_all() - -if __name__ == '__main__': - WalletMergeToAddressTest().main() diff --git a/qa/rpc-tests/wallet_nullifiers.py b/qa/rpc-tests/wallet_nullifiers.py index 832e652c4..99d433585 100755 --- a/qa/rpc-tests/wallet_nullifiers.py +++ b/qa/rpc-tests/wallet_nullifiers.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2016 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_overwintertx.py b/qa/rpc-tests/wallet_overwintertx.py index c24145aba..8915789bb 100755 --- a/qa/rpc-tests/wallet_overwintertx.py +++ b/qa/rpc-tests/wallet_overwintertx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_persistence.py b/qa/rpc-tests/wallet_persistence.py index 72db7c48b..ed34f416b 100755 --- a/qa/rpc-tests/wallet_persistence.py +++ b/qa/rpc-tests/wallet_persistence.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_protectcoinbase.py b/qa/rpc-tests/wallet_protectcoinbase.py index 72541dc52..e7acb0acf 100755 --- a/qa/rpc-tests/wallet_protectcoinbase.py +++ b/qa/rpc-tests/wallet_protectcoinbase.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2016 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_sapling.py b/qa/rpc-tests/wallet_sapling.py index 6fe11e5ec..fed4fe256 100755 --- a/qa/rpc-tests/wallet_sapling.py +++ b/qa/rpc-tests/wallet_sapling.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_shieldcoinbase.py b/qa/rpc-tests/wallet_shieldcoinbase.py index e6ee0e029..5e906adf5 100755 --- a/qa/rpc-tests/wallet_shieldcoinbase.py +++ b/qa/rpc-tests/wallet_shieldcoinbase.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2017 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/wallet_treestate.py b/qa/rpc-tests/wallet_treestate.py index 7dba7cf78..c3d81df22 100755 --- a/qa/rpc-tests/wallet_treestate.py +++ b/qa/rpc-tests/wallet_treestate.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2016 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index 029514dba..ee8ce6f6d 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . """ Exercise the wallet backup code. Ported from walletbackup.sh. diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py index cba7f016f..e9acb51c0 100755 --- a/qa/rpc-tests/zapwallettxes.py +++ b/qa/rpc-tests/zapwallettxes.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # 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. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/zkey_import_export.py b/qa/rpc-tests/zkey_import_export.py index 4a2208221..b0311e16b 100755 --- a/qa/rpc-tests/zkey_import_export.py +++ b/qa/rpc-tests/zkey_import_export.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2017 The Zcash developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index 38ed8e9b2..69b754240 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . # # Test ZMQ interface diff --git a/responsible_disclosure.md b/responsible_disclosure.md index 1f3c9401b..e79ed08d8 100644 --- a/responsible_disclosure.md +++ b/responsible_disclosure.md @@ -41,25 +41,24 @@ CDHCrwSovQRMHtoOWZijBNobO2y1d0FkUpzNlNw44Ssw0Vo= ## Sending Disclosures -In the case where we become aware of security issues affecting other projects that has never affected Zcash, our intention is to inform those projects of security issues on a best effort basis. +In the case where we become aware of security issues affecting other projects that has never affected Bitcoinz, our intention is to inform those projects of security issues on a best effort basis. -In the case where we fix a security issue in Zcash that also affects the following neighboring projects, our intention is to engage in responsible disclosures with them as described in https://github.com/RD-Crypto-Spec/Responsible-Disclosure, subject to the deviations described in the section at the bottom of this document. +In the case where we fix a security issue in Bitcoinz that also affects the following neighboring projects, our intention is to engage in responsible disclosures with them as described in https://github.com/RD-Crypto-Spec/Responsible-Disclosure, subject to the deviations described in the section at the bottom of this document. ## Bilateral Responsible Disclosure Agreements We have set up agreements with the following neighboring projects to share vulnerability information, subject to the deviations described in the next section. -Specifically, we have agreed to engage in responsible disclosures for security issues affecting Zcash technology with the following contacts: +Specifically, we have agreed to engage in responsible disclosures for security issues affecting Bitcoinz technology with the following contacts: -- security@horizen.com via PGP -- ca333@komodoplatform.com via PGP +- Horizen security@horizen.com via PGP +- ca333@komodoplatform.com via PGP - Komodo ca333@komodoplatform.com via PGP +- BitcoinABC https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/DISCLOSURE_POLICY.md ## Deviations from the Standard -Zcash is a technology that provides strong privacy. Notes are encrypted to their destination, and then the monetary base is kept via zero-knowledge proofs intended to only be creatable by the real holder of Zcash. If this fails, and a counterfeiting bug results, that counterfeiting bug might be exploited without any way for blockchain analyzers to identify the perpetrator or which data in the blockchain has been used to exploit the bug. Rollbacks before that point, such as have been executed in some other projects in such cases, are therefore impossible. +Bitcoinz is a technology that provides strong privacy. Notes are encrypted to their destination, and then the monetary base is kept via zero-knowledge proofs intended to only be creatable by the real holder of Bitcoinz. If this fails, and a counterfeiting bug results, that counterfeiting bug might be exploited without any way for blockchain analyzers to identify the perpetrator or which data in the blockchain has been used to exploit the bug. Rollbacks before that point, such as have been executed in some other projects in such cases, are therefore impossible. The standard describes reporters of vulnerabilities including full details of an issue, in order to reproduce it. This is necessary for instance in the case of an external researcher both demonstrating and proving that there really is a security issue, and that security issue really has the impact that they say it has - allowing the development team to accurately prioritize and resolve the issue. In the case of a counterfeiting bug, however, just like in CVE-2019-7167, we might decide not to include those details with our reports to partners ahead of coordinated release, so long as we are sure that they are vulnerable. - - diff --git a/share/genbuild.sh b/share/genbuild.sh index a15cb34e4..5dde844c2 100755 --- a/share/genbuild.sh +++ b/share/genbuild.sh @@ -1,4 +1,11 @@ #!/bin/sh +# Copyright (c) 2017-2020 The BitcoinZ Community +# Copyright (c) 2016-2019 The Zcash developers +# Copyright (c) 2012-2019 The Bitcoin Core developers +# Copyright (c) 2012-2019 Bitcoin Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + if [ $# -gt 1 ]; then cd "$2" fi @@ -18,7 +25,7 @@ SUFFIX="" LAST_COMMIT_DATE="" if [ -e "$(which git 2>/dev/null)" -a "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]; then # clean 'dirty' status of touched files that haven't been modified - git diff >/dev/null 2>/dev/null + git diff >/dev/null 2>/dev/null # if latest commit is tagged and not dirty, then override using the tag name RAWDESC=$(git describe --abbrev=0 2>/dev/null) diff --git a/src/Makefile.am b/src/Makefile.am index b47c8f8cd..1aa04b8de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,10 @@ +# Copyright (c) 2017-2020 The BitcoinZ community +# Copyright (c) 2016-2019 The Zcash developers +# Copyright (c) 2013-2019 The Bitcoin Core developers +# Copyright (c) 2013-2019 Bitcoin Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + DIST_SUBDIRS = secp256k1 univalue AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(SAN_LDFLAGS) $(HARDENED_LDFLAGS) @@ -216,6 +223,7 @@ BITCOIN_CORE_H = \ utiltime.h \ validationinterface.h \ version.h \ + wallet/asyncrpcoperation_common.h \ wallet/asyncrpcoperation_mergetoaddress.h \ wallet/asyncrpcoperation_saplingmigration.h \ wallet/asyncrpcoperation_sendmany.h \ @@ -306,6 +314,7 @@ libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_wallet_a_SOURCES = \ zcbenchmarks.cpp \ zcbenchmarks.h \ + wallet/asyncrpcoperation_common.cpp \ wallet/asyncrpcoperation_mergetoaddress.cpp \ wallet/asyncrpcoperation_saplingmigration.cpp \ wallet/asyncrpcoperation_sendmany.cpp \ @@ -367,6 +376,7 @@ libbitcoin_common_a_SOURCES = \ chainparams.cpp \ coins.cpp \ compressor.cpp \ + consensus/params.cpp \ consensus/upgrades.cpp \ core_read.cpp \ core_write.cpp \ diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index 26d57b54f..c25cb4136 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -1,3 +1,10 @@ +# Copyright (c) 2017-2020 The BitcoinZ community +# Copyright (c) 2016-2019 The Zcash developers +# Copyright (c) 2013-2019 The Bitcoin Core developers +# Copyright (c) 2013-2019 Bitcoin Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + TESTS += zcash-gtest noinst_PROGRAMS += zcash-gtest diff --git a/src/addressindex.h b/src/addressindex.h index e83c9fc2f..1cbd30001 100644 --- a/src/addressindex.h +++ b/src/addressindex.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_ADDRESSINDEX_H #define BITCOIN_ADDRESSINDEX_H @@ -222,4 +222,66 @@ struct CAddressIndexIteratorHeightKey { } }; +struct CMempoolAddressDelta +{ + int64_t time; + CAmount amount; + uint256 prevhash; + unsigned int prevout; + + CMempoolAddressDelta(int64_t t, CAmount a, uint256 hash, unsigned int out) { + time = t; + amount = a; + prevhash = hash; + prevout = out; + } + + CMempoolAddressDelta(int64_t t, CAmount a) { + time = t; + amount = a; + prevhash.SetNull(); + prevout = 0; + } +}; + +struct CMempoolAddressDeltaKey +{ + int type; + uint160 addressBytes; + uint256 txhash; + unsigned int index; + int spending; + + CMempoolAddressDeltaKey(int addressType, uint160 addressHash, uint256 hash, unsigned int i, int s) { + type = addressType; + addressBytes = addressHash; + txhash = hash; + index = i; + spending = s; + } + + CMempoolAddressDeltaKey(int addressType, uint160 addressHash) { + type = addressType; + addressBytes = addressHash; + txhash.SetNull(); + index = 0; + spending = 0; + } +}; + +struct CMempoolAddressDeltaKeyCompare +{ + bool operator()(const CMempoolAddressDeltaKey& a, const CMempoolAddressDeltaKey& b) const { + if (a.type != b.type) + return a.type < b.type; + if (a.addressBytes != b.addressBytes) + return a.addressBytes < b.addressBytes; + if (a.txhash != b.txhash) + return a.txhash < b.txhash; + if (a.index != b.index) + return a.index < b.index; + return a.spending < b.spending; + } +}; + #endif // BITCOIN_ADDRESSINDEX_H diff --git a/src/addrman.cpp b/src/addrman.cpp index c4a2e6e80..5ae0f1734 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012 Pieter Wuille // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "addrman.h" diff --git a/src/addrman.h b/src/addrman.h index 5c77a4fdb..bee1bd9f5 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -1,6 +1,6 @@ // Copyright (c) 2012 Pieter Wuille // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_ADDRMAN_H #define BITCOIN_ADDRMAN_H diff --git a/src/alert.cpp b/src/alert.cpp index ea9cbad21..d7668453d 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "alert.h" diff --git a/src/alert.h b/src/alert.h index 4e3b88775..bca2f8de1 100644 --- a/src/alert.h +++ b/src/alert.h @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_ALERT_H #define BITCOIN_ALERT_H diff --git a/src/amount.cpp b/src/amount.cpp index e9e8c3b5d..dd799c85e 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "amount.h" diff --git a/src/amount.h b/src/amount.h index 1eca3854e..fb1f9e2eb 100644 --- a/src/amount.h +++ b/src/amount.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_AMOUNT_H #define BITCOIN_AMOUNT_H diff --git a/src/amqp/amqpabstractnotifier.cpp b/src/amqp/amqpabstractnotifier.cpp index 57686ef1d..30481b89d 100644 --- a/src/amqp/amqpabstractnotifier.cpp +++ b/src/amqp/amqpabstractnotifier.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "amqpabstractnotifier.h" #include "util.h" diff --git a/src/amqp/amqpabstractnotifier.h b/src/amqp/amqpabstractnotifier.h index c993a2b3e..f68109612 100644 --- a/src/amqp/amqpabstractnotifier.h +++ b/src/amqp/amqpabstractnotifier.h @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H #define ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H diff --git a/src/amqp/amqpconfig.h b/src/amqp/amqpconfig.h index dcc5f7709..8b2fd6a88 100644 --- a/src/amqp/amqpconfig.h +++ b/src/amqp/amqpconfig.h @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_AMQP_AMQPCONFIG_H #define ZCASH_AMQP_AMQPCONFIG_H diff --git a/src/amqp/amqpnotificationinterface.cpp b/src/amqp/amqpnotificationinterface.cpp index 66f5398ca..0dfae00b9 100644 --- a/src/amqp/amqpnotificationinterface.cpp +++ b/src/amqp/amqpnotificationinterface.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "amqpnotificationinterface.h" #include "amqppublishnotifier.h" diff --git a/src/amqp/amqpnotificationinterface.h b/src/amqp/amqpnotificationinterface.h index 0c07ce235..77495a85c 100644 --- a/src/amqp/amqpnotificationinterface.h +++ b/src/amqp/amqpnotificationinterface.h @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H #define ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H diff --git a/src/amqp/amqppublishnotifier.cpp b/src/amqp/amqppublishnotifier.cpp index 589eb151f..227ca11d5 100644 --- a/src/amqp/amqppublishnotifier.cpp +++ b/src/amqp/amqppublishnotifier.cpp @@ -1,8 +1,9 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "amqppublishnotifier.h" +#include "chainparams.h" #include "main.h" #include "util.h" @@ -95,7 +96,7 @@ void AMQPAbstractPublishNotifier::Shutdown() bool AMQPAbstractPublishNotifier::SendMessage(const char *command, const void* data, size_t size) { - try { + try { proton::binary content; const char *p = (const char *)data; content.assign(p, p + size); @@ -152,11 +153,12 @@ bool AMQPPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { LogPrint("amqp", "amqp: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); + const Consensus::Params& consensusParams = Params().GetConsensus(); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); { LOCK(cs_main); CBlock block; - if(!ReadBlockFromDisk(block, pindex)) { + if(!ReadBlockFromDisk(block, pindex, consensusParams)) { LogPrint("amqp", "amqp: Can't read block from disk"); return false; } diff --git a/src/amqp/amqppublishnotifier.h b/src/amqp/amqppublishnotifier.h index 08b3aba08..1d89829b6 100644 --- a/src/amqp/amqppublishnotifier.h +++ b/src/amqp/amqppublishnotifier.h @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H #define ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H diff --git a/src/amqp/amqpsender.h b/src/amqp/amqpsender.h index 7fa85d89c..eb365d3ec 100644 --- a/src/amqp/amqpsender.h +++ b/src/amqp/amqpsender.h @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_AMQP_AMQPSENDER_H #define ZCASH_AMQP_AMQPSENDER_H diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index 2e6136357..6c2f8dbea 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "arith_uint256.h" @@ -173,9 +173,10 @@ unsigned int base_uint::bits() const { for (int pos = WIDTH - 1; pos >= 0; pos--) { if (pn[pos]) { - for (int bits = 31; bits > 0; bits--) { - if (pn[pos] & 1 << bits) + for (size_t bits = 31; bits > 0; bits--) { + if (pn[pos] & (1U << bits)) { return 32 * pos + bits + 1; + } } return 32 * pos + 1; } diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 103c78bb8..833d41ef2 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_ARITH_UINT256_H #define BITCOIN_ARITH_UINT256_H diff --git a/src/asyncrpcoperation.cpp b/src/asyncrpcoperation.cpp index ff5c4cb9f..20186b63e 100644 --- a/src/asyncrpcoperation.cpp +++ b/src/asyncrpcoperation.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "asyncrpcoperation.h" diff --git a/src/asyncrpcoperation.h b/src/asyncrpcoperation.h index 2b821e256..a3bc5bf0b 100644 --- a/src/asyncrpcoperation.h +++ b/src/asyncrpcoperation.h @@ -1,6 +1,6 @@ // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ASYNCRPCOPERATION_H diff --git a/src/asyncrpcqueue.cpp b/src/asyncrpcqueue.cpp index afe6d4bef..e03244945 100644 --- a/src/asyncrpcqueue.cpp +++ b/src/asyncrpcqueue.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "asyncrpcqueue.h" diff --git a/src/asyncrpcqueue.h b/src/asyncrpcqueue.h index 1a099a263..9956405ed 100644 --- a/src/asyncrpcqueue.h +++ b/src/asyncrpcqueue.h @@ -1,6 +1,6 @@ // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ASYNCRPCQUEUE_H #define ASYNCRPCQUEUE_H diff --git a/src/base58.cpp b/src/base58.cpp index 137ce2c9e..3e2f18b40 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "base58.h" diff --git a/src/base58.h b/src/base58.h index 3c926fca0..f29c37556 100644 --- a/src/base58.h +++ b/src/base58.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . /** * Why base-58 instead of standard base-64 encoding? diff --git a/src/bech32.cpp b/src/bech32.cpp index 78c35b976..8910d0345 100644 --- a/src/bech32.cpp +++ b/src/bech32.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "bech32.h" diff --git a/src/bech32.h b/src/bech32.h index 2e2823e97..eecc6e29f 100644 --- a/src/bech32.h +++ b/src/bech32.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . // Bech32 is a string encoding format used in newer address types. // The output consists of a human-readable part (alphanumeric), a diff --git a/src/bitcoin-cli-res.rc b/src/bitcoin-cli-res.rc index 113ee91fa..1291a42cc 100644 --- a/src/bitcoin-cli-res.rc +++ b/src/bitcoin-cli-res.rc @@ -21,7 +21,7 @@ BEGIN VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoinz-cli" VALUE "LegalCopyright", COPYRIGHT_STR - VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or https://www.opensource.org/licenses/mit-license.php ." VALUE "OriginalFilename", "bitcoinz-cli.exe" VALUE "ProductName", "bitcoinz-cli" VALUE "ProductVersion", VER_PRODUCTVERSION_STR diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 1ae29aaf7..4336da3e9 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "chainparamsbase.h" #include "clientversion.h" diff --git a/src/bitcoin-tx-res.rc b/src/bitcoin-tx-res.rc index 39305e28d..03a27bfda 100644 --- a/src/bitcoin-tx-res.rc +++ b/src/bitcoin-tx-res.rc @@ -21,7 +21,7 @@ BEGIN VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoinz-tx" VALUE "LegalCopyright", COPYRIGHT_STR - VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or https://www.opensource.org/licenses/mit-license.php ." VALUE "OriginalFilename", "bitcoinz-tx.exe" VALUE "ProductName", "bitcoinz-tx" VALUE "ProductVersion", VER_PRODUCTVERSION_STR diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 1fcd9a961..73f8f4bd7 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "clientversion.h" #include "coins.h" diff --git a/src/bitcoind-res.rc b/src/bitcoind-res.rc index 079b7d885..802dc45c7 100644 --- a/src/bitcoind-res.rc +++ b/src/bitcoind-res.rc @@ -21,7 +21,7 @@ BEGIN VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoinzd" VALUE "LegalCopyright", COPYRIGHT_STR - VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or https://www.opensource.org/licenses/mit-license.php ." VALUE "OriginalFilename", "bitcoinzd.exe" VALUE "ProductName", "bitcoinzd" VALUE "ProductVersion", VER_PRODUCTVERSION_STR diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 097a29ee3..c89256da0 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "clientversion.h" #include "rpc/server.h" diff --git a/src/bloom.cpp b/src/bloom.cpp index de8720659..49dc5da69 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "bloom.h" diff --git a/src/bloom.h b/src/bloom.h index df5c30b1e..009436104 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_BLOOM_H #define BITCOIN_BLOOM_H diff --git a/src/chain.cpp b/src/chain.cpp index 39520cc8f..35013969f 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "chain.h" diff --git a/src/chain.h b/src/chain.h index a532c8564..7512b06b4 100644 --- a/src/chain.h +++ b/src/chain.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CHAIN_H #define BITCOIN_CHAIN_H @@ -14,11 +14,63 @@ #include -#include - static const int SPROUT_VALUE_VERSION = 1001400; static const int SAPLING_VALUE_VERSION = 1010100; +class CBlockFileInfo +{ +public: + unsigned int nBlocks; //!< number of blocks stored in file + unsigned int nSize; //!< number of used bytes of block file + unsigned int nUndoSize; //!< number of used bytes in the undo file + unsigned int nHeightFirst; //!< lowest height of block in file + unsigned int nHeightLast; //!< highest height of block in file + uint64_t nTimeFirst; //!< earliest time of block in file + uint64_t nTimeLast; //!< latest time of block in file + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(VARINT(nBlocks)); + READWRITE(VARINT(nSize)); + READWRITE(VARINT(nUndoSize)); + READWRITE(VARINT(nHeightFirst)); + READWRITE(VARINT(nHeightLast)); + READWRITE(VARINT(nTimeFirst)); + READWRITE(VARINT(nTimeLast)); + } + + void SetNull() { + nBlocks = 0; + nSize = 0; + nUndoSize = 0; + nHeightFirst = 0; + nHeightLast = 0; + nTimeFirst = 0; + nTimeLast = 0; + } + + CBlockFileInfo() { + SetNull(); + } + + std::string ToString() const; + + /** update statistics (does not update nSize) */ + void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) { + if (nBlocks==0 || nHeightFirst > nHeightIn) + nHeightFirst = nHeightIn; + if (nBlocks==0 || nTimeFirst > nTimeIn) + nTimeFirst = nTimeIn; + nBlocks++; + if (nHeightIn > nHeightLast) + nHeightLast = nHeightIn; + if (nTimeIn > nTimeLast) + nTimeLast = nTimeIn; + } +}; + struct CDiskBlockPos { int nFile; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index db495d6ae..80407d505 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -1,7 +1,8 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2020 The BitcoinZ community // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "key_io.h" #include "main.h" @@ -80,7 +81,9 @@ class CMainParams : public CChainParams { bip44CoinType = 177; // As registered in https://github.com/satoshilabs/slips/blob/master/slip-0044.md consensus.fCoinbaseMustBeProtected = true; consensus.nSubsidySlowStartInterval = 0; - consensus.nSubsidyHalvingInterval = 840000; + consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_HALVING_INTERVAL; + consensus.nPostBlossomSubsidyHalvingInterval = Consensus::POST_BLOSSOM_HALVING_INTERVAL; + //consensus.nSubsidyHalvingInterval = 840000; consensus.nMajorityEnforceBlockUpgrade = 750; consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityWindow = 4000; @@ -89,7 +92,9 @@ class CMainParams : public CChainParams { assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); consensus.nPowMaxAdjustDown = 34; consensus.nPowMaxAdjustUp = 34; - consensus.nPowTargetSpacing = 2.5 * 60; + consensus.nPreBlossomPowTargetSpacing = Consensus::PRE_BLOSSOM_POW_TARGET_SPACING; + consensus.nPostBlossomPowTargetSpacing = Consensus::POST_BLOSSOM_POW_TARGET_SPACING; + //consensus.nPowTargetSpacing = 2.5 * 60; consensus.nPowAllowMinDifficultyBlocksAfterHeight = boost::none; consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002; consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight = @@ -144,12 +149,11 @@ class CMainParams : public CChainParams { vFixedSeeds.clear(); vSeeds.clear(); // use name as: echo -n hostname | sha256sum - vSeeds.push_back(CDNSSeedData("b8491e7ea3502b8fcda9106923e68b92ef43c331dbf9cfb3c94af473bfbf308b.BTCZ", "btcz.kovach.biz")); - vSeeds.push_back(CDNSSeedData("67f534b87f9a2412f845e39102f184e3a48798ed6e2a64d98b915aa12b625e9c.BTCZ", "seed.btcz.life")); - vSeeds.push_back(CDNSSeedData("acdd520508bbfa96029867cf64b824fa5e41ebe47918bd4b7855d7a186ed795c.BTCZ", "bzseed.secnode.tk")); + + vSeeds.push_back(CDNSSeedData("5051c0f9dfb6e29421647ea34bc3c693c2ba2222af3a867519e4cdd6f1b86c2b.BTCZ", "btzseed2.blockhub.info")); vSeeds.push_back(CDNSSeedData("4437c91da6e4c4edca56b57bd52c2e11a3fd7d8b04bd9dec9584fb5220f54b05.BTCZ", "btzseed.blockhub.info")); - vSeeds.push_back(CDNSSeedData("0416c4d89c3c4078f7127b7b482c5c242328306f1706fe2edcdb7c94e2fdad45.BTCZ", "seed.btcz.biz")); - vSeeds.push_back(CDNSSeedData("e3dca99ba0e7b1d24cca73458f1d67f4014a60565bcf05e5748271922ce897a0.BTCZ", "btczseed.1ds.us")); + vSeeds.push_back(CDNSSeedData("d3f8adfdab612a8a41329e4d013d3ee0396289c8afb8c3951aa6deabf13f1ccb.BTCZ", "seed.btcz.app")); + // guarantees the first 2 characters, when base58 encoded, are "t1" @@ -337,7 +341,9 @@ class CTestNetParams : public CChainParams { bip44CoinType = 1; consensus.fCoinbaseMustBeProtected = true; consensus.nSubsidySlowStartInterval = 0; - consensus.nSubsidyHalvingInterval = 840000; + consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_HALVING_INTERVAL; + consensus.nPostBlossomSubsidyHalvingInterval = Consensus::POST_BLOSSOM_HALVING_INTERVAL; + //consensus.nSubsidyHalvingInterval = 840000; consensus.nMajorityEnforceBlockUpgrade = 51; consensus.nMajorityRejectBlockOutdated = 75; consensus.nMajorityWindow = 400; @@ -346,7 +352,9 @@ class CTestNetParams : public CChainParams { assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); consensus.nPowMaxAdjustDown = 34; consensus.nPowMaxAdjustUp = 34; - consensus.nPowTargetSpacing = 2.5 * 60; + consensus.nPreBlossomPowTargetSpacing = Consensus::PRE_BLOSSOM_POW_TARGET_SPACING; + consensus.nPostBlossomPowTargetSpacing = Consensus::POST_BLOSSOM_POW_TARGET_SPACING; + //consensus.nPowTargetSpacing = 2.5 * 60; consensus.nPowAllowMinDifficultyBlocksAfterHeight = boost::none; consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002; consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight = @@ -396,7 +404,7 @@ class CTestNetParams : public CChainParams { vFixedSeeds.clear(); vSeeds.clear(); - vSeeds.push_back(CDNSSeedData("978b674532d58328c4da63ab138c476ffa2f8a8b2b5a023a668fd3a97eb7c48b.TZB", "testnetseed.btcz.biz")); + vSeeds.push_back(CDNSSeedData("6be074a62041bb2bee54f8c48ef41bac55c44b0e1f49aef7c319d992844667c2.TZB", "test.seed.btcz.app")); //vSeeds.push_back(CDNSSeedData("rotorproject.org", "test-dnsseed.rotorproject.org")); // Zclassic // guarantees the first 2 characters, when base58 encoded, are "tm" @@ -566,7 +574,9 @@ class CRegTestParams : public CChainParams { bip44CoinType = 1; consensus.fCoinbaseMustBeProtected = false; consensus.nSubsidySlowStartInterval = 0; - consensus.nSubsidyHalvingInterval = 150; + consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL; + consensus.nPostBlossomSubsidyHalvingInterval = Consensus::POST_BLOSSOM_REGTEST_HALVING_INTERVAL; + //consensus.nSubsidyHalvingInterval = 150; consensus.nMajorityEnforceBlockUpgrade = 750; consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityWindow = 1000; @@ -575,7 +585,9 @@ class CRegTestParams : public CChainParams { assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); consensus.nPowMaxAdjustDown = 0; // Turn off adjustment down consensus.nPowMaxAdjustUp = 0; // Turn off adjustment up - consensus.nPowTargetSpacing = 2.5 * 60; + consensus.nPreBlossomPowTargetSpacing = Consensus::PRE_BLOSSOM_POW_TARGET_SPACING; + consensus.nPostBlossomPowTargetSpacing = Consensus::POST_BLOSSOM_POW_TARGET_SPACING; + //consensus.nPowTargetSpacing = 2.5 * 60; consensus.nPowAllowMinDifficultyBlocksAfterHeight = 0; consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002; consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight = @@ -625,9 +637,9 @@ class CRegTestParams : public CChainParams { //assert(consensus.hashGenesisBlock == uint256S("0x029f11d80ef9765602235e1bc9727e3eb6ba20839319f761fee920d63401e327")); //assert(genesis.hashMerkleRoot == uint256S("0xc4eaa58879081de3c24a7b117ed2b28300e7ec4c4c1dff1d3f1268b7857a4ddb")); - vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds. - vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds. - vSeeds.push_back(CDNSSeedData("978b674532d58328c4da63ab138c476ffa2f8a8b2b5a023a668fd3a97eb7c48b.TZB", "testnetseed.btcz.biz")); + vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. + vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds. + vSeeds.push_back(CDNSSeedData("6be074a62041bb2bee54f8c48ef41bac55c44b0e1f49aef7c319d992844667c2.TZB", "test.seed.btcz.app")); //vSeeds.push_back(CDNSSeedData("rotorproject.org", "test-dnsseed.rotorproject.org")); // Zclassic fMiningRequiresPeers = false; @@ -774,6 +786,13 @@ class CRegTestParams : public CChainParams { consensus.vUpgrades[idx].nActivationHeight = nActivationHeight; } + void UpdateRegtestPow(int64_t nPowMaxAdjustDown, int64_t nPowMaxAdjustUp, uint256 powLimit) + { + consensus.nPowMaxAdjustDown = nPowMaxAdjustDown; + consensus.nPowMaxAdjustUp = nPowMaxAdjustUp; + consensus.powLimit = powLimit; + } + void SetRegTestZIP209Enabled() { fZIP209Enabled = true; } @@ -826,14 +845,24 @@ bool SelectParamsFromCommandLine() return true; } +// Block height must be >0 and <=last founders reward block height // Block height must be >0 and <=last founders reward block height // Index variable i ranges from 0 - (vCommunityFeeAddress.size()-1) std::string CChainParams::GetCommunityFeeAddressAtHeight(int nHeight) const { - int maxHeight = GetLastCommunityFeeBlockHeight(); - assert(nHeight > 0 && nHeight <= maxHeight); - - size_t addressChangeInterval = (maxHeight + vCommunityFeeAddress.size()) / vCommunityFeeAddress.size(); - size_t i = nHeight / addressChangeInterval; - return vCommunityFeeAddress[i]; + int preBlossomMaxHeight = GetLastCommunityFeeBlockHeight(); + // zip208 + + // FounderAddressAdjustedHeight(height) := + // height, if not IsBlossomActivated(height) + // BlossomActivationHeight + floor((height - BlossomActivationHeight) / BlossomPoWTargetSpacingRatio), otherwise + bool blossomActive = consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM); + if (blossomActive) { + int blossomActivationHeight = consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight; + nHeight = blossomActivationHeight + ((nHeight - blossomActivationHeight) / Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO); + } + assert(nHeight > 0 && nHeight <= preBlossomMaxHeight); + size_t addressChangeInterval = (preBlossomMaxHeight + vCommunityFeeAddress.size()) / vCommunityFeeAddress.size(); + size_t i = nHeight / addressChangeInterval; + return vCommunityFeeAddress[i]; } // Block height must be >0 and <=last founders reward block height @@ -859,6 +888,10 @@ void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivation regTestParams.UpdateNetworkUpgradeParameters(idx, nActivationHeight); } +void UpdateRegtestPow(int64_t nPowMaxAdjustDown, int64_t nPowMaxAdjustUp, uint256 powLimit) { + regTestParams.UpdateRegtestPow(nPowMaxAdjustDown, nPowMaxAdjustUp, powLimit); +} + int validEHparameterList(EHparameters *ehparams, unsigned long blockheight, const CChainParams& params){ //if in overlap period, there will be two valid solutions, else 1. //The upcoming version of EH is preferred so will always be first element @@ -887,7 +920,7 @@ bool checkEHParamaters(int solSize, int height, const CChainParams& params) { EHparameters ehparams[MAX_EH_PARAM_LIST_LEN]; int listlength = validEHparameterList(ehparams, height, params); for(int i = 0; i < listlength; i++){ - LogPrint("pow", "checkEHParamaters height: %d n:%d k:%d solsize: %d \n", + LogPrint("pow", "checkEHParamaters height: %d n:%d k:%d solsize: %d \n", height, ehparams[i].n, ehparams[i].k, ehparams[i].nSolSize); if (ehparams[i].nSolSize == solSize) return true; diff --git a/src/chainparams.h b/src/chainparams.h index 335ad3422..3ab2fde8a 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -1,7 +1,8 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2020 The BitcoinZ community // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CHAINPARAMS_H #define BITCOIN_CHAINPARAMS_H @@ -192,6 +193,8 @@ bool SelectParamsFromCommandLine(); */ void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight); +void UpdateRegtestPow(int64_t nPowMaxAdjustDown, int64_t nPowMaxAdjustUp, uint256 powLimit); + int validEHparameterList(EHparameters *ehparams, unsigned long blockheight, const CChainParams& params); bool checkEHParamaters(int solSize, int height, const CChainParams& params); diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index fc1f8f57d..3ed7fa893 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "chainparamsbase.h" diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index 33765f0fc..d17e98e01 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CHAINPARAMSBASE_H #define BITCOIN_CHAINPARAMSBASE_H diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 87f4ad7f2..3cb619db6 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "checkpoints.h" diff --git a/src/checkpoints.h b/src/checkpoints.h index 5fce6fa81..b6501bc9a 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CHECKPOINTS_H #define BITCOIN_CHECKPOINTS_H diff --git a/src/checkqueue.h b/src/checkqueue.h index 20ba25bb4..157b72c3a 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CHECKQUEUE_H #define BITCOIN_CHECKQUEUE_H diff --git a/src/clientversion.cpp b/src/clientversion.cpp index 65cfc7090..f71685979 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "clientversion.h" @@ -19,7 +19,7 @@ * for both bitcoind and bitcoin-core, to make it harder for attackers to * target servers or GUI users specifically. */ -const std::string CLIENT_NAME("KSC"); +const std::string CLIENT_NAME("YODA"); /** * Client version number @@ -117,8 +117,8 @@ std::string FormatFullVersion() return CLIENT_BUILD; } -/** - * Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki) +/** + * Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki) */ std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments) { diff --git a/src/clientversion.h b/src/clientversion.h index 1bf4de214..0469cccd4 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -2,7 +2,7 @@ // Copyright (c) 2016-2019 The Zcash developers // Copyright (c) 2017-2020 The BitcoinZ Community // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CLIENTVERSION_H #define BITCOIN_CLIENTVERSION_H @@ -18,7 +18,7 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 6 +#define CLIENT_VERSION_REVISION 7 #define CLIENT_VERSION_BUILD 50 //! Set to true for release, false for prerelease or test build diff --git a/src/coincontrol.h b/src/coincontrol.h index 3e8de83c3..dc0e8e51a 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -1,6 +1,6 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_COINCONTROL_H #define BITCOIN_COINCONTROL_H diff --git a/src/coins.cpp b/src/coins.cpp index 962fa4405..6194595e2 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "coins.h" @@ -34,7 +34,7 @@ void CCoins::CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) con nBytes += nLastUsedByte; } -bool CCoins::Spend(uint32_t nPos) +bool CCoins::Spend(uint32_t nPos) { if (nPos >= vout.size() || vout[nPos].IsNull()) return false; @@ -316,7 +316,7 @@ void CCoinsViewCache::PopAnchor(const uint256 &newrt, ShieldedType type) { } void CCoinsViewCache::SetNullifiers(const CTransaction& tx, bool spent) { - for (const JSDescription &joinsplit : tx.vjoinsplit) { + for (const JSDescription &joinsplit : tx.vJoinSplit) { for (const uint256 &nullifier : joinsplit.nullifiers) { std::pair ret = cacheSproutNullifiers.insert(std::make_pair(nullifier, CNullifiersCacheEntry())); ret.first->second.entered = spent; @@ -566,7 +566,7 @@ bool CCoinsViewCache::HaveShieldedRequirements(const CTransaction& tx) const { boost::unordered_map intermediates; - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) + BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) { BOOST_FOREACH(const uint256& nullifier, joinsplit.nullifiers) { @@ -630,7 +630,7 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const // use the maximum priority for all (partially or fully) shielded transactions. // (Note that coinbase transactions cannot contain JoinSplits, or Sapling shielded Spends or Outputs.) - if (tx.vjoinsplit.size() > 0 || tx.vShieldedSpend.size() > 0 || tx.vShieldedOutput.size() > 0) { + if (tx.vJoinSplit.size() > 0 || tx.vShieldedSpend.size() > 0 || tx.vShieldedOutput.size() > 0) { return MAX_PRIORITY; } diff --git a/src/coins.h b/src/coins.h index 4f782ee17..c29c13315 100644 --- a/src/coins.h +++ b/src/coins.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_COINS_H #define BITCOIN_COINS_H diff --git a/src/compat.h b/src/compat.h index feaa544e2..b8c238f22 100644 --- a/src/compat.h +++ b/src/compat.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_COMPAT_H #define BITCOIN_COMPAT_H diff --git a/src/compat/byteswap.h b/src/compat/byteswap.h index 899220bdc..f5cbc9f7e 100644 --- a/src/compat/byteswap.h +++ b/src/compat/byteswap.h @@ -1,6 +1,6 @@ // Copyright (c) 2014 The Bitcoin developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_COMPAT_BYTESWAP_H #define BITCOIN_COMPAT_BYTESWAP_H diff --git a/src/compat/endian.h b/src/compat/endian.h index 9fec2a07f..ae9846ff3 100644 --- a/src/compat/endian.h +++ b/src/compat/endian.h @@ -1,6 +1,6 @@ // Copyright (c) 2014 The Bitcoin developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_COMPAT_ENDIAN_H #define BITCOIN_COMPAT_ENDIAN_H diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp index 3b9c70df7..a80137cd8 100644 --- a/src/compat/glibc_compat.cpp +++ b/src/compat/glibc_compat.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" diff --git a/src/compat/glibc_sanity.cpp b/src/compat/glibc_sanity.cpp index d62d74d46..71402559d 100644 --- a/src/compat/glibc_sanity.cpp +++ b/src/compat/glibc_sanity.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" diff --git a/src/compat/glibcxx_sanity.cpp b/src/compat/glibcxx_sanity.cpp index cee8a98c7..bbba438ea 100644 --- a/src/compat/glibcxx_sanity.cpp +++ b/src/compat/glibcxx_sanity.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include #include diff --git a/src/compat/sanity.h b/src/compat/sanity.h index 909c4f6da..64dcade78 100644 --- a/src/compat/sanity.h +++ b/src/compat/sanity.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_COMPAT_SANITY_H #define BITCOIN_COMPAT_SANITY_H diff --git a/src/compat/strnlen.cpp b/src/compat/strnlen.cpp index 1ac266c2d..1a56310af 100644 --- a/src/compat/strnlen.cpp +++ b/src/compat/strnlen.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" diff --git a/src/compressor.cpp b/src/compressor.cpp index 20c154fc1..e91897149 100644 --- a/src/compressor.cpp +++ b/src/compressor.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "compressor.h" diff --git a/src/compressor.h b/src/compressor.h index 961365d26..e9c2cbdbb 100644 --- a/src/compressor.h +++ b/src/compressor.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_COMPRESSOR_H #define BITCOIN_COMPRESSOR_H diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index c0a3138aa..865b280e7 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CONSENSUS_CONSENSUS_H #define BITCOIN_CONSENSUS_CONSENSUS_H diff --git a/src/consensus/params.cpp b/src/consensus/params.cpp new file mode 100644 index 000000000..2974930b3 --- /dev/null +++ b/src/consensus/params.cpp @@ -0,0 +1,82 @@ +// Copyright (c) 2020 The Bitcoinz Community +// Copyright (c) 2019 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "params.h" + +#include "upgrades.h" + +namespace Consensus { + bool Params::NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const { + return NetworkUpgradeState(nHeight, *this, idx) == UPGRADE_ACTIVE; + } + + int Params::Halving(int nHeight) const { + // zip208 + // Halving(height) := + // floor((height - SlowStartShift) / PreBlossomHalvingInterval), if not IsBlossomActivated(height) + // floor((BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (height - BlossomActivationHeight) / PostBlossomHalvingInterval), otherwise + if (NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM)) { + int64_t blossomActivationHeight = vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight; + // Ideally we would say: + // halvings = (blossomActivationHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nPreBlossomSubsidyHalvingInterval + // + (nHeight - blossomActivationHeight) / consensusParams.nPostBlossomSubsidyHalvingInterval; + // But, (blossomActivationHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nPreBlossomSubsidyHalvingInterval + // would need to be treated as a rational number in order for this to work. + // Define scaledHalvings := halvings * consensusParams.nPostBlossomSubsidyHalvingInterval; + int64_t scaledHalvings = ((blossomActivationHeight - SubsidySlowStartShift()) * Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO) + + (nHeight - blossomActivationHeight); + return (int) (scaledHalvings / nPostBlossomSubsidyHalvingInterval); + } else { + return (nHeight - SubsidySlowStartShift()) / nPreBlossomSubsidyHalvingInterval; + } + } + + int Params::GetLastCommunityFeeBlockHeight(int nHeight) const { + // zip208 + // CommunityFeeLastBlockHeight := max({ height ⦂ N | Halving(height) < 1 }) + // Halving(h) is defined as floor(f(h)) where f is a strictly increasing rational + // function, so it's sufficient to solve for f(height) = 1 in the rationals and + // then take ceiling(height - 1). + // H := blossom activation height; SS := SubsidySlowStartShift(); R := BLOSSOM_POW_TARGET_SPACING_RATIO + // preBlossom: + // 1 = (height - SS) / preInterval + // height = preInterval + SS + // postBlossom: + // 1 = (H - SS) / preInterval + (height - H) / postInterval + // height = H + postInterval - (H - SS) * (postInterval / preInterval) + // height = H + postInterval - (H - SS) * R + // Note: This depends on R being an integer + bool blossomActive = NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM); + if (blossomActive) { + int blossomActivationHeight = vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight; + // The following calculation depends on BLOSSOM_POW_TARGET_SPACING_RATIO being an integer. + return blossomActivationHeight + nPostBlossomSubsidyHalvingInterval + - (blossomActivationHeight - SubsidySlowStartShift()) * BLOSSOM_POW_TARGET_SPACING_RATIO - 1; + } else { + return nPreBlossomSubsidyHalvingInterval + SubsidySlowStartShift() - 1; + } + } + + int64_t Params::PoWTargetSpacing(int nHeight) const { + // zip208 + // PoWTargetSpacing(height) := + // PreBlossomPoWTargetSpacing, if not IsBlossomActivated(height) + // PostBlossomPoWTargetSpacing, otherwise. + bool blossomActive = NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM); + return blossomActive ? nPostBlossomPowTargetSpacing : nPreBlossomPowTargetSpacing; + } + + int64_t Params::AveragingWindowTimespan(int nHeight) const { + return nPowAveragingWindow * PoWTargetSpacing(nHeight); + } + + int64_t Params::MinActualTimespan(int nHeight) const { + return (AveragingWindowTimespan(nHeight) * (100 - nPowMaxAdjustUp)) / 100; + } + + int64_t Params::MaxActualTimespan(int nHeight) const { + return (AveragingWindowTimespan(nHeight) * (100 + nPowMaxAdjustDown)) / 100; + } +} diff --git a/src/consensus/params.h b/src/consensus/params.h index d8c239eed..b34d3b72b 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CONSENSUS_PARAMS_H #define BITCOIN_CONSENSUS_PARAMS_H @@ -20,7 +20,7 @@ namespace Consensus { * The order of these indices MUST match the order of the upgrades on-chain, as * several functions depend on the enum being sorted. */ -enum UpgradeIndex { +enum UpgradeIndex : uint32_t { // Sprout must be first BASE_SPROUT, UPGRADE_TESTDUMMY, @@ -61,10 +61,28 @@ struct NetworkUpgrade { static constexpr int NO_ACTIVATION_HEIGHT = -1; }; +/** ZIP208 block target interval in seconds. */ +static const unsigned int PRE_BLOSSOM_POW_TARGET_SPACING = 150; +static const unsigned int POST_BLOSSOM_POW_TARGET_SPACING = 75; +static_assert(POST_BLOSSOM_POW_TARGET_SPACING < PRE_BLOSSOM_POW_TARGET_SPACING, "Blossom target spacing must be less than pre-Blossom target spacing."); +static const unsigned int PRE_BLOSSOM_HALVING_INTERVAL = 840000; +static const unsigned int PRE_BLOSSOM_REGTEST_HALVING_INTERVAL = 150; +static const int BLOSSOM_POW_TARGET_SPACING_RATIO = PRE_BLOSSOM_POW_TARGET_SPACING / POST_BLOSSOM_POW_TARGET_SPACING; +static_assert(BLOSSOM_POW_TARGET_SPACING_RATIO * POST_BLOSSOM_POW_TARGET_SPACING == PRE_BLOSSOM_POW_TARGET_SPACING, "Invalid BLOSSOM_POW_TARGET_SPACING_RATIO"); +static const unsigned int POST_BLOSSOM_HALVING_INTERVAL = PRE_BLOSSOM_HALVING_INTERVAL * BLOSSOM_POW_TARGET_SPACING_RATIO; +static const unsigned int POST_BLOSSOM_REGTEST_HALVING_INTERVAL = PRE_BLOSSOM_REGTEST_HALVING_INTERVAL * BLOSSOM_POW_TARGET_SPACING_RATIO; + /** * Parameters that influence chain consensus. */ struct Params { + /** + * Returns true if the given network upgrade is active as of the given block + * height. Caller must check that the height is >= 0 (and handle unknown + * heights). + */ + bool NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const; + uint256 hashGenesisBlock; bool fCoinbaseMustBeProtected; @@ -84,21 +102,33 @@ struct Params { */ int SubsidySlowStartShift() const { return nSubsidySlowStartInterval / 2; } int nSubsidyHalvingInterval; + int nPreBlossomSubsidyHalvingInterval; + int nPostBlossomSubsidyHalvingInterval; + + int Halving(int nHeight) const; + + int GetLastCommunityFeeBlockHeight(int nHeight) const; + /** Used to check majorities for block version upgrade */ int nMajorityEnforceBlockUpgrade; int nMajorityRejectBlockOutdated; int nMajorityWindow; NetworkUpgrade vUpgrades[MAX_NETWORK_UPGRADES]; /** Proof of work parameters */ + unsigned int nEquihashN = 144; + unsigned int nEquihashK = 5; uint256 powLimit; boost::optional nPowAllowMinDifficultyBlocksAfterHeight; int64_t nPowAveragingWindow; int64_t nPowMaxAdjustDown; int64_t nPowMaxAdjustUp; - int64_t nPowTargetSpacing; - int64_t AveragingWindowTimespan() const { return nPowAveragingWindow * nPowTargetSpacing; } - int64_t MinActualTimespan() const { return (AveragingWindowTimespan() * (100 - nPowMaxAdjustUp )) / 100; } - int64_t MaxActualTimespan() const { return (AveragingWindowTimespan() * (100 + nPowMaxAdjustDown)) / 100; } + int64_t nPreBlossomPowTargetSpacing; + int64_t nPostBlossomPowTargetSpacing; + int64_t PoWTargetSpacing(int nHeight) const; + int64_t AveragingWindowTimespan(int nHeight) const; + int64_t MinActualTimespan(int nHeight) const; + int64_t MaxActualTimespan(int nHeight) const; + uint256 nMinimumChainWork; }; } // namespace Consensus diff --git a/src/consensus/upgrades.cpp b/src/consensus/upgrades.cpp index e11aaa260..9e11e14a8 100644 --- a/src/consensus/upgrades.cpp +++ b/src/consensus/upgrades.cpp @@ -1,6 +1,7 @@ +// Copyright (c) 2020 The BitcoinZ community // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "consensus/upgrades.h" @@ -12,7 +13,7 @@ const struct NUInfo NetworkUpgradeInfo[Consensus::MAX_NETWORK_UPGRADES] = { { /*.nBranchId =*/ 0, /*.strName =*/ "Sprout", - /*.strInfo =*/ "The Zcash network at launch", + /*.strInfo =*/ "The BitcoinZ network at launch", }, { /*.nBranchId =*/ 0x74736554, @@ -65,17 +66,9 @@ UpgradeState NetworkUpgradeState( } } -bool NetworkUpgradeActive( - int nHeight, - const Consensus::Params& params, - Consensus::UpgradeIndex idx) -{ - return NetworkUpgradeState(nHeight, params, idx) == UPGRADE_ACTIVE; -} - int CurrentEpoch(int nHeight, const Consensus::Params& params) { for (auto idxInt = Consensus::MAX_NETWORK_UPGRADES - 1; idxInt >= Consensus::BASE_SPROUT; idxInt--) { - if (NetworkUpgradeActive(nHeight, params, Consensus::UpgradeIndex(idxInt))) { + if (params.NetworkUpgradeActive(nHeight, Consensus::UpgradeIndex(idxInt))) { return idxInt; } } diff --git a/src/consensus/upgrades.h b/src/consensus/upgrades.h index 920ec1ea8..d5bb70b6f 100644 --- a/src/consensus/upgrades.h +++ b/src/consensus/upgrades.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_CONSENSUS_UPGRADES_H #define ZCASH_CONSENSUS_UPGRADES_H @@ -38,16 +38,6 @@ UpgradeState NetworkUpgradeState( const Consensus::Params& params, Consensus::UpgradeIndex idx); -/** - * Returns true if the given network upgrade is active as of the given block - * height. Caller must check that the height is >= 0 (and handle unknown - * heights). - */ -bool NetworkUpgradeActive( - int nHeight, - const Consensus::Params& params, - Consensus::UpgradeIndex idx); - /** * Returns the index of the most recent upgrade as of the given block height * (corresponding to the current "epoch"). Consensus::BASE_SPROUT is the diff --git a/src/consensus/validation.h b/src/consensus/validation.h index c62adcd8f..0ad7701b1 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CONSENSUS_VALIDATION_H #define BITCOIN_CONSENSUS_VALIDATION_H diff --git a/src/core_io.h b/src/core_io.h index ba5b4e648..0abfb4b10 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CORE_IO_H #define BITCOIN_CORE_IO_H diff --git a/src/core_memusage.h b/src/core_memusage.h index b2f4a28ae..bf955ae4c 100644 --- a/src/core_memusage.h +++ b/src/core_memusage.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CORE_MEMUSAGE_H #define BITCOIN_CORE_MEMUSAGE_H diff --git a/src/core_read.cpp b/src/core_read.cpp index 4be24f8e0..23b4a610c 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "core_io.h" diff --git a/src/core_write.cpp b/src/core_write.cpp index 43344656b..89a545a99 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "core_io.h" diff --git a/src/crypto/common.h b/src/crypto/common.h index 9d2100af9..fd62087b7 100644 --- a/src/crypto/common.h +++ b/src/crypto/common.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CRYPTO_COMMON_H #define BITCOIN_CRYPTO_COMMON_H diff --git a/src/crypto/equihash.cpp b/src/crypto/equihash.cpp index b889b7936..863c4f673 100644 --- a/src/crypto/equihash.cpp +++ b/src/crypto/equihash.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2016 Jack Grigg // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . // Implementation of the Equihash Proof-of-Work algorithm. // diff --git a/src/crypto/equihash.h b/src/crypto/equihash.h index 9dac08b56..5d8a8da0a 100644 --- a/src/crypto/equihash.h +++ b/src/crypto/equihash.h @@ -1,7 +1,7 @@ // Copyright (c) 2016 Jack Grigg // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_EQUIHASH_H #define BITCOIN_EQUIHASH_H diff --git a/src/crypto/equihash.tcc b/src/crypto/equihash.tcc index 625749e47..8279396d1 100644 --- a/src/crypto/equihash.tcc +++ b/src/crypto/equihash.tcc @@ -1,7 +1,7 @@ // Copyright (c) 2016 Jack Grigg // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include #include diff --git a/src/crypto/hmac_sha256.cpp b/src/crypto/hmac_sha256.cpp index 3c791625d..951c569ed 100644 --- a/src/crypto/hmac_sha256.cpp +++ b/src/crypto/hmac_sha256.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "crypto/hmac_sha256.h" diff --git a/src/crypto/hmac_sha256.h b/src/crypto/hmac_sha256.h index 1519c1457..c7627da2e 100644 --- a/src/crypto/hmac_sha256.h +++ b/src/crypto/hmac_sha256.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CRYPTO_HMAC_SHA256_H #define BITCOIN_CRYPTO_HMAC_SHA256_H diff --git a/src/crypto/hmac_sha512.cpp b/src/crypto/hmac_sha512.cpp index 5939c6ec4..ca7b00c63 100644 --- a/src/crypto/hmac_sha512.cpp +++ b/src/crypto/hmac_sha512.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "crypto/hmac_sha512.h" diff --git a/src/crypto/hmac_sha512.h b/src/crypto/hmac_sha512.h index 17dee61ea..61514636b 100644 --- a/src/crypto/hmac_sha512.h +++ b/src/crypto/hmac_sha512.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CRYPTO_HMAC_SHA512_H #define BITCOIN_CRYPTO_HMAC_SHA512_H diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp index 77c9acfc2..70dad5e5d 100644 --- a/src/crypto/ripemd160.cpp +++ b/src/crypto/ripemd160.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "crypto/ripemd160.h" diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h index 687204fda..b56aac900 100644 --- a/src/crypto/ripemd160.h +++ b/src/crypto/ripemd160.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CRYPTO_RIPEMD160_H #define BITCOIN_CRYPTO_RIPEMD160_H diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp index 0b895b33a..c437f9d1f 100644 --- a/src/crypto/sha1.cpp +++ b/src/crypto/sha1.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "crypto/sha1.h" diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h index 7b2a21bc6..553f4928a 100644 --- a/src/crypto/sha1.h +++ b/src/crypto/sha1.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CRYPTO_SHA1_H #define BITCOIN_CRYPTO_SHA1_H diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index 39583c26a..ff1ae2f05 100644 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "crypto/sha256.h" diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h index 8ecb7348d..3dff0dd2b 100644 --- a/src/crypto/sha256.h +++ b/src/crypto/sha256.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CRYPTO_SHA256_H #define BITCOIN_CRYPTO_SHA256_H diff --git a/src/crypto/sha512.cpp b/src/crypto/sha512.cpp index 564127cc3..8f02862fa 100644 --- a/src/crypto/sha512.cpp +++ b/src/crypto/sha512.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "crypto/sha512.h" diff --git a/src/crypto/sha512.h b/src/crypto/sha512.h index f1f17caf9..194cc61f9 100644 --- a/src/crypto/sha512.h +++ b/src/crypto/sha512.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_CRYPTO_SHA512_H #define BITCOIN_CRYPTO_SHA512_H diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index b34be5af7..494ab98ce 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "dbwrapper.h" diff --git a/src/dbwrapper.h b/src/dbwrapper.h index e3f9a2652..0996e9cda 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_DBWRAPPER_H #define BITCOIN_DBWRAPPER_H diff --git a/src/deprecation.cpp b/src/deprecation.cpp index c5ba57e85..168969ff3 100644 --- a/src/deprecation.cpp +++ b/src/deprecation.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "deprecation.h" diff --git a/src/deprecation.h b/src/deprecation.h index bfcf53eab..9f49a5191 100644 --- a/src/deprecation.h +++ b/src/deprecation.h @@ -1,6 +1,7 @@ +// Copyright (c) 2020 The BitcoinZ community // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_DEPRECATION_H #define ZCASH_DEPRECATION_H @@ -8,7 +9,7 @@ // Deprecation policy: // * Shut down 16 weeks' worth of blocks after the estimated release block height. // * A warning is shown during the 2 weeks' worth of blocks prior to shut down. -static const int APPROX_RELEASE_HEIGHT = 743740; +static const int APPROX_RELEASE_HEIGHT = 775000; static const int WEEKS_UNTIL_DEPRECATION = 16; static const int DEPRECATION_HEIGHT = APPROX_RELEASE_HEIGHT + (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 24); diff --git a/src/gtest/test_checkblock.cpp b/src/gtest/test_checkblock.cpp index a5ad4c338..7e286309e 100644 --- a/src/gtest/test_checkblock.cpp +++ b/src/gtest/test_checkblock.cpp @@ -31,7 +31,7 @@ TEST(CheckBlock, VersionTooLow) { MockCValidationState state; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "version-too-low", false)).Times(1); - EXPECT_FALSE(CheckBlock(block, state, verifier, false, false)); + EXPECT_FALSE(CheckBlock(block, state, Params(), verifier, false, false)); } @@ -64,7 +64,7 @@ TEST(CheckBlock, BlockSproutRejectsBadVersion) { auto verifier = libzcash::ProofVerifier::Strict(); EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-version-too-low", false)).Times(1); - EXPECT_FALSE(CheckBlock(block, state, verifier, false, false)); + EXPECT_FALSE(CheckBlock(block, state, Params(), verifier, false, false)); } @@ -117,7 +117,7 @@ class ContextualCheckBlockTest : public ::testing::Test { // We now expect this to be a valid block. MockCValidationState state; - EXPECT_TRUE(ContextualCheckBlock(block, state, &indexPrev)); + EXPECT_TRUE(ContextualCheckBlock(block, state, Params(), &indexPrev)); } // Expects a height-1 block containing a given transaction to fail @@ -135,7 +135,7 @@ class ContextualCheckBlockTest : public ::testing::Test { // We now expect this to be an invalid block, for the given reason. MockCValidationState state; EXPECT_CALL(state, DoS(level, false, REJECT_INVALID, reason, false)).Times(1); - EXPECT_FALSE(ContextualCheckBlock(block, state, &indexPrev)); + EXPECT_FALSE(ContextualCheckBlock(block, state, Params(), &indexPrev)); } }; @@ -152,7 +152,7 @@ TEST_F(ContextualCheckBlockTest, BadCoinbaseHeight) { // Treating block as genesis should pass MockCValidationState state; - EXPECT_TRUE(ContextualCheckBlock(block, state, NULL)); + EXPECT_TRUE(ContextualCheckBlock(block, state, Params(), NULL)); // Give the transaction a Founder's Reward vout mtx.vout.push_back(CTxOut( @@ -166,20 +166,20 @@ TEST_F(ContextualCheckBlockTest, BadCoinbaseHeight) { CBlockIndex indexPrev {prev}; indexPrev.nHeight = 0; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-height", false)).Times(1); - EXPECT_FALSE(ContextualCheckBlock(block, state, &indexPrev)); + EXPECT_FALSE(ContextualCheckBlock(block, state, Params(), &indexPrev)); // Setting to an incorrect height should fail mtx.vin[0].scriptSig = CScript() << 2 << OP_0; CTransaction tx3 {mtx}; block.vtx[0] = tx3; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-height", false)).Times(1); - EXPECT_FALSE(ContextualCheckBlock(block, state, &indexPrev)); + EXPECT_FALSE(ContextualCheckBlock(block, state, Params(), &indexPrev)); // After correcting the scriptSig, should pass mtx.vin[0].scriptSig = CScript() << 1 << OP_0; CTransaction tx4 {mtx}; block.vtx[0] = tx4; - EXPECT_TRUE(ContextualCheckBlock(block, state, &indexPrev)); + EXPECT_TRUE(ContextualCheckBlock(block, state, Params(), &indexPrev)); } // TEST PLAN: first, check that each ruleset accepts its own transaction type. diff --git a/src/gtest/test_checktransaction.cpp b/src/gtest/test_checktransaction.cpp index cf9d77441..a30b1268c 100644 --- a/src/gtest/test_checktransaction.cpp +++ b/src/gtest/test_checktransaction.cpp @@ -18,9 +18,9 @@ TEST(checktransaction_tests, check_vpub_not_both_nonzero) { CMutableTransaction newTx(tx); CValidationState state; - newTx.vjoinsplit.push_back(JSDescription()); + newTx.vJoinSplit.push_back(JSDescription()); - JSDescription *jsdesc = &newTx.vjoinsplit[0]; + JSDescription *jsdesc = &newTx.vJoinSplit[0]; jsdesc->vpub_old = 1; jsdesc->vpub_new = 1; @@ -58,14 +58,14 @@ CMutableTransaction GetValidTransaction() { mtx.vin[1].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000002"); mtx.vin[1].prevout.n = 0; mtx.vout.resize(2); - // mtx.vout[0].scriptPubKey = + // mtx.vout[0].scriptPubKey = mtx.vout[0].nValue = 0; mtx.vout[1].nValue = 0; - mtx.vjoinsplit.resize(2); - mtx.vjoinsplit[0].nullifiers.at(0) = uint256S("0000000000000000000000000000000000000000000000000000000000000000"); - mtx.vjoinsplit[0].nullifiers.at(1) = uint256S("0000000000000000000000000000000000000000000000000000000000000001"); - mtx.vjoinsplit[1].nullifiers.at(0) = uint256S("0000000000000000000000000000000000000000000000000000000000000002"); - mtx.vjoinsplit[1].nullifiers.at(1) = uint256S("0000000000000000000000000000000000000000000000000000000000000003"); + mtx.vJoinSplit.resize(2); + mtx.vJoinSplit[0].nullifiers.at(0) = uint256S("0000000000000000000000000000000000000000000000000000000000000000"); + mtx.vJoinSplit[0].nullifiers.at(1) = uint256S("0000000000000000000000000000000000000000000000000000000000000001"); + mtx.vJoinSplit[1].nullifiers.at(0) = uint256S("0000000000000000000000000000000000000000000000000000000000000002"); + mtx.vJoinSplit[1].nullifiers.at(1) = uint256S("0000000000000000000000000000000000000000000000000000000000000003"); CreateJoinSplitSignature(mtx, consensusBranchId); return mtx; @@ -115,7 +115,7 @@ TEST(checktransaction_tests, BadVersionTooLow) { TEST(checktransaction_tests, bad_txns_vin_empty) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); + mtx.vJoinSplit.resize(0); mtx.vin.resize(0); CTransaction tx(mtx); @@ -126,7 +126,7 @@ TEST(checktransaction_tests, bad_txns_vin_empty) { TEST(checktransaction_tests, bad_txns_vout_empty) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); + mtx.vJoinSplit.resize(0); mtx.vout.resize(0); CTransaction tx(mtx); @@ -167,7 +167,7 @@ TEST(checktransaction_tests, BadTxnsOversize) { // ... but fails contextual ones! EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-oversize", false)).Times(1); - EXPECT_FALSE(ContextualCheckTransaction(tx, state, 1, 100)); + EXPECT_FALSE(ContextualCheckTransaction(tx, state, Params(), 1, 100)); } { @@ -179,8 +179,8 @@ TEST(checktransaction_tests, BadTxnsOversize) { mtx.nVersion = SAPLING_TX_VERSION; // Change the proof types (which requires re-signing the JoinSplit data) - mtx.vjoinsplit[0].proof = libzcash::GrothProof(); - mtx.vjoinsplit[1].proof = libzcash::GrothProof(); + mtx.vJoinSplit[0].proof = libzcash::GrothProof(); + mtx.vJoinSplit[1].proof = libzcash::GrothProof(); CreateJoinSplitSignature(mtx, NetworkUpgradeInfo[Consensus::UPGRADE_SAPLING].nBranchId); CTransaction tx(mtx); @@ -188,7 +188,7 @@ TEST(checktransaction_tests, BadTxnsOversize) { MockCValidationState state; EXPECT_TRUE(CheckTransactionWithoutProofVerification(tx, state)); - EXPECT_TRUE(ContextualCheckTransaction(tx, state, 1, 100)); + EXPECT_TRUE(ContextualCheckTransaction(tx, state, Params(), 1, 100)); // Revert to default RegtestDeactivateSapling(); @@ -204,8 +204,8 @@ TEST(checktransaction_tests, OversizeSaplingTxns) { mtx.nVersion = SAPLING_TX_VERSION; // Change the proof types (which requires re-signing the JoinSplit data) - mtx.vjoinsplit[0].proof = libzcash::GrothProof(); - mtx.vjoinsplit[1].proof = libzcash::GrothProof(); + mtx.vJoinSplit[0].proof = libzcash::GrothProof(); + mtx.vJoinSplit[1].proof = libzcash::GrothProof(); CreateJoinSplitSignature(mtx, NetworkUpgradeInfo[Consensus::UPGRADE_SAPLING].nBranchId); // Transaction just under the limit @@ -337,7 +337,7 @@ TEST(checktransaction_tests, ValueBalanceOverflowsTotal) { TEST(checktransaction_tests, bad_txns_txouttotal_toolarge_joinsplit) { CMutableTransaction mtx = GetValidTransaction(); mtx.vout[0].nValue = 1; - mtx.vjoinsplit[0].vpub_old = MAX_MONEY; + mtx.vJoinSplit[0].vpub_old = MAX_MONEY; CTransaction tx(mtx); @@ -348,8 +348,8 @@ TEST(checktransaction_tests, bad_txns_txouttotal_toolarge_joinsplit) { TEST(checktransaction_tests, bad_txns_txintotal_toolarge_joinsplit) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit[0].vpub_new = MAX_MONEY - 1; - mtx.vjoinsplit[1].vpub_new = MAX_MONEY - 1; + mtx.vJoinSplit[0].vpub_new = MAX_MONEY - 1; + mtx.vJoinSplit[1].vpub_new = MAX_MONEY - 1; CTransaction tx(mtx); @@ -360,7 +360,7 @@ TEST(checktransaction_tests, bad_txns_txintotal_toolarge_joinsplit) { TEST(checktransaction_tests, bad_txns_vpub_old_negative) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit[0].vpub_old = -1; + mtx.vJoinSplit[0].vpub_old = -1; CTransaction tx(mtx); @@ -371,7 +371,7 @@ TEST(checktransaction_tests, bad_txns_vpub_old_negative) { TEST(checktransaction_tests, bad_txns_vpub_new_negative) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit[0].vpub_new = -1; + mtx.vJoinSplit[0].vpub_new = -1; CTransaction tx(mtx); @@ -382,7 +382,7 @@ TEST(checktransaction_tests, bad_txns_vpub_new_negative) { TEST(checktransaction_tests, bad_txns_vpub_old_toolarge) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit[0].vpub_old = MAX_MONEY + 1; + mtx.vJoinSplit[0].vpub_old = MAX_MONEY + 1; CTransaction tx(mtx); @@ -393,7 +393,7 @@ TEST(checktransaction_tests, bad_txns_vpub_old_toolarge) { TEST(checktransaction_tests, bad_txns_vpub_new_toolarge) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit[0].vpub_new = MAX_MONEY + 1; + mtx.vJoinSplit[0].vpub_new = MAX_MONEY + 1; CTransaction tx(mtx); @@ -404,8 +404,8 @@ TEST(checktransaction_tests, bad_txns_vpub_new_toolarge) { TEST(checktransaction_tests, bad_txns_vpubs_both_nonzero) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit[0].vpub_old = 1; - mtx.vjoinsplit[0].vpub_new = 1; + mtx.vJoinSplit[0].vpub_old = 1; + mtx.vJoinSplit[0].vpub_new = 1; CTransaction tx(mtx); @@ -428,8 +428,8 @@ TEST(checktransaction_tests, bad_txns_inputs_duplicate) { TEST(checktransaction_tests, bad_joinsplits_nullifiers_duplicate_same_joinsplit) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit[0].nullifiers.at(0) = uint256S("0000000000000000000000000000000000000000000000000000000000000000"); - mtx.vjoinsplit[0].nullifiers.at(1) = uint256S("0000000000000000000000000000000000000000000000000000000000000000"); + mtx.vJoinSplit[0].nullifiers.at(0) = uint256S("0000000000000000000000000000000000000000000000000000000000000000"); + mtx.vJoinSplit[0].nullifiers.at(1) = uint256S("0000000000000000000000000000000000000000000000000000000000000000"); CTransaction tx(mtx); @@ -440,8 +440,8 @@ TEST(checktransaction_tests, bad_joinsplits_nullifiers_duplicate_same_joinsplit) TEST(checktransaction_tests, bad_joinsplits_nullifiers_duplicate_different_joinsplit) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit[0].nullifiers.at(0) = uint256S("0000000000000000000000000000000000000000000000000000000000000000"); - mtx.vjoinsplit[1].nullifiers.at(0) = uint256S("0000000000000000000000000000000000000000000000000000000000000000"); + mtx.vJoinSplit[0].nullifiers.at(0) = uint256S("0000000000000000000000000000000000000000000000000000000000000000"); + mtx.vJoinSplit[1].nullifiers.at(0) = uint256S("0000000000000000000000000000000000000000000000000000000000000000"); CTransaction tx(mtx); @@ -456,7 +456,7 @@ TEST(checktransaction_tests, bad_cb_has_joinsplits) { mtx.vin.resize(1); mtx.vin[0].prevout.SetNull(); - mtx.vjoinsplit.resize(1); + mtx.vJoinSplit.resize(1); CTransaction tx(mtx); EXPECT_TRUE(tx.IsCoinBase()); @@ -472,7 +472,7 @@ TEST(checktransaction_tests, bad_cb_empty_scriptsig) { mtx.vin.resize(1); mtx.vin[0].prevout.SetNull(); - mtx.vjoinsplit.resize(0); + mtx.vJoinSplit.resize(0); CTransaction tx(mtx); EXPECT_TRUE(tx.IsCoinBase()); @@ -496,6 +496,7 @@ TEST(checktransaction_tests, bad_txns_prevout_null) { TEST(checktransaction_tests, bad_txns_invalid_joinsplit_signature) { SelectParams(CBaseChainParams::REGTEST); + auto chainparams = Params(); CMutableTransaction mtx = GetValidTransaction(); mtx.joinSplitSig[0] += 1; @@ -504,13 +505,14 @@ TEST(checktransaction_tests, bad_txns_invalid_joinsplit_signature) { MockCValidationState state; // during initial block download, DoS ban score should be zero, else 100 EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false)).Times(1); - ContextualCheckTransaction(tx, state, 0, 100, []() { return true; }); + ContextualCheckTransaction(tx, state, chainparams, 0, 100, [](const CChainParams&) { return false; });; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false)).Times(1); - ContextualCheckTransaction(tx, state, 0, 100, []() { return false; }); + ContextualCheckTransaction(tx, state, chainparams, 0, 100, [](const CChainParams&) { return false; }); } TEST(checktransaction_tests, non_canonical_ed25519_signature) { SelectParams(CBaseChainParams::REGTEST); + auto chainparams = Params(); CMutableTransaction mtx = GetValidTransaction(); @@ -518,7 +520,7 @@ TEST(checktransaction_tests, non_canonical_ed25519_signature) { { CTransaction tx(mtx); MockCValidationState state; - EXPECT_TRUE(ContextualCheckTransaction(tx, state, 0, 100)); + EXPECT_TRUE(ContextualCheckTransaction(tx, state, chainparams, 0, 100)); } // Copied from libsodium/crypto_sign/ed25519/ref10/open.c @@ -540,9 +542,9 @@ TEST(checktransaction_tests, non_canonical_ed25519_signature) { MockCValidationState state; // during initial block download, DoS ban score should be zero, else 100 EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false)).Times(1); - ContextualCheckTransaction(tx, state, 0, 100, []() { return true; }); + ContextualCheckTransaction(tx, state, chainparams, 0, 100, [](const CChainParams&) { return false; });; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false)).Times(1); - ContextualCheckTransaction(tx, state, 0, 100, []() { return false; }); + ContextualCheckTransaction(tx, state, chainparams, 0, 100, [](const CChainParams&) { return false; }); } TEST(checktransaction_tests, OverwinterConstructors) { @@ -641,7 +643,7 @@ TEST(checktransaction_tests, OverwinterDefaultValues) { // A valid v3 transaction with no joinsplits TEST(checktransaction_tests, OverwinterValidTx) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); + mtx.vJoinSplit.resize(0); mtx.fOverwintered = true; mtx.nVersion = OVERWINTER_TX_VERSION; mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; @@ -653,7 +655,7 @@ TEST(checktransaction_tests, OverwinterValidTx) { TEST(checktransaction_tests, OverwinterExpiryHeight) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); + mtx.vJoinSplit.resize(0); mtx.fOverwintered = true; mtx.nVersion = OVERWINTER_TX_VERSION; mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; @@ -689,12 +691,20 @@ TEST(checktransaction_tests, OverwinterExpiryHeight) { } } +TEST(checktransaction_tests, BlossomExpiryHeight) { + const Consensus::Params& params = RegtestActivateBlossom(false, 100); + CMutableTransaction preBlossomMtx = CreateNewContextualCMutableTransaction(params, 99); + EXPECT_EQ(preBlossomMtx.nExpiryHeight, 100 - 1); + CMutableTransaction blossomMtx = CreateNewContextualCMutableTransaction(params, 100); + EXPECT_EQ(blossomMtx.nExpiryHeight, 100 + 40); + RegtestDeactivateBlossom(); +} // Test that a Sprout tx with a negative version number is detected // given the new Overwinter logic TEST(checktransaction_tests, SproutTxVersionTooLow) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); + mtx.vJoinSplit.resize(0); mtx.fOverwintered = false; mtx.nVersion = -1; @@ -716,7 +726,7 @@ class UNSAFE_CTransaction : public CTransaction { TEST(checktransaction_tests, SaplingSproutInputSumsTooLarge) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); + mtx.vJoinSplit.resize(0); mtx.fOverwintered = true; mtx.nVersion = SAPLING_TX_VERSION; mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID; @@ -744,12 +754,12 @@ TEST(checktransaction_tests, SaplingSproutInputSumsTooLarge) { inputMap, outputMap, 0, 0, false); - mtx.vjoinsplit.push_back(jsdesc); + mtx.vJoinSplit.push_back(jsdesc); } mtx.vShieldedSpend.push_back(SpendDescription()); - mtx.vjoinsplit[0].vpub_new = (MAX_MONEY / 2) + 10; + mtx.vJoinSplit[0].vpub_new = (MAX_MONEY / 2) + 10; { UNSAFE_CTransaction tx(mtx); @@ -770,7 +780,7 @@ TEST(checktransaction_tests, SaplingSproutInputSumsTooLarge) { // Test bad Overwinter version number in CheckTransactionWithoutProofVerification TEST(checktransaction_tests, OverwinterVersionNumberLow) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); + mtx.vJoinSplit.resize(0); mtx.fOverwintered = true; mtx.nVersion = OVERWINTER_MIN_TX_VERSION - 1; mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; @@ -788,7 +798,7 @@ TEST(checktransaction_tests, OverwinterVersionNumberHigh) { UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); + mtx.vJoinSplit.resize(0); mtx.fOverwintered = true; mtx.nVersion = OVERWINTER_MAX_TX_VERSION + 1; mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; @@ -797,7 +807,7 @@ TEST(checktransaction_tests, OverwinterVersionNumberHigh) { UNSAFE_CTransaction tx(mtx); MockCValidationState state; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-tx-overwinter-version-too-high", false)).Times(1); - ContextualCheckTransaction(tx, state, 1, 100); + ContextualCheckTransaction(tx, state, Params(), 1, 100); // Revert to default UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); @@ -807,7 +817,7 @@ TEST(checktransaction_tests, OverwinterVersionNumberHigh) { // Test bad Overwinter version group id TEST(checktransaction_tests, OverwinterBadVersionGroupId) { CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); + mtx.vJoinSplit.resize(0); mtx.fOverwintered = true; mtx.nVersion = OVERWINTER_TX_VERSION; mtx.nExpiryHeight = 0; @@ -822,6 +832,7 @@ TEST(checktransaction_tests, OverwinterBadVersionGroupId) { // This tests an Overwinter transaction checked against Sprout TEST(checktransaction_tests, OverwinterNotActive) { SelectParams(CBaseChainParams::TESTNET); + auto chainparams = Params(); CMutableTransaction mtx = GetValidTransaction(); mtx.fOverwintered = true; @@ -833,9 +844,9 @@ TEST(checktransaction_tests, OverwinterNotActive) { MockCValidationState state; // during initial block download, DoS ban score should be zero, else 100 EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "tx-overwinter-not-active", false)).Times(1); - ContextualCheckTransaction(tx, state, 1, 100, []() { return true; }); + ContextualCheckTransaction(tx, state, chainparams, 1, 100, [](const CChainParams&) { return true; }); EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "tx-overwinter-not-active", false)).Times(1); - ContextualCheckTransaction(tx, state, 1, 100, []() { return false; }); + ContextualCheckTransaction(tx, state, chainparams, 1, 100, [](const CChainParams&) { return false; }); } // This tests a transaction without the fOverwintered flag set, against the Overwinter consensus rule set. @@ -852,7 +863,7 @@ TEST(checktransaction_tests, OverwinterFlagNotSet) { CTransaction tx(mtx); MockCValidationState state; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "tx-overwinter-flag-not-set", false)).Times(1); - ContextualCheckTransaction(tx, state, 1, 100); + ContextualCheckTransaction(tx, state, Params(), 1, 100); // Revert to default UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); @@ -880,90 +891,52 @@ TEST(checktransaction_tests, OverwinterInvalidSoftForkVersion) { } } +static void ContextualCreateTxCheck(const Consensus::Params& params, int nHeight, + int expectedVersion, bool expectedOverwintered, int expectedVersionGroupId, int expectedExpiryHeight) +{ + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(params, nHeight); + EXPECT_EQ(mtx.nVersion, expectedVersion); + EXPECT_EQ(mtx.fOverwintered, expectedOverwintered); + EXPECT_EQ(mtx.nVersionGroupId, expectedVersionGroupId); + EXPECT_EQ(mtx.nExpiryHeight, expectedExpiryHeight); +} + // Test CreateNewContextualCMutableTransaction sets default values based on height TEST(checktransaction_tests, OverwinteredContextualCreateTx) { SelectParams(CBaseChainParams::REGTEST); - const Consensus::Params& consensusParams = Params().GetConsensus(); - int activationHeight = 5; + const Consensus::Params& params = Params().GetConsensus(); + int overwinterActivationHeight = 5; int saplingActivationHeight = 30; - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, activationHeight); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, overwinterActivationHeight); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, saplingActivationHeight); - { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction( - consensusParams, activationHeight - 1); - - EXPECT_EQ(mtx.nVersion, 1); - EXPECT_EQ(mtx.fOverwintered, false); - EXPECT_EQ(mtx.nVersionGroupId, 0); - EXPECT_EQ(mtx.nExpiryHeight, 0); - } + ContextualCreateTxCheck(params, overwinterActivationHeight - 1, 1, false, 0, 0); // Overwinter activates - { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction( - consensusParams, activationHeight ); - - EXPECT_EQ(mtx.nVersion, 3); - EXPECT_EQ(mtx.fOverwintered, true); - EXPECT_EQ(mtx.nVersionGroupId, OVERWINTER_VERSION_GROUP_ID); - EXPECT_EQ(mtx.nExpiryHeight, activationHeight + expiryDelta); - } - + ContextualCreateTxCheck(params, overwinterActivationHeight, + OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, overwinterActivationHeight + DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA); // Close to Sapling activation - { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction( - consensusParams, saplingActivationHeight - expiryDelta - 2); - - EXPECT_EQ(mtx.fOverwintered, true); - EXPECT_EQ(mtx.nVersionGroupId, OVERWINTER_VERSION_GROUP_ID); - EXPECT_EQ(mtx.nVersion, OVERWINTER_TX_VERSION); - EXPECT_EQ(mtx.nExpiryHeight, saplingActivationHeight - 2); - } - - { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction( - consensusParams, saplingActivationHeight - expiryDelta - 1); - - EXPECT_EQ(mtx.fOverwintered, true); - EXPECT_EQ(mtx.nVersionGroupId, OVERWINTER_VERSION_GROUP_ID); - EXPECT_EQ(mtx.nVersion, OVERWINTER_TX_VERSION); - EXPECT_EQ(mtx.nExpiryHeight, saplingActivationHeight - 1); - } - - { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction( - consensusParams, saplingActivationHeight - expiryDelta); - - EXPECT_EQ(mtx.fOverwintered, true); - EXPECT_EQ(mtx.nVersionGroupId, OVERWINTER_VERSION_GROUP_ID); - EXPECT_EQ(mtx.nVersion, OVERWINTER_TX_VERSION); - EXPECT_EQ(mtx.nExpiryHeight, saplingActivationHeight - 1); - } - + ContextualCreateTxCheck(params, saplingActivationHeight - DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA - 2, + OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, saplingActivationHeight - 2); + ContextualCreateTxCheck(params, saplingActivationHeight - DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA - 1, + OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, saplingActivationHeight - 1); + ContextualCreateTxCheck(params, saplingActivationHeight - DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA, + OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, saplingActivationHeight - 1); + ContextualCreateTxCheck(params, saplingActivationHeight - DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA + 1, + OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, saplingActivationHeight - 1); + ContextualCreateTxCheck(params, saplingActivationHeight - DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA + 2, + OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, saplingActivationHeight - 1); + ContextualCreateTxCheck(params, saplingActivationHeight - DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA + 3, + OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, saplingActivationHeight - 1); // Just before Sapling activation - { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction( - consensusParams, saplingActivationHeight - 1); - - EXPECT_EQ(mtx.fOverwintered, true); - EXPECT_EQ(mtx.nVersionGroupId, OVERWINTER_VERSION_GROUP_ID); - EXPECT_EQ(mtx.nVersion, OVERWINTER_TX_VERSION); - EXPECT_EQ(mtx.nExpiryHeight, saplingActivationHeight - 1); - } - + ContextualCreateTxCheck(params, saplingActivationHeight - 4, OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, saplingActivationHeight - 1); + ContextualCreateTxCheck(params, saplingActivationHeight - 3, OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, saplingActivationHeight - 1); + ContextualCreateTxCheck(params, saplingActivationHeight - 2, OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, saplingActivationHeight - 1); + ContextualCreateTxCheck(params, saplingActivationHeight - 1, OVERWINTER_TX_VERSION, true, OVERWINTER_VERSION_GROUP_ID, saplingActivationHeight - 1); // Sapling activates - { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction( - consensusParams, saplingActivationHeight); - - EXPECT_EQ(mtx.fOverwintered, true); - EXPECT_EQ(mtx.nVersionGroupId, SAPLING_VERSION_GROUP_ID); - EXPECT_EQ(mtx.nVersion, SAPLING_TX_VERSION); - EXPECT_EQ(mtx.nExpiryHeight, saplingActivationHeight + expiryDelta); - } - + ContextualCreateTxCheck(params, saplingActivationHeight, + SAPLING_TX_VERSION, true, SAPLING_VERSION_GROUP_ID, saplingActivationHeight + DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA); // Revert to default RegtestDeactivateSapling(); } diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index 6e17ef40b..a497cff52 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -13,6 +13,7 @@ #include #include #include "util.h" +#include "utiltest.h" // To run tests: // ./zcash-gtest --gtest_filter="founders_reward_test.*" @@ -33,7 +34,7 @@ TEST(founders_reward_test, create_testnet_2of3multisig) { ASSERT_EQ(DB_LOAD_OK, pWallet->LoadWallet(fFirstRun)); pWallet->TopUpKeyPool(); std::cout << "Test wallet and logs saved in folder: " << pathTemp.native() << std::endl; - + int numKeys = 48; std::vector pubkeys; pubkeys.resize(3); @@ -61,7 +62,7 @@ TEST(founders_reward_test, create_testnet_2of3multisig) { std::string address = EncodeDestination(innerID); addresses.push_back(address); } - + // Print out the addresses, 4 on each line. std::string s = "vCommunityFeeAddress = {\n"; int i=0; @@ -82,6 +83,12 @@ TEST(founders_reward_test, create_testnet_2of3multisig) { } #endif +static int GetLastCommunityFeeHeight(const Consensus::Params& params) { + int blossomActivationHeight = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight; + bool blossom = blossomActivationHeight != Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + //return params.GetLastCommunityFeeBlockHeight(blossom ? blossomActivationHeight : 0); + return Params().GetLastCommunityFeeBlockHeight(); +} // Utility method to check the number of unique addresses from height 1 to maxHeight void checkNumberOfUniqueAddresses(int nUnique) { @@ -90,6 +97,7 @@ void checkNumberOfUniqueAddresses(int nUnique) { for (int i = 1; i <= maxHeight; i++) { addresses.insert(Params().GetCommunityFeeAddressAtHeight(i)); } + //EXPECT_EQ(addresses.size(), nUnique); ASSERT_TRUE(addresses.size() == nUnique); } @@ -98,7 +106,7 @@ TEST(founders_reward_test, general) { SelectParams(CBaseChainParams::TESTNET); CChainParams params = Params(); - + // Fourth testnet reward: // address = t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy // script.ToString() = OP_HASH160 55d64928e69829d9376c776550b6cc710d427153 OP_EQUAL @@ -111,14 +119,30 @@ TEST(founders_reward_test, general) { EXPECT_EQ(params.GetCommunityFeeAddressAtHeight(53127), "t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy"); int maxHeight = params.GetLastCommunityFeeBlockHeight(); - + // If the block height parameter is out of bounds, there is an assert. EXPECT_DEATH(params.GetCommunityFeeScriptAtHeight(0), "nHeight"); EXPECT_DEATH(params.GetCommunityFeeScriptAtHeight(maxHeight+1), "nHeight"); EXPECT_DEATH(params.GetCommunityFeeAddressAtHeight(0), "nHeight"); - EXPECT_DEATH(params.GetCommunityFeeAddressAtHeight(maxHeight+1), "nHeight"); + EXPECT_DEATH(params.GetCommunityFeeAddressAtHeight(maxHeight+1), "nHeight"); } +TEST(founders_reward_test, regtest_get_last_block_blossom) { + int blossomActivationHeight = Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL / 2; // = 75 + auto params = RegtestActivateBlossom(false, blossomActivationHeight); + int lastFRHeight = Params().GetLastCommunityFeeBlockHeight(); + EXPECT_EQ(0, params.Halving(lastFRHeight)); + EXPECT_EQ(1, params.Halving(lastFRHeight + 1)); + RegtestDeactivateBlossom(); +} + +TEST(founders_reward_test, mainnet_get_last_block) { + SelectParams(CBaseChainParams::MAIN); + auto params = Params().GetConsensus(); + int lastFRHeight = GetLastCommunityFeeHeight(params); + EXPECT_EQ(0, params.Halving(lastFRHeight)); + EXPECT_EQ(1, params.Halving(lastFRHeight + 1)); +} #define NUM_MAINNET_FOUNDER_ADDRESSES 48 @@ -151,13 +175,13 @@ TEST(founders_reward_test, slow_start_subsidy) { SelectParams(CBaseChainParams::MAIN); CChainParams params = Params(); - int maxHeight = params.GetLastCommunityFeeBlockHeight(); + int maxHeight = params.GetLastCommunityFeeBlockHeight(); CAmount totalSubsidy = 0; for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus()) / 5; totalSubsidy += nSubsidy; } - + ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0); } @@ -167,16 +191,21 @@ TEST(founders_reward_test, slow_start_subsidy) { void verifyNumberOfRewards() { CChainParams params = Params(); int maxHeight = params.GetLastCommunityFeeBlockHeight(); - std::multiset ms; + std::map ms; for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { - ms.insert(params.GetCommunityFeeAddressAtHeight(nHeight)); + std::string addr = params.GetCommunityFeeAddressAtHeight(nHeight); + if (ms.count(addr) == 0) { + ms[addr] = 0; + } + ms[addr] = ms[addr] + GetBlockSubsidy(nHeight, params.GetConsensus()) / 5; } - ASSERT_TRUE(ms.count(params.GetCommunityFeeAddressAtIndex(0)) == 17708); - for (int i = 1; i <= 46; i++) { - ASSERT_TRUE(ms.count(params.GetCommunityFeeAddressAtIndex(i)) == 17709); + EXPECT_EQ(ms[params.GetCommunityFeeAddressAtIndex(0)], 1960039937500); + EXPECT_EQ(ms[params.GetCommunityFeeAddressAtIndex(1)], 4394460062500); + for (int i = 2; i <= 46; i++) { + EXPECT_EQ(ms[params.GetCommunityFeeAddressAtIndex(i)], 17709 * COIN * 2.5); } - ASSERT_TRUE(ms.count(params.GetCommunityFeeAddressAtIndex(47)) == 17677); + EXPECT_EQ(ms[params.GetCommunityFeeAddressAtIndex(47)], 17677 * COIN * 2.5); } // Verify the number of rewards going to each mainnet address diff --git a/src/gtest/test_mempool.cpp b/src/gtest/test_mempool.cpp index 97d6ae80c..834e29f64 100644 --- a/src/gtest/test_mempool.cpp +++ b/src/gtest/test_mempool.cpp @@ -174,7 +174,7 @@ TEST(Mempool, OverwinterNotActiveYet) { CTxMemPool pool(::minRelayTxFee); bool missingInputs; CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); // no joinsplits + mtx.vJoinSplit.resize(0); // no joinsplits mtx.fOverwintered = true; mtx.nVersion = OVERWINTER_TX_VERSION; mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; @@ -200,7 +200,7 @@ TEST(Mempool, SproutV3TxFailsAsExpected) { CTxMemPool pool(::minRelayTxFee); bool missingInputs; CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); // no joinsplits + mtx.vJoinSplit.resize(0); // no joinsplits mtx.fOverwintered = false; mtx.nVersion = 3; CValidationState state1; @@ -221,7 +221,7 @@ TEST(Mempool, SproutV3TxWhenOverwinterActive) { CTxMemPool pool(::minRelayTxFee); bool missingInputs; CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); // no joinsplits + mtx.vJoinSplit.resize(0); // no joinsplits mtx.fOverwintered = false; mtx.nVersion = 3; CValidationState state1; @@ -245,7 +245,7 @@ TEST(Mempool, SproutNegativeVersionTxWhenOverwinterActive) { CTxMemPool pool(::minRelayTxFee); bool missingInputs; CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); // no joinsplits + mtx.vJoinSplit.resize(0); // no joinsplits mtx.fOverwintered = false; // A Sprout transaction with version -3 is created using Sprout code (as found in zcashd <= 1.0.14). @@ -294,7 +294,7 @@ TEST(Mempool, ExpiringSoonTxRejection) { CTxMemPool pool(::minRelayTxFee); bool missingInputs; CMutableTransaction mtx = GetValidTransaction(); - mtx.vjoinsplit.resize(0); // no joinsplits + mtx.vJoinSplit.resize(0); // no joinsplits mtx.fOverwintered = true; mtx.nVersion = OVERWINTER_TX_VERSION; mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; diff --git a/src/gtest/test_metrics.cpp b/src/gtest/test_metrics.cpp index 143fe46d6..6b766e4aa 100644 --- a/src/gtest/test_metrics.cpp +++ b/src/gtest/test_metrics.cpp @@ -1,6 +1,7 @@ #include #include "metrics.h" +#include "utiltest.h" #include "utiltime.h" @@ -93,43 +94,16 @@ TEST(Metrics, GetLocalSolPS) { EXPECT_EQ(1, GetLocalSolPS()); } -TEST(Metrics, EstimateNetHeightInner) { - // Ensure that the (rounded) current height is returned if the tip is current - SetMockTime(15000); - EXPECT_EQ(100, EstimateNetHeightInner(100, 14100, 50, 7500, 0, 150)); - SetMockTime(15150); - EXPECT_EQ(100, EstimateNetHeightInner(101, 14250, 50, 7500, 0, 150)); - - // Ensure that correct estimates are returned if the tip is in the past - SetMockTime(15300); // Tip is 2 blocks behind - EXPECT_EQ(100, EstimateNetHeightInner(100, 14100, 50, 7500, 0, 150)); - SetMockTime(15900); // Tip is 6 blocks behind - EXPECT_EQ(110, EstimateNetHeightInner(100, 14100, 50, 7500, 0, 150)); - - // Check estimates during resync - SetMockTime(15000); - EXPECT_EQ(100, EstimateNetHeightInner( 0, 0, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner( 7, 600, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner( 8, 600, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner(10, 750, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner(11, 900, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner(20, 2100, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner(49, 6450, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner(50, 6600, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner(51, 6750, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner(55, 7350, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner(56, 7500, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner(57, 7650, 50, 7500, 0, 150)); - EXPECT_EQ(100, EstimateNetHeightInner(75, 10350, 50, 7500, 0, 150)); - - // More complex calculations: - SetMockTime(20000); - // - Checkpoint spacing: 200 - // -> Average spacing: 175 - // -> estimated height: 127 -> 130 - EXPECT_EQ(130, EstimateNetHeightInner(100, 14100, 50, 5250, 0, 150)); - // - Checkpoint spacing: 50 - // -> Average spacing: 100 - // -> estimated height: 153 -> 150 - EXPECT_EQ(150, EstimateNetHeightInner(100, 14100, 50, 12000, 0, 150)); +TEST(Metrics, EstimateNetHeight) { + auto params = RegtestActivateBlossom(false, 200); + int64_t blockTimes[400]; + for (int i = 0; i < 400; i++) { + blockTimes[i] = i ? blockTimes[i - 1] + params.PoWTargetSpacing(i) : 0; + } + SetMockTime(blockTimes[399]); + for (int i = 0; i < 400; i++) { + // Check that we are within 1 of the correct height + EXPECT_LT(std::abs(399 - EstimateNetHeight(params, i, blockTimes[i])), 2); + } + RegtestDeactivateBlossom(); } diff --git a/src/gtest/test_pow.cpp b/src/gtest/test_pow.cpp index f8dcace49..ad1dbca4b 100644 --- a/src/gtest/test_pow.cpp +++ b/src/gtest/test_pow.cpp @@ -4,10 +4,10 @@ #include "chainparams.h" #include "pow.h" #include "random.h" +#include "utiltest.h" -TEST(PoW, DifficultyAveraging) { - SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); +void TestDifficultyAveragingImpl(const Consensus::Params& params) +{ size_t lastBlk = 2*params.nPowAveragingWindow; size_t firstBlk = lastBlk - params.nPowAveragingWindow; @@ -16,7 +16,7 @@ TEST(PoW, DifficultyAveraging) { for (int i = 0; i <= lastBlk; i++) { blocks[i].pprev = i ? &blocks[i - 1] : nullptr; blocks[i].nHeight = i; - blocks[i].nTime = 1269211443 + i * params.nPowTargetSpacing; + blocks[i].nTime = i ? blocks[i - 1].nTime + params.PoWTargetSpacing(i) : 1269211443; blocks[i].nBits = 0x1e7fffff; /* target 0x007fffff000... */ blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0); } @@ -27,24 +27,26 @@ TEST(PoW, DifficultyAveraging) { EXPECT_EQ(CalculateNextWorkRequired(bnAvg, blocks[lastBlk].GetMedianTimePast(), blocks[firstBlk].GetMedianTimePast(), - params), + params, + blocks[lastBlk].nHeight + 1), GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); // Result should be unchanged, modulo integer division precision loss arith_uint256 bnRes; bnRes.SetCompact(0x1e7fffff); - bnRes /= params.AveragingWindowTimespan(); - bnRes *= params.AveragingWindowTimespan(); + bnRes /= params.AveragingWindowTimespan(blocks[lastBlk].nHeight + 1); + bnRes *= params.AveragingWindowTimespan(blocks[lastBlk].nHeight + 1); EXPECT_EQ(bnRes.GetCompact(), GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); // Randomise the final block time (plus 1 to ensure it is always different) - blocks[lastBlk].nTime += GetRand(params.nPowTargetSpacing/2) + 1; + blocks[lastBlk].nTime += GetRand(params.PoWTargetSpacing(blocks[lastBlk].nHeight + 1)/2) + 1; // Result should be the same as if last difficulty was used bnAvg.SetCompact(blocks[lastBlk].nBits); EXPECT_EQ(CalculateNextWorkRequired(bnAvg, blocks[lastBlk].GetMedianTimePast(), blocks[firstBlk].GetMedianTimePast(), - params), + params, + blocks[lastBlk].nHeight + 1), GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); // Result should not be unchanged EXPECT_NE(0x1e7fffff, GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); @@ -57,7 +59,8 @@ TEST(PoW, DifficultyAveraging) { EXPECT_NE(CalculateNextWorkRequired(bnAvg, blocks[lastBlk].GetMedianTimePast(), blocks[firstBlk].GetMedianTimePast(), - params), + params, + blocks[lastBlk].nHeight + 1), GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); // FIXME: consensus changed @@ -66,10 +69,20 @@ TEST(PoW, DifficultyAveraging) { // EXPECT_EQ(CalculateNextWorkRequired(average, // blocks[lastBlk].GetMedianTimePast(), // blocks[firstBlk].GetMedianTimePast(), -// params), +// params, +// blocks[lastBlk].nHeight + 1), // GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); } +TEST(PoW, DifficultyAveraging) { + SelectParams(CBaseChainParams::MAIN); + TestDifficultyAveragingImpl(Params().GetConsensus()); +} + +TEST(PoW, DifficultyAveragingBlossom) { + TestDifficultyAveragingImpl(RegtestActivateBlossom(true)); + RegtestDeactivateBlossom(); +} TEST(PoW, MinDifficultyRules) { SelectParams(CBaseChainParams::TESTNET); const Consensus::Params& params = Params().GetConsensus(); @@ -81,24 +94,24 @@ TEST(PoW, MinDifficultyRules) { for (int i = 0; i <= lastBlk; i++) { blocks[i].pprev = i ? &blocks[i - 1] : nullptr; blocks[i].nHeight = params.nPowAllowMinDifficultyBlocksAfterHeight.get() + i; - blocks[i].nTime = 1269211443 + i * params.nPowTargetSpacing; + blocks[i].nTime = i ? blocks[i - 1].nTime + params.PoWTargetSpacing(i) : 1269211443; blocks[i].nBits = 0x1e7fffff; /* target 0x007fffff000... */ blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0); } // Create a new block at the target spacing CBlockHeader next; - next.nTime = blocks[lastBlk].nTime + params.nPowTargetSpacing; + next.nTime = blocks[lastBlk].nTime + params.PoWTargetSpacing(blocks[lastBlk].nHeight + 1); // Result should be unchanged, modulo integer division precision loss arith_uint256 bnRes; bnRes.SetCompact(0x1e7fffff); - bnRes /= params.AveragingWindowTimespan(); - bnRes *= params.AveragingWindowTimespan(); + bnRes /= params.AveragingWindowTimespan(blocks[lastBlk].nHeight + 1); + bnRes *= params.AveragingWindowTimespan(blocks[lastBlk].nHeight + 1); EXPECT_EQ(GetNextWorkRequired(&blocks[lastBlk], &next, params), bnRes.GetCompact()); // Delay last block up to the edge of the min-difficulty limit - next.nTime += params.nPowTargetSpacing * 5; + next.nTime += params.PoWTargetSpacing(blocks[lastBlk].nHeight + 1) * 5; // Result should be unchanged, modulo integer division precision loss EXPECT_EQ(GetNextWorkRequired(&blocks[lastBlk], &next, params), bnRes.GetCompact()); diff --git a/src/gtest/test_transaction_builder.cpp b/src/gtest/test_transaction_builder.cpp index 3fe71d21b..a3ccc7fbf 100644 --- a/src/gtest/test_transaction_builder.cpp +++ b/src/gtest/test_transaction_builder.cpp @@ -93,20 +93,20 @@ TEST(TransactionBuilder, TransparentToSapling) // Create a shielding transaction from transparent to Sapling // 0.0005 t-ZEC in, 0.0004 z-ZEC out, 0.0001 t-ZEC fee - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta, &keystore); + auto builder = TransactionBuilder(consensusParams, 1, &keystore); builder.AddTransparentInput(COutPoint(), scriptPubKey, 50000); builder.AddSaplingOutput(fvk_from.ovk, pk, 40000, {}); auto tx = builder.Build().GetTxOrThrow(); EXPECT_EQ(tx.vin.size(), 1); EXPECT_EQ(tx.vout.size(), 0); - EXPECT_EQ(tx.vjoinsplit.size(), 0); + EXPECT_EQ(tx.vJoinSplit.size(), 0); EXPECT_EQ(tx.vShieldedSpend.size(), 0); EXPECT_EQ(tx.vShieldedOutput.size(), 1); EXPECT_EQ(tx.valueBalance, -40000); CValidationState state; - EXPECT_TRUE(ContextualCheckTransaction(tx, state, 2, 0)); + EXPECT_TRUE(ContextualCheckTransaction(tx, state, Params(), 2, 0)); EXPECT_EQ(state.GetRejectReason(), ""); // Revert to default @@ -122,10 +122,10 @@ TEST(TransactionBuilder, SaplingToSapling) { auto pa = sk.default_address(); auto testNote = GetTestSaplingNote(pa, 40000); - + // Create a Sapling-only transaction // 0.0004 z-ZEC in, 0.00025 z-ZEC out, 0.0001 t-ZEC fee, 0.00005 z-ZEC change - auto builder = TransactionBuilder(consensusParams, 2, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 2); builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness()); // Check that trying to add a different anchor fails @@ -137,13 +137,13 @@ TEST(TransactionBuilder, SaplingToSapling) { EXPECT_EQ(tx.vin.size(), 0); EXPECT_EQ(tx.vout.size(), 0); - EXPECT_EQ(tx.vjoinsplit.size(), 0); + EXPECT_EQ(tx.vJoinSplit.size(), 0); EXPECT_EQ(tx.vShieldedSpend.size(), 1); EXPECT_EQ(tx.vShieldedOutput.size(), 2); EXPECT_EQ(tx.valueBalance, 10000); CValidationState state; - EXPECT_TRUE(ContextualCheckTransaction(tx, state, 3, 0)); + EXPECT_TRUE(ContextualCheckTransaction(tx, state, Params(), 3, 0)); EXPECT_EQ(state.GetRejectReason(), ""); // Revert to default @@ -166,22 +166,22 @@ TEST(TransactionBuilder, SaplingToSprout) { // - 0.0004 Sapling-ZEC in - 0.00025 Sprout-ZEC out // - 0.00005 Sapling-ZEC change // - 0.0001 t-ZEC fee - auto builder = TransactionBuilder(consensusParams, 2, expiryDelta, nullptr, params); + auto builder = TransactionBuilder(consensusParams, 2, nullptr, params); builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness()); builder.AddSproutOutput(sproutAddr, 25000); auto tx = builder.Build().GetTxOrThrow(); EXPECT_EQ(tx.vin.size(), 0); EXPECT_EQ(tx.vout.size(), 0); - EXPECT_EQ(tx.vjoinsplit.size(), 1); - EXPECT_EQ(tx.vjoinsplit[0].vpub_old, 25000); - EXPECT_EQ(tx.vjoinsplit[0].vpub_new, 0); + EXPECT_EQ(tx.vJoinSplit.size(), 1); + EXPECT_EQ(tx.vJoinSplit[0].vpub_old, 25000); + EXPECT_EQ(tx.vJoinSplit[0].vpub_new, 0); EXPECT_EQ(tx.vShieldedSpend.size(), 1); EXPECT_EQ(tx.vShieldedOutput.size(), 1); EXPECT_EQ(tx.valueBalance, 35000); CValidationState state; - EXPECT_TRUE(ContextualCheckTransaction(tx, state, 3, 0)); + EXPECT_TRUE(ContextualCheckTransaction(tx, state, Params(), 3, 0)); EXPECT_EQ(state.GetRejectReason(), ""); // Revert to default @@ -200,10 +200,10 @@ TEST(TransactionBuilder, SproutToSproutAndSapling) { auto wtx = GetValidSproutReceive(*params, sproutSk, 25000, true); auto sproutNote = GetSproutNote(*params, sproutSk, wtx, 0, 1); - + SproutMerkleTree sproutTree; for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { - sproutTree.append(wtx.vjoinsplit[0].commitments[i]); + sproutTree.append(wtx.vJoinSplit[0].commitments[i]); } SproutWitness sproutWitness = sproutTree.witness(); // Fake a view with the Sprout note in it @@ -218,7 +218,7 @@ TEST(TransactionBuilder, SproutToSproutAndSapling) { // - 0.00005 Sprout-ZEC change // - 0.00005 Sapling-ZEC out // - 0.00005 t-ZEC fee - auto builder = TransactionBuilder(consensusParams, 2, expiryDelta, nullptr, params, &view); + auto builder = TransactionBuilder(consensusParams, 2, nullptr, params, &view); builder.SetFee(5000); builder.AddSproutInput(sproutSk, sproutNote, sproutWitness); builder.AddSproutOutput(sproutAddr, 6000); @@ -230,19 +230,19 @@ TEST(TransactionBuilder, SproutToSproutAndSapling) { EXPECT_EQ(tx.vout.size(), 0); // TODO: This should be doable in two JoinSplits. // There's an inefficiency in the implementation. - EXPECT_EQ(tx.vjoinsplit.size(), 3); - EXPECT_EQ(tx.vjoinsplit[0].vpub_old, 0); - EXPECT_EQ(tx.vjoinsplit[0].vpub_new, 0); - EXPECT_EQ(tx.vjoinsplit[1].vpub_old, 0); - EXPECT_EQ(tx.vjoinsplit[1].vpub_new, 0); - EXPECT_EQ(tx.vjoinsplit[2].vpub_old, 0); - EXPECT_EQ(tx.vjoinsplit[2].vpub_new, 10000); + EXPECT_EQ(tx.vJoinSplit.size(), 3); + EXPECT_EQ(tx.vJoinSplit[0].vpub_old, 0); + EXPECT_EQ(tx.vJoinSplit[0].vpub_new, 0); + EXPECT_EQ(tx.vJoinSplit[1].vpub_old, 0); + EXPECT_EQ(tx.vJoinSplit[1].vpub_new, 0); + EXPECT_EQ(tx.vJoinSplit[2].vpub_old, 0); + EXPECT_EQ(tx.vJoinSplit[2].vpub_new, 10000); EXPECT_EQ(tx.vShieldedSpend.size(), 0); EXPECT_EQ(tx.vShieldedOutput.size(), 1); EXPECT_EQ(tx.valueBalance, -5000); CValidationState state; - EXPECT_TRUE(ContextualCheckTransaction(tx, state, 4, 0)); + EXPECT_TRUE(ContextualCheckTransaction(tx, state, Params(), 4, 0)); EXPECT_EQ(state.GetRejectReason(), ""); // Revert to default @@ -255,7 +255,7 @@ TEST(TransactionBuilder, ThrowsOnSproutOutputWithoutParams) auto sk = libzcash::SproutSpendingKey::random(); auto addr = sk.address(); - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); ASSERT_THROW(builder.AddSproutOutput(addr, 10), std::runtime_error); } @@ -264,7 +264,7 @@ TEST(TransactionBuilder, ThrowsOnTransparentInputWithoutKeyStore) SelectParams(CBaseChainParams::REGTEST); auto consensusParams = Params().GetConsensus(); - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); ASSERT_THROW(builder.AddTransparentInput(COutPoint(), CScript(), 1), std::runtime_error); } @@ -275,7 +275,7 @@ TEST(TransactionBuilder, RejectsInvalidTransparentOutput) // Default CTxDestination type is an invalid address CTxDestination taddr; - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); ASSERT_THROW(builder.AddTransparentOutput(taddr, 50), UniValue); } @@ -286,7 +286,7 @@ TEST(TransactionBuilder, RejectsInvalidTransparentChangeAddress) // Default CTxDestination type is an invalid address CTxDestination taddr; - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); ASSERT_THROW(builder.SendChangeTo(taddr), UniValue); } @@ -311,13 +311,13 @@ TEST(TransactionBuilder, FailsWithNegativeChange) // Fail if there is only a Sapling output // 0.0005 z-ZEC out, 0.0001 t-ZEC fee - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); builder.AddSaplingOutput(fvk.ovk, pa, 50000, {}); EXPECT_EQ("Change cannot be negative", builder.Build().GetError()); // Fail if there is only a transparent output // 0.0005 t-ZEC out, 0.0001 t-ZEC fee - builder = TransactionBuilder(consensusParams, 1, expiryDelta, &keystore); + builder = TransactionBuilder(consensusParams, 1, &keystore); builder.AddTransparentOutput(taddr, 50000); EXPECT_EQ("Change cannot be negative", builder.Build().GetError()); @@ -359,21 +359,21 @@ TEST(TransactionBuilder, ChangeOutput) // No change address and no Sapling spends { - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta, &keystore); + auto builder = TransactionBuilder(consensusParams, 1, &keystore); builder.AddTransparentInput(COutPoint(), scriptPubKey, 25000); EXPECT_EQ("Could not determine change address", builder.Build().GetError()); } // Change to the same address as the first Sapling spend { - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta, &keystore); + auto builder = TransactionBuilder(consensusParams, 1, &keystore); builder.AddTransparentInput(COutPoint(), scriptPubKey, 25000); builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness()); auto tx = builder.Build().GetTxOrThrow(); EXPECT_EQ(tx.vin.size(), 1); EXPECT_EQ(tx.vout.size(), 0); - EXPECT_EQ(tx.vjoinsplit.size(), 0); + EXPECT_EQ(tx.vJoinSplit.size(), 0); EXPECT_EQ(tx.vShieldedSpend.size(), 1); EXPECT_EQ(tx.vShieldedOutput.size(), 1); EXPECT_EQ(tx.valueBalance, -15000); @@ -381,14 +381,14 @@ TEST(TransactionBuilder, ChangeOutput) // Change to a Sapling address { - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta, &keystore); + auto builder = TransactionBuilder(consensusParams, 1, &keystore); builder.AddTransparentInput(COutPoint(), scriptPubKey, 25000); builder.SendChangeTo(zChangeAddr, fvkOut.ovk); auto tx = builder.Build().GetTxOrThrow(); EXPECT_EQ(tx.vin.size(), 1); EXPECT_EQ(tx.vout.size(), 0); - EXPECT_EQ(tx.vjoinsplit.size(), 0); + EXPECT_EQ(tx.vJoinSplit.size(), 0); EXPECT_EQ(tx.vShieldedSpend.size(), 0); EXPECT_EQ(tx.vShieldedOutput.size(), 1); EXPECT_EQ(tx.valueBalance, -15000); @@ -396,14 +396,14 @@ TEST(TransactionBuilder, ChangeOutput) // Change to a transparent address { - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta, &keystore); + auto builder = TransactionBuilder(consensusParams, 1, &keystore); builder.AddTransparentInput(COutPoint(), scriptPubKey, 25000); builder.SendChangeTo(taddr); auto tx = builder.Build().GetTxOrThrow(); EXPECT_EQ(tx.vin.size(), 1); EXPECT_EQ(tx.vout.size(), 1); - EXPECT_EQ(tx.vjoinsplit.size(), 0); + EXPECT_EQ(tx.vJoinSplit.size(), 0); EXPECT_EQ(tx.vShieldedSpend.size(), 0); EXPECT_EQ(tx.vShieldedOutput.size(), 0); EXPECT_EQ(tx.valueBalance, 0); @@ -428,14 +428,14 @@ TEST(TransactionBuilder, SetFee) // Default fee { - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness()); builder.AddSaplingOutput(fvk.ovk, pa, 25000, {}); auto tx = builder.Build().GetTxOrThrow(); EXPECT_EQ(tx.vin.size(), 0); EXPECT_EQ(tx.vout.size(), 0); - EXPECT_EQ(tx.vjoinsplit.size(), 0); + EXPECT_EQ(tx.vJoinSplit.size(), 0); EXPECT_EQ(tx.vShieldedSpend.size(), 1); EXPECT_EQ(tx.vShieldedOutput.size(), 2); EXPECT_EQ(tx.valueBalance, 10000); @@ -443,7 +443,7 @@ TEST(TransactionBuilder, SetFee) // Configured fee { - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness()); builder.AddSaplingOutput(fvk.ovk, pa, 25000, {}); builder.SetFee(20000); @@ -451,7 +451,7 @@ TEST(TransactionBuilder, SetFee) EXPECT_EQ(tx.vin.size(), 0); EXPECT_EQ(tx.vout.size(), 0); - EXPECT_EQ(tx.vjoinsplit.size(), 0); + EXPECT_EQ(tx.vJoinSplit.size(), 0); EXPECT_EQ(tx.vShieldedSpend.size(), 1); EXPECT_EQ(tx.vShieldedOutput.size(), 2); EXPECT_EQ(tx.valueBalance, 20000); @@ -472,7 +472,7 @@ TEST(TransactionBuilder, CheckSaplingTxVersion) auto pk = sk.default_address(); // Cannot add Sapling outputs to a non-Sapling transaction - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); try { builder.AddSaplingOutput(uint256(), pk, 12345, {}); } catch (std::runtime_error const & err) { diff --git a/src/gtest/test_validation.cpp b/src/gtest/test_validation.cpp index 4e937d042..43c42741d 100644 --- a/src/gtest/test_validation.cpp +++ b/src/gtest/test_validation.cpp @@ -7,7 +7,12 @@ extern ZCJoinSplit* params; -extern bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos); +extern bool ReceivedBlockTransactions( + const CBlock &block, + CValidationState& state, + const CChainParams& chainparams, + CBlockIndex *pindexNew, + const CDiskBlockPos& pos); void ExpectOptionalAmount(CAmount expected, boost::optional actual) { EXPECT_TRUE((bool)actual); @@ -87,6 +92,7 @@ TEST(Validation, ContextualCheckInputsPassesWithCoinbase) { } TEST(Validation, ReceivedBlockTransactions) { + auto chainParams = Params(); auto sk = libzcash::SproutSpendingKey::random(); // Create a fake genesis block @@ -122,7 +128,7 @@ TEST(Validation, ReceivedBlockTransactions) { // Mark the second block's transactions as received first CValidationState state; - EXPECT_TRUE(ReceivedBlockTransactions(block2, state, &fakeIndex2, pos2)); + EXPECT_TRUE(ReceivedBlockTransactions(block2, state, chainParams, &fakeIndex2, pos2)); EXPECT_FALSE(fakeIndex1.IsValid(BLOCK_VALID_TRANSACTIONS)); EXPECT_TRUE(fakeIndex2.IsValid(BLOCK_VALID_TRANSACTIONS)); @@ -137,7 +143,7 @@ TEST(Validation, ReceivedBlockTransactions) { EXPECT_FALSE((bool)fakeIndex2.nChainSproutValue); // Now mark the first block's transactions as received - EXPECT_TRUE(ReceivedBlockTransactions(block1, state, &fakeIndex1, pos1)); + EXPECT_TRUE(ReceivedBlockTransactions(block1, state, chainParams, &fakeIndex1, pos1)); EXPECT_TRUE(fakeIndex1.IsValid(BLOCK_VALID_TRANSACTIONS)); EXPECT_TRUE(fakeIndex2.IsValid(BLOCK_VALID_TRANSACTIONS)); diff --git a/src/hash.cpp b/src/hash.cpp index 9711293e3..2070e0918 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2013-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "hash.h" #include "crypto/common.h" diff --git a/src/hash.h b/src/hash.h index 3e56f4a86..fe1607277 100644 --- a/src/hash.h +++ b/src/hash.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_HASH_H #define BITCOIN_HASH_H diff --git a/src/httprpc.h b/src/httprpc.h index d35445718..cde795ae6 100644 --- a/src/httprpc.h +++ b/src/httprpc.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_HTTPRPC_H #define BITCOIN_HTTPRPC_H diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 2ee8d178f..9227e26bb 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "httpserver.h" diff --git a/src/httpserver.h b/src/httpserver.h index 93fb5d8d6..68d26ce2e 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_HTTPSERVER_H #define BITCOIN_HTTPSERVER_H diff --git a/src/init.cpp b/src/init.cpp index b0ccba090..ad7fbb7ae 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" @@ -350,9 +350,6 @@ std::string HelpMessage(HelpMessageMode mode) #endif } strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); - strUsage += HelpMessageOpt("-disabledeprecation=", - strprintf(_("Disable block-height node deprecation and automatic shutdown (example: -disabledeprecation=%s)"), - FormatVersion(CLIENT_VERSION))); strUsage += HelpMessageOpt("-exportdir=", _("Specify directory to be used when exporting data")); strUsage += HelpMessageOpt("-dbcache=", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); strUsage += HelpMessageOpt("-loadblock=", _("Imports blocks from external blk000??.dat file") + " " + _("on startup")); @@ -421,7 +418,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-txexpirydelta", strprintf(_("Set the number of blocks after which a transaction that has not been mined will become invalid (min: %u, default: %u)"), TX_EXPIRING_SOON_THRESHOLD + 1, DEFAULT_TX_EXPIRY_DELTA)); + strUsage += HelpMessageOpt("-txexpirydelta", strprintf(_("Set the number of blocks after which a transaction that has not been mined will become invalid (min: %u, default: %u (pre-Blossom) or %u (post-Blossom))"), TX_EXPIRING_SOON_THRESHOLD + 1, DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA, DEFAULT_POST_BLOSSOM_TX_EXPIRY_DELTA)); strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"), CURRENCY_UNIT, FormatMoney(maxTxFee))); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); @@ -486,7 +483,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. " "This is intended for regression testing tools and app development."); } - strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)")); + // strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)")); strUsage += HelpMessageOpt("-testnet", _("Use the test network")); strUsage += HelpMessageGroup(_("Node relay options:")); @@ -609,6 +606,7 @@ void CleanupBlockRevFiles() void ThreadImport(std::vector vImportFiles) { + const CChainParams& chainparams = Params(); RenameThread("zcash-loadblk"); // -reindex if (fReindex) { @@ -622,14 +620,14 @@ void ThreadImport(std::vector vImportFiles) if (!file) break; // This error is logged in OpenBlockFile LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile); - LoadExternalBlockFile(file, &pos); + LoadExternalBlockFile(chainparams, file, &pos); nFile++; } pblocktree->WriteReindexing(false); fReindex = false; LogPrintf("Reindexing finished\n"); // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked): - InitBlockIndex(); + InitBlockIndex(chainparams); } // hardcoded $DATADIR/bootstrap.dat @@ -640,7 +638,7 @@ void ThreadImport(std::vector vImportFiles) CImportingNow imp; boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; LogPrintf("Importing bootstrap.dat...\n"); - LoadExternalBlockFile(file); + LoadExternalBlockFile(chainparams, file); RenameOver(pathBootstrap, pathBootstrapOld); } else { LogPrintf("Warning: Could not open bootstrap file %s\n", pathBootstrap.string()); @@ -653,7 +651,7 @@ void ThreadImport(std::vector vImportFiles) if (file) { CImportingNow imp; LogPrintf("Importing blocks file %s...\n", path.string()); - LoadExternalBlockFile(file); + LoadExternalBlockFile(chainparams,file); } else { LogPrintf("Warning: Could not open blocks file %s\n", path.string()); } @@ -665,6 +663,22 @@ void ThreadImport(std::vector vImportFiles) } } +void ThreadNotifyRecentlyAdded() +{ + while (true) { + // Run the notifier on an integer second in the steady clock. + auto now = std::chrono::steady_clock::now().time_since_epoch(); + auto nextFire = std::chrono::duration_cast( + now + std::chrono::seconds(1)); + std::this_thread::sleep_until( + std::chrono::time_point(nextFire)); + + boost::this_thread::interruption_point(); + + mempool.NotifyRecentlyAdded(); + } +} + /** Sanity checks * Ensure that Bitcoin is running in a usable environment with all * necessary library support. @@ -1067,10 +1081,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); - expiryDelta = GetArg("-txexpirydelta", DEFAULT_TX_EXPIRY_DELTA); - uint32_t minExpiryDelta = TX_EXPIRING_SOON_THRESHOLD + 1; - if (expiryDelta < minExpiryDelta) { - return InitError(strprintf(_("Invalid value for -expiryDelta='%u' (must be least %u)"), expiryDelta, minExpiryDelta)); + if (mapArgs.count("-txexpirydelta")) { + int64_t expiryDelta = atoi64(mapArgs["-txexpirydelta"]); + uint32_t minExpiryDelta = TX_EXPIRING_SOON_THRESHOLD + 1; + if (expiryDelta < minExpiryDelta) { + return InitError(strprintf(_("Invalid value for -txexpirydelta='%u' (must be least %u)"), expiryDelta, minExpiryDelta)); + } + expiryDeltaArg = expiryDelta; } bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", true); fSendFreeTransactions = GetBoolArg("-sendfreetransactions", false); @@ -1190,8 +1207,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) #ifndef WIN32 CreatePidFile(GetPidFile(), getpid()); #endif - if (GetBoolArg("-shrinkdebugfile", !fDebug)) - ShrinkDebugFile(); + // if (GetBoolArg("-shrinkdebugfile", !fDebug)) + // ShrinkDebugFile(); if (fPrintToDebugLog) OpenDebugLog(); @@ -1518,7 +1535,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); // Initialize the block index (no-op if non-empty database was already loaded) - if (!InitBlockIndex()) { + if (!InitBlockIndex(chainparams)) { strLoadError = _("Error initializing block database"); break; } @@ -1555,7 +1572,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n", MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", 288)); } - if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3), + if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview, GetArg("-checklevel", 3), GetArg("-checkblocks", 288))) { strLoadError = _("Corrupted block database detected"); break; @@ -1825,7 +1842,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.InitMessage(_("Activating best chain...")); // scan for better chains in the block chain database, that are not yet connected in the active best chain CValidationState state; - if (!ActivateBestChain(state)) + if (!ActivateBestChain(state, chainparams)) strErrors << "Failed to connect best block"; std::vector vImportFiles; @@ -1858,20 +1875,23 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0); #endif + // Start the thread that notifies listeners of transactions that have been + // recently added to the mempool. + threadGroup.create_thread(boost::bind(&TraceThread, "txnotify", &ThreadNotifyRecentlyAdded)); + if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) StartTorControl(threadGroup, scheduler); StartNode(threadGroup, scheduler); - // Monitor the chain, and alert if we get blocks much quicker or slower than expected - int64_t nPowTargetSpacing = Params().GetConsensus().nPowTargetSpacing; - CScheduler::Function f = boost::bind(&PartitionCheck, &IsInitialBlockDownload, - boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing); - scheduler.scheduleEvery(f, nPowTargetSpacing); + // Monitor the chain every minute, and alert if we get blocks much quicker or slower than expected. + //CScheduler::Function frecBlock = boost::bind(&PartitionCheck, &IsInitialBlockDownload, + // boost::ref(cs_main), boost::cref(pindexBestHeader)); + //scheduler.scheduleEvery(frecBlock, 60); #ifdef ENABLE_MINING // Generate coins in the background - GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params()); + GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), chainparams); #endif // ********************************************************* Step 11: finished diff --git a/src/init.h b/src/init.h index 710e43c69..134620519 100644 --- a/src/init.h +++ b/src/init.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_INIT_H #define BITCOIN_INIT_H diff --git a/src/key.cpp b/src/key.cpp index 5688b1302..3508b5e9d 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -1,7 +1,8 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2017 The Zcash developers +// Copyright (c) 2020 The BitcoinZ Community +// Copyright (c) 2019 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "key.h" diff --git a/src/key.h b/src/key.h index 8d64151e3..762fd1ecb 100644 --- a/src/key.h +++ b/src/key.h @@ -2,7 +2,7 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_KEY_H #define BITCOIN_KEY_H diff --git a/src/key_io.cpp b/src/key_io.cpp index 7ffb61974..f118e3625 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2014-2016 The Bitcoin Core developers // Copyright (c) 2016-2018 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include diff --git a/src/key_io.h b/src/key_io.h index 47ca84fb8..57ec67107 100644 --- a/src/key_io.h +++ b/src/key_io.h @@ -1,8 +1,9 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers -// Copyright (c) 2016-2018 The Zcash developers +// Copyright (c) 2017-2020 The BitcoinZ Community +// Copyright (c) 2016-2019 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_KEYIO_H #define BITCOIN_KEYIO_H diff --git a/src/keystore.cpp b/src/keystore.cpp index e1e3ae89b..6c94bf05a 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "keystore.h" diff --git a/src/keystore.h b/src/keystore.h index 6ff34b20d..7c78895dc 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_KEYSTORE_H #define BITCOIN_KEYSTORE_H diff --git a/src/limitedmap.h b/src/limitedmap.h index e8ea54965..0e88c056e 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_LIMITEDMAP_H #define BITCOIN_LIMITEDMAP_H diff --git a/src/main.cpp b/src/main.cpp index 00306e6da..199ed477d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "main.h" @@ -21,7 +21,6 @@ #include "metrics.h" #include "net.h" #include "pow.h" -#include "txdb.h" #include "txmempool.h" #include "ui_interface.h" #include "undo.h" @@ -84,7 +83,7 @@ bool fAlerts = DEFAULT_ALERTS; */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; -unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; +boost::optional expiryDeltaArg = boost::none; /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); @@ -104,7 +103,7 @@ void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards. */ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams); -static void CheckBlockIndex(); +static void CheckBlockIndex(const Consensus::Params& consensusParams); /** Constant stuff for coinbase transactions we create: */ CScript COINBASE_FLAGS; @@ -200,10 +199,10 @@ namespace { /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */ struct QueuedBlock { uint256 hash; - CBlockIndex *pindex; //! Optional. - int64_t nTime; //! Time of "getdata" request in microseconds. - bool fValidatedHeaders; //! Whether this block has validated headers at the time of request. - int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer) + CBlockIndex* pindex; //!< Optional. + int64_t nTime; //!< Time of "getdata" request in microseconds. + bool fValidatedHeaders; //!< Whether this block has validated headers at the time of request. + int64_t nTimeDisconnect; //!< The timeout for this block request (for disconnecting a slow peer) }; map::iterator> > mapBlocksInFlight; @@ -311,11 +310,11 @@ void UpdatePreferredDownload(CNode* node, CNodeState* state) } // Returns time at which to timeout block request (nTime in microseconds) -int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams) -{ - return nTime + 500000 * consensusParams.nPowTargetSpacing * (4 + nValidatedQueuedBefore); +int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams, int nHeight) { + return nTime + 500000 * consensusParams.PoWTargetSpacing(nHeight) * (4 + nValidatedQueuedBefore); } + void InitializeNode(NodeId nodeid, const CNode *pnode) { LOCK(cs_main); CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second; @@ -368,7 +367,8 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Pa MarkBlockAsReceived(hash); int64_t nNow = GetTimeMicros(); - QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)}; + int nHeight = pindex != NULL ? pindex->nHeight : chainActive.Height(); // Help block timeout computation + QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams, nHeight)}; nQueuedValidatedHeaders += newentry.fValidatedHeaders; list::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry); state->nBlocksInFlight++; @@ -654,10 +654,10 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRE } -bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight) -{ - bool overwinterActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER); - bool saplingActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING); +bool IsStandardTx(const CTransaction& tx, string& reason, const CChainParams& chainparams, const int nHeight) { + + bool overwinterActive = chainparams.GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_OVERWINTER); + bool saplingActive = chainparams.GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_SAPLING); if (saplingActive) { // Sapling standard rules apply @@ -881,7 +881,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in /** * Check a transaction contextually against a set of consensus rules valid at a given block height. - * + * * Notes: * 1. AcceptToMemoryPool calls CheckTransaction and this function. * 2. ProcessNewBlock calls AcceptBlock, which calls CheckBlock (which calls CheckTransaction) @@ -891,17 +891,18 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in bool ContextualCheckTransaction( const CTransaction& tx, CValidationState &state, + const CChainParams& chainparams, const int nHeight, const int dosLevel, - bool (*isInitBlockDownload)()) -{ - bool overwinterActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER); - bool saplingActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING); + bool (*isInitBlockDownload)(const CChainParams&)) { + + bool overwinterActive = chainparams.GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_OVERWINTER); + bool saplingActive = chainparams.GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_SAPLING); bool isSprout = !overwinterActive; // If Sprout rules apply, reject transactions which are intended for Overwinter and beyond if (isSprout && tx.fOverwintered) { - return state.DoS(isInitBlockDownload() ? 0 : dosLevel, + return state.DoS(isInitBlockDownload(chainparams) ? 0 : dosLevel, error("ContextualCheckTransaction(): overwinter is not active yet"), REJECT_INVALID, "tx-overwinter-not-active"); } @@ -915,7 +916,7 @@ bool ContextualCheckTransaction( // Reject transactions with non-Sapling version group ID if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) { - return state.DoS(isInitBlockDownload() ? 0 : dosLevel, + return state.DoS(isInitBlockDownload(chainparams) ? 0 : dosLevel, error("CheckTransaction(): invalid Sapling tx version"), REJECT_INVALID, "bad-sapling-tx-version-group-id"); } @@ -940,7 +941,7 @@ bool ContextualCheckTransaction( // Reject transactions with non-Overwinter version group ID if (tx.fOverwintered && tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) { - return state.DoS(isInitBlockDownload() ? 0 : dosLevel, + return state.DoS(isInitBlockDownload(chainparams) ? 0 : dosLevel, error("CheckTransaction(): invalid Overwinter tx version"), REJECT_INVALID, "bad-overwinter-tx-version-group-id"); } @@ -959,7 +960,7 @@ bool ContextualCheckTransaction( return state.DoS(dosLevel, error("ContextualCheckTransaction: overwinter is active"), REJECT_INVALID, "tx-overwinter-active"); } - + // Check that all transactions are unexpired if (IsExpiredTx(tx, nHeight)) { // Don't increase banscore if the transaction only just expired @@ -979,11 +980,11 @@ bool ContextualCheckTransaction( uint256 dataToBeSigned; - if (!tx.vjoinsplit.empty() || + if (!tx.vJoinSplit.empty() || !tx.vShieldedSpend.empty() || !tx.vShieldedOutput.empty()) { - auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus()); + auto consensusBranchId = CurrentEpochBranchId(nHeight, chainparams.GetConsensus()); // Empty output script. CScript scriptCode; try { @@ -994,7 +995,7 @@ bool ContextualCheckTransaction( } } - if (!tx.vjoinsplit.empty()) + if (!tx.vJoinSplit.empty()) { BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32); @@ -1004,7 +1005,7 @@ bool ContextualCheckTransaction( dataToBeSigned.begin(), 32, tx.joinSplitPubKey.begin() ) != 0) { - return state.DoS(isInitBlockDownload() ? 0 : 100, + return state.DoS(isInitBlockDownload(chainparams) ? 0 : 100, error("CheckTransaction(): invalid joinsplit signature"), REJECT_INVALID, "bad-txns-invalid-joinsplit-signature"); } @@ -1078,7 +1079,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, return false; } else { // Ensure that zk-SNARKs verify - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { + BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) { if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) { return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"), REJECT_INVALID, "bad-txns-joinsplit-verification-failed"); @@ -1135,13 +1136,13 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio } // Transactions containing empty `vin` must have either non-empty - // `vjoinsplit` or non-empty `vShieldedSpend`. - if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty()) + // `vJoinSplit` or non-empty `vShieldedSpend`. + if (tx.vin.empty() && tx.vJoinSplit.empty() && tx.vShieldedSpend.empty()) return state.DoS(10, error("CheckTransaction(): vin empty"), REJECT_INVALID, "bad-txns-vin-empty"); // Transactions containing empty `vout` must have either non-empty - // `vjoinsplit` or non-empty `vShieldedOutput`. - if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedOutput.empty()) + // `vJoinSplit` or non-empty `vShieldedOutput`. + if (tx.vout.empty() && tx.vJoinSplit.empty() && tx.vShieldedOutput.empty()) return state.DoS(10, error("CheckTransaction(): vout empty"), REJECT_INVALID, "bad-txns-vout-empty"); @@ -1191,7 +1192,7 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio } // Ensure that joinsplit values are well-formed - BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) + BOOST_FOREACH(const JSDescription& joinsplit, tx.vJoinSplit) { if (joinsplit.vpub_old < 0) { return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old negative"), @@ -1231,7 +1232,7 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio // to the value pool. { CAmount nValueIn = 0; - for (std::vector::const_iterator it(tx.vjoinsplit.begin()); it != tx.vjoinsplit.end(); ++it) + for (std::vector::const_iterator it(tx.vJoinSplit.begin()); it != tx.vJoinSplit.end(); ++it) { nValueIn += it->vpub_new; @@ -1266,7 +1267,7 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio // Check for duplicate joinsplit nullifiers in this transaction { set vJoinSplitNullifiers; - BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) + BOOST_FOREACH(const JSDescription& joinsplit, tx.vJoinSplit) { BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers) { @@ -1295,7 +1296,7 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio if (tx.IsCoinBase()) { // There should be no joinsplits in a coinbase transaction - if (tx.vjoinsplit.size() > 0) + if (tx.vJoinSplit.size() > 0) return state.DoS(100, error("CheckTransaction(): coinbase has joinsplits"), REJECT_INVALID, "bad-cb-has-joinsplits"); @@ -1365,7 +1366,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Node operator can choose to reject tx by number of transparent inputs static_assert(std::numeric_limits::max() >= std::numeric_limits::max(), "size_t too small"); size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0); - if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + if (Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_OVERWINTER)) { limit = 0; } if (limit > 0) { @@ -1382,7 +1383,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // DoS level set to 10 to be more forgiving. // Check transaction contextually against the set of consensus rules which apply in the next block to be mined. - if (!ContextualCheckTransaction(tx, state, nextBlockHeight, 10)) { + if (!ContextualCheckTransaction(tx, state, Params(), nextBlockHeight, 10)) { return error("AcceptToMemoryPool: ContextualCheckTransaction failed"); } @@ -1400,7 +1401,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Rather not work on nonstandard transactions (unless -testnet/-regtest) string reason; - if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight)) + if (Params().RequireStandard() && !IsStandardTx(tx, reason, Params(), nextBlockHeight)) return state.DoS(0, error("AcceptToMemoryPool: nonstandard transaction: %s", reason), REJECT_NONSTANDARD, reason); @@ -1428,7 +1429,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return false; } } - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { + BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) { BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) { if (pool.nullifierExists(nf, SPROUT)) { return false; @@ -1474,8 +1475,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // are the joinsplits' and sapling spends' requirements met in tx(valid anchors/nullifiers)? if (!view.HaveShieldedRequirements(tx)) - return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"), - REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met"); + return state.Invalid(error("AcceptToMemoryPool: shielded requirements not met"), + REJECT_DUPLICATE, "bad-txns-shielded-requirements-not-met"); // Bring the best block into scope view.GetBestBlock(); @@ -1527,7 +1528,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa unsigned int nSize = entry.GetTxSize(); // Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany. - if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) { + if (tx.vJoinSplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) { // In future we will we have more accurate and dynamic computation of fees for tx with joinsplits. } else { // Don't accept it if it can't get into a block @@ -1598,16 +1599,76 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } // Store transaction in memory - pool.addUnchecked(hash, entry, !IsInitialBlockDownload()); + pool.addUnchecked(hash, entry, !IsInitialBlockDownload(Params())); + + // Add memory address index + if (fAddressIndex) { + pool.addAddressIndex(entry, view); + } + + // insightexplorer: Add memory spent index + if (fSpentIndex) { + pool.addSpentIndex(entry, view); + } } - SyncWithWallets(tx, NULL); + return true; +} + +bool GetTimestampIndex(unsigned int high, unsigned int low, bool fActiveOnly, + std::vector > &hashes) +{ + if (!fTimestampIndex) + return error("Timestamp index not enabled"); + + if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes)) + return error("Unable to get hashes for timestamps"); + + return true; +} + +bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) +{ + AssertLockHeld(cs_main); + if (!fSpentIndex) + return error("Spent index not enabled"); + + if (mempool.getSpentIndex(key, value)) + return true; + + if (!pblocktree->ReadSpentIndex(key, value)) + return error("Unable to get spent index information"); + + return true; +} + +bool GetAddressIndex(const uint160& addressHash, int type, + std::vector& addressIndex, + int start, int end) +{ + if (!fAddressIndex) + return error("address index not enabled"); + + if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end)) + return error("unable to get txids for address"); + + return true; +} + +bool GetAddressUnspent(const uint160& addressHash, int type, + std::vector& unspentOutputs) +{ + if (!fAddressIndex) + return error("address index not enabled"); + + if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) + return error("unable to get txids for address"); return true; } /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ -bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) +bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; @@ -1653,7 +1714,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock if (pindexSlow) { CBlock block; - if (ReadBlockFromDisk(block, pindexSlow)) { + if (ReadBlockFromDisk(block, pindexSlow, consensusParams)) { BOOST_FOREACH(const CTransaction &tx, block.vtx) { if (tx.GetHash() == hash) { txOut = tx; @@ -1677,7 +1738,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock // CBlock and CBlockIndex // -bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart) +bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart) { // Open history file to append CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); @@ -1698,10 +1759,9 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::M return true; } -bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) +bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams) { block.SetNull(); - // Open history file to read CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); if (filein.IsNull()) @@ -1718,17 +1778,15 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) // Check the header unsigned int nHeight = chainActive.Height(); if (block.GetHash() != Params().GenesisBlock().GetHash()) { - if (!(CheckEquihashSolution(&block, Params()) && - CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus()))) + if (!(CheckEquihashSolution(&block, consensusParams) && + CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))) return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString()); } - return true; } -bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) -{ - if (!ReadBlockFromDisk(block, pindex->GetBlockPos())) +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams){ + if (!ReadBlockFromDisk(block, pindex->GetBlockPos(), consensusParams)) return false; if (block.GetHash() != pindex->GetBlockHash()) return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s", @@ -1754,20 +1812,27 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams) } assert(nHeight > consensusParams.SubsidySlowStartShift()); - int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval; + int halvings = consensusParams.Halving(nHeight); // Force block reward to zero when right shift is undefined. if (halvings >= 64) return 0; - // Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years. - nSubsidy >>= halvings; - return nSubsidy; + // zip208 + // BlockSubsidy(height) := + // SlowStartRate · height, if height < SlowStartInterval / 2 + // SlowStartRate · (height + 1), if SlowStartInterval / 2 ≤ height and height < SlowStartInterval + // floor(MaxBlockSubsidy / 2^Halving(height)), if SlowStartInterval ≤ height and not IsBlossomActivated(height) + // floor(MaxBlockSubsidy / (BlossomPoWTargetSpacingRatio · 2^Halving(height))), otherwise + if (consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM)) { + return (nSubsidy / Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO) >> halvings; + } else { + // Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years. + return nSubsidy >> halvings; + } } -bool IsInitialBlockDownload() +bool IsInitialBlockDownload(const CChainParams& chainParams) { - const CChainParams& chainParams = Params(); - // Once this function has returned false, it must remain false. static std::atomic latchToFalse{false}; // Optimization: pre-test latch before taking the lock. @@ -1795,12 +1860,12 @@ static bool fLargeWorkInvalidChainFound = false; static CBlockIndex *pindexBestForkTip = NULL; static CBlockIndex *pindexBestForkBase = NULL; -void CheckForkWarningConditions() +void CheckForkWarningConditions(const CChainParams& chainParams) { AssertLockHeld(cs_main); // Before we get past initial download, we cannot reliably alert about forks // (we assume we don't get stuck on a fork before finishing our initial sync) - if (IsInitialBlockDownload()) + if (IsInitialBlockDownload(chainParams)) return; // If our best fork is no longer within 288 blocks (+/- 12 hours if no one mines it) @@ -1838,7 +1903,7 @@ void CheckForkWarningConditions() } } -void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip) +void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip, const CChainParams& chainParams) { AssertLockHeld(cs_main); // If we are on a fork that is sufficiently large, set a warning flag @@ -1868,7 +1933,7 @@ void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip) pindexBestForkBase = pfork; } - CheckForkWarningConditions(); + CheckForkWarningConditions(chainParams); } // Requires cs_main. @@ -1891,7 +1956,7 @@ void Misbehaving(NodeId pnode, int howmuch) LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior); } -void static InvalidChainFound(CBlockIndex* pindexNew) +void static InvalidChainFound(CBlockIndex* pindexNew, const CChainParams& chainParams) { if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork) pindexBestInvalid = pindexNew; @@ -1905,10 +1970,10 @@ void static InvalidChainFound(CBlockIndex* pindexNew) LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__, tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime())); - CheckForkWarningConditions(); + CheckForkWarningConditions(chainParams); } -void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) { +void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state, const CChainParams& chainParams) { int nDoS = 0; if (state.IsInvalid(nDoS)) { std::map::iterator it = mapBlockSource.find(pindex->GetBlockHash()); @@ -1923,7 +1988,7 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state pindex->nStatus |= BLOCK_FAILED_VALID; setDirtyBlockIndex.insert(pindex); setBlockIndexCandidates.erase(pindex); - InvalidChainFound(pindex); + InvalidChainFound(pindex, chainParams); } } @@ -2237,7 +2302,8 @@ enum DisconnectResult * The addressIndex and spentIndex will be updated if requested. */ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& state, - const CBlockIndex* pindex, CCoinsViewCache& view, bool const updateIndices) + const CBlockIndex* pindex, CCoinsViewCache& view, const CChainParams& chainparams, + const bool updateIndices) { assert(pindex->GetBlockHash() == view.GetBestBlock()); @@ -2272,8 +2338,8 @@ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& s if (fAddressIndex && updateIndices) { for (unsigned int k = tx.vout.size(); k-- > 0;) { const CTxOut &out = tx.vout[k]; - int const scriptType = out.scriptPubKey.Type(); - if (scriptType > 0) { + CScript::ScriptType scriptType = out.scriptPubKey.GetType(); + if (scriptType != CScript::UNKNOWN) { uint160 const addrHash = out.scriptPubKey.AddressHash(); // undo receiving activity @@ -2329,8 +2395,8 @@ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& s const CTxIn input = tx.vin[j]; if (fAddressIndex && updateIndices) { const CTxOut &prevout = view.GetOutputFor(input); - int const scriptType = prevout.scriptPubKey.Type(); - if (scriptType > 0) { + CScript::ScriptType scriptType = prevout.scriptPubKey.GetType(); + if (scriptType != CScript::UNKNOWN) { uint160 const addrHash = prevout.scriptPubKey.AddressHash(); // undo spending activity @@ -2363,7 +2429,7 @@ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& s // However, this is only reliable if the last block was on or after // the Sapling activation height. Otherwise, the last anchor was the // empty root. - if (NetworkUpgradeActive(pindex->pprev->nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { + if (chainparams.GetConsensus().NetworkUpgradeActive(pindex->pprev->nHeight, Consensus::UPGRADE_SAPLING)) { view.PopAnchor(pindex->pprev->hashFinalSaplingRoot, SAPLING); } else { view.PopAnchor(SaplingMerkleTree::empty_root(), SAPLING); @@ -2429,11 +2495,10 @@ void ThreadScriptCheck() { // Called periodically asynchronously; alerts if it smells like // we're being fed a bad chain (blocks being generated much // too slowly or too quickly). -// -void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, - int64_t nPowTargetSpacing) +void PartitionCheck(bool (*initialDownloadCheck)(const CChainParams&), + CCriticalSection& cs, const CBlockIndex *const &bestHeader) { - if (bestHeader == NULL || initialDownloadCheck()) return; + if (bestHeader == NULL || initialDownloadCheck(Params())) return; static int64_t lastAlertTime = 0; int64_t now = GetAdjustedTime(); @@ -2441,14 +2506,30 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const const int SPAN_HOURS=4; const int SPAN_SECONDS=SPAN_HOURS*60*60; - int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing; + + LOCK(cs); + + Consensus::Params consensusParams = Params().GetConsensus(); + + int BLOCKS_EXPECTED; + // TODO: This can be simplified when the Blossom activation height is set + int nBlossomBlocks = consensusParams.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight == Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT ? + 0 : std::max(0, bestHeader->nHeight - consensusParams.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight); + int blossomBlockTime = nBlossomBlocks * consensusParams.nPostBlossomPowTargetSpacing; + // If the span period includes Blossom activation, adjust the number of expected blocks. + if (blossomBlockTime < SPAN_SECONDS) { + // If there are 0 blossomBlocks the following is equivalent to + // BLOCKS_EXPECTED = SPAN_SECONDS / consensusParams.nPreBlossomPowTargetSpacing + BLOCKS_EXPECTED = nBlossomBlocks + (SPAN_SECONDS - blossomBlockTime) / consensusParams.nPreBlossomPowTargetSpacing; + } else { + BLOCKS_EXPECTED = SPAN_SECONDS / consensusParams.nPostBlossomPowTargetSpacing; + } boost::math::poisson_distribution poisson(BLOCKS_EXPECTED); std::string strWarning; int64_t startTime = GetAdjustedTime()-SPAN_SECONDS; - LOCK(cs); const CBlockIndex* i = bestHeader; int nBlocks = 0; while (i->GetBlockTime() >= startTime) { @@ -2493,9 +2574,9 @@ static int64_t nTimeIndex = 0; static int64_t nTimeCallbacks = 0; static int64_t nTimeTotal = 0; -bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) +bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, + CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck) { - const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); bool fExpensiveChecks = true; @@ -2509,10 +2590,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin auto verifier = libzcash::ProofVerifier::Strict(); auto disabledVerifier = libzcash::ProofVerifier::Disabled(); - bool fCheckPOW = !fJustCheck && (pindex->nHeight != 0); // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in - if (!CheckBlock(block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck)) + if (!CheckBlock(block, state, chainparams, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck)) return false; // verify that the view's current state corresponds to the previous block @@ -2613,7 +2693,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree)); // Grab the consensus branch ID for the block's height - auto consensusBranchId = CurrentEpochBranchId(pindex->nHeight, Params().GetConsensus()); + auto consensusBranchId = CurrentEpochBranchId(pindex->nHeight, chainparams.GetConsensus()); std::vector txdata; txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated @@ -2646,9 +2726,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin const CTxIn input = tx.vin[j]; const CTxOut &prevout = view.GetOutputFor(tx.vin[j]); - int const scriptType = prevout.scriptPubKey.Type(); + CScript::ScriptType scriptType = prevout.scriptPubKey.GetType(); const uint160 addrHash = prevout.scriptPubKey.AddressHash(); - if (fAddressIndex && scriptType > 0) { + if (fAddressIndex && scriptType != CScript::UNKNOWN) { // record spending activity addressIndex.push_back(make_pair( CAddressIndexKey(scriptType, addrHash, pindex->nHeight, i, hash, j, true), @@ -2698,8 +2778,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (fAddressIndex) { for (unsigned int k = 0; k < tx.vout.size(); k++) { const CTxOut &out = tx.vout[k]; - int const scriptType = out.scriptPubKey.Type(); - if (scriptType > 0) { + CScript::ScriptType scriptType = out.scriptPubKey.GetType(); + if (scriptType != CScript::UNKNOWN) { uint160 const addrHash = out.scriptPubKey.AddressHash(); // record receiving activity @@ -2721,7 +2801,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight); - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { + BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) { BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) { // Insert the note commitments into our temporary tree. @@ -2746,7 +2826,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // If Sapling is active, block.hashFinalSaplingRoot must be the // same as the root of the Sapling tree - if (NetworkUpgradeActive(pindex->nHeight, chainparams.GetConsensus(), Consensus::UPGRADE_SAPLING)) { + if (chainparams.GetConsensus().NetworkUpgradeActive(pindex->nHeight, Consensus::UPGRADE_SAPLING)) { if (block.hashFinalSaplingRoot != sapling_tree.root()) { return state.DoS(100, error("ConnectBlock(): block's hashFinalSaplingRoot is incorrect"), @@ -2791,7 +2871,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Move this if BLOCK_VALID_CONSENSUS is ever altered. static_assert(BLOCK_VALID_CONSENSUS == BLOCK_VALID_SCRIPTS, "nCachedBranchId must be set after all consensus rules have been validated."); - if (IsActivationHeightForAnyUpgrade(pindex->nHeight, Params().GetConsensus())) { + if (IsActivationHeightForAnyUpgrade(pindex->nHeight, chainparams.GetConsensus())) { pindex->nStatus |= BLOCK_ACTIVATES_UPGRADE; pindex->nCachedBranchId = CurrentEpochBranchId(pindex->nHeight, chainparams.GetConsensus()); } else if (pindex->pprev) { @@ -2873,6 +2953,7 @@ enum FlushStateMode { * or always and in all cases if we're in prune mode and are deleting files. */ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { + const CChainParams& chainparams = Params(); LOCK2(cs_main, cs_LastBlockFile); static int64_t nLastWrite = 0; static int64_t nLastFlush = 0; @@ -2881,7 +2962,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { bool fFlushForPrune = false; try { if (fPruneMode && fCheckForPruning && !fReindex) { - FindFilesToPrune(setFilesToPrune); + FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight()); fCheckForPruning = false; if (!setFilesToPrune.empty()) { fFlushForPrune = true; @@ -2980,8 +3061,7 @@ void PruneAndFlush() { } /** Update chainActive and related internal data structures. */ -void static UpdateTip(CBlockIndex *pindexNew) { - const CChainParams& chainParams = Params(); +void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { chainActive.SetTip(pindexNew); // New best block @@ -2994,41 +3074,19 @@ void static UpdateTip(CBlockIndex *pindexNew) { Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize()); cvBlockChange.notify_all(); - - // Check the version of the last 100 blocks to see if we need to upgrade: - static bool fWarned = false; - if (!IsInitialBlockDownload() && !fWarned) - { - int nUpgraded = 0; - const CBlockIndex* pindex = chainActive.Tip(); - for (int i = 0; i < 100 && pindex != NULL; i++) - { - if (pindex->nVersion > CBlock::CURRENT_VERSION) - ++nUpgraded; - pindex = pindex->pprev; - } - if (nUpgraded > 0) - LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION); - if (nUpgraded > 100/2) - { - // strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user: - strMiscWarning = _("Warning: This version is obsolete; upgrade required!"); - CAlert::Notify(strMiscWarning, true); - fWarned = true; - } - } } /** * Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and * mempool.removeWithoutBranchId after this, with cs_main held. */ -bool static DisconnectTip(CValidationState &state, bool fBare = false) { +bool static DisconnectTip(CValidationState &state, const CChainParams& chainparams, bool fBare = false) { + CBlockIndex *pindexDelete = chainActive.Tip(); assert(pindexDelete); // Read block from disk. CBlock block; - if (!ReadBlockFromDisk(block, pindexDelete)) + if (!ReadBlockFromDisk(block, pindexDelete, chainparams.GetConsensus())) return AbortNode(state, "Failed to read block"); // Apply the block atomically to the chain state. uint256 sproutAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SPROUT); @@ -3037,7 +3095,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { { CCoinsViewCache view(pcoinsTip); // insightexplorer: update indices (true) - if (DisconnectBlock(block, state, pindexDelete, view, true) != DISCONNECT_OK) + if (DisconnectBlock(block, state, pindexDelete, view, chainparams, true) != DISCONNECT_OK) return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString()); assert(view.Flush()); } @@ -3070,7 +3128,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { } // Update chainActive and related variables. - UpdateTip(pindexDelete->pprev); + UpdateTip(pindexDelete->pprev, chainparams); // Get the current commitment tree SproutMerkleTree newSproutTree; SaplingMerkleTree newSaplingTree; @@ -3097,13 +3155,14 @@ static int64_t nTimePostConnect = 0; * corresponding to pindexNew, to bypass loading it again from disk. * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held. */ -bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) { +bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const CBlock* pblock) { + assert(pindexNew->pprev == chainActive.Tip()); // Read block from disk. int64_t nTime1 = GetTimeMicros(); CBlock block; if (!pblock) { - if (!ReadBlockFromDisk(block, pindexNew)) + if (!ReadBlockFromDisk(block, pindexNew, chainparams.GetConsensus())) return AbortNode(state, "Failed to read block"); pblock = █ } @@ -3118,11 +3177,11 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); { CCoinsViewCache view(pcoinsTip); - bool rv = ConnectBlock(*pblock, state, pindexNew, view); + bool rv = ConnectBlock(*pblock, state, pindexNew, view, chainparams); GetMainSignals().BlockChecked(*pblock, state); if (!rv) { if (state.IsInvalid()) - InvalidBlockFound(pindexNew, state); + InvalidBlockFound(pindexNew, state, chainparams); return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString()); } mapBlockSource.erase(pindexNew->GetBlockHash()); @@ -3139,13 +3198,13 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001); // Remove conflicting transactions from the mempool. list txConflicted; - mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload()); + mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload(chainparams)); // Remove transactions that expire at new block height from mempool mempool.removeExpired(pindexNew->nHeight); // Update chainActive & related variables. - UpdateTip(pindexNew); + UpdateTip(pindexNew, chainparams); // Tell wallet about transactions that went from mempool // to conflicted: BOOST_FOREACH(const CTransaction &tx, txConflicted) { @@ -3231,7 +3290,7 @@ static CBlockIndex* FindMostWorkChain() { if (fFailedChain || fMissingData || fInvalidChain) { // Candidate chain is not usable (either invalid or missing data) - if ((fFailedChain || fInvalidChain) + if ((fFailedChain || fInvalidChain) && (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork)) pindexBestInvalid = pindexNew; CBlockIndex *pindexFailed = pindexNew; @@ -3282,7 +3341,8 @@ const CBlockIndex* FindBlockAtHeight(int nHeight, const CBlockIndex* pIndex) { * Try to make some progress towards making pindexMostWork the active block. * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. */ -static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) { +static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const CBlock* pblock) { + AssertLockHeld(cs_main); bool fInvalidFound = false; const CBlockIndex *pindexOldTip = chainActive.Tip(); @@ -3311,7 +3371,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo // Disconnect active blocks which are no longer in the best chain. bool fBlocksDisconnected = false; while (chainActive.Tip() && chainActive.Tip() != pindexFork) { - if (!DisconnectTip(state)) + if (!DisconnectTip(state, chainparams)) return false; fBlocksDisconnected = true; } @@ -3335,11 +3395,11 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo // Connect new blocks. BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { - if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { + if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { if (state.IsInvalid()) { // The block violates a consensus rule. if (!state.CorruptionPossible()) - InvalidChainFound(vpindexToConnect.back()); + InvalidChainFound(vpindexToConnect.back(), chainparams); state = CValidationState(); fInvalidFound = true; fContinue = false; @@ -3363,14 +3423,14 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); } mempool.removeWithoutBranchId( - CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus())); + CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, chainparams.GetConsensus())); mempool.check(pcoinsTip); // Callbacks/notifications for a new best chain. if (fInvalidFound) - CheckForkWarningConditionsOnNewFork(vpindexToConnect.back()); + CheckForkWarningConditionsOnNewFork(vpindexToConnect.back(), chainparams); else - CheckForkWarningConditions(); + CheckForkWarningConditions(chainparams); return true; } @@ -3380,10 +3440,11 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo * or an activated best chain. pblock is either NULL or a pointer to a block * that is already loaded (to avoid loading it again from disk). */ -bool ActivateBestChain(CValidationState &state, CBlock *pblock) { +bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, const CBlock* pblock) { + CBlockIndex *pindexNewTip = NULL; CBlockIndex *pindexMostWork = NULL; - const CChainParams& chainParams = Params(); + do { boost::this_thread::interruption_point(); @@ -3396,11 +3457,11 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip()) return true; - if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL)) + if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL)) return false; pindexNewTip = chainActive.Tip(); - fInitialDownload = IsInitialBlockDownload(); + fInitialDownload = IsInitialBlockDownload(chainparams); } // When we reach this point, we switched to a new tip (stored in pindexNewTip). @@ -3410,7 +3471,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { // Relay inventory, but don't relay old inventory during initial block download. int nBlockEstimate = 0; if (fCheckpointsEnabled) - nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()); + nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()); { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) @@ -3422,7 +3483,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { uiInterface.NotifyBlockTip(hashNewTip); } } while(pindexMostWork != chainActive.Tip()); - CheckBlockIndex(); + CheckBlockIndex(chainparams.GetConsensus()); // Write changes periodically to disk, after relay. if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) { @@ -3432,7 +3493,8 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { return true; } -bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { +bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex) { + AssertLockHeld(cs_main); // Mark the block itself as invalid. @@ -3447,10 +3509,10 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { setBlockIndexCandidates.erase(pindexWalk); // ActivateBestChain considers blocks already in chainActive // unconditionally valid already, so force disconnect away from it. - if (!DisconnectTip(state)) { + if (!DisconnectTip(state, chainparams)) { mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); mempool.removeWithoutBranchId( - CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus())); + CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, chainparams.GetConsensus())); return false; } } @@ -3465,10 +3527,10 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { it++; } - InvalidChainFound(pindex); + InvalidChainFound(pindex, chainparams); mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); mempool.removeWithoutBranchId( - CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus())); + CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, chainparams.GetConsensus())); return true; } @@ -3579,9 +3641,13 @@ void FallbackSproutValuePoolBalance( } /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */ -bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos) +bool ReceivedBlockTransactions( + const CBlock &block, + CValidationState& state, + const CChainParams& chainparams, + CBlockIndex *pindexNew, + const CDiskBlockPos& pos) { - const CChainParams& chainparams = Params(); pindexNew->nTx = block.vtx.size(); pindexNew->nChainTx = 0; CAmount sproutValue = 0; @@ -3593,7 +3659,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl // pool. So we invert the sign here. saplingValue += -tx.valueBalance; - for (auto js : tx.vjoinsplit) { + for (auto js : tx.vJoinSplit) { sproutValue += js.vpub_old; sproutValue -= js.vpub_new; } @@ -3750,23 +3816,27 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne return true; } -bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW) +bool CheckBlockHeader( + const CBlockHeader& block, + CValidationState& state, + const CChainParams& chainparams, + bool fCheckPOW) { unsigned int nHeight = chainActive.Height(); const CChainParams& chainParams = Params(); - + // Check block version if (block.nVersion < MIN_BLOCK_VERSION) return state.DoS(100, error("CheckBlockHeader(): block version too low"), REJECT_INVALID, "version-too-low"); // Check Equihash solution is valid - if (fCheckPOW && !CheckEquihashSolution(&block, Params())) + if (fCheckPOW && !CheckEquihashSolution(&block, chainparams.GetConsensus())) return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"), REJECT_INVALID, "invalid-solution"); // Check proof of work matches claimed amount - if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) + if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) return state.DoS(50, error("CheckBlockHeader(): proof of work failed"), REJECT_INVALID, "high-hash"); @@ -3780,6 +3850,7 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f } bool CheckBlock(const CBlock& block, CValidationState& state, + const CChainParams& chainparams, libzcash::ProofVerifier& verifier, bool fCheckPOW, bool fCheckMerkleRoot) { @@ -3787,7 +3858,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, // Check that the header is valid (particularly PoW). This is mostly // redundant with the call in AcceptBlockHeader. - if (!CheckBlockHeader(block, state, fCheckPOW)) + if (!CheckBlockHeader(block, state, chainparams, fCheckPOW)) return false; // Check the merkle root. @@ -3841,11 +3912,12 @@ bool CheckBlock(const CBlock& block, CValidationState& state, return true; } -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev, bool fCheckPOW) +bool ContextualCheckBlockHeader( + const CBlockHeader& block, CValidationState& state, + const CChainParams& chainParams, CBlockIndex * const pindexPrev, bool fCheckPOW) { - const CChainParams& chainParams = Params(); const Consensus::Params& consensusParams = chainParams.GetConsensus(); - uint256 hash = block.GetHash(); + uint256 hash = block.GetHash(); if (hash == consensusParams.hashGenesisBlock) return true; @@ -3857,7 +3929,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta size_t nSolSize = block.nSolution.size(); if (fCheckPOW && !checkEHParamaters(nSolSize, nHeight, chainParams)) { return state.DoS(100,error( - "ContextualCheckBlockHeader: Equihash solution size %d for height %d does not match a valid length", + "ContextualCheckBlockHeader: Equihash solution size %d for height %d does not match a valid length", nSolSize, nHeight), REJECT_INVALID,"bad-equihash-solution-size"); } @@ -3888,16 +3960,18 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta return true; } -bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev) +bool ContextualCheckBlock( + const CBlock& block, CValidationState& state, + const CChainParams& chainparams, CBlockIndex * const pindexPrev) { const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1; - const Consensus::Params& consensusParams = Params().GetConsensus(); + const Consensus::Params& consensusParams = chainparams.GetConsensus(); // Check that all transactions are finalized BOOST_FOREACH(const CTransaction& tx, block.vtx) { // Check transaction contextually against consensus rules at block height - if (!ContextualCheckTransaction(tx, state, nHeight, 100)) { + if (!ContextualCheckTransaction(tx, state, chainparams, nHeight, 100)) { return false; // Failure reason has been set in validation state object } @@ -3928,7 +4002,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn if (nHeight >= Params().GetCommunityFeeStartHeight()) { bool found = false; BOOST_FOREACH(const CTxOut& output, block.vtx[0].vout) { - if (output.scriptPubKey == Params().GetCommunityFeeScriptAtHeight(nHeight)) { + if (output.scriptPubKey == chainparams.GetCommunityFeeScriptAtHeight(nHeight)) { if (output.nValue == (GetBlockSubsidy(nHeight, consensusParams) * 0.05)) { found = true; break; @@ -3944,9 +4018,8 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn return true; } -bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex) +static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex=NULL) { - const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); // Check for duplicate uint256 hash = block.GetHash(); @@ -3962,7 +4035,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc return true; } - if (!CheckBlockHeader(block, state)) + if (!CheckBlockHeader(block, state, chainparams)) return false; // Get prev block index @@ -3976,7 +4049,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); } - if (!ContextualCheckBlockHeader(block, state, pindexPrev, true)) + if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, true)) return false; if (pindex == NULL) @@ -3988,14 +4061,20 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc return true; } -bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) +/** + * Store block on disk. + * JoinSplit proofs are never verified, because: + * - AcceptBlock doesn't perform script checks either. + * - The only caller of AcceptBlock verifies JoinSplit proofs elsewhere. + * If dbp is non-NULL, the file is known to already reside on disk + */ +static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) { - const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); CBlockIndex *&pindex = *ppindex; - if (!AcceptBlockHeader(block, state, &pindex)) + if (!AcceptBlockHeader(block, state, chainparams, &pindex)) return false; // Try to process all requested blocks that we don't have, but only @@ -4023,7 +4102,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, auto verifier = libzcash::ProofVerifier::Disabled(); bool fCheckPOW = (pindex->nHeight != 0); - if ((!CheckBlock(block, state, verifier, fCheckPOW, true)) || !ContextualCheckBlock(block, state, pindex->pprev)) { + if ((!CheckBlock(block, state, chainparams, verifier, fCheckPOW, true)) || !ContextualCheckBlock(block, state, chainparams, pindex->pprev)) { if (state.IsInvalid() && !state.CorruptionPossible()) { pindex->nStatus |= BLOCK_FAILED_VALID; setDirtyBlockIndex.insert(pindex); @@ -4044,7 +4123,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, if (dbp == NULL) if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) AbortNode(state, "Failed to write block"); - if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) + if (!ReceivedBlockTransactions(block, state, chainparams, pindex, blockPos)) return error("AcceptBlock(): ReceivedBlockTransactions failed"); } catch (const std::runtime_error& e) { return AbortNode(state, std::string("System error: ") + e.what()); @@ -4069,11 +4148,11 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned } -bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp) +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos* dbp) { // Preliminary checks auto verifier = libzcash::ProofVerifier::Disabled(); - bool checked = CheckBlock(*pblock, state, verifier); + bool checked = CheckBlock(*pblock, state, chainparams, verifier); { LOCK(cs_main); @@ -4085,22 +4164,22 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool // Store to disk CBlockIndex *pindex = NULL; - bool ret = AcceptBlock(*pblock, state, &pindex, fRequested, dbp); + bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fRequested, dbp); if (pindex && pfrom) { mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); } - CheckBlockIndex(); + CheckBlockIndex(chainparams.GetConsensus()); if (!ret) return error("%s: AcceptBlock FAILED", __func__); } - if (!ActivateBestChain(state, pblock)) + if (!ActivateBestChain(state, chainparams, pblock)) return error("%s: ActivateBestChain failed", __func__); return true; } -bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) +bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) { AssertLockHeld(cs_main); assert(pindexPrev == chainActive.Tip()); @@ -4113,13 +4192,13 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex auto verifier = libzcash::ProofVerifier::Disabled(); // NOTE: CheckBlockHeader is called by CheckBlock - if (!ContextualCheckBlockHeader(block.GetBlockHeader(), state, pindexPrev, fCheckPOW)) + if (!ContextualCheckBlockHeader(block.GetBlockHeader(), state, chainparams, pindexPrev, fCheckPOW)) return false; - if (!CheckBlock(block, state, verifier, fCheckPOW, fCheckMerkleRoot)) + if (!CheckBlock(block, state, chainparams, verifier, fCheckPOW, fCheckMerkleRoot)) return false; - if (!ContextualCheckBlock(block, state, pindexPrev)) + if (!ContextualCheckBlock(block, state, chainparams, pindexPrev)) return false; - if (!ConnectBlock(block, state, &indexDummy, viewNew, true)) + if (!ConnectBlock(block, state, &indexDummy, viewNew, chainparams, true)) return false; assert(state.IsValid()); @@ -4184,13 +4263,13 @@ void UnlinkPrunedFiles(std::set& setFilesToPrune) } /* Calculate the block/rev files that should be deleted to remain under target*/ -void FindFilesToPrune(std::set& setFilesToPrune) +void FindFilesToPrune(std::set& setFilesToPrune, uint64_t nPruneAfterHeight) { LOCK2(cs_main, cs_LastBlockFile); if (chainActive.Tip() == NULL || nPruneTarget == 0) { return; } - if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) { + if (chainActive.Tip()->nHeight <= nPruneAfterHeight) { return; } @@ -4302,7 +4381,7 @@ bool static LoadBlockIndexDB() { const CChainParams& chainparams = Params(); - if (!pblocktree->LoadBlockIndexGuts()) + if (!pblocktree->LoadBlockIndexGuts(InsertBlockIndex)) return false; boost::this_thread::interruption_point(); @@ -4434,9 +4513,10 @@ bool static LoadBlockIndexDB() // insightexplorer // Check whether block explorer features are enabled pblocktree->ReadFlag("insightexplorer", fInsightExplorer); - LogPrintf("%s: insight explorer %s\n", __func__, fAddressIndex ? "enabled" : "disabled"); + LogPrintf("%s: insight explorer %s\n", __func__, fInsightExplorer ? "enabled" : "disabled"); fAddressIndex = fInsightExplorer; fSpentIndex = fInsightExplorer; + fTimestampIndex = fInsightExplorer; // Fill in-memory data BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) @@ -4482,7 +4562,7 @@ CVerifyDB::~CVerifyDB() uiInterface.ShowProgress("", 100); } -bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) +bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) { LOCK(cs_main); if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL) @@ -4510,10 +4590,10 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth break; CBlock block; // check level 0: read from disk - if (!ReadBlockFromDisk(block, pindex)) + if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity - if (nCheckLevel >= 1 && !CheckBlock(block, state, verifier, (pindex->nHeight > 0), true)) + if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams, verifier, (pindex->nHeight > 0), true)) return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 2: verify undo validity if (nCheckLevel >= 2 && pindex) { @@ -4527,7 +4607,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth // check level 3: check for inconsistencies during memory-only disconnect of tip blocks if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) { // insightexplorer: do not update indices (false) - DisconnectResult res = DisconnectBlock(block, state, pindex, coins, false); + DisconnectResult res = DisconnectBlock(block, state, pindex, coins, chainparams, false); if (res == DISCONNECT_FAILED) { return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); } @@ -4553,9 +4633,9 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)))); pindex = chainActive.Next(pindex); CBlock block; - if (!ReadBlockFromDisk(block, pindex)) + if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); - if (!ConnectBlock(block, state, pindex, coins)) + if (!ConnectBlock(block, state, pindex, coins, chainparams)) return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); } } @@ -4565,7 +4645,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth return true; } -bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches) +bool RewindBlockIndex(const CChainParams& chainparams, bool& clearWitnessCaches) { LOCK(cs_main); @@ -4578,8 +4658,8 @@ bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches) // // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades. // - nCachedBranchId for each block matches what we expect. - auto sufficientlyValidated = [¶ms](const CBlockIndex* pindex) { - auto consensus = params.GetConsensus(); + auto sufficientlyValidated = [&chainparams](const CBlockIndex* pindex) { + auto consensus = chainparams.GetConsensus(); bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE; bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->nHeight, consensus); return fFlagSet == fFlagExpected && @@ -4602,7 +4682,7 @@ bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches) if (rewindLength > 0) { LogPrintf("*** First insufficiently validated block at height %d, rewind length %d\n", nHeight, rewindLength); const uint256 *phashFirstInsufValidated = chainActive[nHeight]->phashBlock; - auto networkID = params.NetworkIDString(); + auto networkID = chainparams.NetworkIDString(); // This is true when we intend to do a long rewind. bool intendedRewind = @@ -4649,7 +4729,7 @@ bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches) // of the blockchain). break; } - if (!DisconnectTip(state, true)) { + if (!DisconnectTip(state, chainparams, true)) { return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight); } // Occasionally flush state to disk. @@ -4711,7 +4791,7 @@ bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches) PruneBlockIndexCandidates(); - CheckBlockIndex(); + CheckBlockIndex(chainparams.GetConsensus()); if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) { return false; @@ -4760,8 +4840,8 @@ bool LoadBlockIndex() } -bool InitBlockIndex() { - const CChainParams& chainparams = Params(); +bool InitBlockIndex(const CChainParams& chainparams) { + LOCK(cs_main); // Initialize global variables that cannot be constructed at startup. @@ -4787,7 +4867,7 @@ bool InitBlockIndex() { // Only add the genesis block if not reindexing (in which case we reuse the one already on disk) if (!fReindex) { try { - CBlock &block = const_cast(Params().GenesisBlock()); + CBlock &block = const_cast(chainparams.GenesisBlock()); // Start new block file unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); CDiskBlockPos blockPos; @@ -4797,9 +4877,9 @@ bool InitBlockIndex() { if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) return error("LoadBlockIndex(): writing genesis block to disk failed"); CBlockIndex *pindex = AddToBlockIndex(block); - if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) + if (!ReceivedBlockTransactions(block, state, chainparams, pindex, blockPos)) return error("LoadBlockIndex(): genesis block not accepted"); - if (!ActivateBestChain(state, &block)) + if (!ActivateBestChain(state, chainparams, &block)) return error("LoadBlockIndex(): genesis block cannot be activated"); // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); @@ -4813,9 +4893,8 @@ bool InitBlockIndex() { -bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) +bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp) { - const CChainParams& chainparams = Params(); // Map of disk positions for blocks with unknown parent (only used for reindex) static std::multimap mapBlocksUnknownParent; int64_t nStart = GetTimeMillis(); @@ -4835,10 +4914,10 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) try { // locate a header unsigned char buf[MESSAGE_START_SIZE]; - blkdat.FindByte(Params().MessageStart()[0]); + blkdat.FindByte(chainparams.MessageStart()[0]); nRewind = blkdat.GetPos()+1; blkdat >> FLATDATA(buf); - if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE)) + if (memcmp(buf, chainparams.MessageStart(), MESSAGE_START_SIZE)) continue; // read size blkdat >> nSize; @@ -4872,7 +4951,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) // process in case the block isn't known yet if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) { CValidationState state; - if (ProcessNewBlock(state, NULL, &block, true, dbp)) + if (ProcessNewBlock(state, chainparams, NULL, &block, true, dbp)) nLoaded++; if (state.IsError()) break; @@ -4889,12 +4968,12 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) std::pair::iterator, std::multimap::iterator> range = mapBlocksUnknownParent.equal_range(head); while (range.first != range.second) { std::multimap::iterator it = range.first; - if (ReadBlockFromDisk(block, it->second)) + if (ReadBlockFromDisk(block, it->second, chainparams.GetConsensus())) { LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(), head.ToString()); CValidationState dummy; - if (ProcessNewBlock(dummy, NULL, &block, true, &it->second)) + if (ProcessNewBlock(dummy, chainparams, NULL, &block, true, &it->second)) { nLoaded++; queue.push_back(block.GetHash()); @@ -4916,9 +4995,8 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) return nLoaded > 0; } -void static CheckBlockIndex() +void static CheckBlockIndex(const Consensus::Params& consensusParams) { - const Consensus::Params& consensusParams = Params().GetConsensus(); if (!fCheckBlockIndex) { return; } @@ -5203,7 +5281,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) return true; } -void static ProcessGetData(CNode* pfrom) +void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams) { int currentHeight = GetHeight(); @@ -5238,7 +5316,7 @@ void static ProcessGetData(CNode* pfrom) // best equivalent proof of work) than the best header chain we know about. send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) && - (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth); + (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensusParams) < nOneMonth); if (!send) { LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId()); } @@ -5250,7 +5328,7 @@ void static ProcessGetData(CNode* pfrom) { // Send block from disk CBlock block; - if (!ReadBlockFromDisk(block, (*mi).second)) + if (!ReadBlockFromDisk(block, (*mi).second, consensusParams)) assert(!"cannot load block from disk"); if (inv.type == MSG_BLOCK) pfrom->PushMessage("block", block); @@ -5387,14 +5465,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // Reject incoming connections from nodes that don't know about the current epoch - const Consensus::Params& params = Params().GetConsensus(); - auto currentEpoch = CurrentEpoch(GetHeight(), params); - if (pfrom->nVersion < params.vUpgrades[currentEpoch].nProtocolVersion) + const Consensus::Params& consensusParams = chainparams.GetConsensus(); + auto currentEpoch = CurrentEpoch(GetHeight(), consensusParams); + if (pfrom->nVersion < consensusParams.vUpgrades[currentEpoch].nProtocolVersion) { LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion); pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE, strprintf("Version must be %d or greater", - params.vUpgrades[currentEpoch].nProtocolVersion)); + consensusParams.vUpgrades[currentEpoch].nProtocolVersion)); pfrom->fDisconnect = true; return false; } @@ -5444,7 +5522,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (!pfrom->fInbound) { // Advertise our address - if (fListen && !IsInitialBlockDownload()) + if (fListen && !IsInitialBlockDownload(chainparams)) { CAddress addr = GetLocalAddress(&pfrom->addr); if (addr.IsRoutable()) @@ -5640,7 +5718,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // not a direct successor. pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash); CNodeState *nodestate = State(pfrom->GetId()); - if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 && + + if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().PoWTargetSpacing(pindexBestHeader->nHeight) * 20 && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { vToFetch.push_back(inv); // Mark block as in flight already, even though the actual "getdata" message only goes out @@ -5682,7 +5761,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id); pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end()); - ProcessGetData(pfrom); + ProcessGetData(pfrom, chainparams.GetConsensus()); } @@ -5711,7 +5790,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // If pruning, don't inv blocks unless we have on disk and are likely to still have // for some reasonable time window (1 hour) that block relay might require. - const int nPrunedBlocksLikelyToHave = MIN_BLOCKS_TO_KEEP - 3600 / chainparams.GetConsensus().nPowTargetSpacing; + const int nPrunedBlocksLikelyToHave = MIN_BLOCKS_TO_KEEP - 3600 / chainparams.GetConsensus().PoWTargetSpacing(pindex->nHeight); if (fPruneMode && (!(pindex->nStatus & BLOCK_HAVE_DATA) || pindex->nHeight <= chainActive.Tip()->nHeight - nPrunedBlocksLikelyToHave)) { LogPrint("net", " getblocks stopping, pruned or too old block at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); @@ -5738,7 +5817,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_main); - if (IsInitialBlockDownload()) + if (IsInitialBlockDownload(chainparams)) return true; CBlockIndex* pindex = NULL; @@ -5857,7 +5936,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // TODO: currently, prohibit joinsplits and shielded spends/outputs from entering mapOrphans else if (fMissingInputs && - tx.vjoinsplit.empty() && + tx.vJoinSplit.empty() && tx.vShieldedSpend.empty() && tx.vShieldedOutput.empty()) { @@ -5935,7 +6014,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, Misbehaving(pfrom->GetId(), 20); return error("non-continuous headers sequence"); } - if (!AcceptBlockHeader(header, state, &pindexLast)) { + if (!AcceptBlockHeader(header, state, chainparams, &pindexLast)) { int nDoS; if (state.IsInvalid(nDoS)) { if (nDoS > 0) @@ -5956,7 +6035,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256()); } - CheckBlockIndex(); + CheckBlockIndex(chainparams.GetConsensus()); } else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing @@ -5974,8 +6053,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // unless we're still syncing with the network. // Such an unrequested block may still be processed, subject to the // conditions in AcceptBlock(). - bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload(); - ProcessNewBlock(state, pfrom, &block, forceProcessing, NULL); + bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload(chainparams); + ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL); int nDoS; if (state.IsInvalid(nDoS)) { pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), @@ -6131,7 +6210,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, uint256 alertHash = alert.GetHash(); if (pfrom->setKnown.count(alertHash) == 0) { - if (alert.ProcessAlert(Params().AlertKey())) + if (alert.ProcessAlert(chainparams.AlertKey())) { // Relay pfrom->setKnown.insert(alertHash); @@ -6260,6 +6339,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // requires LOCK(cs_vRecvMsg) bool ProcessMessages(CNode* pfrom) { + const CChainParams& chainparams = Params(); //if (fDebug) // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size()); @@ -6274,7 +6354,7 @@ bool ProcessMessages(CNode* pfrom) bool fOk = true; if (!pfrom->vRecvGetData.empty()) - ProcessGetData(pfrom); + ProcessGetData(pfrom, chainparams.GetConsensus()); // this maintains the order of responses if (!pfrom->vRecvGetData.empty()) return fOk; @@ -6301,7 +6381,7 @@ bool ProcessMessages(CNode* pfrom) it++; // Scan for message start - if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) { + if (memcmp(msg.hdr.pchMessageStart, chainparams.MessageStart(), MESSAGE_START_SIZE) != 0) { LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id); fOk = false; break; @@ -6309,7 +6389,7 @@ bool ProcessMessages(CNode* pfrom) // Read header CMessageHeader& hdr = msg.hdr; - if (!hdr.IsValid(Params().MessageStart())) + if (!hdr.IsValid(chainparams.MessageStart())) { LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id); continue; @@ -6380,7 +6460,8 @@ bool ProcessMessages(CNode* pfrom) bool SendMessages(CNode* pto, bool fSendTrickle) { - const Consensus::Params& consensusParams = Params().GetConsensus(); + const CChainParams& chainParams = Params(); + const Consensus::Params& consensusParams = chainParams.GetConsensus(); { // Don't send anything until we get its version message if (pto->nVersion == 0) @@ -6421,7 +6502,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // Address refresh broadcast static int64_t nLastRebroadcast; - if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) + if (!IsInitialBlockDownload(chainParams) && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) @@ -6501,7 +6582,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // Resend wallet transactions that haven't gotten in a block yet // Except during reindex, importing and IBD, when old wallet // transactions become unconfirmed and spams other nodes. - if (!fReindex && !fImporting && !IsInitialBlockDownload()) + if (!fReindex && !fImporting && !IsInitialBlockDownload(chainParams)) { GetMainSignals().Broadcast(nTimeBestReceived); } @@ -6575,7 +6656,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // more quickly than once every 5 minutes, then we'll shorten the download window for this block). if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) { QueuedBlock &queuedBlock = state.vBlocksInFlight.front(); - int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams); + int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams, pindexBestHeader->nHeight); if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) { LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow); queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow; @@ -6590,7 +6671,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // Message: getdata (blocks) // vector vGetData; - if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload(chainParams)) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { vector vToDownload; NodeId staller = -1; FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller); @@ -6662,35 +6743,36 @@ static class CMainCleanup // Set default values of new CMutableTransaction based on consensus rules at given height. -CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight) -{ - return CreateNewContextualCMutableTransaction(consensusParams, nHeight, expiryDelta); -} - -CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight, int nExpiryDelta) { +CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight) { CMutableTransaction mtx; - bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER); + bool isOverwintered = consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_OVERWINTER); if (isOverwintered) { mtx.fOverwintered = true; - mtx.nExpiryHeight = nHeight + nExpiryDelta; - - if (mtx.nExpiryHeight <= 0 || mtx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) { - throw new std::runtime_error("CreateNewContextualCMutableTransaction: invalid expiry height"); - } - - // NOTE: If the expiry height crosses into an incompatible consensus epoch, and it is changed to the last block - // of the current epoch (see below: Overwinter->Sapling), the transaction will be rejected if it falls within - // the expiring soon threshold of 3 blocks (for DoS mitigation) based on the current height. - // TODO: Generalise this code so behaviour applies to all post-Overwinter epochs - if (NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING)) { + if (consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_SAPLING)) { mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID; mtx.nVersion = SAPLING_TX_VERSION; } else { mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; mtx.nVersion = OVERWINTER_TX_VERSION; - mtx.nExpiryHeight = std::min( - mtx.nExpiryHeight, - static_cast(consensusParams.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight - 1)); + } + + bool blossomActive = consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM); + unsigned int defaultExpiryDelta = blossomActive ? DEFAULT_POST_BLOSSOM_TX_EXPIRY_DELTA : DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA; + mtx.nExpiryHeight = nHeight + (expiryDeltaArg ? expiryDeltaArg.get() : defaultExpiryDelta); + + // mtx.nExpiryHeight == 0 is valid for coinbase transactions + if (mtx.nExpiryHeight <= 0 || mtx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) { + throw new std::runtime_error("CreateNewContextualCMutableTransaction: invalid expiry height"); + } + + // NOTE: If the expiry height crosses into an incompatible consensus epoch, and it is changed to the last block + // of the current epoch, the transaction will be rejected if it falls within the expiring soon threshold of + // TX_EXPIRING_SOON_THRESHOLD (3) blocks (for DoS mitigation) based on the current height. + auto nextActivationHeight = NextActivationHeight(nHeight, consensusParams); + if (nextActivationHeight) { + mtx.nExpiryHeight = std::min(mtx.nExpiryHeight, static_cast(nextActivationHeight.get()) - 1); + + } } return mtx; diff --git a/src/main.h b/src/main.h index a65c04385..3846be3a6 100644 --- a/src/main.h +++ b/src/main.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_MAIN_H #define BITCOIN_MAIN_H @@ -24,6 +24,7 @@ #include "script/standard.h" #include "sync.h" #include "tinyformat.h" +#include "txdb.h" #include "txmempool.h" #include "uint256.h" #include "addressindex.h" @@ -44,6 +45,7 @@ class CBlockIndex; class CBlockTreeDB; class CBloomFilter; +class CChainParams; class CInv; class CScriptCheck; class CValidationInterface; @@ -72,7 +74,8 @@ static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 100; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default for -txexpirydelta, in number of blocks */ -static const unsigned int DEFAULT_TX_EXPIRY_DELTA = 20; +static const unsigned int DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA = 20; +static const unsigned int DEFAULT_POST_BLOSSOM_TX_EXPIRY_DELTA = DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA * Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO; /** The number of blocks within expiry height when a tx is considered to be expiring soon */ static constexpr uint32_t TX_EXPIRING_SOON_THRESHOLD = 3; /** The maximum size of a blk?????.dat file (since 0.8) */ @@ -119,7 +122,7 @@ struct BlockHasher size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } }; -extern unsigned int expiryDelta; +extern boost::optional expiryDeltaArg; extern CScript COINBASE_FLAGS; extern CCriticalSection cs_main; extern CTxMemPool mempool; @@ -149,6 +152,9 @@ extern bool fAddressIndex; // Maintain a full spent index, used to query the spending txid and input index for an outpoint extern bool fSpentIndex; +// Maintain a full timestamp index, used to query for blocks within a time range +extern bool fTimestampIndex; + // END insightexplorer extern bool fIsBareMultisigStd; @@ -193,11 +199,11 @@ void RegisterNodeSignals(CNodeSignals& nodeSignals); /** Unregister a network node */ void UnregisterNodeSignals(CNodeSignals& nodeSignals); -/** +/** * Process an incoming block. This only returns after the best known valid * block is made active. Note that it does not, however, guarantee that the * specific block passed to it has been checked for validity! - * + * * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation. * @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid. * @param[in] pblock The block we want to process. @@ -205,7 +211,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location. * @return True if state.IsValid() */ -bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp); +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos* dbp); /** Check whether enough disk space is available for an incoming block */ bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); /** Open a block file (blk?????.dat) */ @@ -215,9 +221,9 @@ FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); /** Translation to a filesystem path */ boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix); /** Import blocks from an external file */ -bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL); +bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp = NULL); /** Initialize a new block tree database + block data on disk */ -bool InitBlockIndex(); +bool InitBlockIndex(const CChainParams& chainparams); /** Load the block tree and coins database from disk */ bool LoadBlockIndex(); /** Unload database information */ @@ -236,13 +242,13 @@ void ThreadScriptCheck(); /** Try to detect Partition (network isolation) attacks against us */ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, int64_t nPowTargetSpacing); /** Check whether we are doing an initial block download (synchronizing from disk or network) */ -bool IsInitialBlockDownload(); +bool IsInitialBlockDownload(const CChainParams& chainParams); /** Format a string that describes several potential problems detected by the core */ std::string GetWarnings(const std::string& strFor); /** Retrieve a transaction (from memory pool, or from disk, if possible) */ -bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false); +bool GetTransaction(const uint256 &hash, CTransaction &tx, const Consensus::Params& params, uint256 &hashBlock, bool fAllowSlow = false); /** Find the best known block, and make it the tip of the block chain */ -bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL); +bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, const CBlock* pblock = NULL); CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); /** @@ -260,7 +266,7 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); * * @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned */ -void FindFilesToPrune(std::set& setFilesToPrune); +void FindFilesToPrune(std::set& setFilesToPrune, uint64_t nPruneAfterHeight); /** * Actually unlink the specified files @@ -291,39 +297,12 @@ struct CNodeStateStats { int nCommonHeight; std::vector vHeightInFlight; }; - -struct CDiskTxPos : public CDiskBlockPos -{ - unsigned int nTxOffset; // after header - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*(CDiskBlockPos*)this); - READWRITE(VARINT(nTxOffset)); - } - - CDiskTxPos(const CDiskBlockPos &blockIn, unsigned int nTxOffsetIn) : CDiskBlockPos(blockIn.nFile, blockIn.nPos), nTxOffset(nTxOffsetIn) { - } - - CDiskTxPos() { - SetNull(); - } - - void SetNull() { - CDiskBlockPos::SetNull(); - nTxOffset = 0; - } -}; - - CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); /** * Check transaction inputs, and make sure any * pay-to-script-hash transactions are evaluating IsStandard scripts - * + * * Why bother? To avoid denial-of-service attacks; an attacker * can submit a standard HASH... OP_EQUAL transaction, * which will get accepted into blocks. The redemption @@ -332,14 +311,14 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF * DUP CHECKSIG DROP ... repeated 100 times... OP_1 */ -/** +/** * Check for standard transaction types * @param[in] mapInputs Map of previous transactions that have outputs we're spending * @return True if all inputs (scriptSigs) use only standard transaction forms */ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId); -/** +/** * Count ECDSA signature operations the old-fashioned (pre-0.6) way * @return number of sigops this transaction's outputs will produce when spent * @see CTransaction::FetchInputs @@ -348,7 +327,7 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx); /** * Count ECDSA signature operations in pay-to-script-hash inputs. - * + * * @param[in] mapInputs Map of previous transactions that have outputs we're spending * @return maximum number of sigops required to validate this transaction's inputs * @see CTransaction::FetchInputs @@ -367,8 +346,9 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons std::vector *pvChecks = NULL); /** Check a transaction contextually against a set of consensus rules */ -bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state, int nHeight, int dosLevel, - bool (*isInitBlockDownload)() = IsInitialBlockDownload); +bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state, + const CChainParams& chainparams, int nHeight, int dosLevel, + bool (*isInitBlockDownload)(const CChainParams&) = IsInitialBlockDownload); /** Apply the effects of this transaction on the UTXO set represented by view */ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight); @@ -382,7 +362,7 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio /** Check for standard transaction types * @return True if all outputs (scriptPubKeys) use only standard transaction forms */ -bool IsStandardTx(const CTransaction& tx, std::string& reason, int nHeight = 0); +bool IsStandardTx(const CTransaction& tx, std::string& reason, const CChainParams& chainparams, int nHeight = 0); namespace Consensus { @@ -422,9 +402,9 @@ bool IsExpiringSoonTx(const CTransaction &tx, int nNextBlockHeight); */ bool CheckFinalTx(const CTransaction &tx, int flags = -1); -/** +/** * Closure representing one script verification - * Note that this stores references to the spending transaction + * Note that this stores references to the spending transaction */ class CScriptCheck { @@ -462,41 +442,47 @@ class CScriptCheck ScriptError GetScriptError() const { return error; } }; +bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); +bool GetAddressIndex(const uint160& addressHash, int type, + std::vector &addressIndex, + int start = 0, int end = 0); +bool GetAddressUnspent(const uint160& addressHash, int type, + std::vector& unspentOutputs); +bool GetTimestampIndex(unsigned int high, unsigned int low, bool fActiveOnly, + std::vector > &hashes); /** Functions for disk access for blocks */ -bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); -bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos); -bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); - +bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); +bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams); +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams); /** Functions for validating blocks and updating the block tree */ -/** Apply the effects of this block (with given index) on the UTXO set represented by coins */ -bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); - /** Context-independent validity checks */ -bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); +bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, + const CChainParams& chainparams, + bool fCheckPOW = true); bool CheckBlock(const CBlock& block, CValidationState& state, + const CChainParams& chainparams, libzcash::ProofVerifier& verifier, bool fCheckPOW = true, bool fCheckMerkleRoot = true); -/** Context-dependent validity checks */ -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev, bool fCheckPOW = true); -bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); +/** Context-dependent validity checks. + * By "context", we mean only the previous block headers, but not the UTXO + * set; UTXO-related validity checks are done in ConnectBlock(). */ + bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, + const CChainParams& chainparams, CBlockIndex *pindexPrev, bool fCheckPOW = true); + bool ContextualCheckBlock(const CBlock& block, CValidationState& state, + const CChainParams& chainparams, CBlockIndex *pindexPrev); -/** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ -bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); - -/** - * Store block on disk. - * JoinSplit proofs are never verified, because: - * - AcceptBlock doesn't perform script checks either. - * - The only caller of AcceptBlock verifies JoinSplit proofs elsewhere. - * If dbp is non-NULL, the file is known to already reside on disk - */ -bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp); -bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL); +/** Apply the effects of this block (with given index) on the UTXO set represented by coins. + * Validity checks that depend on the UTXO set are also done; ConnectBlock() + * can fail if those validity checks fail (among other reasons). */ + bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, + const CChainParams& chainparams, bool fJustCheck = false); + /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ + bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); /** @@ -507,75 +493,21 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc * clearWitnessCaches is an output parameter that will be set to true iff * witness caches should be cleared in order to handle an intended long rewind. */ -bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches); - -class CBlockFileInfo -{ -public: - unsigned int nBlocks; //! number of blocks stored in file - unsigned int nSize; //! number of used bytes of block file - unsigned int nUndoSize; //! number of used bytes in the undo file - unsigned int nHeightFirst; //! lowest height of block in file - unsigned int nHeightLast; //! highest height of block in file - uint64_t nTimeFirst; //! earliest time of block in file - uint64_t nTimeLast; //! latest time of block in file - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(VARINT(nBlocks)); - READWRITE(VARINT(nSize)); - READWRITE(VARINT(nUndoSize)); - READWRITE(VARINT(nHeightFirst)); - READWRITE(VARINT(nHeightLast)); - READWRITE(VARINT(nTimeFirst)); - READWRITE(VARINT(nTimeLast)); - } - - void SetNull() { - nBlocks = 0; - nSize = 0; - nUndoSize = 0; - nHeightFirst = 0; - nHeightLast = 0; - nTimeFirst = 0; - nTimeLast = 0; - } - - CBlockFileInfo() { - SetNull(); - } - - std::string ToString() const; - - /** update statistics (does not update nSize) */ - void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) { - if (nBlocks==0 || nHeightFirst > nHeightIn) - nHeightFirst = nHeightIn; - if (nBlocks==0 || nTimeFirst > nTimeIn) - nTimeFirst = nTimeIn; - nBlocks++; - if (nHeightIn > nHeightLast) - nHeightLast = nHeightIn; - if (nTimeIn > nTimeLast) - nTimeLast = nTimeIn; - } -}; +bool RewindBlockIndex(const CChainParams& chainparams, bool& clearWitnessCaches); /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ class CVerifyDB { public: CVerifyDB(); ~CVerifyDB(); - bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth); + bool VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth); }; /** Find the last common block between the parameter chain and a locator. */ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator); /** Mark a block as invalid. */ -bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex); +bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex); /** Remove invalidity status from a block and its descendants. */ bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex); @@ -598,10 +530,11 @@ int GetSpendHeight(const CCoinsViewCache& inputs); uint64_t CalculateCurrentUsage(); -/** Return a CMutableTransaction with contextual default values based on set of consensus rules at nHeight, and the default expiry delta. */ -CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight); -/** Return a CMutableTransaction with contextual default values based on set of consensus rules at nHeight, and given expiry delta. */ -CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight, int nExpiryDelta); +/** + * Return a CMutableTransaction with contextual default values based on set of consensus rules at nHeight. The expiryDelta will + * either be based on the command-line argument '-txexpirydelta' or derived from consensusParams. + */ +CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight); #endif // BITCOIN_MAIN_H diff --git a/src/memusage.h b/src/memusage.h index 0b232d88b..87e652557 100644 --- a/src/memusage.h +++ b/src/memusage.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_MEMUSAGE_H #define BITCOIN_MEMUSAGE_H diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index a368b31ad..25d3dc697 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "merkleblock.h" diff --git a/src/merkleblock.h b/src/merkleblock.h index 97223ed92..5f9c02f50 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_MERKLEBLOCK_H #define BITCOIN_MERKLEBLOCK_H diff --git a/src/metrics.cpp b/src/metrics.cpp index 97094357c..528cbaa34 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -1,12 +1,14 @@ +// Copyright (c) 2020 The BitcoinZ community // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "metrics.h" #include "chainparams.h" #include "checkpoints.h" #include "main.h" +#include "timedata.h" #include "ui_interface.h" #include "util.h" #include "utiltime.h" @@ -108,34 +110,29 @@ double GetLocalSolPS() return miningTimer.rate(solutionTargetChecks); } -int EstimateNetHeightInner(int height, int64_t tipmediantime, - int heightLastCheckpoint, int64_t timeLastCheckpoint, - int64_t genesisTime, int64_t targetSpacing) +int EstimateNetHeight(const Consensus::Params& params, int currentHeadersHeight, int64_t currentHeadersTime) { - // We average the target spacing with the observed spacing to the last - // checkpoint (either from below or above depending on the current height), - // and use that to estimate the current network height. - int medianHeight = height > CBlockIndex::nMedianTimeSpan ? - height - (1 + ((CBlockIndex::nMedianTimeSpan - 1) / 2)) : - height / 2; - double checkpointSpacing = medianHeight > heightLastCheckpoint ? - (double (tipmediantime - timeLastCheckpoint)) / (medianHeight - heightLastCheckpoint) : - (double (timeLastCheckpoint - genesisTime)) / heightLastCheckpoint; - double averageSpacing = (targetSpacing + checkpointSpacing) / 2; - int netheight = medianHeight + ((GetTime() - tipmediantime) / averageSpacing); - // Round to nearest ten to reduce noise - return ((netheight + 5) / 10) * 10; -} + int64_t now = GetAdjustedTime(); + if (currentHeadersTime >= now) { + return currentHeadersHeight; + } -int EstimateNetHeight(int height, int64_t tipmediantime, CChainParams chainParams) -{ - auto checkpointData = chainParams.Checkpoints(); - return EstimateNetHeightInner( - height, tipmediantime, - Checkpoints::GetTotalBlocksEstimate(checkpointData), - checkpointData.nTimeLastCheckpoint, - chainParams.GenesisBlock().nTime, - chainParams.GetConsensus().nPowTargetSpacing); + int estimatedHeight = currentHeadersHeight + (now - currentHeadersTime) / params.PoWTargetSpacing(currentHeadersHeight); + + int blossomActivationHeight = params.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight; + if (currentHeadersHeight >= blossomActivationHeight || estimatedHeight <= blossomActivationHeight) { + return ((estimatedHeight + 5) / 10) * 10; + } + + int numPreBlossomBlocks = blossomActivationHeight - currentHeadersHeight; + int64_t preBlossomTime = numPreBlossomBlocks * params.PoWTargetSpacing(blossomActivationHeight - 1); + int64_t blossomActivationTime = currentHeadersTime + preBlossomTime; + if (blossomActivationTime >= now) { + return blossomActivationHeight; + } + + int netheight = blossomActivationHeight + (now - blossomActivationTime) / params.PoWTargetSpacing(blossomActivationHeight); + return ((netheight + 5) / 10) * 10; } void TriggerRefresh() @@ -187,7 +184,6 @@ static void metrics_InitMessage(const std::string& message) { *initMessage = message; } - void ConnectMetricsScreen() { uiInterface.ThreadSafeMessageBox.disconnect_all_slots(); @@ -197,27 +193,28 @@ void ConnectMetricsScreen() uiInterface.InitMessage.disconnect_all_slots(); uiInterface.InitMessage.connect(metrics_InitMessage); } - int printStats(bool mining) { // Number of lines that are always displayed int lines = 4; - int height; - int64_t tipmediantime; + int64_t currentHeadersHeight; + int64_t currentHeadersTime; size_t connections; int64_t netsolps; { LOCK2(cs_main, cs_vNodes); height = chainActive.Height(); - tipmediantime = chainActive.Tip()->GetMedianTimePast(); + currentHeadersHeight = pindexBestHeader ? pindexBestHeader->nHeight: -1; + currentHeadersTime = pindexBestHeader ? pindexBestHeader->nTime : 0; connections = vNodes.size(); netsolps = GetNetworkHashPS(120, -1); } auto localsolps = GetLocalSolPS(); - if (IsInitialBlockDownload()) { - int netheight = EstimateNetHeight(height, tipmediantime, Params()); + if (IsInitialBlockDownload(Params())) { + int netheight = currentHeadersHeight == -1 || currentHeadersTime == 0 ? + 0 : EstimateNetHeight(Params().GetConsensus(), currentHeadersHeight, currentHeadersTime); int downloadPercent = 0; if (netheight > 0) { downloadPercent = height * 100 / netheight; @@ -256,7 +253,7 @@ int printMiningStatus(bool mining) } if (fvNodesEmpty) { std::cout << _("Mining is paused while waiting for connections.") << std::endl; - } else if (IsInitialBlockDownload()) { + } else if (IsInitialBlockDownload(Params())) { std::cout << _("Mining is paused while downloading blocks.") << std::endl; } else { std::cout << _("Mining is paused (a JoinSplit may be in progress).") << std::endl; @@ -444,7 +441,7 @@ bool enableVTMode() void ThreadShowMetricsScreen() { // Make this thread recognisable as the metrics screen thread - RenameThread("zcash-metrics-screen"); + RenameThread("bitcoinz-metrics-screen"); // Determine whether we should render a persistent UI or rolling metrics bool isTTY = isatty(STDOUT_FILENO); @@ -464,6 +461,7 @@ void ThreadShowMetricsScreen() std::cout << std::endl; // Thank you text + std::cout << _("BTCZ Node Version 2.0.7 (YODA) - Protocol 770008") << std::endl; std::cout << _("Thank you for running a BitcoinZ node!") << std::endl; std::cout << _("You're helping to strengthen the network and contributing to a social good :)") << std::endl; } @@ -513,7 +511,7 @@ void ThreadShowMetricsScreen() // Explain how to exit std::cout << "["; #ifdef WIN32 - std::cout << _("'zcash-cli.exe stop' to exit"); + std::cout << _("'bitcoinz-cli.exe stop' to exit"); #else std::cout << _("Press Ctrl+C to exit"); #endif diff --git a/src/metrics.h b/src/metrics.h index a60bf19ce..b56615a60 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -1,8 +1,10 @@ +// Copyright (c) 2020 The BitcoinZ Community // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "uint256.h" +#include "consensus/params.h" #include #include @@ -63,9 +65,7 @@ void TrackMinedBlock(uint256 hash); void MarkStartTime(); double GetLocalSolPS(); -int EstimateNetHeightInner(int height, int64_t tipmediantime, - int heightLastCheckpoint, int64_t timeLastCheckpoint, - int64_t genesisTime, int64_t targetSpacing); +int EstimateNetHeight(const Consensus::Params& params, int currentBlockHeight, int64_t currentBlockTime); void TriggerRefresh(); @@ -79,4 +79,4 @@ void ThreadShowMetricsScreen(); * Rendering options: * Logo: img2txt -W 90 -H 20 -f utf8 -d none -g design.png >> design.ansi */ -const std::string METRICS_ART = "\n\nBitcoinZ - Your Financial Freedom\n\n"; \ No newline at end of file +const std::string METRICS_ART = "\n\nBitcoinZ - Your Financial Freedom\n\n"; diff --git a/src/miner.cpp b/src/miner.cpp index c62d2c2ed..19e54ec67 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "miner.h" #ifdef ENABLE_MINING @@ -106,9 +106,8 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, } } -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) +CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& scriptPubKeyIn) { - const CChainParams& chainparams = Params(); // Create new block std::unique_ptr pblocktemplate(new CBlockTemplate()); if(!pblocktemplate.get()) @@ -117,7 +116,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // -regtest only: allow overriding block.nVersion with // -blockversion=N to test forking scenarios - if (Params().MineBlocksOnDemand()) + if (chainparams.MineBlocksOnDemand()) pblock->nVersion = GetArg("-blockversion", pblock->nVersion); // Add dummy coinbase tx as first transaction @@ -324,7 +323,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // create only contains transactions that are valid in new blocks. CValidationState state; PrecomputedTransactionData txdata(tx); - if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId)) + if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, chainparams.GetConsensus(), consensusBranchId)) continue; if (chainparams.ZIP209Enabled() && monitoring_pool_balances) { @@ -335,7 +334,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) saplingValueDummy += -tx.valueBalance; - for (auto js : tx.vjoinsplit) { + for (auto js : tx.vJoinSplit) { sproutValueDummy += js.vpub_old; sproutValueDummy -= js.vpub_new; } @@ -429,16 +428,17 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) nonce >>= 16; pblock->nNonce = ArithToUint256(nonce); + // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); pblock->hashFinalSaplingRoot = sapling_tree.root(); - UpdateTime(pblock, Params().GetConsensus(), pindexPrev); - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); + UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); pblock->nSolution.clear(); pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); CValidationState state; - if (!TestBlockValidity(state, *pblock, pindexPrev, false, false)) + if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed"); } @@ -476,7 +476,7 @@ void GetScriptForMinerAddress(boost::shared_ptr &script) script->reserveScript = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; } -void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce) +void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce) { // Update nExtraNonce static uint256 hashPrevBlock; @@ -495,7 +495,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& pblock->hashMerkleRoot = pblock->BuildMerkleTree(); } -static bool ProcessBlockFound(CBlock* pblock, const CChainParams& chainparams) +static bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainparams) { LogPrintf("%s\n", pblock->ToString()); LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue)); @@ -512,7 +512,7 @@ static bool ProcessBlockFound(CBlock* pblock, const CChainParams& chainparams) // Process this block the same as if we had received it from another node CValidationState state; - if (!ProcessNewBlock(state, NULL, pblock, true, NULL)) + if (!ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL)) return error("BitcoinZMiner: ProcessNewBlock, block not accepted"); TrackMinedBlock(pblock->GetHash()); @@ -561,7 +561,7 @@ void static BitcoinMiner(const CChainParams& chainparams) LOCK(cs_vNodes); fvNodesEmpty = vNodes.empty(); } - if (!fvNodesEmpty && !IsInitialBlockDownload()) + if (!fvNodesEmpty && !IsInitialBlockDownload(chainparams)) break; MilliSleep(1000); } while (true); @@ -589,7 +589,7 @@ void static BitcoinMiner(const CChainParams& chainparams) unsigned int k = ehparams[0].k; LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k); - unique_ptr pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript)); + unique_ptr pblocktemplate(CreateNewBlock(chainparams, coinbaseScript->reserveScript)); if (!pblocktemplate.get()) { if (GetArg("-mineraddress", "").empty()) { diff --git a/src/miner.h b/src/miner.h index 070989054..e71685898 100644 --- a/src/miner.h +++ b/src/miner.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_MINER_H #define BITCOIN_MINER_H @@ -24,13 +24,13 @@ struct CBlockTemplate }; /** Generate a new block, without valid proof-of-work */ -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); +CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& scriptPubKeyIn); #ifdef ENABLE_MINING /** Get script for -mineraddress */ void GetScriptForMinerAddress(boost::shared_ptr &script); /** Modify the extranonce in a block */ -void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); +void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce); /** Run the miner threads */ void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams); #endif diff --git a/src/mruset.h b/src/mruset.h index 398aa173b..40dee4c4b 100644 --- a/src/mruset.h +++ b/src/mruset.h @@ -1,6 +1,6 @@ // Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_MRUSET_H #define BITCOIN_MRUSET_H diff --git a/src/net.cpp b/src/net.cpp index 475643199..fa2e83710 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" diff --git a/src/net.h b/src/net.h index 16df97a19..63b21f2ca 100644 --- a/src/net.h +++ b/src/net.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_NET_H #define BITCOIN_NET_H diff --git a/src/netbase.cpp b/src/netbase.cpp index 289b62361..c2e779846 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifdef HAVE_CONFIG_H #include "config/bitcoin-config.h" diff --git a/src/netbase.h b/src/netbase.h index a50efc428..1f43391c9 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_NETBASE_H #define BITCOIN_NETBASE_H diff --git a/src/noui.cpp b/src/noui.cpp index 0d9207c11..a5ecd9f27 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "noui.h" diff --git a/src/noui.h b/src/noui.h index 15cd30a63..935a1c5dc 100644 --- a/src/noui.h +++ b/src/noui.h @@ -1,6 +1,6 @@ // Copyright (c) 2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_NOUI_H #define BITCOIN_NOUI_H diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index f08cec311..da182b08e 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "policy/fees.h" diff --git a/src/policy/fees.h b/src/policy/fees.h index ee865c679..8d4906f98 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_POLICYESTIMATOR_H #define BITCOIN_POLICYESTIMATOR_H @@ -259,8 +259,8 @@ class CBlockPolicyEstimator void Read(CAutoFile& filein); private: - CFeeRate minTrackedFee; //! Passed to constructor to avoid dependency on main - double minTrackedPriority; //! Set to AllowFreeThreshold + CFeeRate minTrackedFee; //!< Passed to constructor to avoid dependency on main + double minTrackedPriority; //!< Set to AllowFreeThreshold unsigned int nBestSeenHeight; struct TxStatsInfo { diff --git a/src/pow.cpp b/src/pow.cpp index 9bb53d721..1ac22eca5 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "pow.h" @@ -39,9 +39,9 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead pindexLast->nHeight >= params.nPowAllowMinDifficultyBlocksAfterHeight.get()) { // Special difficulty rule for testnet: - // If the new block's timestamp is more than 6 * 2.5 minutes + // If the new block's timestamp is more than 6 * block interval minutes // then allow mining of a min-difficulty block. - if (pblock && pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing * 6) + if (pblock && pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.PoWTargetSpacing(pindexLast->nHeight + 1) * 6) return nProofOfWorkLimit; } } @@ -62,44 +62,54 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow}; - return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params); + return CalculateNextWorkRequired(bnAvg, + pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), + params, + pindexLast->nHeight + 1); } unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, int64_t nLastBlockTime, int64_t nFirstBlockTime, - const Consensus::Params& params) + const Consensus::Params& params, + int nextHeight) { + int64_t averagingWindowTimespan = params.AveragingWindowTimespan(nextHeight); + int64_t minActualTimespan = params.MinActualTimespan(nextHeight); + int64_t maxActualTimespan = params.MaxActualTimespan(nextHeight); // Limit adjustment step // Use medians to prevent time-warp attacks int64_t nActualTimespan = nLastBlockTime - nFirstBlockTime; LogPrint("pow", " nActualTimespan = %d before dampening\n", nActualTimespan); - nActualTimespan = params.AveragingWindowTimespan() + (nActualTimespan - params.AveragingWindowTimespan())/4; + nActualTimespan = averagingWindowTimespan + (nActualTimespan - averagingWindowTimespan)/4; LogPrint("pow", " nActualTimespan = %d before bounds\n", nActualTimespan); - if (nActualTimespan < params.MinActualTimespan()) - nActualTimespan = params.MinActualTimespan(); - if (nActualTimespan > params.MaxActualTimespan()) - nActualTimespan = params.MaxActualTimespan(); + if (nActualTimespan < minActualTimespan) { + nActualTimespan = minActualTimespan; + } + if (nActualTimespan > maxActualTimespan) { + nActualTimespan = maxActualTimespan; + } // Retarget const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); arith_uint256 bnNew {bnAvg}; - bnNew /= params.AveragingWindowTimespan(); + bnNew /= averagingWindowTimespan; bnNew *= nActualTimespan; - if (bnNew > bnPowLimit) + if (bnNew > bnPowLimit) { bnNew = bnPowLimit; + } /// debug print LogPrint("pow", "GetNextWorkRequired RETARGET\n"); - LogPrint("pow", "params.AveragingWindowTimespan() = %d nActualTimespan = %d\n", params.AveragingWindowTimespan(), nActualTimespan); + LogPrint("pow", "params.AveragingWindowTimespan(%d) = %d nActualTimespan = %d\n", nextHeight, averagingWindowTimespan, nActualTimespan); LogPrint("pow", "Current average: %08x %s\n", bnAvg.GetCompact(), bnAvg.ToString()); LogPrint("pow", "After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString()); return bnNew.GetCompact(); } -bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& params) +bool CheckEquihashSolution(const CBlockHeader *pblock, const Consensus::Params& params) { //Set parameters N,K from solution size. Filtering of valid parameters //for the givenblock height will be carried out in main.cpp/ContextualCheckBlockHeader @@ -181,7 +191,7 @@ int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& fr r = from.nChainWork - to.nChainWork; sign = -1; } - r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip); + r = r * arith_uint256(params.PoWTargetSpacing(tip.nHeight)) / GetBlockProof(tip); if (r.bits() > 63) { return sign * std::numeric_limits::max(); } diff --git a/src/pow.h b/src/pow.h index 30d0f5e63..eb05c6e34 100644 --- a/src/pow.h +++ b/src/pow.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_POW_H #define BITCOIN_POW_H @@ -19,10 +19,11 @@ class arith_uint256; unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&); unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, int64_t nLastBlockTime, int64_t nFirstBlockTime, - const Consensus::Params&); + const Consensus::Params&, + int nextHeight); /** Check whether the Equihash solution in a block header is valid */ -bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams&); +bool CheckEquihashSolution(const CBlockHeader *pblock, const Consensus::Params&); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&); diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 430ac8721..ab80e3255 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "primitives/block.h" diff --git a/src/primitives/block.h b/src/primitives/block.h index 489d54711..d8f659703 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_PRIMITIVES_BLOCK_H #define BITCOIN_PRIMITIVES_BLOCK_H diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 79adf290e..8a4b20327 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "primitives/transaction.h" @@ -203,10 +203,10 @@ CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::SPROUT_MIN_C CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), fOverwintered(tx.fOverwintered), nVersionGroupId(tx.nVersionGroupId), nExpiryHeight(tx.nExpiryHeight), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), valueBalance(tx.valueBalance), vShieldedSpend(tx.vShieldedSpend), vShieldedOutput(tx.vShieldedOutput), - vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig), + vJoinSplit(tx.vJoinSplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig), bindingSig(tx.bindingSig) { - + } uint256 CMutableTransaction::GetHash() const @@ -219,12 +219,12 @@ void CTransaction::UpdateHash() const *const_cast(&hash) = SerializeHash(*this); } -CTransaction::CTransaction() : nVersion(CTransaction::SPROUT_MIN_CURRENT_VERSION), fOverwintered(false), nVersionGroupId(0), nExpiryHeight(0), vin(), vout(), nLockTime(0), valueBalance(0), vShieldedSpend(), vShieldedOutput(), vjoinsplit(), joinSplitPubKey(), joinSplitSig(), bindingSig() { } +CTransaction::CTransaction() : nVersion(CTransaction::SPROUT_MIN_CURRENT_VERSION), fOverwintered(false), nVersionGroupId(0), nExpiryHeight(0), vin(), vout(), nLockTime(0), valueBalance(0), vShieldedSpend(), vShieldedOutput(), vJoinSplit(), joinSplitPubKey(), joinSplitSig(), bindingSig() { } CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), fOverwintered(tx.fOverwintered), nVersionGroupId(tx.nVersionGroupId), nExpiryHeight(tx.nExpiryHeight), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), valueBalance(tx.valueBalance), vShieldedSpend(tx.vShieldedSpend), vShieldedOutput(tx.vShieldedOutput), - vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig), + vJoinSplit(tx.vJoinSplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig), bindingSig(tx.bindingSig) { UpdateHash(); @@ -237,7 +237,7 @@ CTransaction::CTransaction( bool evilDeveloperFlag) : nVersion(tx.nVersion), fOverwintered(tx.fOverwintered), nVersionGroupId(tx.nVersionGroupId), nExpiryHeight(tx.nExpiryHeight), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), valueBalance(tx.valueBalance), vShieldedSpend(tx.vShieldedSpend), vShieldedOutput(tx.vShieldedOutput), - vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig), + vJoinSplit(tx.vJoinSplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig), bindingSig(tx.bindingSig) { assert(evilDeveloperFlag); @@ -247,7 +247,7 @@ CTransaction::CTransaction(CMutableTransaction &&tx) : nVersion(tx.nVersion), fO vin(std::move(tx.vin)), vout(std::move(tx.vout)), nLockTime(tx.nLockTime), nExpiryHeight(tx.nExpiryHeight), valueBalance(tx.valueBalance), vShieldedSpend(std::move(tx.vShieldedSpend)), vShieldedOutput(std::move(tx.vShieldedOutput)), - vjoinsplit(std::move(tx.vjoinsplit)), + vJoinSplit(std::move(tx.vJoinSplit)), joinSplitPubKey(std::move(tx.joinSplitPubKey)), joinSplitSig(std::move(tx.joinSplitSig)) { UpdateHash(); @@ -264,7 +264,7 @@ CTransaction& CTransaction::operator=(const CTransaction &tx) { *const_cast(&valueBalance) = tx.valueBalance; *const_cast*>(&vShieldedSpend) = tx.vShieldedSpend; *const_cast*>(&vShieldedOutput) = tx.vShieldedOutput; - *const_cast*>(&vjoinsplit) = tx.vjoinsplit; + *const_cast*>(&vJoinSplit) = tx.vJoinSplit; *const_cast(&joinSplitPubKey) = tx.joinSplitPubKey; *const_cast(&joinSplitSig) = tx.joinSplitSig; *const_cast(&bindingSig) = tx.bindingSig; @@ -291,7 +291,7 @@ CAmount CTransaction::GetValueOut() const } } - for (std::vector::const_iterator it(vjoinsplit.begin()); it != vjoinsplit.end(); ++it) + for (std::vector::const_iterator it(vJoinSplit.begin()); it != vJoinSplit.end(); ++it) { // NB: vpub_old "takes" money from the transparent value pool just as outputs do nValueOut += it->vpub_old; @@ -315,7 +315,7 @@ CAmount CTransaction::GetShieldedValueIn() const } } - for (std::vector::const_iterator it(vjoinsplit.begin()); it != vjoinsplit.end(); ++it) + for (std::vector::const_iterator it(vJoinSplit.begin()); it != vJoinSplit.end(); ++it) { // NB: vpub_new "gives" money to the transparent value pool just as inputs do nValue += it->vpub_new; diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 6ce15a94b..599903cad 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_PRIMITIVES_TRANSACTION_H #define BITCOIN_PRIMITIVES_TRANSACTION_H @@ -360,7 +360,7 @@ class SaplingOutPoint : public BaseOutPoint { public: SaplingOutPoint() : BaseOutPoint() {}; - SaplingOutPoint(uint256 hashIn, uint32_t nIn) : BaseOutPoint(hashIn, nIn) {}; + SaplingOutPoint(uint256 hashIn, uint32_t nIn) : BaseOutPoint(hashIn, nIn) {}; std::string ToString() const; }; @@ -555,7 +555,7 @@ class CTransaction const CAmount valueBalance; const std::vector vShieldedSpend; const std::vector vShieldedOutput; - const std::vector vjoinsplit; + const std::vector vJoinSplit; const uint256 joinSplitPubKey; const joinsplit_sig_t joinSplitSig = {{0}}; const binding_sig_t bindingSig = {{0}}; @@ -612,8 +612,8 @@ class CTransaction } if (nVersion >= 2) { auto os = WithVersion(&s, static_cast(header)); - ::SerReadWrite(os, *const_cast*>(&vjoinsplit), ser_action); - if (vjoinsplit.size() > 0) { + ::SerReadWrite(os, *const_cast*>(&vJoinSplit), ser_action); + if (vJoinSplit.size() > 0) { READWRITE(*const_cast(&joinSplitPubKey)); READWRITE(*const_cast(&joinSplitSig)); } @@ -702,7 +702,7 @@ struct CMutableTransaction CAmount valueBalance; std::vector vShieldedSpend; std::vector vShieldedOutput; - std::vector vjoinsplit; + std::vector vJoinSplit; uint256 joinSplitPubKey; CTransaction::joinsplit_sig_t joinSplitSig = {{0}}; CTransaction::binding_sig_t bindingSig = {{0}}; @@ -758,8 +758,8 @@ struct CMutableTransaction } if (nVersion >= 2) { auto os = WithVersion(&s, static_cast(header)); - ::SerReadWrite(os, vjoinsplit, ser_action); - if (vjoinsplit.size() > 0) { + ::SerReadWrite(os, vJoinSplit, ser_action); + if (vJoinSplit.size() > 0) { READWRITE(joinSplitPubKey); READWRITE(joinSplitSig); } diff --git a/src/protocol.cpp b/src/protocol.cpp index dd855aa33..ec2fbbfca 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "protocol.h" diff --git a/src/protocol.h b/src/protocol.h index d908191cc..6d9e928b1 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef __cplusplus #error This header can only be compiled as C++. diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 53e94fbdb..adabd11d1 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "pubkey.h" diff --git a/src/pubkey.h b/src/pubkey.h index 12f11c249..871f51179 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -2,7 +2,7 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_PUBKEY_H #define BITCOIN_PUBKEY_H diff --git a/src/random.cpp b/src/random.cpp index 29faa32a7..6c4d1bf13 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "random.h" diff --git a/src/random.h b/src/random.h index 8cec678ef..38b66bf0f 100644 --- a/src/random.h +++ b/src/random.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_RANDOM_H #define BITCOIN_RANDOM_H diff --git a/src/rest.cpp b/src/rest.cpp index 4f92bbb0a..08f217815 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -1,8 +1,9 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . +#include "chainparams.h" #include "primitives/block.h" #include "primitives/transaction.h" #include "main.h" @@ -214,7 +215,7 @@ static bool rest_block(HTTPRequest* req, if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); - if (!ReadBlockFromDisk(block, pblockindex)) + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } @@ -355,7 +356,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) CTransaction tx; uint256 hashBlock = uint256(); - if (!GetTransaction(hash, tx, hashBlock, true)) + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/reverselock.h b/src/reverselock.h index fac1ccb79..85d2d964f 100644 --- a/src/reverselock.h +++ b/src/reverselock.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_REVERSELOCK_H #define BITCOIN_REVERSELOCK_H diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 58089d0d6..c72abfd7a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1,13 +1,14 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "amount.h" #include "chain.h" #include "chainparams.h" #include "checkpoints.h" #include "consensus/validation.h" +#include "key_io.h" #include "main.h" #include "primitives/transaction.h" #include "rpc/server.h" @@ -51,7 +52,7 @@ double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficul int nShiftAmount = (powLimit >> 24) & 0xff; double dDiff = - (double)(powLimit & 0x00ffffff) / + (double)(powLimit & 0x00ffffff) / (double)(bits & 0x00ffffff); while (nShift < nShiftAmount) @@ -125,6 +126,95 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) return result; } +// insightexplorer +UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex) +{ + UniValue result(UniValue::VOBJ); + result.push_back(Pair("hash", block.GetHash().GetHex())); + // Only report confirmations if the block is on the main chain + if (!chainActive.Contains(blockindex)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block is an orphan"); + int confirmations = chainActive.Height() - blockindex->nHeight + 1; + result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", block.nVersion)); + result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); + + UniValue deltas(UniValue::VARR); + for (unsigned int i = 0; i < block.vtx.size(); i++) { + const CTransaction &tx = block.vtx[i]; + const uint256 txhash = tx.GetHash(); + + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("txid", txhash.GetHex())); + entry.push_back(Pair("index", (int)i)); + + UniValue inputs(UniValue::VARR); + if (!tx.IsCoinBase()) { + for (size_t j = 0; j < tx.vin.size(); j++) { + const CTxIn input = tx.vin[j]; + UniValue delta(UniValue::VOBJ); + CSpentIndexValue spentInfo; + CSpentIndexKey spentKey(input.prevout.hash, input.prevout.n); + + if (!GetSpentIndex(spentKey, spentInfo)) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Spent information not available"); + } + CTxDestination dest = DestFromAddressHash(spentInfo.addressType, spentInfo.addressHash); + if (IsValidDestination(dest)) { + delta.push_back(Pair("address", EncodeDestination(dest))); + } + delta.push_back(Pair("satoshis", -1 * spentInfo.satoshis)); + delta.push_back(Pair("index", (int)j)); + delta.push_back(Pair("prevtxid", input.prevout.hash.GetHex())); + delta.push_back(Pair("prevout", (int)input.prevout.n)); + + inputs.push_back(delta); + } + } + entry.push_back(Pair("inputs", inputs)); + + UniValue outputs(UniValue::VARR); + for (unsigned int k = 0; k < tx.vout.size(); k++) { + const CTxOut &out = tx.vout[k]; + UniValue delta(UniValue::VOBJ); + const uint160 addrhash = out.scriptPubKey.AddressHash(); + CTxDestination dest; + + if (out.scriptPubKey.IsPayToScriptHash()) { + dest = CScriptID(addrhash); + } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { + dest = CKeyID(addrhash); + } + if (IsValidDestination(dest)) { + delta.push_back(Pair("address", EncodeDestination(dest))); + } + delta.push_back(Pair("address", EncodeDestination(dest))); + delta.push_back(Pair("satoshis", out.nValue)); + delta.push_back(Pair("index", (int)k)); + + outputs.push_back(delta); + } + entry.push_back(Pair("outputs", outputs)); + deltas.push_back(entry); + } + result.push_back(Pair("deltas", deltas)); + result.push_back(Pair("time", block.GetBlockTime())); + result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); + result.push_back(Pair("nonce", block.nNonce.GetHex())); + result.push_back(Pair("bits", strprintf("%08x", block.nBits))); + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + CBlockIndex *pnext = chainActive.Next(blockindex); + if (pnext) + result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + return result; +} + UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { UniValue result(UniValue::VOBJ); @@ -313,6 +403,172 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) return mempoolToJSON(fVerbose); } +// insightexplorer +UniValue getblockdeltas(const UniValue& params, bool fHelp) +{ + std::string enableArg = "insightexplorer"; + bool enabled = fExperimentalMode && fInsightExplorer; + std::string disabledMsg = ""; + if (!enabled) { + disabledMsg = experimentalDisabledHelpMsg("getblockdeltas", enableArg); + } + if (fHelp || params.size() != 1) + throw runtime_error( + "getblockdeltas \"blockhash\"\n" + "\nReturns information about the given block and its transactions.\n" + + disabledMsg + + "\nArguments:\n" + "1. \"hash\" (string, required) The block hash\n" + "\nResult:\n" + "{\n" + " \"hash\": \"hash\", (string) block ID\n" + " \"confirmations\": n, (numeric) number of confirmations\n" + " \"size\": n, (numeric) block size in bytes\n" + " \"height\": n, (numeric) block height\n" + " \"version\": n, (numeric) block version (e.g. 4)\n" + " \"merkleroot\": \"hash\", (hexstring) block Merkle root\n" + " \"deltas\": [\n" + " {\n" + " \"txid\": \"hash\", (hexstring) transaction ID\n" + " \"index\": n, (numeric) The offset of the tx in the block\n" + " \"inputs\": [ (array of json objects)\n" + " {\n" + " \"address\": \"taddr\", (string) transparent address\n" + " \"satoshis\": n, (numeric) negative of spend amount\n" + " \"index\": n, (numeric) vin index\n" + " \"prevtxid\": \"hash\", (string) source utxo tx ID\n" + " \"prevout\": n (numeric) source utxo index\n" + " }, ...\n" + " ],\n" + " \"outputs\": [ (array of json objects)\n" + " {\n" + " \"address\": \"taddr\", (string) transparent address\n" + " \"satoshis\": n, (numeric) amount\n" + " \"index\": n (numeric) vout index\n" + " }, ...\n" + " ]\n" + " }, ...\n" + " ],\n" + " \"time\" : n, (numeric) The block version\n" + " \"mediantime\": n, (numeric) The most recent blocks' ave time\n" + " \"nonce\" : \"nonce\", (hex string) The nonce\n" + " \"bits\" : \"1d00ffff\", (hex string) The bits\n" + " \"difficulty\": n, (numeric) the current difficulty\n" + " \"chainwork\": \"xxxx\" (hex string) total amount of work in active chain\n" + " \"previousblockhash\" : \"hash\",(hex string) The hash of the previous block\n" + " \"nextblockhash\" : \"hash\" (hex string) The hash of the next block\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getblockdeltas", "00227e566682aebd6a7a5b772c96d7a999cadaebeaf1ce96f4191a3aad58b00b") + + HelpExampleRpc("getblockdeltas", "\"00227e566682aebd6a7a5b772c96d7a999cadaebeaf1ce96f4191a3aad58b00b\"") + ); + + if (!enabled) { + throw JSONRPCError(RPC_MISC_ERROR, "Error: getblockdeltas is disabled. " + "Run './bitcoinz-cli help getblockdeltas' for instructions on how to enable this feature."); + } + + std::string strHash = params[0].get_str(); + uint256 hash(uint256S(strHash)); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); + + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); + + return blockToDeltasJSON(block, pblockindex); +} + +// insightexplorer +UniValue getblockhashes(const UniValue& params, bool fHelp) +{ + std::string enableArg = "insightexplorer"; + bool fEnableGetBlockHashes = fExperimentalMode && fInsightExplorer; + std::string disabledMsg = ""; + if (!fEnableGetBlockHashes) { + disabledMsg = experimentalDisabledHelpMsg("getblockhashes", enableArg); + } + if (fHelp || params.size() < 2) + throw runtime_error( + "getblockhashes high low ( {\"noOrphans\": true|false, \"logicalTimes\": true|false} )\n" + "\nReturns array of hashes of blocks within the timestamp range provided,\n" + "\ngreater or equal to low, less than high.\n" + + disabledMsg + + "\nArguments:\n" + "1. high (numeric, required) The newer block timestamp\n" + "2. low (numeric, required) The older block timestamp\n" + "3. options (string, optional) A json object\n" + " {\n" + " \"noOrphans\": true|false (boolean) will only include blocks on the main chain\n" + " \"logicalTimes\": true|false (boolean) will include logical timestamps with hashes\n" + " }\n" + "\nResult:\n" + "[\n" + " \"xxxx\" (hex string) The block hash\n" + "]\n" + "or\n" + "[\n" + " {\n" + " \"blockhash\": \"xxxx\" (hex string) The block hash\n" + " \"logicalts\": n (numeric) The logical timestamp\n" + " }\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getblockhashes", "1558141697 1558141576") + + HelpExampleRpc("getblockhashes", "1558141697, 1558141576") + + HelpExampleCli("getblockhashes", "1558141697 1558141576 '{\"noOrphans\":false, \"logicalTimes\":true}'") + ); + + if (!fEnableGetBlockHashes) { + throw JSONRPCError(RPC_MISC_ERROR, "Error: getblockhashes is disabled. " + "Run './bitcoinz-cli help getblockhashes' for instructions on how to enable this feature."); + } + + unsigned int high = params[0].get_int(); + unsigned int low = params[1].get_int(); + bool fActiveOnly = false; + bool fLogicalTS = false; + + if (params.size() > 2) { + UniValue noOrphans = find_value(params[2].get_obj(), "noOrphans"); + if (!noOrphans.isNull()) + fActiveOnly = noOrphans.get_bool(); + + UniValue returnLogical = find_value(params[2].get_obj(), "logicalTimes"); + if (!returnLogical.isNull()) + fLogicalTS = returnLogical.get_bool(); + } + + std::vector > blockHashes; + { + LOCK(cs_main); + if (!GetTimestampIndex(high, low, fActiveOnly, blockHashes)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, + "No information available for block hashes"); + } + } + UniValue result(UniValue::VARR); + for (std::vector >::const_iterator it=blockHashes.begin(); + it!=blockHashes.end(); it++) { + if (fLogicalTS) { + UniValue item(UniValue::VOBJ); + item.push_back(Pair("blockhash", it->first.GetHex())); + item.push_back(Pair("logicalts", (int)it->second)); + result.push_back(item); + } else { + result.push_back(it->first.GetHex()); + } + } + return result; +} + UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -493,7 +749,7 @@ UniValue getblock(const UniValue& params, bool fHelp) if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); - if(!ReadBlockFromDisk(block, pblockindex)) + if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); if (verbosity == 0) @@ -650,7 +906,7 @@ UniValue verifychain(const UniValue& params, bool fHelp) if (params.size() > 1) nCheckDepth = params[1].get_int(); - return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth); + return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth); } /** Implementation of IsSuperMajority with better feedback */ @@ -929,6 +1185,10 @@ UniValue mempoolInfoToJSON() ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + if (Params().NetworkIDString() == "regtest") { + ret.push_back(Pair("fullyNotified", mempool.IsFullyNotified())); + } + return ret; } @@ -976,11 +1236,11 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); CBlockIndex* pblockindex = mapBlockIndex[hash]; - InvalidateBlock(state, pblockindex); + InvalidateBlock(state, Params(), pblockindex); } if (state.IsValid()) { - ActivateBestChain(state); + ActivateBestChain(state, Params()); } if (!state.IsValid()) { @@ -1019,7 +1279,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) } if (state.IsValid()) { - ActivateBestChain(state); + ActivateBestChain(state, Params()); } if (!state.IsValid()) { @@ -1046,6 +1306,10 @@ static const CRPCCommand commands[] = { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true }, { "blockchain", "verifychain", &verifychain, true }, + // insightexplorer + { "blockchain", "getblockdeltas", &getblockdeltas, false }, + { "blockchain", "getblockhashes", &getblockhashes, true }, + /* Not shown in help */ { "hidden", "invalidateblock", &invalidateblock, true }, { "hidden", "reconsiderblock", &reconsiderblock, true }, diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 8838bd273..bd2a16b5a 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "rpc/client.h" #include "rpc/protocol.h" @@ -17,8 +17,8 @@ using namespace std; class CRPCConvertParam { public: - std::string methodName; //! method whose params want conversion - int paramIdx; //! 0-based idx of param to convert + std::string methodName; //!< method whose params want conversion + int paramIdx; //!< 0-based idx of param to convert }; static const CRPCConvertParam vRPCConvertParams[] = @@ -99,6 +99,16 @@ static const CRPCConvertParam vRPCConvertParams[] = { "prioritisetransaction", 2 }, { "setban", 2 }, { "setban", 3 }, + { "getspentinfo", 0}, + { "getaddresstxids", 0}, + { "getaddressbalance", 0}, + { "getaddressdeltas", 0}, + { "getaddressutxos", 0}, + { "getaddressmempool", 0}, + { "getblockhashes", 0}, + { "getblockhashes", 1}, + { "getblockhashes", 2}, + { "getblockdeltas", 0}, { "zcrawjoinsplit", 1 }, { "zcrawjoinsplit", 2 }, { "zcrawjoinsplit", 3 }, diff --git a/src/rpc/client.h b/src/rpc/client.h index 8937a56f0..7c3ee3cc0 100644 --- a/src/rpc/client.h +++ b/src/rpc/client.h @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_RPCCLIENT_H #define BITCOIN_RPCCLIENT_H diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 29cfe1c13..c29bcc5d9 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "amount.h" #include "chainparams.h" @@ -207,7 +207,7 @@ UniValue generate(const UniValue& params, bool fHelp) unsigned int n = ehparams[0].n; unsigned int k = ehparams[0].k; - std::unique_ptr pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript)); + std::unique_ptr pblocktemplate(CreateNewBlock(Params(), coinbaseScript->reserveScript)); if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); CBlock *pblock = &pblocktemplate->block; @@ -255,7 +255,7 @@ UniValue generate(const UniValue& params, bool fHelp) } endloop: CValidationState state; - if (!ProcessNewBlock(state, NULL, pblock, true, NULL)) + if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); @@ -531,7 +531,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) if (block.hashPrevBlock != pindexPrev->GetBlockHash()) return "inconclusive-not-best-prevblk"; CValidationState state; - TestBlockValidity(state, block, pindexPrev, false, true); + TestBlockValidity(state, Params(), block, pindexPrev, false, true); return BIP22ValidationResult(state); } } @@ -542,7 +542,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) if (vNodes.empty()) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "BitcoinZ is not connected!"); - if (IsInitialBlockDownload()) + if (IsInitialBlockDownload(Params())) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "BitcoinZ is downloading blocks..."); static unsigned int nTransactionsUpdatedLast; @@ -622,7 +622,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) if (!coinbaseScript->reserveScript.size()) throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet or -mineraddress)"); - pblocktemplate = CreateNewBlock(coinbaseScript->reserveScript); + pblocktemplate = CreateNewBlock(Params(), coinbaseScript->reserveScript); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); @@ -790,7 +790,7 @@ UniValue submitblock(const UniValue& params, bool fHelp) CValidationState state; submitblock_StateCatcher sc(block.GetHash()); RegisterValidationInterface(&sc); - bool fAccepted = ProcessNewBlock(state, NULL, &block, true, NULL); + bool fAccepted = ProcessNewBlock(state, Params(), NULL, &block, true, NULL); UnregisterValidationInterface(&sc); if (fBlockPresent) { diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 589fbf5c6..4764cc459 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "clientversion.h" #include "init.h" @@ -11,6 +11,7 @@ #include "netbase.h" #include "rpc/server.h" #include "timedata.h" +#include "txmempool.h" #include "util.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" @@ -51,7 +52,7 @@ UniValue getinfo(const UniValue& params, bool fHelp) " \"version\": xxxxx, (numeric) the server version\n" " \"protocolversion\": xxxxx, (numeric) the protocol version\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total Zcash balance of the wallet\n" + " \"balance\": xxxxxxx, (numeric) the total BitcoinZ balance of the wallet\n" " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" " \"timeoffset\": xxxxx, (numeric) the time offset\n" " \"connections\": xxxxx, (numeric) the number of connections\n" @@ -154,13 +155,13 @@ UniValue validateaddress(const UniValue& params, bool fHelp) if (fHelp || params.size() != 1) throw runtime_error( "validateaddress \"zcashaddress\"\n" - "\nReturn information about the given Zcash address.\n" + "\nReturn information about the given BitcoinZ address.\n" "\nArguments:\n" - "1. \"zcashaddress\" (string, required) The Zcash address to validate\n" + "1. \"zcashaddress\" (string, required) The BitcoinZ address to validate\n" "\nResult:\n" "{\n" " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" - " \"address\" : \"zcashaddress\", (string) The Zcash address validated\n" + " \"address\" : \"zcashaddress\", (string) The BitcoinZ address validated\n" " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n" " \"ismine\" : true|false, (boolean) If the address is yours or not\n" " \"isscript\" : true|false, (boolean) If the key is a script\n" @@ -364,9 +365,9 @@ UniValue createmultisig(const UniValue& params, bool fHelp) "\nArguments:\n" "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" - "2. \"keys\" (string, required) A json array of keys which are Zcash addresses or hex-encoded public keys\n" + "2. \"keys\" (string, required) A json array of keys which are BitcoinZ addresses or hex-encoded public keys\n" " [\n" - " \"key\" (string) Zcash address or hex-encoded public key\n" + " \"key\" (string) BitcoinZ address or hex-encoded public key\n" " ,...\n" " ]\n" @@ -403,7 +404,7 @@ UniValue verifymessage(const UniValue& params, bool fHelp) "verifymessage \"zcashaddress\" \"signature\" \"message\"\n" "\nVerify a signed message\n" "\nArguments:\n" - "1. \"zcashaddress\" (string, required) The Zcash address to use for the signature.\n" + "1. \"zcashaddress\" (string, required) The BitcoinZ address to use for the signature.\n" "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n" "3. \"message\" (string, required) The message that was signed.\n" "\nResult:\n" @@ -483,6 +484,632 @@ UniValue setmocktime(const UniValue& params, bool fHelp) return NullUniValue; } +// insightexplorer +static bool getAddressFromIndex( + int type, const uint160 &hash, std::string &address) +{ + if (type == CScript::P2SH) { + address = EncodeDestination(CScriptID(hash)); + } else if (type == CScript::P2PKH) { + address = EncodeDestination(CKeyID(hash)); + } else { + return false; + } + return true; +} + +// This function accepts an address and returns in the output parameters +// the version and raw bytes for the RIPEMD-160 hash. +static bool getIndexKey( + const CTxDestination& dest, uint160& hashBytes, int& type) +{ + if (!IsValidDestination(dest)) { + return false; + } + if (dest.type() == typeid(CKeyID)) { + auto x = boost::get(&dest); + memcpy(&hashBytes, x->begin(), 20); + type = CScript::P2PKH; + return true; + } + if (dest.type() == typeid(CScriptID)) { + auto x = boost::get(&dest); + memcpy(&hashBytes, x->begin(), 20); + type = CScript::P2SH; + return true; + } + return false; +} + +// insightexplorer +static bool getAddressesFromParams( + const UniValue& params, + std::vector> &addresses) +{ + std::vector param_addresses; + if (params[0].isStr()) { + param_addresses.push_back(params[0].get_str()); + } else if (params[0].isObject()) { + UniValue addressValues = find_value(params[0].get_obj(), "addresses"); + if (!addressValues.isArray()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, + "Addresses is expected to be an array"); + } + for (const auto& it : addressValues.getValues()) { + param_addresses.push_back(it.get_str()); + } + + } else { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + for (const auto& it : param_addresses) { + CTxDestination address = DecodeDestination(it); + uint160 hashBytes; + int type = 0; + if (!getIndexKey(address, hashBytes, type)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + addresses.push_back(std::make_pair(hashBytes, type)); + } + return true; +} + +// insightexplorer +UniValue getaddressmempool(const UniValue& params, bool fHelp) +{ + std::string enableArg = "insightexplorer"; + bool enabled = fExperimentalMode && fInsightExplorer; + std::string disabledMsg = ""; + if (!enabled) { + disabledMsg = experimentalDisabledHelpMsg("getaddressmempool", enableArg); + } + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressmempool {\"addresses\": [\"taddr\", ...]}\n" + "\nReturns all mempool deltas for an address.\n" + + disabledMsg + + "\nArguments:\n" + "{\n" + " \"addresses\":\n" + " [\n" + " \"address\" (string) The base58check encoded address\n" + " ,...\n" + " ]\n" + "}\n" + "(or)\n" + "\"address\" (string) The base58check encoded address\n" + "\nResult:\n" + "[\n" + " {\n" + " \"address\" (string) The base58check encoded address\n" + " \"txid\" (string) The related txid\n" + " \"index\" (number) The related input or output index\n" + " \"satoshis\" (number) The difference of zatoshis\n" + " \"timestamp\" (number) The time the transaction entered the mempool (seconds)\n" + " \"prevtxid\" (string) The previous txid (if spending)\n" + " \"prevout\" (string) The previous transaction output index (if spending)\n" + " }\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getaddressmempool", "'{\"addresses\": [\"tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ\"]}'") + + HelpExampleRpc("getaddressmempool", "{\"addresses\": [\"tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ\"]}") + ); + + if (!enabled) { + throw JSONRPCError(RPC_MISC_ERROR, "Error: getaddressmempool is disabled. " + "Run './bitcoinz-cli help getaddressmempool' for instructions on how to enable this feature."); + } + + std::vector> addresses; + + if (!getAddressesFromParams(params, addresses)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + std::vector> indexes; + mempool.getAddressIndex(addresses, indexes); + std::sort(indexes.begin(), indexes.end(), + [](const std::pair& a, + const std::pair& b) -> bool { + return a.second.time < b.second.time; + }); + + UniValue result(UniValue::VARR); + + for (const auto& it : indexes) { + std::string address; + if (!getAddressFromIndex(it.first.type, it.first.addressBytes, address)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type"); + } + UniValue delta(UniValue::VOBJ); + delta.push_back(Pair("address", address)); + delta.push_back(Pair("txid", it.first.txhash.GetHex())); + delta.push_back(Pair("index", (int)it.first.index)); + delta.push_back(Pair("satoshis", it.second.amount)); + delta.push_back(Pair("timestamp", it.second.time)); + if (it.second.amount < 0) { + delta.push_back(Pair("prevtxid", it.second.prevhash.GetHex())); + delta.push_back(Pair("prevout", (int)it.second.prevout)); + } + result.push_back(delta); + } + return result; +} + +// insightexplorer +UniValue getaddressutxos(const UniValue& params, bool fHelp) +{ + std::string enableArg = "insightexplorer"; + bool enabled = fExperimentalMode && fInsightExplorer; + std::string disabledMsg = ""; + if (!enabled) { + disabledMsg = experimentalDisabledHelpMsg("getaddressutxos", enableArg); + } + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressutxos {\"addresses\": [\"taddr\", ...], (\"chainInfo\": true|false)}\n" + "\nReturns all unspent outputs for an address.\n" + + disabledMsg + + "\nArguments:\n" + "{\n" + " \"addresses\":\n" + " [\n" + " \"address\" (string) The base58check encoded address\n" + " ,...\n" + " ],\n" + " \"chainInfo\" (boolean, optional, default=false) Include chain info with results\n" + "}\n" + "(or)\n" + "\"address\" (string) The base58check encoded address\n" + "\nResult\n" + "[\n" + " {\n" + " \"address\" (string) The address base58check encoded\n" + " \"txid\" (string) The output txid\n" + " \"height\" (number) The block height\n" + " \"outputIndex\" (number) The output index\n" + " \"script\" (string) The script hex encoded\n" + " \"satoshis\" (number) The number of zatoshis of the output\n" + " }, ...\n" + "]\n\n" + "(or, if chainInfo is true):\n\n" + "{\n" + " \"utxos\":\n" + " [\n" + " {\n" + " \"address\" (string) The address base58check encoded\n" + " \"txid\" (string) The output txid\n" + " \"height\" (number) The block height\n" + " \"outputIndex\" (number) The output index\n" + " \"script\" (string) The script hex encoded\n" + " \"satoshis\" (number) The number of zatoshis of the output\n" + " }, ...\n" + " ],\n" + " \"hash\" (string) The block hash\n" + " \"height\" (numeric) The block height\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getaddressutxos", "'{\"addresses\": [\"tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ\"], \"chainInfo\": true}'") + + HelpExampleRpc("getaddressutxos", "{\"addresses\": [\"tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ\"], \"chainInfo\": true}") + ); + + if (!enabled) { + throw JSONRPCError(RPC_MISC_ERROR, "Error: getaddressutxos is disabled. " + "Run './bitcoinz-cli help getaddressutxos' for instructions on how to enable this feature."); + } + + bool includeChainInfo = false; + if (params[0].isObject()) { + UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo"); + if (!chainInfo.isNull()) { + includeChainInfo = chainInfo.get_bool(); + } + } + std::vector> addresses; + if (!getAddressesFromParams(params, addresses)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + std::vector unspentOutputs; + for (const auto& it : addresses) { + if (!GetAddressUnspent(it.first, it.second, unspentOutputs)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + } + std::sort(unspentOutputs.begin(), unspentOutputs.end(), + [](const CAddressUnspentDbEntry& a, const CAddressUnspentDbEntry& b) -> bool { + return a.second.blockHeight < b.second.blockHeight; + }); + + UniValue utxos(UniValue::VARR); + for (const auto& it : unspentOutputs) { + UniValue output(UniValue::VOBJ); + std::string address; + if (!getAddressFromIndex(it.first.type, it.first.hashBytes, address)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type"); + } + + output.push_back(Pair("address", address)); + output.push_back(Pair("txid", it.first.txhash.GetHex())); + output.push_back(Pair("outputIndex", (int)it.first.index)); + output.push_back(Pair("script", HexStr(it.second.script.begin(), it.second.script.end()))); + output.push_back(Pair("satoshis", it.second.satoshis)); + output.push_back(Pair("height", it.second.blockHeight)); + utxos.push_back(output); + } + + if (!includeChainInfo) + return utxos; + + UniValue result(UniValue::VOBJ); + result.push_back(Pair("utxos", utxos)); + + LOCK(cs_main); // for chainActive + result.push_back(Pair("hash", chainActive.Tip()->GetBlockHash().GetHex())); + result.push_back(Pair("height", (int)chainActive.Height())); + return result; +} + +static void getHeightRange(const UniValue& params, int& start, int& end) +{ + start = 0; + end = 0; + if (params[0].isObject()) { + UniValue startValue = find_value(params[0].get_obj(), "start"); + UniValue endValue = find_value(params[0].get_obj(), "end"); + // If either is not specified, the other is ignored. + if (!startValue.isNull() && !endValue.isNull()) { + start = startValue.get_int(); + end = endValue.get_int(); + if (start <= 0 || end <= 0) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, + "Start and end are expected to be greater than zero"); + } + if (end < start) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, + "End value is expected to be greater than start"); + } + } + } + + LOCK(cs_main); // for chainActive + if (start > chainActive.Height() || end > chainActive.Height()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start or end is outside chain range"); + } +} + +// Parse an address list then fetch the corresponding addressindex information. +static void getAddressesInHeightRange( + const UniValue& params, + int start, int end, + std::vector>& addresses, + std::vector> &addressIndex) +{ + if (!getAddressesFromParams(params, addresses)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + for (const auto& it : addresses) { + if (!GetAddressIndex(it.first, it.second, addressIndex, start, end)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, + "No information available for address"); + } + } +} + +// insightexplorer +UniValue getaddressdeltas(const UniValue& params, bool fHelp) +{ + std::string enableArg = "insightexplorer"; + bool enabled = fExperimentalMode && fInsightExplorer; + std::string disabledMsg = ""; + if (!enabled) { + disabledMsg = experimentalDisabledHelpMsg("getaddressdeltas", enableArg); + } + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressdeltas {\"addresses\": [\"taddr\", ...], (\"start\": n), (\"end\": n), (\"chainInfo\": true|false)}\n" + "\nReturns all changes for an address.\n" + "\nReturns information about all changes to the given transparent addresses within the given (inclusive)\n" + "\nblock height range, default is the full blockchain.\n" + + disabledMsg + + "\nArguments:\n" + "{\n" + " \"addresses\":\n" + " [\n" + " \"address\" (string) The base58check encoded address\n" + " ,...\n" + " ]\n" + " \"start\" (number, optional) The start block height\n" + " \"end\" (number, optional) The end block height\n" + " \"chainInfo\" (boolean, optional, default=false) Include chain info in results, only applies if start and end specified\n" + "}\n" + "(or)\n" + "\"address\" (string) The base58check encoded address\n" + "\nResult:\n" + "[\n" + " {\n" + " \"satoshis\" (number) The difference of zatoshis\n" + " \"txid\" (string) The related txid\n" + " \"index\" (number) The related input or output index\n" + " \"height\" (number) The block height\n" + " \"address\" (string) The base58check encoded address\n" + " }, ...\n" + "]\n\n" + "(or, if chainInfo is true):\n\n" + "{\n" + " \"deltas\":\n" + " [\n" + " {\n" + " \"satoshis\" (number) The difference of zatoshis\n" + " \"txid\" (string) The related txid\n" + " \"index\" (number) The related input or output index\n" + " \"height\" (number) The block height\n" + " \"address\" (string) The address base58check encoded\n" + " }, ...\n" + " ],\n" + " \"start\":\n" + " {\n" + " \"hash\" (string) The start block hash\n" + " \"height\" (numeric) The height of the start block\n" + " }\n" + " \"end\":\n" + " {\n" + " \"hash\" (string) The end block hash\n" + " \"height\" (numeric) The height of the end block\n" + " }\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getaddressdeltas", "'{\"addresses\": [\"tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ\"], \"start\": 1000, \"end\": 2000, \"chainInfo\": true}'") + + HelpExampleRpc("getaddressdeltas", "{\"addresses\": [\"tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ\"], \"start\": 1000, \"end\": 2000, \"chainInfo\": true}") + ); + + if (!enabled) { + throw JSONRPCError(RPC_MISC_ERROR, "Error: getaddressdeltas is disabled. " + "Run './bitcoinz-cli help getaddressdeltas' for instructions on how to enable this feature."); + } + + int start = 0; + int end = 0; + getHeightRange(params, start, end); + + std::vector> addresses; + std::vector> addressIndex; + getAddressesInHeightRange(params, start, end, addresses, addressIndex); + + bool includeChainInfo = false; + if (params[0].isObject()) { + UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo"); + if (!chainInfo.isNull()) { + includeChainInfo = chainInfo.get_bool(); + } + } + + UniValue deltas(UniValue::VARR); + for (const auto& it : addressIndex) { + std::string address; + if (!getAddressFromIndex(it.first.type, it.first.hashBytes, address)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type"); + } + + UniValue delta(UniValue::VOBJ); + delta.push_back(Pair("address", address)); + delta.push_back(Pair("blockindex", (int)it.first.txindex)); + delta.push_back(Pair("height", it.first.blockHeight)); + delta.push_back(Pair("index", (int)it.first.index)); + delta.push_back(Pair("satoshis", it.second)); + delta.push_back(Pair("txid", it.first.txhash.GetHex())); + deltas.push_back(delta); + } + + UniValue result(UniValue::VOBJ); + + if (!(includeChainInfo && start > 0 && end > 0)) { + return deltas; + } + + UniValue startInfo(UniValue::VOBJ); + UniValue endInfo(UniValue::VOBJ); + { + LOCK(cs_main); // for chainActive + if (start > chainActive.Height() || end > chainActive.Height()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start or end is outside chain range"); + } + startInfo.push_back(Pair("hash", chainActive[start]->GetBlockHash().GetHex())); + endInfo.push_back(Pair("hash", chainActive[end]->GetBlockHash().GetHex())); + } + startInfo.push_back(Pair("height", start)); + endInfo.push_back(Pair("height", end)); + + result.push_back(Pair("deltas", deltas)); + result.push_back(Pair("start", startInfo)); + result.push_back(Pair("end", endInfo)); + + return result; +} + +// insightexplorer +UniValue getaddressbalance(const UniValue& params, bool fHelp) +{ + std::string enableArg = "insightexplorer"; + bool enabled = fExperimentalMode && fInsightExplorer; + std::string disabledMsg = ""; + if (!enabled) { + disabledMsg = experimentalDisabledHelpMsg("getaddressbalance", enableArg); + } + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressbalance {\"addresses\": [\"taddr\", ...]}\n" + "\nReturns the balance for addresses.\n" + + disabledMsg + + "\nArguments:\n" + "{\n" + " \"addresses:\"\n" + " [\n" + " \"address\" (string) The base58check encoded address\n" + " ,...\n" + " ]\n" + "}\n" + "(or)\n" + "\"address\" (string) The base58check encoded address\n" + "\nResult:\n" + "{\n" + " \"balance\" (string) The current balance in zatoshis\n" + " \"received\" (string) The total number of zatoshis received (including change)\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getaddressbalance", "'{\"addresses\": [\"tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ\"]}'") + + HelpExampleRpc("getaddressbalance", "{\"addresses\": [\"tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ\"]}") + ); + + if (!enabled) { + throw JSONRPCError(RPC_MISC_ERROR, "Error: getaddressbalance is disabled. " + "Run './bitcoinz-cli help getaddressbalance' for instructions on how to enable this feature."); + } + + std::vector> addresses; + std::vector> addressIndex; + // this method doesn't take start and end block height params, so set + // to zero (full range, entire blockchain) + getAddressesInHeightRange(params, 0, 0, addresses, addressIndex); + + CAmount balance = 0; + CAmount received = 0; + for (const auto& it : addressIndex) { + if (it.second > 0) { + received += it.second; + } + balance += it.second; + } + UniValue result(UniValue::VOBJ); + result.push_back(Pair("balance", balance)); + result.push_back(Pair("received", received)); + return result; +} + +// insightexplorer +UniValue getaddresstxids(const UniValue& params, bool fHelp) +{ + std::string enableArg = "insightexplorer"; + bool enabled = fExperimentalMode && fInsightExplorer; + std::string disabledMsg = ""; + if (!enabled) { + disabledMsg = experimentalDisabledHelpMsg("getaddresstxids", enableArg); + } + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddresstxids {\"addresses\": [\"taddr\", ...], (\"start\": n), (\"end\": n)}\n" + "\nReturns the txids for given transparent addresses within the given (inclusive)\n" + "\nblock height range, default is the full blockchain.\n" + + disabledMsg + + "\nArguments:\n" + "{\n" + " \"addresses\":\n" + " [\n" + " \"taddr\" (string) The base58check encoded address\n" + " ,...\n" + " ]\n" + " \"start\" (number, optional) The start block height\n" + " \"end\" (number, optional) The end block height\n" + "}\n" + "(or)\n" + "\"address\" (string) The base58check encoded address\n" + "\nResult:\n" + "[\n" + " \"transactionid\" (string) The transaction id\n" + " ,...\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getaddresstxids", "'{\"addresses\": [\"tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ\"], \"start\": 1000, \"end\": 2000}'") + + HelpExampleRpc("getaddresstxids", "{\"addresses\": [\"tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ\"], \"start\": 1000, \"end\": 2000}") + ); + + if (!enabled) { + throw JSONRPCError(RPC_MISC_ERROR, "Error: getaddresstxids is disabled. " + "Run './bitcoinz-cli help getaddresstxids' for instructions on how to enable this feature."); + } + + int start = 0; + int end = 0; + getHeightRange(params, start, end); + + std::vector> addresses; + std::vector> addressIndex; + getAddressesInHeightRange(params, start, end, addresses, addressIndex); + + // This is an ordered set, sorted by height, so result also sorted by height. + std::set> txids; + + for (const auto& it : addressIndex) { + const int height = it.first.blockHeight; + const std::string txid = it.first.txhash.GetHex(); + // Duplicate entries (two addresses in same tx) are suppressed + txids.insert(std::make_pair(height, txid)); + } + UniValue result(UniValue::VARR); + for (const auto& it : txids) { + // only push the txid, not the height + result.push_back(it.second); + } + return result; +} + +// insightexplorer +UniValue getspentinfo(const UniValue& params, bool fHelp) +{ + std::string enableArg = "insightexplorer"; + bool enabled = fExperimentalMode && fInsightExplorer; + std::string disabledMsg = ""; + if (!enabled) { + disabledMsg = experimentalDisabledHelpMsg("getspentinfo", enableArg); + } + if (fHelp || params.size() != 1 || !params[0].isObject()) + throw runtime_error( + "getspentinfo {\"txid\": \"txidhex\", \"index\": n}\n" + "\nReturns the txid and index where an output is spent.\n" + + disabledMsg + + "\nArguments:\n" + "{\n" + " \"txid\" (string) The hex string of the txid\n" + " \"index\" (number) The vout (output) index\n" + "}\n" + "\nResult:\n" + "{\n" + " \"txid\" (string) The transaction id\n" + " \"index\" (number) The spending (vin, input) index\n" + " ,...\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getspentinfo", "'{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}'") + + HelpExampleRpc("getspentinfo", "{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}") + ); + + if (!enabled) { + throw JSONRPCError(RPC_MISC_ERROR, "Error: getspentinfo is disabled. " + "Run './bitcoinz-cli help getspentinfo' for instructions on how to enable this feature."); + } + + UniValue txidValue = find_value(params[0].get_obj(), "txid"); + UniValue indexValue = find_value(params[0].get_obj(), "index"); + + if (!txidValue.isStr()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid txid, must be a string"); + if (!indexValue.isNum()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid index, must be an integer"); + uint256 txid = ParseHashV(txidValue, "txid"); + int outputIndex = indexValue.get_int(); + + CSpentIndexKey key(txid, outputIndex); + CSpentIndexValue value; + + if (!GetSpentIndex(key, value)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to get spent info"); + } + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("txid", value.txid.GetHex())); + obj.push_back(Pair("index", (int)value.inputIndex)); + obj.push_back(Pair("height", value.blockHeight)); + + return obj; +} + static const CRPCCommand commands[] = { // category name actor (function) okSafeMode // --------------------- ------------------------ ----------------------- ---------- @@ -492,6 +1119,16 @@ static const CRPCCommand commands[] = { "util", "createmultisig", &createmultisig, true }, { "util", "verifymessage", &verifymessage, true }, + // START insightexplorer + /* Address index */ + { "addressindex", "getaddresstxids", &getaddresstxids, false }, /* insight explorer */ + { "addressindex", "getaddressbalance", &getaddressbalance, false }, /* insight explorer */ + { "addressindex", "getaddressdeltas", &getaddressdeltas, false }, /* insight explorer */ + { "addressindex", "getaddressutxos", &getaddressutxos, false }, /* insight explorer */ + { "addressindex", "getaddressmempool", &getaddressmempool, true }, /* insight explorer */ + { "blockchain", "getspentinfo", &getspentinfo, false }, /* insight explorer */ + // END insightexplorer + /* Not shown in help */ { "hidden", "setmocktime", &setmocktime, true }, }; diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 0a2879276..9180fe2fb 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "rpc/server.h" diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index 7713a54b3..1361fe6f8 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "rpc/protocol.h" diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h index 816ce9ec5..5e12d0a4f 100644 --- a/src/rpc/protocol.h +++ b/src/rpc/protocol.h @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_RPCPROTOCOL_H #define BITCOIN_RPCPROTOCOL_H diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index cd95fcb86..67a54cb64 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "consensus/upgrades.h" #include "consensus/validation.h" @@ -60,13 +60,15 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud UniValue TxJoinSplitToJSON(const CTransaction& tx) { bool useGroth = tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION; - UniValue vjoinsplit(UniValue::VARR); - for (unsigned int i = 0; i < tx.vjoinsplit.size(); i++) { - const JSDescription& jsdescription = tx.vjoinsplit[i]; + UniValue vJoinSplit(UniValue::VARR); + for (unsigned int i = 0; i < tx.vJoinSplit.size(); i++) { + const JSDescription& jsdescription = tx.vJoinSplit[i]; UniValue joinsplit(UniValue::VOBJ); joinsplit.push_back(Pair("vpub_old", ValueFromAmount(jsdescription.vpub_old))); + joinsplit.push_back(Pair("vpub_oldZat", jsdescription.vpub_old)); joinsplit.push_back(Pair("vpub_new", ValueFromAmount(jsdescription.vpub_new))); + joinsplit.push_back(Pair("vpub_newZat", jsdescription.vpub_new)); joinsplit.push_back(Pair("anchor", jsdescription.anchor.GetHex())); @@ -110,9 +112,9 @@ UniValue TxJoinSplitToJSON(const CTransaction& tx) { joinsplit.push_back(Pair("ciphertexts", ciphertexts)); } - vjoinsplit.push_back(joinsplit); + vJoinSplit.push_back(joinsplit); } - return vjoinsplit; + return vJoinSplit; } UniValue TxShieldedSpendsToJSON(const CTransaction& tx) { @@ -147,7 +149,8 @@ UniValue TxShieldedOutputsToJSON(const CTransaction& tx) { void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { - entry.push_back(Pair("txid", tx.GetHash().GetHex())); + const uint256 txid = tx.GetHash(); + entry.push_back(Pair("txid", txid.GetHex())); entry.push_back(Pair("overwintered", tx.fOverwintered)); entry.push_back(Pair("version", tx.nVersion)); if (tx.fOverwintered) { @@ -169,6 +172,20 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true))); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); + + // Add address and value info if spentindex enabled + CSpentIndexValue spentInfo; + CSpentIndexKey spentKey(txin.prevout.hash, txin.prevout.n); + if (fSpentIndex && GetSpentIndex(spentKey, spentInfo)) { + in.push_back(Pair("value", ValueFromAmount(spentInfo.satoshis))); + in.push_back(Pair("valueSat", spentInfo.satoshis)); + + CTxDestination dest = + DestFromAddressHash(spentInfo.addressType, spentInfo.addressHash); + if (IsValidDestination(dest)) { + in.push_back(Pair("address", EncodeDestination(dest))); + } + } } in.push_back(Pair("sequence", (int64_t)txin.nSequence)); vin.push_back(in); @@ -180,19 +197,30 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); out.push_back(Pair("valueZat", txout.nValue)); + out.push_back(Pair("valueSat", txout.nValue)); out.push_back(Pair("n", (int64_t)i)); UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(txout.scriptPubKey, o, true); out.push_back(Pair("scriptPubKey", o)); + + // Add spent information if spentindex is enabled + CSpentIndexValue spentInfo; + CSpentIndexKey spentKey(txid, i); + if (fSpentIndex && GetSpentIndex(spentKey, spentInfo)) { + out.push_back(Pair("spentTxId", spentInfo.txid.GetHex())); + out.push_back(Pair("spentIndex", (int)spentInfo.inputIndex)); + out.push_back(Pair("spentHeight", spentInfo.blockHeight)); + } vout.push_back(out); } entry.push_back(Pair("vout", vout)); - UniValue vjoinsplit = TxJoinSplitToJSON(tx); - entry.push_back(Pair("vjoinsplit", vjoinsplit)); + UniValue vJoinSplit = TxJoinSplitToJSON(tx); + entry.push_back(Pair("vJoinSplit", vJoinSplit)); if (tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION) { entry.push_back(Pair("valueBalance", ValueFromAmount(tx.valueBalance))); + entry.push_back(Pair("valueBalanceZat", tx.valueBalance)); UniValue vspenddesc = TxShieldedSpendsToJSON(tx); entry.push_back(Pair("vShieldedSpend", vspenddesc)); UniValue voutputdesc = TxShieldedOutputsToJSON(tx); @@ -208,14 +236,16 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (chainActive.Contains(pindex)) { + entry.push_back(Pair("height", pindex->nHeight)); entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight)); entry.push_back(Pair("time", pindex->GetBlockTime())); entry.push_back(Pair("blocktime", pindex->GetBlockTime())); - } - else + } else { + entry.push_back(Pair("height", -1)); entry.push_back(Pair("confirmations", 0)); - } - } + } + } + } } UniValue getrawtransaction(const UniValue& params, bool fHelp) @@ -266,7 +296,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) " \"reqSigs\" : n, (numeric) The required sigs\n" " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" " \"addresses\" : [ (json array of string)\n" - " \"zcashaddress\" (string) Zcash address\n" + " \"zcashaddress\" (string) BitcoinZ address\n" " ,...\n" " ]\n" " }\n" @@ -312,7 +342,6 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1") ); - LOCK(cs_main); uint256 hash = ParseHashV(params[0], "parameter 1"); @@ -320,9 +349,11 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) if (params.size() > 1) fVerbose = (params[1].get_int() != 0); + LOCK(cs_main); + CTransaction tx; uint256 hashBlock; - if (!GetTransaction(hash, tx, hashBlock, true)) + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); string strHex = EncodeHexTx(tx); @@ -392,7 +423,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) if (pblockindex == NULL) { CTransaction tx; - if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull()) + if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block"); if (!mapBlockIndex.count(hashBlock)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt"); @@ -400,7 +431,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) } CBlock block; - if(!ReadBlockFromDisk(block, pblockindex)) + if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); unsigned int ntxFound = 0; @@ -472,11 +503,13 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) " ]\n" "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n" " {\n" - " \"address\": x.xxx (numeric, required) The key is the Zcash address, the value is the " + CURRENCY_UNIT + " amount\n" + " \"address\": x.xxx (numeric, required) The key is the BitcoinZ address, the value is the " + CURRENCY_UNIT + " amount\n" " ,...\n" " }\n" "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n" - "4. expiryheight (numeric, optional, default=nextblockheight+" + strprintf("%d", DEFAULT_TX_EXPIRY_DELTA) + ") Expiry height of transaction (if Overwinter is active)\n" + "4. expiryheight (numeric, optional, default=" + + strprintf("nextblockheight+%d (pre-Blossom) or nextblockheight+%d (post-Blossom)", DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA, DEFAULT_POST_BLOSSOM_TX_EXPIRY_DELTA) + ") " + "Expiry height of transaction (if Overwinter is active)\n" "\nResult:\n" "\"transaction\" (string) hex string of the transaction\n" @@ -503,9 +536,9 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range"); rawTx.nLockTime = nLockTime; } - + if (params.size() > 3 && !params[3].isNull()) { - if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + if (Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_OVERWINTER)) { int64_t nExpiryHeight = params[3].get_int64(); if (nExpiryHeight < 0 || nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, expiryheight must be nonnegative and less than %d.", TX_EXPIRY_HEIGHT_THRESHOLD)); @@ -609,7 +642,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) " \"reqSigs\" : n, (numeric) The required sigs\n" " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" " \"addresses\" : [ (json array of string)\n" - " \"t12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) zcash address\n" + " \"t12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) BitcoinZ address\n" " ,...\n" " ]\n" " }\n" @@ -679,7 +712,7 @@ UniValue decodescript(const UniValue& params, bool fHelp) " \"type\":\"type\", (string) The output type\n" " \"reqSigs\": n, (numeric) The required signatures\n" " \"addresses\": [ (json array of string)\n" - " \"address\" (string) Zcash address\n" + " \"address\" (string) BitcoinZ address\n" " ,...\n" " ],\n" " \"p2sh\",\"address\" (string) script address\n" @@ -922,7 +955,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) } bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); - // Use the approximate release height if it is greater so offline nodes + // Use the approximate release height if it is greater so offline nodes // have a better estimation of the current height and will be more likely to // determine the correct consensus branch ID. Regtest mode ignores release height. int chainHeight = chainActive.Height() + 1; @@ -937,8 +970,8 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) if (!IsConsensusBranchId(consensusBranchId)) { throw runtime_error(params[4].get_str() + " is not a valid consensus branch id"); } - } - + } + // Script verification errors UniValue vErrors(UniValue::VARR); @@ -1020,7 +1053,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) // DoS mitigation: reject transactions expiring soon if (tx.nExpiryHeight > 0) { int nextBlockHeight = chainActive.Height() + 1; - if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + if (Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_OVERWINTER)) { if (nextBlockHeight + TX_EXPIRING_SOON_THRESHOLD > tx.nExpiryHeight) { throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("tx-expiring-soon: expiryheight is %d but should be at least %d to avoid transaction expiring soon", diff --git a/src/rpc/register.h b/src/rpc/register.h index 01aa58a25..4e0e05a04 100644 --- a/src/rpc/register.h +++ b/src/rpc/register.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_RPCREGISTER_H #define BITCOIN_RPCREGISTER_H diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 523f26c67..ff812d582 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "rpc/server.h" diff --git a/src/rpc/server.h b/src/rpc/server.h index 6ae427928..63758f9dd 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_RPCSERVER_H #define BITCOIN_RPCSERVER_H diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 8729f2a5a..ecd904cde 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "scheduler.h" diff --git a/src/scheduler.h b/src/scheduler.h index 436659e58..a79782603 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SCHEDULER_H #define BITCOIN_SCHEDULER_H diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index ec1ac5255..e92534df2 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "interpreter.h" @@ -91,7 +91,7 @@ bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { * Where R and S are not negative (their first byte has its highest bit not set), and not * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, * in which case a single 0 byte is necessary and even required). - * + * * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 * * This function is consensus-critical since BIP66. @@ -131,7 +131,7 @@ bool static IsValidSignatureEncoding(const std::vector &sig) { // Verify that the length of the signature matches the sum of the length // of the elements. if ((size_t)(lenR + lenS + 7) != sig.size()) return false; - + // Check whether the R element is an integer. if (sig[2] != 0x02) return false; @@ -965,12 +965,12 @@ namespace { */ class CTransactionSignatureSerializer { private: - const CTransaction &txTo; //! reference to the spending transaction (the one being serialized) - const CScript &scriptCode; //! output script being consumed - const unsigned int nIn; //! input index of txTo being signed - const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set - const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE - const bool fHashNone; //! whether the hashtype is SIGHASH_NONE + const CTransaction& txTo; //!< reference to the spending transaction (the one being serialized) + const CScript& scriptCode; //!< output script being consumed + const unsigned int nIn; //!< input index of txTo being signed + const bool fAnyoneCanPay; //!< whether the hashtype has the SIGHASH_ANYONECANPAY flag set + const bool fHashSingle; //!< whether the hashtype is SIGHASH_SINGLE + const bool fHashNone; //!< whether the hashtype is SIGHASH_NONE public: CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : @@ -1038,7 +1038,7 @@ class CTransactionSignatureSerializer { // Serialize nLockTime ::Serialize(s, txTo.nLockTime); - // Serialize vjoinsplit + // Serialize vJoinSplit if (txTo.nVersion >= 2) { // // SIGHASH_* functions will hash portions of @@ -1046,8 +1046,8 @@ class CTransactionSignatureSerializer { // keeps the JoinSplit cryptographically bound // to the transaction. // - ::Serialize(s, txTo.vjoinsplit); - if (txTo.vjoinsplit.size() > 0) { + ::Serialize(s, txTo.vJoinSplit); + if (txTo.vJoinSplit.size() > 0) { ::Serialize(s, txTo.joinSplitPubKey); CTransaction::joinsplit_sig_t nullSig = {}; @@ -1096,8 +1096,8 @@ uint256 GetOutputsHash(const CTransaction& txTo) { uint256 GetJoinSplitsHash(const CTransaction& txTo) { CBLAKE2bWriter ss(SER_GETHASH, static_cast(txTo.GetHeader()), ZCASH_JOINSPLITS_HASH_PERSONALIZATION); - for (unsigned int n = 0; n < txTo.vjoinsplit.size(); n++) { - ss << txTo.vjoinsplit[n]; + for (unsigned int n = 0; n < txTo.vJoinSplit.size(); n++) { + ss << txTo.vJoinSplit[n]; } ss << txTo.joinSplitPubKey; return ss.GetHash(); @@ -1188,7 +1188,7 @@ uint256 SignatureHash( hashOutputs = ss.GetHash(); } - if (!txTo.vjoinsplit.empty()) { + if (!txTo.vJoinSplit.empty()) { hashJoinSplits = cache ? cache->hashJoinSplits : GetJoinSplitsHash(txTo); } diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 8315c8252..e88528cf5 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SCRIPT_INTERPRETER_H #define BITCOIN_SCRIPT_INTERPRETER_H diff --git a/src/script/script.cpp b/src/script/script.cpp index 9d13fd040..11db1e358 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "script.h" @@ -242,14 +242,14 @@ bool CScript::IsPushOnly() const } // insightexplorer -int CScript::Type() const +CScript::ScriptType CScript::GetType() const { if (this->IsPayToPublicKeyHash()) - return 1; + return CScript::P2PKH; if (this->IsPayToScriptHash()) - return 2; + return CScript::P2SH; // We don't know this script - return 0; + return CScript::UNKNOWN; } // insightexplorer @@ -262,7 +262,7 @@ uint160 CScript::AddressHash() const else if (this->IsPayToScriptHash()) start = 2; else { - // unknown script type; return zeros + // unknown script type; return zeros (this can happen) vector hashBytes; hashBytes.resize(20); return uint160(hashBytes); diff --git a/src/script/script.h b/src/script/script.h index 6f8867611..6a677266d 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SCRIPT_SCRIPT_H #define BITCOIN_SCRIPT_SCRIPT_H @@ -567,8 +567,15 @@ class CScript : public CScriptBase */ unsigned int GetSigOpCount(const CScript& scriptSig) const; + // insightexplorer, there may be more script types in the future + enum ScriptType : int { + UNKNOWN = 0, + P2PKH = 1, + P2SH = 2, + }; bool IsPayToPublicKeyHash() const; bool IsPayToScriptHash() const; + ScriptType GetType() const; int Type() const; uint160 AddressHash() const; diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index f1aa1fb40..fa0cd1858 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "script_error.h" diff --git a/src/script/script_error.h b/src/script/script_error.h index bb10b8a29..cae125c13 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SCRIPT_SCRIPT_ERROR_H #define BITCOIN_SCRIPT_SCRIPT_ERROR_H diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index eee96e7c2..50e475558 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "sigcache.h" diff --git a/src/script/sigcache.h b/src/script/sigcache.h index 3583bd452..28de26751 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SCRIPT_SIGCACHE_H #define BITCOIN_SCRIPT_SIGCACHE_H diff --git a/src/script/sign.cpp b/src/script/sign.cpp index a4f642f97..a6434e80c 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "script/sign.h" diff --git a/src/script/sign.h b/src/script/sign.h index f531ad0d8..ee457423a 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SCRIPT_SIGN_H #define BITCOIN_SCRIPT_SIGN_H diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 88cde3698..e94dfb38b 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "script/standard.h" @@ -320,3 +320,19 @@ CScript GetScriptForMultisig(int nRequired, const std::vector& keys) bool IsValidDestination(const CTxDestination& dest) { return dest.which() != 0; } + +// insightexplorer +CTxDestination DestFromAddressHash(int scriptType, uint160& addressHash) +{ + switch (scriptType) { + case CScript::P2PKH: + return CTxDestination(CKeyID(addressHash)); + case CScript::P2SH: + return CTxDestination(CScriptID(addressHash)); + default: + // This probably won't ever happen, because it would mean that + // the addressindex contains a type (say, 3) that we (currently) + // don't recognize; maybe we "dropped support" for it? + return CNoDestination(); + } +} diff --git a/src/script/standard.h b/src/script/standard.h index fdb02f7c7..c4d895689 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SCRIPT_STANDARD_H #define BITCOIN_SCRIPT_STANDARD_H @@ -25,7 +25,7 @@ class CScriptID : public uint160 CScriptID(const uint160& in) : uint160(in) {} }; -static const unsigned int MAX_OP_RETURN_RELAY = 80; //! bytes +static const unsigned int MAX_OP_RETURN_RELAY = 80; //!< bytes extern unsigned nMaxDatacarrierBytes; /** @@ -73,7 +73,7 @@ class CNoDestination { friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } }; -/** +/** * A txout script template with a specific destination. It is either: * * CNoDestination: no destination set * * CKeyID: TX_PUBKEYHASH destination @@ -96,4 +96,7 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std:: CScript GetScriptForDestination(const CTxDestination& dest); CScript GetScriptForMultisig(int nRequired, const std::vector& keys); +// insightexplorer +CTxDestination DestFromAddressHash(int scriptType, uint160& addressHash); + #endif // BITCOIN_SCRIPT_STANDARD_H diff --git a/src/script/zcashconsensus.cpp b/src/script/zcashconsensus.cpp index 50d732fff..ec6091551 100644 --- a/src/script/zcashconsensus.cpp +++ b/src/script/zcashconsensus.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "zcashconsensus.h" diff --git a/src/script/zcashconsensus.h b/src/script/zcashconsensus.h index ff13471c6..a9176dbec 100644 --- a/src/script/zcashconsensus.h +++ b/src/script/zcashconsensus.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_ZCASHCONSENSUS_H #define BITCOIN_ZCASHCONSENSUS_H diff --git a/src/sendalert.cpp b/src/sendalert.cpp index 6e98a73fd..b7ebff8c6 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019 The BitcoinZ Community +// Copyright (c) 2018-2020 The BitcoinZ Community // Copyright (c) 2016-2018 The Zcash developers // Original code from: https://gist.github.com/laanwj/0e689cfa37b52bcbbb44 @@ -80,8 +80,9 @@ void ThreadSendAlert() // 170002 : 1.0.0 // 170006 : 1.1.2 // 170007 : 2.0.0 + // 170008 : 2.0.7 alert.nMinVer = 170002; - alert.nMaxVer = 770007; + alert.nMaxVer = 770008; // // main.cpp: diff --git a/src/serialize.h b/src/serialize.h index ac2db6edd..eb0d4e785 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SERIALIZE_H #define BITCOIN_SERIALIZE_H diff --git a/src/spentindex.h b/src/spentindex.h index 3e11b6080..9f85c62b0 100644 --- a/src/spentindex.h +++ b/src/spentindex.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SPENTINDEX_H #define BITCOIN_SPENTINDEX_H diff --git a/src/streams.h b/src/streams.h index 9d4a2e39e..5b2309e84 100644 --- a/src/streams.h +++ b/src/streams.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_STREAMS_H #define BITCOIN_STREAMS_H diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h index 5e7bb66ea..1de474b3f 100644 --- a/src/support/allocators/secure.h +++ b/src/support/allocators/secure.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SUPPORT_ALLOCATORS_SECURE_H #define BITCOIN_SUPPORT_ALLOCATORS_SECURE_H diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h index 41e23392e..19075f4e6 100644 --- a/src/support/allocators/zeroafterfree.h +++ b/src/support/allocators/zeroafterfree.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H #define BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H diff --git a/src/support/cleanse.cpp b/src/support/cleanse.cpp index a2141b244..7a4da12b4 100644 --- a/src/support/cleanse.cpp +++ b/src/support/cleanse.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "cleanse.h" diff --git a/src/support/cleanse.h b/src/support/cleanse.h index 3e02aa8fd..c6fe12912 100644 --- a/src/support/cleanse.h +++ b/src/support/cleanse.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SUPPORT_CLEANSE_H #define BITCOIN_SUPPORT_CLEANSE_H diff --git a/src/support/events.h b/src/support/events.h index 4f2f3cf9e..e14961231 100644 --- a/src/support/events.h +++ b/src/support/events.h @@ -1,6 +1,6 @@ // Copyright (c) 2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SUPPORT_EVENTS_H #define BITCOIN_SUPPORT_EVENTS_H diff --git a/src/support/pagelocker.cpp b/src/support/pagelocker.cpp index 440e0a519..47a98ba5d 100644 --- a/src/support/pagelocker.cpp +++ b/src/support/pagelocker.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "support/pagelocker.h" diff --git a/src/support/pagelocker.h b/src/support/pagelocker.h index cf42e3dfd..4002fd953 100644 --- a/src/support/pagelocker.h +++ b/src/support/pagelocker.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SUPPORT_PAGELOCKER_H #define BITCOIN_SUPPORT_PAGELOCKER_H diff --git a/src/sync.cpp b/src/sync.cpp index 1837e8d53..91a6745c0 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2012 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "sync.h" diff --git a/src/sync.h b/src/sync.h index 68a944308..45a3bd3fd 100644 --- a/src/sync.h +++ b/src/sync.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_SYNC_H #define BITCOIN_SYNC_H diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index 32b14cb93..4a985994f 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . // // Unit tests for block-chain checkpoints diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 6044b221f..742b87a61 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . // // Unit tests for denial-of-service detection/prevention code diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index 0c2ade48d..dcf28ed85 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "wallet/wallet.h" #include "wallet/walletdb.h" diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index fc0600dfc..0aa7f2369 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "addrman.h" #include "test/test_bitcoin.h" #include diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index d80bf4a6b..5854de113 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . // // Unit tests for alert system @@ -19,6 +19,7 @@ #include "streams.h" #include "util.h" #include "utilstrencodings.h" +#include "utiltest.h" #include "test/test_bitcoin.h" @@ -385,65 +386,92 @@ BOOST_AUTO_TEST_CASE(AlertDisablesRPC) mapAlerts.clear(); } -static bool falseFunc() { return false; } +static bool falseFunc(const CChainParams&) { return false; } -BOOST_AUTO_TEST_CASE(PartitionAlert) +void PartitionAlertTestImpl(const Consensus::Params& params, int startTime, int expectedTotal, int expectedSlow, int expectedFast) { // Test PartitionCheck CCriticalSection csDummy; - CBlockIndex indexDummy[400]; - CChainParams& params = Params(CBaseChainParams::MAIN); - int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing; + CBlockIndex indexDummy[800]; // Generate fake blockchain timestamps relative to // an arbitrary time: - int64_t now = 1427379054; - SetMockTime(now); - for (int i = 0; i < 400; i++) + int64_t start = startTime; + for (int i = 0; i < 800; i++) { indexDummy[i].phashBlock = NULL; - if (i == 0) indexDummy[i].pprev = NULL; - else indexDummy[i].pprev = &indexDummy[i-1]; + indexDummy[i].pprev = i ? &indexDummy[i-1] : NULL; indexDummy[i].nHeight = i; - indexDummy[i].nTime = now - (400-i)*nPowTargetSpacing; + indexDummy[i].nTime = i ? indexDummy[i - 1].nTime + params.PoWTargetSpacing(i) : start; // Other members don't matter, the partition check code doesn't // use them } + int64_t now = indexDummy[799].nTime + params.PoWTargetSpacing(800); + SetMockTime(now); // Test 1: chain with blocks every nPowTargetSpacing seconds, // as normal, no worries: - PartitionCheck(falseFunc, csDummy, &indexDummy[399], nPowTargetSpacing); - BOOST_CHECK(strMiscWarning.empty()); + strMiscWarning = ""; + PartitionCheck(falseFunc, csDummy, &indexDummy[799]); + BOOST_CHECK_EQUAL("", strMiscWarning); // Test 2: go 3.5 hours without a block, expect a warning: now += 3*60*60+30*60; SetMockTime(now); - PartitionCheck(falseFunc, csDummy, &indexDummy[399], nPowTargetSpacing); - BOOST_CHECK(!strMiscWarning.empty()); - BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); strMiscWarning = ""; + PartitionCheck(falseFunc, csDummy, &indexDummy[799]); + std::string expectedSlowErr = strprintf("WARNING: check your network connection, %d blocks received in the last 4 hours (%d expected)", expectedSlow, expectedTotal); + BOOST_CHECK_EQUAL(expectedSlowErr, strMiscWarning); + BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); // Test 3: test the "partition alerts only go off once per day" // code: now += 60*10; SetMockTime(now); - PartitionCheck(falseFunc, csDummy, &indexDummy[399], nPowTargetSpacing); - BOOST_CHECK(strMiscWarning.empty()); + strMiscWarning = ""; + PartitionCheck(falseFunc, csDummy, &indexDummy[799]); + BOOST_CHECK_EQUAL("", strMiscWarning); // Test 4: get 2.5 times as many blocks as expected: - now += 60*60*24; // Pretend it is a day later + start = now + 60*60*24; // Pretend it is a day later + for (int i = 0; i < 800; i++) { + // Tweak chain timestamps: + indexDummy[i].nTime = i ? indexDummy[i - 1].nTime + params.PoWTargetSpacing(i) * 2/5 : start; + } + now = indexDummy[799].nTime + params.PoWTargetSpacing(0) * 2/5; SetMockTime(now); - int64_t quickSpacing = nPowTargetSpacing*2/5; - for (int i = 0; i < 400; i++) // Tweak chain timestamps: - indexDummy[i].nTime = now - (400-i)*quickSpacing; - PartitionCheck(falseFunc, csDummy, &indexDummy[399], nPowTargetSpacing); - BOOST_CHECK(!strMiscWarning.empty()); + strMiscWarning = ""; + PartitionCheck(falseFunc, csDummy, &indexDummy[799]); + std::string expectedFastErr = strprintf("WARNING: abnormally high number of blocks generated, %d blocks received in the last 4 hours (%d expected)", expectedFast, expectedTotal); + BOOST_CHECK_EQUAL(expectedFastErr, strMiscWarning); BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); strMiscWarning = ""; SetMockTime(0); } +BOOST_AUTO_TEST_CASE(PartitionAlert) +{ + CChainParams& params = Params(CBaseChainParams::MAIN); + PartitionAlertTestImpl(params.GetConsensus(), 1000000000, 96, 12, 240); +} + +BOOST_AUTO_TEST_CASE(PartitionAlertBlossomOnly) +{ + PartitionAlertTestImpl(RegtestActivateBlossom(false), 1500000000, 96 * 2, 12 * 2, 240 * 2); + RegtestDeactivateBlossom(); +} + +BOOST_AUTO_TEST_CASE(PartitionAlertBlossomActivates) +{ + // 48 pre blossom blocks, 96 blossom blocks will take 48 * 150s + 96 * 75s = 4hrs + // in the slow case, all of the blocks will be blossom blocks + // in the fast case, 96 blocks will be blossom => 96 * 75s * 2/5 = 2880s spent on blossom + // => (14400 - 2880) / (150 * 2/5) = 11520 / 60 = 192 pre blossom blocks + PartitionAlertTestImpl(RegtestActivateBlossom(false, 799 - 96), 2000000000, 144, 12 * 2, 192 + 96); + RegtestDeactivateBlossom(); +} + BOOST_AUTO_TEST_SUITE_END() */ diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 2108efece..63f4bed00 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "util.h" diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 17d6bed6d..ba0b6141c 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include #include diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp index 0b883fbef..7779461aa 100644 --- a/src/test/base32_tests.cpp +++ b/src/test/base32_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "utilstrencodings.h" #include "test/test_bitcoin.h" diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 80b2bb1dc..f7a6c9e39 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "base58.h" diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index b134e49ca..1996b38f1 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "utilstrencodings.h" #include "test/test_bitcoin.h" diff --git a/src/test/bctest.py b/src/test/bctest.py index 86724241b..33e7c8aa3 100644 --- a/src/test/bctest.py +++ b/src/test/bctest.py @@ -1,6 +1,6 @@ # Copyright 2014 BitPay, Inc. # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import subprocess import json diff --git a/src/test/bech32_tests.cpp b/src/test/bech32_tests.cpp index 02252bcbf..ac4779006 100644 --- a/src/test/bech32_tests.cpp +++ b/src/test/bech32_tests.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "bech32.h" #include "test/test_bitcoin.h" diff --git a/src/test/bignum.h b/src/test/bignum.h index a7fb18953..13e70133a 100644 --- a/src/test/bignum.h +++ b/src/test/bignum.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_TEST_BIGNUM_H #define BITCOIN_TEST_BIGNUM_H diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 8815d1c54..104173b19 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py index 6551eb6f2..c977a1e28 100755 --- a/src/test/bitcoin-util-test.py +++ b/src/test/bitcoin-util-test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright 2014 BitPay, Inc. # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# file COPYING or https://www.opensource.org/licenses/mit-license.php . import os import bctest diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 9189e4af8..ef9c4cd28 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "bloom.h" diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index c813c9af9..2563076f9 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2013-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "clientversion.h" #include "consensus/validation.h" @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(May15) // After May 15'th, big blocks are OK: forkingBlock.nTime = tMay15; // Invalidates PoW auto verifier = libzcash::ProofVerifier::Strict(); - BOOST_CHECK(CheckBlock(forkingBlock, state, verifier, false, false)); + BOOST_CHECK(CheckBlock(forkingBlock, state, Params(), verifier, false, false)); } SetMockTime(0); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 1612ab449..cd7b21441 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "coins.h" #include "random.h" @@ -237,8 +237,8 @@ class TxWithNullifiers sproutNullifier = GetRandHash(); JSDescription jsd; jsd.nullifiers[0] = sproutNullifier; - mutableTx.vjoinsplit.emplace_back(jsd); - + mutableTx.vJoinSplit.emplace_back(jsd); + saplingNullifier = GetRandHash(); SpendDescription sd; sd.nullifier = saplingNullifier; @@ -580,7 +580,7 @@ template void anchorsFlushImpl(ShieldedType type) cache.PushAnchor(tree); cache.Flush(); } - + { CCoinsViewCacheTest cache(&base); Tree tree; @@ -640,7 +640,7 @@ BOOST_AUTO_TEST_CASE(chained_joinsplits) { CMutableTransaction mtx; - mtx.vjoinsplit.push_back(js2); + mtx.vJoinSplit.push_back(js2); BOOST_CHECK(!cache.HaveShieldedRequirements(mtx)); } @@ -649,35 +649,35 @@ BOOST_AUTO_TEST_CASE(chained_joinsplits) // js2 is trying to anchor to js1 but js1 // appears afterwards -- not a permitted ordering CMutableTransaction mtx; - mtx.vjoinsplit.push_back(js2); - mtx.vjoinsplit.push_back(js1); + mtx.vJoinSplit.push_back(js2); + mtx.vJoinSplit.push_back(js1); BOOST_CHECK(!cache.HaveShieldedRequirements(mtx)); } { CMutableTransaction mtx; - mtx.vjoinsplit.push_back(js1); - mtx.vjoinsplit.push_back(js2); + mtx.vJoinSplit.push_back(js1); + mtx.vJoinSplit.push_back(js2); BOOST_CHECK(cache.HaveShieldedRequirements(mtx)); } { CMutableTransaction mtx; - mtx.vjoinsplit.push_back(js1); - mtx.vjoinsplit.push_back(js2); - mtx.vjoinsplit.push_back(js3); + mtx.vJoinSplit.push_back(js1); + mtx.vJoinSplit.push_back(js2); + mtx.vJoinSplit.push_back(js3); BOOST_CHECK(cache.HaveShieldedRequirements(mtx)); } { CMutableTransaction mtx; - mtx.vjoinsplit.push_back(js1); - mtx.vjoinsplit.push_back(js1b); - mtx.vjoinsplit.push_back(js2); - mtx.vjoinsplit.push_back(js3); + mtx.vJoinSplit.push_back(js1); + mtx.vJoinSplit.push_back(js1b); + mtx.vJoinSplit.push_back(js2); + mtx.vJoinSplit.push_back(js3); BOOST_CHECK(cache.HaveShieldedRequirements(mtx)); } @@ -738,7 +738,7 @@ template void anchorsTestImpl(ShieldedType type) { Tree test_tree2; GetAnchorAt(cache, newrt, test_tree2); - + BOOST_CHECK(test_tree2.root() == newrt); } diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp index 376ae9368..5227f6cfd 100644 --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "compressor.h" #include "util.h" diff --git a/src/test/convertbits_tests.cpp b/src/test/convertbits_tests.cpp index a8908ebfc..1a4786912 100644 --- a/src/test/convertbits_tests.cpp +++ b/src/test/convertbits_tests.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include #include diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index aeb2a5caa..9e3cf2d59 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "crypto/ripemd160.h" #include "crypto/sha1.h" diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index a047938db..1853cbf1d 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2018 The Zcash developers // Copyright (c) 2012-2017 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "dbwrapper.h" #include "uint256.h" diff --git a/src/test/equihash_tests.cpp b/src/test/equihash_tests.cpp index 6f2f0b858..745afbd99 100644 --- a/src/test/equihash_tests.cpp +++ b/src/test/equihash_tests.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2016 Jack Grigg // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index a0c5592a9..acc1adab7 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "util.h" #include "test/test_bitcoin.h" diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index e5d2e5a43..356fb245b 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "hash.h" #include "utilstrencodings.h" diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 64d7ade52..6d28cd1b8 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "key.h" diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index fab12fc90..db953e1ea 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "chainparams.h" #include "main.h" @@ -10,76 +10,101 @@ #include #include + BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup) +const CAmount INITIAL_SUBSIDY = 12500 * COIN; + +static int GetTotalHalvings(const Consensus::Params& consensusParams) { + // This assumes that BLOSSOM_POW_TARGET_SPACING_RATIO == 2 + // and treats blossom activation as a halving event + return consensusParams.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight == Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT ? 64 : 65; +} + static void TestBlockSubsidyHalvings(const Consensus::Params& consensusParams) { - int maxHalvings = 64; - CAmount nInitialSubsidy = 12500 * COIN; - - CAmount nPreviousSubsidy = nInitialSubsidy * 2; // for height == 0 - BOOST_CHECK_EQUAL(nPreviousSubsidy, nInitialSubsidy * 2); - for (int nHalvings = 0; nHalvings < maxHalvings; nHalvings++) { - int nHeight; - if (nHalvings > 0) // Check subsidy right at halvings - nHeight = nHalvings * consensusParams.nSubsidyHalvingInterval + consensusParams.SubsidySlowStartShift(); - else // Check subsidy just after end of slow start - nHeight = consensusParams.nSubsidySlowStartInterval; + bool blossomActive = false; + int blossomActivationHeight = consensusParams.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight; + int nHeight = consensusParams.nSubsidySlowStartInterval; + BOOST_CHECK_EQUAL(GetBlockSubsidy(nHeight, consensusParams), INITIAL_SUBSIDY); + CAmount nPreviousSubsidy = INITIAL_SUBSIDY; + for (int nHalvings = 1; nHalvings < GetTotalHalvings(consensusParams); nHalvings++) { + if (blossomActive) { + if (nHeight == blossomActivationHeight) { + int preBlossomHeight = (nHalvings - 1) * consensusParams.nPreBlossomSubsidyHalvingInterval + consensusParams.SubsidySlowStartShift(); + nHeight += (preBlossomHeight - blossomActivationHeight) * Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO; + } else { + nHeight += consensusParams.nPostBlossomSubsidyHalvingInterval; + } + } else { + nHeight = nHalvings * consensusParams.nPreBlossomSubsidyHalvingInterval + consensusParams.SubsidySlowStartShift(); + if (consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM)) { + nHeight = blossomActivationHeight; + blossomActive = true; + } + } + BOOST_CHECK_EQUAL(GetBlockSubsidy(nHeight - 1, consensusParams), nPreviousSubsidy); CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams); - BOOST_CHECK(nSubsidy <= nInitialSubsidy); + BOOST_CHECK(nSubsidy <= INITIAL_SUBSIDY); BOOST_CHECK_EQUAL(nSubsidy, nPreviousSubsidy / 2); nPreviousSubsidy = nSubsidy; } - BOOST_CHECK_EQUAL(GetBlockSubsidy((maxHalvings * consensusParams.nSubsidyHalvingInterval) + consensusParams.SubsidySlowStartShift(), consensusParams), 0); + BOOST_CHECK_EQUAL(GetBlockSubsidy(nHeight, consensusParams), 0); } -static void TestBlockSubsidyHalvings(int nSubsidySlowStartInterval, int nSubsidyHalvingInterval) +static void TestBlockSubsidyHalvings(int nSubsidySlowStartInterval, int nPreBlossomSubsidyHalvingInterval, int blossomActivationHeight) { Consensus::Params consensusParams; consensusParams.nSubsidySlowStartInterval = nSubsidySlowStartInterval; - consensusParams.nSubsidyHalvingInterval = nSubsidyHalvingInterval; + consensusParams.nPreBlossomSubsidyHalvingInterval = nPreBlossomSubsidyHalvingInterval; + consensusParams.nPostBlossomSubsidyHalvingInterval = nPreBlossomSubsidyHalvingInterval * Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO; + consensusParams.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight = blossomActivationHeight; TestBlockSubsidyHalvings(consensusParams); } BOOST_AUTO_TEST_CASE(block_subsidy_test) { TestBlockSubsidyHalvings(Params(CBaseChainParams::MAIN).GetConsensus()); // As in main - TestBlockSubsidyHalvings(50, 150); // As in regtest - TestBlockSubsidyHalvings(500, 1000); // Just another interval + TestBlockSubsidyHalvings(20000, Consensus::PRE_BLOSSOM_HALVING_INTERVAL, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); // Pre-Blossom + TestBlockSubsidyHalvings(50, 150, 80); // As in regtest + TestBlockSubsidyHalvings(500, 1000, 900); // Just another interval + TestBlockSubsidyHalvings(500, 1000, 3000); // Multiple halvings before Blossom activation } BOOST_AUTO_TEST_CASE(subsidy_limit_test) { const Consensus::Params& consensusParams = Params(CBaseChainParams::MAIN).GetConsensus(); + CAmount nSum = 0; + int nHeight = 0; // Mining slow start - for (int nHeight = 0; nHeight < consensusParams.nSubsidySlowStartInterval; nHeight ++) { + for (; nHeight < consensusParams.nSubsidySlowStartInterval; nHeight++) { CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams); - BOOST_CHECK(nSubsidy <= 12500 * COIN); + BOOST_CHECK(nSubsidy <= INITIAL_SUBSIDY); nSum += nSubsidy; BOOST_CHECK(MoneyRange(nSum)); } BOOST_CHECK_EQUAL(nSum, 1250000000000ULL); - // Remainder of first period - for (int nHeight = consensusParams.nSubsidySlowStartInterval; nHeight < consensusParams.nSubsidyHalvingInterval + consensusParams.SubsidySlowStartShift(); nHeight ++) { - CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams); - BOOST_CHECK(nSubsidy <= 12500 * COIN); - nSum += nSubsidy; - BOOST_CHECK(MoneyRange(nSum)); - } - BOOST_CHECK_EQUAL(nSum, 1050000000000000000ULL); + // Regular mining - for (int nHeight = consensusParams.nSubsidyHalvingInterval + consensusParams.SubsidySlowStartShift(); nHeight < 56000000; nHeight += 1000) { - CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams); - BOOST_CHECK(nSubsidy <= 12500 * COIN); - nSum += nSubsidy * 1000; - BOOST_CHECK(MoneyRange(nSum)); - } + CAmount nSubsidy; + do { + nSubsidy = GetBlockSubsidy(nHeight, consensusParams); + BOOST_CHECK(nSubsidy <= INITIAL_SUBSIDY); + nSum += nSubsidy; + BOOST_ASSERT(MoneyRange(nSum)); + ++nHeight; + } while (nSubsidy > 0); + // Changing the block interval from 10 to 2.5 minutes causes truncation // effects to occur earlier (from the 9th halving interval instead of the // 11th), decreasing the total monetary supply by 0.0693 ZEC. If the // transaction output field is widened, this discrepancy will become smaller // or disappear entirely. + // Reducing the interval further to 1.25 minutes has a similar effect, + // decreasing the total monetary supply by another 0.09240 ZEC. + // TODO Change this assert when setting the blossom activation height + // Note that these numbers may or may not change depending on the activation height BOOST_CHECK_EQUAL(nSum, 2099999999988240000ULL); } diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index a82f5bce6..f448d92e0 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "consensus/upgrades.h" #include "main.h" diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 3f6a0af77..c88a53c13 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "arith_uint256.h" #include "consensus/validation.h" @@ -138,6 +138,7 @@ struct { // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { + const CChainParams& chainparams = Params(CBaseChainParams::MAIN); CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; CBlockTemplate *pblocktemplate; CMutableTransaction tx,tx2; @@ -158,7 +159,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i) { // Simple block creation, nothing special yet: - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); CBlock *pblock = &pblocktemplate->block; // pointer for convenience pblock->nVersion = 4; @@ -167,7 +168,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) // of the next block must be six spacings ahead of that to be at least // one spacing ahead of the tip. Within 11 blocks of genesis, the median // will be closer to the tip, and blocks will appear slower. - pblock->nTime = chainActive.Tip()->GetMedianTimePast()+6*Params().GetConsensus().nPowTargetSpacing; + pblock->nTime = chainActive.Tip()->GetMedianTimePast()+6*Params().GetConsensus().PoWTargetSpacing(i); CMutableTransaction txCoinbase(pblock->vtx[0]); txCoinbase.nVersion = 1; txCoinbase.vin[0].scriptSig = CScript() << (chainActive.Height()+1) << OP_0; @@ -264,7 +265,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->hashFinalSaplingRoot = uint256(); CValidationState state; - BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL)); + BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL)); BOOST_CHECK_MESSAGE(state.IsValid(), state.GetRejectReason()); pblock->hashPrevBlock = pblock->GetHash(); @@ -273,7 +274,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) } // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; // block sigops > limit: 1000 CHECKMULTISIG + 1 @@ -292,7 +293,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -313,14 +314,14 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); // orphan in mempool hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -338,7 +339,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 49000LL; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -349,7 +350,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 0; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -367,7 +368,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue -= 10000; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -381,17 +382,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); // subsidy changing int nHeight = chainActive.Height(); chainActive.Tip()->nHeight = 209999; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; chainActive.Tip()->nHeight = 210000; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; chainActive.Tip()->nHeight = nHeight; @@ -423,7 +424,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx2)); BOOST_CHECK(!CheckFinalTx(tx2, LOCKTIME_MEDIAN_TIME_PAST)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); // Neither tx should have made it into the template. BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); @@ -438,7 +439,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) //BOOST_CHECK(CheckFinalTx(tx)); //BOOST_CHECK(CheckFinalTx(tx2)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 2); delete pblocktemplate; diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp index 2b68f8899..04f2f9b05 100644 --- a/src/test/mruset_tests.cpp +++ b/src/test/mruset_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "mruset.h" diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index a7e48ee4c..506575f1a 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "consensus/upgrades.h" #include "key.h" diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 40b32a7b3..d81a10038 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "netbase.h" #include "test/test_bitcoin.h" diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 3975dff2e..f5c80b4a7 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "merkleblock.h" #include "serialize.h" diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index 7b0a632cb..382f9d614 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "policy/fees.h" #include "txmempool.h" diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index 5a11483f2..d8aadd707 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -1,10 +1,11 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "main.h" #include "pow.h" #include "util.h" +#include "utiltest.h" #include "test/test_bitcoin.h" #include @@ -18,13 +19,30 @@ BOOST_AUTO_TEST_CASE(get_next_work) { SelectParams(CBaseChainParams::MAIN); const Consensus::Params& params = Params().GetConsensus(); + BOOST_CHECK_EQUAL(150, params.PoWTargetSpacing(0)); - int64_t nLastRetargetTime = 1262149169; // NOTE: Not an actual block time - int64_t nThisTime = 1262152739; // Block #32255 of Bitcoin + int64_t nLastRetargetTime = 1000000000; // NOTE: Not an actual block time + int64_t nThisTime = 1000003570; arith_uint256 bnAvg; bnAvg.SetCompact(0x1d00ffff); BOOST_CHECK_EQUAL(0x1d011998, - CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params)); + CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, 0)); +} + + +BOOST_AUTO_TEST_CASE(get_next_work_blossom) +{ + const Consensus::Params& params = RegtestActivateBlossom(true); + BOOST_CHECK_EQUAL(75, params.PoWTargetSpacing(0)); + + int64_t nLastRetargetTime = 1000000000; // NOTE: Not an actual block time + int64_t nThisTime = 1000001445; + arith_uint256 bnAvg; + bnAvg.SetCompact(0x1d00ffff); + BOOST_CHECK_GT(0x1d011998, + CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, 0)); + + RegtestDeactivateBlossom(); } /* Test the constraint on the upper bound for next work */ @@ -33,12 +51,26 @@ BOOST_AUTO_TEST_CASE(get_next_work_pow_limit) SelectParams(CBaseChainParams::MAIN); const Consensus::Params& params = Params().GetConsensus(); - int64_t nLastRetargetTime = 1231006505; // Block #0 of Bitcoin - int64_t nThisTime = 1233061996; // Block #2015 of Bitcoin + int64_t nLastRetargetTime = 1231006505; + int64_t nThisTime = 1233061996; arith_uint256 bnAvg; bnAvg.SetCompact(0x1f07ffff); BOOST_CHECK_EQUAL(0x1f07ffff, - CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params)); + CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, 0)); +} + +BOOST_AUTO_TEST_CASE(get_next_work_pow_limit_blossom) +{ + const Consensus::Params& params = RegtestActivateBlossom(true); + + int64_t nLastRetargetTime = 1231006505; + int64_t nThisTime = 1233061996; + arith_uint256 bnAvg; + bnAvg.SetCompact(0x1f07ffff); + BOOST_CHECK_EQUAL(0x1f07ffff, + CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, 0)); + + RegtestDeactivateBlossom(); } /* Test the constraint on the lower bound for actual time taken */ @@ -47,12 +79,28 @@ BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual) SelectParams(CBaseChainParams::MAIN); const Consensus::Params& params = Params().GetConsensus(); - int64_t nLastRetargetTime = 1279296753; // NOTE: Not an actual block time - int64_t nThisTime = 1279297671; // Block #68543 of Bitcoin + int64_t nLastRetargetTime = 1000000000; // NOTE: Not an actual block time + // 17*150*(1 - PoWMaxAdjustUp*PoWDampingFactor) = 918 + // so we pick 917 to be outside of this window + int64_t nThisTime = 100000917; arith_uint256 bnAvg; bnAvg.SetCompact(0x1c05a3f4); BOOST_CHECK_EQUAL(0x1c04bceb, - CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params)); + CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, 0)); +} + +BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual_blossom) +{ + const Consensus::Params& params = RegtestActivateBlossom(true); + + int64_t nLastRetargetTime = 1000000000; // NOTE: Not an actual block time + int64_t nThisTime = 1000000458; + arith_uint256 bnAvg; + bnAvg.SetCompact(0x1c05a3f4); + BOOST_CHECK_EQUAL(0x1c04bceb, + CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, 0)); + + RegtestDeactivateBlossom(); } /* Test the constraint on the upper bound for actual time taken */ @@ -61,24 +109,35 @@ BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) SelectParams(CBaseChainParams::MAIN); const Consensus::Params& params = Params().GetConsensus(); - int64_t nLastRetargetTime = 1269205629; // NOTE: Not an actual block time - int64_t nThisTime = 1269211443; // Block #46367 of Bitcoin + int64_t nLastRetargetTime = 1000000000; // NOTE: Not an actual block time + // 17*150*(1 + maxAdjustDown*PoWDampingFactor) = 5814 + int64_t nThisTime = 1000005815; arith_uint256 bnAvg; bnAvg.SetCompact(0x1c387f6f); BOOST_CHECK_EQUAL(0x1c4a93bb, - CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params)); + CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, 0)); } -BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) +BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual_blossom) { - SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = RegtestActivateBlossom(true); + int64_t nLastRetargetTime = 1000000000; // NOTE: Not an actual block time + int64_t nThisTime = 1000002908; + arith_uint256 bnAvg; + bnAvg.SetCompact(0x1c387f6f); + BOOST_CHECK_EQUAL(0x1c4a93bb, + CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, 0)); + + RegtestDeactivateBlossom(); +} + +void GetBlockProofEquivalentTimeImpl(const Consensus::Params& params) { std::vector blocks(10000); for (int i = 0; i < 10000; i++) { blocks[i].pprev = i ? &blocks[i - 1] : NULL; blocks[i].nHeight = i; - blocks[i].nTime = 1269211443 + i * params.nPowTargetSpacing; + blocks[i].nTime = i ? blocks[i - 1].nTime + params.PoWTargetSpacing(i) : 1269211443; blocks[i].nBits = 0x207fffff; /* target 0x7fffff000... */ blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0); } @@ -93,4 +152,16 @@ BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) } } +BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) +{ + SelectParams(CBaseChainParams::MAIN); + GetBlockProofEquivalentTimeImpl(Params().GetConsensus()); +} + +BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test_blossom) +{ + GetBlockProofEquivalentTimeImpl(RegtestActivateBlossom(true)); + RegtestDeactivateBlossom(); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index 01a45b540..7e93d4248 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include #include "prevector.h" diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp index 0f40874f5..fd4d92fd0 100644 --- a/src/test/raii_event_tests.cpp +++ b/src/test/raii_event_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp index 8bdff9700..3aeba7af1 100644 --- a/src/test/reverselock_tests.cpp +++ b/src/test/reverselock_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "reverselock.h" #include "test/test_bitcoin.h" diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 7cb1ef010..cef8537e9 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -1,11 +1,12 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "rpc/server.h" #include "rpc/client.h" #include "key_io.h" +#include "main.h" #include "netbase.h" #include "utilstrencodings.h" @@ -55,6 +56,19 @@ UniValue CallRPC(string args) } +void CheckRPCThrows(std::string rpcString, std::string expectedErrorMessage) { + try { + CallRPC(rpcString); + // Note: CallRPC catches (const UniValue& objError) and rethrows a runtime_error + BOOST_FAIL("Should have caused an error"); + } catch (const std::runtime_error& e) { + BOOST_CHECK_EQUAL(expectedErrorMessage, e.what()); + } catch(const std::exception& e) { + BOOST_FAIL(std::string("Unexpected exception: ") + typeid(e).name() + ", message=\"" + e.what() + "\""); + } +} + + BOOST_FIXTURE_TEST_SUITE(rpc_tests, TestingSetup) BOOST_AUTO_TEST_CASE(rpc_rawparams) @@ -220,7 +234,7 @@ BOOST_AUTO_TEST_CASE(json_parse_errors) BOOST_AUTO_TEST_CASE(rpc_ban) { BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); - + UniValue r; BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0 add"))); BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.0:8334")), runtime_error); //portnumber for setban not allowed @@ -346,4 +360,106 @@ BOOST_AUTO_TEST_CASE(rpc_getnetworksolps) BOOST_CHECK_NO_THROW(CallRPC("getnetworksolps 120 -1")); } +// Test parameter processing (not functionality). +// These tests also ensure that src/rpc/client.cpp has the correct entries. +BOOST_AUTO_TEST_CASE(rpc_insightexplorer) +{ + CheckRPCThrows("getaddressmempool \"a\"", + "Error: getaddressmempool is disabled. " + "Run './zcash-cli help getaddressmempool' for instructions on how to enable this feature."); + CheckRPCThrows("getaddressutxos \"a\"", + "Error: getaddressutxos is disabled. " + "Run './zcash-cli help getaddressutxos' for instructions on how to enable this feature."); + CheckRPCThrows("getaddressdeltas \"a\"", + "Error: getaddressdeltas is disabled. " + "Run './zcash-cli help getaddressdeltas' for instructions on how to enable this feature."); + CheckRPCThrows("getaddressbalance \"a\"", + "Error: getaddressbalance is disabled. " + "Run './zcash-cli help getaddressbalance' for instructions on how to enable this feature."); + CheckRPCThrows("getaddresstxids \"a\"", + "Error: getaddresstxids is disabled. " + "Run './zcash-cli help getaddresstxids' for instructions on how to enable this feature."); + CheckRPCThrows("getspentinfo {\"a\":1}", + "Error: getspentinfo is disabled. " + "Run './zcash-cli help getspentinfo' for instructions on how to enable this feature."); + CheckRPCThrows("getblockdeltas \"a\"", + "Error: getblockdeltas is disabled. " + "Run './zcash-cli help getblockdeltas' for instructions on how to enable this feature."); + CheckRPCThrows("getblockhashes 0 0", + "Error: getblockhashes is disabled. " + "Run './zcash-cli help getblockhashes' for instructions on how to enable this feature."); + + // During startup of the real system, fInsightExplorer ("-insightexplorer") + // automatically enables the next three, but not here, must explicitly enable. + fExperimentalMode = true; + fInsightExplorer = true; + fAddressIndex = true; + fSpentIndex = true; + fTimestampIndex = true; + + // must be a legal mainnet address + const string addr = "t1T3G72ToPuCDTiCEytrU1VUBRHsNupEBut"; + BOOST_CHECK_NO_THROW(CallRPC("getaddressmempool \"" + addr + "\"")); + BOOST_CHECK_NO_THROW(CallRPC("getaddressmempool {\"addresses\":[\"" + addr + "\"]}")); + BOOST_CHECK_NO_THROW(CallRPC("getaddressmempool {\"addresses\":[\"" + addr + "\",\"" + addr + "\"]}")); + + BOOST_CHECK_NO_THROW(CallRPC("getaddressutxos {\"addresses\":[],\"chainInfo\":true}")); + CheckRPCThrows("getaddressutxos {}", + "Addresses is expected to be an array"); + CheckRPCThrows("getaddressutxos {\"addressesmisspell\":[]}", + "Addresses is expected to be an array"); + CheckRPCThrows("getaddressutxos {\"addresses\":[],\"chainInfo\":1}", + "JSON value is not a boolean as expected"); + + BOOST_CHECK_NO_THROW(CallRPC("getaddressdeltas {\"addresses\":[]}")); + CheckRPCThrows("getaddressdeltas {\"addresses\":[],\"start\":0,\"end\":0,\"chainInfo\":true}", + "Start and end are expected to be greater than zero"); + CheckRPCThrows("getaddressdeltas {\"addresses\":[],\"start\":3,\"end\":2,\"chainInfo\":true}", + "End value is expected to be greater than start"); + // in this test environment, only the genesis block (0) exists + CheckRPCThrows("getaddressdeltas {\"addresses\":[],\"start\":2,\"end\":3,\"chainInfo\":true}", + "Start or end is outside chain range"); + + BOOST_CHECK_NO_THROW(CallRPC("getaddressbalance {\"addresses\":[]}")); + + BOOST_CHECK_NO_THROW(CallRPC("getaddresstxids {\"addresses\":[]}")); + CheckRPCThrows("getaddresstxids {\"addresses\":[],\"start\":0,\"end\":0,\"chainInfo\":true}", + "Start and end are expected to be greater than zero"); + CheckRPCThrows("getaddresstxids {\"addresses\":[],\"start\":3,\"end\":2,\"chainInfo\":true}", + "End value is expected to be greater than start"); + // in this test environment, only the genesis block (0) exists + CheckRPCThrows("getaddresstxids {\"addresses\":[],\"start\":2,\"end\":3,\"chainInfo\":true}", + "Start or end is outside chain range"); + + // transaction does not exist: + CheckRPCThrows("getspentinfo {\"txid\":\"b4cc287e58f87cdae59417329f710f3ecd75a4ee1d2872b7248f50977c8493f3\",\"index\":0}", + "Unable to get spent info"); + CheckRPCThrows("getspentinfo {\"txid\":\"b4cc287e58f87cdae59417329f710f3ecd75a4ee1d2872b7248f50977c8493f3\"}", + "Invalid index, must be an integer"); + CheckRPCThrows("getspentinfo {\"txid\":\"hello\",\"index\":0}", + "txid must be hexadecimal string (not 'hello')"); + + // only the mainnet genesis block exists + BOOST_CHECK_NO_THROW(CallRPC("getblockdeltas \"00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08\"")); + // damage the block hash (change last digit) + CheckRPCThrows("getblockdeltas \"00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce09\"", + "Block not found"); + + BOOST_CHECK_NO_THROW(CallRPC("getblockhashes 1477641360 1477641360")); + BOOST_CHECK_NO_THROW(CallRPC("getblockhashes 1477641360 1477641360 {\"noOrphans\":true,\"logicalTimes\":true}")); + // Unfortunately, an unknown or mangled key is ignored + BOOST_CHECK_NO_THROW(CallRPC("getblockhashes 1477641360 1477641360 {\"AAAnoOrphans\":true,\"logicalTimes\":true}")); + CheckRPCThrows("getblockhashes 1477641360 1477641360 {\"noOrphans\":true,\"logicalTimes\":1}", + "JSON value is not a boolean as expected"); + CheckRPCThrows("getblockhashes 1477641360 1477641360 {\"noOrphans\":True,\"logicalTimes\":false}", + "Error parsing JSON:{\"noOrphans\":True,\"logicalTimes\":false}"); + + // revert + fExperimentalMode = false; + fInsightExplorer = false; + fAddressIndex = false; + fSpentIndex = false; + fTimestampIndex = false; +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index f04d3f2c2..9e0c0f993 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2013-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "rpc/server.h" #include "rpc/client.h" @@ -15,6 +15,7 @@ #include "asyncrpcqueue.h" #include "asyncrpcoperation.h" +#include "wallet/asyncrpcoperation_common.h" #include "wallet/asyncrpcoperation_mergetoaddress.h" #include "wallet/asyncrpcoperation_sendmany.h" #include "wallet/asyncrpcoperation_shieldcoinbase.h" @@ -1018,6 +1019,17 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters) } } +BOOST_AUTO_TEST_CASE(asyncrpcoperation_sign_send_raw_transaction) { + // Raw joinsplit is a zaddr->zaddr + std::string raw = "020000000000000000000100000000000000001027000000000000183a0d4c46c369078705e39bcfebee59a978dbd210ce8de3efc9555a03fbabfd3cea16693d730c63850d7e48ccde79854c19adcb7e9dcd7b7d18805ee09083f6b16e1860729d2d4a90e2f2acd009cf78b5eb0f4a6ee4bdb64b1262d7ce9eb910c460b02022991e968d0c50ee44908e4ccccbc591d0053bcca154dd6d6fc400a29fa686af4682339832ccea362a62aeb9df0d5aa74f86a1e75ac0f48a8ccc41e0a940643c6c33e1d09223b0a46eaf47a1bb4407cfc12b1dcf83a29c0cef51e45c7876ca5b9e5bae86d92976eb3ef68f29cd29386a8be8451b50f82bf9da10c04651868655194da8f6ed3d241bb5b5ff93a3e2bbe44644544d88bcde5cc35978032ee92699c7a61fcbb395e7583f47e698c4d53ede54f956629400bf510fb5e22d03158cc10bdcaaf29e418ef18eb6480dd9c8b9e2a377809f9f32a556ef872febd0021d4ad013aa9f0b7255e98e408d302abefd33a71180b720271835b487ab309e160b06dfe51932120fb84a7ede16b20c53599a11071592109e10260f265ee60d48c62bfe24074020e9b586ce9e9356e68f2ad1a9538258234afe4b83a209f178f45202270eaeaeecaf2ce3100b2c5a714f75f35777a9ebff5ebf47059d2bbf6f3726190216468f2b152673b766225b093f3a2f827c86d6b48b42117fec1d0ac38dd7af700308dcfb02eba821612b16a2c164c47715b9b0c93900893b1aba2ea03765c94d87022db5be06ab338d1912e0936dfe87586d0a8ee49144a6cd2e306abdcb652faa3e0222739deb23154d778b50de75069a4a2cce1208cd1ced3cb4744c9888ce1c2fcd2e66dc31e62d3aa9e423d7275882525e9981f92e84ac85975b8660739407efbe1e34c2249420fde7e17db3096d5b22e83d051d01f0e6e7690dca7d168db338aadf0897fedac10de310db2b1bff762d322935dddbb60c2efb8b15d231fa17b84630371cb275c209f0c4c7d0c68b150ea5cd514122215e3f7fcfb351d69514788d67c2f3c8922581946e3a04bdf1f07f15696ca76eb95b10698bf1188fd882945c57657515889d042a6fc45d38cbc943540c4f0f6d1c45a1574c81f3e42d1eb8702328b729909adee8a5cfed7c79d54627d1fd389af941d878376f7927b9830ca659bf9ab18c5ca5192d52d02723008728d03701b8ab3e1c4a3109409ec0b13df334c7deec3523eeef4c97b5603e643de3a647b873f4c1b47fbfc6586ba66724f112e51fc93839648005043620aa3ce458e246d77977b19c53d98e3e812de006afc1a79744df236582943631d04cc02941ac4be500e4ed9fb9e3e7cc187b1c4050fad1d9d09d5fd70d5d01d615b439d8c0015d2eb10398bcdbf8c4b2bd559dbe4c288a186aed3f86f608da4d582e120c4a896e015e2241900d1daeccd05db968852677c71d752bec46de9962174b46f980e8cc603654daf8b98a3ee92dac066033954164a89568b70b1780c2ce2410b2f816dbeddb2cd463e0c8f21a52cf6427d9647a6fd4bafa8fb4cd4d47ac057b0160bee86c6b2fb8adce214c2bcdda277512200adf0eaa5d2114a2c077b009836a68ec254bfe56f51d147b9afe2ddd9cb917c0c2de19d81b7b8fd9f4574f51fa1207630dc13976f4d7587c962f761af267de71f3909a576e6bedaf6311633910d291ac292c467cc8331ef577aef7646a5d949322fa0367a49f20597a13def53136ee31610395e3e48d291fd8f58504374031fe9dcfba5e06086ebcf01a9106f6a4d6e16e19e4c5bb893f7da79419c94eca31a384be6fa1747284dee0fc3bbc8b1b860172c10b29c1594bb8c747d7fe05827358ff2160f49050001625ffe2e880bd7fc26cd0ffd89750745379a8e862816e08a5a2008043921ab6a4976064ac18f7ee37b6628bc0127d8d5ebd3548e41d8881a082d86f20b32e33094f15a0e6ea6074b08c6cd28142de94713451640a55985051f5577eb54572699d838cb34a79c8939e981c0c277d06a6e2ce69ccb74f8a691ff08f81d8b99e6a86223d29a2b7c8e7b041aba44ea678ae654277f7e91cbfa79158b989164a3d549d9f4feb0cc43169699c13e321fe3f4b94258c75d198ff9184269cd6986c55409e07528c93f64942c6c283ce3917b4bf4c3be2fe3173c8c38cccb35f1fbda0ca88b35a599c0678cb22aa8eabea8249dbd2e4f849fffe69803d299e435ebcd7df95854003d8eda17a74d98b4be0e62d45d7fe48c06a6f464a14f8e0570077cc631279092802a89823f031eef5e1028a6d6fdbd502869a731ee7d28b4d6c71b419462a30d31442d3ee444ffbcbd16d558c9000c97e949c2b1f9d6f6d8db7b9131ebd963620d3fc8595278d6f8fdf49084325373196d53e64142fa5a23eccd6ef908c4d80b8b3e6cc334b7f7012103a3682e4678e9b518163d262a39a2c1a69bf88514c52b7ccd7cc8dc80e71f7c2ec0701cff982573eb0c2c4daeb47fa0b586f4451c10d1da2e5d182b03dd067a5e971b3a6138ca6667aaf853d2ac03b80a1d5870905f2cfb6c78ec3c3719c02f973d638a0f973424a2b0f2b0023f136d60092fe15fba4bc180b9176bd0ff576e053f1af6939fe9ca256203ffaeb3e569f09774d2a6cbf91873e56651f4d6ff77e0b5374b0a1a201d7e523604e0247644544cc571d48c458a4f96f45580b"; + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("rawtxn", raw)); + // Verify test mode is returning output (since no input taddrs, signed and unsigned are the same). + std::pair txAndResult = SignSendRawTransaction(obj, boost::none, true); + UniValue resultObj = txAndResult.second.get_obj(); + std::string hex = find_value(resultObj, "hex").get_str(); + BOOST_CHECK_EQUAL(hex, raw); +} // TODO: test private methods BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) @@ -1135,15 +1147,16 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) CTransaction tx = proxy.getTx(); BOOST_CHECK(tx.vout.size() == 0); + CReserveKey keyChange(pwalletMain); CAmount amount = AmountFromValue(ValueFromString("123.456")); - proxy.add_taddr_change_output_to_tx(amount); + proxy.add_taddr_change_output_to_tx(keyChange, amount); tx = proxy.getTx(); BOOST_CHECK(tx.vout.size() == 1); CTxOut out = tx.vout[0]; BOOST_CHECK_EQUAL(out.nValue, amount); amount = AmountFromValue(ValueFromString("1.111")); - proxy.add_taddr_change_output_to_tx(amount); + proxy.add_taddr_change_output_to_tx(keyChange, amount); tx = proxy.getTx(); BOOST_CHECK(tx.vout.size() == 2); out = tx.vout[1]; @@ -1170,36 +1183,6 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) BOOST_CHECK_EQUAL(tx.vout[2].nValue, CAmount(7.89)); } - - // Raw joinsplit is a zaddr->zaddr - { - std::string raw = "020000000000000000000100000000000000001027000000000000183a0d4c46c369078705e39bcfebee59a978dbd210ce8de3efc9555a03fbabfd3cea16693d730c63850d7e48ccde79854c19adcb7e9dcd7b7d18805ee09083f6b16e1860729d2d4a90e2f2acd009cf78b5eb0f4a6ee4bdb64b1262d7ce9eb910c460b02022991e968d0c50ee44908e4ccccbc591d0053bcca154dd6d6fc400a29fa686af4682339832ccea362a62aeb9df0d5aa74f86a1e75ac0f48a8ccc41e0a940643c6c33e1d09223b0a46eaf47a1bb4407cfc12b1dcf83a29c0cef51e45c7876ca5b9e5bae86d92976eb3ef68f29cd29386a8be8451b50f82bf9da10c04651868655194da8f6ed3d241bb5b5ff93a3e2bbe44644544d88bcde5cc35978032ee92699c7a61fcbb395e7583f47e698c4d53ede54f956629400bf510fb5e22d03158cc10bdcaaf29e418ef18eb6480dd9c8b9e2a377809f9f32a556ef872febd0021d4ad013aa9f0b7255e98e408d302abefd33a71180b720271835b487ab309e160b06dfe51932120fb84a7ede16b20c53599a11071592109e10260f265ee60d48c62bfe24074020e9b586ce9e9356e68f2ad1a9538258234afe4b83a209f178f45202270eaeaeecaf2ce3100b2c5a714f75f35777a9ebff5ebf47059d2bbf6f3726190216468f2b152673b766225b093f3a2f827c86d6b48b42117fec1d0ac38dd7af700308dcfb02eba821612b16a2c164c47715b9b0c93900893b1aba2ea03765c94d87022db5be06ab338d1912e0936dfe87586d0a8ee49144a6cd2e306abdcb652faa3e0222739deb23154d778b50de75069a4a2cce1208cd1ced3cb4744c9888ce1c2fcd2e66dc31e62d3aa9e423d7275882525e9981f92e84ac85975b8660739407efbe1e34c2249420fde7e17db3096d5b22e83d051d01f0e6e7690dca7d168db338aadf0897fedac10de310db2b1bff762d322935dddbb60c2efb8b15d231fa17b84630371cb275c209f0c4c7d0c68b150ea5cd514122215e3f7fcfb351d69514788d67c2f3c8922581946e3a04bdf1f07f15696ca76eb95b10698bf1188fd882945c57657515889d042a6fc45d38cbc943540c4f0f6d1c45a1574c81f3e42d1eb8702328b729909adee8a5cfed7c79d54627d1fd389af941d878376f7927b9830ca659bf9ab18c5ca5192d52d02723008728d03701b8ab3e1c4a3109409ec0b13df334c7deec3523eeef4c97b5603e643de3a647b873f4c1b47fbfc6586ba66724f112e51fc93839648005043620aa3ce458e246d77977b19c53d98e3e812de006afc1a79744df236582943631d04cc02941ac4be500e4ed9fb9e3e7cc187b1c4050fad1d9d09d5fd70d5d01d615b439d8c0015d2eb10398bcdbf8c4b2bd559dbe4c288a186aed3f86f608da4d582e120c4a896e015e2241900d1daeccd05db968852677c71d752bec46de9962174b46f980e8cc603654daf8b98a3ee92dac066033954164a89568b70b1780c2ce2410b2f816dbeddb2cd463e0c8f21a52cf6427d9647a6fd4bafa8fb4cd4d47ac057b0160bee86c6b2fb8adce214c2bcdda277512200adf0eaa5d2114a2c077b009836a68ec254bfe56f51d147b9afe2ddd9cb917c0c2de19d81b7b8fd9f4574f51fa1207630dc13976f4d7587c962f761af267de71f3909a576e6bedaf6311633910d291ac292c467cc8331ef577aef7646a5d949322fa0367a49f20597a13def53136ee31610395e3e48d291fd8f58504374031fe9dcfba5e06086ebcf01a9106f6a4d6e16e19e4c5bb893f7da79419c94eca31a384be6fa1747284dee0fc3bbc8b1b860172c10b29c1594bb8c747d7fe05827358ff2160f49050001625ffe2e880bd7fc26cd0ffd89750745379a8e862816e08a5a2008043921ab6a4976064ac18f7ee37b6628bc0127d8d5ebd3548e41d8881a082d86f20b32e33094f15a0e6ea6074b08c6cd28142de94713451640a55985051f5577eb54572699d838cb34a79c8939e981c0c277d06a6e2ce69ccb74f8a691ff08f81d8b99e6a86223d29a2b7c8e7b041aba44ea678ae654277f7e91cbfa79158b989164a3d549d9f4feb0cc43169699c13e321fe3f4b94258c75d198ff9184269cd6986c55409e07528c93f64942c6c283ce3917b4bf4c3be2fe3173c8c38cccb35f1fbda0ca88b35a599c0678cb22aa8eabea8249dbd2e4f849fffe69803d299e435ebcd7df95854003d8eda17a74d98b4be0e62d45d7fe48c06a6f464a14f8e0570077cc631279092802a89823f031eef5e1028a6d6fdbd502869a731ee7d28b4d6c71b419462a30d31442d3ee444ffbcbd16d558c9000c97e949c2b1f9d6f6d8db7b9131ebd963620d3fc8595278d6f8fdf49084325373196d53e64142fa5a23eccd6ef908c4d80b8b3e6cc334b7f7012103a3682e4678e9b518163d262a39a2c1a69bf88514c52b7ccd7cc8dc80e71f7c2ec0701cff982573eb0c2c4daeb47fa0b586f4451c10d1da2e5d182b03dd067a5e971b3a6138ca6667aaf853d2ac03b80a1d5870905f2cfb6c78ec3c3719c02f973d638a0f973424a2b0f2b0023f136d60092fe15fba4bc180b9176bd0ff576e053f1af6939fe9ca256203ffaeb3e569f09774d2a6cbf91873e56651f4d6ff77e0b5374b0a1a201d7e523604e0247644544cc571d48c458a4f96f45580b"; - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("rawtxn", raw)); - - // we have the spending key for the dummy recipient zaddr1 - std::vector recipients = { SendManyRecipient(zaddr1, 0.0005, "ABCD") }; - - std::shared_ptr operation( new AsyncRPCOperation_sendmany(boost::none, mtx, zaddr1, {}, recipients, 1) ); - std::shared_ptr ptr = std::dynamic_pointer_cast (operation); - TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); - - // Enable test mode so tx is not sent - static_cast(operation.get())->testmode = true; - - // Pretend that the operation completed successfully - proxy.set_state(OperationStatus::SUCCESS); - - // Verify test mode is returning output (since no input taddrs, signed and unsigned are the same). - BOOST_CHECK_NO_THROW( proxy.sign_send_raw_transaction(obj) ); - UniValue result = operation->getResult(); - BOOST_CHECK(!result.isNull()); - UniValue resultObj = result.get_obj(); - std::string hex = find_value(resultObj, "hex").get_str(); - BOOST_CHECK_EQUAL(hex, raw); - } - - // Test the perform_joinsplit methods. { // Dummy input so the operation object can be instantiated. @@ -1252,7 +1235,6 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) BOOST_CHECK( string(e.what()).find("error verifying joinsplit")!= string::npos); } } - } @@ -1302,7 +1284,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_taddr_to_sapling) pwalletMain->AddToWallet(wtx, true, NULL); // Context that z_sendmany requires - auto builder = TransactionBuilder(consensusParams, nextBlockHeight, expiryDelta, pwalletMain); + auto builder = TransactionBuilder(consensusParams, nextBlockHeight, pwalletMain); mtx = CreateNewContextualCMutableTransaction(consensusParams, nextBlockHeight); std::vector recipients = { SendManyRecipient(zaddr1, 1 * COIN, "ABCD") }; @@ -1617,7 +1599,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_shieldcoinbase_internals) if (mtx.nVersion == 1) { mtx.nVersion = 2; } - + // Test that option -mempooltxinputlimit is respected. mapArgs["-mempooltxinputlimit"] = "1"; @@ -1674,19 +1656,6 @@ BOOST_AUTO_TEST_CASE(rpc_z_shieldcoinbase_internals) } - -void CheckRPCThrows(std::string rpcString, std::string expectedErrorMessage) { - try { - CallRPC(rpcString); - // Note: CallRPC catches (const UniValue& objError) and rethrows a runtime_error - BOOST_FAIL("Should have caused an error"); - } catch (const std::runtime_error& e) { - BOOST_CHECK_EQUAL(expectedErrorMessage, e.what()); - } catch(const std::exception& e) { - BOOST_FAIL(std::string("Unexpected exception: ") + typeid(e).name() + ", message=\"" + e.what() + "\""); - } -} - BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_parameters) { SelectParams(CBaseChainParams::TESTNET); @@ -1769,7 +1738,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_parameters) std::vector v (2 * (ZC_MEMO_SIZE+1)); // x2 for hexadecimal string format std::fill(v.begin(),v.end(), 'A'); std::string badmemo(v.begin(), v.end()); - CheckRPCThrows("z_mergetoaddress [\"" + taddr1 + "\"] " + aSproutAddr + " 0.0001 100 100 " + badmemo, + CheckRPCThrows("z_mergetoaddress [\"" + taddr1 + "\"] " + aSproutAddr + " 0.0001 100 100 " + badmemo, "Invalid parameter, size of memo is larger than maximum allowed 512"); // Mutable tx containing contextual information we need to build tx @@ -1809,9 +1778,9 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_parameters) BOOST_CHECK( find_error(objError, "Recipient parameter missing")); } - std::vector sproutNoteInputs = + std::vector sproutNoteInputs = {MergeToAddressInputSproutNote{JSOutPoint(), SproutNote(), 0, SproutSpendingKey()}}; - std::vector saplingNoteInputs = + std::vector saplingNoteInputs = {MergeToAddressInputSaplingNote{SaplingOutPoint(), SaplingNote(), 0, SaplingExpandedSpendingKey()}}; // Sprout and Sapling inputs -> throw @@ -1997,33 +1966,6 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_internals) BOOST_CHECK( string(e.what()).find("error verifying joinsplit")!= string::npos); } } - - // Raw joinsplit is a zaddr->zaddr - { - std::string raw = "020000000000000000000100000000000000001027000000000000183a0d4c46c369078705e39bcfebee59a978dbd210ce8de3efc9555a03fbabfd3cea16693d730c63850d7e48ccde79854c19adcb7e9dcd7b7d18805ee09083f6b16e1860729d2d4a90e2f2acd009cf78b5eb0f4a6ee4bdb64b1262d7ce9eb910c460b02022991e968d0c50ee44908e4ccccbc591d0053bcca154dd6d6fc400a29fa686af4682339832ccea362a62aeb9df0d5aa74f86a1e75ac0f48a8ccc41e0a940643c6c33e1d09223b0a46eaf47a1bb4407cfc12b1dcf83a29c0cef51e45c7876ca5b9e5bae86d92976eb3ef68f29cd29386a8be8451b50f82bf9da10c04651868655194da8f6ed3d241bb5b5ff93a3e2bbe44644544d88bcde5cc35978032ee92699c7a61fcbb395e7583f47e698c4d53ede54f956629400bf510fb5e22d03158cc10bdcaaf29e418ef18eb6480dd9c8b9e2a377809f9f32a556ef872febd0021d4ad013aa9f0b7255e98e408d302abefd33a71180b720271835b487ab309e160b06dfe51932120fb84a7ede16b20c53599a11071592109e10260f265ee60d48c62bfe24074020e9b586ce9e9356e68f2ad1a9538258234afe4b83a209f178f45202270eaeaeecaf2ce3100b2c5a714f75f35777a9ebff5ebf47059d2bbf6f3726190216468f2b152673b766225b093f3a2f827c86d6b48b42117fec1d0ac38dd7af700308dcfb02eba821612b16a2c164c47715b9b0c93900893b1aba2ea03765c94d87022db5be06ab338d1912e0936dfe87586d0a8ee49144a6cd2e306abdcb652faa3e0222739deb23154d778b50de75069a4a2cce1208cd1ced3cb4744c9888ce1c2fcd2e66dc31e62d3aa9e423d7275882525e9981f92e84ac85975b8660739407efbe1e34c2249420fde7e17db3096d5b22e83d051d01f0e6e7690dca7d168db338aadf0897fedac10de310db2b1bff762d322935dddbb60c2efb8b15d231fa17b84630371cb275c209f0c4c7d0c68b150ea5cd514122215e3f7fcfb351d69514788d67c2f3c8922581946e3a04bdf1f07f15696ca76eb95b10698bf1188fd882945c57657515889d042a6fc45d38cbc943540c4f0f6d1c45a1574c81f3e42d1eb8702328b729909adee8a5cfed7c79d54627d1fd389af941d878376f7927b9830ca659bf9ab18c5ca5192d52d02723008728d03701b8ab3e1c4a3109409ec0b13df334c7deec3523eeef4c97b5603e643de3a647b873f4c1b47fbfc6586ba66724f112e51fc93839648005043620aa3ce458e246d77977b19c53d98e3e812de006afc1a79744df236582943631d04cc02941ac4be500e4ed9fb9e3e7cc187b1c4050fad1d9d09d5fd70d5d01d615b439d8c0015d2eb10398bcdbf8c4b2bd559dbe4c288a186aed3f86f608da4d582e120c4a896e015e2241900d1daeccd05db968852677c71d752bec46de9962174b46f980e8cc603654daf8b98a3ee92dac066033954164a89568b70b1780c2ce2410b2f816dbeddb2cd463e0c8f21a52cf6427d9647a6fd4bafa8fb4cd4d47ac057b0160bee86c6b2fb8adce214c2bcdda277512200adf0eaa5d2114a2c077b009836a68ec254bfe56f51d147b9afe2ddd9cb917c0c2de19d81b7b8fd9f4574f51fa1207630dc13976f4d7587c962f761af267de71f3909a576e6bedaf6311633910d291ac292c467cc8331ef577aef7646a5d949322fa0367a49f20597a13def53136ee31610395e3e48d291fd8f58504374031fe9dcfba5e06086ebcf01a9106f6a4d6e16e19e4c5bb893f7da79419c94eca31a384be6fa1747284dee0fc3bbc8b1b860172c10b29c1594bb8c747d7fe05827358ff2160f49050001625ffe2e880bd7fc26cd0ffd89750745379a8e862816e08a5a2008043921ab6a4976064ac18f7ee37b6628bc0127d8d5ebd3548e41d8881a082d86f20b32e33094f15a0e6ea6074b08c6cd28142de94713451640a55985051f5577eb54572699d838cb34a79c8939e981c0c277d06a6e2ce69ccb74f8a691ff08f81d8b99e6a86223d29a2b7c8e7b041aba44ea678ae654277f7e91cbfa79158b989164a3d549d9f4feb0cc43169699c13e321fe3f4b94258c75d198ff9184269cd6986c55409e07528c93f64942c6c283ce3917b4bf4c3be2fe3173c8c38cccb35f1fbda0ca88b35a599c0678cb22aa8eabea8249dbd2e4f849fffe69803d299e435ebcd7df95854003d8eda17a74d98b4be0e62d45d7fe48c06a6f464a14f8e0570077cc631279092802a89823f031eef5e1028a6d6fdbd502869a731ee7d28b4d6c71b419462a30d31442d3ee444ffbcbd16d558c9000c97e949c2b1f9d6f6d8db7b9131ebd963620d3fc8595278d6f8fdf49084325373196d53e64142fa5a23eccd6ef908c4d80b8b3e6cc334b7f7012103a3682e4678e9b518163d262a39a2c1a69bf88514c52b7ccd7cc8dc80e71f7c2ec0701cff982573eb0c2c4daeb47fa0b586f4451c10d1da2e5d182b03dd067a5e971b3a6138ca6667aaf853d2ac03b80a1d5870905f2cfb6c78ec3c3719c02f973d638a0f973424a2b0f2b0023f136d60092fe15fba4bc180b9176bd0ff576e053f1af6939fe9ca256203ffaeb3e569f09774d2a6cbf91873e56651f4d6ff77e0b5374b0a1a201d7e523604e0247644544cc571d48c458a4f96f45580b"; - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("rawtxn", raw)); - - // we have the spending key for the dummy recipient zaddr1 - std::vector inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},100000, CScript()} }; - std::shared_ptr operation( new AsyncRPCOperation_mergetoaddress(boost::none, mtx, inputs, {}, {}, zaddr1) ); - std::shared_ptr ptr = std::dynamic_pointer_cast (operation); - TEST_FRIEND_AsyncRPCOperation_mergetoaddress proxy(ptr); - - // Enable test mode so tx is not sent - static_cast(operation.get())->testmode = true; - - // Pretend that the operation completed successfully - proxy.set_state(OperationStatus::SUCCESS); - - // Verify test mode is returning output (since no input taddrs, signed and unsigned are the same). - BOOST_CHECK_NO_THROW( proxy.sign_send_raw_transaction(obj) ); - UniValue result = operation->getResult(); - BOOST_CHECK(!result.isNull()); - UniValue resultObj = result.get_obj(); - std::string hex = find_value(resultObj, "hex").get_str(); - BOOST_CHECK_EQUAL(hex, raw); - } } diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp index f5f7f381d..c29b173fa 100644 --- a/src/test/sanity_tests.cpp +++ b/src/test/sanity_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "compat/sanity.h" #include "key.h" diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp index d6c93ef3b..3bc0be7ae 100644 --- a/src/test/scheduler_tests.cpp +++ b/src/test/scheduler_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "random.h" #include "scheduler.h" diff --git a/src/test/script_P2PKH_tests.cpp b/src/test/script_P2PKH_tests.cpp index 3a7dc1660..99d826345 100644 --- a/src/test/script_P2PKH_tests.cpp +++ b/src/test/script_P2PKH_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "script/script.h" #include "test/test_bitcoin.h" diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index fac63dbf5..a01e3e8e4 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "consensus/upgrades.h" #include "core_io.h" @@ -95,7 +95,7 @@ BOOST_DATA_TEST_CASE(sign, boost::unit_test::data::xrange(static_cast(Conse txFrom.vout[i+4].scriptPubKey = standardScripts[i]; txFrom.vout[i+4].nValue = COIN; } - BOOST_CHECK(IsStandardTx(txFrom, reason)); + BOOST_CHECK(IsStandardTx(txFrom, reason, Params())); CMutableTransaction txTo[8]; // Spending transactions for (int i = 0; i < 8; i++) @@ -198,7 +198,7 @@ BOOST_DATA_TEST_CASE(set, boost::unit_test::data::xrange(static_cast(Consen txFrom.vout[i].scriptPubKey = outer[i]; txFrom.vout[i].nValue = CENT; } - BOOST_CHECK(IsStandardTx(txFrom, reason)); + BOOST_CHECK(IsStandardTx(txFrom, reason, Params())); CMutableTransaction txTo[4]; // Spending transactions for (int i = 0; i < 4; i++) @@ -216,7 +216,7 @@ BOOST_DATA_TEST_CASE(set, boost::unit_test::data::xrange(static_cast(Consen for (int i = 0; i < 4; i++) { BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL, consensusBranchId), strprintf("SignSignature %d", i)); - BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason), strprintf("txTo[%d].IsStandard", i)); + BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason, Params()), strprintf("txTo[%d].IsStandard", i)); } } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 4e8388358..2b2ec3fbf 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "data/script_invalid.json.h" #include "data/script_valid.json.h" diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index d95724dbe..784ff7399 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "bignum.h" #include "script/script.h" diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index eaf69f175..bed934000 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "serialize.h" #include "streams.h" diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index f7ecfe5c8..d56c3a80f 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "consensus/upgrades.h" #include "consensus/validation.h" @@ -124,7 +124,7 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle, uint32_t co tx.vout.clear(); tx.vShieldedSpend.clear(); tx.vShieldedOutput.clear(); - tx.vjoinsplit.clear(); + tx.vJoinSplit.clear(); tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0; int ins = (insecure_rand() % 4) + 1; int outs = fSingle ? ins : (insecure_rand() % 4) + 1; @@ -193,7 +193,7 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle, uint32_t co jsdesc.macs[0] = GetRandHash(); jsdesc.macs[1] = GetRandHash(); - tx.vjoinsplit.push_back(jsdesc); + tx.vJoinSplit.push_back(jsdesc); } unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index ea2b9b795..3fd68f28d 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "pubkey.h" #include "key.h" diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index 86a4bc672..023a7cebb 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "main.h" #include "random.h" diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 3548b9d4b..03f98870c 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #define BOOST_TEST_MODULE Bitcoin Test Suite @@ -87,6 +87,7 @@ BasicTestingSetup::~BasicTestingSetup() TestingSetup::TestingSetup() { + const CChainParams& chainparams = Params(); // Ideally we'd move all the RPC tests to the functional testing framework // instead of unit tests, but for now we need these here. RegisterAllCoreRPCCommands(tableRPC); @@ -105,7 +106,7 @@ TestingSetup::TestingSetup() pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); - InitBlockIndex(); + InitBlockIndex(chainparams); #ifdef ENABLE_WALLET bool fFirstRun; pwalletMain = new CWallet("wallet.dat"); diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index ff1ad48e2..d1f9b2e54 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -68,4 +68,7 @@ struct TestMemPoolEntryHelper TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; } TestMemPoolEntryHelper &BranchId(uint32_t _branchId) { nBranchId = _branchId; return *this; } }; + +void CheckRPCThrows(std::string rpcString, std::string expectedErrorMessage); + #endif diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp index 887cfb476..b3420afea 100644 --- a/src/test/timedata_tests.cpp +++ b/src/test/timedata_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . // #include "timedata.h" #include "test/test_bitcoin.h" diff --git a/src/test/torcontrol_tests.cpp b/src/test/torcontrol_tests.cpp index b7affaacd..0e9ff78de 100644 --- a/src/test/torcontrol_tests.cpp +++ b/src/test/torcontrol_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . // #include "test/test_bitcoin.h" #include "torcontrol.cpp" diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 88f390c17..3d888b323 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "data/tx_invalid.json.h" #include "data/tx_valid.json.h" @@ -484,14 +484,14 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa BOOST_CHECK(!CheckTransactionWithoutProofVerification(newTx, state)); BOOST_CHECK(state.GetRejectReason() == "bad-txns-vout-empty"); - newTx.vjoinsplit.push_back(JSDescription()); - JSDescription *jsdesc = &newTx.vjoinsplit[0]; + newTx.vJoinSplit.push_back(JSDescription()); + JSDescription *jsdesc = &newTx.vJoinSplit[0]; jsdesc->nullifiers[0] = GetRandHash(); jsdesc->nullifiers[1] = GetRandHash(); BOOST_CHECK(CheckTransactionWithoutProofVerification(newTx, state)); - BOOST_CHECK(!ContextualCheckTransaction(newTx, state, 0, 100)); + BOOST_CHECK(!ContextualCheckTransaction(newTx, state, Params(), 0, 100)); BOOST_CHECK(state.GetRejectReason() == "bad-txns-invalid-joinsplit-signature"); // Empty output script. @@ -505,16 +505,16 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa ) == 0); BOOST_CHECK(CheckTransactionWithoutProofVerification(newTx, state)); - BOOST_CHECK(ContextualCheckTransaction(newTx, state, 0, 100)); + BOOST_CHECK(ContextualCheckTransaction(newTx, state, Params(), 0, 100)); } { // Ensure that values within the joinsplit are well-formed. CMutableTransaction newTx(tx); CValidationState state; - newTx.vjoinsplit.push_back(JSDescription()); - - JSDescription *jsdesc = &newTx.vjoinsplit[0]; + newTx.vJoinSplit.push_back(JSDescription()); + + JSDescription *jsdesc = &newTx.vJoinSplit[0]; jsdesc->vpub_old = -1; BOOST_CHECK(!CheckTransaction(newTx, state, verifier)); @@ -538,9 +538,9 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa jsdesc->vpub_new = (MAX_MONEY / 2) + 10; - newTx.vjoinsplit.push_back(JSDescription()); + newTx.vJoinSplit.push_back(JSDescription()); - JSDescription *jsdesc2 = &newTx.vjoinsplit[1]; + JSDescription *jsdesc2 = &newTx.vJoinSplit[1]; jsdesc2->vpub_new = (MAX_MONEY / 2) + 10; BOOST_CHECK(!CheckTransaction(newTx, state, verifier)); @@ -551,8 +551,8 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa CMutableTransaction newTx(tx); CValidationState state; - newTx.vjoinsplit.push_back(JSDescription()); - JSDescription *jsdesc = &newTx.vjoinsplit[0]; + newTx.vJoinSplit.push_back(JSDescription()); + JSDescription *jsdesc = &newTx.vJoinSplit[0]; jsdesc->nullifiers[0] = GetRandHash(); jsdesc->nullifiers[1] = jsdesc->nullifiers[0]; @@ -562,9 +562,9 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa jsdesc->nullifiers[1] = GetRandHash(); - newTx.vjoinsplit.push_back(JSDescription()); - jsdesc = &newTx.vjoinsplit[0]; // Fixes #2026. Related PR #2078. - JSDescription *jsdesc2 = &newTx.vjoinsplit[1]; + newTx.vJoinSplit.push_back(JSDescription()); + jsdesc = &newTx.vJoinSplit[0]; // Fixes #2026. Related PR #2078. + JSDescription *jsdesc2 = &newTx.vJoinSplit[1]; jsdesc2->nullifiers[0] = GetRandHash(); jsdesc2->nullifiers[1] = jsdesc->nullifiers[0]; @@ -577,8 +577,8 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa CMutableTransaction newTx(tx); CValidationState state; - newTx.vjoinsplit.push_back(JSDescription()); - JSDescription *jsdesc = &newTx.vjoinsplit[0]; + newTx.vJoinSplit.push_back(JSDescription()); + JSDescription *jsdesc = &newTx.vJoinSplit[0]; jsdesc->nullifiers[0] = GetRandHash(); jsdesc->nullifiers[1] = GetRandHash(); @@ -748,6 +748,7 @@ BOOST_AUTO_TEST_CASE(test_big_overwinter_transaction) { BOOST_AUTO_TEST_CASE(test_IsStandard) { LOCK(cs_main); + auto chainparams = Params(); CBasicKeyStore keystore; CCoinsView coinsDummy; CCoinsViewCache coins(&coinsDummy); @@ -765,48 +766,49 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) t.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); string reason; - BOOST_CHECK(IsStandardTx(t, reason)); + BOOST_CHECK(IsStandardTx(t, reason, chainparams)); t.vout[0].nValue = 53; // dust - BOOST_CHECK(!IsStandardTx(t, reason)); + BOOST_CHECK(!IsStandardTx(t, reason, chainparams)); t.vout[0].nValue = 2730; // not dust - BOOST_CHECK(IsStandardTx(t, reason)); + BOOST_CHECK(IsStandardTx(t, reason, chainparams)); t.vout[0].scriptPubKey = CScript() << OP_1; - BOOST_CHECK(!IsStandardTx(t, reason)); + BOOST_CHECK(!IsStandardTx(t, reason, chainparams)); // 80-byte TX_NULL_DATA (standard) t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); - BOOST_CHECK(IsStandardTx(t, reason)); + BOOST_CHECK(IsStandardTx(t, reason, chainparams)); // 81-byte TX_NULL_DATA (non-standard) t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800"); - BOOST_CHECK(!IsStandardTx(t, reason)); + BOOST_CHECK(!IsStandardTx(t, reason, chainparams)); // TX_NULL_DATA w/o PUSHDATA t.vout.resize(1); t.vout[0].scriptPubKey = CScript() << OP_RETURN; - BOOST_CHECK(IsStandardTx(t, reason)); + BOOST_CHECK(IsStandardTx(t, reason, chainparams)); // Only one TX_NULL_DATA permitted in all cases t.vout.resize(2); t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); t.vout[1].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); - BOOST_CHECK(!IsStandardTx(t, reason)); + BOOST_CHECK(!IsStandardTx(t, reason, chainparams)); t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); t.vout[1].scriptPubKey = CScript() << OP_RETURN; - BOOST_CHECK(!IsStandardTx(t, reason)); + BOOST_CHECK(!IsStandardTx(t, reason, chainparams)); t.vout[0].scriptPubKey = CScript() << OP_RETURN; t.vout[1].scriptPubKey = CScript() << OP_RETURN; - BOOST_CHECK(!IsStandardTx(t, reason)); + BOOST_CHECK(!IsStandardTx(t, reason, chainparams)); } BOOST_AUTO_TEST_CASE(test_IsStandardV2) { LOCK(cs_main); + auto chainparams = Params(); CBasicKeyStore keystore; CCoinsView coinsDummy; CCoinsViewCache coins(&coinsDummy); @@ -826,33 +828,33 @@ BOOST_AUTO_TEST_CASE(test_IsStandardV2) string reason; // A v2 transaction with no JoinSplits is still standard. t.nVersion = 2; - BOOST_CHECK(IsStandardTx(t, reason)); + BOOST_CHECK(IsStandardTx(t, reason, chainparams)); // ... and with one JoinSplit. - t.vjoinsplit.push_back(JSDescription()); - BOOST_CHECK(IsStandardTx(t, reason)); + t.vJoinSplit.push_back(JSDescription()); + BOOST_CHECK(IsStandardTx(t, reason, chainparams)); // ... and when that JoinSplit takes from a transparent input. - JSDescription *jsdesc = &t.vjoinsplit[0]; + JSDescription *jsdesc = &t.vJoinSplit[0]; jsdesc->vpub_old = 10*CENT; t.vout[0].nValue -= 10*CENT; - BOOST_CHECK(IsStandardTx(t, reason)); + BOOST_CHECK(IsStandardTx(t, reason, chainparams)); // A v2 transaction with JoinSplits but no transparent inputs is standard. jsdesc->vpub_old = 0; jsdesc->vpub_new = 100*CENT; t.vout[0].nValue = 90*CENT; t.vin.resize(0); - BOOST_CHECK(IsStandardTx(t, reason)); + BOOST_CHECK(IsStandardTx(t, reason, chainparams)); // v2 transactions can still be non-standard for the same reasons as v1. t.vout[0].nValue = 53; // dust - BOOST_CHECK(!IsStandardTx(t, reason)); + BOOST_CHECK(!IsStandardTx(t, reason, chainparams)); // v3 is not standard. t.nVersion = 3; t.vout[0].nValue = 90*CENT; - BOOST_CHECK(!IsStandardTx(t, reason)); + BOOST_CHECK(!IsStandardTx(t, reason, chainparams)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index a6501faa1..7034ccfeb 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "arith_uint256.h" #include "uint256.h" #include "version.h" diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index f3bbfaef1..51db25e8b 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -1,6 +1,6 @@ // Copyright 2014 BitPay, Inc. // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include #include diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 0fcdd6530..24a096b1e 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "util.h" diff --git a/src/threadsafety.h b/src/threadsafety.h index d01c50abb..42e2168ad 100644 --- a/src/threadsafety.h +++ b/src/threadsafety.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_THREADSAFETY_H #define BITCOIN_THREADSAFETY_H diff --git a/src/timedata.cpp b/src/timedata.cpp index 202bad25c..c6c8f45c1 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "timedata.h" diff --git a/src/timedata.h b/src/timedata.h index 2296baf11..69a1eb0f6 100644 --- a/src/timedata.h +++ b/src/timedata.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_TIMEDATA_H #define BITCOIN_TIMEDATA_H diff --git a/src/timestampindex.h b/src/timestampindex.h index 3e402872c..fe72669d7 100644 --- a/src/timestampindex.h +++ b/src/timestampindex.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_TIMESTAMPINDEX_H #define BITCOIN_TIMESTAMPINDEX_H diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 99c76995b..4618042a5 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2015-2017 The Bitcoin Core developers // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "torcontrol.h" #include "utilstrencodings.h" diff --git a/src/torcontrol.h b/src/torcontrol.h index 72dc82c5b..c3edaee05 100644 --- a/src/torcontrol.h +++ b/src/torcontrol.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . /** * Functionality for communicating with Tor. diff --git a/src/transaction_builder.cpp b/src/transaction_builder.cpp index 687c1a420..ca3b9bf66 100644 --- a/src/transaction_builder.cpp +++ b/src/transaction_builder.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "transaction_builder.h" @@ -50,7 +50,6 @@ std::string TransactionBuilderResult::GetError() { TransactionBuilder::TransactionBuilder( const Consensus::Params& consensusParams, int nHeight, - int nExpiryDelta, CKeyStore* keystore, ZCJoinSplit* sproutParams, CCoinsViewCache* coinsView, @@ -62,7 +61,7 @@ TransactionBuilder::TransactionBuilder( coinsView(coinsView), cs_coinsView(cs_coinsView) { - mtx = CreateNewContextualCMutableTransaction(consensusParams, nHeight, nExpiryDelta); + mtx = CreateNewContextualCMutableTransaction(consensusParams, nHeight); } // This exception is thrown in certain scenarios when building JoinSplits fails. @@ -76,6 +75,14 @@ struct JSDescException : public std::exception std::string msg; }; +void TransactionBuilder::SetExpiryHeight(uint32_t nExpiryHeight) +{ + if (nExpiryHeight < nHeight || nExpiryHeight <= 0 || nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) { + throw new std::runtime_error("TransactionBuilder::SetExpiryHeight: invalid expiry height"); + } + mtx.nExpiryHeight = nExpiryHeight; +} + void TransactionBuilder::AddSaplingSpend( libzcash::SaplingExpandedSpendingKey expsk, libzcash::SaplingNote note, @@ -508,12 +515,12 @@ void TransactionBuilder::CreateJSDescriptions() JSDescription prevJoinSplit; // Keep track of previous JoinSplit and its commitments - if (mtx.vjoinsplit.size() > 0) { - prevJoinSplit = mtx.vjoinsplit.back(); + if (mtx.vJoinSplit.size() > 0) { + prevJoinSplit = mtx.vJoinSplit.back(); } // If there is no change, the chain has terminated so we can reset the tracked treestate. - if (jsChange == 0 && mtx.vjoinsplit.size() > 0) { + if (jsChange == 0 && mtx.vJoinSplit.size() > 0) { intermediates.clear(); previousCommitments.clear(); } @@ -679,7 +686,7 @@ void TransactionBuilder::CreateJSDescription( std::array& outputMap) { LogPrint("zrpcunsafe", "CreateJSDescription: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", - mtx.vjoinsplit.size(), + mtx.vJoinSplit.size(), FormatMoney(vpub_old), FormatMoney(vpub_new), FormatMoney(vjsin[0].note.value()), FormatMoney(vjsin[1].note.value()), FormatMoney(vjsout[0].value), FormatMoney(vjsout[1].value)); @@ -708,7 +715,7 @@ void TransactionBuilder::CreateJSDescription( } } - mtx.vjoinsplit.push_back(jsdesc); + mtx.vJoinSplit.push_back(jsdesc); // TODO: Sprout payment disclosure } diff --git a/src/transaction_builder.h b/src/transaction_builder.h index 46f38481e..8db064c7f 100644 --- a/src/transaction_builder.h +++ b/src/transaction_builder.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef TRANSACTION_BUILDER_H #define TRANSACTION_BUILDER_H @@ -95,12 +95,13 @@ class TransactionBuilder TransactionBuilder( const Consensus::Params& consensusParams, int nHeight, - int nExpiryDelta, CKeyStore* keyStore = nullptr, ZCJoinSplit* sproutParams = nullptr, CCoinsViewCache* coinsView = nullptr, CCriticalSection* cs_coinsView = nullptr); + void SetExpiryHeight(uint32_t nExpiryHeight); + void SetFee(CAmount fee); // Throws if the anchor does not match the anchor used by diff --git a/src/txdb.cpp b/src/txdb.cpp index 5815685ad..b5bb4267e 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "txdb.h" @@ -45,7 +45,7 @@ static const char DB_BLOCKHASHINDEX = 'h'; CCoinsViewDB::CCoinsViewDB(std::string dbName, size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / dbName, nCacheSize, fMemory, fWipe) { } -CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) +CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) { } @@ -107,7 +107,7 @@ uint256 CCoinsViewDB::GetBestBlock() const { uint256 CCoinsViewDB::GetBestAnchor(ShieldedType type) const { uint256 hashBestAnchor; - + switch (type) { case SPROUT: if (!db.Read(DB_BEST_SPROUT_ANCHOR, hashBestAnchor)) @@ -326,7 +326,7 @@ bool CBlockTreeDB::ReadAddressUnspentIndex(uint160 addressHash, int type, std::v if (!(pcursor->GetKey(key) && key.first == DB_ADDRESSUNSPENTINDEX && key.second.hashBytes == addressHash)) break; CAddressUnspentValue nValue; - if (pcursor->GetValue(nValue)) + if (!pcursor->GetValue(nValue)) return error("failed to get address unspent value"); unspentOutputs.push_back(make_pair(key.second, nValue)); pcursor->Next(); @@ -399,7 +399,7 @@ bool CBlockTreeDB::WriteTimestampIndex(const CTimestampIndexKey ×tampIndex) return WriteBatch(batch); } -bool CBlockTreeDB::ReadTimestampIndex(const unsigned int &high, const unsigned int &low, +bool CBlockTreeDB::ReadTimestampIndex(unsigned int high, unsigned int low, const bool fActiveOnly, std::vector > &hashes) { boost::scoped_ptr pcursor(NewIterator()); @@ -456,7 +456,7 @@ bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) { return true; } -bool CBlockTreeDB::LoadBlockIndexGuts() +bool CBlockTreeDB::LoadBlockIndexGuts(boost::function insertBlockIndex) { boost::scoped_ptr pcursor(NewIterator()); @@ -470,8 +470,8 @@ bool CBlockTreeDB::LoadBlockIndexGuts() CDiskBlockIndex diskindex; if (pcursor->GetValue(diskindex)) { // Construct block index object - CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); - pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); + CBlockIndex* pindexNew = insertBlockIndex(diskindex.GetBlockHash()); + pindexNew->pprev = insertBlockIndex(diskindex.hashPrev); pindexNew->nHeight = diskindex.nHeight; pindexNew->nFile = diskindex.nFile; pindexNew->nDataPos = diskindex.nDataPos; diff --git a/src/txdb.h b/src/txdb.h index c00b2d68a..eebbc0492 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -1,22 +1,23 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_TXDB_H #define BITCOIN_TXDB_H #include "coins.h" #include "dbwrapper.h" +#include "chain.h" #include #include #include #include -class CBlockFileInfo; +#include + class CBlockIndex; -struct CDiskTxPos; // START insightexplorer struct CAddressUnspentKey; @@ -45,6 +46,31 @@ static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024; //! min. -dbcache in (MiB) static const int64_t nMinDbCache = 4; +struct CDiskTxPos : public CDiskBlockPos +{ + unsigned int nTxOffset; // after header + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(*(CDiskBlockPos*)this); + READWRITE(VARINT(nTxOffset)); + } + + CDiskTxPos(const CDiskBlockPos &blockIn, unsigned int nTxOffsetIn) : CDiskBlockPos(blockIn.nFile, blockIn.nPos), nTxOffset(nTxOffsetIn) { + } + + CDiskTxPos() { + SetNull(); + } + + void SetNull() { + CDiskBlockPos::SetNull(); + nTxOffset = 0; + } +}; + /** CCoinsView backed by the coin database (chainstate/) */ class CCoinsViewDB : public CCoinsView { @@ -99,7 +125,7 @@ class CBlockTreeDB : public CDBWrapper bool ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); bool UpdateSpentIndex(const std::vector &vect); bool WriteTimestampIndex(const CTimestampIndexKey ×tampIndex); - bool ReadTimestampIndex(const unsigned int &high, const unsigned int &low, + bool ReadTimestampIndex(unsigned int high, unsigned int low, const bool fActiveOnly, std::vector > &vect); bool WriteTimestampBlockIndex(const CTimestampBlockIndexKey &blockhashIndex, const CTimestampBlockIndexValue &logicalts); @@ -108,7 +134,7 @@ class CBlockTreeDB : public CDBWrapper bool WriteFlag(const std::string &name, bool fValue); bool ReadFlag(const std::string &name, bool &fValue); - bool LoadBlockIndexGuts(); + bool LoadBlockIndexGuts(boost::function insertBlockIndex); }; #endif // BITCOIN_TXDB_H diff --git a/src/txmempool.cpp b/src/txmempool.cpp index cf04ad577..325109fe4 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "txmempool.h" @@ -14,6 +14,7 @@ #include "timedata.h" #include "util.h" #include "utilmoneystr.h" +#include "validationinterface.h" #include "version.h" using namespace std; @@ -103,9 +104,11 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, LOCK(cs); mapTx.insert(entry); const CTransaction& tx = mapTx.find(hash)->GetTx(); + mapRecentlyAddedTx[tx.GetHash()] = &tx; + nRecentlyAddedSequence += 1; for (unsigned int i = 0; i < tx.vin.size(); i++) mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { + BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) { BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) { mapSproutNullifiers[nf] = &tx; } @@ -121,6 +124,112 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, return true; } +void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view) +{ + LOCK(cs); + const CTransaction& tx = entry.GetTx(); + std::vector inserted; + + uint256 txhash = tx.GetHash(); + for (unsigned int j = 0; j < tx.vin.size(); j++) { + const CTxIn input = tx.vin[j]; + const CTxOut &prevout = view.GetOutputFor(input); + CScript::ScriptType type = prevout.scriptPubKey.GetType(); + if (type == CScript::UNKNOWN) + continue; + CMempoolAddressDeltaKey key(type, prevout.scriptPubKey.AddressHash(), txhash, j, 1); + CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n); + mapAddress.insert(make_pair(key, delta)); + inserted.push_back(key); + } + + for (unsigned int j = 0; j < tx.vout.size(); j++) { + const CTxOut &out = tx.vout[j]; + CScript::ScriptType type = out.scriptPubKey.GetType(); + if (type == CScript::UNKNOWN) + continue; + CMempoolAddressDeltaKey key(type, out.scriptPubKey.AddressHash(), txhash, j, 0); + mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); + inserted.push_back(key); + } + + mapAddressInserted.insert(make_pair(txhash, inserted)); +} + +// START insightexplorer +void CTxMemPool::getAddressIndex( + const std::vector>& addresses, + std::vector>& results) +{ + LOCK(cs); + for (const auto& it : addresses) { + auto ait = mapAddress.lower_bound(CMempoolAddressDeltaKey(it.second, it.first)); + while (ait != mapAddress.end() && (*ait).first.addressBytes == it.first && (*ait).first.type == it.second) { + results.push_back(*ait); + ait++; + } + } +} + +void CTxMemPool::removeAddressIndex(const uint256& txhash) +{ + LOCK(cs); + auto it = mapAddressInserted.find(txhash); + + if (it != mapAddressInserted.end()) { + std::vector keys = it->second; + for (const auto& mit : keys) { + mapAddress.erase(mit); + } + mapAddressInserted.erase(it); + } +} + +void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view) +{ + LOCK(cs); + const CTransaction& tx = entry.GetTx(); + uint256 txhash = tx.GetHash(); + std::vector inserted; + + for (unsigned int j = 0; j < tx.vin.size(); j++) { + const CTxIn input = tx.vin[j]; + const CTxOut &prevout = view.GetOutputFor(input); + CSpentIndexKey key = CSpentIndexKey(input.prevout.hash, input.prevout.n); + CSpentIndexValue value = CSpentIndexValue(txhash, j, -1, prevout.nValue, + prevout.scriptPubKey.GetType(), + prevout.scriptPubKey.AddressHash()); + mapSpent.insert(make_pair(key, value)); + inserted.push_back(key); + } + mapSpentInserted.insert(make_pair(txhash, inserted)); +} + +bool CTxMemPool::getSpentIndex(const CSpentIndexKey &key, CSpentIndexValue &value) +{ + LOCK(cs); + std::map::iterator it = mapSpent.find(key); + if (it != mapSpent.end()) { + value = it->second; + return true; + } + return false; +} + +void CTxMemPool::removeSpentIndex(const uint256 txhash) +{ + LOCK(cs); + auto it = mapSpentInserted.find(txhash); + + if (it != mapSpentInserted.end()) { + std::vector keys = (*it).second; + for (std::vector::iterator mit = keys.begin(); mit != keys.end(); mit++) { + mapSpent.erase(*mit); + } + mapSpentInserted.erase(it); + } +} +// END insightexplorer void CTxMemPool::remove(const CTransaction &origTx, std::list& removed, bool fRecursive) { @@ -156,9 +265,10 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem txToRemove.push_back(it->second.ptx->GetHash()); } } + mapRecentlyAddedTx.erase(hash); BOOST_FOREACH(const CTxIn& txin, tx.vin) mapNextTx.erase(txin.prevout); - BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) { + BOOST_FOREACH(const JSDescription& joinsplit, tx.vJoinSplit) { BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers) { mapSproutNullifiers.erase(nf); } @@ -172,6 +282,12 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem mapTx.erase(hash); nTransactionsUpdated++; minerPolicyEstimator->removeTx(hash); + + // insightexplorer + if (fAddressIndex) + removeAddressIndex(hash); + if (fSpentIndex) + removeSpentIndex(hash); } } } @@ -219,7 +335,7 @@ void CTxMemPool::removeWithAnchor(const uint256 &invalidRoot, ShieldedType type) const CTransaction& tx = it->GetTx(); switch (type) { case SPROUT: - BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) { + BOOST_FOREACH(const JSDescription& joinsplit, tx.vJoinSplit) { if (joinsplit.anchor == invalidRoot) { transactionsToRemove.push_back(tx); break; @@ -262,7 +378,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list } } - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { + BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) { BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) { std::map::iterator it = mapSproutNullifiers.find(nf); if (it != mapSproutNullifiers.end()) { @@ -407,7 +523,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const boost::unordered_map intermediates; - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { + BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) { BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) { assert(!pcoins->GetNullifier(nf, SPROUT)); } @@ -612,6 +728,49 @@ bool CTxMemPool::nullifierExists(const uint256& nullifier, ShieldedType type) co } } +void CTxMemPool::NotifyRecentlyAdded() +{ + uint64_t recentlyAddedSequence; + std::vector txs; + { + LOCK(cs); + recentlyAddedSequence = nRecentlyAddedSequence; + for (const auto& kv : mapRecentlyAddedTx) { + txs.push_back(*(kv.second)); + } + mapRecentlyAddedTx.clear(); + } + + // A race condition can occur here between these SyncWithWallets calls, and + // the ones triggered by block logic (in ConnectTip and DisconnectTip). It + // is harmless because calling SyncWithWallets(_, NULL) does not alter the + // wallet transaction's block information. + for (auto tx : txs) { + try { + SyncWithWallets(tx, NULL); + } catch (const boost::thread_interrupted&) { + throw; + } catch (const std::exception& e) { + PrintExceptionContinue(&e, "CTxMemPool::NotifyRecentlyAdded()"); + } catch (...) { + PrintExceptionContinue(NULL, "CTxMemPool::NotifyRecentlyAdded()"); + } + } + + // Update the notified sequence number. We only need this in regtest mode, + // and should not lock on cs after calling SyncWithWallets otherwise. + if (Params().NetworkIDString() == "regtest") { + LOCK(cs); + nNotifiedSequence = recentlyAddedSequence; + } +} + +bool CTxMemPool::IsFullyNotified() { + assert(Params().NetworkIDString() == "regtest"); + LOCK(cs); + return nRecentlyAddedSequence == nNotifiedSequence; +} + CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } bool CCoinsViewMemPool::GetNullifier(const uint256 &nf, ShieldedType type) const diff --git a/src/txmempool.h b/src/txmempool.h index ec8a8518a..43d54a27b 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_TXMEMPOOL_H #define BITCOIN_TXMEMPOOL_H @@ -12,6 +12,8 @@ #include "coins.h" #include "primitives/transaction.h" #include "sync.h" +#include "addressindex.h" +#include "spentindex.h" #undef foreach #include "boost/multi_index_container.hpp" @@ -41,17 +43,17 @@ class CTxMemPoolEntry { private: CTransaction tx; - CAmount nFee; //! Cached to avoid expensive parent-transaction lookups - size_t nTxSize; //! ... and avoid recomputing tx size - size_t nModSize; //! ... and modified size for priority - size_t nUsageSize; //! ... and total memory usage - CFeeRate feeRate; //! ... and fee per kB - int64_t nTime; //! Local time when entering the mempool - double dPriority; //! Priority when entering the mempool - unsigned int nHeight; //! Chain height when entering the mempool - bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool - bool spendsCoinbase; //! keep track of transactions that spend a coinbase - uint32_t nBranchId; //! Branch ID this transaction is known to commit to, cached for efficiency + CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups + size_t nTxSize; //!< ... and avoid recomputing tx size + size_t nModSize; //!< ... and modified size for priority + size_t nUsageSize; //!< ... and total memory usage + CFeeRate feeRate; //!< ... and fee per kB + int64_t nTime; //!< Local time when entering the mempool + double dPriority; //!< Priority when entering the mempool + unsigned int nHeight; //!< Chain height when entering the mempool + bool hadNoDependencies; //!< Not dependent on any other txs when it entered the mempool + bool spendsCoinbase; //!< keep track of transactions that spend a coinbase + uint32_t nBranchId; //!< Branch ID this transaction is known to commit to, cached for efficiency public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, @@ -124,18 +126,22 @@ class CInPoint class CTxMemPool { private: - uint32_t nCheckFrequency; //! Value n means that n times in 2^32 we check. + uint32_t nCheckFrequency; //!< Value n means that n times in 2^32 we check. unsigned int nTransactionsUpdated; CBlockPolicyEstimator* minerPolicyEstimator; - uint64_t totalTxSize = 0; //! sum of all mempool tx' byte sizes - uint64_t cachedInnerUsage; //! sum of dynamic memory usage of all the map elements (NOT the maps themselves) + uint64_t totalTxSize = 0; //!< sum of all mempool tx' byte sizes + uint64_t cachedInnerUsage; //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves) + + std::map mapRecentlyAddedTx; + uint64_t nRecentlyAddedSequence = 0; + uint64_t nNotifiedSequence = 0; std::map mapSproutNullifiers; std::map mapSaplingNullifiers; void checkNullifiers(ShieldedType type) const; - + public: typedef boost::multi_index_container< CTxMemPoolEntry, @@ -152,6 +158,15 @@ class CTxMemPool mutable CCriticalSection cs; indexed_transaction_set mapTx; + + private: + // insightexplorer + std::map mapAddress; + std::map > mapAddressInserted; + std::map mapSpent; + std::map> mapSpentInserted; + + public: std::map mapNextTx; std::map > mapDeltas; @@ -168,6 +183,18 @@ class CTxMemPool void setSanityCheck(double dFrequency = 1.0) { nCheckFrequency = static_cast(dFrequency * 4294967295.0); } bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true); + + // START insightexplorer + void addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); + void getAddressIndex(const std::vector>& addresses, + std::vector>& results); + void removeAddressIndex(const uint256& txhash); + + void addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); + bool getSpentIndex(const CSpentIndexKey &key, CSpentIndexValue &value); + void removeSpentIndex(const uint256 txhash); + // END insightexplorer + void remove(const CTransaction &tx, std::list& removed, bool fRecursive = false); void removeWithAnchor(const uint256 &invalidRoot, ShieldedType type); void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); @@ -194,6 +221,9 @@ class CTxMemPool bool nullifierExists(const uint256& nullifier, ShieldedType type) const; + void NotifyRecentlyAdded(); + bool IsFullyNotified(); + unsigned long size() { LOCK(cs); @@ -219,7 +249,7 @@ class CTxMemPool /** Estimate priority needed to get into the next nBlocks */ double estimatePriority(int nBlocks) const; - + /** Write/Read estimates to disk */ bool WriteFeeEstimates(CAutoFile& fileout) const; bool ReadFeeEstimates(CAutoFile& filein); @@ -232,7 +262,7 @@ class CTxMemPool } }; -/** +/** * CCoinsView that brings transactions from a memorypool into view. * It does not check for spendings by memory pool transactions. */ diff --git a/src/ui_interface.h b/src/ui_interface.h index ee0fd9113..3bcd57648 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2012 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_UI_INTERFACE_H #define BITCOIN_UI_INTERFACE_H diff --git a/src/uint256.cpp b/src/uint256.cpp index 25148808c..b16b0d904 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "uint256.h" diff --git a/src/uint256.h b/src/uint256.h index f22a8bafa..b07047b04 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_UINT256_H #define BITCOIN_UINT256_H diff --git a/src/undo.h b/src/undo.h index fbb350e60..6bf96a79f 100644 --- a/src/undo.h +++ b/src/undo.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_UNDO_H #define BITCOIN_UNDO_H diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index dfc84f921..f4dea4af9 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -1,7 +1,7 @@ // Copyright 2014 BitPay Inc. // Copyright 2015 Bitcoin Core Developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef UNIVALUE_H__ #define UNIVALUE_H__ diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index 14f4c3c4f..aaa027546 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -1,7 +1,7 @@ // Copyright 2014 BitPay Inc. // Copyright 2015 Bitcoin Core Developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include #include diff --git a/src/univalue/lib/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp index 7a9acdd75..35a9c726d 100644 --- a/src/univalue/lib/univalue_read.cpp +++ b/src/univalue/lib/univalue_read.cpp @@ -1,6 +1,6 @@ // Copyright 2014 BitPay Inc. // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include #include diff --git a/src/univalue/lib/univalue_utffilter.h b/src/univalue/lib/univalue_utffilter.h index b4a9ddc0a..41da1b0c4 100644 --- a/src/univalue/lib/univalue_utffilter.h +++ b/src/univalue/lib/univalue_utffilter.h @@ -1,6 +1,6 @@ // Copyright 2016 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef UNIVALUE_UTFFILTER_H #define UNIVALUE_UTFFILTER_H diff --git a/src/univalue/lib/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp index cf2783599..0337e690d 100644 --- a/src/univalue/lib/univalue_write.cpp +++ b/src/univalue/lib/univalue_write.cpp @@ -1,6 +1,6 @@ // Copyright 2014 BitPay Inc. // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include #include diff --git a/src/univalue/test/unitester.cpp b/src/univalue/test/unitester.cpp index aa6f91c1b..ea0c395e4 100644 --- a/src/univalue/test/unitester.cpp +++ b/src/univalue/test/unitester.cpp @@ -1,6 +1,6 @@ // Copyright 2014 BitPay Inc. // Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include #include diff --git a/src/util.cpp b/src/util.cpp index 3152ac2b6..98d5716dc 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" @@ -920,7 +920,7 @@ std::string LicenseInfo() "\n" + FormatParagraph(_("This is experimental software.")) + "\n" + "\n" + - FormatParagraph(_("Distributed under the MIT software license, see the accompanying file COPYING or .")) + "\n" + + FormatParagraph(_("Distributed under the MIT software license, see the accompanying file COPYING or .")) + "\n" + "\n" + FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written by Eric Young.")) + "\n"; diff --git a/src/util.h b/src/util.h index 6b3ecabf2..fddde236d 100644 --- a/src/util.h +++ b/src/util.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . /** * Server/client environment: argument handling, config file parsing, diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp index 0f3203432..0a47765ec 100644 --- a/src/utilmoneystr.cpp +++ b/src/utilmoneystr.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "utilmoneystr.h" diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h index 99c3ba830..d3bb1bb62 100644 --- a/src/utilmoneystr.h +++ b/src/utilmoneystr.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . /** * Money parsing/formatting utilities. diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index ece2ec73e..c3a25ca62 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "utilstrencodings.h" diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index 37a07ea06..ce2ca034e 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . /** * Utilities for converting data from/to strings. diff --git a/src/utiltest.cpp b/src/utiltest.cpp index e62c5611b..a942c020a 100644 --- a/src/utiltest.cpp +++ b/src/utiltest.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "utiltest.h" @@ -48,7 +48,7 @@ CMutableTransaction GetValidSproutReceiveTransaction(ZCJoinSplit& params, uint256 rt; JSDescription jsdesc {false, params, mtx.joinSplitPubKey, rt, inputs, outputs, 2*value, 0, false}; - mtx.vjoinsplit.push_back(jsdesc); + mtx.vJoinSplit.push_back(jsdesc); // Consider: The following is a bit misleading (given the name of this function) // and should perhaps be changed, but currently a few tests in test_wallet.cpp @@ -97,8 +97,8 @@ CWalletTx GetInvalidCommitmentSproutReceive(ZCJoinSplit& params, CMutableTransaction mtx = GetValidSproutReceiveTransaction( params, sk, value, randomInputs, version ); - mtx.vjoinsplit[0].commitments[0] = uint256(); - mtx.vjoinsplit[0].commitments[1] = uint256(); + mtx.vJoinSplit[0].commitments[0] = uint256(); + mtx.vJoinSplit[0].commitments[1] = uint256(); CTransaction tx {mtx}; CWalletTx wtx {NULL, tx}; return wtx; @@ -108,11 +108,11 @@ libzcash::SproutNote GetSproutNote(ZCJoinSplit& params, const libzcash::SproutSpendingKey& sk, const CTransaction& tx, size_t js, size_t n) { ZCNoteDecryption decryptor {sk.receiving_key()}; - auto hSig = tx.vjoinsplit[js].h_sig(params, tx.joinSplitPubKey); + auto hSig = tx.vJoinSplit[js].h_sig(params, tx.joinSplitPubKey); auto note_pt = libzcash::SproutNotePlaintext::decrypt( decryptor, - tx.vjoinsplit[js].ciphertexts[n], - tx.vjoinsplit[js].ephemeralKey, + tx.vJoinSplit[js].ciphertexts[n], + tx.vJoinSplit[js].ephemeralKey, hSig, (unsigned char) n); return note_pt.note(sk.address()); @@ -169,7 +169,7 @@ CWalletTx GetValidSproutSpend(ZCJoinSplit& params, uint256 rt = tree.root(); JSDescription jsdesc {false, params, mtx.joinSplitPubKey, rt, inputs, outputs, 0, value, false}; - mtx.vjoinsplit.push_back(jsdesc); + mtx.vJoinSplit.push_back(jsdesc); // Empty output script. uint32_t consensusBranchId = SPROUT_BRANCH_ID; @@ -200,6 +200,25 @@ void RegtestDeactivateSapling() { UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); } +const Consensus::Params& RegtestActivateBlossom(bool updatePow, int blossomActivationHeight) { + SelectParams(CBaseChainParams::REGTEST); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_BLOSSOM, blossomActivationHeight); + if (updatePow) { + UpdateRegtestPow(32, 16, uint256S("0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); + } + return Params().GetConsensus(); +} + +void RegtestDeactivateBlossom() { + UpdateRegtestPow(0, 0, uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f")); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_BLOSSOM, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); + SelectParams(CBaseChainParams::MAIN); +} + libzcash::SaplingExtendedSpendingKey GetTestMasterSaplingSpendingKey() { std::vector> rawSeed(32); HDSeed seed(rawSeed); @@ -232,7 +251,7 @@ CWalletTx GetValidSaplingReceive(const Consensus::Params& consensusParams, auto fvk = sk.expsk.full_viewing_key(); auto pa = sk.DefaultAddress(); - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta, &keyStore); + auto builder = TransactionBuilder(consensusParams, 1, &keyStore); builder.SetFee(0); builder.AddTransparentInput(COutPoint(), scriptPubKey, value); builder.AddSaplingOutput(fvk.ovk, pa, value, {}); diff --git a/src/utiltest.h b/src/utiltest.h index 5480c559e..6ea887ff2 100644 --- a/src/utiltest.h +++ b/src/utiltest.h @@ -1,6 +1,6 @@ // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_UTIL_TEST_H #define ZCASH_UTIL_TEST_H @@ -43,6 +43,10 @@ const Consensus::Params& RegtestActivateSapling(); void RegtestDeactivateSapling(); +const Consensus::Params& RegtestActivateBlossom(bool updatePow, int blossomActivationHeight = Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + +void RegtestDeactivateBlossom(); + libzcash::SaplingExtendedSpendingKey GetTestMasterSaplingSpendingKey(); CKey AddTestCKeyToKeyStore(CBasicKeyStore& keyStore); diff --git a/src/utiltime.cpp b/src/utiltime.cpp index f1a408a31..6249133c1 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" @@ -15,7 +15,7 @@ using namespace std; -static int64_t nMockTime = 0; //! For unit testing +static int64_t nMockTime = 0; //!< For unit testing int64_t GetTime() { diff --git a/src/utiltime.h b/src/utiltime.h index 900992f87..b1267112e 100644 --- a/src/utiltime.h +++ b/src/utiltime.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_UTILTIME_H #define BITCOIN_UTILTIME_H diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 1dc3351ab..54da44773 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "validationinterface.h" diff --git a/src/validationinterface.h b/src/validationinterface.h index 7b02bd9da..1b5a426de 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_VALIDATIONINTERFACE_H #define BITCOIN_VALIDATIONINTERFACE_H diff --git a/src/version.h b/src/version.h index b05f9bd1d..4e0834fb6 100644 --- a/src/version.h +++ b/src/version.h @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_VERSION_H #define BITCOIN_VERSION_H @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 770007; +static const int PROTOCOL_VERSION = 770008; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; diff --git a/src/wallet/asyncrpcoperation_common.cpp b/src/wallet/asyncrpcoperation_common.cpp new file mode 100644 index 000000000..dec29f8a2 --- /dev/null +++ b/src/wallet/asyncrpcoperation_common.cpp @@ -0,0 +1,56 @@ +#include "asyncrpcoperation_common.h" + +#include "core_io.h" +#include "init.h" +#include "rpc/protocol.h" + +extern UniValue signrawtransaction(const UniValue& params, bool fHelp); + +UniValue SendTransaction(CTransaction& tx, boost::optional reservekey, bool testmode) { + UniValue o(UniValue::VOBJ); + // Send the transaction + if (!testmode) { + CWalletTx wtx(pwalletMain, tx); + pwalletMain->CommitTransaction(wtx, reservekey); + o.push_back(Pair("txid", tx.GetHash().ToString())); + } else { + // Test mode does not send the transaction to the network. + o.push_back(Pair("test", 1)); + o.push_back(Pair("txid", tx.GetHash().ToString())); + o.push_back(Pair("hex", EncodeHexTx(tx))); + } + return o; +} + +std::pair SignSendRawTransaction(UniValue obj, boost::optional reservekey, bool testmode) { + // Sign the raw transaction + UniValue rawtxnValue = find_value(obj, "rawtxn"); + if (rawtxnValue.isNull()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction"); + } + std::string rawtxn = rawtxnValue.get_str(); + + UniValue params = UniValue(UniValue::VARR); + params.push_back(rawtxn); + UniValue signResultValue = signrawtransaction(params, false); + UniValue signResultObject = signResultValue.get_obj(); + UniValue completeValue = find_value(signResultObject, "complete"); + bool complete = completeValue.get_bool(); + if (!complete) { + // TODO: #1366 Maybe get "errors" and print array vErrors into a string + throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction"); + } + + UniValue hexValue = find_value(signResultObject, "hex"); + if (hexValue.isNull()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction"); + } + std::string signedtxn = hexValue.get_str(); + CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + stream >> tx; + + UniValue sendResult = SendTransaction(tx, reservekey, testmode); + + return std::make_pair(tx, sendResult); +} diff --git a/src/wallet/asyncrpcoperation_common.h b/src/wallet/asyncrpcoperation_common.h new file mode 100644 index 000000000..0b27d2952 --- /dev/null +++ b/src/wallet/asyncrpcoperation_common.h @@ -0,0 +1,31 @@ +// Copyright (c) 2019 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ASYNCRPCOPERATION_COMMON_H +#define ASYNCRPCOPERATION_COMMON_H + +#include "primitives/transaction.h" +#include "univalue.h" +#include "wallet.h" + +/** + * Sends a given transaction. + * + * If testmode is false, commit the transaction to the wallet, + * return {"txid": tx.GetHash().ToString()} + * + * If testmode is true, do not commit the transaction, + * return {"test": 1, "txid": tx.GetHash().ToString(), "hex": EncodeHexTx(tx)} + */ +UniValue SendTransaction(CTransaction& tx, boost::optional reservekey, bool testmode); + +/** + * Sign and send a raw transaction. + * Raw transaction as hex string should be in object field "rawtxn" + * + * Returns a pair of (the parsed transaction, and the result of sending) + */ +std::pair SignSendRawTransaction(UniValue obj, boost::optional reservekey, bool testmode); + +#endif /* ASYNCRPCOPERATION_COMMON_H */ diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index 0e5dd3409..b8bc0ff7b 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -1,10 +1,11 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "asyncrpcoperation_mergetoaddress.h" #include "amount.h" +#include "asyncrpcoperation_common.h" #include "asyncrpcqueue.h" #include "core_io.h" #include "init.h" @@ -33,8 +34,6 @@ using namespace libzcash; -extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); - int mta_find_output(UniValue obj, int n) { UniValue outputMapValue = find_value(obj, "outputmap"); @@ -217,7 +216,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); { LOCK(cs_main); - if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + if (Params().GetConsensus().NetworkUpgradeActive(chainActive.Height() + 1, Consensus::UPGRADE_OVERWINTER)) { limit = 0; } } @@ -287,7 +286,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() * SCENARIO #0 * * Sprout not involved, so we just use the TransactionBuilder and we're done. - * + * * This is based on code from AsyncRPCOperation_sendmany::main_impl() and should be refactored. */ if (isUsingBuilder_) { @@ -360,31 +359,8 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() // Build the transaction tx_ = builder_.Build().GetTxOrThrow(); - - // Send the transaction - // TODO: Use CWallet::CommitTransaction instead of sendrawtransaction - auto signedtxn = EncodeHexTx(tx_); - if (!testmode) { - UniValue params = UniValue(UniValue::VARR); - params.push_back(signedtxn); - UniValue sendResultValue = sendrawtransaction(params, false); - if (sendResultValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "sendrawtransaction did not return an error or a txid."); - } - - auto txid = sendResultValue.get_str(); - - UniValue o(UniValue::VOBJ); - o.push_back(Pair("txid", txid)); - set_result(o); - } else { - // Test mode does not send the transaction to the network. - UniValue o(UniValue::VOBJ); - o.push_back(Pair("test", 1)); - o.push_back(Pair("txid", tx_.GetHash().ToString())); - o.push_back(Pair("hex", signedtxn)); - set_result(o); - } + UniValue sendResult = SendTransaction(tx_, boost::none, testmode); + set_result(sendResult); return true; } @@ -403,7 +379,9 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() if (isPureTaddrOnlyTx) { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("rawtxn", EncodeHexTx(tx_))); - sign_send_raw_transaction(obj); + auto txAndResult = SignSendRawTransaction(obj, boost::none, testmode); + tx_ = txAndResult.first; + set_result(txAndResult.second); return true; } /** @@ -438,9 +416,10 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() } info.vjsout.push_back(jso); - UniValue obj(UniValue::VOBJ); - obj = perform_joinsplit(info); - sign_send_raw_transaction(obj); + UniValue obj = perform_joinsplit(info); + auto txAndResult = SignSendRawTransaction(obj, boost::none, testmode); + tx_ = txAndResult.first; + set_result(txAndResult.second); return true; } /** @@ -532,12 +511,12 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() JSDescription prevJoinSplit; // Keep track of previous JoinSplit and its commitments - if (tx_.vjoinsplit.size() > 0) { - prevJoinSplit = tx_.vjoinsplit.back(); + if (tx_.vJoinSplit.size() > 0) { + prevJoinSplit = tx_.vJoinSplit.back(); } // If there is no change, the chain has terminated so we can reset the tracked treestate. - if (jsChange == 0 && tx_.vjoinsplit.size() > 0) { + if (jsChange == 0 && tx_.vJoinSplit.size() > 0) { intermediates.clear(); previousCommitments.clear(); } @@ -645,7 +624,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight; wtxDepth = wtx.GetDepthInMainChain(); } - LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, jsoutindex=%d, amount=%s, height=%d, confirmations=%d)\n", + LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vJoinSplit=%d, jsoutindex=%d, amount=%s, height=%d, confirmations=%d)\n", getId(), jso.hash.ToString().substr(0, 10), jso.js, @@ -739,80 +718,13 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() assert(zInputsDeque.size() == 0); assert(vpubNewProcessed); - sign_send_raw_transaction(obj); + auto txAndResult = SignSendRawTransaction(obj, boost::none, testmode); + tx_ = txAndResult.first; + set_result(txAndResult.second); return true; } -extern UniValue signrawtransaction(const UniValue& params, bool fHelp); - -/** - * Sign and send a raw transaction. - * Raw transaction as hex string should be in object field "rawtxn" - */ -void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj) -{ - // Sign the raw transaction - UniValue rawtxnValue = find_value(obj, "rawtxn"); - if (rawtxnValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction"); - } - std::string rawtxn = rawtxnValue.get_str(); - - UniValue params = UniValue(UniValue::VARR); - params.push_back(rawtxn); - UniValue signResultValue = signrawtransaction(params, false); - UniValue signResultObject = signResultValue.get_obj(); - UniValue completeValue = find_value(signResultObject, "complete"); - bool complete = completeValue.get_bool(); - if (!complete) { - // TODO: #1366 Maybe get "errors" and print array vErrors into a string - throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction"); - } - - UniValue hexValue = find_value(signResultObject, "hex"); - if (hexValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction"); - } - std::string signedtxn = hexValue.get_str(); - - // Send the signed transaction - if (!testmode) { - params.clear(); - params.setArray(); - params.push_back(signedtxn); - UniValue sendResultValue = sendrawtransaction(params, false); - if (sendResultValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Send raw transaction did not return an error or a txid."); - } - - std::string txid = sendResultValue.get_str(); - - UniValue o(UniValue::VOBJ); - o.push_back(Pair("txid", txid)); - set_result(o); - } else { - // Test mode does not send the transaction to the network. - - CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - - UniValue o(UniValue::VOBJ); - o.push_back(Pair("test", 1)); - o.push_back(Pair("txid", tx.GetHash().ToString())); - o.push_back(Pair("hex", signedtxn)); - set_result(o); - } - - // Keep the signed transaction so we can hash to the same txid - CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - tx_ = tx; -} - - UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info) { std::vector> witnesses; @@ -877,7 +789,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", getId(), - tx_.vjoinsplit.size(), + tx_.vJoinSplit.size(), FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value)); @@ -910,7 +822,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( } } - mtx.vjoinsplit.push_back(jsdesc); + mtx.vJoinSplit.push_back(jsdesc); // Empty output script. CScript scriptCode; @@ -973,7 +885,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer std::vector vch(&buffer[0], &buffer[0] + 32); uint256 joinSplitPrivKey = uint256(vch); - size_t js_index = tx_.vjoinsplit.size() - 1; + size_t js_index = tx_.vJoinSplit.size() - 1; uint256 placeholder; for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { uint8_t mapped_index = outputMap[i]; diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h index 774695cf2..c2c82f858 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.h +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ASYNCRPCOPERATION_MERGETOADDRESS_H #define ASYNCRPCOPERATION_MERGETOADDRESS_H @@ -84,7 +84,7 @@ class AsyncRPCOperation_mergetoaddress : public AsyncRPCOperation friend class TEST_FRIEND_AsyncRPCOperation_mergetoaddress; // class for unit testing UniValue contextinfo_; // optional data to include in return value from getStatus() - + bool isUsingBuilder_; // Indicates that no Sprout addresses are involved uint32_t consensusBranchId_; CAmount fee_; @@ -123,8 +123,6 @@ class AsyncRPCOperation_mergetoaddress : public AsyncRPCOperation std::vector> witnesses, uint256 anchor); - void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error - void lock_utxos(); void unlock_utxos(); @@ -186,11 +184,6 @@ class TEST_FRIEND_AsyncRPCOperation_mergetoaddress return delegate->perform_joinsplit(info, witnesses, anchor); } - void sign_send_raw_transaction(UniValue obj) - { - delegate->sign_send_raw_transaction(obj); - } - void set_state(OperationStatus state) { delegate->state_.store(state); diff --git a/src/wallet/asyncrpcoperation_saplingmigration.cpp b/src/wallet/asyncrpcoperation_saplingmigration.cpp index 8e1dda615..3bb57fab8 100644 --- a/src/wallet/asyncrpcoperation_saplingmigration.cpp +++ b/src/wallet/asyncrpcoperation_saplingmigration.cpp @@ -69,7 +69,15 @@ void AsyncRPCOperation_saplingmigration::main() { bool AsyncRPCOperation_saplingmigration::main_impl() { LogPrint("zrpcunsafe", "%s: Beginning AsyncRPCOperation_saplingmigration.\n", getId()); - std::vector sproutEntries; + auto consensusParams = Params().GetConsensus(); + auto nextActivationHeight = NextActivationHeight(targetHeight_, consensusParams); + if (nextActivationHeight && targetHeight_ + MIGRATION_EXPIRY_DELTA >= nextActivationHeight.get()) { + LogPrint("zrpcunsafe", "%s: Migration txs would be created before a NU activation but may expire after. Skipping this round.\n", getId()); + setMigrationResult(0, 0, std::vector()); + return true; + } + + std::vector sproutEntries; std::vector saplingEntries; { LOCK2(cs_main, pwalletMain->cs_wallet); @@ -79,8 +87,8 @@ bool AsyncRPCOperation_saplingmigration::main_impl() { pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, "", 11); } CAmount availableFunds = 0; - for (const CSproutNotePlaintextEntry& sproutEntry : sproutEntries) { - availableFunds += sproutEntry.plaintext.value(); + for (const SproutNoteEntry& sproutEntry : sproutEntries) { + availableFunds += sproutEntry.note.value(); } // If the remaining amount to be migrated is less than 0.01 ZEC, end the migration. if (availableFunds < CENT) { @@ -93,7 +101,6 @@ bool AsyncRPCOperation_saplingmigration::main_impl() { HDSeed seed = pwalletMain->GetHDSeedForRPC(); libzcash::SaplingPaymentAddress migrationDestAddress = getMigrationDestAddress(seed); - auto consensusParams = Params().GetConsensus(); // Up to the limit of 5, as many transactions are sent as are needed to migrate the remaining funds int numTxCreated = 0; @@ -103,28 +110,27 @@ bool AsyncRPCOperation_saplingmigration::main_impl() { CCoinsViewCache coinsView(pcoinsTip); do { CAmount amountToSend = chooseAmount(availableFunds); - auto builder = TransactionBuilder(consensusParams, targetHeight_, MIGRATION_EXPIRY_DELTA, pwalletMain, pzcashParams, - &coinsView, &cs_main); + auto builder = TransactionBuilder(consensusParams, targetHeight_, pwalletMain, pzcashParams, &coinsView, &cs_main); + builder.SetExpiryHeight(targetHeight_ + MIGRATION_EXPIRY_DELTA); LogPrint("zrpcunsafe", "%s: Beginning creating transaction with Sapling output amount=%s\n", getId(), FormatMoney(amountToSend - FEE)); - std::vector fromNotes; + std::vector fromNotes; CAmount fromNoteAmount = 0; while (fromNoteAmount < amountToSend) { auto sproutEntry = sproutEntries[noteIndex++]; fromNotes.push_back(sproutEntry); - fromNoteAmount += sproutEntry.plaintext.value(); + fromNoteAmount += sproutEntry.note.value(); } availableFunds -= fromNoteAmount; - for (const CSproutNotePlaintextEntry& sproutEntry : fromNotes) { - std::string data(sproutEntry.plaintext.memo().begin(), sproutEntry.plaintext.memo().end()); - LogPrint("zrpcunsafe", "%s: Adding Sprout note input (txid=%s, vjoinsplit=%d, jsoutindex=%d, amount=%s, memo=%s)\n", + for (const SproutNoteEntry& sproutEntry : fromNotes) { + std::string data(sproutEntry.memo.begin(), sproutEntry.memo.end()); + LogPrint("zrpcunsafe", "%s: Adding Sprout note input (txid=%s, vJoinSplit=%d, jsoutindex=%d, amount=%s, memo=%s)\n", getId(), sproutEntry.jsop.hash.ToString().substr(0, 10), sproutEntry.jsop.js, int(sproutEntry.jsop.n), // uint8_t - FormatMoney(sproutEntry.plaintext.value()), + FormatMoney(sproutEntry.note.value()), HexStr(data).substr(0, 10) ); - libzcash::SproutNote sproutNote = sproutEntry.plaintext.note(sproutEntry.address); libzcash::SproutSpendingKey sproutSk; pwalletMain->GetSproutSpendingKey(sproutEntry.address, sproutSk); std::vector vOutPoints = {sproutEntry.jsop}; @@ -134,7 +140,7 @@ bool AsyncRPCOperation_saplingmigration::main_impl() { uint256 inputAnchor; std::vector> vInputWitnesses; pwalletMain->GetSproutNoteWitnesses(vOutPoints, vInputWitnesses, inputAnchor); - builder.AddSproutInput(sproutSk, sproutNote, vInputWitnesses[0].get()); + builder.AddSproutInput(sproutSk, sproutEntry.note, vInputWitnesses[0].get()); } // The amount chosen *includes* the 0.0001 ZEC fee for this transaction, i.e. // the value of the Sapling output will be 0.0001 ZEC less. diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 93ec59b53..29efb9304 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -1,10 +1,12 @@ // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "asyncrpcoperation_sendmany.h" -#include "asyncrpcqueue.h" + #include "amount.h" +#include "asyncrpcoperation_common.h" +#include "asyncrpcqueue.h" #include "consensus/upgrades.h" #include "core_io.h" #include "init.h" @@ -34,9 +36,6 @@ using namespace libzcash; -extern UniValue signrawtransaction(const UniValue& params, bool fHelp); -extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); - int find_output(UniValue obj, int n) { UniValue outputMapValue = find_value(obj, "outputmap"); if (!outputMapValue.isArray()) { @@ -70,11 +69,11 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( if (minDepth < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Minconf cannot be negative"); } - + if (fromAddress.size() == 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "From address parameter missing"); } - + if (tOutputs.size() == 0 && zOutputs.size() == 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "No recipients"); } @@ -224,9 +223,9 @@ bool AsyncRPCOperation_sendmany::main_impl() { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any non-coinbase UTXOs to spend."); } } - } + } } - + if (isfromzaddr_ && !find_unspent_notes()) { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds, no unspent notes found for zaddr from address."); } @@ -268,7 +267,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { strprintf("Insufficient transparent funds, have %s, need %s", FormatMoney(t_inputs_total), FormatMoney(targetAmount))); } - + if (isfromzaddr_ && (z_inputs_total < targetAmount)) { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strprintf("Insufficient shielded funds, have %s, need %s", @@ -318,7 +317,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); { LOCK(cs_main); - if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + if (Params().GetConsensus().NetworkUpgradeActive(chainActive.Height() + 1, Consensus::UPGRADE_OVERWINTER)) { limit = 0; } } @@ -387,11 +386,11 @@ bool AsyncRPCOperation_sendmany::main_impl() { // Set change address if we are using transparent funds // TODO: Should we just use fromtaddr_ as the change address? + CReserveKey keyChange(pwalletMain); if (isfromtaddr_) { LOCK2(cs_main, pwalletMain->cs_wallet); EnsureWalletIsUnlocked(); - CReserveKey keyChange(pwalletMain); CPubKey vchPubKey; bool ret = keyChange.GetReservedKey(vchPubKey); if (!ret) { @@ -461,30 +460,8 @@ bool AsyncRPCOperation_sendmany::main_impl() { // Build the transaction tx_ = builder_.Build().GetTxOrThrow(); - // Send the transaction - // TODO: Use CWallet::CommitTransaction instead of sendrawtransaction - auto signedtxn = EncodeHexTx(tx_); - if (!testmode) { - UniValue params = UniValue(UniValue::VARR); - params.push_back(signedtxn); - UniValue sendResultValue = sendrawtransaction(params, false); - if (sendResultValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "sendrawtransaction did not return an error or a txid."); - } - - auto txid = sendResultValue.get_str(); - - UniValue o(UniValue::VOBJ); - o.push_back(Pair("txid", txid)); - set_result(o); - } else { - // Test mode does not send the transaction to the network. - UniValue o(UniValue::VOBJ); - o.push_back(Pair("test", 1)); - o.push_back(Pair("txid", tx_.GetHash().ToString())); - o.push_back(Pair("hex", signedtxn)); - set_result(o); - } + UniValue sendResult = SendTransaction(tx_, keyChange, testmode); + set_result(sendResult); return true; } @@ -501,37 +478,40 @@ bool AsyncRPCOperation_sendmany::main_impl() { /** * SCENARIO #1 - * + * * taddr -> taddrs - * + * * There are no zaddrs or joinsplits involved. */ if (isPureTaddrOnlyTx) { add_taddr_outputs_to_tx(); - + CAmount funds = selectedUTXOAmount; CAmount fundsSpent = t_outputs_total + minersFee; CAmount change = funds - fundsSpent; - + + CReserveKey keyChange(pwalletMain); if (change > 0) { - add_taddr_change_output_to_tx(change); + add_taddr_change_output_to_tx(keyChange, change); LogPrint("zrpc", "%s: transparent change in transaction output (amount=%s)\n", getId(), FormatMoney(change) ); } - + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("rawtxn", EncodeHexTx(tx_))); - sign_send_raw_transaction(obj); + auto txAndResult = SignSendRawTransaction(obj, keyChange, testmode); + tx_ = txAndResult.first; + set_result(txAndResult.second); return true; } /** * END SCENARIO #1 */ - + // Prepare raw transaction to handle JoinSplits CMutableTransaction mtx(tx_); crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_); @@ -571,10 +551,10 @@ bool AsyncRPCOperation_sendmany::main_impl() { /** * SCENARIO #2 - * + * * taddr -> taddrs * -> zaddrs - * + * * Note: Consensus rule states that coinbase utxos can only be sent to a zaddr. * Local wallet rule does not allow any change when sending coinbase utxos * since there is currently no way to specify a change address and we don't @@ -582,11 +562,12 @@ bool AsyncRPCOperation_sendmany::main_impl() { */ if (isfromtaddr_) { add_taddr_outputs_to_tx(); - + CAmount funds = selectedUTXOAmount; CAmount fundsSpent = t_outputs_total + minersFee + z_outputs_total; CAmount change = funds - fundsSpent; - + + CReserveKey keyChange(pwalletMain); if (change > 0) { if (selectedUTXOCoinbase) { assert(isSingleZaddrOutput); @@ -595,7 +576,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { "allow any change as there is currently no way to specify a change address " "in z_sendmany.", FormatMoney(change))); } else { - add_taddr_change_output_to_tx(change); + add_taddr_change_output_to_tx(keyChange, change); LogPrint("zrpc", "%s: transparent change in transaction output (amount=%s)\n", getId(), FormatMoney(change) @@ -623,27 +604,30 @@ bool AsyncRPCOperation_sendmany::main_impl() { jso.memo = get_memo_from_hex_string(hexMemo); } info.vjsout.push_back(jso); - + // Funds are removed from the value pool and enter the private pool info.vpub_old += value; } obj = perform_joinsplit(info); } - sign_send_raw_transaction(obj); + + auto txAndResult = SignSendRawTransaction(obj, keyChange, testmode); + tx_ = txAndResult.first; + set_result(txAndResult.second); return true; } /** * END SCENARIO #2 - */ - - - + */ + + + /** * SCENARIO #3 - * + * * zaddr -> taddrs * -> zaddrs - * + * * Send to zaddrs by chaining JoinSplits together and immediately consuming any change * Send to taddrs by creating dummy z outputs and accumulating value in a change note * which is used to set vpub_new in the last chained joinsplit. @@ -674,12 +658,12 @@ bool AsyncRPCOperation_sendmany::main_impl() { JSDescription prevJoinSplit; // Keep track of previous JoinSplit and its commitments - if (tx_.vjoinsplit.size() > 0) { - prevJoinSplit = tx_.vjoinsplit.back(); + if (tx_.vJoinSplit.size() > 0) { + prevJoinSplit = tx_.vJoinSplit.back(); } // If there is no change, the chain has terminated so we can reset the tracked treestate. - if (jsChange==0 && tx_.vjoinsplit.size() > 0) { + if (jsChange==0 && tx_.vJoinSplit.size() > 0) { intermediates.clear(); previousCommitments.clear(); } @@ -769,9 +753,9 @@ bool AsyncRPCOperation_sendmany::main_impl() { vOutPoints.push_back(jso); vInputNotes.push_back(note); - + jsInputValue += noteFunds; - + int wtxHeight = -1; int wtxDepth = -1; { @@ -784,7 +768,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight; wtxDepth = wtx.GetDepthInMainChain(); } - LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, jsoutindex=%d, amount=%s, height=%d, confirmations=%d)\n", + LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vJoinSplit=%d, jsoutindex=%d, amount=%s, height=%d, confirmations=%d)\n", getId(), jso.hash.ToString().substr(0, 10), jso.js, @@ -794,14 +778,14 @@ bool AsyncRPCOperation_sendmany::main_impl() { wtxDepth ); } - + // Add history of previous commitments to witness if (vInputNotes.size() > 0) { if (vInputWitnesses.size()==0) { throw JSONRPCError(RPC_WALLET_ERROR, "Could not find witness for note commitment"); } - + for (auto & optionalWitness : vInputWitnesses) { if (!optionalWitness) { throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null"); @@ -907,78 +891,13 @@ bool AsyncRPCOperation_sendmany::main_impl() { assert(zOutputsDeque.size() == 0); assert(vpubNewProcessed); - sign_send_raw_transaction(obj); + auto txAndResult = SignSendRawTransaction(obj, boost::none, testmode); + tx_ = txAndResult.first; + set_result(txAndResult.second); return true; } -/** - * Sign and send a raw transaction. - * Raw transaction as hex string should be in object field "rawtxn" - */ -void AsyncRPCOperation_sendmany::sign_send_raw_transaction(UniValue obj) -{ - // Sign the raw transaction - UniValue rawtxnValue = find_value(obj, "rawtxn"); - if (rawtxnValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction"); - } - std::string rawtxn = rawtxnValue.get_str(); - - UniValue params = UniValue(UniValue::VARR); - params.push_back(rawtxn); - UniValue signResultValue = signrawtransaction(params, false); - UniValue signResultObject = signResultValue.get_obj(); - UniValue completeValue = find_value(signResultObject, "complete"); - bool complete = completeValue.get_bool(); - if (!complete) { - // TODO: #1366 Maybe get "errors" and print array vErrors into a string - throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction"); - } - - UniValue hexValue = find_value(signResultObject, "hex"); - if (hexValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction"); - } - std::string signedtxn = hexValue.get_str(); - - // Send the signed transaction - if (!testmode) { - params.clear(); - params.setArray(); - params.push_back(signedtxn); - UniValue sendResultValue = sendrawtransaction(params, false); - if (sendResultValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Send raw transaction did not return an error or a txid."); - } - - std::string txid = sendResultValue.get_str(); - - UniValue o(UniValue::VOBJ); - o.push_back(Pair("txid", txid)); - set_result(o); - } else { - // Test mode does not send the transaction to the network. - - CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - - UniValue o(UniValue::VOBJ); - o.push_back(Pair("test", 1)); - o.push_back(Pair("txid", tx.GetHash().ToString())); - o.push_back(Pair("hex", signedtxn)); - set_result(o); - } - - // Keep the signed transaction so we can hash to the same txid - CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - tx_ = tx; -} - - bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) { std::set destinations; destinations.insert(fromtaddr_); @@ -1029,7 +948,7 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) { bool AsyncRPCOperation_sendmany::find_unspent_notes() { - std::vector sproutEntries; + std::vector sproutEntries; std::vector saplingEntries; { LOCK2(cs_main, pwalletMain->cs_wallet); @@ -1045,15 +964,15 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { saplingEntries.clear(); } - for (CSproutNotePlaintextEntry & entry : sproutEntries) { - z_sprout_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(boost::get(frompaymentaddress_)), CAmount(entry.plaintext.value()))); - std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end()); - LogPrint("zrpcunsafe", "%s: found unspent Sprout note (txid=%s, vjoinsplit=%d, jsoutindex=%d, amount=%s, memo=%s)\n", + for (SproutNoteEntry & entry : sproutEntries) { + z_sprout_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.note, CAmount(entry.note.value()))); + std::string data(entry.memo.begin(), entry.memo.end()); + LogPrint("zrpcunsafe", "%s: found unspent Sprout note (txid=%s, vJoinSplit=%d, jsoutindex=%d, amount=%s, memo=%s)\n", getId(), entry.jsop.hash.ToString().substr(0, 10), entry.jsop.js, int(entry.jsop.n), // uint8_t - FormatMoney(entry.plaintext.value()), + FormatMoney(entry.note.value()), HexStr(data).substr(0, 10) ); } @@ -1144,7 +1063,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", getId(), - tx_.vjoinsplit.size(), + tx_.vJoinSplit.size(), FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value) @@ -1180,7 +1099,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( } } - mtx.vjoinsplit.push_back(jsdesc); + mtx.vJoinSplit.push_back(jsdesc); // Empty output script. CScript scriptCode; @@ -1247,7 +1166,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer std::vector vch(&buffer[0], &buffer[0] + 32); uint256 joinSplitPrivKey = uint256(vch); - size_t js_index = tx_.vjoinsplit.size() - 1; + size_t js_index = tx_.vJoinSplit.size() - 1; uint256 placeholder; for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { uint8_t mapped_index = outputMap[i]; @@ -1293,12 +1212,11 @@ void AsyncRPCOperation_sendmany::add_taddr_outputs_to_tx() { tx_ = CTransaction(rawTx); } -void AsyncRPCOperation_sendmany::add_taddr_change_output_to_tx(CAmount amount) { +void AsyncRPCOperation_sendmany::add_taddr_change_output_to_tx(CReserveKey& keyChange, CAmount amount) { LOCK2(cs_main, pwalletMain->cs_wallet); EnsureWalletIsUnlocked(); - CReserveKey keyChange(pwalletMain); CPubKey vchPubKey; bool ret = keyChange.GetReservedKey(vchPubKey); if (!ret) { @@ -1315,7 +1233,7 @@ void AsyncRPCOperation_sendmany::add_taddr_change_output_to_tx(CAmount amount) { std::array AsyncRPCOperation_sendmany::get_memo_from_hex_string(std::string s) { // initialize to default memo (no_memo), see section 5.5 of the protocol spec std::array memo = {{0xF6}}; - + std::vector rawMemo = ParseHex(s.c_str()); // If ParseHex comes across a non-hex char, it will stop but still return results so far. @@ -1323,11 +1241,11 @@ std::array AsyncRPCOperation_sendmany::get_memo_fro if (slen % 2 !=0 || (slen>0 && rawMemo.size()!=slen/2)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo must be in hexadecimal format"); } - + if (rawMemo.size() > ZC_MEMO_SIZE) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Memo size of %d is too big, maximum allowed is %d", rawMemo.size(), ZC_MEMO_SIZE)); } - + // copy vector into boost array int lenMemo = rawMemo.size(); for (int i = 0; i < ZC_MEMO_SIZE && i < lenMemo; i++) { @@ -1350,4 +1268,3 @@ UniValue AsyncRPCOperation_sendmany::getStatus() const { obj.push_back(Pair("params", contextinfo_ )); return obj; } - diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index fcb95227a..f55cf9936 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -1,6 +1,6 @@ // Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ASYNCRPCOPERATION_SENDMANY_H #define ASYNCRPCOPERATION_SENDMANY_H @@ -62,13 +62,13 @@ class AsyncRPCOperation_sendmany : public AsyncRPCOperation { CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue); virtual ~AsyncRPCOperation_sendmany(); - + // We don't want to be copied or moved around AsyncRPCOperation_sendmany(AsyncRPCOperation_sendmany const&) = delete; // Copy construct AsyncRPCOperation_sendmany(AsyncRPCOperation_sendmany&&) = delete; // Move construct AsyncRPCOperation_sendmany& operator=(AsyncRPCOperation_sendmany const&) = delete; // Copy assign AsyncRPCOperation_sendmany& operator=(AsyncRPCOperation_sendmany &&) = delete; // Move assign - + virtual void main(); virtual UniValue getStatus() const; @@ -92,7 +92,7 @@ class AsyncRPCOperation_sendmany : public AsyncRPCOperation { CTxDestination fromtaddr_; PaymentAddress frompaymentaddress_; SpendingKey spendingkey_; - + uint256 joinSplitPubKey_; unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES]; @@ -107,8 +107,8 @@ class AsyncRPCOperation_sendmany : public AsyncRPCOperation { TransactionBuilder builder_; CTransaction tx_; - - void add_taddr_change_output_to_tx(CAmount amount); + + void add_taddr_change_output_to_tx(CReserveKey& keyChange, CAmount amount); void add_taddr_outputs_to_tx(); bool find_unspent_notes(); bool find_utxos(bool fAcceptCoinbase); @@ -127,8 +127,6 @@ class AsyncRPCOperation_sendmany : public AsyncRPCOperation { std::vector> witnesses, uint256 anchor); - void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error - // payment disclosure! std::vector paymentDisclosureData_; }; @@ -138,27 +136,27 @@ class AsyncRPCOperation_sendmany : public AsyncRPCOperation { class TEST_FRIEND_AsyncRPCOperation_sendmany { public: std::shared_ptr delegate; - + TEST_FRIEND_AsyncRPCOperation_sendmany(std::shared_ptr ptr) : delegate(ptr) {} - + CTransaction getTx() { return delegate->tx_; } - + void setTx(CTransaction tx) { delegate->tx_ = tx; } - + // Delegated methods - - void add_taddr_change_output_to_tx(CAmount amount) { - delegate->add_taddr_change_output_to_tx(amount); + + void add_taddr_change_output_to_tx(CReserveKey& keyChange, CAmount amount) { + delegate->add_taddr_change_output_to_tx(keyChange, amount); } - + void add_taddr_outputs_to_tx() { delegate->add_taddr_outputs_to_tx(); } - + bool find_unspent_notes() { return delegate->find_unspent_notes(); } @@ -166,11 +164,11 @@ class TEST_FRIEND_AsyncRPCOperation_sendmany { bool find_utxos(bool fAcceptCoinbase) { return delegate->find_utxos(fAcceptCoinbase); } - + std::array get_memo_from_hex_string(std::string s) { return delegate->get_memo_from_hex_string(s); } - + bool main_impl() { return delegate->main_impl(); } @@ -191,10 +189,6 @@ class TEST_FRIEND_AsyncRPCOperation_sendmany { return delegate->perform_joinsplit(info, witnesses, anchor); } - void sign_send_raw_transaction(UniValue obj) { - delegate->sign_send_raw_transaction(obj); - } - void set_state(OperationStatus state) { delegate->state_.store(state); } @@ -202,4 +196,3 @@ class TEST_FRIEND_AsyncRPCOperation_sendmany { #endif /* ASYNCRPCOPERATION_SENDMANY_H */ - diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index 84811c686..9bc1cbcc2 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -1,9 +1,12 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "asyncrpcoperation_shieldcoinbase.h" -#include "asyncrpcqueue.h" #include "amount.h" +#include "asyncrpcoperation_common.h" +#include "asyncrpcqueue.h" #include "consensus/upgrades.h" #include "core_io.h" #include "init.h" @@ -31,8 +34,6 @@ #include #include -#include "asyncrpcoperation_shieldcoinbase.h" - using namespace libzcash; static int find_output(UniValue obj, int n) { @@ -61,7 +62,7 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase( UniValue contextInfo) : builder_(builder), tx_(contextualTx), inputs_(inputs), fee_(fee), contextinfo_(contextInfo) { - assert(contextualTx.nVersion >= 2); // transaction format version must support vjoinsplit + assert(contextualTx.nVersion >= 2); // transaction format version must support vJoinSplit if (fee < 0 || fee > MAX_MONEY) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Fee is out of range"); @@ -180,7 +181,7 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() { size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); { LOCK(cs_main); - if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + if (Params().GetConsensus().NetworkUpgradeActive(chainActive.Height() + 1, Consensus::UPGRADE_OVERWINTER)) { limit = 0; } } @@ -224,22 +225,20 @@ bool ShieldToAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) co m_op->tx_ = CTransaction(mtx); // Create joinsplit - UniValue obj(UniValue::VOBJ); ShieldCoinbaseJSInfo info; info.vpub_old = sendAmount; info.vpub_new = 0; JSOutput jso = JSOutput(zaddr, sendAmount); info.vjsout.push_back(jso); - obj = m_op->perform_joinsplit(info); + UniValue obj = m_op->perform_joinsplit(info); - m_op->sign_send_raw_transaction(obj); + auto txAndResult = SignSendRawTransaction(obj, boost::none, m_op->testmode); + m_op->tx_ = txAndResult.first; + m_op->set_result(txAndResult.second); return true; } -extern UniValue signrawtransaction(const UniValue& params, bool fHelp); -extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); - bool ShieldToAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) const { m_op->builder_.SetFee(m_op->fee_); @@ -261,30 +260,8 @@ bool ShieldToAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) c // Build the transaction m_op->tx_ = m_op->builder_.Build().GetTxOrThrow(); - // Send the transaction - // TODO: Use CWallet::CommitTransaction instead of sendrawtransaction - auto signedtxn = EncodeHexTx(m_op->tx_); - if (!m_op->testmode) { - UniValue params = UniValue(UniValue::VARR); - params.push_back(signedtxn); - UniValue sendResultValue = sendrawtransaction(params, false); - if (sendResultValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "sendrawtransaction did not return an error or a txid."); - } - - auto txid = sendResultValue.get_str(); - - UniValue o(UniValue::VOBJ); - o.push_back(Pair("txid", txid)); - m_op->set_result(o); - } else { - // Test mode does not send the transaction to the network. - UniValue o(UniValue::VOBJ); - o.push_back(Pair("test", 1)); - o.push_back(Pair("txid", m_op->tx_.GetHash().ToString())); - o.push_back(Pair("hex", signedtxn)); - m_op->set_result(o); - } + UniValue sendResult = SendTransaction(m_op->tx_, boost::none, m_op->testmode); + m_op->set_result(sendResult); return true; } @@ -294,73 +271,6 @@ bool ShieldToAddress::operator()(const libzcash::InvalidEncoding& no) const { } -/** - * Sign and send a raw transaction. - * Raw transaction as hex string should be in object field "rawtxn" - */ -void AsyncRPCOperation_shieldcoinbase::sign_send_raw_transaction(UniValue obj) -{ - // Sign the raw transaction - UniValue rawtxnValue = find_value(obj, "rawtxn"); - if (rawtxnValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction"); - } - std::string rawtxn = rawtxnValue.get_str(); - - UniValue params = UniValue(UniValue::VARR); - params.push_back(rawtxn); - UniValue signResultValue = signrawtransaction(params, false); - UniValue signResultObject = signResultValue.get_obj(); - UniValue completeValue = find_value(signResultObject, "complete"); - bool complete = completeValue.get_bool(); - if (!complete) { - // TODO: #1366 Maybe get "errors" and print array vErrors into a string - throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction"); - } - - UniValue hexValue = find_value(signResultObject, "hex"); - if (hexValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction"); - } - std::string signedtxn = hexValue.get_str(); - - // Send the signed transaction - if (!testmode) { - params.clear(); - params.setArray(); - params.push_back(signedtxn); - UniValue sendResultValue = sendrawtransaction(params, false); - if (sendResultValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Send raw transaction did not return an error or a txid."); - } - - std::string txid = sendResultValue.get_str(); - - UniValue o(UniValue::VOBJ); - o.push_back(Pair("txid", txid)); - set_result(o); - } else { - // Test mode does not send the transaction to the network. - - CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - - UniValue o(UniValue::VOBJ); - o.push_back(Pair("test", 1)); - o.push_back(Pair("txid", tx.GetHash().ToString())); - o.push_back(Pair("hex", signedtxn)); - set_result(o); - } - - // Keep the signed transaction so we can hash to the same txid - CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - tx_ = tx; -} - - UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInfo & info) { uint32_t consensusBranchId; uint256 anchor; @@ -392,7 +302,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", getId(), - tx_.vjoinsplit.size(), + tx_.vJoinSplit.size(), FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value) @@ -428,7 +338,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf } } - mtx.vjoinsplit.push_back(jsdesc); + mtx.vJoinSplit.push_back(jsdesc); // Empty output script. CScript scriptCode; @@ -494,7 +404,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer std::vector vch(&buffer[0], &buffer[0] + 32); uint256 joinSplitPrivKey = uint256(vch); - size_t js_index = tx_.vjoinsplit.size() - 1; + size_t js_index = tx_.vJoinSplit.size() - 1; uint256 placeholder; for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { uint8_t mapped_index = outputMap[i]; diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.h b/src/wallet/asyncrpcoperation_shieldcoinbase.h index 4311d84b3..c0a2fad5f 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.h +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.h @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ASYNCRPCOPERATION_SHIELDCOINBASE_H #define ASYNCRPCOPERATION_SHIELDCOINBASE_H @@ -87,8 +87,6 @@ class AsyncRPCOperation_shieldcoinbase : public AsyncRPCOperation { // JoinSplit without any input notes to spend UniValue perform_joinsplit(ShieldCoinbaseJSInfo &); - void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error - void lock_utxos(); void unlock_utxos(); @@ -137,10 +135,6 @@ class TEST_FRIEND_AsyncRPCOperation_shieldcoinbase { return delegate->perform_joinsplit(info); } - void sign_send_raw_transaction(UniValue obj) { - delegate->sign_send_raw_transaction(obj); - } - void set_state(OperationStatus state) { delegate->state_.store(state); } @@ -148,4 +142,3 @@ class TEST_FRIEND_AsyncRPCOperation_shieldcoinbase { #endif /* ASYNCRPCOPERATION_SHIELDCOINBASE_H */ - diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index cf87c01d4..3cd91abe4 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "crypter.h" diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index 1cfefe886..a5c11a527 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_WALLET_CRYPTER_H #define BITCOIN_WALLET_CRYPTER_H diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 7fe2c9b87..e0ef27e78 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "db.h" diff --git a/src/wallet/db.h b/src/wallet/db.h index 64071caa3..1ae5a03b5 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_WALLET_DB_H #define BITCOIN_WALLET_DB_H diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index 6d07bee38..b5b9a237a 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -188,7 +188,7 @@ TEST(WalletTests, FindUnspentSproutNotes) { EXPECT_FALSE(wallet.IsSproutSpent(nullifier)); // We currently have an unspent and unconfirmed note in the wallet (depth of -1) - std::vector sproutEntries; + std::vector sproutEntries; std::vector saplingEntries; wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 0); EXPECT_EQ(0, sproutEntries.size()); @@ -379,7 +379,7 @@ TEST(WalletTests, SetSaplingNoteAddrsInCWalletTx) { ASSERT_TRUE(nf); uint256 nullifier = nf.get(); - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); builder.AddSaplingSpend(expsk, note, anchor, witness); builder.AddSaplingOutput(fvk.ovk, pk, 50000, {}); builder.SetFee(0); @@ -451,11 +451,11 @@ TEST(WalletTests, CheckSproutNoteCommitmentAgainstNotePlaintext) { auto note = GetSproutNote(sk, wtx, 0, 1); auto nullifier = note.nullifier(sk); - auto hSig = wtx.vjoinsplit[0].h_sig( + auto hSig = wtx.vJoinSplit[0].h_sig( *params, wtx.joinSplitPubKey); ASSERT_THROW(wallet.GetSproutNoteNullifier( - wtx.vjoinsplit[0], + wtx.vJoinSplit[0], address, dec, hSig, 1), libzcash::note_decryption_failed); @@ -472,11 +472,11 @@ TEST(WalletTests, GetSproutNoteNullifier) { auto note = GetSproutNote(sk, wtx, 0, 1); auto nullifier = note.nullifier(sk); - auto hSig = wtx.vjoinsplit[0].h_sig( + auto hSig = wtx.vJoinSplit[0].h_sig( *params, wtx.joinSplitPubKey); auto ret = wallet.GetSproutNoteNullifier( - wtx.vjoinsplit[0], + wtx.vJoinSplit[0], address, dec, hSig, 1); @@ -485,7 +485,7 @@ TEST(WalletTests, GetSproutNoteNullifier) { wallet.AddSproutSpendingKey(sk); ret = wallet.GetSproutNoteNullifier( - wtx.vjoinsplit[0], + wtx.vJoinSplit[0], address, dec, hSig, 1); @@ -506,7 +506,7 @@ TEST(WalletTests, FindMySaplingNotes) { auto testNote = GetTestSaplingNote(pa, 50000); // Generate transaction - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness()); builder.AddSaplingOutput(fvk.ovk, pa, 25000, {}); auto tx = builder.Build().GetTxOrThrow(); @@ -638,7 +638,7 @@ TEST(WalletTests, GetConflictedSaplingNotes) { auto witness = saplingTree.witness(); // Generate tx to create output note B - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); builder.AddSaplingSpend(expsk, note, anchor, witness); builder.AddSaplingOutput(fvk.ovk, pk, 35000, {}); auto tx = builder.Build().GetTxOrThrow(); @@ -692,13 +692,13 @@ TEST(WalletTests, GetConflictedSaplingNotes) { anchor = saplingTree.root(); // Create transaction to spend note B - auto builder2 = TransactionBuilder(consensusParams, 2, expiryDelta); + auto builder2 = TransactionBuilder(consensusParams, 2); builder2.AddSaplingSpend(expsk, note2, anchor, spend_note_witness); builder2.AddSaplingOutput(fvk.ovk, pk, 20000, {}); auto tx2 = builder2.Build().GetTxOrThrow(); // Create conflicting transaction which also spends note B - auto builder3 = TransactionBuilder(consensusParams, 2, expiryDelta); + auto builder3 = TransactionBuilder(consensusParams, 2); builder3.AddSaplingSpend(expsk, note2, anchor, spend_note_witness); builder3.AddSaplingOutput(fvk.ovk, pk, 19999, {}); auto tx3 = builder3.Build().GetTxOrThrow(); @@ -785,7 +785,7 @@ TEST(WalletTests, SaplingNullifierIsSpent) { auto testNote = GetTestSaplingNote(pa, 50000); // Generate transaction - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness()); builder.AddSaplingOutput(fvk.ovk, pa, 25000, {}); auto tx = builder.Build().GetTxOrThrow(); @@ -868,7 +868,7 @@ TEST(WalletTests, NavigateFromSaplingNullifierToNote) { auto testNote = GetTestSaplingNote(pa, 50000); // Generate transaction - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness()); builder.AddSaplingOutput(fvk.ovk, pa, 25000, {}); auto tx = builder.Build().GetTxOrThrow(); @@ -996,7 +996,7 @@ TEST(WalletTests, SpentSaplingNoteIsFromMe) { auto witness = saplingTree.witness(); // Generate transaction, which sends funds to note B - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); builder.AddSaplingSpend(expsk, note, anchor, witness); builder.AddSaplingOutput(fvk.ovk, pk, 25000, {}); auto tx = builder.Build().GetTxOrThrow(); @@ -1066,13 +1066,13 @@ TEST(WalletTests, SpentSaplingNoteIsFromMe) { anchor = saplingTree.root(); // Create transaction to spend note B - auto builder2 = TransactionBuilder(consensusParams, 2, expiryDelta); + auto builder2 = TransactionBuilder(consensusParams, 2); builder2.AddSaplingSpend(expsk, note2, anchor, spend_note_witness); builder2.AddSaplingOutput(fvk.ovk, pk, 12500, {}); auto tx2 = builder2.Build().GetTxOrThrow(); EXPECT_EQ(tx2.vin.size(), 0); EXPECT_EQ(tx2.vout.size(), 0); - EXPECT_EQ(tx2.vjoinsplit.size(), 0); + EXPECT_EQ(tx2.vJoinSplit.size(), 0); EXPECT_EQ(tx2.vShieldedSpend.size(), 1); EXPECT_EQ(tx2.vShieldedOutput.size(), 2); EXPECT_EQ(tx2.valueBalance, 10000); @@ -1771,7 +1771,7 @@ TEST(WalletTests, UpdatedSaplingNoteData) { auto testNote = GetTestSaplingNote(pa, 50000); // Generate transaction - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta); + auto builder = TransactionBuilder(consensusParams, 1); builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness()); builder.AddSaplingOutput(fvk.ovk, pa2, 25000, {}); auto tx = builder.Build().GetTxOrThrow(); @@ -1912,14 +1912,14 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) { // Generate shielding tx from transparent to Sapling // 0.0005 t-ZEC in, 0.0004 z-ZEC out, 0.0001 t-ZEC fee - auto builder = TransactionBuilder(consensusParams, 1, expiryDelta, &keystore); + auto builder = TransactionBuilder(consensusParams, 1, &keystore); builder.AddTransparentInput(COutPoint(), scriptPubKey, 50000); builder.AddSaplingOutput(fvk.ovk, pk, 40000, {}); auto tx1 = builder.Build().GetTxOrThrow(); EXPECT_EQ(tx1.vin.size(), 1); EXPECT_EQ(tx1.vout.size(), 0); - EXPECT_EQ(tx1.vjoinsplit.size(), 0); + EXPECT_EQ(tx1.vJoinSplit.size(), 0); EXPECT_EQ(tx1.vShieldedSpend.size(), 0); EXPECT_EQ(tx1.vShieldedOutput.size(), 1); EXPECT_EQ(tx1.valueBalance, -40000); @@ -1967,14 +1967,14 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) { // Create a Sapling-only transaction // 0.0004 z-ZEC in, 0.00025 z-ZEC out, 0.0001 t-ZEC fee, 0.00005 z-ZEC change - auto builder2 = TransactionBuilder(consensusParams, 2, expiryDelta); + auto builder2 = TransactionBuilder(consensusParams, 2); builder2.AddSaplingSpend(expsk, note, anchor, witness); builder2.AddSaplingOutput(fvk.ovk, pk, 25000, {}); auto tx2 = builder2.Build().GetTxOrThrow(); EXPECT_EQ(tx2.vin.size(), 0); EXPECT_EQ(tx2.vout.size(), 0); - EXPECT_EQ(tx2.vjoinsplit.size(), 0); + EXPECT_EQ(tx2.vJoinSplit.size(), 0); EXPECT_EQ(tx2.vShieldedSpend.size(), 1); EXPECT_EQ(tx2.vShieldedOutput.size(), 2); EXPECT_EQ(tx2.valueBalance, 10000); diff --git a/src/wallet/paymentdisclosure.cpp b/src/wallet/paymentdisclosure.cpp index 5dd1e3d1b..ddce48cc2 100644 --- a/src/wallet/paymentdisclosure.cpp +++ b/src/wallet/paymentdisclosure.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "wallet/paymentdisclosure.h" diff --git a/src/wallet/paymentdisclosure.h b/src/wallet/paymentdisclosure.h index 28a1d4cdc..2233c8820 100644 --- a/src/wallet/paymentdisclosure.h +++ b/src/wallet/paymentdisclosure.h @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_PAYMENTDISCLOSURE_H #define ZCASH_PAYMENTDISCLOSURE_H @@ -74,7 +74,7 @@ struct PaymentDisclosurePayload { uint8_t version; // 0 = experimental, 1 = first production version, etc. uint256 esk; // zcash/NoteEncryption.cpp uint256 txid; // primitives/transaction.h - uint64_t js; // Index into CTransaction.vjoinsplit + uint64_t js; // Index into CTransaction.vJoinSplit uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS libzcash::SproutPaymentAddress zaddr; // zcash/Address.hpp std::string message; // parameter to RPC call diff --git a/src/wallet/paymentdisclosuredb.cpp b/src/wallet/paymentdisclosuredb.cpp index db7924fbb..21b489e3c 100644 --- a/src/wallet/paymentdisclosuredb.cpp +++ b/src/wallet/paymentdisclosuredb.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "wallet/paymentdisclosuredb.h" diff --git a/src/wallet/paymentdisclosuredb.h b/src/wallet/paymentdisclosuredb.h index 2ec5ad5e4..e4a797e45 100644 --- a/src/wallet/paymentdisclosuredb.h +++ b/src/wallet/paymentdisclosuredb.h @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_PAYMENTDISCLOSUREDB_H #define ZCASH_PAYMENTDISCLOSUREDB_H diff --git a/src/wallet/rpcdisclosure.cpp b/src/wallet/rpcdisclosure.cpp index df35bb6dd..6e1e4185a 100644 --- a/src/wallet/rpcdisclosure.cpp +++ b/src/wallet/rpcdisclosure.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "rpc/server.h" #include "init.h" @@ -82,7 +82,7 @@ UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp) uint256 hashBlock; // Check txid has been seen - if (!GetTransaction(hash, tx, hashBlock, true)) { + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); } @@ -98,13 +98,13 @@ UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp) const CWalletTx& wtx = pwalletMain->mapWallet[hash]; // Check if shielded tx - if (wtx.vjoinsplit.empty()) { - throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not a shielded transaction"); + if (wtx.vJoinSplit.empty()) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not a shielded transaction"); } // Check js_index int js_index = params[1].get_int(); - if (js_index < 0 || js_index >= wtx.vjoinsplit.size()) { + if (js_index < 0 || js_index >= wtx.vJoinSplit.size()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid js_index"); } @@ -195,7 +195,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) // too much data is ignored, but if not enough data, exception of type ios_base::failure is thrown, // CBaseDataStream::read(): end of data: iostream error } catch (const std::exception &e) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure data is malformed."); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure data is malformed."); } if (pd.payload.marker != PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES) { @@ -210,7 +210,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) CTransaction tx; uint256 hashBlock; // Check if we have seen the transaction - if (!GetTransaction(hash, tx, hashBlock, true)) { + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); } @@ -220,8 +220,8 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) } // Check if shielded tx - if (tx.vjoinsplit.empty()) { - throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not a shielded transaction"); + if (tx.vJoinSplit.empty()) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not a shielded transaction"); } UniValue errs(UniValue::VARR); @@ -229,7 +229,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) o.push_back(Pair("txid", pd.payload.txid.ToString())); // Check js_index - if (pd.payload.js >= tx.vjoinsplit.size()) { + if (pd.payload.js >= tx.vJoinSplit.size()) { errs.push_back("Payment disclosure refers to an invalid joinsplit index"); } o.push_back(Pair("jsIndex", pd.payload.js)); @@ -250,9 +250,9 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) tx.joinSplitPubKey.begin()) == 0); o.push_back(Pair("signatureVerified", sigVerified)); if (!sigVerified) { - errs.push_back("Payment disclosure signature does not match transaction signature"); + errs.push_back("Payment disclosure signature does not match transaction signature"); } - + // Check the payment address is valid SproutPaymentAddress zaddr = pd.payload.zaddr; { @@ -260,7 +260,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) try { // Decrypt the note to get value and memo field - JSDescription jsdesc = tx.vjoinsplit[pd.payload.js]; + JSDescription jsdesc = tx.vJoinSplit[pd.payload.js]; uint256 h_sig = jsdesc.h_sig(*pzcashParams, tx.joinSplitPubKey); ZCPaymentDisclosureNoteDecryption decrypter; @@ -278,7 +278,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) string memoHexString = HexStr(npt.memo().data(), npt.memo().data() + npt.memo().size()); o.push_back(Pair("memo", memoHexString)); o.push_back(Pair("value", ValueFromAmount(npt.value()))); - + // Check the blockchain commitment matches decrypted note commitment uint256 cm_blockchain = jsdesc.commitments[pd.payload.n]; SproutNote note = npt.note(zaddr); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 6b1df7e14..ac805be08 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "chain.h" #include "key_io.h" diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3588fee21..203a308ba 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "amount.h" #include "consensus/upgrades.h" @@ -105,7 +105,7 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue) entry.push_back(Pair(item.first, item.second)); - entry.push_back(Pair("vjoinsplit", TxJoinSplitToJSON(wtx))); + entry.push_back(Pair("vJoinSplit", TxJoinSplitToJSON(wtx))); } string AccountFromValue(const UniValue& value) @@ -419,7 +419,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n" + HelpRequiringPassphrase() + "\nArguments:\n" - "1. \"zcashaddress\" (string, required) The Zcash address to send to.\n" + "1. \"zcashaddress\" (string, required) The BitcoinZ address to send to.\n" "2. \"amount\" (numeric, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" @@ -900,7 +900,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp) + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" - "2. \"tozcashaddress\" (string, required) The Zcash address to send funds to.\n" + "2. \"tozcashaddress\" (string, required) The BitcoinZ address to send funds to.\n" "3. amount (numeric, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" @@ -967,7 +967,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) "1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n" " {\n" - " \"address\":amount (numeric) The Zcash address is the key, the numeric amount in " + CURRENCY_UNIT + " is the value\n" + " \"address\":amount (numeric) The BitcoinZ address is the key, the numeric amount in " + CURRENCY_UNIT + " is the value\n" " ,...\n" " }\n" "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" @@ -1741,7 +1741,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) " }\n" " ,...\n" " ],\n" - " \"vjoinsplit\" : [\n" + " \"vJoinSplit\" : [\n" " {\n" " \"anchor\" : \"treestateref\", (string) Merkle root of note commitment tree\n" " \"nullifiers\" : [ string, ... ] (string) Nullifiers of input notes\n" @@ -2359,7 +2359,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) " \"txid\" : \"txid\", (string) the transaction id \n" " \"vout\" : n, (numeric) the vout value\n" " \"generated\" : true|false (boolean) true if txout is a coinbase transaction output\n" - " \"address\" : \"address\", (string) the Zcash address\n" + " \"address\" : \"address\", (string) the BitcoinZ address\n" " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" " \"scriptPubKey\" : \"key\", (string) the script key\n" " \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n" @@ -2555,11 +2555,11 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) // User did not provide zaddrs, so use default i.e. all addresses std::set sproutzaddrs = {}; pwalletMain->GetSproutPaymentAddresses(sproutzaddrs); - + // Sapling support std::set saplingzaddrs = {}; pwalletMain->GetSaplingPaymentAddresses(saplingzaddrs); - + zaddrs.insert(sproutzaddrs.begin(), sproutzaddrs.end()); zaddrs.insert(saplingzaddrs.begin(), saplingzaddrs.end()); } @@ -2567,11 +2567,11 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) UniValue results(UniValue::VARR); if (zaddrs.size() > 0) { - std::vector sproutEntries; + std::vector sproutEntries; std::vector saplingEntries; pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, zaddrs, nMinDepth, nMaxDepth, true, !fIncludeWatchonly, false); std::set> nullifierSet = pwalletMain->GetNullifiersForAddresses(zaddrs); - + for (auto & entry : sproutEntries) { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("txid", entry.jsop.hash.ToString())); @@ -2581,15 +2581,15 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) bool hasSproutSpendingKey = pwalletMain->HaveSproutSpendingKey(boost::get(entry.address)); obj.push_back(Pair("spendable", hasSproutSpendingKey)); obj.push_back(Pair("address", EncodePaymentAddress(entry.address))); - obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value())))); - std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end()); + obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.note.value())))); + std::string data(entry.memo.begin(), entry.memo.end()); obj.push_back(Pair("memo", HexStr(data))); if (hasSproutSpendingKey) { obj.push_back(Pair("change", pwalletMain->IsNoteSproutChange(nullifierSet, entry.address, entry.jsop))); } results.push_back(obj); } - + for (auto & entry : saplingEntries) { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("txid", entry.op.hash.ToString())); @@ -3063,7 +3063,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp) assert(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey)); } - mtx.vjoinsplit.push_back(jsdesc); + mtx.vJoinSplit.push_back(jsdesc); // Empty output script. CScript scriptCode; @@ -3291,12 +3291,12 @@ CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1, bool ign CAmount getBalanceZaddr(std::string address, int minDepth = 1, bool ignoreUnspendable=true) { CAmount balance = 0; - std::vector sproutEntries; + std::vector sproutEntries; std::vector saplingEntries; LOCK2(cs_main, pwalletMain->cs_wallet); pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, address, minDepth, true, ignoreUnspendable); for (auto & entry : sproutEntries) { - balance += CAmount(entry.plaintext.value()); + balance += CAmount(entry.note.value()); } for (auto & entry : saplingEntries) { balance += CAmount(entry.note.value()); @@ -3356,7 +3356,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) } UniValue result(UniValue::VARR); - std::vector sproutEntries; + std::vector sproutEntries; std::vector saplingEntries; pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, fromaddress, nMinDepth, false, false); @@ -3367,11 +3367,11 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) } if (boost::get(&zaddr) != nullptr) { - for (CSproutNotePlaintextEntry & entry : sproutEntries) { + for (SproutNoteEntry & entry : sproutEntries) { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("txid", entry.jsop.hash.ToString())); - obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value())))); - std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end()); + obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.note.value())))); + std::string data(entry.memo.begin(), entry.memo.end()); obj.push_back(Pair("memo", HexStr(data))); obj.push_back(Pair("jsindex", entry.jsop.js)); obj.push_back(Pair("jsoutindex", entry.jsop.n)); @@ -3475,8 +3475,8 @@ UniValue z_gettotalbalance(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"transparent\": xxxxx, (numeric) the total balance of transparent funds\n" - " \"private\": xxxxx, (numeric) the total balance of private funds (in both Sprout and Sapling addresses)\n" - " \"total\": xxxxx, (numeric) the total balance of both transparent and private funds\n" + " \"private\": xxxxx, (numeric) the total balance of shielded funds (in both Sprout and Sapling addresses)\n" + " \"total\": xxxxx, (numeric) the total balance of both transparent and shielded funds\n" "}\n" "\nExamples:\n" "\nThe total amount in the wallet\n" @@ -3790,8 +3790,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID; mtx.nVersion = SAPLING_TX_VERSION; unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING; - if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { - if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + if (!Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_SAPLING)) { + if (Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_OVERWINTER)) { mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; mtx.nVersion = OVERWINTER_TX_VERSION; } else { @@ -3805,10 +3805,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) if (zaddrRecipients.size() > Z_SENDMANY_MAX_ZADDR_OUTPUTS_BEFORE_SAPLING) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, too many zaddr outputs"); } - } - - // If Sapling is not active, do not allow sending from or sending to Sapling addresses. - if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { + // If Sapling is not active, do not allow sending from or sending to Sapling addresses. if (fromSapling || containsSaplingOutput) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated"); } @@ -3828,7 +3825,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) if (mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION)) { jsdesc.proof = GrothProof(); } - mtx.vjoinsplit.push_back(jsdesc); + mtx.vJoinSplit.push_back(jsdesc); } } CTransaction tx(mtx); @@ -3888,7 +3885,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) // Builder (used if Sapling addresses are involved) boost::optional builder; if (noSproutAddrs) { - builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, expiryDelta, pwalletMain); + builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain); } // Contextual transaction we will build on @@ -3896,7 +3893,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextBlockHeight); bool isShielded = !fromTaddr || zaddrRecipients.size() > 0; if (contextualTx.nVersion == 1 && isShielded) { - contextualTx.nVersion = 2; // Tx format should support vjoinsplits + contextualTx.nVersion = 2; // Tx format should support vJoinSplits } // Create operation and add to global queue @@ -3937,9 +3934,8 @@ UniValue z_getmigrationstatus(const UniValue& params, bool fHelp) { throw runtime_error( "z_getmigrationstatus\n" "Returns information about the status of the Sprout to Sapling migration.\n" - "In the result a transactions is defined as finalized if and only if it has\n" - "at least ten confirmations.\n" - "Note: It is possible that manually created transactions involving this wallet\n" + "Note: A transaction is defined as finalized if it has at least ten confirmations.\n" + "Also, it is possible that manually created transactions involving this wallet\n" "will be included in the result.\n" "\nResult:\n" "{\n" @@ -3965,7 +3961,7 @@ UniValue z_getmigrationstatus(const UniValue& params, bool fHelp) { // account failed transactions, that were not mined within their expiration // height. { - std::vector sproutEntries; + std::vector sproutEntries; std::vector saplingEntries; std::set noFilter; // Here we are looking for any and all Sprout notes for which we have the spending key, including those @@ -3973,7 +3969,7 @@ UniValue z_getmigrationstatus(const UniValue& params, bool fHelp) { pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, noFilter, 0, INT_MAX, true, true, false); CAmount unmigratedAmount = 0; for (const auto& sproutEntry : sproutEntries) { - unmigratedAmount += sproutEntry.plaintext.value(); + unmigratedAmount += sproutEntry.note.value(); } migrationStatus.push_back(Pair("unmigrated_amount", FormatMoney(unmigratedAmount))); } @@ -3991,9 +3987,9 @@ UniValue z_getmigrationstatus(const UniValue& params, bool fHelp) { // * one or more Sprout JoinSplits with nonzero vpub_new field; and // * no Sapling Spends, and; // * one or more Sapling Outputs. - if (tx.vjoinsplit.size() > 0 && tx.vShieldedSpend.empty() && tx.vShieldedOutput.size() > 0) { + if (tx.vJoinSplit.size() > 0 && tx.vShieldedSpend.empty() && tx.vShieldedOutput.size() > 0) { bool nonZeroVPubNew = false; - for (const auto& js : tx.vjoinsplit) { + for (const auto& js : tx.vJoinSplit) { if (js.vpub_new > 0) { nonZeroVPubNew = true; break; @@ -4123,15 +4119,12 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) } int nextBlockHeight = chainActive.Height() + 1; - bool overwinterActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER); + bool overwinterActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_OVERWINTER); unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING; - if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { + if (!Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_SAPLING)) { max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING; - } - - // If Sapling is not active, do not allow sending to a Sapling address. - if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { auto res = DecodePaymentAddress(destaddress); + // If Sapling is not active, do not allow sending to a Sapling address. if (IsValidPaymentAddress(res)) { bool toSapling = boost::get(&res) != nullptr; if (toSapling) { @@ -4229,14 +4222,14 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) // Builder (used if Sapling addresses are involved) TransactionBuilder builder = TransactionBuilder( - Params().GetConsensus(), nextBlockHeight, expiryDelta, pwalletMain); + Params().GetConsensus(), nextBlockHeight, pwalletMain); // Contextual transaction we will build on // (used if no Sapling addresses are involved) CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction( Params().GetConsensus(), nextBlockHeight); if (contextualTx.nVersion == 1) { - contextualTx.nVersion = 2; // Tx format should support vjoinsplits + contextualTx.nVersion = 2; // Tx format should support vJoinSplits } // Create operation and add to global queue @@ -4298,7 +4291,9 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) " - \"ANY_TADDR\": Merge UTXOs from any taddrs belonging to the wallet.\n" " - \"ANY_SPROUT\": Merge notes from any Sprout zaddrs belonging to the wallet.\n" " - \"ANY_SAPLING\": Merge notes from any Sapling zaddrs belonging to the wallet.\n" - " If a special string is given, any given addresses of that type will be counted as duplicates and cause an error.\n" + " While it is possible to use a variety of different combinations of addresses and the above values,\n" + " it is not possible to send funds from both sprout and sapling addresses simultaneously. If a special\n" + " string is given, any given addresses of that type will be counted as duplicates and cause an error.\n" " [\n" " \"address\" (string) Can be a taddr or a zaddr\n" " ,...\n" @@ -4329,7 +4324,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) ); if (!fEnableMergeToAddress) { - throw JSONRPCError(RPC_WALLET_ERROR, "Error: z_mergetoaddress is disabled. Run './zcash-cli help z_mergetoaddress' for instructions on how to enable this feature."); + throw JSONRPCError(RPC_WALLET_ERROR, "Error: z_mergetoaddress is disabled. Run './bitcoinz-cli help z_mergetoaddress' for instructions on how to enable this feature."); } LOCK2(cs_main, pwalletMain->cs_wallet); @@ -4387,8 +4382,8 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) } const int nextBlockHeight = chainActive.Height() + 1; - const bool overwinterActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER); - const bool saplingActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING); + const bool overwinterActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_OVERWINTER); + const bool saplingActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_SAPLING); // Validate the destination address auto destaddress = params[1].get_str(); @@ -4525,7 +4520,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) if (useAnySprout || useAnySapling || zaddrs.size() > 0) { // Get available notes - std::vector sproutEntries; + std::vector sproutEntries; std::vector saplingEntries; pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, zaddrs); @@ -4533,8 +4528,15 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) if (!saplingActive && saplingEntries.size() > 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated"); } + // Do not include Sprout/Sapling notes if using "ANY_SAPLING"/"ANY_SPROUT" respectively + if (useAnySprout) { + saplingEntries.clear(); + } + if (useAnySapling) { + sproutEntries.clear(); + } // Sending from both Sprout and Sapling is currently unsupported using z_mergetoaddress - if (sproutEntries.size() > 0 && saplingEntries.size() > 0) { + if ((sproutEntries.size() > 0 && saplingEntries.size() > 0) || (useAnySprout && useAnySapling)) { throw JSONRPCError( RPC_INVALID_PARAMETER, "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress"); @@ -4547,9 +4549,9 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) } // Find unspent notes and update estimated size - for (const CSproutNotePlaintextEntry& entry : sproutEntries) { + for (const SproutNoteEntry& entry : sproutEntries) { noteCounter++; - CAmount nValue = entry.plaintext.value(); + CAmount nValue = entry.note.value(); if (!maxedOutNotesFlag) { // If we haven't added any notes yet and the merge is to a @@ -4564,7 +4566,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) auto zaddr = entry.address; SproutSpendingKey zkey; pwalletMain->GetSproutSpendingKey(zaddr, zkey); - sproutNoteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey); + sproutNoteInputs.emplace_back(entry.jsop, entry.note, nValue, zkey); mergedNoteValue += nValue; } } @@ -4640,13 +4642,13 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) nextBlockHeight); bool isSproutShielded = sproutNoteInputs.size() > 0 || isToSproutZaddr; if (contextualTx.nVersion == 1 && isSproutShielded) { - contextualTx.nVersion = 2; // Tx format should support vjoinsplit + contextualTx.nVersion = 2; // Tx format should support vJoinSplit } // Builder (used if Sapling addresses are involved) boost::optional builder; if (isToSaplingZaddr || saplingNoteInputs.size() > 0) { - builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, expiryDelta, pwalletMain); + builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain); } // Create operation and add to global queue std::shared_ptr q = getAsyncRPCQueue(); diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index a5de7e2de..fda75db17 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -1,6 +1,6 @@ // Copyright (c) 2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_WALLET_RPCWALLET_H #define BITCOIN_WALLET_RPCWALLET_H diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index a5bc52b8d..5807600b3 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "wallet/wallet.h" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 23030257a..4d035a52d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "wallet/wallet.h" @@ -36,8 +36,6 @@ using namespace std; using namespace libzcash; -extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); - /** * Settings */ @@ -157,7 +155,7 @@ SaplingPaymentAddress CWallet::GenerateNewSaplingZKey() return addr; } -// Add spending key to keystore +// Add spending key to keystore bool CWallet::AddSaplingZKey( const libzcash::SaplingExtendedSpendingKey &sk, const libzcash::SaplingPaymentAddress &defaultAddr) @@ -167,7 +165,7 @@ bool CWallet::AddSaplingZKey( if (!CCryptoKeyStore::AddSaplingSpendingKey(sk, defaultAddr)) { return false; } - + if (!fFileBacked) { return true; } @@ -176,7 +174,7 @@ bool CWallet::AddSaplingZKey( auto ivk = sk.expsk.full_viewing_key().in_viewing_key(); return CWalletDB(strWalletFile).WriteSaplingZKey(ivk, sk, mapSaplingZKeyMetadata[ivk]); } - + return true; } @@ -573,17 +571,17 @@ void CWallet::ChainTipAdded(const CBlockIndex *pindex, UpdateSaplingNullifierNoteMapForBlock(pblock); } -void CWallet::ChainTip(const CBlockIndex *pindex, +void CWallet::ChainTip(const CBlockIndex *pindex, const CBlock *pblock, SproutMerkleTree sproutTree, - SaplingMerkleTree saplingTree, + SaplingMerkleTree saplingTree, bool added) { if (added) { ChainTipAdded(pindex, pblock, sproutTree, saplingTree); // Prevent migration transactions from being created when node is syncing after launch, // and also when node wakes up from suspension/hibernation and incoming blocks are old. - if (!IsInitialBlockDownload() && + if (!IsInitialBlockDownload(Params()) && pblock->GetBlockTime() > GetAdjustedTime() - 3 * 60 * 60) { RunSaplingMigration(pindex->nHeight); @@ -595,7 +593,7 @@ void CWallet::ChainTip(const CBlockIndex *pindex, } void CWallet::RunSaplingMigration(int blockHeight) { - if (!NetworkUpgradeActive(blockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { + if (!Params().GetConsensus().NetworkUpgradeActive(blockHeight, Consensus::UPGRADE_SAPLING)) { return; } LOCK(cs_wallet); @@ -625,16 +623,9 @@ void CWallet::RunSaplingMigration(int blockHeight) { lastOperation->cancel(); } for (const CTransaction& transaction : pendingSaplingMigrationTxs) { - // The following is taken from z_sendmany/z_mergetoaddress // Send the transaction - // TODO: Use CWallet::CommitTransaction instead of sendrawtransaction - auto signedtxn = EncodeHexTx(transaction); - UniValue params = UniValue(UniValue::VARR); - params.push_back(signedtxn); - UniValue sendResultValue = sendrawtransaction(params, false); - if (sendResultValue.isNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, "sendrawtransaction did not return an error or a txid."); - } + CWalletTx wtx(this, transaction); + CommitTransaction(wtx, boost::none); } pendingSaplingMigrationTxs.clear(); } @@ -705,7 +696,7 @@ bool CWallet::IsNoteSproutChange( // - Notes created by consolidation transactions (e.g. using // z_mergetoaddress). // - Notes sent from one address to itself. - for (const JSDescription & jsd : mapWallet[jsop.hash].vjoinsplit) { + for (const JSDescription & jsd : mapWallet[jsop.hash].vJoinSplit) { for (const uint256 & nullifier : jsd.nullifiers) { if (nullifierSet.count(std::make_pair(address, nullifier))) { return true; @@ -797,7 +788,7 @@ set CWallet::GetConflicts(const uint256& txid) const std::pair range_n; - for (const JSDescription& jsdesc : wtx.vjoinsplit) { + for (const JSDescription& jsdesc : wtx.vJoinSplit) { for (const uint256& nullifier : jsdesc.nullifiers) { if (mapTxSproutNullifiers.count(nullifier) <= 1) { continue; // No conflict if zero or one spends @@ -1004,7 +995,7 @@ void CWallet::AddToSpends(const uint256& wtxid) for (const CTxIn& txin : thisTx.vin) { AddToTransparentSpends(txin.prevout, wtxid); } - for (const JSDescription& jsdesc : thisTx.vjoinsplit) { + for (const JSDescription& jsdesc : thisTx.vJoinSplit) { for (const uint256& nullifier : jsdesc.nullifiers) { AddToSproutSpends(nullifier, wtxid); } @@ -1134,7 +1125,7 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex, const CBlock* pblock {pblockIn}; CBlock block; if (!pblock) { - ReadBlockFromDisk(block, pindex); + ReadBlockFromDisk(block, pindex, Params().GetConsensus()); pblock = █ } @@ -1142,8 +1133,8 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex, auto hash = tx.GetHash(); bool txIsOurs = mapWallet.count(hash); // Sprout - for (size_t i = 0; i < tx.vjoinsplit.size(); i++) { - const JSDescription& jsdesc = tx.vjoinsplit[i]; + for (size_t i = 0; i < tx.vJoinSplit.size(); i++) { + const JSDescription& jsdesc = tx.vJoinSplit[i]; for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) { const uint256& note_commitment = jsdesc.commitments[j]; sproutTree.append(note_commitment); @@ -1207,7 +1198,7 @@ void DecrementNoteWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t n if (nd->witnesses.size() > 0) { nd->witnesses.pop_front(); } - // indexHeight is the height of the block being removed, so + // indexHeight is the height of the block being removed, so // the new witness cache height is one below it. nd->witnessHeight = indexHeight - 1; } @@ -1400,10 +1391,10 @@ bool CWallet::UpdateNullifierNoteMap() if (!item.second.nullifier) { if (GetNoteDecryptor(item.second.address, dec)) { auto i = item.first.js; - auto hSig = wtxItem.second.vjoinsplit[i].h_sig( + auto hSig = wtxItem.second.vJoinSplit[i].h_sig( *pzcashParams, wtxItem.second.joinSplitPubKey); item.second.nullifier = GetSproutNoteNullifier( - wtxItem.second.vjoinsplit[i], + wtxItem.second.vJoinSplit[i], item.second.address, dec, hSig, @@ -1665,9 +1656,16 @@ bool CWallet::UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx) } /** - * Add a transaction to the wallet, or update it. - * pblock is optional, but should be provided if the transaction is known to be in a block. - * If fUpdate is true, existing transactions will be updated. + * Add a transaction to the wallet, or update it. + * pblock is optional, but should be provided if the transaction is known to be in a block. + * If fUpdate is true, existing transactions will be updated. + * + * If pblock is null, this transaction has either recently entered the mempool from the + * network, is re-entering the mempool after a block was disconnected, or is exiting the + * mempool because it conflicts with another transaction. In all these cases, if there is + * an existing wallet transaction, the wallet transaction's Merkle branch data is _not_ + * updated; instead, the transaction being in the mempool or conflicted is determined on + * the fly in CMerkleTx::GetDepthInMainChain(). */ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate) { @@ -1712,7 +1710,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock) { - LOCK2(cs_main, cs_wallet); + LOCK(cs_wallet); if (!AddToWalletIfInvolvingMe(tx, pblock, true)) return; // Not one of ours @@ -1729,7 +1727,7 @@ void CWallet::MarkAffectedTransactionsDirty(const CTransaction& tx) if (mapWallet.count(txin.prevout.hash)) mapWallet[txin.prevout.hash].MarkDirty(); } - for (const JSDescription& jsdesc : tx.vjoinsplit) { + for (const JSDescription& jsdesc : tx.vJoinSplit) { for (const uint256& nullifier : jsdesc.nullifiers) { if (mapSproutNullifiersToNotes.count(nullifier) && mapWallet.count(mapSproutNullifiersToNotes[nullifier].hash)) { @@ -1808,15 +1806,15 @@ mapSproutNoteData_t CWallet::FindMySproutNotes(const CTransaction &tx) const uint256 hash = tx.GetHash(); mapSproutNoteData_t noteData; - for (size_t i = 0; i < tx.vjoinsplit.size(); i++) { - auto hSig = tx.vjoinsplit[i].h_sig(*pzcashParams, tx.joinSplitPubKey); - for (uint8_t j = 0; j < tx.vjoinsplit[i].ciphertexts.size(); j++) { + for (size_t i = 0; i < tx.vJoinSplit.size(); i++) { + auto hSig = tx.vJoinSplit[i].h_sig(*pzcashParams, tx.joinSplitPubKey); + for (uint8_t j = 0; j < tx.vJoinSplit[i].ciphertexts.size(); j++) { for (const NoteDecryptorMap::value_type& item : mapNoteDecryptors) { try { auto address = item.first; JSOutPoint jsoutpt {hash, i, j}; auto nullifier = GetSproutNoteNullifier( - tx.vjoinsplit[i], + tx.vJoinSplit[i], address, item.second, hSig, j); @@ -2047,7 +2045,7 @@ bool CWallet::IsFromMe(const CTransaction& tx) const if (GetDebit(tx, ISMINE_ALL) > 0) { return true; } - for (const JSDescription& jsdesc : tx.vjoinsplit) { + for (const JSDescription& jsdesc : tx.vJoinSplit) { for (const uint256& nullifier : jsdesc.nullifiers) { if (IsSproutNullifierFromMe(nullifier)) { return true; @@ -2196,8 +2194,8 @@ void CWalletTx::SetSproutNoteData(mapSproutNoteData_t ¬eData) { mapSproutNoteData.clear(); for (const std::pair nd : noteData) { - if (nd.first.js < vjoinsplit.size() && - nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) { + if (nd.first.js < vJoinSplit.size() && + nd.first.n < vJoinSplit[nd.first.js].ciphertexts.size()) { // Store the address and nullifier for the Note mapSproutNoteData[nd.first] = nd.second; } else { @@ -2289,7 +2287,7 @@ void CWalletTx::GetAmounts(list& listReceived, if (isFromMyTaddr) { CAmount myVpubOld = 0; CAmount myVpubNew = 0; - for (const JSDescription& js : vjoinsplit) { + for (const JSDescription& js : vJoinSplit) { bool fMyJSDesc = false; // Check input side @@ -2303,7 +2301,7 @@ void CWalletTx::GetAmounts(list& listReceived, // Check output side if (!fMyJSDesc) { for (const std::pair nd : this->mapSproutNoteData) { - if (nd.first.js < vjoinsplit.size() && nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) { + if (nd.first.js < vJoinSplit.size() && nd.first.n < vJoinSplit[nd.first.js].ciphertexts.size()) { fMyJSDesc = true; break; } @@ -2432,11 +2430,11 @@ void CWallet::WitnessNoteCommitment(std::vector commitments, while (pindex) { CBlock block; - ReadBlockFromDisk(block, pindex); + ReadBlockFromDisk(block, pindex, Params().GetConsensus()); BOOST_FOREACH(const CTransaction& tx, block.vtx) { - BOOST_FOREACH(const JSDescription& jsdesc, tx.vjoinsplit) + BOOST_FOREACH(const JSDescription& jsdesc, tx.vJoinSplit) { BOOST_FOREACH(const uint256 ¬e_commitment, jsdesc.commitments) { @@ -2511,7 +2509,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100)))); CBlock block; - ReadBlockFromDisk(block, pindex); + ReadBlockFromDisk(block, pindex, Params().GetConsensus()); BOOST_FOREACH(CTransaction& tx, block.vtx) { if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) { @@ -2526,7 +2524,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) // state on the path to the tip of our chain assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, sproutTree)); if (pindex->pprev) { - if (NetworkUpgradeActive(pindex->pprev->nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { + if (Params().GetConsensus().NetworkUpgradeActive(pindex->pprev->nHeight, Consensus::UPGRADE_SAPLING)) { assert(pcoinsTip->GetSaplingAnchorAt(pindex->pprev->hashFinalSaplingRoot, saplingTree)); } } @@ -3303,7 +3301,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt Params().GetConsensus(), nextBlockHeight); // Activates after Overwinter network upgrade - if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + if (Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_OVERWINTER)) { if (txNew.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD){ strFailReason = _("nExpiryHeight must be less than TX_EXPIRY_HEIGHT_THRESHOLD."); return false; @@ -3311,7 +3309,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt } unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING; - if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { + if (!Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_SAPLING)) { max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING; } @@ -3502,7 +3500,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); { LOCK(cs_main); - if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + if (Params().GetConsensus().NetworkUpgradeActive(chainActive.Height() + 1, Consensus::UPGRADE_OVERWINTER)) { limit = 0; } } @@ -3601,7 +3599,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt /** * Call after CreateTransaction unless you want to abort */ -bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) +bool CWallet::CommitTransaction(CWalletTx& wtxNew, boost::optional reservekey) { { LOCK2(cs_main, cs_wallet); @@ -3612,8 +3610,10 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) // maybe makes sense; please don't do it anywhere else. CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL; - // Take key pair from key pool so it won't be used again - reservekey.KeepKey(); + if (reservekey) { + // Take key pair from key pool so it won't be used again + reservekey.get().KeepKey(); + } // Add tx to wallet, because if it has change it's also ours, // otherwise just for transaction history. @@ -4394,9 +4394,8 @@ CWalletKey::CWalletKey(int64_t nExpires) nTimeExpires = nExpires; } -int CMerkleTx::SetMerkleBranch(const CBlock& block) +void CMerkleTx::SetMerkleBranch(const CBlock& block) { - AssertLockHeld(cs_main); CBlock blockTmp; // Update the tx's hashBlock @@ -4411,21 +4410,10 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) vMerkleBranch.clear(); nIndex = -1; LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n"); - return 0; } // Fill in merkle branch vMerkleBranch = block.GetMerkleBranch(nIndex); - - // Is the tx in a block that's in the main chain - BlockMap::iterator mi = mapBlockIndex.find(hashBlock); - if (mi == mapBlockIndex.end()) - return 0; - const CBlockIndex* pindex = (*mi).second; - if (!pindex || !chainActive.Contains(pindex)) - return 0; - - return chainActive.Height() - pindex->nHeight + 1; } int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const @@ -4483,7 +4471,7 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) * These notes are decrypted and added to the output parameter vector, outEntries. */ void CWallet::GetFilteredNotes( - std::vector& sproutEntries, + std::vector& sproutEntries, std::vector& saplingEntries, std::string address, int minDepth, @@ -4500,12 +4488,12 @@ void CWallet::GetFilteredNotes( } /** - * Find notes in the wallet filtered by payment addresses, min depth, max depth, + * Find notes in the wallet filtered by payment addresses, min depth, max depth, * if the note is spent, if a spending key is required, and if the notes are locked. * These notes are decrypted and added to the output parameter vector, outEntries. */ void CWallet::GetFilteredNotes( - std::vector& sproutEntries, + std::vector& sproutEntries, std::vector& saplingEntries, std::set& filterAddresses, int minDepth, @@ -4552,7 +4540,7 @@ void CWallet::GetFilteredNotes( continue; } - int i = jsop.js; // Index into CTransaction.vjoinsplit + int i = jsop.js; // Index into CTransaction.vJoinSplit int j = jsop.n; // Index into JSDescription.ciphertexts // Get cached decryptor @@ -4563,16 +4551,17 @@ void CWallet::GetFilteredNotes( } // determine amount of funds in the note - auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey); + auto hSig = wtx.vJoinSplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey); try { SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt( decryptor, - wtx.vjoinsplit[i].ciphertexts[j], - wtx.vjoinsplit[i].ephemeralKey, + wtx.vJoinSplit[i].ciphertexts[j], + wtx.vJoinSplit[i].ephemeralKey, hSig, (unsigned char) j); - sproutEntries.push_back(CSproutNotePlaintextEntry{jsop, pa, plaintext, wtx.GetDepthInMainChain()}); + sproutEntries.push_back(SproutNoteEntry { + jsop, pa, plaintext.note(pa), plaintext.memo(), wtx.GetDepthInMainChain() }); } catch (const note_decryption_failed &err) { // Couldn't decrypt with this spending key @@ -4752,10 +4741,10 @@ SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingE m_wallet->mapSaplingZKeyMetadata[ivk].seedFp = seedFp; } return KeyAdded; - } + } } } -SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::InvalidEncoding& no) const { +SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::InvalidEncoding& no) const { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key"); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index fa1370111..449f06166 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_WALLET_WALLET_H #define BITCOIN_WALLET_WALLET_H @@ -167,7 +167,7 @@ class JSOutPoint public: // Transaction hash uint256 hash; - // Index into CTransaction.vjoinsplit + // Index into CTransaction.vJoinSplit uint64_t js; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS uint8_t n; @@ -312,12 +312,13 @@ class SaplingNoteData typedef std::map mapSproutNoteData_t; typedef std::map mapSaplingNoteData_t; -/** Decrypted note, its location in a transaction, and number of confirmations. */ -struct CSproutNotePlaintextEntry +/** Sprout note, its location in a transaction, and number of confirmations. */ +struct SproutNoteEntry { JSOutPoint jsop; libzcash::SproutPaymentAddress address; - libzcash::SproutNotePlaintext plaintext; + libzcash::SproutNote note; + std::array memo; int confirmations; }; @@ -373,7 +374,7 @@ class CMerkleTx : public CTransaction READWRITE(nIndex); } - int SetMerkleBranch(const CBlock& block); + void SetMerkleBranch(const CBlock& block); /** @@ -389,7 +390,7 @@ class CMerkleTx : public CTransaction bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true); }; -/** +/** * A transaction with a bunch of additional info that only the owner cares about. * It includes any unrecorded transactions needed to link it back to the block chain. */ @@ -404,11 +405,11 @@ class CWalletTx : public CMerkleTx mapSaplingNoteData_t mapSaplingNoteData; std::vector > vOrderForm; unsigned int fTimeReceivedIsTxTime; - unsigned int nTimeReceived; //! time received by this node + unsigned int nTimeReceived; //!< time received by this node unsigned int nTimeSmart; char fFromMe; std::string strFromAccount; - int64_t nOrderPos; //! position in ordered transaction list + int64_t nOrderPos; //!< position in ordered transaction list // memory only mutable bool fDebitCached; @@ -502,7 +503,7 @@ class CWalletTx : public CMerkleTx } READWRITE(*(CMerkleTx*)this); - std::vector vUnused; //! Used to be vtxPrev + std::vector vUnused; //!< Used to be vtxPrev READWRITE(vUnused); READWRITE(mapValue); READWRITE(mapSproutNoteData); @@ -648,7 +649,7 @@ class CAccountingEntry std::string strOtherAccount; std::string strComment; mapValue_t mapValue; - int64_t nOrderPos; //! position in ordered transaction list + int64_t nOrderPos; //!< position in ordered transaction list uint64_t nEntryNo; CAccountingEntry() @@ -718,7 +719,7 @@ class CAccountingEntry }; -/** +/** * A CWallet is an extension of a keystore, which also maintains a set of transactions and balances, * and provides the ability to create new transactions. */ @@ -1095,7 +1096,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool LoadCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector &vchCryptedSecret); - /** + /** * Increment the next transaction order id * @return next transaction order id */ @@ -1137,7 +1138,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason); bool CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true); - bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); + bool CommitTransaction(CWalletTx& wtxNew, boost::optional reservekey); static CFeeRate minTxFee; static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); @@ -1222,7 +1223,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface LOCK(cs_wallet); mapRequestCount[hash] = 0; }; - + unsigned int GetKeyPoolSize() { AssertLockHeld(cs_wallet); // setKeyPool @@ -1248,8 +1249,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface //! Verify the wallet database and perform salvage if required static bool Verify(const std::string& walletFile, std::string& warningString, std::string& errorString); - - /** + + /** * Address book entry changed. * @note called with lock cs_wallet held. */ @@ -1258,7 +1259,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface const std::string &purpose, ChangeType status)> NotifyAddressBookChanged; - /** + /** * Wallet transaction added, removed or updated. * @note called with lock cs_wallet held. */ @@ -1299,9 +1300,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool LoadHDSeed(const HDSeed& key); /* Set the current encrypted HD seed, without saving it to disk (used by LoadWallet) */ bool LoadCryptedHDSeed(const uint256& seedFp, const std::vector& seed); - + /* Find notes filtered by payment address, min depth, ability to spend */ - void GetFilteredNotes(std::vector& sproutEntries, + void GetFilteredNotes(std::vector& sproutEntries, std::vector& saplingEntries, std::string address, int minDepth=1, @@ -1310,7 +1311,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface /* Find notes filtered by payment addresses, min depth, max depth, if they are spent, if a spending key is required, and if they are locked */ - void GetFilteredNotes(std::vector& sproutEntries, + void GetFilteredNotes(std::vector& sproutEntries, std::vector& saplingEntries, std::set& filterAddresses, int minDepth=1, @@ -1346,7 +1347,7 @@ class CReserveKey : public CReserveScript }; -/** +/** * Account information. * Stored in wallet with key "acc"+string account name. */ @@ -1431,7 +1432,7 @@ class AddSpendingKeyToWallet : public boost::static_visitor hdKeypath; // currently sapling only boost::optional seedFpStr; // currently sapling only bool log; -public: +public: AddSpendingKeyToWallet(CWallet *wallet, const Consensus::Params ¶ms) : m_wallet(wallet), params(params), nTime(1), hdKeypath(boost::none), seedFpStr(boost::none), log(false) {} AddSpendingKeyToWallet( @@ -1446,7 +1447,7 @@ class AddSpendingKeyToWallet : public boost::static_visitor& vTxHash, vector& vWtx) +DBErrors CWalletDB::FindWalletTxToZap(CWallet* pwallet, vector& vTxHash, vector& vWtx) { pwallet->vchDefaultKey = CPubKey(); bool fNoncriticalErrors = false; @@ -1050,7 +1050,7 @@ DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet, vector& vWtx) { // build list of wallet TXs vector vTxHash; - DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx); + DBErrors err = FindWalletTxToZap(pwallet, vTxHash, vWtx); if (err != DB_LOAD_OK) return err; diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index b3210bbc0..94ebc0c75 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_WALLET_WALLETDB_H #define BITCOIN_WALLET_WALLETDB_H @@ -172,7 +172,7 @@ class CWalletDB : public CDB DBErrors ReorderTransactions(CWallet* pwallet); DBErrors LoadWallet(CWallet* pwallet); - DBErrors FindWalletTx(CWallet* pwallet, std::vector& vTxHash, std::vector& vWtx); + DBErrors FindWalletTxToZap(CWallet* pwallet, std::vector& vTxHash, std::vector& vWtx); DBErrors ZapWalletTx(CWallet* pwallet, std::vector& vWtx); static bool Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys); static bool Recover(CDBEnv& dbenv, const std::string& filename); diff --git a/src/zcash/Note.cpp b/src/zcash/Note.cpp index ee8f7b641..23210c784 100644 --- a/src/zcash/Note.cpp +++ b/src/zcash/Note.cpp @@ -173,15 +173,21 @@ boost::optional SaplingOutgoingPlaintext::decrypt( } // Deserialize from the plaintext - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << pt.get(); + try { + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << pt.get(); - SaplingOutgoingPlaintext ret; - ss >> ret; + SaplingOutgoingPlaintext ret; + ss >> ret; - assert(ss.size() == 0); + assert(ss.size() == 0); - return ret; + return ret; + } catch (const boost::thread_interrupted&) { + throw; + } catch (...) { + return boost::none; + } } boost::optional SaplingNotePlaintext::decrypt( @@ -197,13 +203,17 @@ boost::optional SaplingNotePlaintext::decrypt( } // Deserialize from the plaintext - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << pt.get(); - SaplingNotePlaintext ret; - ss >> ret; - - assert(ss.size() == 0); + try { + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << pt.get(); + ss >> ret; + assert(ss.size() == 0); + } catch (const boost::thread_interrupted&) { + throw; + } catch (...) { + return boost::none; + } uint256 pk_d; if (!librustzcash_ivk_to_pkd(ivk.begin(), ret.d.data(), pk_d.begin())) { @@ -243,11 +253,17 @@ boost::optional SaplingNotePlaintext::decrypt( } // Deserialize from the plaintext - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << pt.get(); - SaplingNotePlaintext ret; - ss >> ret; + try { + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << pt.get(); + ss >> ret; + assert(ss.size() == 0); + } catch (const boost::thread_interrupted&) { + throw; + } catch (...) { + return boost::none; + } uint256 cmu_expected; if (!librustzcash_sapling_compute_cm( @@ -265,8 +281,6 @@ boost::optional SaplingNotePlaintext::decrypt( return boost::none; } - assert(ss.size() == 0); - return ret; } diff --git a/src/zcash/zip32.cpp b/src/zcash/zip32.cpp index 15478843e..5733bd351 100644 --- a/src/zcash/zip32.cpp +++ b/src/zcash/zip32.cpp @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "zip32.h" diff --git a/src/zcash/zip32.h b/src/zcash/zip32.h index 44bc58598..8a958cb38 100644 --- a/src/zcash/zip32.h +++ b/src/zcash/zip32.h @@ -1,6 +1,6 @@ // 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. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef ZCASH_ZIP32_H #define ZCASH_ZIP32_H diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 5a94d40a2..be8c84a8e 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -173,6 +173,7 @@ double benchmark_solve_equihash() CEquihashInput I{pblock}; CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << I; + auto params = Params(CBaseChainParams::MAIN).GetConsensus(); unsigned int n = 200; unsigned int k = 9; @@ -219,11 +220,11 @@ std::vector benchmark_solve_equihash_threaded(int nThreads) double benchmark_verify_equihash() { CChainParams params = Params(CBaseChainParams::MAIN); - CBlock genesis = Params(CBaseChainParams::MAIN).GenesisBlock(); + CBlock genesis = params.GenesisBlock(); CBlockHeader genesis_header = genesis.GetBlockHeader(); struct timeval tv_start; timer_start(tv_start); - CheckEquihashSolution(&genesis_header, params); + CheckEquihashSolution(&genesis_header, params.GetConsensus()); return timer_stop(tv_start); } @@ -557,7 +558,7 @@ double benchmark_connectblock_slow() CValidationState state; struct timeval tv_start; timer_start(tv_start); - assert(ConnectBlock(block, state, &index, view, true)); + assert(ConnectBlock(block, state, &index, view, Params(), true)); auto duration = timer_stop(tv_start); // Undo alterations to global state diff --git a/src/zmq/zmqabstractnotifier.cpp b/src/zmq/zmqabstractnotifier.cpp index 3562a8824..3e9c48672 100644 --- a/src/zmq/zmqabstractnotifier.cpp +++ b/src/zmq/zmqabstractnotifier.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "zmqabstractnotifier.h" #include "util.h" diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h index 8873b71d8..2ef35bd4f 100644 --- a/src/zmq/zmqabstractnotifier.h +++ b/src/zmq/zmqabstractnotifier.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H #define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H diff --git a/src/zmq/zmqconfig.h b/src/zmq/zmqconfig.h index 6057f5d1a..b88fcc4f4 100644 --- a/src/zmq/zmqconfig.h +++ b/src/zmq/zmqconfig.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_ZMQ_ZMQCONFIG_H #define BITCOIN_ZMQ_ZMQCONFIG_H diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 0d8c36ad2..e427e6b97 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "zmqnotificationinterface.h" #include "zmqpublishnotifier.h" diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index e0fe3b570..1dc7211d5 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H #define BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 4567f25b1..a2a6758ca 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -1,7 +1,8 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . +#include "chainparams.h" #include "zmqpublishnotifier.h" #include "main.h" #include "util.h" @@ -164,11 +165,12 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { LogPrint("zmq", "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); + const Consensus::Params& consensusParams = Params().GetConsensus(); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); { LOCK(cs_main); CBlock block; - if(!ReadBlockFromDisk(block, pindex)) + if(!ReadBlockFromDisk(block, pindex, consensusParams)) { zmqError("Can't read block from disk"); return false; diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index 627c8af96..3a5a6986e 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -1,6 +1,6 @@ // Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H #define BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H diff --git a/zcutil/fetch-params.sh b/zcutil/fetch-params.sh index 1c1bec5fb..eb97402c3 100755 --- a/zcutil/fetch-params.sh +++ b/zcutil/fetch-params.sh @@ -13,7 +13,7 @@ SPROUT_VKEY_NAME='sprout-verifying.key' SAPLING_SPEND_NAME='sapling-spend.params' SAPLING_OUTPUT_NAME='sapling-output.params' SAPLING_SPROUT_GROTH16_NAME='sprout-groth16.params' -SPROUT_URL="https://z.cash/downloads" +SPROUT_URL="https://download.z.cash/downloads" SPROUT_IPFS="/ipfs/QmZKKx7Xup7LiAtFRhYsE1M7waXcv9ir9eCECyXAFGxhEo" SHA256CMD="$(command -v sha256sum || echo shasum)" @@ -107,13 +107,27 @@ function fetch_params { if ! [ -f "$output" ] then - for method in wget ipfs curl failure; do - if "fetch_$method" "$filename" "$dlname"; then - echo "Download successful!" - break + for i in 1 2 + do + for method in wget ipfs curl failure; do + if "fetch_$method" "${filename}.part.${i}" "${dlname}.part.${i}"; then + echo "Download of part ${i} successful!" + break + fi + done + done + + for i in 1 2 + do + if ! [ -f "${dlname}.part.${i}" ] + then + fetch_failure fi done + cat "${dlname}.part.1" "${dlname}.part.2" > "${dlname}" + rm "${dlname}.part.1" "${dlname}.part.2" + "$SHA256CMD" $SHA256ARGS -c <