diff options
265 files changed, 4239 insertions, 2266 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f5d63517b1..4e67af6278 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -170,13 +170,13 @@ judge the general consensus of contributors. In general, all pull requests must: - - have a clear use case, fix a demonstrable bug or serve the greater good of + - Have a clear use case, fix a demonstrable bug or serve the greater good of the project (for example refactoring for modularisation); - - be well peer reviewed; - - have unit tests and functional tests where appropriate; - - follow code style guidelines; - - not break the existing test suite; - - where bugs are fixed, where possible, there should be unit tests + - Be well peer reviewed; + - Have unit tests and functional tests where appropriate; + - Follow code style guidelines; + - Not break the existing test suite; + - Where bugs are fixed, where possible, there should be unit tests demonstrating the bug and also proving the fix. This helps prevent regression. Patches that change Bitcoin consensus rules are considerably more involved than diff --git a/configure.ac b/configure.ac index fd1396fc9e..e5ed938947 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 14) +define(_CLIENT_VERSION_MINOR, 15) define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) @@ -1261,7 +1261,7 @@ if test x$need_bundled_univalue = xyes; then AC_CONFIG_SUBDIRS([src/univalue]) fi -ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery" +ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery --disable-jni" AC_CONFIG_SUBDIRS([src/secp256k1]) AC_OUTPUT diff --git a/contrib/README.md b/contrib/README.md index 6f750106e4..34c4cfc55a 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -35,7 +35,7 @@ PGP keys used for signing Bitcoin Core [Gitian release](/doc/release-process.md) Scripts and notes for Mac builds. ### [RPM](/contrib/rpm) ### -RPM spec file for building bitcoin-core on RPM based distributions +RPM spec file for building bitcoin-core on RPM based distributions. ### [Gitian-build](/contrib/gitian-build.sh) ### Script for running full Gitian builds. diff --git a/contrib/bitcoind.bash-completion b/contrib/bitcoind.bash-completion index af87e97d80..cccd4bde0d 100644 --- a/contrib/bitcoind.bash-completion +++ b/contrib/bitcoind.bash-completion @@ -30,7 +30,7 @@ _bitcoind() { ;; *) - # only parse -help if senseful + # only parse -help if sensible if [[ -z "$cur" || "$cur" =~ ^- ]]; then local helpopts helpopts=$($bitcoind -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) diff --git a/contrib/debian/examples/bitcoin.conf b/contrib/debian/examples/bitcoin.conf index 1029a51073..14a59fdf6b 100644 --- a/contrib/debian/examples/bitcoin.conf +++ b/contrib/debian/examples/bitcoin.conf @@ -76,7 +76,7 @@ #rpcuser=Ulysseys #rpcpassword=YourSuperGreatPasswordNumber_DO_NOT_USE_THIS_OR_YOU_WILL_GET_ROBBED_385593 # -# The second method `rpcauth` can be added to server startup argument. It is set at intialization time +# The second method `rpcauth` can be added to server startup argument. It is set at initialization time # using the output from the script in share/rpcuser/rpcuser.py after providing a username: # # ./share/rpcuser/rpcuser.py alice diff --git a/contrib/gitian-build.sh b/contrib/gitian-build.sh index 6ee5df4703..d94c7f4f8e 100755 --- a/contrib/gitian-build.sh +++ b/contrib/gitian-build.sh @@ -40,15 +40,15 @@ version Version number, commit, or branch to build. If building a commit or bra Options: -c|--commit Indicate that the version argument is for a commit or branch -u|--url Specify the URL of the repository. Default is https://github.com/bitcoin/bitcoin --v|--verify Verify the gitian build --b|--build Do a gitian build +-v|--verify Verify the Gitian build +-b|--build Do a Gitian build -s|--sign Make signed binaries for Windows and Mac OSX -B|--buildsign Build both signed and unsigned binaries -o|--os Specify which Operating Systems the build is for. Default is lwx. l for linux, w for windows, x for osx -j Number of processes to use. Default 2 -m Memory to allocate in MiB. Default 2000 --kvm Use KVM instead of LXC ---setup Setup the gitian building environment. Uses KVM. If you want to use lxc, use the --lxc option. Only works on Debian-based systems (Ubuntu, Debian) +--setup Set up the Gitian building environment. Uses KVM. If you want to use lxc, use the --lxc option. Only works on Debian-based systems (Ubuntu, Debian) --detach-sign Create the assert file for detached signing. Will not commit anything. --no-commit Do not commit anything to git -h|--help Print this help message diff --git a/contrib/gitian-descriptors/README.md b/contrib/gitian-descriptors/README.md index 6149706596..d9dbfd3cb3 100644 --- a/contrib/gitian-descriptors/README.md +++ b/contrib/gitian-descriptors/README.md @@ -1,4 +1,4 @@ -### Gavin's notes on getting gitian builds up and running using KVM +### Gavin's notes on getting Gitian builds up and running using KVM These instructions distilled from [https://help.ubuntu.com/community/KVM/Installation](https://help.ubuntu.com/community/KVM/Installation). @@ -56,10 +56,10 @@ Here's a description of Gavin's setup on OSX 10.6: 4. Inside the running Ubuntu desktop, install: - sudo apt-get install debootstrap lxc ruby apache2 git apt-cacher-ng python-vm-builder + sudo apt-get install debootstrap lxc ruby apache2 git apt-cacher-ng python-vm-builder 5. Still inside Ubuntu, tell gitian-builder to use LXC, then follow the "Once you've got the right hardware and software" instructions above: - export USE_LXC=1 - git clone git://github.com/bitcoin/bitcoin.git - ... etc + export USE_LXC=1 + git clone git://github.com/bitcoin/bitcoin.git + ... etc diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 3da8510cfb..c80e19edbb 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-linux-0.15" +name: "bitcoin-linux-0.16" enable_cache: true suites: - "trusty" @@ -132,7 +132,6 @@ script: | export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host - export GIT_DIR="$PWD/.git" ./autogen.sh CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ make dist @@ -145,6 +144,9 @@ script: | find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd + # Workaround for tarball not building with the bare tag version (prep) + make -C src obj/build.h + ORIGPATH="$PATH" # Extract the release tarball into a dir for each host and build for i in ${HOSTS}; do @@ -155,6 +157,11 @@ script: | mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST + # Workaround for tarball not building with the bare tag version + echo '#!/bin/true' >share/genbuild.sh + mkdir src/obj + cp ../src/obj/build.h src/obj/ + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" make ${MAKEOPTS} make ${MAKEOPTS} -C src check-security diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 206db7c19e..cbf286d2cd 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-osx-0.15" +name: "bitcoin-osx-0.16" enable_cache: true suites: - "trusty" @@ -101,7 +101,6 @@ script: | export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host - export GIT_DIR="$PWD/.git" ./autogen.sh CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ make dist @@ -115,6 +114,9 @@ script: | find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd + # Workaround for tarball not building with the bare tag version (prep) + make -C src obj/build.h + ORIGPATH="$PATH" # Extract the release tarball into a dir for each host and build for i in ${HOSTS}; do @@ -125,6 +127,11 @@ script: | mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST + # Workaround for tarball not building with the bare tag version + echo '#!/bin/true' >share/genbuild.sh + mkdir src/obj + cp ../src/obj/build.h src/obj/ + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} make install-strip DESTDIR=${INSTALLPATH} diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 1d4d70494b..95ff9759c7 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-win-0.15" +name: "bitcoin-win-0.16" enable_cache: true suites: - "trusty" @@ -116,7 +116,6 @@ script: | export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host - export GIT_DIR="$PWD/.git" ./autogen.sh CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ make dist @@ -132,6 +131,9 @@ script: | cp ../$SOURCEDIST $OUTDIR/src popd + # Workaround for tarball not building with the bare tag version (prep) + make -C src obj/build.h + ORIGPATH="$PATH" # Extract the release tarball into a dir for each host and build for i in ${HOSTS}; do @@ -142,6 +144,11 @@ script: | mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST + # Workaround for tarball not building with the bare tag version + echo '#!/bin/true' >share/genbuild.sh + mkdir src/obj + cp ../src/obj/build.h src/obj/ + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" make ${MAKEOPTS} make ${MAKEOPTS} -C src check-security diff --git a/contrib/gitian-keys/README.md b/contrib/gitian-keys/README.md index 439910330d..4b0b7a2615 100644 --- a/contrib/gitian-keys/README.md +++ b/contrib/gitian-keys/README.md @@ -3,7 +3,7 @@ PGP keys This folder contains the public keys of developers and active contributors. -The keys are mainly used to sign git commits or the build results of gitian +The keys are mainly used to sign git commits or the build results of Gitian builds. You can import the keys into gpg as follows. Also, make sure to fetch the diff --git a/contrib/init/bitcoind.conf b/contrib/init/bitcoind.conf index f9554eecde..de4ea0ed52 100644 --- a/contrib/init/bitcoind.conf +++ b/contrib/init/bitcoind.conf @@ -30,12 +30,12 @@ pre-start script echo echo "This password is security critical to securing wallets " echo "and must not be the same as the rpcuser setting." - echo "You can generate a suitable random password using the following" + echo "You can generate a suitable random password using the following " echo "command from the shell:" echo echo "bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo'" echo - echo "It is also recommended that you also set alertnotify so you are " + echo "It is recommended that you also set alertnotify so you are " echo "notified of problems:" echo echo "ie: alertnotify=echo %%s | mail -s \"Bitcoin Alert\"" \ diff --git a/contrib/init/bitcoind.openrc b/contrib/init/bitcoind.openrc index eda1a96fb4..50377c0995 100644 --- a/contrib/init/bitcoind.openrc +++ b/contrib/init/bitcoind.openrc @@ -76,12 +76,12 @@ checkconfig() eerror "" eerror "This password is security critical to securing wallets " eerror "and must not be the same as the rpcuser setting." - eerror "You can generate a suitable random password using the following" + eerror "You can generate a suitable random password using the following " eerror "command from the shell:" eerror "" eerror "bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo'" eerror "" - eerror "It is also recommended that you also set alertnotify so you are " + eerror "It is recommended that you also set alertnotify so you are " eerror "notified of problems:" eerror "" eerror "ie: alertnotify=echo %%s | mail -s \"Bitcoin Alert\"" \ diff --git a/contrib/linearize/README.md b/contrib/linearize/README.md index f2a2ab2768..2985106982 100644 --- a/contrib/linearize/README.md +++ b/contrib/linearize/README.md @@ -46,7 +46,7 @@ linearize-hashes.py. (Default: `1000*1000*1000 bytes`) * `netmagic`: Network magic number. * `out_of_order_cache_sz`: If out-of-order blocks are being read, the block can -be written to a cache so that the blockchain doesn't have to be seeked again. +be written to a cache so that the blockchain doesn't have to be sought again. This option specifies the cache size. (Default: `100*1000*1000 bytes`) * `rev_hash_bytes`: If true, the block hash list written by linearize-hashes.py will be byte-reversed when read by linearize-data.py. See the linearize-hashes diff --git a/contrib/rpm/README.md b/contrib/rpm/README.md index 4ab2f35680..e1e0745fd6 100644 --- a/contrib/rpm/README.md +++ b/contrib/rpm/README.md @@ -84,16 +84,16 @@ If you would prefer not to build the GUI at all, you can pass the switch The desktop and KDE meta files are created in the spec file itself with the `cat` command. This is done to allow easy distribution specific changes without -needing to use any patches. A specific time stamp is given to the files so that +needing to use any patches. A specific timestamp is given to the files so that it does not they do not appear to have been updated every time the package is -built. If you do make changes to them, you probably should update time stamp -assigned to them in the `touch` command that specifies the time stamp. +built. If you do make changes to them, you probably should update timestamp +assigned to them in the `touch` command that specifies the timestamp. ## SVG, PNG, and XPM Icons The `bitcoin.svg` file is from the source listed as `Source100`. It is used as the source for the PNG and XPM files. The generated PNG and XPM files are given -the same time stamp as the source SVG file as a means of indicating they are +the same timestamp as the source SVG file as a means of indicating they are derived from it. ## Systemd @@ -105,10 +105,10 @@ distributions that still receive vendor updates do in fact use systemd. The files to control the service are created in the RPM spec file itself using the `cat` command. This is done to make it easy to modify for other distributions that may implement things differently without needing to patch -source. A specific time stamp is given to the files so that they do not appear +source. A specific timestamp is given to the files so that they do not appear to have been updated every time the package is built. If you do make changes to -them, you probably should update the time stamp assigned to them in the `touch` -command that specifies the time stamp. +them, you probably should update the timestamp assigned to them in the `touch` +command that specifies the timestamp. ## SELinux diff --git a/doc/REST-interface.md b/doc/REST-interface.md index caf6782886..7a17c175bd 100644 --- a/doc/REST-interface.md +++ b/doc/REST-interface.md @@ -8,14 +8,14 @@ The interface runs on the same port as the JSON-RPC interface, by default port 8 Supported API ------------- -####Transactions +#### Transactions `GET /rest/tx/<TX-HASH>.<bin|hex|json>` Given a transaction hash: returns a transaction in binary, hex-encoded binary, or JSON formats. For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option. -####Blocks +#### Blocks `GET /rest/block/<BLOCK-HASH>.<bin|hex|json>` `GET /rest/block/notxdetails/<BLOCK-HASH>.<bin|hex|json>` @@ -25,12 +25,12 @@ The HTTP request and response are both handled entirely in-memory, thus making m With the /notxdetails/ option JSON response will only contain the transaction hash instead of the complete transaction details. The option only affects the JSON response. -####Blockheaders +#### Blockheaders `GET /rest/headers/<COUNT>/<BLOCK-HASH>.<bin|hex|json>` Given a block hash: returns <COUNT> amount of blockheaders in upward direction. -####Chaininfos +#### Chaininfos `GET /rest/chaininfo.json` Returns various state info regarding block chain processing. @@ -48,7 +48,7 @@ Only supports JSON as output format. * softforks : (array) status of softforks in progress * bip9_softforks : (object) status of BIP9 softforks in progress -####Query UTXO set +#### Query UTXO set `GET /rest/getutxos/<checkmempool>/<txid>-<n>/<txid>-<n>/.../<txid>-<n>.<bin|hex|json>` The getutxo command allows querying of the UTXO set given a set of outpoints. @@ -81,7 +81,7 @@ $ curl localhost:18332/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff76 } ``` -####Memory pool +#### Memory pool `GET /rest/mempool/info.json` Returns various information about the TX mempool. diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index f4a9826d80..cd800464b4 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,6 +1,6 @@ OpenBSD build guide ====================== -(updated for OpenBSD 6.0) +(updated for OpenBSD 6.1) This guide describes how to build bitcoind and command-line utilities on OpenBSD. @@ -48,13 +48,13 @@ BOOST_PREFIX="${BITCOIN_ROOT}/boost" mkdir -p $BOOST_PREFIX # Fetch the source and verify that it is not tampered with -curl -o boost_1_61_0.tar.bz2 http://heanet.dl.sourceforge.net/project/boost/boost/1.61.0/boost_1_61_0.tar.bz2 -echo 'a547bd06c2fd9a71ba1d169d9cf0339da7ebf4753849a8f7d6fdb8feee99b640 boost_1_61_0.tar.bz2' | sha256 -c -# MUST output: (SHA256) boost_1_61_0.tar.bz2: OK -tar -xjf boost_1_61_0.tar.bz2 +curl -o boost_1_64_0.tar.bz2 https://netcologne.dl.sourceforge.net/project/boost/boost/1.64.0/boost_1_64_0.tar.bz2 +echo '7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332 boost_1_64_0.tar.bz2' | sha256 -c +# MUST output: (SHA256) boost_1_64_0.tar.bz2: OK +tar -xjf boost_1_64_0.tar.bz2 -# Boost 1.61 needs one small patch for OpenBSD -cd boost_1_61_0 +# Boost 1.64 needs one small patch for OpenBSD +cd boost_1_64_0 # Also here: https://gist.githubusercontent.com/laanwj/bf359281dc319b8ff2e1/raw/92250de8404b97bb99d72ab898f4a8cb35ae1ea3/patch-boost_test_impl_execution_monitor_ipp.patch patch -p0 < /usr/ports/devel/boost/patches/patch-boost_test_impl_execution_monitor_ipp diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 458e7bcbff..9b85600ccc 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -4,7 +4,7 @@ Developer Notes Various coding styles have been used during the history of the codebase, and the result is not very consistent. However, we're now trying to converge to a single style, which is specified below. When writing patches, favor the new -style over attempting to mimick the surrounding style, except for move-only +style over attempting to mimic the surrounding style, except for move-only commits. Do not submit patches solely to modify the style of existing code. @@ -37,6 +37,8 @@ code. - **Miscellaneous** - `++i` is preferred over `i++`. + - `nullptr` is preferred over `NULL` or `(void*)0`. + - `static_assert` is preferred over `assert` where possible. Generally; compile-time checking is preferred over run-time checking. Block style example: ```c++ @@ -275,7 +277,7 @@ Wallet - *Rationale*: In RPC code that conditionally uses the wallet (such as `validateaddress`) it is easy to forget that global pointer `pwalletMain` - can be NULL. See `test/functional/disablewallet.py` for functional tests + can be nullptr. See `test/functional/disablewallet.py` for functional tests exercising the API with `-disablewallet` - Include `db_cxx.h` (BerkeleyDB header) only when `ENABLE_WALLET` is set @@ -561,10 +563,10 @@ A few guidelines for introducing and reviewing new RPC interfaces: which is error prone, and it is easy to get things such as escaping wrong. JSON already supports nested data structures, no need to re-invent the wheel. - - *Exception*: AmountToValue can parse amounts as string. This was introduced because many JSON + - *Exception*: AmountFromValue can parse amounts as string. This was introduced because many JSON parsers and formatters hard-code handling decimal numbers as floating point values, resulting in potential loss of precision. This is unacceptable for - monetary values. **Always** use `AmountToValue` and `ValueToAmount` when + monetary values. **Always** use `AmountFromValue` and `ValueFromAmount` when inputting or outputting monetary values. The only exceptions to this are `prioritisetransaction` and `getblocktemplate` because their interface is specified as-is in BIP22. diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 9f9afaf04f..636686b391 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -76,7 +76,11 @@ In the VirtualBox GUI click "New" and choose the following parameters in the wiz After creating the VM, we need to configure it. -- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attached to `NAT`. +- Click the `Settings` button, then go to `System` tab and `Processor` sub-tab. Increase the number of processors to the number of cores on your machine if you want builds to be faster. + +![](gitian-building/system_settings.png) + +- Go to the `Network` tab. Adapter 1 should be attached to `NAT`. ![](gitian-building/network_settings.png) diff --git a/doc/gitian-building/system_settings.png b/doc/gitian-building/system_settings.png Binary files differnew file mode 100644 index 0000000000..a5720ef3a3 --- /dev/null +++ b/doc/gitian-building/system_settings.png diff --git a/doc/init.md b/doc/init.md index e3db5b05ef..75f9013f29 100644 --- a/doc/init.md +++ b/doc/init.md @@ -10,14 +10,14 @@ can be found in the contrib/init folder. contrib/init/bitcoind.conf: Upstart service configuration file contrib/init/bitcoind.init: CentOS compatible SysV style init script -1. Service User +Service User --------------------------------- All three Linux startup configurations assume the existence of a "bitcoin" user and group. They must be created before attempting to use these scripts. The OS X configuration assumes bitcoind will be set up for the current user. -2. Configuration +Configuration --------------------------------- At a bare minimum, bitcoind requires that the rpcpassword setting be set @@ -46,10 +46,10 @@ relative to the data directory. `wallet` *only* supports relative paths. For an example configuration file that describes the configuration settings, see `contrib/debian/examples/bitcoin.conf`. -3. Paths +Paths --------------------------------- -3a) Linux +### Linux All three configurations assume several paths that might need to be adjusted. @@ -65,17 +65,17 @@ reasons to make the configuration file and data directory only readable by the bitcoin user and group. Access to bitcoin-cli and other bitcoind rpc clients can then be controlled by group membership. -3b) Mac OS X +### Mac OS X Binary: `/usr/local/bin/bitcoind` Configuration file: `~/Library/Application Support/Bitcoin/bitcoin.conf` -Data directory: `~/Library/Application Support/Bitcoin` -Lock file: `~/Library/Application Support/Bitcoin/.lock` +Data directory: `~/Library/Application Support/Bitcoin` +Lock file: `~/Library/Application Support/Bitcoin/.lock` -4. Installing Service Configuration +Installing Service Configuration ----------------------------------- -4a) systemd +### systemd Installing this .service file consists of just copying it to /usr/lib/systemd/system directory, followed by the command @@ -84,14 +84,14 @@ Installing this .service file consists of just copying it to To test, run `systemctl start bitcoind` and to enable for system startup run `systemctl enable bitcoind` -4b) OpenRC +### OpenRC Rename bitcoind.openrc to bitcoind and drop it in /etc/init.d. Double check ownership and permissions and make it executable. Test it with `/etc/init.d/bitcoind start` and configure it to run on startup with `rc-update add bitcoind` -4c) Upstart (for Debian/Ubuntu based distributions) +### Upstart (for Debian/Ubuntu based distributions) Drop bitcoind.conf in /etc/init. Test by running `service bitcoind start` it will automatically start on reboot. @@ -99,7 +99,7 @@ it will automatically start on reboot. NOTE: This script is incompatible with CentOS 5 and Amazon Linux 2014 as they use old versions of Upstart and do not supply the start-stop-daemon utility. -4d) CentOS +### CentOS Copy bitcoind.init to /etc/init.d/bitcoind. Test by running `service bitcoind start`. @@ -107,7 +107,7 @@ Using this script, you can adjust the path and flags to the bitcoind program by setting the BITCOIND and FLAGS environment variables in the file /etc/sysconfig/bitcoind. You can also use the DAEMONOPTS environment variable here. -4e) Mac OS X +### Mac OS X Copy org.bitcoin.bitcoind.plist into ~/Library/LaunchAgents. Load the launch agent by running `launchctl load ~/Library/LaunchAgents/org.bitcoin.bitcoind.plist`. @@ -118,7 +118,7 @@ NOTE: This approach is intended for those wanting to run bitcoind as the current You will need to modify org.bitcoin.bitcoind.plist if you intend to use it as a Launch Daemon with a dedicated bitcoin user. -5. Auto-respawn +Auto-respawn ----------------------------------- Auto respawning is currently only configured for Upstart and systemd. diff --git a/doc/release-notes.md b/doc/release-notes.md index a13ede2dd5..aa1d1bea14 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -16,16 +16,39 @@ To receive security and update notifications, please subscribe to: <https://bitcoincore.org/en/list/announcements/join/> +How to Upgrade +============== + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes for older versions), then run the +installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) +or `bitcoind`/`bitcoin-qt` (on Linux). + +The first time you run version 0.15.0, your chainstate database will be converted to a +new format, which will take anywhere from a few minutes to half an hour, +depending on the speed of your machine. + +Note that the block database format also changed in version 0.8.0 and there is no +automatic upgrade code from before version 0.8 to version 0.15.0. Upgrading +directly from 0.7.x and earlier without redownloading the blockchain is not supported. +However, as usual, old wallet versions are still supported. + +Downgrading warning +------------------- + +The chainstate database for this release is not compatible with previous +releases, so if you run 0.15 and then decide to switch back to any +older version, you will need to run the old release with the `-reindex-chainstate` +option to rebuild the chainstate data structures in the old format. + +If your node has pruning enabled, this will entail re-downloading and +processing the entire blockchain. + Compatibility ============== Bitcoin Core is extensively tested on multiple operating systems using -the Linux kernel, macOS 10.8+, and Windows Vista and later. - -Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support). -No attempt is made to prevent installing or running the software on Windows XP, you -can still do so at your own risk but be aware that there are known instabilities. -Please do not report issues about Windows XP to the issue tracker. +the Linux kernel, macOS 10.8+, and Windows Vista and later. Windows XP is not supported. Bitcoin Core should also work on most other Unix-like systems but is not frequently tested on them. @@ -33,70 +56,6 @@ frequently tested on them. Notable changes =============== -Low-level RPC changes ---------------------- - -- The new database model no longer stores information about transaction - versions of unspent outputs. This means that: - - The `gettxout` RPC no longer has a `version` field in the response. - - The `gettxoutsetinfo` RPC reports `hash_serialized_2` instead of `hash_serialized`, - which does not commit to the transaction versions of unspent outputs, but does - commit to the height and coinbase information. - - The `gettxoutsetinfo` response now contains `disk_size` and `bogosize` instead of - `bytes_serialized`. The first is a more accurate estimate of actual disk usage, but - is not deterministic. The second is unrelated to disk usage, but is a - database-independent metric of UTXO set size: it counts every UTXO entry as 50 + the - length of its scriptPubKey. - - The `getutxos` REST path no longer reports the `txvers` field in JSON format, - and always reports 0 for transaction versions in the binary format - - -- Error codes have been updated to be more accurate for the following error cases: - - `getblock` now returns RPC_MISC_ERROR if the block can't be found on disk (for - example if the block has been pruned). Previously returned RPC_INTERNAL_ERROR. - - `pruneblockchain` now returns RPC_MISC_ERROR if the blocks cannot be pruned - because the node is not in pruned mode. Previously returned RPC_METHOD_NOT_FOUND. - - `pruneblockchain` now returns RPC_INVALID_PARAMETER if the blocks cannot be pruned - because the supplied timestamp is too late. Previously returned RPC_INTERNAL_ERROR. - - `pruneblockchain` now returns RPC_MISC_ERROR if the blocks cannot be pruned - because the blockchain is too short. Previously returned RPC_INTERNAL_ERROR. - - `setban` now returns RPC_CLIENT_INVALID_IP_OR_SUBNET if the supplied IP address - or subnet is invalid. Previously returned RPC_CLIENT_NODE_ALREADY_ADDED. - - `setban` now returns RPC_CLIENT_INVALID_IP_OR_SUBNET if the user tries to unban - a node that has not previously been banned. Previously returned RPC_MISC_ERROR. - - `removeprunedfunds` now returns RPC_WALLET_ERROR if bitcoind is unable to remove - the transaction. Previously returned RPC_INTERNAL_ERROR. - - `removeprunedfunds` now returns RPC_INVALID_PARAMETER if the transaction does not - exist in the wallet. Previously returned RPC_INTERNAL_ERROR. - - `fundrawtransaction` now returns RPC_INVALID_ADDRESS_OR_KEY if an invalid change - address is provided. Previously returned RPC_INVALID_PARAMETER. - - `fundrawtransaction` now returns RPC_WALLET_ERROR if bitcoind is unable to create - the transaction. The error message provides further details. Previously returned - RPC_INTERNAL_ERROR. - - `bumpfee` now returns RPC_INVALID_PARAMETER if the provided transaction has - descendants in the wallet. Previously returned RPC_MISC_ERROR. - - `bumpfee` now returns RPC_INVALID_PARAMETER if the provided transaction has - descendants in the mempool. Previously returned RPC_MISC_ERROR. - - `bumpfee` now returns RPC_WALLET_ERROR if the provided transaction has - has been mined or conflicts with a mined transaction. Previously returned - RPC_INVALID_ADDRESS_OR_KEY. - - `bumpfee` now returns RPC_WALLET_ERROR if the provided transaction is not - BIP 125 replaceable. Previously returned RPC_INVALID_ADDRESS_OR_KEY. - - `bumpfee` now returns RPC_WALLET_ERROR if the provided transaction has already - been bumped by a different transaction. Previously returned RPC_INVALID_REQUEST. - - `bumpfee` now returns RPC_WALLET_ERROR if the provided transaction contains - inputs which don't belong to this wallet. Previously returned RPC_INVALID_ADDRESS_OR_KEY. - - `bumpfee` now returns RPC_WALLET_ERROR if the provided transaction has multiple change - outputs. Previously returned RPC_MISC_ERROR. - - `bumpfee` now returns RPC_WALLET_ERROR if the provided transaction has no change - output. Previously returned RPC_MISC_ERROR. - - `bumpfee` now returns RPC_WALLET_ERROR if the fee is too high. Previously returned - RPC_MISC_ERROR. - - `bumpfee` now returns RPC_WALLET_ERROR if the fee is too low. Previously returned - RPC_MISC_ERROR. - - `bumpfee` now returns RPC_WALLET_ERROR if the change output is too small to bump the - fee. Previously returned RPC_MISC_ERROR. - Credits ======= diff --git a/doc/release-process.md b/doc/release-process.md index 5a99b726f1..f429b4bbdb 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -111,16 +111,16 @@ The gbuild invocations below <b>DO NOT DO THIS</b> by default. ### Build and sign Bitcoin Core for Linux, Windows, and OS X: pushd ./gitian-builder - ./bin/gbuild --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml + ./bin/gbuild --num-make 2 --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ - ./bin/gbuild --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml + ./bin/gbuild --num-make 2 --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ - ./bin/gbuild --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + ./bin/gbuild --num-make 2 --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ diff --git a/doc/zmq.md b/doc/zmq.md index 1019ff6653..38c58fb7fd 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -72,7 +72,7 @@ For instance: Each PUB notification has a topic and body, where the header corresponds to the notification type. For instance, for the notification `-zmqpubhashtx` the topic is `hashtx` (no null -terminator) and the body is the hexadecimal transaction hash (32 +terminator) and the body is the transaction hash (32 bytes). These options can also be provided in bitcoin.conf. diff --git a/src/addrdb.h b/src/addrdb.h index 6cb36dfac4..d930de204d 100644 --- a/src/addrdb.h +++ b/src/addrdb.h @@ -37,7 +37,7 @@ public: SetNull(); } - CBanEntry(int64_t nCreateTimeIn) + explicit CBanEntry(int64_t nCreateTimeIn) { SetNull(); nCreateTime = nCreateTimeIn; @@ -61,7 +61,7 @@ public: banReason = BanReasonUnknown; } - std::string banReasonToString() + std::string banReasonToString() const { switch (banReason) { case BanReasonNodeMisbehaving: diff --git a/src/addrman.cpp b/src/addrman.cpp index 4a408b9beb..a56bb4f9c1 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -69,13 +69,13 @@ CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int* pnId) { std::map<CNetAddr, int>::iterator it = mapAddr.find(addr); if (it == mapAddr.end()) - return NULL; + return nullptr; if (pnId) *pnId = (*it).second; std::map<int, CAddrInfo>::iterator it2 = mapInfo.find((*it).second); if (it2 != mapInfo.end()) return &(*it2).second; - return NULL; + return nullptr; } CAddrInfo* CAddrMan::Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId) diff --git a/src/addrman.h b/src/addrman.h index 70d907488f..547088aedf 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -220,11 +220,11 @@ protected: FastRandomContext insecure_rand; //! Find an entry. - CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL); + CAddrInfo* Find(const CNetAddr& addr, int *pnId = nullptr); //! find an entry, creating it if necessary. //! nTime and nServices of the found node are updated, if necessary. - CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = NULL); + CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr); //! Swap two elements in vRandom. void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2); diff --git a/src/arith_uint256.h b/src/arith_uint256.h index c7734035df..5fd4fe96cf 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -250,7 +250,7 @@ public: uint64_t GetLow64() const { - assert(WIDTH >= 2); + static_assert(WIDTH >= 2, "Assertion WIDTH >= 2 failed (WIDTH = BITS / 32). BITS is a template parameter."); return pn[0] | (uint64_t)pn[1] << 32; } }; @@ -283,7 +283,7 @@ public: * complexities of the sign bit and using base 256 are probably an * implementation accident. */ - arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); + arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = nullptr, bool *pfOverflow = nullptr); uint32_t GetCompact(bool fNegative = false) const; friend uint256 ArithToUint256(const arith_uint256 &); diff --git a/src/base58.cpp b/src/base58.cpp index 17022a6bc1..3802f953f9 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -37,7 +37,7 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch) while (*psz && !isspace(*psz)) { // Decode base58 character const char* ch = strchr(pszBase58, *psz); - if (ch == NULL) + if (ch == nullptr) return false; // Apply "b256 = b256 * 58 + ch". int carry = ch - pszBase58; @@ -218,7 +218,7 @@ private: CBitcoinAddress* addr; public: - CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {} + explicit CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {} bool operator()(const CKeyID& id) const { return addr->Set(id); } bool operator()(const CScriptID& id) const { return addr->Set(id); } diff --git a/src/base58.h b/src/base58.h index 4de5cc6ce5..db12208f74 100644 --- a/src/base58.h +++ b/src/base58.h @@ -26,7 +26,7 @@ /** * Encode a byte sequence as a base58-encoded string. - * pbegin and pend cannot be NULL, unless both are. + * pbegin and pend cannot be nullptr, unless both are. */ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend); @@ -38,7 +38,7 @@ std::string EncodeBase58(const std::vector<unsigned char>& vch); /** * Decode a base58-encoded string (psz) into a byte vector (vchRet). * return true if decoding is successful. - * psz cannot be NULL. + * psz cannot be nullptr. */ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet); diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index 33631d2d15..849d924af2 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -17,7 +17,7 @@ benchmark::BenchRunner::BenchmarkMap &benchmark::BenchRunner::benchmarks() { static double gettimedouble(void) { struct timeval tv; - gettimeofday(&tv, NULL); + gettimeofday(&tv, nullptr); return tv.tv_usec * 0.000001 + tv.tv_sec; } @@ -100,6 +100,7 @@ bool benchmark::State::KeepRunning() int64_t averageCycles = (nowCycles-beginCycles)/count; std::cout << std::fixed << std::setprecision(15) << name << "," << count << "," << minTime << "," << maxTime << "," << average << "," << minCycles << "," << maxCycles << "," << averageCycles << "\n"; + std::cout.copyfmt(std::ios(nullptr)); return false; } diff --git a/src/bench/checkqueue.cpp b/src/bench/checkqueue.cpp index 88a2a570f9..b7ae5c2d57 100644 --- a/src/bench/checkqueue.cpp +++ b/src/bench/checkqueue.cpp @@ -67,7 +67,7 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::State& state) prevector<PREVECTOR_SIZE, uint8_t> p; PrevectorJob(){ } - PrevectorJob(FastRandomContext& insecure_rand){ + explicit PrevectorJob(FastRandomContext& insecure_rand){ p.resize(insecure_rand.randrange(PREVECTOR_SIZE*2)); } bool operator()() diff --git a/src/bench/lockedpool.cpp b/src/bench/lockedpool.cpp index 43a1422795..c6a05567be 100644 --- a/src/bench/lockedpool.cpp +++ b/src/bench/lockedpool.cpp @@ -21,14 +21,14 @@ static void BenchLockedPool(benchmark::State& state) std::vector<void*> addr; for (int x=0; x<ASIZE; ++x) - addr.push_back(0); + addr.push_back(nullptr); uint32_t s = 0x12345678; while (state.KeepRunning()) { for (int x=0; x<BITER; ++x) { int idx = s & (addr.size()-1); if (s & 0x80000000) { b.free(addr[idx]); - addr[idx] = 0; + addr[idx] = nullptr; } else if(!addr[idx]) { addr[idx] = b.alloc((s >> 16) & (MSIZE-1)); } diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index c1a7c927e3..8bec0289f5 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -79,10 +79,10 @@ static int AppInitRPC(int argc, char* argv[]) // // Parameters // - ParseParameters(argc, argv); - if (argc<2 || IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help") || IsArgSet("-version")) { + gArgs.ParseParameters(argc, argv); + if (argc<2 || gArgs.IsArgSet("-?") || gArgs.IsArgSet("-h") || gArgs.IsArgSet("-help") || gArgs.IsArgSet("-version")) { std::string strUsage = strprintf(_("%s RPC client version"), _(PACKAGE_NAME)) + " " + FormatFullVersion() + "\n"; - if (!IsArgSet("-version")) { + if (!gArgs.IsArgSet("-version")) { strUsage += "\n" + _("Usage:") + "\n" + " bitcoin-cli [options] <command> [params] " + strprintf(_("Send command to %s"), _(PACKAGE_NAME)) + "\n" + " bitcoin-cli [options] -named <command> [name=value] ... " + strprintf(_("Send command to %s (with named arguments)"), _(PACKAGE_NAME)) + "\n" + @@ -100,11 +100,11 @@ static int AppInitRPC(int argc, char* argv[]) return EXIT_SUCCESS; } if (!fs::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", GetArg("-datadir", "").c_str()); + fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); return EXIT_FAILURE; } try { - ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)); + gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return EXIT_FAILURE; @@ -116,7 +116,7 @@ static int AppInitRPC(int argc, char* argv[]) fprintf(stderr, "Error: %s\n", e.what()); return EXIT_FAILURE; } - if (GetBoolArg("-rpcssl", false)) + if (gArgs.GetBoolArg("-rpcssl", false)) { fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n"); return EXIT_FAILURE; @@ -161,8 +161,8 @@ static void http_request_done(struct evhttp_request *req, void *ctx) { HTTPReply *reply = static_cast<HTTPReply*>(ctx); - if (req == NULL) { - /* If req is NULL, it means an error occurred while connecting: the + if (req == nullptr) { + /* If req is nullptr, it means an error occurred while connecting: the * error code will have been passed to http_error_cb. */ reply->status = 0; @@ -198,19 +198,19 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) // 2. port in -rpcconnect (ie following : in ipv4 or ]: in ipv6) // 3. default port for chain int port = BaseParams().RPCPort(); - SplitHostPort(GetArg("-rpcconnect", DEFAULT_RPCCONNECT), port, host); - port = GetArg("-rpcport", port); + SplitHostPort(gArgs.GetArg("-rpcconnect", DEFAULT_RPCCONNECT), port, host); + port = gArgs.GetArg("-rpcport", port); // Obtain event base raii_event_base base = obtain_event_base(); // Synchronously look up hostname raii_evhttp_connection evcon = obtain_evhttp_connection_base(base.get(), host, port); - evhttp_connection_set_timeout(evcon.get(), GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT)); + evhttp_connection_set_timeout(evcon.get(), gArgs.GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT)); HTTPReply response; raii_evhttp_request req = obtain_evhttp_request(http_request_done, (void*)&response); - if (req == NULL) + if (req == nullptr) throw std::runtime_error("create http request failed"); #if LIBEVENT_VERSION_NUMBER >= 0x02010300 evhttp_request_set_error_cb(req.get(), http_error_cb); @@ -218,16 +218,16 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) // Get credentials std::string strRPCUserColonPass; - if (GetArg("-rpcpassword", "") == "") { + if (gArgs.GetArg("-rpcpassword", "") == "") { // Try fall back to cookie-based authentication if no password is provided if (!GetAuthCookie(&strRPCUserColonPass)) { throw std::runtime_error(strprintf( _("Could not locate RPC credentials. No authentication cookie could be found, and no rpcpassword is set in the configuration file (%s)"), - GetConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)).string().c_str())); + GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string().c_str())); } } else { - strRPCUserColonPass = GetArg("-rpcuser", "") + ":" + GetArg("-rpcpassword", ""); + strRPCUserColonPass = gArgs.GetArg("-rpcuser", "") + ":" + gArgs.GetArg("-rpcpassword", ""); } struct evkeyvalq* output_headers = evhttp_request_get_output_headers(req.get()); @@ -244,7 +244,7 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) // check if we should use a special wallet endpoint std::string endpoint = "/"; - std::string walletName = GetArg("-rpcwallet", ""); + std::string walletName = gArgs.GetArg("-rpcwallet", ""); if (!walletName.empty()) { char *encodedURI = evhttp_uriencode(walletName.c_str(), walletName.size(), false); if (encodedURI) { @@ -294,7 +294,7 @@ int CommandLineRPC(int argc, char *argv[]) argv++; } std::vector<std::string> args = std::vector<std::string>(&argv[1], &argv[argc]); - if (GetBoolArg("-stdin", false)) { + if (gArgs.GetBoolArg("-stdin", false)) { // Read one arg per line from stdin and append std::string line; while (std::getline(std::cin,line)) @@ -306,14 +306,14 @@ int CommandLineRPC(int argc, char *argv[]) args.erase(args.begin()); // Remove trailing method name from arguments vector UniValue params; - if(GetBoolArg("-named", DEFAULT_NAMED)) { + if(gArgs.GetBoolArg("-named", DEFAULT_NAMED)) { params = RPCConvertNamedValues(strMethod, args); } else { params = RPCConvertValues(strMethod, args); } // Execute and handle connection failures with -rpcwait - const bool fWait = GetBoolArg("-rpcwait", false); + const bool fWait = gArgs.GetBoolArg("-rpcwait", false); do { try { const UniValue reply = CallRPC(strMethod, params); @@ -370,7 +370,7 @@ int CommandLineRPC(int argc, char *argv[]) nRet = EXIT_FAILURE; } catch (...) { - PrintExceptionContinue(NULL, "CommandLineRPC()"); + PrintExceptionContinue(nullptr, "CommandLineRPC()"); throw; } @@ -397,7 +397,7 @@ int main(int argc, char* argv[]) PrintExceptionContinue(&e, "AppInitRPC()"); return EXIT_FAILURE; } catch (...) { - PrintExceptionContinue(NULL, "AppInitRPC()"); + PrintExceptionContinue(nullptr, "AppInitRPC()"); return EXIT_FAILURE; } @@ -408,7 +408,7 @@ int main(int argc, char* argv[]) catch (const std::exception& e) { PrintExceptionContinue(&e, "CommandLineRPC()"); } catch (...) { - PrintExceptionContinue(NULL, "CommandLineRPC()"); + PrintExceptionContinue(nullptr, "CommandLineRPC()"); } return ret; } diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 9acb3fd30e..cff90d13af 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -39,7 +39,7 @@ static int AppInitRawTx(int argc, char* argv[]) // // Parameters // - ParseParameters(argc, argv); + gArgs.ParseParameters(argc, argv); // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) try { @@ -49,9 +49,9 @@ static int AppInitRawTx(int argc, char* argv[]) return EXIT_FAILURE; } - fCreateBlank = GetBoolArg("-create", false); + fCreateBlank = gArgs.GetBoolArg("-create", false); - if (argc<2 || IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help")) + if (argc<2 || gArgs.IsArgSet("-?") || gArgs.IsArgSet("-h") || gArgs.IsArgSet("-help")) { // First part of help message is specific to this utility std::string strUsage = strprintf(_("%s bitcoin-tx utility version"), _(PACKAGE_NAME)) + " " + FormatFullVersion() + "\n\n" + @@ -737,9 +737,9 @@ static void OutputTxHex(const CTransaction& tx) static void OutputTx(const CTransaction& tx) { - if (GetBoolArg("-json", false)) + if (gArgs.GetBoolArg("-json", false)) OutputTxJSON(tx); - else if (GetBoolArg("-txid", false)) + else if (gArgs.GetBoolArg("-txid", false)) OutputTxHash(tx); else OutputTxHex(tx); @@ -822,7 +822,7 @@ static int CommandLineRawTx(int argc, char* argv[]) nRet = EXIT_FAILURE; } catch (...) { - PrintExceptionContinue(NULL, "CommandLineRawTx()"); + PrintExceptionContinue(nullptr, "CommandLineRawTx()"); throw; } @@ -845,7 +845,7 @@ int main(int argc, char* argv[]) PrintExceptionContinue(&e, "AppInitRawTx()"); return EXIT_FAILURE; } catch (...) { - PrintExceptionContinue(NULL, "AppInitRawTx()"); + PrintExceptionContinue(nullptr, "AppInitRawTx()"); return EXIT_FAILURE; } @@ -856,7 +856,7 @@ int main(int argc, char* argv[]) catch (const std::exception& e) { PrintExceptionContinue(&e, "CommandLineRawTx()"); } catch (...) { - PrintExceptionContinue(NULL, "CommandLineRawTx()"); + PrintExceptionContinue(nullptr, "CommandLineRawTx()"); } return ret; } diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index ff61b9065b..543eba0e69 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -71,14 +71,14 @@ bool AppInit(int argc, char* argv[]) // Parameters // // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main() - ParseParameters(argc, argv); + gArgs.ParseParameters(argc, argv); // Process help and version before taking care about datadir - if (IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help") || IsArgSet("-version")) + if (gArgs.IsArgSet("-?") || gArgs.IsArgSet("-h") || gArgs.IsArgSet("-help") || gArgs.IsArgSet("-version")) { std::string strUsage = strprintf(_("%s Daemon"), _(PACKAGE_NAME)) + " " + _("version") + " " + FormatFullVersion() + "\n"; - if (IsArgSet("-version")) + if (gArgs.IsArgSet("-version")) { strUsage += FormatParagraph(LicenseInfo()); } @@ -98,12 +98,12 @@ bool AppInit(int argc, char* argv[]) { if (!fs::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", GetArg("-datadir", "").c_str()); + fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); return false; } try { - ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)); + gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return false; @@ -125,7 +125,7 @@ bool AppInit(int argc, char* argv[]) } // -server defaults to true for bitcoind but not for the GUI so do this here - SoftSetBoolArg("-server", true); + gArgs.SoftSetBoolArg("-server", true); // Set this early so that parameter interactions go to console InitLogging(); InitParameterInteraction(); @@ -144,7 +144,7 @@ bool AppInit(int argc, char* argv[]) // InitError will have been called with detailed error, which ends up on console exit(EXIT_FAILURE); } - if (GetBoolArg("-daemon", false)) + if (gArgs.GetBoolArg("-daemon", false)) { #if HAVE_DECL_DAEMON fprintf(stdout, "Bitcoin server starting\n"); @@ -170,7 +170,7 @@ bool AppInit(int argc, char* argv[]) catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInit()"); } catch (...) { - PrintExceptionContinue(NULL, "AppInit()"); + PrintExceptionContinue(nullptr, "AppInit()"); } if (!fRet) diff --git a/src/blockencodings.h b/src/blockencodings.h index 5a1d80d421..50478f9f32 100644 --- a/src/blockencodings.h +++ b/src/blockencodings.h @@ -16,7 +16,7 @@ struct TransactionCompressor { private: CTransactionRef& tx; public: - TransactionCompressor(CTransactionRef& txIn) : tx(txIn) {} + explicit TransactionCompressor(CTransactionRef& txIn) : tx(txIn) {} ADD_SERIALIZE_METHODS; @@ -75,7 +75,7 @@ public: std::vector<CTransactionRef> txn; BlockTransactions() {} - BlockTransactions(const BlockTransactionsRequest& req) : + explicit BlockTransactions(const BlockTransactionsRequest& req) : blockhash(req.blockhash), txn(req.indexes.size()) {} ADD_SERIALIZE_METHODS; @@ -198,7 +198,7 @@ protected: CTxMemPool* pool; public: CBlockHeader header; - PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {} + explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {} // extra_txn is a list of extra transactions to look at, in <witness hash, reference> form ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn); diff --git a/src/chain.cpp b/src/chain.cpp index ffd58d471d..47acde882e 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -9,7 +9,7 @@ * CChain implementation */ void CChain::SetTip(CBlockIndex *pindex) { - if (pindex == NULL) { + if (pindex == nullptr) { vChain.clear(); return; } @@ -49,8 +49,8 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { } const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { - if (pindex == NULL) { - return NULL; + if (pindex == nullptr) { + return nullptr; } if (pindex->nHeight > Height()) pindex = pindex->GetAncestor(Height()); @@ -63,7 +63,7 @@ CBlockIndex* CChain::FindEarliestAtLeast(int64_t nTime) const { std::vector<CBlockIndex*>::const_iterator lower = std::lower_bound(vChain.begin(), vChain.end(), nTime, [](CBlockIndex* pBlock, const int64_t& time) -> bool { return pBlock->GetBlockTimeMax() < time; }); - return (lower == vChain.end() ? NULL : *lower); + return (lower == vChain.end() ? nullptr : *lower); } /** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ @@ -83,14 +83,14 @@ int static inline GetSkipHeight(int height) { CBlockIndex* CBlockIndex::GetAncestor(int height) { if (height > nHeight || height < 0) - return NULL; + return nullptr; CBlockIndex* pindexWalk = this; int heightWalk = nHeight; while (heightWalk > height) { int heightSkip = GetSkipHeight(heightWalk); int heightSkipPrev = GetSkipHeight(heightWalk - 1); - if (pindexWalk->pskip != NULL && + if (pindexWalk->pskip != nullptr && (heightSkip == height || (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && heightSkipPrev >= height)))) { @@ -150,7 +150,7 @@ int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& fr } /** Find the last common ancestor two blocks have. - * Both pa and pb must be non-NULL. */ + * Both pa and pb must be non-nullptr. */ const CBlockIndex* LastCommonAncestor(const CBlockIndex* pa, const CBlockIndex* pb) { if (pa->nHeight > pb->nHeight) { pa = pa->GetAncestor(pb->nHeight); diff --git a/src/chain.h b/src/chain.h index c5304b7d6f..ef7e6f9554 100644 --- a/src/chain.h +++ b/src/chain.h @@ -216,14 +216,14 @@ public: //! (memory only) Sequential id assigned to distinguish order in which blocks are received. int32_t nSequenceId; - //! (memory only) Maximum nTime in the chain upto and including this block. + //! (memory only) Maximum nTime in the chain up to and including this block. unsigned int nTimeMax; void SetNull() { - phashBlock = NULL; - pprev = NULL; - pskip = NULL; + phashBlock = nullptr; + pprev = nullptr; + pskip = nullptr; nHeight = 0; nFile = 0; nDataPos = 0; @@ -247,7 +247,7 @@ public: SetNull(); } - CBlockIndex(const CBlockHeader& block) + explicit CBlockIndex(const CBlockHeader& block) { SetNull(); @@ -437,20 +437,20 @@ private: std::vector<CBlockIndex*> vChain; public: - /** Returns the index entry for the genesis block of this chain, or NULL if none. */ + /** Returns the index entry for the genesis block of this chain, or nullptr if none. */ CBlockIndex *Genesis() const { - return vChain.size() > 0 ? vChain[0] : NULL; + return vChain.size() > 0 ? vChain[0] : nullptr; } - /** Returns the index entry for the tip of this chain, or NULL if none. */ + /** Returns the index entry for the tip of this chain, or nullptr if none. */ CBlockIndex *Tip() const { - return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL; + return vChain.size() > 0 ? vChain[vChain.size() - 1] : nullptr; } - /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ + /** Returns the index entry at a particular height in this chain, or nullptr if no such height exists. */ CBlockIndex *operator[](int nHeight) const { if (nHeight < 0 || nHeight >= (int)vChain.size()) - return NULL; + return nullptr; return vChain[nHeight]; } @@ -465,12 +465,12 @@ public: return (*this)[pindex->nHeight] == pindex; } - /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */ + /** Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip. */ CBlockIndex *Next(const CBlockIndex *pindex) const { if (Contains(pindex)) return (*this)[pindex->nHeight + 1]; else - return NULL; + return nullptr; } /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */ @@ -482,7 +482,7 @@ public: void SetTip(CBlockIndex *pindex); /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ - CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const; + CBlockLocator GetLocator(const CBlockIndex *pindex = nullptr) const; /** Find the last common block between this chain and a block index entry. */ const CBlockIndex *FindFork(const CBlockIndex *pindex) const; diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 43c9a13c54..224c9eb0ea 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -89,8 +89,8 @@ void SelectBaseParams(const std::string& chain) std::string ChainNameFromCommandLine() { - bool fRegTest = GetBoolArg("-regtest", false); - bool fTestNet = GetBoolArg("-testnet", false); + bool fRegTest = gArgs.GetBoolArg("-regtest", false); + bool fTestNet = gArgs.GetBoolArg("-testnet", false); if (fTestNet && fRegTest) throw std::runtime_error("Invalid combination of -regtest and -testnet."); diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index e6b5fb72a7..5afe3e66b6 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -26,7 +26,7 @@ namespace Checkpoints { if (t != mapBlockIndex.end()) return t->second; } - return NULL; + return nullptr; } } // namespace Checkpoints diff --git a/src/checkqueue.h b/src/checkqueue.h index 408e278d21..6377fbe942 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -131,7 +131,7 @@ public: boost::mutex ControlMutex; //! Create a new check queue - CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} + explicit CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} //! Worker thread void Thread() @@ -183,15 +183,15 @@ public: CCheckQueueControl& operator=(const CCheckQueueControl&) = delete; explicit CCheckQueueControl(CCheckQueue<T> * const pqueueIn) : pqueue(pqueueIn), fDone(false) { - // passed queue is supposed to be unused, or NULL - if (pqueue != NULL) { + // passed queue is supposed to be unused, or nullptr + if (pqueue != nullptr) { ENTER_CRITICAL_SECTION(pqueue->ControlMutex); } } bool Wait() { - if (pqueue == NULL) + if (pqueue == nullptr) return true; bool fRet = pqueue->Wait(); fDone = true; @@ -200,7 +200,7 @@ public: void Add(std::vector<T>& vChecks) { - if (pqueue != NULL) + if (pqueue != nullptr) pqueue->Add(vChecks); } @@ -208,7 +208,7 @@ public: { if (!fDone) Wait(); - if (pqueue != NULL) { + if (pqueue != nullptr) { LEAVE_CRITICAL_SECTION(pqueue->ControlMutex); } } diff --git a/src/coins.cpp b/src/coins.cpp index e30bda930a..b45dfc3342 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -14,7 +14,7 @@ bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return f uint256 CCoinsView::GetBestBlock() const { return uint256(); } std::vector<uint256> CCoinsView::GetHeadBlocks() const { return std::vector<uint256>(); } bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; } -CCoinsViewCursor *CCoinsView::Cursor() const { return 0; } +CCoinsViewCursor *CCoinsView::Cursor() const { return nullptr; } bool CCoinsView::HaveCoin(const COutPoint &outpoint) const { diff --git a/src/compressor.h b/src/compressor.h index 015911484a..094c1bcfe1 100644 --- a/src/compressor.h +++ b/src/compressor.h @@ -53,7 +53,7 @@ protected: unsigned int GetSpecialSize(unsigned int nSize) const; bool Decompress(unsigned int nSize, const std::vector<unsigned char> &out); public: - CScriptCompressor(CScript &scriptIn) : script(scriptIn) { } + explicit CScriptCompressor(CScript &scriptIn) : script(scriptIn) { } template<typename Stream> void Serialize(Stream &s) const { @@ -99,7 +99,7 @@ public: static uint64_t CompressAmount(uint64_t nAmount); static uint64_t DecompressAmount(uint64_t nAmount); - CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } + explicit CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } ADD_SERIALIZE_METHODS; diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp index 1ce5a9d87e..798ce4b5fd 100644 --- a/src/consensus/merkle.cpp +++ b/src/consensus/merkle.cpp @@ -132,13 +132,13 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated) { uint256 hash; - MerkleComputation(leaves, &hash, mutated, -1, NULL); + MerkleComputation(leaves, &hash, mutated, -1, nullptr); return hash; } std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position) { std::vector<uint256> ret; - MerkleComputation(leaves, NULL, NULL, position, &ret); + MerkleComputation(leaves, nullptr, nullptr, position, &ret); return ret; } diff --git a/src/consensus/merkle.h b/src/consensus/merkle.h index 194aea9b75..33764c7460 100644 --- a/src/consensus/merkle.h +++ b/src/consensus/merkle.h @@ -12,7 +12,7 @@ #include "primitives/block.h" #include "uint256.h" -uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated = NULL); +uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated = nullptr); std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position); uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& branch, uint32_t position); @@ -20,13 +20,13 @@ uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint2 * Compute the Merkle root of the transactions in a block. * *mutated is set to true if a duplicated subtree was found. */ -uint256 BlockMerkleRoot(const CBlock& block, bool* mutated = NULL); +uint256 BlockMerkleRoot(const CBlock& block, bool* mutated = nullptr); /* * Compute the Merkle root of the witness transactions in a block. * *mutated is set to true if a duplicated subtree was found. */ -uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated = NULL); +uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated = nullptr); /* * Compute the Merkle branch for the tree of transactions in a block, for a diff --git a/src/core_io.h b/src/core_io.h index 2d63be5fc4..ccc72ebb32 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_CORE_IO_H #define BITCOIN_CORE_IO_H +#include "amount.h" + #include <string> #include <vector> @@ -25,9 +27,10 @@ uint256 ParseHashStr(const std::string&, const std::string& strName); std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName); // core_write.cpp +UniValue ValueFromAmount(const CAmount& amount); std::string FormatScript(const CScript& script); std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0); void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); -void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry); +void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, int serialize_flags = 0); #endif // BITCOIN_CORE_IO_H diff --git a/src/core_write.cpp b/src/core_write.cpp index a366ef933c..1431fa0c9b 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -16,6 +16,16 @@ #include "utilmoneystr.h" #include "utilstrencodings.h" +UniValue ValueFromAmount(const CAmount& amount) +{ + bool sign = amount < 0; + int64_t n_abs = (sign ? -amount : amount); + int64_t quotient = n_abs / COIN; + int64_t remainder = n_abs % COIN; + return UniValue(UniValue::VNUM, + strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder)); +} + std::string FormatScript(const CScript& script) { std::string ret; @@ -92,7 +102,7 @@ std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDeco // this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to // the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the // checks in CheckSignatureEncoding. - if (CheckSignatureEncoding(vch, SCRIPT_VERIFY_STRICTENC, NULL)) { + if (CheckSignatureEncoding(vch, SCRIPT_VERIFY_STRICTENC, nullptr)) { const unsigned char chSigHashType = vch.back(); if (mapSigHashTypes.count(chSigHashType)) { strSigHashDecode = "[" + mapSigHashTypes.find(chSigHashType)->second + "]"; @@ -143,7 +153,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey, out.pushKV("addresses", a); } -void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) +void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags) { entry.pushKV("txid", tx.GetHash().GetHex()); entry.pushKV("hash", tx.GetWitnessHash().GetHex()); @@ -184,8 +194,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) UniValue out(UniValue::VOBJ); - UniValue outValue(UniValue::VNUM, FormatMoney(txout.nValue)); - out.pushKV("value", outValue); + out.pushKV("value", ValueFromAmount(txout.nValue)); out.pushKV("n", (int64_t)i); UniValue o(UniValue::VOBJ); @@ -198,5 +207,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) if (!hashBlock.IsNull()) entry.pushKV("blockhash", hashBlock.GetHex()); - entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction". + if (include_hex) { + entry.pushKV("hex", EncodeHexTx(tx, serialize_flags)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction". + } } diff --git a/src/crypto/aes.h b/src/crypto/aes.h index e9f1b52e71..a7b63b19df 100644 --- a/src/crypto/aes.h +++ b/src/crypto/aes.h @@ -22,7 +22,7 @@ private: AES128_ctx ctx; public: - AES128Encrypt(const unsigned char key[16]); + explicit AES128Encrypt(const unsigned char key[16]); ~AES128Encrypt(); void Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const; }; @@ -34,7 +34,7 @@ private: AES128_ctx ctx; public: - AES128Decrypt(const unsigned char key[16]); + explicit AES128Decrypt(const unsigned char key[16]); ~AES128Decrypt(); void Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const; }; @@ -46,7 +46,7 @@ private: AES256_ctx ctx; public: - AES256Encrypt(const unsigned char key[32]); + explicit AES256Encrypt(const unsigned char key[32]); ~AES256Encrypt(); void Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const; }; @@ -58,7 +58,7 @@ private: AES256_ctx ctx; public: - AES256Decrypt(const unsigned char key[32]); + explicit AES256Decrypt(const unsigned char key[32]); ~AES256Decrypt(); void Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const; }; diff --git a/src/crypto/chacha20.cpp b/src/crypto/chacha20.cpp index 816ae870e1..4038ae9f86 100644 --- a/src/crypto/chacha20.cpp +++ b/src/crypto/chacha20.cpp @@ -75,7 +75,7 @@ void ChaCha20::Output(unsigned char* c, size_t bytes) { uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; - unsigned char *ctarget = NULL; + unsigned char *ctarget = nullptr; unsigned char tmp[64]; unsigned int i; diff --git a/src/cuckoocache.h b/src/cuckoocache.h index fd24d05ee7..9246a3924e 100644 --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -58,7 +58,7 @@ public: * @post All calls to bit_is_set (without subsequent bit_unset) will return * true. */ - bit_packed_atomic_flags(uint32_t size) + explicit bit_packed_atomic_flags(uint32_t size) { // pad out the size if needed size = (size + 7) / 8; diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index 3626e0177f..72eeeef2c3 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -92,7 +92,7 @@ static leveldb::Options GetOptions(size_t nCacheSize) CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bool fWipe, bool obfuscate) { - penv = NULL; + penv = nullptr; readoptions.verify_checksums = true; iteroptions.verify_checksums = true; iteroptions.fill_cache = false; @@ -115,7 +115,7 @@ CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bo dbwrapper_private::HandleError(status); LogPrintf("Opened LevelDB successfully\n"); - if (GetBoolArg("-forcecompactdb", false)) { + if (gArgs.GetBoolArg("-forcecompactdb", false)) { LogPrintf("Starting database compaction of %s\n", path.string()); pdb->CompactRange(nullptr, nullptr); LogPrintf("Finished database compaction of %s\n", path.string()); @@ -144,15 +144,15 @@ CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bo CDBWrapper::~CDBWrapper() { delete pdb; - pdb = NULL; + pdb = nullptr; delete options.filter_policy; - options.filter_policy = NULL; + options.filter_policy = nullptr; delete options.info_log; - options.info_log = NULL; + options.info_log = nullptr; delete options.block_cache; - options.block_cache = NULL; + options.block_cache = nullptr; delete penv; - options.env = NULL; + options.env = nullptr; } bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync) @@ -190,7 +190,7 @@ bool CDBWrapper::IsEmpty() } CDBIterator::~CDBIterator() { delete piter; } -bool CDBIterator::Valid() { return piter->Valid(); } +bool CDBIterator::Valid() const { return piter->Valid(); } void CDBIterator::SeekToFirst() { piter->SeekToFirst(); } void CDBIterator::Next() { piter->Next(); } diff --git a/src/dbwrapper.h b/src/dbwrapper.h index d36188652a..e19fde51c1 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -22,7 +22,7 @@ static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024; class dbwrapper_error : public std::runtime_error { public: - dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {} + explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {} }; class CDBWrapper; @@ -61,7 +61,7 @@ public: /** * @param[in] _parent CDBWrapper that this batch is to be submitted to */ - CDBBatch(const CDBWrapper &_parent) : parent(_parent), ssKey(SER_DISK, CLIENT_VERSION), ssValue(SER_DISK, CLIENT_VERSION), size_estimate(0) { }; + explicit CDBBatch(const CDBWrapper &_parent) : parent(_parent), ssKey(SER_DISK, CLIENT_VERSION), ssValue(SER_DISK, CLIENT_VERSION), size_estimate(0) { }; void Clear() { @@ -130,7 +130,7 @@ public: parent(_parent), piter(_piter) { }; ~CDBIterator(); - bool Valid(); + bool Valid() const; void SeekToFirst(); @@ -177,7 +177,7 @@ class CDBWrapper { friend const std::vector<unsigned char>& dbwrapper_private::GetObfuscateKey(const CDBWrapper &w); private: - //! custom environment this database is using (may be NULL in case of default environment) + //! custom environment this database is using (may be nullptr in case of default environment) leveldb::Env* penv; //! database options used diff --git a/src/hash.h b/src/hash.h index b9952d39fc..ad59bb1817 100644 --- a/src/hash.h +++ b/src/hash.h @@ -168,7 +168,7 @@ private: Source* source; public: - CHashVerifier(Source* source_) : CHashWriter(source_->GetType(), source_->GetVersion()), source(source_) {} + explicit CHashVerifier(Source* source_) : CHashWriter(source_->GetType(), source_->GetVersion()), source(source_) {} void read(char* pch, size_t nSize) { diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 69c3e3f49f..91f96ef207 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -43,7 +43,7 @@ private: class HTTPRPCTimerInterface : public RPCTimerInterface { public: - HTTPRPCTimerInterface(struct event_base* _base) : base(_base) + explicit HTTPRPCTimerInterface(struct event_base* _base) : base(_base) { } const char* Name() override @@ -62,7 +62,7 @@ private: /* Pre-base64-encoded authentication token */ static std::string strRPCUserColonPass; /* Stored RPC timer interface (for unregistration) */ -static HTTPRPCTimerInterface* httpRPCTimerInterface = 0; +static HTTPRPCTimerInterface* httpRPCTimerInterface = nullptr; static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const UniValue& id) { @@ -210,7 +210,7 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) static bool InitRPCAuthentication() { - if (GetArg("-rpcpassword", "") == "") + if (gArgs.GetArg("-rpcpassword", "") == "") { LogPrintf("No rpcpassword set - using random cookie authentication\n"); if (!GenerateAuthCookie(&strRPCUserColonPass)) { @@ -221,7 +221,7 @@ static bool InitRPCAuthentication() } } else { LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation.\n"); - strRPCUserColonPass = GetArg("-rpcuser", "") + ":" + GetArg("-rpcpassword", ""); + strRPCUserColonPass = gArgs.GetArg("-rpcuser", "") + ":" + gArgs.GetArg("-rpcpassword", ""); } return true; } @@ -255,6 +255,6 @@ void StopHTTPRPC() if (httpRPCTimerInterface) { RPCUnsetTimerInterface(httpRPCTimerInterface); delete httpRPCTimerInterface; - httpRPCTimerInterface = 0; + httpRPCTimerInterface = nullptr; } } diff --git a/src/httpserver.cpp b/src/httpserver.cpp index ba01255400..5923871691 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -40,7 +40,7 @@ static const size_t MAX_HEADERS_SIZE = 8192; /** HTTP request work item */ -class HTTPWorkItem : public HTTPClosure +class HTTPWorkItem final : public HTTPClosure { public: HTTPWorkItem(std::unique_ptr<HTTPRequest> _req, const std::string &_path, const HTTPRequestHandler& _func): @@ -79,7 +79,7 @@ private: { public: WorkQueue &wq; - ThreadCounter(WorkQueue &w): wq(w) + explicit ThreadCounter(WorkQueue &w): wq(w) { std::lock_guard<std::mutex> lock(wq.cs); wq.numThreads += 1; @@ -93,7 +93,7 @@ private: }; public: - WorkQueue(size_t _maxDepth) : running(true), + explicit WorkQueue(size_t _maxDepth) : running(true), maxDepth(_maxDepth), numThreads(0) { @@ -164,13 +164,13 @@ struct HTTPPathHandler /** HTTP module state */ //! libevent event loop -static struct event_base* eventBase = 0; +static struct event_base* eventBase = nullptr; //! HTTP server -struct evhttp* eventHTTP = 0; +struct evhttp* eventHTTP = nullptr; //! List of subnets to allow RPC connections from static std::vector<CSubNet> rpc_allow_subnets; //! Work queue for handling longer requests off the event loop thread -static WorkQueue<HTTPClosure>* workQueue = 0; +static WorkQueue<HTTPClosure>* workQueue = nullptr; //! Handlers for (sub)paths std::vector<HTTPPathHandler> pathHandlers; //! Bound listening sockets @@ -292,7 +292,7 @@ static void http_request_cb(struct evhttp_request* req, void* arg) static void http_reject_request_cb(struct evhttp_request* req, void*) { LogPrint(BCLog::HTTP, "Rejecting request while shutting down\n"); - evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL); + evhttp_send_error(req, HTTP_SERVUNAVAIL, nullptr); } /** Event dispatcher thread */ @@ -309,14 +309,14 @@ static bool ThreadHTTP(struct event_base* base, struct evhttp* http) /** Bind HTTP server to specified addresses */ static bool HTTPBindAddresses(struct evhttp* http) { - int defaultPort = GetArg("-rpcport", BaseParams().RPCPort()); + int defaultPort = gArgs.GetArg("-rpcport", BaseParams().RPCPort()); std::vector<std::pair<std::string, uint16_t> > endpoints; // Determine what addresses to bind to - if (!IsArgSet("-rpcallowip")) { // Default to loopback if not allowing external IPs + if (!gArgs.IsArgSet("-rpcallowip")) { // Default to loopback if not allowing external IPs endpoints.push_back(std::make_pair("::1", defaultPort)); endpoints.push_back(std::make_pair("127.0.0.1", defaultPort)); - if (IsArgSet("-rpcbind")) { + if (gArgs.IsArgSet("-rpcbind")) { LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n"); } } else if (gArgs.IsArgSet("-rpcbind")) { // Specific bind address @@ -334,7 +334,7 @@ static bool HTTPBindAddresses(struct evhttp* http) // Bind addresses for (std::vector<std::pair<std::string, uint16_t> >::iterator i = endpoints.begin(); i != endpoints.end(); ++i) { LogPrint(BCLog::HTTP, "Binding RPC on address %s port %i\n", i->first, i->second); - evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle(http, i->first.empty() ? NULL : i->first.c_str(), i->second); + evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle(http, i->first.empty() ? nullptr : i->first.c_str(), i->second); if (bind_handle) { boundSockets.push_back(bind_handle); } else { @@ -369,7 +369,7 @@ bool InitHTTPServer() if (!InitHTTPAllowList()) return false; - if (GetBoolArg("-rpcssl", false)) { + if (gArgs.GetBoolArg("-rpcssl", false)) { uiInterface.ThreadSafeMessageBox( "SSL mode for RPC (-rpcssl) is no longer supported.", "", CClientUIInterface::MSG_ERROR); @@ -401,10 +401,10 @@ bool InitHTTPServer() return false; } - evhttp_set_timeout(http, GetArg("-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT)); + evhttp_set_timeout(http, gArgs.GetArg("-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT)); evhttp_set_max_headers_size(http, MAX_HEADERS_SIZE); evhttp_set_max_body_size(http, MAX_SIZE); - evhttp_set_gencb(http, http_request_cb, NULL); + evhttp_set_gencb(http, http_request_cb, nullptr); if (!HTTPBindAddresses(http)) { LogPrintf("Unable to bind any endpoint for RPC server\n"); @@ -412,11 +412,11 @@ bool InitHTTPServer() } LogPrint(BCLog::HTTP, "Initialized HTTP server\n"); - int workQueueDepth = std::max((long)GetArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L); + int workQueueDepth = std::max((long)gArgs.GetArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L); LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth); workQueue = new WorkQueue<HTTPClosure>(workQueueDepth); - // tranfer ownership to eventBase/HTTP via .release() + // transfer ownership to eventBase/HTTP via .release() eventBase = base_ctr.release(); eventHTTP = http_ctr.release(); return true; @@ -442,7 +442,7 @@ std::future<bool> threadResult; bool StartHTTPServer() { LogPrint(BCLog::HTTP, "Starting HTTP server\n"); - int rpcThreads = std::max((long)GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L); + int rpcThreads = std::max((long)gArgs.GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L); LogPrintf("HTTP: starting %d worker threads\n", rpcThreads); std::packaged_task<bool(event_base*, evhttp*)> task(ThreadHTTP); threadResult = task.get_future(); @@ -464,7 +464,7 @@ void InterruptHTTPServer() evhttp_del_accept_socket(eventHTTP, socket); } // Reject requests on current connections - evhttp_set_gencb(eventHTTP, http_reject_request_cb, NULL); + evhttp_set_gencb(eventHTTP, http_reject_request_cb, nullptr); } if (workQueue) workQueue->Interrupt(); @@ -495,11 +495,11 @@ void StopHTTPServer() } if (eventHTTP) { evhttp_free(eventHTTP); - eventHTTP = 0; + eventHTTP = nullptr; } if (eventBase) { event_base_free(eventBase); - eventBase = 0; + eventBase = nullptr; } LogPrint(BCLog::HTTP, "Stopped HTTP server\n"); } @@ -530,7 +530,7 @@ HTTPEvent::~HTTPEvent() } void HTTPEvent::trigger(struct timeval* tv) { - if (tv == NULL) + if (tv == nullptr) event_active(ev, 0, 0); // immediately trigger event in main thread else evtimer_add(ev, tv); // trigger after timeval passed @@ -573,7 +573,7 @@ std::string HTTPRequest::ReadBody() * abstraction to consume the evbuffer on the fly in the parsing algorithm. */ const char* data = (const char*)evbuffer_pullup(buf, size); - if (!data) // returns NULL in case of empty buffer + if (!data) // returns nullptr in case of empty buffer return ""; std::string rv(data, size); evbuffer_drain(buf, size); @@ -600,10 +600,10 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply) assert(evb); evbuffer_add(evb, strReply.data(), strReply.size()); HTTPEvent* ev = new HTTPEvent(eventBase, true, - std::bind(evhttp_send_reply, req, nStatus, (const char*)NULL, (struct evbuffer *)NULL)); - ev->trigger(0); + std::bind(evhttp_send_reply, req, nStatus, (const char*)nullptr, (struct evbuffer *)nullptr)); + ev->trigger(nullptr); replySent = true; - req = 0; // transferred back to main thread + req = nullptr; // transferred back to main thread } CService HTTPRequest::GetPeer() @@ -669,7 +669,7 @@ void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch) std::string urlDecode(const std::string &urlEncoded) { std::string res; if (!urlEncoded.empty()) { - char *decoded = evhttp_uridecode(urlEncoded.c_str(), false, NULL); + char *decoded = evhttp_uridecode(urlEncoded.c_str(), false, nullptr); if (decoded) { res = std::string(decoded); free(decoded); diff --git a/src/httpserver.h b/src/httpserver.h index 3e434bf0a0..91ce5b4e00 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -61,7 +61,7 @@ private: bool replySent; public: - HTTPRequest(struct evhttp_request* req); + explicit HTTPRequest(struct evhttp_request* req); ~HTTPRequest(); enum RequestMethod { diff --git a/src/init.cpp b/src/init.cpp index e3fc3fc923..3f68ea1021 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -69,14 +69,14 @@ bool fFeeEstimatesInitialized = false; static const bool DEFAULT_PROXYRANDOMIZE = true; static const bool DEFAULT_REST_ENABLE = false; -static const bool DEFAULT_DISABLE_SAFEMODE = false; +static const bool DEFAULT_DISABLE_SAFEMODE = true; static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; std::unique_ptr<CConnman> g_connman; std::unique_ptr<PeerLogicValidation> peerLogic; #if ENABLE_ZMQ -static CZMQNotificationInterface* pzmqNotificationInterface = NULL; +static CZMQNotificationInterface* pzmqNotificationInterface = nullptr; #endif #ifdef WIN32 @@ -133,10 +133,10 @@ bool ShutdownRequested() * chainstate, while keeping user interface out of the common library, which is shared * between bitcoind, and bitcoin-qt and non-server tools. */ -class CCoinsViewErrorCatcher : public CCoinsViewBacked +class CCoinsViewErrorCatcher final : public CCoinsViewBacked { public: - CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {} + explicit CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {} bool GetCoin(const COutPoint &outpoint, Coin &coin) const override { try { return CCoinsViewBacked::GetCoin(outpoint, coin); @@ -153,7 +153,7 @@ public: // Writes do not need similar protection, as failure to write is handled by the caller. }; -static CCoinsViewErrorCatcher *pcoinscatcher = NULL; +static CCoinsViewErrorCatcher *pcoinscatcher = nullptr; static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle; void Interrupt(boost::thread_group& threadGroup) @@ -199,7 +199,7 @@ void Shutdown() StopTorControl(); UnregisterNodeSignals(GetNodeSignals()); - if (fDumpMempoolLater && GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { + if (fDumpMempoolLater && gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { DumpMempool(); } @@ -232,17 +232,17 @@ void Shutdown() { LOCK(cs_main); - if (pcoinsTip != NULL) { + if (pcoinsTip != nullptr) { FlushStateToDisk(); } delete pcoinsTip; - pcoinsTip = NULL; + pcoinsTip = nullptr; delete pcoinscatcher; - pcoinscatcher = NULL; + pcoinscatcher = nullptr; delete pcoinsdbview; - pcoinsdbview = NULL; + pcoinsdbview = nullptr; delete pblocktree; - pblocktree = NULL; + pblocktree = nullptr; } #ifdef ENABLE_WALLET for (CWalletRef pwallet : vpwallets) { @@ -254,7 +254,7 @@ void Shutdown() if (pzmqNotificationInterface) { UnregisterValidationInterface(pzmqNotificationInterface); delete pzmqNotificationInterface; - pzmqNotificationInterface = NULL; + pzmqNotificationInterface = nullptr; } #endif @@ -300,7 +300,7 @@ static void registerSignalHandler(int signal, void(*handler)(int)) sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - sigaction(signal, &sa, NULL); + sigaction(signal, &sa, nullptr); } #endif @@ -321,7 +321,7 @@ void OnRPCPreCommand(const CRPCCommand& cmd) { // Observe safe mode std::string strWarning = GetWarnings("rpc"); - if (strWarning != "" && !GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) && + if (strWarning != "" && !gArgs.GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) && !cmd.okSafeMode) throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + strWarning); } @@ -332,7 +332,7 @@ std::string HelpMessage(HelpMessageMode mode) const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET); const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN); const auto testnetChainParams = CreateChainParams(CBaseChainParams::TESTNET); - const bool showDebug = GetBoolArg("-help-debug", false); + const bool showDebug = gArgs.GetBoolArg("-help-debug", false); // When adding new options to the categories, please keep and ensure alphabetical ordering. // Do not translate _(...) -help-debug options, Many technical terms, and only a very small audience, so is unnecessary stress to translators. @@ -546,7 +546,7 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex if (initialSync || !pBlockIndex) return; - std::string strCmd = GetArg("-blocknotify", ""); + std::string strCmd = gArgs.GetArg("-blocknotify", ""); boost::replace_all(strCmd, "%s", pBlockIndex->GetBlockHash().GetHex()); boost::thread t(runCommand, strCmd); // thread runs free @@ -558,7 +558,7 @@ static CConditionVariable condvar_GenesisWait; static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex) { - if (pBlockIndex != NULL) { + if (pBlockIndex != nullptr) { { boost::unique_lock<boost::mutex> lock_GenesisWait(cs_GenesisWait); fHaveGenesis = true; @@ -683,12 +683,12 @@ void ThreadImport(std::vector<fs::path> vImportFiles) StartShutdown(); } - if (GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) { + if (gArgs.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) { LogPrintf("Stopping after block import\n"); StartShutdown(); } } // End scope of CImportingNow - if (GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { + if (gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { LoadMempool(); fDumpMempoolLater = !fRequestShutdown; } @@ -727,7 +727,7 @@ bool AppInitServers(boost::thread_group& threadGroup) return false; if (!StartHTTPRPC()) return false; - if (GetBoolArg("-rest", DEFAULT_REST_ENABLE) && !StartREST()) + if (gArgs.GetBoolArg("-rest", DEFAULT_REST_ENABLE) && !StartREST()) return false; if (!StartHTTPServer()) return false; @@ -739,61 +739,61 @@ void InitParameterInteraction() { // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified - if (IsArgSet("-bind")) { - if (SoftSetBoolArg("-listen", true)) + if (gArgs.IsArgSet("-bind")) { + if (gArgs.SoftSetBoolArg("-listen", true)) LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__); } - if (IsArgSet("-whitebind")) { - if (SoftSetBoolArg("-listen", true)) + if (gArgs.IsArgSet("-whitebind")) { + if (gArgs.SoftSetBoolArg("-listen", true)) LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__); } if (gArgs.IsArgSet("-connect")) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default - if (SoftSetBoolArg("-dnsseed", false)) + if (gArgs.SoftSetBoolArg("-dnsseed", false)) LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__); - if (SoftSetBoolArg("-listen", false)) + if (gArgs.SoftSetBoolArg("-listen", false)) LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__); } - if (IsArgSet("-proxy")) { + if (gArgs.IsArgSet("-proxy")) { // to protect privacy, do not listen by default if a default proxy server is specified - if (SoftSetBoolArg("-listen", false)) + if (gArgs.SoftSetBoolArg("-listen", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__); // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1 // to listen locally, so don't rely on this happening through -listen below. - if (SoftSetBoolArg("-upnp", false)) + if (gArgs.SoftSetBoolArg("-upnp", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__); // to protect privacy, do not discover addresses by default - if (SoftSetBoolArg("-discover", false)) + if (gArgs.SoftSetBoolArg("-discover", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__); } - if (!GetBoolArg("-listen", DEFAULT_LISTEN)) { + if (!gArgs.GetBoolArg("-listen", DEFAULT_LISTEN)) { // do not map ports or try to retrieve public IP when not listening (pointless) - if (SoftSetBoolArg("-upnp", false)) + if (gArgs.SoftSetBoolArg("-upnp", false)) LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__); - if (SoftSetBoolArg("-discover", false)) + if (gArgs.SoftSetBoolArg("-discover", false)) LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__); - if (SoftSetBoolArg("-listenonion", false)) + if (gArgs.SoftSetBoolArg("-listenonion", false)) LogPrintf("%s: parameter interaction: -listen=0 -> setting -listenonion=0\n", __func__); } - if (IsArgSet("-externalip")) { + if (gArgs.IsArgSet("-externalip")) { // if an explicit public IP is specified, do not try to find others - if (SoftSetBoolArg("-discover", false)) + if (gArgs.SoftSetBoolArg("-discover", false)) LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__); } // disable whitelistrelay in blocksonly mode - if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) { - if (SoftSetBoolArg("-whitelistrelay", false)) + if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) { + if (gArgs.SoftSetBoolArg("-whitelistrelay", false)) LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__); } // Forcing relay from whitelisted hosts implies we will accept relays from them in the first place. - if (GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { - if (SoftSetBoolArg("-whitelistrelay", true)) + if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { + if (gArgs.SoftSetBoolArg("-whitelistrelay", true)) LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1\n", __func__); } } @@ -805,10 +805,10 @@ static std::string ResolveErrMsg(const char * const optname, const std::string& void InitLogging() { - fPrintToConsole = GetBoolArg("-printtoconsole", false); - fLogTimestamps = GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); - fLogTimeMicros = GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); - fLogIPs = GetBoolArg("-logips", DEFAULT_LOGIPS); + fPrintToConsole = gArgs.GetBoolArg("-printtoconsole", false); + fLogTimestamps = gArgs.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); + fLogTimeMicros = gArgs.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); + fLogIPs = gArgs.GetBoolArg("-logips", DEFAULT_LOGIPS); LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); LogPrintf("Bitcoin version %s\n", FormatFullVersion()); @@ -843,7 +843,7 @@ bool AppInitBasicSetup() #ifdef _MSC_VER // Turn off Microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); + _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0)); // Disable confusing "helpful" text message on abort, Ctrl-C _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif @@ -858,14 +858,14 @@ bool AppInitBasicSetup() #endif typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD); PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); - if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); + if (setProcDEPPol != nullptr) setProcDEPPol(PROCESS_DEP_ENABLE); #endif if (!SetupNetworking()) return InitError("Initializing networking failed"); #ifndef WIN32 - if (!GetBoolArg("-sysperms", false)) { + if (!gArgs.GetBoolArg("-sysperms", false)) { umask(077); } @@ -893,8 +893,8 @@ bool AppInitParameterInteraction() // also see: InitParameterInteraction() // if using block pruning, then disallow txindex - if (GetArg("-prune", 0)) { - if (GetBoolArg("-txindex", DEFAULT_TXINDEX)) + if (gArgs.GetArg("-prune", 0)) { + if (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) return InitError(_("Prune mode is incompatible with -txindex.")); } @@ -906,7 +906,7 @@ bool AppInitParameterInteraction() // Make sure enough file descriptors are available int nBind = std::max(nUserBind, size_t(1)); - nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); + nUserMaxConnections = gArgs.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); nMaxConnections = std::max(nUserMaxConnections, 0); // Trim requested connection counts, to fit into system limitations @@ -947,55 +947,55 @@ bool AppInitParameterInteraction() } // Check for -debugnet - if (GetBoolArg("-debugnet", false)) + if (gArgs.GetBoolArg("-debugnet", false)) InitWarning(_("Unsupported argument -debugnet ignored, use -debug=net.")); // Check for -socks - as this is a privacy risk to continue, exit here - if (IsArgSet("-socks")) + if (gArgs.IsArgSet("-socks")) return InitError(_("Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.")); // Check for -tor - as this is a privacy risk to continue, exit here - if (GetBoolArg("-tor", false)) + if (gArgs.GetBoolArg("-tor", false)) return InitError(_("Unsupported argument -tor found, use -onion.")); - if (GetBoolArg("-benchmark", false)) + if (gArgs.GetBoolArg("-benchmark", false)) InitWarning(_("Unsupported argument -benchmark ignored, use -debug=bench.")); - if (GetBoolArg("-whitelistalwaysrelay", false)) + if (gArgs.GetBoolArg("-whitelistalwaysrelay", false)) InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay.")); - if (IsArgSet("-blockminsize")) + if (gArgs.IsArgSet("-blockminsize")) InitWarning("Unsupported argument -blockminsize ignored."); // Checkmempool and checkblockindex default to true in regtest mode - int ratio = std::min<int>(std::max<int>(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); + int ratio = std::min<int>(std::max<int>(gArgs.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); if (ratio != 0) { mempool.setSanityCheck(1.0 / ratio); } - fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); - fCheckpointsEnabled = GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED); + fCheckBlockIndex = gArgs.GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); + fCheckpointsEnabled = gArgs.GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED); - hashAssumeValid = uint256S(GetArg("-assumevalid", chainparams.GetConsensus().defaultAssumeValid.GetHex())); + hashAssumeValid = uint256S(gArgs.GetArg("-assumevalid", chainparams.GetConsensus().defaultAssumeValid.GetHex())); if (!hashAssumeValid.IsNull()) LogPrintf("Assuming ancestors of block %s have valid signatures.\n", hashAssumeValid.GetHex()); else LogPrintf("Validating signatures for all blocks.\n"); // mempool limits - int64_t nMempoolSizeMax = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; - int64_t nMempoolSizeMin = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40; + int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + int64_t nMempoolSizeMin = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40; if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin) return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(nMempoolSizeMin / 1000000.0))); // incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool // and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting. - if (IsArgSet("-incrementalrelayfee")) + if (gArgs.IsArgSet("-incrementalrelayfee")) { CAmount n = 0; - if (!ParseMoney(GetArg("-incrementalrelayfee", ""), n)) - return InitError(AmountErrMsg("incrementalrelayfee", GetArg("-incrementalrelayfee", ""))); + if (!ParseMoney(gArgs.GetArg("-incrementalrelayfee", ""), n)) + return InitError(AmountErrMsg("incrementalrelayfee", gArgs.GetArg("-incrementalrelayfee", ""))); incrementalRelayFee = CFeeRate(n); } // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency - nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS); + nScriptCheckThreads = gArgs.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS); if (nScriptCheckThreads <= 0) nScriptCheckThreads += GetNumCores(); if (nScriptCheckThreads <= 1) @@ -1004,7 +1004,7 @@ bool AppInitParameterInteraction() nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS; // block pruning; get the amount of disk space (in MiB) to allot for block & undo files - int64_t nPruneArg = GetArg("-prune", 0); + int64_t nPruneArg = gArgs.GetArg("-prune", 0); if (nPruneArg < 0) { return InitError(_("Prune cannot be configured with a negative value.")); } @@ -1026,14 +1026,14 @@ bool AppInitParameterInteraction() RegisterWalletRPCCommands(tableRPC); #endif - nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); + nConnectTimeout = gArgs.GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); if (nConnectTimeout <= 0) nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; - if (IsArgSet("-minrelaytxfee")) { + if (gArgs.IsArgSet("-minrelaytxfee")) { CAmount n = 0; - if (!ParseMoney(GetArg("-minrelaytxfee", ""), n)) { - return InitError(AmountErrMsg("minrelaytxfee", GetArg("-minrelaytxfee", ""))); + if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) { + return InitError(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", ""))); } // High fee check is done afterward in CWallet::ParameterInteraction() ::minRelayTxFee = CFeeRate(n); @@ -1045,55 +1045,55 @@ bool AppInitParameterInteraction() // Sanity check argument for min fee for including tx in block // TODO: Harmonize which arguments need sanity checking and where that happens - if (IsArgSet("-blockmintxfee")) + if (gArgs.IsArgSet("-blockmintxfee")) { CAmount n = 0; - if (!ParseMoney(GetArg("-blockmintxfee", ""), n)) - return InitError(AmountErrMsg("blockmintxfee", GetArg("-blockmintxfee", ""))); + if (!ParseMoney(gArgs.GetArg("-blockmintxfee", ""), n)) + return InitError(AmountErrMsg("blockmintxfee", gArgs.GetArg("-blockmintxfee", ""))); } // Feerate used to define dust. Shouldn't be changed lightly as old // implementations may inadvertently create non-standard transactions - if (IsArgSet("-dustrelayfee")) + if (gArgs.IsArgSet("-dustrelayfee")) { CAmount n = 0; - if (!ParseMoney(GetArg("-dustrelayfee", ""), n) || 0 == n) - return InitError(AmountErrMsg("dustrelayfee", GetArg("-dustrelayfee", ""))); + if (!ParseMoney(gArgs.GetArg("-dustrelayfee", ""), n) || 0 == n) + return InitError(AmountErrMsg("dustrelayfee", gArgs.GetArg("-dustrelayfee", ""))); dustRelayFee = CFeeRate(n); } - fRequireStandard = !GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard()); + fRequireStandard = !gArgs.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard()); if (chainparams.RequireStandard() && !fRequireStandard) return InitError(strprintf("acceptnonstdtxn is not currently supported for %s chain", chainparams.NetworkIDString())); - nBytesPerSigOp = GetArg("-bytespersigop", nBytesPerSigOp); + nBytesPerSigOp = gArgs.GetArg("-bytespersigop", nBytesPerSigOp); #ifdef ENABLE_WALLET if (!CWallet::ParameterInteraction()) return false; #endif - fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); - fAcceptDatacarrier = GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER); - nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes); + fIsBareMultisigStd = gArgs.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); + fAcceptDatacarrier = gArgs.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER); + nMaxDatacarrierBytes = gArgs.GetArg("-datacarriersize", nMaxDatacarrierBytes); // Option to startup with mocktime set (used for regression testing): - SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op + SetMockTime(gArgs.GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op - if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) + if (gArgs.GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM); - if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) < 0) + if (gArgs.GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) < 0) return InitError("rpcserialversion must be non-negative."); - if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1) + if (gArgs.GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1) return InitError("unknown rpcserialversion requested."); - nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); + nMaxTipAge = gArgs.GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); - fEnableReplacement = GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT); - if ((!fEnableReplacement) && IsArgSet("-mempoolreplacement")) { + fEnableReplacement = gArgs.GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT); + if ((!fEnableReplacement) && gArgs.IsArgSet("-mempoolreplacement")) { // Minimal effort at forwards compatibility - std::string strReplacementModeList = GetArg("-mempoolreplacement", ""); // default is impossible + std::string strReplacementModeList = gArgs.GetArg("-mempoolreplacement", ""); // default is impossible std::vector<std::string> vstrReplacementModes; boost::split(vstrReplacementModes, strReplacementModeList, boost::is_any_of(",")); fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end()); @@ -1198,7 +1198,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) #ifndef WIN32 CreatePidFile(GetPidFile(), getpid()); #endif - if (GetBoolArg("-shrinkdebugfile", logCategories == BCLog::NONE)) { + if (gArgs.GetBoolArg("-shrinkdebugfile", logCategories == BCLog::NONE)) { // Do this first since it both loads a bunch of debug.log into memory, // and because this needs to happen before any other debug.log printing ShrinkDebugFile(); @@ -1211,7 +1211,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime())); LogPrintf("Default data directory %s\n", GetDefaultDataDir().string()); LogPrintf("Using data directory %s\n", GetDataDir().string()); - LogPrintf("Using config file %s\n", GetConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)).string()); + LogPrintf("Using config file %s\n", GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string()); LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD); InitSignatureCache(); @@ -1234,7 +1234,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) * that the server is there and will be ready later). Warmup mode will * be disabled when initialisation is finished. */ - if (GetBoolArg("-server", false)) + if (gArgs.GetBoolArg("-server", false)) { uiInterface.InitMessage.connect(SetRPCWarmupStatus); if (!AppInitServers(threadGroup)) @@ -1291,12 +1291,12 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } // Check for host lookup allowed before parsing any network related parameters - fNameLookup = GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); + fNameLookup = gArgs.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); - bool proxyRandomize = GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE); + bool proxyRandomize = gArgs.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE); // -proxy sets a proxy for all outgoing network traffic // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default - std::string proxyArg = GetArg("-proxy", ""); + std::string proxyArg = gArgs.GetArg("-proxy", ""); SetLimited(NET_TOR); if (proxyArg != "" && proxyArg != "0") { CService proxyAddr; @@ -1318,7 +1318,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses // -noonion (or -onion=0) disables connecting to .onion entirely // An empty string is used to not override the onion proxy (in which case it defaults to -proxy set above, or none) - std::string onionArg = GetArg("-onion", ""); + std::string onionArg = gArgs.GetArg("-onion", ""); if (onionArg != "") { if (onionArg == "0") { // Handle -noonion/-onion=0 SetLimited(NET_TOR); // set onions as unreachable @@ -1336,9 +1336,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } // see Step 2: parameter interactions for more information about these - fListen = GetBoolArg("-listen", DEFAULT_LISTEN); - fDiscover = GetBoolArg("-discover", true); - fRelayTxes = !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); + fListen = gArgs.GetBoolArg("-listen", DEFAULT_LISTEN); + fDiscover = gArgs.GetBoolArg("-discover", true); + fRelayTxes = !gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); for (const std::string& strAddr : gArgs.GetArgs("-externalip")) { CService addrLocal; @@ -1358,27 +1358,27 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) uint64_t nMaxOutboundLimit = 0; //unlimited unless -maxuploadtarget is set uint64_t nMaxOutboundTimeframe = MAX_UPLOAD_TIMEFRAME; - if (IsArgSet("-maxuploadtarget")) { - nMaxOutboundLimit = GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET)*1024*1024; + if (gArgs.IsArgSet("-maxuploadtarget")) { + nMaxOutboundLimit = gArgs.GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET)*1024*1024; } // ********************************************************* Step 7: load block chain - fReindex = GetBoolArg("-reindex", false); - bool fReindexChainState = GetBoolArg("-reindex-chainstate", false); + fReindex = gArgs.GetBoolArg("-reindex", false); + bool fReindexChainState = gArgs.GetBoolArg("-reindex-chainstate", false); // cache size calculations - int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20); + int64_t nTotalCache = (gArgs.GetArg("-dbcache", nDefaultDbCache) << 20); nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greater than nMaxDbcache int64_t nBlockTreeDBCache = nTotalCache / 8; - nBlockTreeDBCache = std::min(nBlockTreeDBCache, (GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxBlockDBAndTxIndexCache : nMaxBlockDBCache) << 20); + nBlockTreeDBCache = std::min(nBlockTreeDBCache, (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxBlockDBAndTxIndexCache : nMaxBlockDBCache) << 20); nTotalCache -= nBlockTreeDBCache; int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache nCoinDBCache = std::min(nCoinDBCache, nMaxCoinsDBCache << 20); // cap total coins db cache nTotalCache -= nCoinDBCache; nCoinCacheUsage = nTotalCache; // the rest goes to in-memory cache - int64_t nMempoolSizeMax = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; LogPrintf("Cache configuration:\n"); LogPrintf("* Using %.1fMiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024)); LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024)); @@ -1427,7 +1427,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); // Check for changed -txindex state - if (fTxIndex != GetBoolArg("-txindex", DEFAULT_TXINDEX)) { + if (fTxIndex != gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { strLoadError = _("You need to rebuild the database using -reindex-chainstate to change -txindex"); break; } @@ -1477,7 +1477,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) strLoadError = _("Error initializing block database"); break; } - assert(chainActive.Tip() != NULL); + assert(chainActive.Tip() != nullptr); } if (!fReset) { @@ -1493,7 +1493,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) if (!is_coinsview_empty) { uiInterface.InitMessage(_("Verifying blocks...")); - if (fHavePruned && GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { + if (fHavePruned && gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks", MIN_BLOCKS_TO_KEEP); } @@ -1510,8 +1510,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } } - if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview, GetArg("-checklevel", DEFAULT_CHECKLEVEL), - GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { + if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview, gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL), + gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { strLoadError = _("Corrupted block database detected"); break; } @@ -1604,13 +1604,13 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly. // No locking, as this happens before any background thread is started. - if (chainActive.Tip() == NULL) { + if (chainActive.Tip() == nullptr) { uiInterface.NotifyBlockTip.connect(BlockNotifyGenesisWait); } else { fHaveGenesis = true; } - if (IsArgSet("-blocknotify")) + if (gArgs.IsArgSet("-blocknotify")) uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); std::vector<fs::path> vImportFiles; @@ -1634,13 +1634,13 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) //// debug print LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size()); LogPrintf("nBestHeight = %d\n", chainActive.Height()); - if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) + if (gArgs.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) StartTorControl(threadGroup, scheduler); Discover(threadGroup); // Map ports with UPnP - MapPort(GetBoolArg("-upnp", DEFAULT_UPNP)); + MapPort(gArgs.GetBoolArg("-upnp", DEFAULT_UPNP)); CConnman::Options connOptions; connOptions.nLocalServices = nLocalServices; @@ -1651,8 +1651,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) connOptions.nMaxFeeler = 1; connOptions.nBestHeight = chainActive.Height(); connOptions.uiInterface = &uiInterface; - connOptions.nSendBufferMaxSize = 1000*GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER); - connOptions.nReceiveFloodSize = 1000*GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER); + connOptions.nSendBufferMaxSize = 1000*gArgs.GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER); + connOptions.nReceiveFloodSize = 1000*gArgs.GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER); connOptions.nMaxOutboundTimeframe = nMaxOutboundTimeframe; connOptions.nMaxOutboundLimit = nMaxOutboundLimit; diff --git a/src/key.cpp b/src/key.cpp index 5a991fc1d2..315a3978c8 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -13,7 +13,7 @@ #include <secp256k1.h> #include <secp256k1_recovery.h> -static secp256k1_context* secp256k1_context_sign = NULL; +static secp256k1_context* secp256k1_context_sign = nullptr; /** These functions are taken from the libsecp256k1 distribution and are very ugly. */ static int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) { @@ -165,7 +165,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_ unsigned char extra_entropy[32] = {0}; WriteLE32(extra_entropy, test_case); secp256k1_ecdsa_signature sig; - int ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL); + int ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : nullptr); assert(ret); secp256k1_ecdsa_signature_serialize_der(secp256k1_context_sign, (unsigned char*)vchSig.data(), &nSigLen, &sig); vchSig.resize(nSigLen); @@ -192,7 +192,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) vchSig.resize(65); int rec = -1; secp256k1_ecdsa_recoverable_signature sig; - int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, NULL); + int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, nullptr); assert(ret); secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_sign, (unsigned char*)&vchSig[1], &rec, &sig); assert(ret); @@ -289,10 +289,10 @@ bool ECC_InitSanityCheck() { } void ECC_Start() { - assert(secp256k1_context_sign == NULL); + assert(secp256k1_context_sign == nullptr); secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - assert(ctx != NULL); + assert(ctx != nullptr); { // Pass in a random blinding seed to the secp256k1 context. @@ -307,7 +307,7 @@ void ECC_Start() { void ECC_Stop() { secp256k1_context *ctx = secp256k1_context_sign; - secp256k1_context_sign = NULL; + secp256k1_context_sign = nullptr; if (ctx) { secp256k1_context_destroy(ctx); @@ -172,6 +172,8 @@ struct CExtKey { { unsigned int len = ::ReadCompactSize(s); unsigned char code[BIP32_EXTKEY_SIZE]; + if (len != BIP32_EXTKEY_SIZE) + throw std::runtime_error("Invalid extended key size\n"); s.read((char *)&code[0], len); Decode(code); } diff --git a/src/limitedmap.h b/src/limitedmap.h index e9dcb6defd..7afc8b458d 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -27,7 +27,7 @@ protected: size_type nMaxSize; public: - limitedmap(size_type nMaxSizeIn) + explicit limitedmap(size_type nMaxSizeIn) { assert(nMaxSizeIn > 0); nMaxSize = nMaxSizeIn; diff --git a/src/merkleblock.h b/src/merkleblock.h index f590c487de..20f2b36886 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -63,7 +63,7 @@ protected: bool fBad; /** helper function to efficiently calculate the number of nodes at given height in the merkle tree */ - unsigned int CalcTreeWidth(int height) { + unsigned int CalcTreeWidth(int height) const { return (nTransactions+(1 << height)-1) >> height; } diff --git a/src/miner.cpp b/src/miner.cpp index 79016bfd3e..f1942ec570 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -88,20 +88,20 @@ static BlockAssembler::Options DefaultOptions(const CChainParams& params) options.nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT; options.nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE; bool fWeightSet = false; - if (IsArgSet("-blockmaxweight")) { - options.nBlockMaxWeight = GetArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT); + if (gArgs.IsArgSet("-blockmaxweight")) { + options.nBlockMaxWeight = gArgs.GetArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT); options.nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE; fWeightSet = true; } - if (IsArgSet("-blockmaxsize")) { - options.nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); + if (gArgs.IsArgSet("-blockmaxsize")) { + options.nBlockMaxSize = gArgs.GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); if (!fWeightSet) { options.nBlockMaxWeight = options.nBlockMaxSize * WITNESS_SCALE_FACTOR; } } - if (IsArgSet("-blockmintxfee")) { + if (gArgs.IsArgSet("-blockmintxfee")) { CAmount n = 0; - ParseMoney(GetArg("-blockmintxfee", ""), n); + ParseMoney(gArgs.GetArg("-blockmintxfee", ""), n); options.blockMinFeeRate = CFeeRate(n); } else { options.blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE); @@ -151,7 +151,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc // -regtest only: allow overriding block.nVersion with // -blockversion=N to test forking scenarios if (chainparams.MineBlocksOnDemand()) - pblock->nVersion = GetArg("-blockversion", pblock->nVersion); + pblock->nVersion = gArgs.GetArg("-blockversion", pblock->nVersion); pblock->nTime = GetAdjustedTime(); const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); @@ -224,7 +224,7 @@ void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet) } } -bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) +bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) const { // TODO: switch to weight-based accounting for packages instead of vsize-based accounting. if (nBlockWeight + WITNESS_SCALE_FACTOR * packageSize >= nBlockMaxWeight) @@ -272,7 +272,7 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) nFees += iter->GetFee(); inBlock.insert(iter); - bool fPrintPriority = GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY); + bool fPrintPriority = gArgs.GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY); if (fPrintPriority) { LogPrintf("fee %s txid %s\n", CFeeRate(iter->GetModifiedFee(), iter->GetTxSize()).ToString(), diff --git a/src/miner.h b/src/miner.h index 5c9cfd78f0..6e5fe761db 100644 --- a/src/miner.h +++ b/src/miner.h @@ -33,7 +33,7 @@ struct CBlockTemplate // Container for tracking updates to ancestor feerate as we include (parent) // transactions in a block struct CTxMemPoolModifiedEntry { - CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) + explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) { iter = entry; nSizeWithAncestors = entry->GetSizeWithAncestors(); @@ -116,7 +116,7 @@ typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator struct update_for_parent_inclusion { - update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} + explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} void operator() (CTxMemPoolModifiedEntry &e) { @@ -164,7 +164,7 @@ public: CFeeRate blockMinFeeRate; }; - BlockAssembler(const CChainParams& params); + explicit BlockAssembler(const CChainParams& params); BlockAssembler(const CChainParams& params, const Options& options); /** Construct a new block template with coinbase to scriptPubKeyIn */ @@ -187,7 +187,7 @@ private: /** Remove confirmed (inBlock) entries from given set */ void onlyUnconfirmed(CTxMemPool::setEntries& testSet); /** Test if a new package would "fit" in the block */ - bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost); + bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) const; /** Perform checks on each transaction in a package: * locktime, premature-witness, serialized size (if necessary) * These checks should always succeed, and they're here diff --git a/src/net.cpp b/src/net.cpp index ca9a173abe..1af317726a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -101,7 +101,7 @@ void CConnman::AddOneShot(const std::string& strDest) unsigned short GetListenPort() { - return (unsigned short)(GetArg("-port", Params().GetDefaultPort())); + return (unsigned short)(gArgs.GetArg("-port", Params().GetDefaultPort())); } // find 'best' local address for a particular peer @@ -306,7 +306,7 @@ CNode* CConnman::FindNode(const CNetAddr& ip) for (CNode* pnode : vNodes) if ((CNetAddr)pnode->addr == ip) return (pnode); - return NULL; + return nullptr; } CNode* CConnman::FindNode(const CSubNet& subNet) @@ -315,7 +315,7 @@ CNode* CConnman::FindNode(const CSubNet& subNet) for (CNode* pnode : vNodes) if (subNet.Match((CNetAddr)pnode->addr)) return (pnode); - return NULL; + return nullptr; } CNode* CConnman::FindNode(const std::string& addrName) @@ -326,7 +326,7 @@ CNode* CConnman::FindNode(const std::string& addrName) return (pnode); } } - return NULL; + return nullptr; } CNode* CConnman::FindNode(const CService& addr) @@ -335,7 +335,7 @@ CNode* CConnman::FindNode(const CService& addr) for (CNode* pnode : vNodes) if ((CService)pnode->addr == addr) return (pnode); - return NULL; + return nullptr; } bool CConnman::CheckIncomingNonce(uint64_t nonce) @@ -366,16 +366,16 @@ static CAddress GetBindAddress(SOCKET sock) CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure) { - if (pszDest == NULL) { + if (pszDest == nullptr) { if (IsLocal(addrConnect)) - return NULL; + return nullptr; // Look for an existing connection CNode* pnode = FindNode((CService)addrConnect); if (pnode) { LogPrintf("Failed to open new connection, already connected\n"); - return NULL; + return nullptr; } } @@ -393,7 +393,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo if (!IsSelectableSocket(hSocket)) { LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n"); CloseSocket(hSocket); - return NULL; + return nullptr; } if (pszDest && addrConnect.IsValid()) { @@ -408,7 +408,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo pnode->MaybeSetAddrName(std::string(pszDest)); CloseSocket(hSocket); LogPrintf("Failed to open new connection, already connected\n"); - return NULL; + return nullptr; } } @@ -429,7 +429,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo addrman.Attempt(addrConnect, fCountFailure); } - return NULL; + return nullptr; } void CConnman::DumpBanlist() @@ -514,7 +514,7 @@ void CConnman::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t ba banEntry.banReason = banReason; if (bantimeoffset <= 0) { - bantimeoffset = GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME); + bantimeoffset = gArgs.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME); sinceUnixEpoch = false; } banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset; @@ -966,7 +966,7 @@ bool CConnman::AttemptToEvictConnection() NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime, node->nLastBlockTime, node->nLastTXTime, (node->nServices & nRelevantServices) == nRelevantServices, - node->fRelayTxes, node->pfilter != NULL, node->addr, node->nKeyedNetGroup}; + node->fRelayTxes, node->pfilter != nullptr, node->addr, node->nKeyedNetGroup}; vEvictionCandidates.push_back(candidate); } } @@ -1438,9 +1438,9 @@ void CConnman::WakeMessageHandler() void ThreadMapPort() { std::string port = strprintf("%u", GetListenPort()); - const char * multicastif = 0; - const char * minissdpdpath = 0; - struct UPNPDev * devlist = 0; + const char * multicastif = nullptr; + const char * minissdpdpath = nullptr; + struct UPNPDev * devlist = nullptr; char lanaddr[64]; #ifndef UPNPDISCOVER_SUCCESS @@ -1510,13 +1510,13 @@ void ThreadMapPort() { r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); - freeUPNPDevlist(devlist); devlist = 0; + freeUPNPDevlist(devlist); devlist = nullptr; FreeUPNPUrls(&urls); throw; } } else { LogPrintf("No valid UPnP IGDs found\n"); - freeUPNPDevlist(devlist); devlist = 0; + freeUPNPDevlist(devlist); devlist = nullptr; if (r != 0) FreeUPNPUrls(&urls); } @@ -1524,7 +1524,7 @@ void ThreadMapPort() void MapPort(bool fUseUPnP) { - static boost::thread* upnp_thread = NULL; + static boost::thread* upnp_thread = nullptr; if (fUseUPnP) { @@ -1539,7 +1539,7 @@ void MapPort(bool fUseUPnP) upnp_thread->interrupt(); upnp_thread->join(); delete upnp_thread; - upnp_thread = NULL; + upnp_thread = nullptr; } } @@ -1575,7 +1575,7 @@ void CConnman::ThreadDNSAddressSeed() // creating fewer identifying DNS requests, reduces trust by giving seeds // less influence on the network topology, and reduces traffic to the seeds. if ((addrman.size() > 0) && - (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { + (!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { if (!interruptNet.sleep_for(std::chrono::seconds(11))) return; @@ -1685,7 +1685,7 @@ void CConnman::ThreadOpenConnections() for (const std::string& strAddr : gArgs.GetArgs("-connect")) { CAddress addr(CService(), NODE_NONE); - OpenNetworkConnection(addr, false, NULL, strAddr.c_str()); + OpenNetworkConnection(addr, false, nullptr, strAddr.c_str()); for (int i = 0; i < 10 && i < nLoop; i++) { if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) @@ -1841,7 +1841,7 @@ void CConnman::ThreadOpenConnections() LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString()); } - OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, NULL, false, fFeeler); + OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, false, fFeeler); } } } @@ -2153,9 +2153,9 @@ void Discover(boost::thread_group& threadGroup) struct ifaddrs* myaddrs; if (getifaddrs(&myaddrs) == 0) { - for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) + for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == NULL) continue; + if (ifa->ifa_addr == nullptr) continue; if ((ifa->ifa_flags & IFF_UP) == 0) continue; if (strcmp(ifa->ifa_name, "lo") == 0) continue; if (strcmp(ifa->ifa_name, "lo0") == 0) continue; @@ -2208,8 +2208,8 @@ CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSe nLastNodeId = 0; nSendBufferMaxSize = 0; nReceiveFloodSize = 0; - semOutbound = NULL; - semAddnode = NULL; + semOutbound = nullptr; + semAddnode = nullptr; flagInterruptMsgProc = false; Options connOptions; @@ -2312,11 +2312,11 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) fAddressesInitialized = true; - if (semOutbound == NULL) { + if (semOutbound == nullptr) { // initialize semaphore semOutbound = new CSemaphore(std::min((nMaxOutbound + nMaxFeeler), nMaxConnections)); } - if (semAddnode == NULL) { + if (semAddnode == nullptr) { // initialize semaphore semAddnode = new CSemaphore(nMaxAddnode); } @@ -2336,7 +2336,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) // Send and receive from sockets, accept connections threadSocketHandler = std::thread(&TraceThread<std::function<void()> >, "net", std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this))); - if (!GetBoolArg("-dnsseed", true)) + if (!gArgs.GetBoolArg("-dnsseed", true)) LogPrintf("DNS seeding disabled\n"); else threadDNSAddressSeed = std::thread(&TraceThread<std::function<void()> >, "dnsseed", std::function<void()>(std::bind(&CConnman::ThreadDNSAddressSeed, this))); @@ -2434,9 +2434,9 @@ void CConnman::Stop() vNodesDisconnected.clear(); vhListenSocket.clear(); delete semOutbound; - semOutbound = NULL; + semOutbound = nullptr; delete semAddnode; - semAddnode = NULL; + semAddnode = nullptr; } void CConnman::DeleteNode(CNode* pnode) @@ -170,7 +170,7 @@ public: void Interrupt(); bool GetNetworkActive() const { return fNetworkActive; }; void SetNetworkActive(bool active); - bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false, bool fAddnode = false); + bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, bool fOneShot = false, bool fFeeler = false, bool fAddnode = false); bool CheckIncomingNonce(uint64_t nonce); bool ForNode(NodeId id, std::function<bool(CNode* pnode)> func); @@ -470,7 +470,7 @@ bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE); bool RemoveLocal(const CService& addr); bool SeenLocal(const CService& addr); bool IsLocal(const CService& addr); -bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); +bool GetLocal(CService &addr, const CNetAddr *paddrPeer = nullptr); bool IsReachable(enum Network net); bool IsReachable(const CNetAddr &addr); CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 6fabfcf0ad..596ae1139b 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -202,10 +202,10 @@ struct CNodeState { fCurrentlyConnected = false; nMisbehavior = 0; fShouldBan = false; - pindexBestKnownBlock = NULL; + pindexBestKnownBlock = nullptr; hashLastUnknownBlock.SetNull(); - pindexLastCommonBlock = NULL; - pindexBestHeaderSent = NULL; + pindexLastCommonBlock = nullptr; + pindexBestHeaderSent = nullptr; nUnconnectingHeaders = 0; fSyncStarted = false; nHeadersSyncTimeout = 0; @@ -230,7 +230,7 @@ std::map<NodeId, CNodeState> mapNodeState; CNodeState *State(NodeId pnode) { std::map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode); if (it == mapNodeState.end()) - return NULL; + return nullptr; return &it->second; } @@ -336,9 +336,9 @@ bool MarkBlockAsReceived(const uint256& hash) { // Requires cs_main. // returns false, still setting pit, if the block was already in flight from the same peer // pit will only be valid as long as the same cs_main lock is being held -bool MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const CBlockIndex* pindex = NULL, std::list<QueuedBlock>::iterator** pit = NULL) { +bool MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const CBlockIndex* pindex = nullptr, std::list<QueuedBlock>::iterator** pit = nullptr) { CNodeState *state = State(nodeid); - assert(state != NULL); + assert(state != nullptr); // Short-circuit most stuff in case its from the same node std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash); @@ -353,14 +353,14 @@ bool MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const CBlockIndex* MarkBlockAsReceived(hash); std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), - {hash, pindex, pindex != NULL, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&mempool) : NULL)}); + {hash, pindex, pindex != nullptr, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&mempool) : nullptr)}); state->nBlocksInFlight++; state->nBlocksInFlightValidHeaders += it->fValidatedHeaders; if (state->nBlocksInFlight == 1) { // We're starting a block download (batch) from this peer. state->nDownloadingSince = GetTimeMicros(); } - if (state->nBlocksInFlightValidHeaders == 1 && pindex != NULL) { + if (state->nBlocksInFlightValidHeaders == 1 && pindex != nullptr) { nPeersWithValidatedDownloads++; } itInFlight = mapBlocksInFlight.insert(std::make_pair(hash, std::make_pair(nodeid, it))).first; @@ -372,12 +372,12 @@ bool MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const CBlockIndex* /** Check whether the last unknown block a peer advertised is not yet known. */ void ProcessBlockAvailability(NodeId nodeid) { CNodeState *state = State(nodeid); - assert(state != NULL); + assert(state != nullptr); if (!state->hashLastUnknownBlock.IsNull()) { BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock); if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) { - if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) + if (state->pindexBestKnownBlock == nullptr || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) state->pindexBestKnownBlock = itOld->second; state->hashLastUnknownBlock.SetNull(); } @@ -387,14 +387,14 @@ void ProcessBlockAvailability(NodeId nodeid) { /** Update tracking information about which blocks a peer is assumed to have. */ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { CNodeState *state = State(nodeid); - assert(state != NULL); + assert(state != nullptr); ProcessBlockAvailability(nodeid); BlockMap::iterator it = mapBlockIndex.find(hash); if (it != mapBlockIndex.end() && it->second->nChainWork > 0) { // An actually better block was announced. - if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) + if (state->pindexBestKnownBlock == nullptr || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) state->pindexBestKnownBlock = it->second; } else { // An unknown block was announced; just assume that the latest one is the best one. @@ -461,17 +461,17 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<con vBlocks.reserve(vBlocks.size() + count); CNodeState *state = State(nodeid); - assert(state != NULL); + assert(state != nullptr); // Make sure pindexBestKnownBlock is up to date, we'll need it. ProcessBlockAvailability(nodeid); - if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < UintToArith256(consensusParams.nMinimumChainWork)) { + if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < UintToArith256(consensusParams.nMinimumChainWork)) { // This peer has nothing interesting. return; } - if (state->pindexLastCommonBlock == NULL) { + if (state->pindexLastCommonBlock == nullptr) { // Bootstrap quickly by guessing a parent of our best tip is the forking point. // Guessing wrong in either direction is not a problem. state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())]; @@ -546,7 +546,7 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<con bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) { LOCK(cs_main); CNodeState *state = State(nodeid); - if (state == NULL) + if (state == nullptr) return false; stats.nMisbehavior = state->nMisbehavior; stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1; @@ -581,7 +581,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals) void AddToCompactExtraTransactions(const CTransactionRef& tx) { - size_t max_extra_txn = GetArg("-blockreconstructionextratxn", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN); + size_t max_extra_txn = gArgs.GetArg("-blockreconstructionextratxn", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN); if (max_extra_txn <= 0) return; if (!vExtraTxnForCompact.size()) @@ -700,11 +700,11 @@ void Misbehaving(NodeId pnode, int howmuch) return; CNodeState *state = State(pnode); - if (state == NULL) + if (state == nullptr) return; state->nMisbehavior += howmuch; - int banscore = GetArg("-banscore", DEFAULT_BANSCORE_THRESHOLD); + int banscore = gArgs.GetArg("-banscore", DEFAULT_BANSCORE_THRESHOLD); if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore) { LogPrintf("%s: %s peer=%d (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior); @@ -1006,7 +1006,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // To prevent fingerprinting attacks, only send blocks outside of the active // chain if they are valid, and no more than a month older (both in time, and in // best equivalent proof of work) than the best header chain we know about. - send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) && + send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != nullptr) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) && (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensusParams) < nOneMonth); if (!send) { @@ -1017,7 +1017,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // disconnect node in case we have reached the outbound limit for serving historical blocks // never disconnect whitelisted nodes static const int nOneWeek = 7 * 24 * 60 * 60; // assume > 1 week = historical - if (send && connman.OutboundTargetReached(true) && ( ((pindexBestHeader != NULL) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() > nOneWeek)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted) + if (send && connman.OutboundTargetReached(true) && ( ((pindexBestHeader != nullptr) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() > nOneWeek)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted) { LogPrint(BCLog::NET, "historical block serving limit reached, disconnect peer=%d\n", pfrom->GetId()); @@ -1175,7 +1175,7 @@ inline void static SendBlockTransactions(const CBlock& block, const BlockTransac bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman& connman, const std::atomic<bool>& interruptMsgProc) { LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->GetId()); - if (IsArgSet("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 0)) == 0) + if (gArgs.IsArgSet("-dropmessagestest") && GetRand(gArgs.GetArg("-dropmessagestest", 0)) == 0) { LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n"); return true; @@ -1541,7 +1541,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr bool fBlocksOnly = !fRelayTxes; // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistrelay is true - if (pfrom->fWhitelisted && GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) + if (pfrom->fWhitelisted && gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) fBlocksOnly = false; LOCK(cs_main); @@ -1734,7 +1734,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } CNodeState *nodestate = State(pfrom->GetId()); - const CBlockIndex* pindex = NULL; + const CBlockIndex* pindex = nullptr; if (locator.IsNull()) { // If locator is null, return the hashStop block @@ -1761,7 +1761,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) break; } - // pindex can be NULL either if we sent chainActive.Tip() OR + // pindex can be nullptr either if we sent chainActive.Tip() OR // if our peer has chainActive.Tip() (and thus we are sending an empty // headers message). In both cases it's safe to update // pindexBestHeaderSent to be our tip. @@ -1782,7 +1782,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr { // Stop processing the transaction early if // We are in blocks only mode and peer is either not whitelisted or whitelistrelay is off - if (!fRelayTxes && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))) + if (!fRelayTxes && (!pfrom->fWhitelisted || !gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))) { LogPrint(BCLog::NET, "transaction sent in violation of protocol peer=%d\n", pfrom->GetId()); return true; @@ -1901,7 +1901,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr AddOrphanTx(ptx, pfrom->GetId()); // DoS prevention: do not allow mapOrphanTransactions to grow unbounded - unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS)); + unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, gArgs.GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS)); unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx); if (nEvicted > 0) { LogPrint(BCLog::MEMPOOL, "mapOrphan overflow, removed %u tx\n", nEvicted); @@ -1926,7 +1926,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr AddToCompactExtraTransactions(ptx); } - if (pfrom->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { + if (pfrom->fWhitelisted && gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { // Always relay transactions received from whitelisted peers, even // if they were already in the mempool or rejected from it due // to policy, allowing the node to function as a gateway for @@ -1980,7 +1980,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } } - const CBlockIndex *pindex = NULL; + const CBlockIndex *pindex = nullptr; CValidationState state; if (!ProcessNewBlockHeaders({cmpctblock.header}, state, chainparams, &pindex)) { int nDoS; @@ -2052,7 +2052,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr if (pindex->nHeight <= chainActive.Height() + 2) { if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) || (fAlreadyInFlight && blockInFlightIt->second.first == pfrom->GetId())) { - std::list<QueuedBlock>::iterator* queuedBlockIt = NULL; + std::list<QueuedBlock>::iterator* queuedBlockIt = nullptr; if (!MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), pindex, &queuedBlockIt)) { if (!(*queuedBlockIt)->partialBlock) (*queuedBlockIt)->partialBlock.reset(new PartiallyDownloadedBlock(&mempool)); @@ -2145,9 +2145,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } bool fNewBlock = false; ProcessNewBlock(chainparams, pblock, true, &fNewBlock); - if (fNewBlock) + if (fNewBlock) { pfrom->nLastBlockTime = GetTime(); - + } else { + LOCK(cs_main); + mapBlockSource.erase(pblock->GetHash()); + } LOCK(cs_main); // hold cs_main for CBlockIndex::IsValid() if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS)) { // Clear download state for this block, which is in @@ -2222,8 +2225,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr // Since we requested this block (it was in mapBlocksInFlight), force it to be processed, // even if it would not be a candidate for new tip (missing previous block, chain not long enough, etc) ProcessNewBlock(chainparams, pblock, true, &fNewBlock); - if (fNewBlock) + if (fNewBlock) { pfrom->nLastBlockTime = GetTime(); + } else { + LOCK(cs_main); + mapBlockSource.erase(pblock->GetHash()); + } } } @@ -2250,7 +2257,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr return true; } - const CBlockIndex *pindexLast = NULL; + const CBlockIndex *pindexLast = nullptr; { LOCK(cs_main); CNodeState *nodestate = State(pfrom->GetId()); @@ -2401,8 +2408,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } bool fNewBlock = false; ProcessNewBlock(chainparams, pblock, forceProcessing, &fNewBlock); - if (fNewBlock) + if (fNewBlock) { pfrom->nLastBlockTime = GetTime(); + } else { + LOCK(cs_main); + mapBlockSource.erase(pblock->GetHash()); + } } @@ -2755,7 +2766,7 @@ bool ProcessMessages(CNode* pfrom, CConnman& connman, const std::atomic<bool>& i catch (const std::exception& e) { PrintExceptionContinue(&e, "ProcessMessages()"); } catch (...) { - PrintExceptionContinue(NULL, "ProcessMessages()"); + PrintExceptionContinue(nullptr, "ProcessMessages()"); } if (!fRet) { @@ -2772,7 +2783,7 @@ class CompareInvMempoolOrder { CTxMemPool *mp; public: - CompareInvMempoolOrder(CTxMemPool *_mempool) + explicit CompareInvMempoolOrder(CTxMemPool *_mempool) { mp = _mempool; } @@ -2870,7 +2881,7 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr } // Start block sync - if (pindexBestHeader == NULL) + if (pindexBestHeader == nullptr) pindexBestHeader = chainActive.Tip(); bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do. if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) { @@ -2918,7 +2929,7 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr bool fRevertToInv = ((!state.fPreferHeaders && (!state.fPreferHeaderAndIDs || pto->vBlockHashesToAnnounce.size() > 1)) || pto->vBlockHashesToAnnounce.size() > MAX_BLOCKS_TO_ANNOUNCE); - const CBlockIndex *pBestIndex = NULL; // last header queued for delivery + const CBlockIndex *pBestIndex = nullptr; // last header queued for delivery ProcessBlockAvailability(pto->GetId()); // ensure pindexBestKnownBlock is up-to-date if (!fRevertToInv) { @@ -2935,7 +2946,7 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr fRevertToInv = true; break; } - if (pBestIndex != NULL && pindex->pprev != pBestIndex) { + if (pBestIndex != nullptr && pindex->pprev != pBestIndex) { // This means that the list of blocks to announce don't // connect to each other. // This shouldn't really be possible to hit during @@ -2956,7 +2967,7 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr vHeaders.push_back(pindex->GetBlockHeader()); } else if (PeerHasHeader(&state, pindex)) { continue; // keep looking for the first new block - } else if (pindex->pprev == NULL || PeerHasHeader(&state, pindex->pprev)) { + } else if (pindex->pprev == nullptr || PeerHasHeader(&state, pindex->pprev)) { // Peer doesn't have this header but they do have the prior one. // Start sending headers. fFoundStartingHeader = true; @@ -3286,9 +3297,9 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr // Message: feefilter // // We don't want white listed peers to filter txs to us if we have -whitelistforcerelay - if (pto->nVersion >= FEEFILTER_VERSION && GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && - !(pto->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY))) { - CAmount currentFilter = mempool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); + if (pto->nVersion >= FEEFILTER_VERSION && gArgs.GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && + !(pto->fWhitelisted && gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY))) { + CAmount currentFilter = mempool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); int64_t timeNow = GetTimeMicros(); if (timeNow > pto->nextSendTimeFeeFilter) { static CFeeRate default_feerate(DEFAULT_MIN_RELAY_TX_FEE); diff --git a/src/net_processing.h b/src/net_processing.h index db6d81e6b6..f4a43980a5 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -32,7 +32,7 @@ private: CConnman* connman; public: - PeerLogicValidation(CConnman* connmanIn); + explicit PeerLogicValidation(CConnman* connmanIn); void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected, const std::vector<CTransactionRef>& vtxConflicted) override; void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override; diff --git a/src/netaddress.cpp b/src/netaddress.cpp index f31b2fc49b..b8a261c921 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -271,7 +271,7 @@ std::string CNetAddr::ToStringIP() const socklen_t socklen = sizeof(sockaddr); if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) { char name[1025] = ""; - if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST)) + if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), nullptr, 0, NI_NUMERICHOST)) return std::string(name); } if (IsIPv4()) @@ -407,7 +407,7 @@ static const int NET_UNKNOWN = NET_MAX + 0; static const int NET_TEREDO = NET_MAX + 1; int static GetExtNetwork(const CNetAddr *addr) { - if (addr == NULL) + if (addr == nullptr) return NET_UNKNOWN; if (addr->IsRFC4380()) return NET_TEREDO; diff --git a/src/netaddress.h b/src/netaddress.h index 61afe0f1fe..6ca99b36b5 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -36,7 +36,7 @@ class CNetAddr public: CNetAddr(); - CNetAddr(const struct in_addr& ipv4Addr); + explicit CNetAddr(const struct in_addr& ipv4Addr); void Init(); void SetIP(const CNetAddr& ip); @@ -80,9 +80,9 @@ class CNetAddr uint64_t GetHash() const; bool GetInAddr(struct in_addr* pipv4Addr) const; std::vector<unsigned char> GetGroup() const; - int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const; + int GetReachabilityFrom(const CNetAddr *paddrPartner = nullptr) const; - CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0); + explicit CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0); bool GetIn6Addr(struct in6_addr* pipv6Addr) const; friend bool operator==(const CNetAddr& a, const CNetAddr& b); @@ -146,7 +146,7 @@ class CService : public CNetAddr CService(); CService(const CNetAddr& ip, unsigned short port); CService(const struct in_addr& ipv4Addr, unsigned short port); - CService(const struct sockaddr_in& addr); + explicit CService(const struct sockaddr_in& addr); void Init(); unsigned short GetPort() const; bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const; @@ -160,7 +160,7 @@ class CService : public CNetAddr std::string ToStringIPPort() const; CService(const struct in6_addr& ipv6Addr, unsigned short port); - CService(const struct sockaddr_in6& addr); + explicit CService(const struct sockaddr_in6& addr); ADD_SERIALIZE_METHODS; diff --git a/src/netbase.cpp b/src/netbase.cpp index 8952468ecd..05f9f6961c 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -81,13 +81,13 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign #else aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; #endif - struct addrinfo *aiRes = NULL; - int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes); + struct addrinfo *aiRes = nullptr; + int nErr = getaddrinfo(pszName, nullptr, &aiHint, &aiRes); if (nErr) return false; struct addrinfo *aiTrav = aiRes; - while (aiTrav != NULL && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions)) + while (aiTrav != nullptr && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions)) { CNetAddr resolved; if (aiTrav->ai_family == AF_INET) @@ -227,7 +227,7 @@ static IntrRecvError InterruptibleRecv(char* data, size_t len, int timeout, cons fd_set fdset; FD_ZERO(&fdset); FD_SET(hSocket, &fdset); - int nRet = select(hSocket + 1, &fdset, NULL, NULL, &tval); + int nRet = select(hSocket + 1, &fdset, nullptr, nullptr, &tval); if (nRet == SOCKET_ERROR) { return IntrRecvError::NetworkError; } @@ -439,7 +439,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe fd_set fdset; FD_ZERO(&fdset); FD_SET(hSocket, &fdset); - int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); + int nRet = select(hSocket + 1, nullptr, &fdset, nullptr, &timeout); if (nRet == 0) { LogPrint(BCLog::NET, "connection to %s timeout\n", addrConnect.ToString()); @@ -642,8 +642,8 @@ std::string NetworkErrorString(int err) char buf[256]; buf[0] = 0; if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - buf, sizeof(buf), NULL)) + nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + buf, sizeof(buf), nullptr)) { return strprintf("%s (%d)", buf, err); } diff --git a/src/netbase.h b/src/netbase.h index 941da31f9c..6572f0a12e 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -29,7 +29,7 @@ class proxyType { public: proxyType(): randomize_credentials(false) {} - proxyType(const CService &_proxy, bool _randomize_credentials=false): proxy(_proxy), randomize_credentials(_randomize_credentials) {} + explicit proxyType(const CService &_proxy, bool _randomize_credentials=false): proxy(_proxy), randomize_credentials(_randomize_credentials) {} bool IsValid() const { return proxy.IsValid(); } @@ -50,8 +50,8 @@ bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLoo bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions); CService LookupNumeric(const char *pszName, int portDefault = 0); bool LookupSubNet(const char *pszName, CSubNet& subnet); -bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = 0); -bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = 0); +bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = nullptr); +bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = nullptr); /** Return readable error string for a network error code */ std::string NetworkErrorString(int err); /** Close socket and set hSocket to INVALID_SOCKET */ diff --git a/src/netmessagemaker.h b/src/netmessagemaker.h index 8e8a6e4a02..79b2501c5d 100644 --- a/src/netmessagemaker.h +++ b/src/netmessagemaker.h @@ -12,7 +12,7 @@ class CNetMsgMaker { public: - CNetMsgMaker(int nVersionIn) : nVersion(nVersionIn){} + explicit CNetMsgMaker(int nVersionIn) : nVersion(nVersionIn){} template <typename... Args> CSerializedNetMsg Make(int nFlags, std::string sCommand, Args&&... args) const diff --git a/src/policy/fees.h b/src/policy/fees.h index f4ef793643..6edaf28714 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -284,7 +284,7 @@ private: public: /** Create new FeeFilterRounder */ - FeeFilterRounder(const CFeeRate& minIncrementalFee); + explicit FeeFilterRounder(const CFeeRate& minIncrementalFee); /** Quantize a minimum fee for privacy purpose before broadcast **/ CAmount round(CAmount currentMinFee); diff --git a/src/pow.cpp b/src/pow.cpp index e06d9662e6..7d87c6bbb7 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -12,7 +12,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { - assert(pindexLast != NULL); + assert(pindexLast != nullptr); unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); // Only change once per difficulty adjustment interval diff --git a/src/prevector.h b/src/prevector.h index 46640d6fff..f7bde8911a 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -448,7 +448,7 @@ public: } if (!is_direct()) { free(_union.indirect); - _union.indirect = NULL; + _union.indirect = nullptr; } } diff --git a/src/primitives/block.h b/src/primitives/block.h index c90a1dfa64..292df40896 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -129,7 +129,7 @@ struct CBlockLocator CBlockLocator() {} - CBlockLocator(const std::vector<uint256>& vHaveIn) : vHave(vHaveIn) {} + explicit CBlockLocator(const std::vector<uint256>& vHaveIn) : vHave(vHaveIn) {} ADD_SERIALIZE_METHODS; diff --git a/src/protocol.h b/src/protocol.h index 7890bb627d..67e01d9606 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -39,7 +39,7 @@ public: }; typedef unsigned char MessageStartChars[MESSAGE_START_SIZE]; - CMessageHeader(const MessageStartChars& pchMessageStartIn); + explicit CMessageHeader(const MessageStartChars& pchMessageStartIn); CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn); std::string GetCommand() const; diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 91af4e56f2..2da7be783f 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -10,7 +10,7 @@ namespace { /* Global secp256k1_context object used for verification. */ -secp256k1_context* secp256k1_context_verify = NULL; +secp256k1_context* secp256k1_context_verify = nullptr; } // namespace /** This function is taken from the libsecp256k1 distribution and implements @@ -274,7 +274,7 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const { if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) { return false; } - return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, NULL, &sig)); + return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, nullptr, &sig)); } /* static */ int ECCVerifyHandle::refcount = 0; @@ -282,9 +282,9 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const { ECCVerifyHandle::ECCVerifyHandle() { if (refcount == 0) { - assert(secp256k1_context_verify == NULL); + assert(secp256k1_context_verify == nullptr); secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - assert(secp256k1_context_verify != NULL); + assert(secp256k1_context_verify != nullptr); } refcount++; } @@ -293,8 +293,8 @@ ECCVerifyHandle::~ECCVerifyHandle() { refcount--; if (refcount == 0) { - assert(secp256k1_context_verify != NULL); + assert(secp256k1_context_verify != nullptr); secp256k1_context_destroy(secp256k1_context_verify); - secp256k1_context_verify = NULL; + secp256k1_context_verify = nullptr; } } diff --git a/src/pubkey.h b/src/pubkey.h index dbf0e23f20..65738d8fe2 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -30,7 +30,7 @@ class CKeyID : public uint160 { public: CKeyID() : uint160() {} - CKeyID(const uint160& in) : uint160(in) {} + explicit CKeyID(const uint160& in) : uint160(in) {} }; typedef uint256 ChainCode; @@ -88,7 +88,7 @@ public: } //! Construct a public key from a byte vector. - CPubKey(const std::vector<unsigned char>& _vch) + explicit CPubKey(const std::vector<unsigned char>& _vch) { Set(_vch.begin(), _vch.end()); } diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index cebac46b95..f295bd4689 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -273,7 +273,7 @@ void AddressBookPage::on_exportButton_clicked() // CSV is currently the only supported format QString filename = GUIUtil::getSaveFileName(this, tr("Export Address List"), QString(), - tr("Comma separated file (*.csv)"), NULL); + tr("Comma separated file (*.csv)"), nullptr); if (filename.isNull()) return; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 4a4116c670..3fd58a2f9a 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -106,7 +106,7 @@ static QString GetLangTerritory() if(!lang_territory_qsettings.isEmpty()) lang_territory = lang_territory_qsettings; // 3) -lang command line argument - lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString())); + lang_territory = QString::fromStdString(gArgs.GetArg("-lang", lang_territory.toStdString())); return lang_territory; } @@ -227,7 +227,7 @@ public: void requestShutdown(); /// Get process return value - int getReturnValue() { return returnValue; } + int getReturnValue() const { return returnValue; } /// Get window identifier of QMainWindow (BitcoinGUI) WId getMainWinId() const; @@ -305,7 +305,7 @@ void BitcoinCore::initialize() } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { - handleRunawayException(NULL); + handleRunawayException(nullptr); } } @@ -322,7 +322,7 @@ void BitcoinCore::shutdown() } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { - handleRunawayException(NULL); + handleRunawayException(nullptr); } } @@ -345,7 +345,7 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv): // This must be done inside the BitcoinApplication constructor, or after it, because // PlatformStyle::instantiate requires a QApplication std::string platformName; - platformName = GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM); + platformName = gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM); platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName)); if (!platformStyle) // Fall back to "other" if specified name not found platformStyle = PlatformStyle::instantiate("other"); @@ -383,7 +383,7 @@ void BitcoinApplication::createPaymentServer() void BitcoinApplication::createOptionsModel(bool resetSettings) { - optionsModel = new OptionsModel(NULL, resetSettings); + optionsModel = new OptionsModel(nullptr, resetSettings); } void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) @@ -498,7 +498,7 @@ void BitcoinApplication::initializeResult(bool success) #endif // If -min option passed, start window minimized. - if(GetBoolArg("-min", false)) + if(gArgs.GetBoolArg("-min", false)) { window->showMinimized(); } @@ -550,7 +550,7 @@ int main(int argc, char *argv[]) /// 1. Parse command-line options. These take precedence over anything else. // Command-line options take precedence: - ParseParameters(argc, argv); + gArgs.ParseParameters(argc, argv); // Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory @@ -606,9 +606,9 @@ int main(int argc, char *argv[]) // Show help message immediately after parsing command-line options (for "-lang") and setting locale, // but before showing splash screen. - if (IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help") || IsArgSet("-version")) + if (gArgs.IsArgSet("-?") || gArgs.IsArgSet("-h") || gArgs.IsArgSet("-help") || gArgs.IsArgSet("-version")) { - HelpMessageDialog help(NULL, IsArgSet("-version")); + HelpMessageDialog help(nullptr, gArgs.IsArgSet("-version")); help.showOrPrint(); return EXIT_SUCCESS; } @@ -623,11 +623,11 @@ int main(int argc, char *argv[]) if (!fs::is_directory(GetDataDir(false))) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), - QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(GetArg("-datadir", "")))); + QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", "")))); return EXIT_FAILURE; } try { - ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)); + gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); @@ -691,12 +691,12 @@ int main(int argc, char *argv[]) // Allow parameter interaction before we create the options model app.parameterSetup(); // Load GUI settings from QSettings - app.createOptionsModel(IsArgSet("-resetguisettings")); + app.createOptionsModel(gArgs.IsArgSet("-resetguisettings")); // Subscribe to global signals from core uiInterface.InitMessage.connect(InitMessage); - if (GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !GetBoolArg("-min", false)) + if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false)) app.createSplashScreen(networkStyle.data()); int rv = EXIT_SUCCESS; @@ -723,7 +723,7 @@ int main(int argc, char *argv[]) PrintExceptionContinue(&e, "Runaway exception"); app.handleRunawayException(QString::fromStdString(GetWarnings("gui"))); } catch (...) { - PrintExceptionContinue(NULL, "Runaway exception"); + PrintExceptionContinue(nullptr, "Runaway exception"); app.handleRunawayException(QString::fromStdString(GetWarnings("gui"))); } return rv; diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 429c18cba8..e3970298e6 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -479,7 +479,7 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) connect(_clientModel, SIGNAL(networkActiveChanged(bool)), this, SLOT(setNetworkActive(bool))); modalOverlay->setKnownBestHeight(_clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(_clientModel->getHeaderTipTime())); - setNumBlocks(_clientModel->getNumBlocks(), _clientModel->getLastBlockDate(), _clientModel->getVerificationProgress(NULL), false); + setNumBlocks(_clientModel->getNumBlocks(), _clientModel->getLastBlockDate(), _clientModel->getVerificationProgress(nullptr), false); connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool))); // Receive and report messages from client model @@ -922,7 +922,7 @@ void BitcoinGUI::message(const QString &title, const QString &message, unsigned showNormalIfMinimized(); QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons, this); int r = mBox.exec(); - if (ret != NULL) + if (ret != nullptr) *ret = r == QMessageBox::Ok; } else diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 8731caafc7..aa45ea1f0a 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -168,7 +168,7 @@ public Q_SLOTS: @see CClientUIInterface::MessageBoxFlags @param[in] ret pointer to a bool that will be modified to whether Ok was clicked (modal only) */ - void message(const QString &title, const QString &message, unsigned int style, bool *ret = NULL); + void message(const QString &title, const QString &message, unsigned int style, bool *ret = nullptr); #ifdef ENABLE_WALLET /** Set the encryption status as shown in the UI. diff --git a/src/qt/callback.h b/src/qt/callback.h index a8b593a652..da6b0c4c2e 100644 --- a/src/qt/callback.h +++ b/src/qt/callback.h @@ -16,7 +16,7 @@ class FunctionCallback : public Callback F f; public: - FunctionCallback(F f_) : f(std::move(f_)) {} + explicit FunctionCallback(F f_) : f(std::move(f_)) {} ~FunctionCallback() override {} void call() override { f(this); } }; diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 99a9f893ff..4949c91771 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -30,9 +30,9 @@ namespace Ui { class CCoinControlWidgetItem : public QTreeWidgetItem { public: - CCoinControlWidgetItem(QTreeWidget *parent, int type = Type) : QTreeWidgetItem(parent, type) {} - CCoinControlWidgetItem(int type = Type) : QTreeWidgetItem(type) {} - CCoinControlWidgetItem(QTreeWidgetItem *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + explicit CCoinControlWidgetItem(QTreeWidget *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + explicit CCoinControlWidgetItem(int type = Type) : QTreeWidgetItem(type) {} + explicit CCoinControlWidgetItem(QTreeWidgetItem *parent, int type = Type) : QTreeWidgetItem(parent, type) {} bool operator<(const QTreeWidgetItem &other) const; }; diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index bffa81137b..f3c5daebec 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -634,11 +634,11 @@ bool SetStartOnSystemStartup(bool fAutoStart) if (fAutoStart) { - CoInitialize(NULL); + CoInitialize(nullptr); // Get a pointer to the IShellLink interface. - IShellLink* psl = NULL; - HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, + IShellLink* psl = nullptr; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, reinterpret_cast<void**>(&psl)); @@ -646,12 +646,12 @@ bool SetStartOnSystemStartup(bool fAutoStart) { // Get the current executable path TCHAR pszExePath[MAX_PATH]; - GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); + GetModuleFileName(nullptr, pszExePath, sizeof(pszExePath)); // Start client minimized QString strArgs = "-min"; // Set -testnet /-regtest options - strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false))); + strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", gArgs.GetBoolArg("-testnet", false), gArgs.GetBoolArg("-regtest", false))); #ifdef UNICODE boost::scoped_array<TCHAR> args(new TCHAR[strArgs.length() + 1]); @@ -674,7 +674,7 @@ bool SetStartOnSystemStartup(bool fAutoStart) // Query IShellLink for the IPersistFile interface for // saving the shortcut in persistent storage. - IPersistFile* ppf = NULL; + IPersistFile* ppf = nullptr; hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&ppf)); if (SUCCEEDED(hres)) { @@ -760,7 +760,7 @@ bool SetStartOnSystemStartup(bool fAutoStart) optionFile << "Name=Bitcoin\n"; else optionFile << strprintf("Name=Bitcoin (%s)\n", chain); - optionFile << "Exec=" << pszExePath << strprintf(" -min -testnet=%d -regtest=%d\n", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false)); + optionFile << "Exec=" << pszExePath << strprintf(" -min -testnet=%d -regtest=%d\n", gArgs.GetBoolArg("-testnet", false), gArgs.GetBoolArg("-regtest", false)); optionFile << "Terminal=false\n"; optionFile << "Hidden=false\n"; optionFile.close(); @@ -781,21 +781,21 @@ LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl) { // loop through the list of startup items and try to find the bitcoin app - CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(list, NULL); + CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(list, nullptr); for(int i = 0; i < CFArrayGetCount(listSnapshot); i++) { LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i); UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes; - CFURLRef currentItemURL = NULL; + CFURLRef currentItemURL = nullptr; #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 10100 if(&LSSharedFileListItemCopyResolvedURL) - currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, NULL); + currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, nullptr); #if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 10100 else - LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL); + LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, nullptr); #endif #else - LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL); + LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, nullptr); #endif if(currentItemURL && CFEqual(currentItemURL, findUrl)) { @@ -807,13 +807,13 @@ LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef CFRelease(currentItemURL); } } - return NULL; + return nullptr; } bool GetStartOnSystemStartup() { CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); + LSSharedFileListRef loginItems = LSSharedFileListCreate(nullptr, kLSSharedFileListSessionLoginItems, nullptr); LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, bitcoinAppUrl); return !!foundItem; // return boolified object } @@ -821,12 +821,12 @@ bool GetStartOnSystemStartup() bool SetStartOnSystemStartup(bool fAutoStart) { CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); + LSSharedFileListRef loginItems = LSSharedFileListCreate(nullptr, kLSSharedFileListSessionLoginItems, nullptr); LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, bitcoinAppUrl); if(fAutoStart && !foundItem) { // add bitcoin app to startup item list - LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst, NULL, NULL, bitcoinAppUrl, NULL, NULL); + LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst, nullptr, nullptr, bitcoinAppUrl, nullptr, nullptr); } else if(!fAutoStart && foundItem) { // remove item diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 231a715753..0ff95d8502 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -43,7 +43,7 @@ class FreespaceChecker : public QObject Q_OBJECT public: - FreespaceChecker(Intro *intro); + explicit FreespaceChecker(Intro *intro); enum Status { ST_OK, @@ -131,7 +131,7 @@ Intro::Intro(QWidget *parent) : ); ui->lblExplanation2->setText(ui->lblExplanation2->text().arg(tr(PACKAGE_NAME))); - uint64_t pruneTarget = std::max<int64_t>(0, GetArg("-prune", 0)); + uint64_t pruneTarget = std::max<int64_t>(0, gArgs.GetArg("-prune", 0)); requiredSpace = BLOCK_CHAIN_SIZE; QString storageRequiresMsg = tr("At least %1 GB of data will be stored in this directory, and it will grow over time."); if (pruneTarget) { @@ -191,14 +191,14 @@ bool Intro::pickDataDirectory() QSettings settings; /* If data directory provided on command line, no need to look at settings or show a picking dialog */ - if(!GetArg("-datadir", "").empty()) + if(!gArgs.GetArg("-datadir", "").empty()) return true; /* 1) Default data directory for operating system */ QString dataDir = getDefaultDataDirectory(); /* 2) Allow QSettings to override default dir */ dataDir = settings.value("strDataDir", dataDir).toString(); - if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR) || settings.value("fReset", false).toBool() || GetBoolArg("-resetguisettings", false)) + if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || gArgs.GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR) || settings.value("fReset", false).toBool() || gArgs.GetBoolArg("-resetguisettings", false)) { /* If current default data directory does not exist, let the user choose one */ Intro intro; @@ -231,7 +231,7 @@ bool Intro::pickDataDirectory() * (to be consistent with bitcoind behavior) */ if(dataDir != getDefaultDataDirectory()) - SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting + gArgs.SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting return true; } diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index bf8f0ceb88..ffa80a10bd 100644 --- a/src/qt/locale/bitcoin_es_MX.ts +++ b/src/qt/locale/bitcoin_es_MX.ts @@ -3,7 +3,7 @@ <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>Click derecho para editar tu dirección o etiqueta</translation> + <translation>Click derecho para editar dirección o etiqueta</translation> </message> <message> <source>Create a new address</source> @@ -31,7 +31,7 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Exportar la información en la tabla actual a un archivo</translation> + <translation>Exportar la información en la pestaña actual a un archivo</translation> </message> <message> <source>&Export</source> @@ -596,6 +596,10 @@ </context> <context> <name>WalletView</name> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Exportar la información en la pestaña actual a un archivo</translation> + </message> </context> <context> <name>bitcoin-core</name> diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index 38f0e1444c..d13a5639e5 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -66,6 +66,10 @@ <translation>Nämä ovat Bitcoin-osoitteesi maksujen lähettämistä varten. Tarkista aina määrä ja vastaanotto-osoite ennen kolikoiden lähettämistä.</translation> </message> <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>Tässä ovat Bitcoin vastaanotto-osoitteesi. On suositeltavaa käyttää uutta vastaanotto-osoitetta jokaista lähetystä varten.</translation> + </message> + <message> <source>&Copy Address</source> <translation>&Kopioi osoite</translation> </message> @@ -82,10 +86,18 @@ <translation>Vie osoitelista</translation> </message> <message> + <source>Comma separated file (*.csv)</source> + <translation>Pilkuilla erotettu tiedosto (*.csv)</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Vienti epäonnistui</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Virhe tallentaessa osoitelistaa kohteeseen %1. Yritä uudelleen.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -120,14 +132,26 @@ <translation>Toista uusi tunnuslause</translation> </message> <message> + <source>Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>.</source> + <translation>Kirjoita uusi salauslause lompakolle.<br/>Käytä salauslausetta jossa on joko<b>kymmenen tai useampi satunnainen merkki</b>, tai<b>vähintään kahdeksan sanaa</b></translation> + </message> + <message> <source>Encrypt wallet</source> <translation>Salaa lompakko</translation> </message> <message> + <source>This operation needs your wallet passphrase to unlock the wallet.</source> + <translation>Tämä toiminto vaatii lompakkosi tunnuslauseen sen avaamiseksi</translation> + </message> + <message> <source>Unlock wallet</source> <translation>Avaa lompakko</translation> </message> <message> + <source>This operation needs your wallet passphrase to decrypt the wallet.</source> + <translation>Tämä toiminto vaatii lompakkosia tunnuslauseen salauksen purkuun</translation> + </message> + <message> <source>Decrypt wallet</source> <translation>Pura lompakon salaus</translation> </message> @@ -136,10 +160,18 @@ <translation>Vaihda salasana</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Syötä vanha ja uusi tunnuslause lompakolle.</translation> + </message> + <message> <source>Confirm wallet encryption</source> <translation>Vahvista lompakon salaaminen</translation> </message> <message> + <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> + <translation>Varoitus: Jos salaat lompakkosi ja menetät tunnuslauseesi, <b>MENETÄT KAIKKI BITCOINISI</b>!</translation> + </message> + <message> <source>Are you sure you wish to encrypt your wallet?</source> <translation>Oletko varma, että haluat salata lompakkosi?</translation> </message> @@ -148,14 +180,34 @@ <translation>Lompakko salattiin</translation> </message> <message> + <source>%1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>%1 sulkeutuu lopettaakseen salausprosessin. Muista, että salattukaan lompakko ei täysin suojaa sitä haittaohjelmien aiheuttamilta varkauksilta.</translation> + </message> + <message> + <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> + <translation>TÄRKEÄÄ: Kaikki tekemäsi vanhan lompakon varmuuskopiot pitäisi korvata uusilla suojatuilla varmuuskopioilla. Turvallisuussyistä edelliset varmuuskopiot muuttuvat turhiksi, kun aloitat uuden suojatun lompakon käytön.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>Lompakon salaus epäonnistui</translation> </message> <message> + <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> + <translation>Lompakon salaaminen epäonnistui sisäisen virheen vuoksi. Lompakkoasi ei salattu.</translation> + </message> + <message> + <source>The supplied passphrases do not match.</source> + <translation>Annetut salauslauseet eivät täsmää.</translation> + </message> + <message> <source>Wallet unlock failed</source> <translation>Lompakon lukituksen avaaminen epäonnistui</translation> </message> <message> + <source>The passphrase entered for the wallet decryption was incorrect.</source> + <translation>Annettu salauslause lompakon avaamiseksi oli väärä.</translation> + </message> + <message> <source>Wallet decryption failed</source> <translation>Lompakon salauksen purkaminen epäonnistui</translation> </message> @@ -278,6 +330,10 @@ <translation>Paina ottaaksesi verkkoyhteysilmaisin uudelleen käyttöön.</translation> </message> <message> + <source>Syncing Headers (%1%)...</source> + <translation>Synkronoidaan Tunnisteita (%1%)...</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>Ladataan lohkoindeksiä...</translation> </message> @@ -476,6 +532,14 @@ <translation>Saapuva rahansiirto</translation> </message> <message> + <source>HD key generation is <b>enabled</b></source> + <translation>HD avaimen generointi on <b>päällä</b></translation> + </message> + <message> + <source>HD key generation is <b>disabled</b></source> + <translation>HD avaimen generointi on </b>pois päältä</b></translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Lompakko on <b>salattu</b> ja tällä hetkellä <b>avoinna</b></translation> </message> @@ -483,7 +547,11 @@ <source>Wallet is <b>encrypted</b> and currently <b>locked</b></source> <translation>Lompakko on <b>salattu</b> ja tällä hetkellä <b>lukittuna</b></translation> </message> - </context> + <message> + <source>A fatal error occurred. Bitcoin can no longer continue safely and will quit.</source> + <translation>Peruuttamaton virhe on tapahtunut. Bitcoin ei voi enää jatkaa turvallisesti ja sammutetaan.</translation> + </message> +</context> <context> <name>CoinControlDialog</name> <message> @@ -615,6 +683,10 @@ <translation>ei</translation> </message> <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Saattaa vaihdella +/- %1 satoshia per syöte.</translation> + </message> + <message> <source>(no label)</source> <translation>(ei nimikettä)</translation> </message> @@ -654,6 +726,26 @@ <translation>Uusi lähetysosoite</translation> </message> <message> + <source>Edit receiving address</source> + <translation>Muokkaa vastaanottavaa osoitetta</translation> + </message> + <message> + <source>Edit sending address</source> + <translation>Muokkaa lähettävää osoitetta</translation> + </message> + <message> + <source>The entered address "%1" is not a valid Bitcoin address.</source> + <translation>Antamasi osoite "%1" ei ole kelvollinen Bitcoin-osoite.</translation> + </message> + <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>Antamasi osoite "%1" on jo osoitekirjassa</translation> + </message> + <message> + <source>Could not unlock wallet.</source> + <translation>Lompakkoa ei voitu avata.</translation> + </message> + <message> <source>New key generation failed.</source> <translation>Uuden avaimen luonti epäonnistui.</translation> </message> @@ -1206,10 +1298,22 @@ <context> <name>QRImageWidget</name> <message> + <source>&Save Image...</source> + <translation>&Tallenna kuva</translation> + </message> + <message> + <source>&Copy Image</source> + <translation>&Kopioi kuva</translation> + </message> + <message> <source>Save QR Code</source> <translation>Tallenna QR-koodi</translation> </message> - </context> + <message> + <source>PNG Image (*.png)</source> + <translation>PNG kuva (*.png)</translation> + </message> +</context> <context> <name>RPCConsole</name> <message> @@ -1568,6 +1672,10 @@ <translation>Kopioi nimike</translation> </message> <message> + <source>Copy message</source> + <translation>Kopioi viesti</translation> + </message> + <message> <source>Copy amount</source> <translation>Kopioi määrä</translation> </message> @@ -1591,6 +1699,10 @@ <translation>&Tallenna kuva</translation> </message> <message> + <source>Payment information</source> + <translation>Maksutiedot</translation> + </message> + <message> <source>Address</source> <translation>Osoite</translation> </message> @@ -1793,6 +1905,10 @@ <translation>Kopioi vaihtorahat</translation> </message> <message> + <source>Total Amount %1</source> + <translation>Kokonaismäärä %1</translation> + </message> + <message> <source>or</source> <translation>tai</translation> </message> @@ -1882,7 +1998,11 @@ </context> <context> <name>SendConfirmationDialog</name> - </context> + <message> + <source>Yes</source> + <translation>Kyllä</translation> + </message> +</context> <context> <name>ShutdownWindow</name> <message> @@ -1972,7 +2092,11 @@ <source>Reset all verify message fields</source> <translation>Tyhjennä kaikki varmista-viesti-kentät</translation> </message> - </context> + <message> + <source>Message verified.</source> + <translation>Viesti varmistettu.</translation> + </message> +</context> <context> <name>SplashScreen</name> <message> @@ -1990,14 +2114,50 @@ <context> <name>TransactionDesc</name> <message> + <source>%1/unconfirmed</source> + <translation>%1/vahvistamaton</translation> + </message> + <message> + <source>%1 confirmations</source> + <translation>%1 vahvistusta</translation> + </message> + <message> <source>Date</source> <translation>Aika</translation> </message> <message> + <source>Source</source> + <translation>Lähde</translation> + </message> + <message> + <source>Generated</source> + <translation>Generoitu</translation> + </message> + <message> + <source>From</source> + <translation>Lähettäjä</translation> + </message> + <message> + <source>unknown</source> + <translation>tuntematon</translation> + </message> + <message> + <source>To</source> + <translation>Saaja</translation> + </message> + <message> + <source>own address</source> + <translation>oma osoite</translation> + </message> + <message> <source>Message</source> <translation>Viesti</translation> </message> <message> + <source>Comment</source> + <translation>Kommentti</translation> + </message> + <message> <source>Amount</source> <translation>Määrä</translation> </message> @@ -2016,10 +2176,30 @@ <translation>Aika</translation> </message> <message> + <source>Type</source> + <translation>Tyyppi</translation> + </message> + <message> <source>Label</source> <translation>Nimike</translation> </message> <message> + <source>Received with</source> + <translation>Vastaanotettu osoitteella</translation> + </message> + <message> + <source>Sent to</source> + <translation>Lähetetty vastaanottajalle</translation> + </message> + <message> + <source>Payment to yourself</source> + <translation>Maksu itsellesi</translation> + </message> + <message> + <source>Mined</source> + <translation>Louhittu</translation> + </message> + <message> <source>(no label)</source> <translation>(ei nimikettä)</translation> </message> @@ -2027,6 +2207,50 @@ <context> <name>TransactionView</name> <message> + <source>All</source> + <translation>Kaikki</translation> + </message> + <message> + <source>Today</source> + <translation>Tänään</translation> + </message> + <message> + <source>This week</source> + <translation>Tällä viikolla</translation> + </message> + <message> + <source>This month</source> + <translation>Tässä kuussa</translation> + </message> + <message> + <source>Last month</source> + <translation>Viime kuussa</translation> + </message> + <message> + <source>This year</source> + <translation>Tänä vuonna</translation> + </message> + <message> + <source>Received with</source> + <translation>Vastaanotettu osoitteella</translation> + </message> + <message> + <source>Sent to</source> + <translation>Lähetetty vastaanottajalle</translation> + </message> + <message> + <source>To yourself</source> + <translation>Itsellesi</translation> + </message> + <message> + <source>Mined</source> + <translation>Louhittu</translation> + </message> + <message> + <source>Min amount</source> + <translation>Minimimäärä</translation> + </message> + <message> <source>Copy address</source> <translation>Kopioi osoite</translation> </message> @@ -2043,10 +2267,34 @@ <translation>Kopioi transaktion ID</translation> </message> <message> + <source>Edit label</source> + <translation>Muokkaa nimeä</translation> + </message> + <message> + <source>Show transaction details</source> + <translation>Näytä rahansiirron yksityiskohdat</translation> + </message> + <message> + <source>Export Transaction History</source> + <translation>Vie rahansiirtohistoria</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Pilkuilla erotettu tiedosto (*.csv)</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Vahvistettu</translation> + </message> + <message> <source>Date</source> <translation>Aika</translation> </message> <message> + <source>Type</source> + <translation>Tyyppi</translation> + </message> + <message> <source>Label</source> <translation>Nimike</translation> </message> @@ -2055,10 +2303,26 @@ <translation>Osoite</translation> </message> <message> + <source>ID</source> + <translation>ID</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Vienti epäonnistui</translation> </message> - </context> + <message> + <source>There was an error trying to save the transaction history to %1.</source> + <translation>Rahansiirron historian tallentamisessa tapahtui virhe paikkaan %1.</translation> + </message> + <message> + <source>Exporting Successful</source> + <translation>Vienti onnistui</translation> + </message> + <message> + <source>to</source> + <translation>vastaanottaja</translation> + </message> +</context> <context> <name>UnitDisplayStatusBarControl</name> <message> @@ -2068,16 +2332,44 @@ </context> <context> <name>WalletFrame</name> - </context> + <message> + <source>No wallet has been loaded.</source> + <translation>Lomakkoa ei ole ladattu.</translation> + </message> +</context> <context> <name>WalletModel</name> - </context> + <message> + <source>Send Coins</source> + <translation>Lähetä kolikoita</translation> + </message> +</context> <context> <name>WalletView</name> <message> <source>&Export</source> <translation>&Vie</translation> </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Vie auki olevan välilehden tiedot tiedostoon</translation> + </message> + <message> + <source>Backup Wallet</source> + <translation>Varmuuskopioi lompakko</translation> + </message> + <message> + <source>Wallet Data (*.dat)</source> + <translation>Lompakkodata (*.dat)</translation> + </message> + <message> + <source>Backup Failed</source> + <translation>Varmuuskopio epäonnistui</translation> + </message> + <message> + <source>Backup Successful</source> + <translation>Varmuuskopio Onnistui</translation> + </message> </context> <context> <name>bitcoin-core</name> @@ -2318,6 +2610,10 @@ <translation>Karsittu tila ei ole yhteensopiva -txindex:n kanssa.</translation> </message> <message> + <source>Rewinding blocks...</source> + <translation>Varmistetaan lohkoja...</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Aseta tietokannan välimuistin koko megatavuissa (%d - %d, oletus: %d</translation> </message> @@ -2554,6 +2850,10 @@ <translation>Käytä erillistä SOCKS5-proxyä tavoittaaksesi vertaisia Tor-piilopalveluiden kautta (oletus: %s)</translation> </message> <message> + <source>%s is set very high!</source> + <translation>%s on asetettu todella korkeaksi!</translation> + </message> + <message> <source>(default: %s)</source> <translation>(oletus: %s)</translation> </message> @@ -2638,10 +2938,26 @@ <translation>Käytä vahvistamattomia vaihtorahoja lähetettäessä rahansiirtoja (oletus: %u)</translation> </message> <message> + <source>Starting network threads...</source> + <translation>Käynnistetään verkkoa...</translation> + </message> + <message> + <source>This is the transaction fee you will pay if you send a transaction.</source> + <translation>Tämä on lähetyksestä maksettava maksu jonka maksat</translation> + </message> + <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Aikaväli sopimattomien vertaisten yhteyksien katkaisuun (oletus: %u)</translation> </message> <message> + <source>Transaction amounts must not be negative</source> + <translation>Lähetyksen siirtosumman tulee olla positiivinen</translation> + </message> + <message> + <source>Transaction must have at least one recipient</source> + <translation>Lähetyksessä tulee olla ainakin yksi vastaanottaja</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Tuntematon verkko -onlynet parametrina: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index 5aa9137753..c51a611b3c 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -2,6 +2,10 @@ <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>დააჭირეთ მარჯვენა ღილაკს მისამართის ან იარლიყის ჩასასწორებლად</translation> + </message> + <message> <source>Create a new address</source> <translation>ახალი მისამართის შექმნა</translation> </message> @@ -38,6 +42,10 @@ <translation>&წაშლა</translation> </message> <message> + <source>C&hoose</source> + <translation>&არჩევა</translation> + </message> + <message> <source>Sending addresses</source> <translation>გამმგზავნი მისამართ</translation> </message> @@ -45,9 +53,17 @@ <source>Receiving addresses</source> <translation>მიმღები მისამართი</translation> </message> + <message> + <source>&Edit</source> + <translation>&რედაქტირება</translation> + </message> </context> <context> <name>AddressTableModel</name> + <message> + <source>Address</source> + <translation>მისამართი</translation> + </message> </context> <context> <name>AskPassphraseDialog</name> @@ -67,6 +83,22 @@ <source>Repeat new passphrase</source> <translation>გაიმეორეთ ახალი ფრაზა-პაროლი</translation> </message> + <message> + <source>Encrypt wallet</source> + <translation>საფულის დაშიფრვა</translation> + </message> + <message> + <source>Unlock wallet</source> + <translation>საფულის განბლოკვა</translation> + </message> + <message> + <source>Decrypt wallet</source> + <translation>საფულის განბლოკვა</translation> + </message> + <message> + <source>Change passphrase</source> + <translation>პაროლის შეცვლა</translation> + </message> </context> <context> <name>BanTableModel</name> @@ -110,6 +142,14 @@ <translation>გასვლა</translation> </message> <message> + <source>&About %1</source> + <translation>%1-ის &შესახებ</translation> + </message> + <message> + <source>Show information about %1</source> + <translation>%1-ის შესახებ ინფორმაციის ჩვენება</translation> + </message> + <message> <source>About &Qt</source> <translation>&Qt-ს შესახებ</translation> </message> @@ -274,8 +314,36 @@ <translation>განახლებულია</translation> </message> <message> + <source>%1 client</source> + <translation>%1 კლიენტი</translation> + </message> + <message> <source>Catching up...</source> - <translation>ჩართვა...</translation> + <translation>მიმდინარეობს განახლება...</translation> + </message> + <message> + <source>Date: %1 +</source> + <translation>თარიღი: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>რაოდენობა: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>ტიპი: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>მისამართი: %1 +</translation> </message> <message> <source>Sent transaction</source> @@ -313,6 +381,10 @@ <translation>საკომისიო:</translation> </message> <message> + <source>Dust:</source> + <translation>მტვერი:</translation> + </message> + <message> <source>After Fee:</source> <translation>დამატებითი საკომისიო:</translation> </message> @@ -348,7 +420,19 @@ <source>Confirmed</source> <translation>დადასტურებულია</translation> </message> - </context> + <message> + <source>yes</source> + <translation>დიახ</translation> + </message> + <message> + <source>no</source> + <translation>არა</translation> + </message> + <message> + <source>(change)</source> + <translation>(ხურდა)</translation> + </message> +</context> <context> <name>EditAddressDialog</name> <message> @@ -402,6 +486,14 @@ <translation>ვერსია</translation> </message> <message> + <source>(%1-bit)</source> + <translation>(%1-ბიტი)</translation> + </message> + <message> + <source>About %1</source> + <translation>%1-ის შესახებ</translation> + </message> + <message> <source>Command-line options</source> <translation>კომანდების ზოლის ოპციები</translation> </message> @@ -413,6 +505,10 @@ <source>command-line options</source> <translation>კომანდების ზოლის ოპციები</translation> </message> + <message> + <source>UI Options:</source> + <translation>მომხმარებლის ინტერფეისის ოპციები:</translation> + </message> </context> <context> <name>Intro</name> @@ -421,6 +517,10 @@ <translation>მოგესალმებით</translation> </message> <message> + <source>Welcome to %1.</source> + <translation>კეთილი იყოს თქვენი მობრძანება %1-ში.</translation> + </message> + <message> <source>Use the default data directory</source> <translation>ნაგულისხმევი კატალოგის გამოყენება</translation> </message> @@ -432,7 +532,15 @@ <source>Error</source> <translation>შეცდომა</translation> </message> - </context> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>ხელმისაწვდომია თავისუფალი სივრცის %n გბ</numerusform></translation> + </message> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(საჭირო %n გბ-დან)</numerusform></translation> + </message> +</context> <context> <name>ModalOverlay</name> <message> @@ -440,9 +548,25 @@ <translation>ფორმა</translation> </message> <message> + <source>Unknown...</source> + <translation>უცნობი...</translation> + </message> + <message> <source>Last block time</source> <translation>ბოლო ბლოკის დრო</translation> </message> + <message> + <source>Progress</source> + <translation>პროგრესი</translation> + </message> + <message> + <source>calculating...</source> + <translation>მიმდინარეობს გამოთვლა...</translation> + </message> + <message> + <source>Hide</source> + <translation>დამალვა</translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -510,6 +634,10 @@ <translation>ს&აფულე</translation> </message> <message> + <source>Expert</source> + <translation>ექსპერტი</translation> + </message> + <message> <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> <translation>დაუდასტურებელი ხურდის გამოყენების აკრძალვის შემდეგ მათი გამოყენება შეუძლებელი იქნება, სანამ ტრანსაქციას არ ექნება ერთი დასტური მაინც. ეს აისახება თქვენი ნაშთის დათვლაზეც.</translation> </message> @@ -534,6 +662,18 @@ <translation>პროქსის პორტი (მაგ.: 9050)</translation> </message> <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> <source>&Window</source> <translation>&ფანჯარა</translation> </message> @@ -880,6 +1020,10 @@ <source>&Save Image...</source> <translation>გამო&სახულების შენახვა...</translation> </message> + <message> + <source>Address</source> + <translation>მისამართი</translation> + </message> </context> <context> <name>RecentRequestsTableModel</name> @@ -943,6 +1087,10 @@ <translation>ტრანსაქციის საფასური - საკომისიო:</translation> </message> <message> + <source>Hide</source> + <translation>დამალვა</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>გაგზავნა რამდენიმე რეციპიენტთან ერთდროულად</translation> </message> @@ -955,6 +1103,10 @@ <translation>ფორმის ყველა ველის წაშლა</translation> </message> <message> + <source>Dust:</source> + <translation>მტვერი:</translation> + </message> + <message> <source>Clear &All</source> <translation>გ&ასუფთავება</translation> </message> @@ -1140,6 +1292,10 @@ </context> <context> <name>TransactionView</name> + <message> + <source>Address</source> + <translation>მისამართი</translation> + </message> </context> <context> <name>UnitDisplayStatusBarControl</name> diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts index 66ab7c81f4..0cb0e7f6e4 100644 --- a/src/qt/locale/bitcoin_ru_RU.ts +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -49,16 +49,104 @@ <source>Choose the address to receive coins with</source> <translation>Выбрать адрес для получения монет</translation> </message> + <message> + <source>C&hoose</source> + <translation>В&ыбрать</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Адреса отправки</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Адреса получения</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>&Копировать адрес</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Копировать &метку</translation> + </message> + <message> + <source>&Edit</source> + <translation>&Редактировать</translation> + </message> + <message> + <source>Export Address List</source> + <translation>Экспортировать список адресов</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Экспорт не удался</translation> + </message> </context> <context> <name>AddressTableModel</name> - </context> + <message> + <source>Label</source> + <translation>Метка</translation> + </message> + <message> + <source>Address</source> + <translation>Адрес</translation> + </message> + <message> + <source>(no label)</source> + <translation>(нет метки)</translation> + </message> +</context> <context> <name>AskPassphraseDialog</name> <message> + <source>Passphrase Dialog</source> + <translation>Ввод пароля</translation> + </message> + <message> + <source>Enter passphrase</source> + <translation>Введите пароль</translation> + </message> + <message> + <source>New passphrase</source> + <translation>Новый пароль</translation> + </message> + <message> <source>Repeat new passphrase</source> <translation>Повторите новый пароль</translation> </message> + <message> + <source>Encrypt wallet</source> + <translation>Зашифровать бумажник</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to unlock the wallet.</source> + <translation>Эта операция требует вашего пароля для разблокировки бумажника</translation> + </message> + <message> + <source>Unlock wallet</source> + <translation>Разблокировать бумажник</translation> + </message> + <message> + <source>Decrypt wallet</source> + <translation>Расшифровать бумажник</translation> + </message> + <message> + <source>Change passphrase</source> + <translation>Изменить пароль</translation> + </message> + <message> + <source>Confirm wallet encryption</source> + <translation>Подтвердите шифрование бумажника</translation> + </message> + <message> + <source>Wallet encrypted</source> + <translation>Бумажник зашифрован</translation> + </message> + <message> + <source>Wallet unlock failed</source> + <translation>Ошибка разблокировки кошелька</translation> + </message> </context> <context> <name>BanTableModel</name> @@ -66,10 +154,114 @@ <context> <name>BitcoinGUI</name> <message> + <source>Sign &message...</source> + <translation>Подписать &сообщение...</translation> + </message> + <message> + <source>&Transactions</source> + <translation>&Транзакции</translation> + </message> + <message> + <source>Browse transaction history</source> + <translation>Просмотр истории транзакций</translation> + </message> + <message> + <source>E&xit</source> + <translation>В&ыход</translation> + </message> + <message> + <source>Quit application</source> + <translation>Выйти</translation> + </message> + <message> + <source>&About %1</source> + <translation>&О программе %1</translation> + </message> + <message> + <source>Show information about %1</source> + <translation>Показать информацию о %1</translation> + </message> + <message> + <source>About &Qt</source> + <translation>О библиотеке &Qt</translation> + </message> + <message> + <source>Show information about Qt</source> + <translation>Показать информацию о библиотеке Qt</translation> + </message> + <message> + <source>&Options...</source> + <translation>&Опции...</translation> + </message> + <message> + <source>&Encrypt Wallet...</source> + <translation>&Зашифровать кошелёк</translation> + </message> + <message> + <source>&Backup Wallet...</source> + <translation>&Создать резервную копию бумажника</translation> + </message> + <message> + <source>&Change Passphrase...</source> + <translation>&Изменить пароль...</translation> + </message> + <message> + <source>&Sending addresses...</source> + <translation>&Адреса для отправки...</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>&Адреса для получения...</translation> + </message> + <message> + <source>Open &URI...</source> + <translation>Открыть &URI...</translation> + </message> + <message> + <source>Syncing Headers (%1%)...</source> + <translation>Синхронизация заголовков (%1%)...</translation> + </message> + <message> + <source>&Debug window</source> + <translation>&Окно отладки</translation> + </message> + <message> + <source>&Verify message...</source> + <translation>&Проверить сообщение...</translation> + </message> + <message> <source>Bitcoin</source> <translation>Bitcoin Core</translation> </message> <message> + <source>Wallet</source> + <translation>Кошелек</translation> + </message> + <message> + <source>&Send</source> + <translation>&Отправить</translation> + </message> + <message> + <source>&Receive</source> + <translation>&Получить</translation> + </message> + <message> + <source>&Show / Hide</source> + <translation>&Показать / Спрятать</translation> + </message> + <message> + <source>&File</source> + <translation>&Файл</translation> + </message> + <message> + <source>&Settings</source> + <translation>&Настройки</translation> + </message> + <message> + <source>&Help</source> + <translation>&Помощь</translation> + </message> + <message> <source>&Command-line options</source> <translation>Опции командной строки</translation> </message> @@ -85,10 +277,30 @@ <source>Information</source> <translation>Информация</translation> </message> + <message> + <source>Up to date</source> + <translation>Готов</translation> + </message> + <message> + <source>Connecting to peers...</source> + <translation>Подключение к пирам...</translation> + </message> </context> <context> <name>CoinControlDialog</name> <message> + <source>Bytes:</source> + <translation>Байтов:</translation> + </message> + <message> + <source>Amount:</source> + <translation>Количество:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Комиссия:</translation> + </message> + <message> <source>Date</source> <translation>Дата</translation> </message> @@ -100,6 +312,34 @@ <source>Confirmed</source> <translation>Подтвержденные</translation> </message> + <message> + <source>Copy address</source> + <translation>Копировать адрес</translation> + </message> + <message> + <source>Copy label</source> + <translation>Копировать метку</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Копировать сумму</translation> + </message> + <message> + <source>Copy transaction ID</source> + <translation>Копировать ID транзакции</translation> + </message> + <message> + <source>yes</source> + <translation>да</translation> + </message> + <message> + <source>no</source> + <translation>нет</translation> + </message> + <message> + <source>(no label)</source> + <translation>(нет метки)</translation> + </message> </context> <context> <name>EditAddressDialog</name> @@ -125,16 +365,36 @@ <source>command-line options</source> <translation>Опции командной строки</translation> </message> + <message> + <source>Start minimized</source> + <translation>Запускать свернутым</translation> + </message> </context> <context> <name>Intro</name> <message> + <source>Welcome</source> + <translation>Добро пожаловать</translation> + </message> + <message> + <source>Welcome to %1.</source> + <translation>Добро пожаловать в %1.</translation> + </message> + <message> <source>Error</source> <translation>Ошибка</translation> </message> </context> <context> <name>ModalOverlay</name> + <message> + <source>Progress</source> + <translation>Прогресс</translation> + </message> + <message> + <source>Hide</source> + <translation>Спрятать</translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -149,9 +409,109 @@ </context> <context> <name>OptionsDialog</name> + <message> + <source>Options</source> + <translation>Опции</translation> + </message> + <message> + <source>MB</source> + <translation>МБ</translation> + </message> + <message> + <source>Allow incoming connections</source> + <translation>Разрешить входящие соеденения</translation> + </message> + <message> + <source>&Reset Options</source> + <translation>&Сбросить опции</translation> + </message> + <message> + <source>&Network</source> + <translation>&Сеть</translation> + </message> + <message> + <source>W&allet</source> + <translation>К&ошелёк</translation> + </message> + <message> + <source>Expert</source> + <translation>Эксперт</translation> + </message> + <message> + <source>Map port using &UPnP</source> + <translation>Пробросить порт через &UPnP</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Подключится к сети Bitcoin через SOCKS5 прокси.</translation> + </message> + <message> + <source>Proxy &IP:</source> + <translation>IP прокси:</translation> + </message> + <message> + <source>&Port:</source> + <translation>&Порт:</translation> + </message> + <message> + <source>Port of the proxy (e.g. 9050)</source> + <translation>Порт прокси: (напр. 9050)</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>&Window</source> + <translation>&Окно</translation> + </message> + <message> + <source>Hide tray icon</source> + <translation>Спрятать иконку в трее</translation> + </message> + <message> + <source>&OK</source> + <translation>&ОК</translation> + </message> + <message> + <source>&Cancel</source> + <translation>&Отмена</translation> + </message> </context> <context> <name>OverviewPage</name> + <message> + <source>Immature:</source> + <translation>Незрелые:</translation> + </message> + <message> + <source>Balances</source> + <translation>Балансы</translation> + </message> + <message> + <source>Total:</source> + <translation>Всего:</translation> + </message> + <message> + <source>Your current total balance</source> + <translation>Ваш текущий баланс:</translation> + </message> + <message> + <source>Your current balance in watch-only addresses</source> + <translation>Ваш текущий баланс на адресах только для чтения:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Последние транзакции</translation> + </message> </context> <context> <name>PaymentServer</name> @@ -161,43 +521,243 @@ </context> <context> <name>QObject</name> + <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Введите биткоин-адрес (напр. %1)</translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n час</numerusform><numerusform>%n часа</numerusform><numerusform>%n часов</numerusform><numerusform>%n часов</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n день</numerusform><numerusform>%n дней</numerusform><numerusform>%n дней</numerusform><numerusform>%n дней</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n неделя</numerusform><numerusform>%n недель</numerusform><numerusform>%n недель</numerusform><numerusform>%n недель</numerusform></translation> + </message> + <message> + <source>%1 and %2</source> + <translation>%1 и %2</translation> + </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n год</numerusform><numerusform>%n лет</numerusform><numerusform>%n лет</numerusform><numerusform>%n лет</numerusform></translation> + </message> </context> <context> <name>QObject::QObject</name> - </context> + <message> + <source>Error: %1</source> + <translation>Ошибка: %1</translation> + </message> +</context> <context> <name>QRImageWidget</name> - </context> + <message> + <source>Save QR Code</source> + <translation>Сохранить QR-код</translation> + </message> + <message> + <source>PNG Image (*.png)</source> + <translation>PNG Картинка (*.png)</translation> + </message> +</context> <context> <name>RPCConsole</name> <message> <source>&Information</source> <translation>Информация</translation> </message> - </context> + <message> + <source>Debug window</source> + <translation>Окно отладки</translation> + </message> + <message> + <source>Received</source> + <translation>Получено</translation> + </message> + <message> + <source>Sent</source> + <translation>Отправлено</translation> + </message> + <message> + <source>&Peers</source> + <translation>&Пиры</translation> + </message> + <message> + <source>Banned peers</source> + <translation>Заблокированные пиры</translation> + </message> + <message> + <source>Version</source> + <translation>Версия</translation> + </message> + <message> + <source>&Open</source> + <translation>&Открыть</translation> + </message> + <message> + <source>&Console</source> + <translation>&Консоль</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &час</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &день</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &неделя</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &год</translation> + </message> + <message> + <source>%1 B</source> + <translation>%1 Б</translation> + </message> + <message> + <source>%1 KB</source> + <translation>%1 КБ</translation> + </message> + <message> + <source>%1 MB</source> + <translation>%1 МБ</translation> + </message> + <message> + <source>%1 GB</source> + <translation>%1 ГБ</translation> + </message> + <message> + <source>never</source> + <translation>никогда</translation> + </message> + <message> + <source>Yes</source> + <translation>Да</translation> + </message> + <message> + <source>No</source> + <translation>Нет</translation> + </message> + <message> + <source>Unknown</source> + <translation>Неизвестно</translation> + </message> +</context> <context> <name>ReceiveCoinsDialog</name> - </context> + <message> + <source>Clear</source> + <translation>Отчистить</translation> + </message> + <message> + <source>Show</source> + <translation>Показать</translation> + </message> + <message> + <source>Remove</source> + <translation>Удалить</translation> + </message> + <message> + <source>Copy URI</source> + <translation>Копировать URI</translation> + </message> + <message> + <source>Copy label</source> + <translation>Копировать метку</translation> + </message> + <message> + <source>Copy message</source> + <translation>Копировать сообщение</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Копировать сумму</translation> + </message> +</context> <context> <name>ReceiveRequestDialog</name> + <message> + <source>Address</source> + <translation>Адрес</translation> + </message> + <message> + <source>Label</source> + <translation>Метка</translation> + </message> </context> <context> <name>RecentRequestsTableModel</name> + <message> + <source>Label</source> + <translation>Метка</translation> + </message> + <message> + <source>(no label)</source> + <translation>(нет метки)</translation> + </message> </context> <context> <name>SendCoinsDialog</name> - </context> + <message> + <source>Bytes:</source> + <translation>Байтов:</translation> + </message> + <message> + <source>Amount:</source> + <translation>Количество:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Комиссия:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Выбрать...</translation> + </message> + <message> + <source>Hide</source> + <translation>Спрятать</translation> + </message> + <message> + <source>Balance:</source> + <translation>Баланс:</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Копировать сумму</translation> + </message> + <message> + <source>(no label)</source> + <translation>(нет метки)</translation> + </message> +</context> <context> <name>SendCoinsEntry</name> </context> <context> <name>SendConfirmationDialog</name> - </context> + <message> + <source>Yes</source> + <translation>Да</translation> + </message> +</context> <context> <name>ShutdownWindow</name> </context> <context> <name>SignVerifyMessageDialog</name> + <message> + <source>Signature</source> + <translation>Подпись</translation> + </message> </context> <context> <name>SplashScreen</name> @@ -213,9 +773,45 @@ </context> <context> <name>TransactionTableModel</name> + <message> + <source>Label</source> + <translation>Метка</translation> + </message> + <message> + <source>(no label)</source> + <translation>(нет метки)</translation> + </message> </context> <context> <name>TransactionView</name> + <message> + <source>Copy address</source> + <translation>Копировать адрес</translation> + </message> + <message> + <source>Copy label</source> + <translation>Копировать метку</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Копировать сумму</translation> + </message> + <message> + <source>Copy transaction ID</source> + <translation>Копировать ID транзакции</translation> + </message> + <message> + <source>Label</source> + <translation>Метка</translation> + </message> + <message> + <source>Address</source> + <translation>Адрес</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Экспорт не удался</translation> + </message> </context> <context> <name>UnitDisplayStatusBarControl</name> diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index 7126b2e5c1..4cff6bf370 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -62,6 +62,18 @@ <translation>Адреса отримання</translation> </message> <message> + <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> + <translation>Це ваші адреси Bitcoin для надсилання платежів. Завжди перевіряйте суму та адресу одержувача перед відправленням монет.</translation> + </message> + <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>Це ваші адреси Bitcoin для отримання платежів. Для кожної транзакції рекомендується використовувати нову адресу одержувача.</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>&Скопіювати адресу</translation> + </message> + <message> <source>Copy &Label</source> <translation>Зкопіювати&Створити мітку</translation> </message> @@ -93,6 +105,10 @@ <translation>Мітка</translation> </message> <message> + <source>Address</source> + <translation>Адреса</translation> + </message> + <message> <source>(no label)</source> <translation>(немає мітки)</translation> </message> @@ -115,7 +131,95 @@ <source>Repeat new passphrase</source> <translation>Повторіть пароль</translation> </message> - </context> + <message> + <source>Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>.</source> + <translation>Введіть нову кодову фразу для гаманця.<br/>Будь ласка, використовуйте кодові фрази що містять <b> щонайменше десять випадкових символів </b> або <b> щонайменше вісім слів </b>.</translation> + </message> + <message> + <source>Encrypt wallet</source> + <translation>Зашифрувати гаманець</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to unlock the wallet.</source> + <translation>Ця операція потребує пароль для розблокування гаманця.</translation> + </message> + <message> + <source>Unlock wallet</source> + <translation>Розблокувати гаманець</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to decrypt the wallet.</source> + <translation>Ця операція потребує пароль для розшифрування гаманця.</translation> + </message> + <message> + <source>Decrypt wallet</source> + <translation>Дешифрувати гаманець</translation> + </message> + <message> + <source>Change passphrase</source> + <translation>Змінити пароль</translation> + </message> + <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Введіть старий пароль та новий пароль до гаманця.</translation> + </message> + <message> + <source>Confirm wallet encryption</source> + <translation>Підтвердіть шифрування гаманця</translation> + </message> + <message> + <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> + <translation>УВАГА: Якщо ви зашифруєте гаманець і забудете пароль, ви <b>ВТРАТИТЕ ВСІ СВОЇ БІТКОІНИ</b>!</translation> + </message> + <message> + <source>Are you sure you wish to encrypt your wallet?</source> + <translation>Ви дійсно хочете зашифрувати свій гаманець?</translation> + </message> + <message> + <source>Wallet encrypted</source> + <translation>Гаманець зашифровано</translation> + </message> + <message> + <source>%1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>%1 буде закрито зараз, щоб завершити процес шифрування. Пам'ятайте, що шифрування гаманця не може повністю захистити ваші біткойни від крадіжки шкідливими програмами, у випадку якщо ваш комп'ютер буде інфіковано.</translation> + </message> + <message> + <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> + <translation>ВАЖЛИВО: Всі попередні резервні копії, які ви зробили з вашого файлу гаманця повинні бути замінені новоствореним, зашифрованим файлом гаманця. З міркувань безпеки, попередні резервні копії незашифрованого файла гаманця стануть непридатними одразу ж, як тільки ви почнете використовувати новий, зашифрований гаманець.</translation> + </message> + <message> + <source>Wallet encryption failed</source> + <translation>Не вдалося зашифрувати гаманець</translation> + </message> + <message> + <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> + <translation>Виникла помилка під час шифрування гаманця. Ваш гаманець не було зашифровано.</translation> + </message> + <message> + <source>The supplied passphrases do not match.</source> + <translation>Введені паролі не співпадають.</translation> + </message> + <message> + <source>Wallet unlock failed</source> + <translation>Не вдалося розблокувати гаманець</translation> + </message> + <message> + <source>The passphrase entered for the wallet decryption was incorrect.</source> + <translation>Введений пароль є невірним.</translation> + </message> + <message> + <source>Wallet decryption failed</source> + <translation>Не вдалося розшифрувати гаманець</translation> + </message> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>Пароль було успішно змінено.</translation> + </message> + <message> + <source>Warning: The Caps Lock key is on!</source> + <translation>Увага: Ввімкнено Caps Lock!</translation> + </message> +</context> <context> <name>BanTableModel</name> <message> @@ -170,6 +274,10 @@ <translation>П&ро %1</translation> </message> <message> + <source>Show information about %1</source> + <translation>Показати інформацію про %1</translation> + </message> + <message> <source>About &Qt</source> <translation>&Про Qt</translation> </message> @@ -182,6 +290,10 @@ <translation>&Параметри...</translation> </message> <message> + <source>Modify configuration options for %1</source> + <translation>Редагувати параметри для %1</translation> + </message> + <message> <source>&Encrypt Wallet...</source> <translation>&Шифрування гаманця...</translation> </message> @@ -206,6 +318,22 @@ <translation>Відкрити &URI</translation> </message> <message> + <source>Click to disable network activity.</source> + <translation>Натисніть, щоб вимкнути активність мережі.</translation> + </message> + <message> + <source>Network activity disabled.</source> + <translation>Мережева активність вимкнена.</translation> + </message> + <message> + <source>Click to enable network activity again.</source> + <translation>Натисніть, щоб знову активувати мережеву активність.</translation> + </message> + <message> + <source>Syncing Headers (%1%)...</source> + <translation>Синхронізація заголовків (%1%)...</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>Переіндексація блоків на диску ...</translation> </message> @@ -309,6 +437,14 @@ <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n активне з'єднання з мережею Bitcoin</numerusform><numerusform>%n активні з'єднання з мережею Bitcoin</numerusform><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation> </message> + <message> + <source>Indexing blocks on disk...</source> + <translation>Індексація блоків на диску ...</translation> + </message> + <message> + <source>Processing blocks on disk...</source> + <translation>Обробка блоків на диску...</translation> + </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Оброблено %n блок історії транзакцій.</numerusform><numerusform>Оброблено %n блоки історії транзакцій.</numerusform><numerusform>Оброблено %n блоків історії транзакцій.</numerusform></translation> @@ -342,6 +478,18 @@ <translation>Синхронізовано</translation> </message> <message> + <source>Show the %1 help message to get a list with possible Bitcoin command-line options</source> + <translation>Показати довідку %1 для отримання переліку можливих параметрів командного рядка.</translation> + </message> + <message> + <source>%1 client</source> + <translation>%1 клієнт</translation> + </message> + <message> + <source>Connecting to peers...</source> + <translation>Підключення до вузлів...</translation> + </message> + <message> <source>Catching up...</source> <translation>Синхронізується...</translation> </message> @@ -384,6 +532,14 @@ <translation>Отримані транзакції</translation> </message> <message> + <source>HD key generation is <b>enabled</b></source> + <translation>Генерація HD ключа <b>увімкнена</b></translation> + </message> + <message> + <source>HD key generation is <b>disabled</b></source> + <translation>Генерація HD ключа<b>вимкнена</b></translation> + </message> + <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation><b>Зашифрований</b> гаманець <b>розблоковано</b></translation> </message> @@ -391,7 +547,11 @@ <source>Wallet is <b>encrypted</b> and currently <b>locked</b></source> <translation><b>Зашифрований</b> гаманець <b>заблоковано</b></translation> </message> - </context> + <message> + <source>A fatal error occurred. Bitcoin can no longer continue safely and will quit.</source> + <translation>Сталася фатальна помилка. Помилки не сумісні з подальщою роботою. Гаманець буде закрито.</translation> + </message> +</context> <context> <name>CoinControlDialog</name> <message> @@ -463,10 +623,82 @@ <translation>Підтверджені</translation> </message> <message> + <source>Copy address</source> + <translation>Скопіювати адресу</translation> + </message> + <message> + <source>Copy label</source> + <translation>Скопіювати мітку</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Скопіювати суму</translation> + </message> + <message> + <source>Copy transaction ID</source> + <translation>Скопіювати ID транзакції </translation> + </message> + <message> + <source>Lock unspent</source> + <translation>Заблокувати</translation> + </message> + <message> + <source>Unlock unspent</source> + <translation>Розблокувати</translation> + </message> + <message> + <source>Copy quantity</source> + <translation>Скопіювати кількість</translation> + </message> + <message> + <source>Copy fee</source> + <translation>Скопіювати комісію</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Скопіювати після комісії</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Скопіювати байти</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Скопіювати інше</translation> + </message> + <message> + <source>Copy change</source> + <translation>Скопіювати решту</translation> + </message> + <message> + <source>(%1 locked)</source> + <translation>(%1 заблоковано)</translation> + </message> + <message> + <source>yes</source> + <translation>так</translation> + </message> + <message> + <source>no</source> + <translation>ні</translation> + </message> + <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Може відрізнятися на +/- %1 сатоші за введені</translation> + </message> + <message> <source>(no label)</source> <translation>немає мітки</translation> </message> - </context> + <message> + <source>change from %1 (%2)</source> + <translation>решта з %1 (%2)</translation> + </message> + <message> + <source>(change)</source> + <translation>(решта)</translation> + </message> +</context> <context> <name>EditAddressDialog</name> <message> @@ -489,7 +721,39 @@ <source>&Address</source> <translation>&Адреса</translation> </message> - </context> + <message> + <source>New receiving address</source> + <translation>Нова адреса для отримання</translation> + </message> + <message> + <source>New sending address</source> + <translation>Нова адреса для відправлення</translation> + </message> + <message> + <source>Edit receiving address</source> + <translation>Редагувати адресу для отримання</translation> + </message> + <message> + <source>Edit sending address</source> + <translation>Редагувати адресу для відправлення</translation> + </message> + <message> + <source>The entered address "%1" is not a valid Bitcoin address.</source> + <translation>Введена адреса "%1" не є адресою в мережі Bitcoin.</translation> + </message> + <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>Введена адреса «%1» вже присутня в адресній книзі.</translation> + </message> + <message> + <source>Could not unlock wallet.</source> + <translation>Неможливо розблокувати гаманець.</translation> + </message> + <message> + <source>New key generation failed.</source> + <translation>Не вдалося згенерувати нові ключі.</translation> + </message> +</context> <context> <name>FreespaceChecker</name> <message> @@ -524,6 +788,10 @@ <translation>(%1-бітний)</translation> </message> <message> + <source>About %1</source> + <translation>Про %1</translation> + </message> + <message> <source>Command-line options</source> <translation>Параметри командного рядка</translation> </message> @@ -559,7 +827,11 @@ <source>Show splash screen on startup (default: %u)</source> <translation>Показувати заставку під час запуску (типово: %u)</translation> </message> - </context> + <message> + <source>Reset all settings changed in the GUI</source> + <translation>Скинути налаштування, які було змінено через графічний інтерфейс користувача</translation> + </message> +</context> <context> <name>Intro</name> <message> @@ -567,6 +839,14 @@ <translation>Вітання</translation> </message> <message> + <source>Welcome to %1.</source> + <translation>Ласкаво просимо до %1.</translation> + </message> + <message> + <source>As this is the first time the program is launched, you can choose where %1 will store its data.</source> + <translation>Оскільки це перший запуск програми, ви можете обрати де %1 буде зберігати дані.</translation> + </message> + <message> <source>Use the default data directory</source> <translation>Використовувати типовий каталог даних</translation> </message> @@ -598,14 +878,50 @@ <translation>Форма</translation> </message> <message> + <source>Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below.</source> + <translation>Нещодавні транзакції ще не відображаються, тому баланс вашого гаманця може бути неточним. Ця інформація буде вірною після того, як ваш гаманець завершить синхронізацію з мережею біткойн, врахровуйте показники нижче.</translation> + </message> + <message> + <source>Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network.</source> + <translation>Спроба видправити біткойни, які ще не відображаються, не буде прийнята мережею.</translation> + </message> + <message> + <source>Number of blocks left</source> + <translation>Залишилося блоків</translation> + </message> + <message> + <source>Unknown...</source> + <translation>Невідомо...</translation> + </message> + <message> <source>Last block time</source> <translation>Час останнього блоку</translation> </message> <message> + <source>Progress</source> + <translation>Прогрес</translation> + </message> + <message> + <source>Progress increase per hour</source> + <translation>Прогрес за годину</translation> + </message> + <message> + <source>calculating...</source> + <translation>рахування...</translation> + </message> + <message> + <source>Estimated time left until synced</source> + <translation>Орієнтовний час до кінця синхронізації</translation> + </message> + <message> <source>Hide</source> <translation>Приховати</translation> </message> - </context> + <message> + <source>Unknown. Syncing Headers (%1)...</source> + <translation>Невідомо. Синхронізація заголовків (%1%)...</translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -624,7 +940,11 @@ <source>Select payment request file</source> <translation>Виберіть файл запиту платежу</translation> </message> - </context> + <message> + <source>Select payment request file to open</source> + <translation>Виберіть файл запиту платежу</translation> + </message> +</context> <context> <name>OptionsDialog</name> <message> @@ -636,6 +956,10 @@ <translation>&Головні</translation> </message> <message> + <source>&Start %1 on system login</source> + <translation>&Запускати %1 при вході в систему</translation> + </message> + <message> <source>Size of &database cache</source> <translation>Розмір &кешу бази даних</translation> </message> @@ -772,6 +1096,10 @@ <translation>&Вікно</translation> </message> <message> + <source>Hide tray icon</source> + <translation>Сховати іконку в треї</translation> + </message> + <message> <source>Show only a tray icon after minimizing the window.</source> <translation>Показувати лише іконку в треї після згортання вікна.</translation> </message> @@ -917,6 +1245,14 @@ </context> <context> <name>PaymentServer</name> + <message> + <source>Payment request error</source> + <translation>Помилка запиту платежу</translation> + </message> + <message> + <source>URI handling</source> + <translation>Обробка URI</translation> + </message> </context> <context> <name>PeerTableModel</name> @@ -928,7 +1264,11 @@ <source>Node/Service</source> <translation>Вузол/Сервіс</translation> </message> - </context> + <message> + <source>Ping</source> + <translation>Затримка</translation> + </message> +</context> <context> <name>QObject</name> <message> @@ -974,10 +1314,30 @@ </context> <context> <name>QObject::QObject</name> - </context> + <message> + <source>Error: %1</source> + <translation>Помилка: %1</translation> + </message> +</context> <context> <name>QRImageWidget</name> - </context> + <message> + <source>&Save Image...</source> + <translation>&Зберегти зображення...</translation> + </message> + <message> + <source>&Copy Image</source> + <translation>&Копіювати зображення</translation> + </message> + <message> + <source>Save QR Code</source> + <translation>Зберегти QR-код</translation> + </message> + <message> + <source>PNG Image (*.png)</source> + <translation>Зображення PNG (*.png)</translation> + </message> +</context> <context> <name>RPCConsole</name> <message> @@ -1089,6 +1449,14 @@ <translation>Клієнт користувача</translation> </message> <message> + <source>Decrease font size</source> + <translation>Зменшити розмір шрифту</translation> + </message> + <message> + <source>Increase font size</source> + <translation>Збільшити розмір шрифту</translation> + </message> + <message> <source>Services</source> <translation>Сервіси</translation> </message> @@ -1189,6 +1557,10 @@ <translation>Наберіть <b>help</b> для перегляду доступних команд.</translation> </message> <message> + <source>Network activity disabled</source> + <translation>Мережева активність вимкнена.</translation> + </message> + <message> <source>%1 B</source> <translation>%1 Б</translation> </message> @@ -1307,7 +1679,23 @@ <source>Remove</source> <translation>Вилучити</translation> </message> - </context> + <message> + <source>Copy URI</source> + <translation>Скопіювати адресу</translation> + </message> + <message> + <source>Copy label</source> + <translation>Скопіювати мітку</translation> + </message> + <message> + <source>Copy message</source> + <translation>Скопіювати повідомлення</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Скопіювати суму</translation> + </message> +</context> <context> <name>ReceiveRequestDialog</name> <message> @@ -1327,21 +1715,57 @@ <translation>&Зберегти зображення...</translation> </message> <message> + <source>Payment information</source> + <translation>Інформація про платіж</translation> + </message> + <message> + <source>Address</source> + <translation>Адреса</translation> + </message> + <message> + <source>Amount</source> + <translation>Кількість</translation> + </message> + <message> <source>Label</source> <translation>Мітка</translation> </message> + <message> + <source>Message</source> + <translation>Повідомлення</translation> + </message> </context> <context> <name>RecentRequestsTableModel</name> <message> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> <source>Label</source> <translation>Мітка</translation> </message> <message> + <source>Message</source> + <translation>Повідомлення</translation> + </message> + <message> <source>(no label)</source> <translation>немає мітки</translation> </message> - </context> + <message> + <source>(no message)</source> + <translation>(без повідомлення)</translation> + </message> + <message> + <source>(no amount requested)</source> + <translation>(без суми)</translation> + </message> + <message> + <source>Requested</source> + <translation>Запрошено</translation> + </message> +</context> <context> <name>SendCoinsDialog</name> <message> @@ -1469,6 +1893,10 @@ <translation>Пил:</translation> </message> <message> + <source>Confirmation time target:</source> + <translation>Час підтвердження:</translation> + </message> + <message> <source>Clear &All</source> <translation>Очистити &все</translation> </message> @@ -1485,6 +1913,34 @@ <translation>&Відправити</translation> </message> <message> + <source>Copy quantity</source> + <translation>Скопіювати кількість</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Скопіювати суму</translation> + </message> + <message> + <source>Copy fee</source> + <translation>Скопіювати комісію</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Скопіювати після комісії</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Скопіювати байти</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Скопіювати інше</translation> + </message> + <message> + <source>Copy change</source> + <translation>Скопіювати решту</translation> + </message> + <message> <source>(no label)</source> <translation>немає мітки</translation> </message> @@ -1567,10 +2023,18 @@ <source>Memo:</source> <translation>Нотатка:</translation> </message> - </context> + <message> + <source>Enter a label for this address to add it to your address book</source> + <translation>Введіть мітку для цієї адреси для додавання її в адресну книгу</translation> + </message> +</context> <context> <name>SendConfirmationDialog</name> - </context> + <message> + <source>Yes</source> + <translation>Так</translation> + </message> +</context> <context> <name>ShutdownWindow</name> <message> @@ -1664,7 +2128,59 @@ <source>Reset all verify message fields</source> <translation>Скинути всі поля перевірки повідомлення</translation> </message> - </context> + <message> + <source>Click "Sign Message" to generate signature</source> + <translation>Натисніть кнопку «Підписати повідомлення», для отримання підпису</translation> + </message> + <message> + <source>The entered address is invalid.</source> + <translation>Введена адреса не співпадає.</translation> + </message> + <message> + <source>Please check the address and try again.</source> + <translation>Будь ласка, перевірте адресу та спробуйте ще.</translation> + </message> + <message> + <source>The entered address does not refer to a key.</source> + <translation>Введена адреса не відноситься до ключа.</translation> + </message> + <message> + <source>Wallet unlock was cancelled.</source> + <translation>Розблокування гаманця було скасоване.</translation> + </message> + <message> + <source>Private key for the entered address is not available.</source> + <translation>Приватний ключ для введеної адреси недоступний. </translation> + </message> + <message> + <source>Message signing failed.</source> + <translation>Не вдалося підписати повідомлення.</translation> + </message> + <message> + <source>Message signed.</source> + <translation>Повідомлення підписано.</translation> + </message> + <message> + <source>The signature could not be decoded.</source> + <translation>Підпис не можливо декодувати.</translation> + </message> + <message> + <source>Please check the signature and try again.</source> + <translation>Будь ласка, перевірте підпис та спробуйте ще.</translation> + </message> + <message> + <source>The signature did not match the message digest.</source> + <translation>Підпис не збігається з хешем повідомлення.</translation> + </message> + <message> + <source>Message verification failed.</source> + <translation>Не вдалося перевірити повідомлення.</translation> + </message> + <message> + <source>Message verified.</source> + <translation>Повідомлення перевірено.</translation> + </message> +</context> <context> <name>SplashScreen</name> <message> @@ -1681,36 +2197,356 @@ </context> <context> <name>TransactionDesc</name> - </context> + <message> + <source>Open until %1</source> + <translation>Відкрито до %1</translation> + </message> + <message> + <source>Status</source> + <translation>Статут</translation> + </message> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <source>Source</source> + <translation>Джерело</translation> + </message> + <message> + <source>Generated</source> + <translation>Згенеровано</translation> + </message> + <message> + <source>From</source> + <translation>Від</translation> + </message> + <message> + <source>unknown</source> + <translation>невідомо</translation> + </message> + <message> + <source>To</source> + <translation>Отримувач</translation> + </message> + <message> + <source>own address</source> + <translation>Власна адреса</translation> + </message> + <message> + <source>label</source> + <translation>мітка</translation> + </message> + <message> + <source>Credit</source> + <translation>Кредит</translation> + </message> + <message> + <source>not accepted</source> + <translation>не прийнято</translation> + </message> + <message> + <source>Debit</source> + <translation>Дебет</translation> + </message> + <message> + <source>Total debit</source> + <translation>Загальний дебет</translation> + </message> + <message> + <source>Total credit</source> + <translation>Загальний кредит</translation> + </message> + <message> + <source>Transaction fee</source> + <translation>Комісія за транзакцію</translation> + </message> + <message> + <source>Net amount</source> + <translation>Загальна сума</translation> + </message> + <message> + <source>Message</source> + <translation>Повідомлення</translation> + </message> + <message> + <source>Comment</source> + <translation>Коментар</translation> + </message> + <message> + <source>Transaction ID</source> + <translation>ID транзакції</translation> + </message> + <message> + <source>Transaction total size</source> + <translation>Розмір транзакції</translation> + </message> + <message> + <source>Merchant</source> + <translation>Продавець</translation> + </message> + <message> + <source>Transaction</source> + <translation>Транзакція</translation> + </message> + <message> + <source>Inputs</source> + <translation>Входи</translation> + </message> + <message> + <source>Amount</source> + <translation>Кількість</translation> + </message> + <message> + <source>true</source> + <translation>вірний</translation> + </message> + <message> + <source>false</source> + <translation>хибний</translation> + </message> +</context> <context> <name>TransactionDescDialog</name> <message> <source>This pane shows a detailed description of the transaction</source> <translation>Даний діалог показує детальну статистику по вибраній транзакції</translation> </message> - </context> + <message> + <source>Details for %1</source> + <translation>Інформація по %1</translation> + </message> +</context> <context> <name>TransactionTableModel</name> <message> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <source>Type</source> + <translation>Тип</translation> + </message> + <message> <source>Label</source> <translation>Мітка</translation> </message> <message> + <source>Open until %1</source> + <translation>Відкрито до %1</translation> + </message> + <message> + <source>Offline</source> + <translation>Поза мережею</translation> + </message> + <message> + <source>Unconfirmed</source> + <translation>Не підтверджено</translation> + </message> + <message> + <source>Abandoned</source> + <translation>Відкинуті</translation> + </message> + <message> + <source>Confirming (%1 of %2 recommended confirmations)</source> + <translation>Підтверджується (%1 з %2 рекомендованих підтверджень)</translation> + </message> + <message> + <source>Confirmed (%1 confirmations)</source> + <translation>Підтверджено (%1 підтверджень)</translation> + </message> + <message> + <source>Conflicted</source> + <translation>Суперечить</translation> + </message> + <message> + <source>Immature (%1 confirmations, will be available after %2)</source> + <translation>Повністтю не підтверджено (%1 підтверджень, будуть доступні після %2)</translation> + </message> + <message> + <source>This block was not received by any other nodes and will probably not be accepted!</source> + <translation>Цей блок не був отриманий жодними іншими вузлами і, ймовірно, не буде прийнятий!</translation> + </message> + <message> + <source>Generated but not accepted</source> + <translation>Згенеровано (не підтверджено)</translation> + </message> + <message> + <source>Received with</source> + <translation>Отримано з</translation> + </message> + <message> + <source>Received from</source> + <translation>Отримано від</translation> + </message> + <message> + <source>Sent to</source> + <translation>Відправлені на</translation> + </message> + <message> + <source>Payment to yourself</source> + <translation>Відправлено собі</translation> + </message> + <message> + <source>Mined</source> + <translation>Добуті</translation> + </message> + <message> <source>(no label)</source> <translation>немає мітки</translation> </message> - </context> + <message> + <source>Transaction status. Hover over this field to show number of confirmations.</source> + <translation>Статус транзакції. Наведіть вказівник на це поле, щоб показати кількість підтверджень.</translation> + </message> + <message> + <source>Date and time that the transaction was received.</source> + <translation>Дата і час, коли транзакцію було отримано.</translation> + </message> + <message> + <source>Type of transaction.</source> + <translation>Тип транзакції.</translation> + </message> + <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Визначений користувачем намір чи мета транзакції.</translation> + </message> + <message> + <source>Amount removed from or added to balance.</source> + <translation>Сума, додана чи знята з балансу.</translation> + </message> +</context> <context> <name>TransactionView</name> <message> + <source>All</source> + <translation>Всі</translation> + </message> + <message> + <source>Today</source> + <translation>Сьогодні</translation> + </message> + <message> + <source>This week</source> + <translation>На цьому тижні</translation> + </message> + <message> + <source>This month</source> + <translation>Цього місяця</translation> + </message> + <message> + <source>Last month</source> + <translation>Минулого місяця</translation> + </message> + <message> + <source>This year</source> + <translation>Цього року</translation> + </message> + <message> + <source>Range...</source> + <translation>Діапазон від:</translation> + </message> + <message> + <source>Received with</source> + <translation>Отримано з</translation> + </message> + <message> + <source>Sent to</source> + <translation>Відправлені на</translation> + </message> + <message> + <source>To yourself</source> + <translation>Відправлені собі</translation> + </message> + <message> + <source>Mined</source> + <translation>Добуті</translation> + </message> + <message> + <source>Other</source> + <translation>Інше</translation> + </message> + <message> + <source>Enter address or label to search</source> + <translation>Введіть адресу чи мітку для пошуку</translation> + </message> + <message> + <source>Min amount</source> + <translation>Мінімальна сума</translation> + </message> + <message> + <source>Abandon transaction</source> + <translation>Відмовитися від транзакції</translation> + </message> + <message> + <source>Copy address</source> + <translation>Скопіювати адресу</translation> + </message> + <message> + <source>Copy label</source> + <translation>Скопіювати мітку</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Скопіювати суму</translation> + </message> + <message> + <source>Copy transaction ID</source> + <translation>Скопіювати ID транзакції </translation> + </message> + <message> + <source>Copy raw transaction</source> + <translation>Скопіювати RAW транзакцію</translation> + </message> + <message> + <source>Copy full transaction details</source> + <translation>Скопіювати повні деталі транзакції</translation> + </message> + <message> + <source>Edit label</source> + <translation>Редагувати мітку</translation> + </message> + <message> + <source>Show transaction details</source> + <translation>Показати деталі транзакції</translation> + </message> + <message> + <source>Export Transaction History</source> + <translation>Експортувати історію транзакцій</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Файли (*.csv) розділеі комами</translation> </message> <message> + <source>Confirmed</source> + <translation>Підтверджено</translation> + </message> + <message> + <source>Watch-only</source> + <translation>Тільки спостереження:</translation> + </message> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <source>Type</source> + <translation>Тип</translation> + </message> + <message> <source>Label</source> <translation>Мітка</translation> </message> <message> + <source>Address</source> + <translation>Адреса</translation> + </message> + <message> + <source>ID</source> + <translation>Ідентифікатор</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Експортування пройшло не успішно</translation> </message> @@ -1730,7 +2566,35 @@ </context> <context> <name>WalletView</name> - </context> + <message> + <source>&Export</source> + <translation>&Експорт</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Експортувати дані з поточної вкладки в файл</translation> + </message> + <message> + <source>Backup Wallet</source> + <translation>Зробити резервне копіювання гаманця</translation> + </message> + <message> + <source>Wallet Data (*.dat)</source> + <translation>Данi гаманця (*.dat)</translation> + </message> + <message> + <source>Backup Failed</source> + <translation>Помилка резервного копіювання</translation> + </message> + <message> + <source>Backup Successful</source> + <translation>Резервну копію створено успішно</translation> + </message> + <message> + <source>The wallet data was successfully saved to %1.</source> + <translation>Дані гаманця успішно збережено в %1.</translation> + </message> +</context> <context> <name>bitcoin-core</name> <message> @@ -1834,6 +2698,10 @@ <translation>Параметри з'єднання:</translation> </message> <message> + <source>Copyright (C) %i-%i</source> + <translation>Всі права збережено. %i-%i</translation> + </message> + <message> <source>Corrupted block database detected</source> <translation>Виявлено пошкоджений блок бази даних</translation> </message> @@ -1914,6 +2782,10 @@ <translation>Підключатися тільки до вузлів в мережі <net> (ipv4, ipv6 або onion)</translation> </message> <message> + <source>Print this help message and exit</source> + <translation>Надрукувати це довідкове повідомлення та вийти</translation> + </message> + <message> <source>Print version and exit</source> <translation>Версія для друку і виходу</translation> </message> @@ -1926,6 +2798,10 @@ <translation>Використання скороченого ланцюжка блоків несумісне з параметром -txindex.</translation> </message> <message> + <source>Rewinding blocks...</source> + <translation>Відтворення блоків...</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Встановити розмір кешу бази даних в мегабайтах (від %d до %d, типово: %d)</translation> </message> @@ -2298,10 +3174,18 @@ <translation>Ретранслювати не-P2SH транзакції з мультипідписом (типово: %u)</translation> </message> <message> + <source>Send transactions with full-RBF opt-in enabled (default: %u)</source> + <translation>Надіслати транзакції з увімкненням full-RBF opt-in (типово: %u)</translation> + </message> + <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Встановити розмір пулу ключів <n> (типово: %u)</translation> </message> <message> + <source>Set maximum BIP141 block weight (default: %d)</source> + <translation>Встановити максимальний розмір блоку BIP141 (за замовчуванням: %d)</translation> + </message> + <message> <source>Set the number of threads to service RPC calls (default: %d)</source> <translation>Встановити число потоків для обслуговування викликів RPC (типово: %d)</translation> </message> @@ -2322,10 +3206,38 @@ <translation>Витрачати непідтверджену решту при відправленні транзакцій (типово: %u)</translation> </message> <message> + <source>Starting network threads...</source> + <translation>Запуск мережевих потоків...</translation> + </message> + <message> + <source>The wallet will avoid paying less than the minimum relay fee.</source> + <translation>Гаманець не не переведе кошти якщо комісія менше мінімальної плати за транзакцію.</translation> + </message> + <message> + <source>This is the minimum transaction fee you pay on every transaction.</source> + <translation>Це мінімальна плата за транзакцію, яку ви сплачуєте за кожну операцію.</translation> + </message> + <message> + <source>This is the transaction fee you will pay if you send a transaction.</source> + <translation>Це транзакційна комісія, яку ви сплатите, якщо будете надсилати транзакцію.</translation> + </message> + <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Поріг відключення учасників з поганою поведінкою (типово: %u)</translation> </message> <message> + <source>Transaction amounts must not be negative</source> + <translation>Сума транзакції занадто мала (зменьшіть комісію, якщо можливо)</translation> + </message> + <message> + <source>Transaction has too long of a mempool chain</source> + <translation>У транзакції занадто довгий ланцюг</translation> + </message> + <message> + <source>Transaction must have at least one recipient</source> + <translation>У транзакції повинен бути щонайменше один одержувач</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Невідома мережа вказана в -onlynet: «%s»</translation> </message> diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index a41d39d51e..9e7de0f98f 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -18,7 +18,7 @@ extern void qt_mac_set_dock_menu(QMenu *); #endif -static MacDockIconHandler *s_instance = NULL; +static MacDockIconHandler *s_instance = nullptr; bool dockClickHandler(id self,SEL _cmd,...) { Q_UNUSED(self) @@ -34,7 +34,7 @@ void setupDockClickHandler() { Class cls = objc_getClass("NSApplication"); id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication")); - if (appInst != NULL) { + if (appInst != nullptr) { id delegate = objc_msgSend(appInst, sel_registerName("delegate")); Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class")); SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); @@ -53,7 +53,7 @@ MacDockIconHandler::MacDockIconHandler() : QObject() setupDockClickHandler(); this->m_dummyWidget = new QWidget(); this->m_dockMenu = new QMenu(this->m_dummyWidget); - this->setMainWindow(NULL); + this->setMainWindow(nullptr); #if QT_VERSION < 0x050000 qt_mac_set_dock_menu(this->m_dockMenu); #elif QT_VERSION >= 0x050200 @@ -69,7 +69,7 @@ void MacDockIconHandler::setMainWindow(QMainWindow *window) { MacDockIconHandler::~MacDockIconHandler() { delete this->m_dummyWidget; - this->setMainWindow(NULL); + this->setMainWindow(nullptr); } QMenu *MacDockIconHandler::dockMenu() diff --git a/src/qt/macnotificationhandler.mm b/src/qt/macnotificationhandler.mm index dd3f622818..4c96d08c8a 100644 --- a/src/qt/macnotificationhandler.mm +++ b/src/qt/macnotificationhandler.mm @@ -75,7 +75,7 @@ bool MacNotificationHandler::hasUserNotificationCenterSupport(void) MacNotificationHandler *MacNotificationHandler::instance() { - static MacNotificationHandler *s_instance = NULL; + static MacNotificationHandler *s_instance = nullptr; if (!s_instance) { s_instance = new MacNotificationHandler(); diff --git a/src/qt/modaloverlay.h b/src/qt/modaloverlay.h index 21ccdbd839..cda23f9540 100644 --- a/src/qt/modaloverlay.h +++ b/src/qt/modaloverlay.h @@ -32,7 +32,7 @@ public Q_SLOTS: // will show or hide the modal layer void showHide(bool hide = false, bool userRequested = false); void closeClicked(); - bool isLayerVisible() { return layerIsVisible; } + bool isLayerVisible() const { return layerIsVisible; } protected: bool eventFilter(QObject * obj, QEvent * ev); diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 93092501c9..4b81c54d36 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -44,7 +44,7 @@ NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift, // loop through pixels for(int x=0;x<img.width();x++) { - // preserve alpha because QColor::getHsl doesen't return the alpha value + // preserve alpha because QColor::getHsl doesn't return the alpha value a = qAlpha(scL[x]); QColor col(scL[x]); diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 8718929c6a..a7a7a4ce11 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -93,7 +93,7 @@ class FreedesktopImage { public: FreedesktopImage() {} - FreedesktopImage(const QImage &img); + explicit FreedesktopImage(const QImage &img); static int metaType(); diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index 5a66161346..3ee656d470 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -44,7 +44,7 @@ void OpenURIDialog::accept() void OpenURIDialog::on_selectFileButton_clicked() { - QString filename = GUIUtil::getOpenFileName(this, tr("Select payment request file to open"), "", "", NULL); + QString filename = GUIUtil::getOpenFileName(this, tr("Select payment request file to open"), "", "", nullptr); if(filename.isEmpty()) return; QUrl fileUri = QUrl::fromLocalFile(filename); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index d6e740ee9c..e9960a01b1 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -36,7 +36,7 @@ OptionsModel::OptionsModel(QObject *parent, bool resetSettings) : void OptionsModel::addOverriddenOption(const std::string &option) { - strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(GetArg(option, "")) + " "; + strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(gArgs.GetArg(option, "")) + " "; } // Writes all missing QSettings with their default values @@ -86,18 +86,18 @@ void OptionsModel::Init(bool resetSettings) // // If setting doesn't exist create it with defaults. // - // If SoftSetArg() or SoftSetBoolArg() return false we were overridden + // If gArgs.SoftSetArg() or gArgs.SoftSetBoolArg() return false we were overridden // by command-line and show this in the UI. // Main if (!settings.contains("nDatabaseCache")) settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache); - if (!SoftSetArg("-dbcache", settings.value("nDatabaseCache").toString().toStdString())) + if (!gArgs.SoftSetArg("-dbcache", settings.value("nDatabaseCache").toString().toStdString())) addOverriddenOption("-dbcache"); if (!settings.contains("nThreadsScriptVerif")) settings.setValue("nThreadsScriptVerif", DEFAULT_SCRIPTCHECK_THREADS); - if (!SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString())) + if (!gArgs.SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString())) addOverriddenOption("-par"); if (!settings.contains("strDataDir")) @@ -107,19 +107,19 @@ void OptionsModel::Init(bool resetSettings) #ifdef ENABLE_WALLET if (!settings.contains("bSpendZeroConfChange")) settings.setValue("bSpendZeroConfChange", true); - if (!SoftSetBoolArg("-spendzeroconfchange", settings.value("bSpendZeroConfChange").toBool())) + if (!gArgs.SoftSetBoolArg("-spendzeroconfchange", settings.value("bSpendZeroConfChange").toBool())) addOverriddenOption("-spendzeroconfchange"); #endif // Network if (!settings.contains("fUseUPnP")) settings.setValue("fUseUPnP", DEFAULT_UPNP); - if (!SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool())) + if (!gArgs.SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool())) addOverriddenOption("-upnp"); if (!settings.contains("fListen")) settings.setValue("fListen", DEFAULT_LISTEN); - if (!SoftSetBoolArg("-listen", settings.value("fListen").toBool())) + if (!gArgs.SoftSetBoolArg("-listen", settings.value("fListen").toBool())) addOverriddenOption("-listen"); if (!settings.contains("fUseProxy")) @@ -127,9 +127,9 @@ void OptionsModel::Init(bool resetSettings) if (!settings.contains("addrProxy")) settings.setValue("addrProxy", "127.0.0.1:9050"); // Only try to set -proxy, if user has enabled fUseProxy - if (settings.value("fUseProxy").toBool() && !SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString())) + if (settings.value("fUseProxy").toBool() && !gArgs.SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString())) addOverriddenOption("-proxy"); - else if(!settings.value("fUseProxy").toBool() && !GetArg("-proxy", "").empty()) + else if(!settings.value("fUseProxy").toBool() && !gArgs.GetArg("-proxy", "").empty()) addOverriddenOption("-proxy"); if (!settings.contains("fUseSeparateProxyTor")) @@ -137,15 +137,15 @@ void OptionsModel::Init(bool resetSettings) if (!settings.contains("addrSeparateProxyTor")) settings.setValue("addrSeparateProxyTor", "127.0.0.1:9050"); // Only try to set -onion, if user has enabled fUseSeparateProxyTor - if (settings.value("fUseSeparateProxyTor").toBool() && !SoftSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString())) + if (settings.value("fUseSeparateProxyTor").toBool() && !gArgs.SoftSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString())) addOverriddenOption("-onion"); - else if(!settings.value("fUseSeparateProxyTor").toBool() && !GetArg("-onion", "").empty()) + else if(!settings.value("fUseSeparateProxyTor").toBool() && !gArgs.GetArg("-onion", "").empty()) addOverriddenOption("-onion"); // Display if (!settings.contains("language")) settings.setValue("language", ""); - if (!SoftSetArg("-lang", settings.value("language").toString().toStdString())) + if (!gArgs.SoftSetArg("-lang", settings.value("language").toString().toStdString())) addOverriddenOption("-lang"); language = settings.value("language").toString(); @@ -441,7 +441,7 @@ void OptionsModel::setRestartRequired(bool fRequired) return settings.setValue("fRestartRequired", fRequired); } -bool OptionsModel::isRestartRequired() +bool OptionsModel::isRestartRequired() const { QSettings settings; return settings.value("fRestartRequired", false).toBool(); diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 78529fbdcc..0ac82a4148 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -59,18 +59,18 @@ public: void setDisplayUnit(const QVariant &value); /* Explicit getters */ - bool getHideTrayIcon() { return fHideTrayIcon; } - bool getMinimizeToTray() { return fMinimizeToTray; } - bool getMinimizeOnClose() { return fMinimizeOnClose; } - int getDisplayUnit() { return nDisplayUnit; } - QString getThirdPartyTxUrls() { return strThirdPartyTxUrls; } + bool getHideTrayIcon() const { return fHideTrayIcon; } + bool getMinimizeToTray() const { return fMinimizeToTray; } + bool getMinimizeOnClose() const { return fMinimizeOnClose; } + int getDisplayUnit() const { return nDisplayUnit; } + QString getThirdPartyTxUrls() const { return strThirdPartyTxUrls; } bool getProxySettings(QNetworkProxy& proxy) const; - bool getCoinControlFeatures() { return fCoinControlFeatures; } + bool getCoinControlFeatures() const { return fCoinControlFeatures; } const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; } /* Restart flag helper */ void setRestartRequired(bool fRequired); - bool isRestartRequired(); + bool isRestartRequired() const; private: /* Qt-only settings */ diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index ba344f4dbf..ba1839e7b4 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -25,7 +25,7 @@ class TxViewDelegate : public QAbstractItemDelegate { Q_OBJECT public: - TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr): + explicit TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr): QAbstractItemDelegate(parent), unit(BitcoinUnits::BTC), platformStyle(_platformStyle) { diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 01ec416613..d3799f59ab 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -22,7 +22,7 @@ class SSLVerifyError : public std::runtime_error { public: - SSLVerifyError(std::string err) : std::runtime_error(err) { } + explicit SSLVerifyError(std::string err) : std::runtime_error(err) { } }; bool PaymentRequestPlus::parse(const QByteArray& data) @@ -66,7 +66,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c // One day we'll support more PKI types, but just // x509 for now: - const EVP_MD* digestAlgorithm = NULL; + const EVP_MD* digestAlgorithm = nullptr; if (paymentRequest.pki_type() == "x509+sha256") { digestAlgorithm = EVP_sha256(); } @@ -104,7 +104,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c } #endif const unsigned char *data = (const unsigned char *)certChain.certificate(i).data(); - X509 *cert = d2i_X509(NULL, &data, certChain.certificate(i).size()); + X509 *cert = d2i_X509(nullptr, &data, certChain.certificate(i).size()); if (cert) certs.push_back(cert); } @@ -129,7 +129,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c return false; } - char *website = NULL; + char *website = nullptr; bool fResult = true; try { @@ -145,7 +145,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c int error = X509_STORE_CTX_get_error(store_ctx); // For testing payment requests, we allow self signed root certs! // This option is just shown in the UI options, if -help-debug is enabled. - if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && GetBoolArg("-allowselfsignedrootcertificates", DEFAULT_SELFSIGNED_ROOTCERTS))) { + if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && gArgs.GetBoolArg("-allowselfsignedrootcertificates", DEFAULT_SELFSIGNED_ROOTCERTS))) { throw SSLVerifyError(X509_verify_cert_error_string(error)); } else { qDebug() << "PaymentRequestPlus::getMerchant: Allowing self signed root certificate, because -allowselfsignedrootcertificates is true."; @@ -169,7 +169,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c #endif EVP_PKEY *pubkey = X509_get_pubkey(signing_cert); EVP_MD_CTX_init(ctx); - if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, NULL) || + if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, nullptr) || !EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) || !EVP_VerifyFinal(ctx, (const unsigned char*)paymentRequest.signature().data(), (unsigned int)paymentRequest.signature().size(), pubkey)) { throw SSLVerifyError("Bad signature, invalid payment request."); @@ -179,7 +179,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c #endif // OpenSSL API for getting human printable strings from certs is baroque. - int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0); + int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, nullptr, 0); website = new char[textlen + 1]; if (X509_NAME_get_text_by_NID(certname, NID_commonName, website, textlen + 1) == textlen && textlen > 0) { merchant = website; diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 132ee32748..d4137d280f 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -122,7 +122,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) // Note: use "-system-" default here so that users can pass -rootcertificates="" // and get 'I don't like X.509 certificates, don't trust anybody' behavior: - QString certFile = QString::fromStdString(GetArg("-rootcertificates", "-system-")); + QString certFile = QString::fromStdString(gArgs.GetArg("-rootcertificates", "-system-")); // Empty store if (certFile.isEmpty()) { @@ -274,7 +274,7 @@ bool PaymentServer::ipcSendCommandLine() if (!socket->waitForConnected(BITCOIN_IPC_CONNECT_TIMEOUT)) { delete socket; - socket = NULL; + socket = nullptr; return false; } @@ -290,7 +290,7 @@ bool PaymentServer::ipcSendCommandLine() socket->disconnectFromServer(); delete socket; - socket = NULL; + socket = nullptr; fResult = true; } @@ -364,7 +364,7 @@ void PaymentServer::initNetManager() { if (!optionsModel) return; - if (netManager != NULL) + if (netManager != nullptr) delete netManager; // netManager is used to fetch paymentrequests given in bitcoin: URIs @@ -620,7 +620,7 @@ void PaymentServer::fetchRequest(const QUrl& url) netManager->get(netRequest); } -void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction) +void PaymentServer::fetchPaymentACK(CWallet* wallet, const SendCoinsRecipient& recipient, QByteArray transaction) { const payments::PaymentDetails& details = recipient.paymentRequest.getDetails(); if (!details.has_payment_url()) diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 7c6d4507fe..98b2364b92 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -72,15 +72,15 @@ public: static bool ipcSendCommandLine(); // parent should be QApplication object - PaymentServer(QObject* parent, bool startLocalServer = true); + explicit PaymentServer(QObject* parent, bool startLocalServer = true); ~PaymentServer(); - // Load root certificate authorities. Pass NULL (default) + // Load root certificate authorities. Pass nullptr (default) // to read from the file specified in the -rootcertificates setting, // or, if that's not set, to use the system default root certificates. // If you pass in a store, you should not X509_STORE_free it: it will be // freed either at exit or when another set of CAs are loaded. - static void LoadRootCAs(X509_STORE* store = NULL); + static void LoadRootCAs(X509_STORE* store = nullptr); // Return certificate store static X509_STORE* getCertStore(); @@ -113,7 +113,7 @@ public Q_SLOTS: void uiReady(); // Submit Payment message to a merchant, get back PaymentACK: - void fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction); + void fetchPaymentACK(CWallet* wallet, const SendCoinsRecipient& recipient, QByteArray transaction); // Handle an incoming URI, URI with local file scheme or file void handleURIOrFile(const QString& s); diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 3752fa4b66..4aa6375d8a 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -68,7 +68,7 @@ void QRImageWidget::saveImage() { if(!pixmap()) return; - QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Image (*.png)"), NULL); + QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Image (*.png)"), nullptr); if (!fn.isEmpty()) { exportImage().save(fn); diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 4e88c8802c..1c4f7aca86 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -123,7 +123,7 @@ void RecentRequestsTableModel::updateAmountColumnTitle() /** Gets title for amount column including current display unit if optionsModel reference available. */ QString RecentRequestsTableModel::getAmountTitle() { - return (this->walletModel->getOptionsModel() != NULL) ? tr("Requested") + " ("+BitcoinUnits::name(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")" : ""; + return (this->walletModel->getOptionsModel() != nullptr) ? tr("Requested") + " ("+BitcoinUnits::name(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")" : ""; } QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 232068bf45..3590a98efa 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -60,7 +60,7 @@ const struct { {"cmd-reply", ":/icons/tx_output"}, {"cmd-error", ":/icons/tx_output"}, {"misc", ":/icons/tx_inout"}, - {NULL, NULL} + {nullptr, nullptr} }; namespace { @@ -532,7 +532,7 @@ void RPCConsole::setClientModel(ClientModel *model) setNumConnections(model->getNumConnections()); connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(NULL), false); + setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(nullptr), false); connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool))); updateNetworkState(); @@ -982,7 +982,7 @@ void RPCConsole::peerLayoutChanged() if (!clientModel || !clientModel->getPeerTableModel()) return; - const CNodeCombinedStats *stats = NULL; + const CNodeCombinedStats *stats = nullptr; bool fUnselect = false; bool fReselect = false; diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index ec531c99c8..da06818f87 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -36,8 +36,8 @@ public: explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent); ~RPCConsole(); - static bool RPCParseCommandLine(std::string &strResult, const std::string &strCommand, bool fExecute, std::string * const pstrFilteredOut = NULL); - static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = NULL) { + static bool RPCParseCommandLine(std::string &strResult, const std::string &strCommand, bool fExecute, std::string * const pstrFilteredOut = nullptr); + static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = nullptr) { return RPCParseCommandLine(strResult, strCommand, true, pstrFilteredOut); } diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index b9a8ad6e28..c7830071ed 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -25,7 +25,7 @@ X509 *parse_b64der_cert(const char* cert_data) std::vector<unsigned char> data = DecodeBase64(cert_data); assert(data.size() > 0); const unsigned char* dptr = &data[0]; - X509 *cert = d2i_X509(NULL, &dptr, data.size()); + X509 *cert = d2i_X509(nullptr, &dptr, data.size()); assert(cert); return cert; } @@ -66,7 +66,7 @@ void PaymentServerTests::paymentServerTests() { SelectParams(CBaseChainParams::MAIN); OptionsModel optionsModel; - PaymentServer* server = new PaymentServer(NULL, false); + PaymentServer* server = new PaymentServer(nullptr, false); X509_STORE* caStore = X509_STORE_new(); X509_STORE_add_cert(caStore, parse_b64der_cert(caCert1_BASE64)); PaymentServer::LoadRootCAs(caStore); @@ -205,7 +205,7 @@ void PaymentServerTests::paymentServerTests() delete server; } -void RecipientCatcher::getRecipient(SendCoinsRecipient r) +void RecipientCatcher::getRecipient(const SendCoinsRecipient& r) { recipient = r; } diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h index 9ffcbb02ac..faf167f2c6 100644 --- a/src/qt/test/paymentservertests.h +++ b/src/qt/test/paymentservertests.h @@ -26,7 +26,7 @@ class RecipientCatcher : public QObject Q_OBJECT public Q_SLOTS: - void getRecipient(SendCoinsRecipient r); + void getRecipient(const SendCoinsRecipient& r); public: SendCoinsRecipient recipient; diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index fbad9e544a..cd9ab23457 100644 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -41,7 +41,7 @@ void RPCNestedTests::rpcNestedTests() std::string path = QDir::tempPath().toStdString() + "/" + strprintf("test_bitcoin_qt_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); QDir dir(QString::fromStdString(path)); dir.mkpath("."); - ForceSetArg("-datadir", path); + gArgs.ForceSetArg("-datadir", path); //mempool.setSanityCheck(1.0); TestingSetup test; @@ -69,13 +69,13 @@ void RPCNestedTests::rpcNestedTests() RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo "); //whitespace at the end will be tolerated QVERIFY(result.substr(0,1) == "{"); - (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child contaning the quotes in the key + (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child containing the quotes in the key QVERIFY(result == "null"); (RPCConsole::RPCExecuteCommandLine(result, "createrawtransaction [] {} 0")); //parameter not in brackets are allowed (RPCConsole::RPCExecuteCommandLine(result2, "createrawtransaction([],{},0)")); //parameter in brackets are allowed QVERIFY(result == result2); - (RPCConsole::RPCExecuteCommandLine(result2, "createrawtransaction( [], {} , 0 )")); //whitespace between parametres is allowed + (RPCConsole::RPCExecuteCommandLine(result2, "createrawtransaction( [], {} , 0 )")); //whitespace between parameters is allowed QVERIFY(result == result2); RPCConsole::RPCExecuteCommandLine(result, "getblock(getbestblockhash())[tx][0]", &filtered); diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index 1b28a285f1..80a00a634a 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -57,7 +57,7 @@ int main(int argc, char *argv[]) bool fInvalid = false; // Prefer the "minimal" platform for the test instead of the normal default - // platform ("xcb", "windows", or "cocoa") so tests can't unintentially + // platform ("xcb", "windows", or "cocoa") so tests can't unintentionally // interfere with any background GUIs and don't require extra resources. #if defined(WIN32) _putenv_s("QT_QPA_PLATFORM", "minimal"); diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 03fd734e92..36d98ce49d 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -167,7 +167,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) // Determine transaction status // Find the block the tx is in - CBlockIndex* pindex = NULL; + CBlockIndex* pindex = nullptr; BlockMap::iterator mi = mapBlockIndex.find(wtx.hashBlock); if (mi != mapBlockIndex.end()) pindex = (*mi).second; @@ -248,7 +248,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) status.needsUpdate = false; } -bool TransactionRecord::statusUpdateNeeded() +bool TransactionRecord::statusUpdateNeeded() const { AssertLockHeld(cs_main); return status.cur_num_blocks != chainActive.Height() || status.needsUpdate; diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 59f681224f..a26e676142 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -140,7 +140,7 @@ public: /** Return whether a status update is needed. */ - bool statusUpdateNeeded(); + bool statusUpdateNeeded() const; }; #endif // BITCOIN_QT_TRANSACTIONRECORD_H diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 80aeb64c41..b1f81498b2 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -79,7 +79,7 @@ public: QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; - bool processingQueuedTransactions() { return fProcessingQueuedTransactions; } + bool processingQueuedTransactions() const { return fProcessingQueuedTransactions; } private: CWallet* wallet; diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 43d6e8826b..53c38da9db 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -343,7 +343,7 @@ void TransactionView::exportClicked() // CSV is currently the only supported format QString filename = GUIUtil::getSaveFileName(this, tr("Export Transaction History"), QString(), - tr("Comma separated file (*.csv)"), NULL); + tr("Comma separated file (*.csv)"), nullptr); if (filename.isNull()) return; diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index c9b344fbd8..5d8c23d13c 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -78,7 +78,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : cursor.insertBlock(); std::string strUsage = HelpMessage(HMM_BITCOIN_QT); - const bool showDebug = GetBoolArg("-help-debug", false); + const bool showDebug = gArgs.GetBoolArg("-help-debug", false); strUsage += HelpMessageGroup(tr("UI Options:").toStdString()); if (showDebug) { strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", strprintf("Allow self signed root certificates (default: %u)", DEFAULT_SELFSIGNED_ROOTCERTS)); diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index acaa864148..738eeed136 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -41,7 +41,7 @@ class ShutdownWindow : public QWidget Q_OBJECT public: - ShutdownWindow(QWidget *parent=0, Qt::WindowFlags f=0); + explicit ShutdownWindow(QWidget *parent=0, Qt::WindowFlags f=0); static QWidget *showShutdownWindow(BitcoinGUI *window); protected: diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index ba0e1da0c7..445d00e9c8 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -577,10 +577,11 @@ void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vect LOCK2(cs_main, wallet->cs_wallet); for (const COutPoint& outpoint : vOutpoints) { - if (!wallet->mapWallet.count(outpoint.hash)) continue; - int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain(); + auto it = wallet->mapWallet.find(outpoint.hash); + if (it == wallet->mapWallet.end()) continue; + int nDepth = it->second.GetDepthInMainChain(); if (nDepth < 0) continue; - COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */); + COutput out(&it->second, outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */); vOutputs.push_back(out); } } @@ -739,7 +740,7 @@ bool WalletModel::bumpFee(uint256 hash) bool WalletModel::isWalletEnabled() { - return !GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET); + return !gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET); } bool WalletModel::hdEnabled() const diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 5258dc6699..6be36a57e2 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -129,7 +129,7 @@ public: TransactionTableModel *getTransactionTableModel(); RecentRequestsTableModel *getRecentRequestsTableModel(); - CAmount getBalance(const CCoinControl *coinControl = NULL) const; + CAmount getBalance(const CCoinControl *coinControl = nullptr) const; CAmount getUnconfirmedBalance() const; CAmount getImmatureBalance() const; bool haveWatchOnly() const; diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 8bc9ef725e..eae2c27f8a 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -22,12 +22,12 @@ WalletModelTransaction::~WalletModelTransaction() delete walletTransaction; } -QList<SendCoinsRecipient> WalletModelTransaction::getRecipients() +QList<SendCoinsRecipient> WalletModelTransaction::getRecipients() const { return recipients; } -CWalletTx *WalletModelTransaction::getTransaction() +CWalletTx *WalletModelTransaction::getTransaction() const { return walletTransaction; } @@ -37,7 +37,7 @@ unsigned int WalletModelTransaction::getTransactionSize() return (!walletTransaction ? 0 : ::GetVirtualTransactionSize(*walletTransaction)); } -CAmount WalletModelTransaction::getTransactionFee() +CAmount WalletModelTransaction::getTransactionFee() const { return fee; } @@ -79,7 +79,7 @@ void WalletModelTransaction::reassignAmounts(int nChangePosRet) } } -CAmount WalletModelTransaction::getTotalTransactionAmount() +CAmount WalletModelTransaction::getTotalTransactionAmount() const { CAmount totalTransactionAmount = 0; for (const SendCoinsRecipient &rcp : recipients) diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index 64922efada..d7ecd7aa8c 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -22,15 +22,15 @@ public: explicit WalletModelTransaction(const QList<SendCoinsRecipient> &recipients); ~WalletModelTransaction(); - QList<SendCoinsRecipient> getRecipients(); + QList<SendCoinsRecipient> getRecipients() const; - CWalletTx *getTransaction(); + CWalletTx *getTransaction() const; unsigned int getTransactionSize(); void setTransactionFee(const CAmount& newFee); - CAmount getTransactionFee(); + CAmount getTransactionFee() const; - CAmount getTotalTransactionAmount(); + CAmount getTotalTransactionAmount() const; void newPossibleKeyChange(CWallet *wallet); CReserveKey *getPossibleKeyChange(); diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 4a18c0bd4d..971f5e0e1a 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -246,7 +246,7 @@ void WalletView::backupWallet() { QString filename = GUIUtil::getSaveFileName(this, tr("Backup Wallet"), QString(), - tr("Wallet Data (*.dat)"), NULL); + tr("Wallet Data (*.dat)"), nullptr); if (filename.isEmpty()) return; diff --git a/src/qt/winshutdownmonitor.cpp b/src/qt/winshutdownmonitor.cpp index d6f40c38b8..d78d9a2358 100644 --- a/src/qt/winshutdownmonitor.cpp +++ b/src/qt/winshutdownmonitor.cpp @@ -57,7 +57,7 @@ void WinShutdownMonitor::registerShutdownBlockReason(const QString& strReason, c { typedef BOOL (WINAPI *PSHUTDOWNBRCREATE)(HWND, LPCWSTR); PSHUTDOWNBRCREATE shutdownBRCreate = (PSHUTDOWNBRCREATE)GetProcAddress(GetModuleHandleA("User32.dll"), "ShutdownBlockReasonCreate"); - if (shutdownBRCreate == NULL) { + if (shutdownBRCreate == nullptr) { qWarning() << "registerShutdownBlockReason: GetProcAddress for ShutdownBlockReasonCreate failed"; return; } diff --git a/src/random.cpp b/src/random.cpp index e07ef44471..4bcb8945f3 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -155,7 +155,7 @@ static void RandAddSeedPerfmon() const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data while (true) { nSize = vData.size(); - ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, vData.data(), &nSize); + ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", nullptr, nullptr, vData.data(), &nSize); if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize) break; vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially @@ -203,7 +203,7 @@ void GetOSRand(unsigned char *ent32) { #if defined(WIN32) HCRYPTPROV hProvider; - int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if (!ret) { RandFailure(); } @@ -242,7 +242,7 @@ void GetOSRand(unsigned char *ent32) } #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX) // We need a fallback for OSX < 10.12 - if (&getentropy != NULL) { + if (&getentropy != nullptr) { if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) { RandFailure(); } @@ -257,7 +257,7 @@ void GetOSRand(unsigned char *ent32) int have = 0; do { size_t len = NUM_OS_RANDOM_BYTES - have; - if (sysctl(name, ARRAYLEN(name), ent32 + have, &len, NULL, 0) != 0) { + if (sysctl(name, ARRAYLEN(name), ent32 + have, &len, nullptr, 0) != 0) { RandFailure(); } have += len; diff --git a/src/rest.cpp b/src/rest.cpp index 33e3fb4529..154ee04eed 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -48,7 +48,7 @@ struct CCoin { ADD_SERIALIZE_METHODS; CCoin() : nHeight(0) {} - CCoin(Coin&& in) : nHeight(in.nHeight), out(std::move(in.out)) {} + explicit CCoin(Coin&& in) : nHeight(in.nHeight), out(std::move(in.out)) {} template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) @@ -134,7 +134,7 @@ static bool rest_headers(HTTPRequest* req, if (path.size() != 2) return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>."); - long count = strtol(path[0].c_str(), NULL, 10); + long count = strtol(path[0].c_str(), nullptr, 10); if (count < 1 || count > 2000) return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); @@ -148,8 +148,8 @@ static bool rest_headers(HTTPRequest* req, { LOCK(cs_main); BlockMap::const_iterator it = mapBlockIndex.find(hash); - const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : NULL; - while (pindex != NULL && chainActive.Contains(pindex)) { + const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : nullptr; + while (pindex != nullptr && chainActive.Contains(pindex)) { headers.push_back(pindex); if (headers.size() == (unsigned long)count) break; @@ -209,7 +209,7 @@ static bool rest_block(HTTPRequest* req, return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); CBlock block; - CBlockIndex* pblockindex = NULL; + CBlockIndex* pblockindex = nullptr; { LOCK(cs_main); if (mapBlockIndex.count(hash) == 0) diff --git a/src/reverse_iterator.h b/src/reverse_iterator.h index 409f895ce0..ab467f07c9 100644 --- a/src/reverse_iterator.h +++ b/src/reverse_iterator.h @@ -1,7 +1,7 @@ // Taken from https://gist.github.com/arvidsson/7231973 -#ifndef BITCOIN_REVERSE_ITERATOR_HPP -#define BITCOIN_REVERSE_ITERATOR_HPP +#ifndef BITCOIN_REVERSE_ITERATOR_H +#define BITCOIN_REVERSE_ITERATOR_H /** * Template used for reverse iteration in C++11 range-based for loops. @@ -14,19 +14,19 @@ template <typename T> class reverse_range { - T &x; + T &m_x; public: - reverse_range(T &x) : x(x) {} + explicit reverse_range(T &x) : m_x(x) {} - auto begin() const -> decltype(this->x.rbegin()) + auto begin() const -> decltype(this->m_x.rbegin()) { - return x.rbegin(); + return m_x.rbegin(); } - auto end() const -> decltype(this->x.rend()) + auto end() const -> decltype(this->m_x.rend()) { - return x.rend(); + return m_x.rend(); } }; @@ -36,4 +36,4 @@ reverse_range<T> reverse_iterate(T &x) return reverse_range<T>(x); } -#endif // BITCOIN_REVERSE_ITERATOR_HPP +#endif // BITCOIN_REVERSE_ITERATOR_H diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index d65e107e3c..34bcdf9ccc 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -48,9 +48,9 @@ extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& double GetDifficulty(const CBlockIndex* blockindex) { - if (blockindex == NULL) + if (blockindex == nullptr) { - if (chainActive.Tip() == NULL) + if (chainActive.Tip() == nullptr) return 1.0; else blockindex = chainActive.Tip(); @@ -125,7 +125,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx if(txDetails) { UniValue objTx(UniValue::VOBJ); - TxToUniv(*tx, uint256(), objTx); + TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags()); txs.push_back(objTx); } else @@ -962,7 +962,6 @@ UniValue gettxout(const JSONRPCRequest& request) " ,...\n" " ]\n" " },\n" - " \"version\" : n, (numeric) The version\n" " \"coinbase\" : true|false (boolean) Coinbase or not\n" "}\n" @@ -1019,8 +1018,8 @@ UniValue gettxout(const JSONRPCRequest& request) UniValue verifychain(const JSONRPCRequest& request) { - int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL); - int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); + int nCheckLevel = gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL); + int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); if (request.fHelp || request.params.size() > 2) throw std::runtime_error( "verifychain ( checklevel nblocks )\n" @@ -1325,7 +1324,7 @@ UniValue mempoolInfoToJSON() ret.push_back(Pair("size", (int64_t) mempool.size())); ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); - size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; ret.push_back(Pair("maxmempool", (int64_t) maxmempool)); ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK()))); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 7d292a4635..652d886c7e 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -52,7 +52,7 @@ UniValue GetNetworkHashPS(int lookup, int height) { if (height >= 0 && height < chainActive.Height()) pb = chainActive[height]; - if (pb == NULL || !pb->nHeight) + if (pb == nullptr || !pb->nHeight) return 0; // If lookup is -1, then use blocks since last difficulty change. @@ -139,7 +139,7 @@ UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGen continue; } std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock); - if (!ProcessNewBlock(Params(), shared_pblock, true, NULL)) + if (!ProcessNewBlock(Params(), shared_pblock, true, nullptr)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); @@ -686,7 +686,7 @@ public: bool found; CValidationState state; - submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {} + explicit submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {} protected: void BlockChecked(const CBlock& block, const CValidationState& stateIn) override { @@ -754,7 +754,7 @@ UniValue submitblock(const JSONRPCRequest& request) submitblock_StateCatcher sc(block.GetHash()); RegisterValidationInterface(&sc); - bool fAccepted = ProcessNewBlock(Params(), blockptr, true, NULL); + bool fAccepted = ProcessNewBlock(Params(), blockptr, true, nullptr); UnregisterValidationInterface(&sc); if (fBlockPresent) { if (fAccepted && !sc.found) { diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index f3c86038a3..1dd660eb8f 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -6,6 +6,7 @@ #include "base58.h" #include "chain.h" #include "clientversion.h" +#include "core_io.h" #include "init.h" #include "validation.h" #include "httpserver.h" @@ -77,7 +78,7 @@ UniValue getinfo(const JSONRPCRequest& request) #ifdef ENABLE_WALLET CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL); + LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr); #else LOCK(cs_main); #endif @@ -124,7 +125,7 @@ class DescribeAddressVisitor : public boost::static_visitor<UniValue> public: CWallet * const pwallet; - DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {} + explicit DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {} UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); } @@ -201,7 +202,7 @@ UniValue validateaddress(const JSONRPCRequest& request) #ifdef ENABLE_WALLET CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL); + LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr); #else LOCK(cs_main); #endif @@ -321,7 +322,7 @@ UniValue createmultisig(const JSONRPCRequest& request) #ifdef ENABLE_WALLET CWallet * const pwallet = GetWalletForJSONRPCRequest(request); #else - CWallet * const pwallet = NULL; + CWallet * const pwallet = nullptr; #endif if (request.fHelp || request.params.size() < 2 || request.params.size() > 2) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index b4d6795e62..e463a4eda4 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -6,6 +6,7 @@ #include "chainparams.h" #include "clientversion.h" +#include "core_io.h" #include "validation.h" #include "net.h" #include "net_processing.h" @@ -216,7 +217,7 @@ UniValue addnode(const JSONRPCRequest& request) if (strCommand == "onetry") { CAddress addr; - g_connman->OpenNetworkConnection(addr, false, NULL, strNode.c_str()); + g_connman->OpenNetworkConnection(addr, false, nullptr, strNode.c_str()); return NullUniValue; } diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index 823a5775f6..db0626b5e1 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -68,7 +68,7 @@ static const std::string COOKIEAUTH_FILE = ".cookie"; fs::path GetAuthCookieFile() { - fs::path path(GetArg("-rpccookiefile", COOKIEAUTH_FILE)); + fs::path path(gArgs.GetArg("-rpccookiefile", COOKIEAUTH_FILE)); if (!path.is_complete()) path = GetDataDir() / path; return path; } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index b967f2dbf8..55e4746827 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -41,7 +41,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) // Blockchain contextual information (confirmations and blocktime) is not // available to code in bitcoin-common, so we query them here and push the // data into the returned UniValue. - TxToUniv(tx, uint256(), entry); + TxToUniv(tx, uint256(), entry, true, RPCSerializationFlags()); if (!hashBlock.IsNull()) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); @@ -160,13 +160,10 @@ UniValue getrawtransaction(const JSONRPCRequest& request) : "No such mempool transaction. Use -txindex to enable blockchain transaction queries") + ". Use gettransaction for wallet transactions."); - std::string strHex = EncodeHexTx(*tx, RPCSerializationFlags()); - if (!fVerbose) - return strHex; + return EncodeHexTx(*tx, RPCSerializationFlags()); UniValue result(UniValue::VOBJ); - result.push_back(Pair("hex", strHex)); TxToJSON(*tx, hashBlock, result); return result; } @@ -208,7 +205,7 @@ UniValue gettxoutproof(const JSONRPCRequest& request) LOCK(cs_main); - CBlockIndex* pblockindex = NULL; + CBlockIndex* pblockindex = nullptr; uint256 hashBlock; if (!request.params[1].isNull()) @@ -228,7 +225,7 @@ UniValue gettxoutproof(const JSONRPCRequest& request) } } - if (pblockindex == NULL) + if (pblockindex == nullptr) { CTransactionRef tx; if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull()) @@ -483,7 +480,7 @@ UniValue decoderawtransaction(const JSONRPCRequest& request) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); UniValue result(UniValue::VOBJ); - TxToUniv(CTransaction(std::move(mtx)), uint256(), result); + TxToUniv(CTransaction(std::move(mtx)), uint256(), result, false); return result; } @@ -572,7 +569,7 @@ UniValue combinerawtransaction(const JSONRPCRequest& request) " ]\n" "\nResult:\n" - "\"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n" + "\"hex\" (string) The hex-encoded raw transaction with signature(s)\n" "\nExamples:\n" + HelpExampleCli("combinerawtransaction", "[\"myhex1\", \"myhex2\", \"myhex3\"]") @@ -707,7 +704,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) ); #ifdef ENABLE_WALLET - LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL); + LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr); #else LOCK(cs_main); #endif @@ -937,7 +934,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) CValidationState state; bool fMissingInputs; bool fLimitFree = true; - if (!AcceptToMemoryPool(mempool, state, std::move(tx), fLimitFree, &fMissingInputs, NULL, false, nMaxRawTxFee)) { + if (!AcceptToMemoryPool(mempool, state, std::move(tx), fLimitFree, &fMissingInputs, nullptr, false, nMaxRawTxFee)) { if (state.IsInvalid()) { throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); } else { diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 63e4e9c630..9ad8d228fa 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -30,7 +30,7 @@ static bool fRPCInWarmup = true; static std::string rpcWarmupStatus("RPC server started"); static CCriticalSection cs_rpcWarmup; /* Timer-creating functions */ -static RPCTimerInterface* timerInterface = NULL; +static RPCTimerInterface* timerInterface = nullptr; /* Map of name to timer. */ static std::map<std::string, std::unique_ptr<RPCTimerBase> > deadlineTimers; @@ -123,16 +123,6 @@ CAmount AmountFromValue(const UniValue& value) return amount; } -UniValue ValueFromAmount(const CAmount& amount) -{ - bool sign = amount < 0; - int64_t n_abs = (sign ? -amount : amount); - int64_t quotient = n_abs / COIN; - int64_t remainder = n_abs % COIN; - return UniValue(UniValue::VNUM, - strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder)); -} - uint256 ParseHashV(const UniValue& v, std::string strName) { std::string strHex; @@ -301,7 +291,7 @@ const CRPCCommand *CRPCTable::operator[](const std::string &name) const { std::map<std::string, const CRPCCommand*>::const_iterator it = mapCommands.find(name); if (it == mapCommands.end()) - return NULL; + return nullptr; return (*it).second; } @@ -547,7 +537,7 @@ void RPCSetTimerInterface(RPCTimerInterface *iface) void RPCUnsetTimerInterface(RPCTimerInterface *iface) { if (timerInterface == iface) - timerInterface = NULL; + timerInterface = nullptr; } void RPCRunLater(const std::string& name, std::function<void(void)> func, int64_t nSeconds) @@ -562,7 +552,7 @@ void RPCRunLater(const std::string& name, std::function<void(void)> func, int64_ int RPCSerializationFlags() { int flag = 0; - if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0) + if (gArgs.GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0) flag |= SERIALIZE_TRANSACTION_NO_WITNESS; return flag; } diff --git a/src/rpc/server.h b/src/rpc/server.h index b20c827727..89b1d169d5 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -31,7 +31,7 @@ namespace RPCServer /** Wrapper for UniValue::VType, which includes typeAny: * Used to denote don't care type. Only used by RPCTypeCheckObj */ struct UniValueType { - UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {} + explicit UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {} UniValueType() : typeAny(true) {} bool typeAny; UniValue::VType type; @@ -185,7 +185,6 @@ extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strNa extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey); extern CAmount AmountFromValue(const UniValue& value); -extern UniValue ValueFromAmount(const CAmount& amount); extern std::string HelpExampleCli(const std::string& methodname, const std::string& args); extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args); diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 1d3fb1f6ea..4edb2c6d9b 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -174,7 +174,7 @@ void SingleThreadedSchedulerClient::ProcessQueue() { // to ensure both happen safely even if callback() throws. struct RAIICallbacksRunning { SingleThreadedSchedulerClient* instance; - RAIICallbacksRunning(SingleThreadedSchedulerClient* _instance) : instance(_instance) {} + explicit RAIICallbacksRunning(SingleThreadedSchedulerClient* _instance) : instance(_instance) {} ~RAIICallbacksRunning() { { LOCK(instance->m_cs_callbacks_pending); diff --git a/src/scheduler.h b/src/scheduler.h index 0365d668b2..db93bcb21e 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -81,7 +81,7 @@ private: int nThreadsServicingQueue; bool stopRequested; bool stopWhenEmpty; - bool shouldStop() { return stopRequested || (stopWhenEmpty && taskQueue.empty()); } + bool shouldStop() const { return stopRequested || (stopWhenEmpty && taskQueue.empty()); } }; /** @@ -102,7 +102,7 @@ private: void ProcessQueue(); public: - SingleThreadedSchedulerClient(CScheduler *pschedulerIn) : m_pscheduler(pschedulerIn) {} + explicit SingleThreadedSchedulerClient(CScheduler *pschedulerIn) : m_pscheduler(pschedulerIn) {} void AddToProcessQueue(std::function<void (void)> func); // Processes all remaining queue members on the calling thread, blocking until queue is empty diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 4b71a42cdf..03128917fd 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -28,10 +28,10 @@ public: if (nSize > m_remaining) throw std::ios_base::failure(std::string(__func__) + ": end of data"); - if (pch == NULL) + if (pch == nullptr) throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer"); - if (m_data == NULL) + if (m_data == nullptr) throw std::ios_base::failure(std::string(__func__) + ": bad source buffer"); memcpy(pch, m_data, nSize); @@ -95,7 +95,7 @@ static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptP set_error(err, bitcoinconsensus_ERR_OK); PrecomputedTransactionData txdata(tx); - return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), &tx.vin[nIn].scriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata), NULL); + return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), &tx.vin[nIn].scriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata), nullptr); } catch (const std::exception&) { return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing } diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index 1bef4fe9e9..33bf80e5a7 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -63,7 +63,7 @@ enum /// Returns 1 if the input nIn of the serialized transaction pointed to by /// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under /// the additional constraints specified by flags. -/// If not NULL, err will contain an error/success code for the operation +/// If not nullptr, err will contain an error/success code for the operation EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char *txTo , unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err); diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 8a121774a0..f9716dfc66 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1407,7 +1407,7 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) { static const CScriptWitness emptyWitness; - if (witness == NULL) { + if (witness == nullptr) { witness = &emptyWitness; } bool hadWitness = false; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index ab1dc4e681..f845e1943b 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -114,7 +114,7 @@ struct PrecomputedTransactionData { uint256 hashPrevouts, hashSequence, hashOutputs; - PrecomputedTransactionData(const CTransaction& tx); + explicit PrecomputedTransactionData(const CTransaction& tx); }; enum SigVersion @@ -123,7 +123,7 @@ enum SigVersion SIGVERSION_WITNESS_V0 = 1, }; -uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = NULL); +uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = nullptr); class BaseSignatureChecker { @@ -158,7 +158,7 @@ protected: virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; public: - TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(NULL) {} + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(nullptr) {} TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override; bool CheckLockTime(const CScriptNum& nLockTime) const override; @@ -174,8 +174,8 @@ public: MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : TransactionSignatureChecker(&txTo, nInIn, amountIn), txTo(*txToIn) {} }; -bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = NULL); -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = NULL); +bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = nullptr); +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = nullptr); size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags); diff --git a/src/script/script.h b/src/script/script.h index d16bfd0e00..587f2d26eb 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -377,6 +377,12 @@ private: int64_t m_value; }; +/** + * We use a prevector for the script to reduce the considerable memory overhead + * of vectors in cases where they normally contain a small number of small elements. + * Tests in October 2015 showed use of this reduced dbcache memory usage by 23% + * and made an initial sync 13% faster. + */ typedef prevector<28, unsigned char> CScriptBase; /** Serialized script, used inside transaction inputs and outputs */ @@ -498,7 +504,7 @@ public: bool GetOp(iterator& pc, opcodetype& opcodeRet) { const_iterator pc2 = pc; - bool fRet = GetOp2(pc2, opcodeRet, NULL); + bool fRet = GetOp2(pc2, opcodeRet, nullptr); pc = begin() + (pc2 - begin()); return fRet; } @@ -510,7 +516,7 @@ public: bool GetOp(const_iterator& pc, opcodetype& opcodeRet) const { - return GetOp2(pc, opcodeRet, NULL); + return GetOp2(pc, opcodeRet, nullptr); } bool GetOp2(const_iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet) const diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index ceb573b2ec..4cc7afa2f5 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -74,7 +74,7 @@ void InitSignatureCache() { // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero, // setup_bytes creates the minimum possible cache (2 elements). - size_t nMaxCacheSize = std::min(std::max((int64_t)0, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); + size_t nMaxCacheSize = std::min(std::max((int64_t)0, gArgs.GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); size_t nElems = signatureCache.setup_bytes(nMaxCacheSize); LogPrintf("Using %zu MiB out of %zu/2 requested for signature cache, able to store %zu elements\n", (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems); diff --git a/src/script/sign.h b/src/script/sign.h index bd45862892..a0d8ee4ff9 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -21,7 +21,7 @@ protected: const CKeyStore* keystore; public: - BaseSignatureCreator(const CKeyStore* keystoreIn) : keystore(keystoreIn) {} + explicit BaseSignatureCreator(const CKeyStore* keystoreIn) : keystore(keystoreIn) {} const CKeyStore& KeyStore() const { return *keystore; }; virtual ~BaseSignatureCreator() {} virtual const BaseSignatureChecker& Checker() const =0; @@ -54,7 +54,7 @@ public: /** A signature creator that just produces 72-byte empty signatures. */ class DummySignatureCreator : public BaseSignatureCreator { public: - DummySignatureCreator(const CKeyStore* keystoreIn) : BaseSignatureCreator(keystoreIn) {} + explicit DummySignatureCreator(const CKeyStore* keystoreIn) : BaseSignatureCreator(keystoreIn) {} const BaseSignatureChecker& Checker() const override; bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override; }; diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 760a5305e5..0f720d9e76 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -31,7 +31,7 @@ const char* GetTxnOutputType(txnouttype t) case TX_WITNESS_V0_KEYHASH: return "witness_v0_keyhash"; case TX_WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash"; } - return NULL; + return nullptr; } /** @@ -253,7 +253,7 @@ class CScriptVisitor : public boost::static_visitor<bool> private: CScript *script; public: - CScriptVisitor(CScript *scriptin) { script = scriptin; } + explicit CScriptVisitor(CScript *scriptin) { script = scriptin; } bool operator()(const CNoDestination &dest) const { script->clear(); diff --git a/src/serialize.h b/src/serialize.h index 8b86a07a76..eeb05fa76c 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -402,7 +402,7 @@ class CVarInt protected: I &n; public: - CVarInt(I& nIn) : n(nIn) { } + explicit CVarInt(I& nIn) : n(nIn) { } template<typename Stream> void Serialize(Stream &s) const { @@ -420,7 +420,7 @@ class CCompactSize protected: uint64_t &n; public: - CCompactSize(uint64_t& nIn) : n(nIn) { } + explicit CCompactSize(uint64_t& nIn) : n(nIn) { } template<typename Stream> void Serialize(Stream &s) const { @@ -439,7 +439,7 @@ class LimitedString protected: std::string& string; public: - LimitedString(std::string& _string) : string(_string) {} + explicit LimitedString(std::string& _string) : string(_string) {} template<typename Stream> void Unserialize(Stream& s) diff --git a/src/streams.h b/src/streams.h index 245fb9cd8f..a3fc919714 100644 --- a/src/streams.h +++ b/src/streams.h @@ -332,7 +332,7 @@ public: // bool eof() const { return size() == 0; } CDataStream* rdbuf() { return this; } - int in_avail() { return size(); } + int in_avail() const { return size(); } void SetType(int n) { nType = n; } int GetType() const { return nType; } @@ -479,7 +479,7 @@ public: { if (file) { ::fclose(file); - file = NULL; + file = nullptr; } } @@ -487,7 +487,7 @@ public: * @note This will invalidate the CAutoFile object, and makes it the responsibility of the caller * of this function to clean up the returned FILE*. */ - FILE* release() { FILE* ret = file; file = NULL; return ret; } + FILE* release() { FILE* ret = file; file = nullptr; return ret; } /** Get wrapped FILE* without transfer of ownership. * @note Ownership of the FILE* will remain with this class. Use this only if the scope of the @@ -495,9 +495,9 @@ public: */ FILE* Get() const { return file; } - /** Return true if the wrapped FILE* is NULL, false otherwise. + /** Return true if the wrapped FILE* is nullptr, false otherwise. */ - bool IsNull() const { return (file == NULL); } + bool IsNull() const { return (file == nullptr); } // // Stream subset @@ -508,7 +508,7 @@ public: void read(char* pch, size_t nSize) { if (!file) - throw std::ios_base::failure("CAutoFile::read: file handle is NULL"); + throw std::ios_base::failure("CAutoFile::read: file handle is nullptr"); if (fread(pch, 1, nSize, file) != nSize) throw std::ios_base::failure(feof(file) ? "CAutoFile::read: end of file" : "CAutoFile::read: fread failed"); } @@ -516,7 +516,7 @@ public: void ignore(size_t nSize) { if (!file) - throw std::ios_base::failure("CAutoFile::ignore: file handle is NULL"); + throw std::ios_base::failure("CAutoFile::ignore: file handle is nullptr"); unsigned char data[4096]; while (nSize > 0) { size_t nNow = std::min<size_t>(nSize, sizeof(data)); @@ -529,7 +529,7 @@ public: void write(const char* pch, size_t nSize) { if (!file) - throw std::ios_base::failure("CAutoFile::write: file handle is NULL"); + throw std::ios_base::failure("CAutoFile::write: file handle is nullptr"); if (fwrite(pch, 1, nSize, file) != nSize) throw std::ios_base::failure("CAutoFile::write: write failed"); } @@ -539,7 +539,7 @@ public: { // Serialize to this stream if (!file) - throw std::ios_base::failure("CAutoFile::operator<<: file handle is NULL"); + throw std::ios_base::failure("CAutoFile::operator<<: file handle is nullptr"); ::Serialize(*this, obj); return (*this); } @@ -549,7 +549,7 @@ public: { // Unserialize from this stream if (!file) - throw std::ios_base::failure("CAutoFile::operator>>: file handle is NULL"); + throw std::ios_base::failure("CAutoFile::operator>>: file handle is nullptr"); ::Unserialize(*this, obj); return (*this); } @@ -616,7 +616,7 @@ public: { if (src) { ::fclose(src); - src = NULL; + src = nullptr; } } @@ -648,7 +648,7 @@ public: } // return the current reading position - uint64_t GetPos() { + uint64_t GetPos() const { return nReadPos; } diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h index 9daba86ef3..39347c73bb 100644 --- a/src/support/allocators/secure.h +++ b/src/support/allocators/secure.h @@ -26,13 +26,13 @@ struct secure_allocator : public std::allocator<T> { typedef typename base::reference reference; typedef typename base::const_reference const_reference; typedef typename base::value_type value_type; - secure_allocator() throw() {} - secure_allocator(const secure_allocator& a) throw() : base(a) {} + secure_allocator() noexcept {} + secure_allocator(const secure_allocator& a) noexcept : base(a) {} template <typename U> - secure_allocator(const secure_allocator<U>& a) throw() : base(a) + secure_allocator(const secure_allocator<U>& a) noexcept : base(a) { } - ~secure_allocator() throw() {} + ~secure_allocator() noexcept {} template <typename _Other> struct rebind { typedef secure_allocator<_Other> other; @@ -45,7 +45,7 @@ struct secure_allocator : public std::allocator<T> { void deallocate(T* p, std::size_t n) { - if (p != NULL) { + if (p != nullptr) { memory_cleanse(p, sizeof(T) * n); } LockedPoolManager::Instance().free(p); diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h index 28a940ad1b..618874ceee 100644 --- a/src/support/allocators/zeroafterfree.h +++ b/src/support/allocators/zeroafterfree.h @@ -22,13 +22,13 @@ struct zero_after_free_allocator : public std::allocator<T> { typedef typename base::reference reference; typedef typename base::const_reference const_reference; typedef typename base::value_type value_type; - zero_after_free_allocator() throw() {} - zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {} + zero_after_free_allocator() noexcept {} + zero_after_free_allocator(const zero_after_free_allocator& a) noexcept : base(a) {} template <typename U> - zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) + zero_after_free_allocator(const zero_after_free_allocator<U>& a) noexcept : base(a) { } - ~zero_after_free_allocator() throw() {} + ~zero_after_free_allocator() noexcept {} template <typename _Other> struct rebind { typedef zero_after_free_allocator<_Other> other; @@ -36,7 +36,7 @@ struct zero_after_free_allocator : public std::allocator<T> { void deallocate(T* p, std::size_t n) { - if (p != NULL) + if (p != nullptr) memory_cleanse(p, sizeof(T) * n); std::allocator<T>::deallocate(p, n); } diff --git a/src/support/events.h b/src/support/events.h index 90690876ee..cc6d29aecd 100644 --- a/src/support/events.h +++ b/src/support/events.h @@ -47,7 +47,7 @@ inline raii_evhttp_request obtain_evhttp_request(void(*cb)(struct evhttp_request } inline raii_evhttp_connection obtain_evhttp_connection_base(struct event_base* base, std::string host, uint16_t port) { - auto result = raii_evhttp_connection(evhttp_connection_base_new(base, NULL, host.c_str(), port)); + auto result = raii_evhttp_connection(evhttp_connection_base_new(base, nullptr, host.c_str(), port)); if (!result.get()) throw std::runtime_error("create connection failed"); return result; diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp index 2df6b84a59..2ead72185f 100644 --- a/src/support/lockedpool.cpp +++ b/src/support/lockedpool.cpp @@ -28,7 +28,7 @@ #include <algorithm> -LockedPoolManager* LockedPoolManager::_instance = NULL; +LockedPoolManager* LockedPoolManager::_instance = nullptr; std::once_flag LockedPoolManager::init_flag; /*******************************************************************************/ @@ -87,7 +87,7 @@ template <class Iterator, class Pair> bool extend(Iterator it, const Pair& other void Arena::free(void *ptr) { - // Freeing the NULL pointer is OK. + // Freeing the nullptr pointer is OK. if (ptr == nullptr) { return; } diff --git a/src/support/lockedpool.h b/src/support/lockedpool.h index f5212bc266..cecbdec1aa 100644 --- a/src/support/lockedpool.h +++ b/src/support/lockedpool.h @@ -150,7 +150,7 @@ public: * If this callback is provided and returns false, the allocation fails (hard fail), if * it returns true the allocation proceeds, but it could warn. */ - LockedPool(std::unique_ptr<LockedPageAllocator> allocator, LockingFailed_Callback lf_cb_in = 0); + explicit LockedPool(std::unique_ptr<LockedPageAllocator> allocator, LockingFailed_Callback lf_cb_in = nullptr); ~LockedPool(); /** Allocate size bytes from this arena. @@ -217,7 +217,7 @@ public: } private: - LockedPoolManager(std::unique_ptr<LockedPageAllocator> allocator); + explicit LockedPoolManager(std::unique_ptr<LockedPageAllocator> allocator); /** Create a new LockedPoolManager specialized to the OS */ static void CreateInstance(); diff --git a/src/sync.cpp b/src/sync.cpp index c359e8220b..9c351ea487 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -100,7 +100,7 @@ static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) { - if (lockstack.get() == NULL) + if (lockstack.get() == nullptr) lockstack.reset(new LockStack); boost::unique_lock<boost::mutex> lock(lockdata.dd_mutex); @@ -162,7 +162,7 @@ void DeleteLock(void* cs) return; } boost::unique_lock<boost::mutex> lock(lockdata.dd_mutex); - std::pair<void*, void*> item = std::make_pair(cs, (void*)0); + std::pair<void*, void*> item = std::make_pair(cs, nullptr); LockOrders::iterator it = lockdata.lockorders.lower_bound(item); while (it != lockdata.lockorders.end() && it->first.first == cs) { std::pair<void*, void*> invitem = std::make_pair(it->first.second, it->first.first); diff --git a/src/sync.h b/src/sync.h index 20974f5fbc..0871c5fb4d 100644 --- a/src/sync.h +++ b/src/sync.h @@ -196,7 +196,7 @@ private: int value; public: - CSemaphore(int init) : value(init) {} + explicit CSemaphore(int init) : value(init) {} void wait() { @@ -265,9 +265,9 @@ public: fHaveGrant = false; } - CSemaphoreGrant() : sem(NULL), fHaveGrant(false) {} + CSemaphoreGrant() : sem(nullptr), fHaveGrant(false) {} - CSemaphoreGrant(CSemaphore& sema, bool fTry = false) : sem(&sema), fHaveGrant(false) + explicit CSemaphoreGrant(CSemaphore& sema, bool fTry = false) : sem(&sema), fHaveGrant(false) { if (fTry) TryAcquire(); @@ -280,7 +280,7 @@ public: Release(); } - operator bool() + operator bool() const { return fHaveGrant; } diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 4a284517a1..ffbeeb7d91 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) std::atomic<bool> interruptDummy(false); connman->ClearBanned(); - ForceSetArg("-banscore", "111"); // because 11 is my favorite number + gArgs.ForceSetArg("-banscore", "111"); // because 11 is my favorite number CAddress addr1(ip(0xa0b0c001), NODE_NONE); CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, 1, CAddress(), "", true); dummyNode1.SetSendVersion(PROTOCOL_VERSION); @@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) Misbehaving(dummyNode1.GetId(), 1); SendMessages(&dummyNode1, *connman, interruptDummy); BOOST_CHECK(connman->IsBanned(addr1)); - ForceSetArg("-banscore", std::to_string(DEFAULT_BANSCORE_THRESHOLD)); + gArgs.ForceSetArg("-banscore", std::to_string(DEFAULT_BANSCORE_THRESHOLD)); } BOOST_AUTO_TEST_CASE(DoS_bantime) diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index bc6aef2c11..2ad22d34ad 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -15,9 +15,14 @@ class CAddrManTest : public CAddrMan uint64_t state; public: - CAddrManTest() + CAddrManTest(bool makeDeterministic = true) { state = 1; + + if (makeDeterministic) { + // Set addrman addr placement to be deterministic. + MakeDeterministic(); + } } //! Ensure that bucket placement is always the same for testing purposes. @@ -33,12 +38,12 @@ public: return (unsigned int)(state % nMax); } - CAddrInfo* Find(const CNetAddr& addr, int* pnId = NULL) + CAddrInfo* Find(const CNetAddr& addr, int* pnId = nullptr) { return CAddrMan::Find(addr, pnId); } - CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = NULL) + CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = nullptr) { return CAddrMan::Create(addr, addrSource, pnId); } @@ -79,9 +84,6 @@ BOOST_AUTO_TEST_CASE(addrman_simple) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - CNetAddr source = ResolveIP("252.2.2.2"); // Test: Does Addrman respond correctly when empty. @@ -131,9 +133,6 @@ BOOST_AUTO_TEST_CASE(addrman_ports) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - CNetAddr source = ResolveIP("252.2.2.2"); BOOST_CHECK_EQUAL(addrman.size(), 0); @@ -163,9 +162,6 @@ BOOST_AUTO_TEST_CASE(addrman_select) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - CNetAddr source = ResolveIP("252.2.2.2"); // Test: Select from new with 1 addr in new. @@ -225,9 +221,6 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - CNetAddr source = ResolveIP("252.2.2.2"); BOOST_CHECK_EQUAL(addrman.size(), 0); @@ -254,9 +247,6 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - CNetAddr source = ResolveIP("252.2.2.2"); BOOST_CHECK_EQUAL(addrman.size(), 0); @@ -284,9 +274,6 @@ BOOST_AUTO_TEST_CASE(addrman_find) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - BOOST_CHECK_EQUAL(addrman.size(), 0); CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE); @@ -320,9 +307,6 @@ BOOST_AUTO_TEST_CASE(addrman_create) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - BOOST_CHECK_EQUAL(addrman.size(), 0); CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE); @@ -343,9 +327,6 @@ BOOST_AUTO_TEST_CASE(addrman_delete) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - BOOST_CHECK_EQUAL(addrman.size(), 0); CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE); @@ -359,16 +340,13 @@ BOOST_AUTO_TEST_CASE(addrman_delete) addrman.Delete(nId); BOOST_CHECK_EQUAL(addrman.size(), 0); CAddrInfo* info2 = addrman.Find(addr1); - BOOST_CHECK(info2 == NULL); + BOOST_CHECK(info2 == nullptr); } BOOST_AUTO_TEST_CASE(addrman_getaddr) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - // Test: Sanity check, GetAddr should never return anything if addrman // is empty. BOOST_CHECK_EQUAL(addrman.size(), 0); @@ -430,9 +408,6 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - CAddress addr1 = CAddress(ResolveService("250.1.1.1", 8333), NODE_NONE); CAddress addr2 = CAddress(ResolveService("250.1.1.1", 9999), NODE_NONE); @@ -487,9 +462,6 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) { CAddrManTest addrman; - // Set addrman addr placement to be deterministic. - addrman.MakeDeterministic(); - CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE); CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE); diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index b33cdb9fe6..ee633249e9 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -78,7 +78,7 @@ class TestAddrTypeVisitor : public boost::static_visitor<bool> private: std::string exp_addrType; public: - TestAddrTypeVisitor(const std::string &_exp_addrType) : exp_addrType(_exp_addrType) { } + explicit TestAddrTypeVisitor(const std::string &_exp_addrType) : exp_addrType(_exp_addrType) { } bool operator()(const CKeyID &id) const { return (exp_addrType == "pubkey"); @@ -99,7 +99,7 @@ class TestPayloadVisitor : public boost::static_visitor<bool> private: std::vector<unsigned char> exp_payload; public: - TestPayloadVisitor(std::vector<unsigned char> &_exp_payload) : exp_payload(_exp_payload) { } + explicit TestPayloadVisitor(std::vector<unsigned char> &_exp_payload) : exp_payload(_exp_payload) { } bool operator()(const CKeyID &id) const { uint160 exp_key(exp_payload); diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 6bcd550d7b..c851ab2849 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -24,7 +24,7 @@ struct TestVector { std::string strHexMaster; std::vector<TestDerivation> vDerive; - TestVector(std::string strHexMasterIn) : strHexMaster(strHexMasterIn) {} + explicit TestVector(std::string strHexMasterIn) : strHexMaster(strHexMasterIn) {} TestVector& operator()(std::string pub, std::string prv, unsigned int nChild) { vDerive.push_back(TestDerivation()); diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index 10a40fea3c..f2d5b385d0 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -51,7 +51,7 @@ static CBlock BuildBlockTestCase() { return block; } -// Number of shared use_counts we expect for a tx we havent touched +// Number of shared use_counts we expect for a tx we haven't touched // == 2 (mempool + our copy from the GetSharedTx call) #define SHARED_TX_OFFSET 2 @@ -118,12 +118,12 @@ public: std::vector<uint64_t> shorttxids; std::vector<PrefilledTransaction> prefilledtxn; - TestHeaderAndShortIDs(const CBlockHeaderAndShortTxIDs& orig) { + explicit TestHeaderAndShortIDs(const CBlockHeaderAndShortTxIDs& orig) { CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << orig; stream >> *this; } - TestHeaderAndShortIDs(const CBlock& block) : + explicit TestHeaderAndShortIDs(const CBlock& block) : TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs(block, true)) {} uint64_t GetShortID(const uint256& txhash) const { diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index e24431528a..dc358bff95 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -74,7 +74,7 @@ public: class CCoinsViewCacheTest : public CCoinsViewCache { public: - CCoinsViewCacheTest(CCoinsView* _base) : CCoinsViewCache(_base) {} + explicit CCoinsViewCacheTest(CCoinsView* _base) : CCoinsViewCache(_base) {} void SelfTest() const { @@ -89,8 +89,8 @@ public: BOOST_CHECK_EQUAL(DynamicMemoryUsage(), ret); } - CCoinsMap& map() { return cacheCoins; } - size_t& usage() { return cachedCoinsUsage; } + CCoinsMap& map() const { return cacheCoins; } + size_t& usage() const { return cachedCoinsUsage; } }; } // namespace @@ -275,7 +275,7 @@ UtxoData::iterator FindRandomFrom(const std::set<COutPoint> &utxoSet) { // except the emphasis is on testing the functionality of UpdateCoins // random txs are created and UpdateCoins is used to update the cache stack // In particular it is tested that spending a duplicate coinbase tx -// has the expected effect (the other duplicate is overwitten at all cache levels) +// has the expected effect (the other duplicate is overwritten at all cache levels) BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) { bool spent_a_duplicate_coinbase = false; diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 2235bd0ae7..09442b7f9f 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -205,7 +205,7 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000feff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -["By-time locks, with argument just beyond txin.nSequence (but within numerical boundries)"], +["By-time locks, with argument just beyond txin.nSequence (but within numerical boundaries)"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194305 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 6ed6e7744e..251d5a7142 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -231,7 +231,7 @@ struct StringContentsSerializer { // This is a terrible idea std::string str; StringContentsSerializer() {} - StringContentsSerializer(const std::string& inp) : str(inp) {} + explicit StringContentsSerializer(const std::string& inp) : str(inp) {} StringContentsSerializer& operator+=(const std::string& s) { str += s; diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index c79675f5a6..18a7e59933 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -27,135 +27,135 @@ static void ResetArgs(const std::string& strArg) for (std::string& s : vecArg) vecChar.push_back(s.c_str()); - ParseParameters(vecChar.size(), &vecChar[0]); + gArgs.ParseParameters(vecChar.size(), &vecChar[0]); } BOOST_AUTO_TEST_CASE(boolarg) { ResetArgs("-foo"); - BOOST_CHECK(GetBoolArg("-foo", false)); - BOOST_CHECK(GetBoolArg("-foo", true)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); - BOOST_CHECK(!GetBoolArg("-fo", false)); - BOOST_CHECK(GetBoolArg("-fo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-fo", false)); + BOOST_CHECK(gArgs.GetBoolArg("-fo", true)); - BOOST_CHECK(!GetBoolArg("-fooo", false)); - BOOST_CHECK(GetBoolArg("-fooo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-fooo", false)); + BOOST_CHECK(gArgs.GetBoolArg("-fooo", true)); ResetArgs("-foo=0"); - BOOST_CHECK(!GetBoolArg("-foo", false)); - BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); ResetArgs("-foo=1"); - BOOST_CHECK(GetBoolArg("-foo", false)); - BOOST_CHECK(GetBoolArg("-foo", true)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); // New 0.6 feature: auto-map -nosomething to !-something: ResetArgs("-nofoo"); - BOOST_CHECK(!GetBoolArg("-foo", false)); - BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); ResetArgs("-nofoo=1"); - BOOST_CHECK(!GetBoolArg("-foo", false)); - BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); ResetArgs("-foo -nofoo"); // -nofoo should win - BOOST_CHECK(!GetBoolArg("-foo", false)); - BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); ResetArgs("-foo=1 -nofoo=1"); // -nofoo should win - BOOST_CHECK(!GetBoolArg("-foo", false)); - BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); ResetArgs("-foo=0 -nofoo=0"); // -nofoo=0 should win - BOOST_CHECK(GetBoolArg("-foo", false)); - BOOST_CHECK(GetBoolArg("-foo", true)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); // New 0.6 feature: treat -- same as -: ResetArgs("--foo=1"); - BOOST_CHECK(GetBoolArg("-foo", false)); - BOOST_CHECK(GetBoolArg("-foo", true)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); ResetArgs("--nofoo=1"); - BOOST_CHECK(!GetBoolArg("-foo", false)); - BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); } BOOST_AUTO_TEST_CASE(stringarg) { ResetArgs(""); - BOOST_CHECK_EQUAL(GetArg("-foo", ""), ""); - BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), "eleven"); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "eleven"); ResetArgs("-foo -bar"); - BOOST_CHECK_EQUAL(GetArg("-foo", ""), ""); - BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), ""); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), ""); ResetArgs("-foo="); - BOOST_CHECK_EQUAL(GetArg("-foo", ""), ""); - BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), ""); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), ""); ResetArgs("-foo=11"); - BOOST_CHECK_EQUAL(GetArg("-foo", ""), "11"); - BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), "11"); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "11"); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "11"); ResetArgs("-foo=eleven"); - BOOST_CHECK_EQUAL(GetArg("-foo", ""), "eleven"); - BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), "eleven"); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "eleven"); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "eleven"); } BOOST_AUTO_TEST_CASE(intarg) { ResetArgs(""); - BOOST_CHECK_EQUAL(GetArg("-foo", 11), 11); - BOOST_CHECK_EQUAL(GetArg("-foo", 0), 0); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 11), 11); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 0), 0); ResetArgs("-foo -bar"); - BOOST_CHECK_EQUAL(GetArg("-foo", 11), 0); - BOOST_CHECK_EQUAL(GetArg("-bar", 11), 0); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 11), 0); + BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 11), 0); ResetArgs("-foo=11 -bar=12"); - BOOST_CHECK_EQUAL(GetArg("-foo", 0), 11); - BOOST_CHECK_EQUAL(GetArg("-bar", 11), 12); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 0), 11); + BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 11), 12); ResetArgs("-foo=NaN -bar=NotANumber"); - BOOST_CHECK_EQUAL(GetArg("-foo", 1), 0); - BOOST_CHECK_EQUAL(GetArg("-bar", 11), 0); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 1), 0); + BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 11), 0); } BOOST_AUTO_TEST_CASE(doubledash) { ResetArgs("--foo"); - BOOST_CHECK_EQUAL(GetBoolArg("-foo", false), true); + BOOST_CHECK_EQUAL(gArgs.GetBoolArg("-foo", false), true); ResetArgs("--foo=verbose --bar=1"); - BOOST_CHECK_EQUAL(GetArg("-foo", ""), "verbose"); - BOOST_CHECK_EQUAL(GetArg("-bar", 0), 1); + BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "verbose"); + BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 0), 1); } BOOST_AUTO_TEST_CASE(boolargno) { ResetArgs("-nofoo"); - BOOST_CHECK(!GetBoolArg("-foo", true)); - BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); ResetArgs("-nofoo=1"); - BOOST_CHECK(!GetBoolArg("-foo", true)); - BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); ResetArgs("-nofoo=0"); - BOOST_CHECK(GetBoolArg("-foo", true)); - BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); ResetArgs("-foo --nofoo"); // --nofoo should win - BOOST_CHECK(!GetBoolArg("-foo", true)); - BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); ResetArgs("-nofoo -foo"); // foo always wins: - BOOST_CHECK(GetBoolArg("-foo", true)); - BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index eaff2ac70d..9fa9a8509c 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->nNonce = blockinfo[i].nonce; std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock); - BOOST_CHECK(ProcessNewBlock(chainparams, shared_pblock, true, NULL)); + BOOST_CHECK(ProcessNewBlock(chainparams, shared_pblock, true, nullptr)); pblock->hashPrevBlock = pblock->GetHash(); } diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index c686f679c2..5e89ef60d2 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -79,20 +79,20 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys.assign(1,key[0]); keys.push_back(key[1]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK(VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err)); + BOOST_CHECK(VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); for (int i = 0; i < 4; i++) { keys.assign(1,key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 1: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 1: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); keys.assign(1,key[1]); keys.push_back(key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 2: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 2: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -103,18 +103,18 @@ BOOST_AUTO_TEST_CASE(multisig_verify) s = sign_multisig(a_or_b, keys, txTo[1], 0); if (i == 0 || i == 1) { - BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } s.clear(); s << OP_0 << OP_1; - BOOST_CHECK(!VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err)); + BOOST_CHECK(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); @@ -126,12 +126,12 @@ BOOST_AUTO_TEST_CASE(multisig_verify) s = sign_multisig(escrow, keys, txTo[2], 0); if (i < j && i < 3 && j < 3) { - BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, NULL, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 1: %d %d", i, j)); + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 1: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, NULL, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 2: %d %d", i, j)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 2: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 095d86834c..31b05d868b 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(cnode_listen_port) BOOST_CHECK(port == Params().GetDefaultPort()); // test set port unsigned short altPort = 12345; - SoftSetArg("-port", std::to_string(altPort)); + gArgs.SoftSetArg("-port", std::to_string(altPort)); port = GetListenPort(); BOOST_CHECK(port == altPort); } diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index b9fabd02e4..b13f2625aa 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); std::vector<CBlockIndex> blocks(10000); for (int i = 0; i < 10000; i++) { - blocks[i].pprev = i ? &blocks[i - 1] : NULL; + blocks[i].pprev = i ? &blocks[i - 1] : nullptr; blocks[i].nHeight = i; blocks[i].nTime = 1269211443 + i * chainParams->GetConsensus().nPowTargetSpacing; blocks[i].nBits = 0x207fffff; /* target 0x7fffff000... */ diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index 345c4a2148..841282873f 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -152,11 +152,11 @@ public: pre_vector.assign(n, value); } - Size size() { + Size size() const { return real_vector.size(); } - Size capacity() { + Size capacity() const { return pre_vector.capacity(); } diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp index 0f40874f55..0d541ec7d4 100644 --- a/src/test/raii_event_tests.cpp +++ b/src/test/raii_event_tests.cpp @@ -42,7 +42,7 @@ BOOST_AUTO_TEST_CASE(raii_event_creation) { event_set_mem_functions(tag_malloc, realloc, tag_free); - void* base_ptr = NULL; + void* base_ptr = nullptr; { auto base = obtain_event_base(); base_ptr = (void*)base.get(); @@ -50,10 +50,10 @@ BOOST_AUTO_TEST_CASE(raii_event_creation) } BOOST_CHECK(tags[base_ptr] == 0); - void* event_ptr = NULL; + void* event_ptr = nullptr; { auto base = obtain_event_base(); - auto event = obtain_event(base.get(), -1, 0, NULL, NULL); + auto event = obtain_event(base.get(), -1, 0, nullptr, nullptr); base_ptr = (void*)base.get(); event_ptr = (void*)event.get(); @@ -71,11 +71,11 @@ BOOST_AUTO_TEST_CASE(raii_event_order) { event_set_mem_functions(tag_malloc, realloc, tag_free); - void* base_ptr = NULL; - void* event_ptr = NULL; + void* base_ptr = nullptr; + void* event_ptr = nullptr; { auto base = obtain_event_base(); - auto event = obtain_event(base.get(), -1, 0, NULL, NULL); + auto event = obtain_event(base.get(), -1, 0, nullptr, nullptr); base_ptr = (void*)base.get(); event_ptr = (void*)event.get(); diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 134bd7c609..c6643be7a7 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -6,6 +6,7 @@ #include "rpc/client.h" #include "base58.h" +#include "core_io.h" #include "netbase.h" #include "test/test_bitcoin.h" diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 0789b2e80c..efd0f77d9f 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -42,7 +42,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri txTo.vin[0].scriptSig = scriptSig; txTo.vout[0].nValue = 1; - return VerifyScript(scriptSig, scriptPubKey, NULL, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue), &err); + return VerifyScript(scriptSig, scriptPubKey, nullptr, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue), &err); } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index a18471588a..17374edcc4 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -172,10 +172,10 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript int libconsensus_flags = flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL; if (libconsensus_flags == flags) { if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expect, message); } else { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect, message); - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect,message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expect, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expect,message); } } #endif @@ -450,7 +450,7 @@ public: return array; } - std::string GetComment() + std::string GetComment() const { return comment; } @@ -1064,18 +1064,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, NULL, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, NULL, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, NULL, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, NULL, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -1097,54 +1097,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) std::vector<CKey> keys; keys.push_back(key1); keys.push_back(key2); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key3); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key3); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); // Must have signatures CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); } @@ -1265,7 +1265,7 @@ BOOST_AUTO_TEST_CASE(script_standard_push) CScript script; script << i; BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Number " << i << " is not pure push."); - BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, NULL, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Number " << i << " push is not minimal data."); + BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, nullptr, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Number " << i << " push is not minimal data."); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -1274,7 +1274,7 @@ BOOST_AUTO_TEST_CASE(script_standard_push) CScript script; script << data; BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Length " << i << " is not pure push."); - BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, NULL, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Length " << i << " push is not minimal data."); + BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, nullptr, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Length " << i << " push is not minimal data."); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } } diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index 77c321cdf6..e3654e67ad 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -20,7 +20,7 @@ BOOST_AUTO_TEST_CASE(skiplist_test) for (int i=0; i<SKIPLIST_LENGTH; i++) { vIndex[i].nHeight = i; - vIndex[i].pprev = (i == 0) ? NULL : &vIndex[i - 1]; + vIndex[i].pprev = (i == 0) ? nullptr : &vIndex[i - 1]; vIndex[i].BuildSkip(); } @@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE(skiplist_test) BOOST_CHECK(vIndex[i].pskip == &vIndex[vIndex[i].pskip->nHeight]); BOOST_CHECK(vIndex[i].pskip->nHeight < i); } else { - BOOST_CHECK(vIndex[i].pskip == NULL); + BOOST_CHECK(vIndex[i].pskip == nullptr); } } @@ -51,11 +51,11 @@ BOOST_AUTO_TEST_CASE(getlocator_test) for (unsigned int i=0; i<vBlocksMain.size(); i++) { vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height, so we can quickly check the distances. vBlocksMain[i].nHeight = i; - vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : NULL; + vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : nullptr; vBlocksMain[i].phashBlock = &vHashMain[i]; vBlocksMain[i].BuildSkip(); BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksMain[i].GetBlockHash()).GetLow64(), vBlocksMain[i].nHeight); - BOOST_CHECK(vBlocksMain[i].pprev == NULL || vBlocksMain[i].nHeight == vBlocksMain[i].pprev->nHeight + 1); + BOOST_CHECK(vBlocksMain[i].pprev == nullptr || vBlocksMain[i].nHeight == vBlocksMain[i].pprev->nHeight + 1); } // Build a branch that splits off at block 49999, 50000 blocks long. @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(getlocator_test) vBlocksSide[i].phashBlock = &vHashSide[i]; vBlocksSide[i].BuildSkip(); BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksSide[i].GetBlockHash()).GetLow64(), vBlocksSide[i].nHeight); - BOOST_CHECK(vBlocksSide[i].pprev == NULL || vBlocksSide[i].nHeight == vBlocksSide[i].pprev->nHeight + 1); + BOOST_CHECK(vBlocksSide[i].pprev == nullptr || vBlocksSide[i].nHeight == vBlocksSide[i].pprev->nHeight + 1); } // Build a CChain for the main branch. @@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(findearliestatleast_test) for (unsigned int i=0; i<vBlocksMain.size(); i++) { vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height vBlocksMain[i].nHeight = i; - vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : NULL; + vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : nullptr; vBlocksMain[i].phashBlock = &vHashMain[i]; vBlocksMain[i].BuildSkip(); if (i < 10) { @@ -138,7 +138,7 @@ BOOST_AUTO_TEST_CASE(findearliestatleast_test) int64_t test_time = vBlocksMain[r].nTime; CBlockIndex *ret = chain.FindEarliestAtLeast(test_time); BOOST_CHECK(ret->nTimeMax >= test_time); - BOOST_CHECK((ret->pprev==NULL) || ret->pprev->nTimeMax < test_time); + BOOST_CHECK((ret->pprev==nullptr) || ret->pprev->nTimeMax < test_time); BOOST_CHECK(vBlocksMain[r].GetAncestor(ret->nHeight) == ret); } } diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index e2e0a9668f..94ec7c03f5 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -63,7 +63,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha ClearDatadirCache(); pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(InsecureRandRange(100000))); fs::create_directories(pathTemp); - ForceSetArg("-datadir", pathTemp.string()); + gArgs.ForceSetArg("-datadir", pathTemp.string()); // Note that because we don't bother running a scheduler thread here, // callbacks via CValidationInterface are unreliable, but that's OK, @@ -140,7 +140,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce; std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block); - ProcessNewBlock(chainparams, shared_pblock, true, NULL); + ProcessNewBlock(chainparams, shared_pblock, true, nullptr); CBlock result = block; return result; diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index dd3b13c8c8..2ddac2f076 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -41,7 +41,7 @@ static inline bool InsecureRandBool() { return insecure_rand_ctx.randbool(); } struct BasicTestingSetup { ECCVerifyHandle globalVerifyHandle; - BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); + explicit BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~BasicTestingSetup(); }; @@ -56,7 +56,7 @@ struct TestingSetup: public BasicTestingSetup { CConnman* connman; CScheduler scheduler; - TestingSetup(const std::string& chainName = CBaseChainParams::MAIN); + explicit TestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~TestingSetup(); }; diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index f609cb1af4..2d25cb96c8 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -29,7 +29,7 @@ ToMemPool(CMutableTransaction& tx) LOCK(cs_main); CValidationState state; - return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), false, NULL, NULL, true, 0); + return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), false, nullptr, nullptr, true, 0); } BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 5e9dfb730b..5679086969 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -328,7 +328,7 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32) { int32_t n; // Valid values - BOOST_CHECK(ParseInt32("1234", NULL)); + BOOST_CHECK(ParseInt32("1234", nullptr)); BOOST_CHECK(ParseInt32("0", &n) && n == 0); BOOST_CHECK(ParseInt32("1234", &n) && n == 1234); BOOST_CHECK(ParseInt32("01234", &n) && n == 1234); // no octal @@ -347,17 +347,17 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32) std::string teststr(test_bytes, sizeof(test_bytes)); BOOST_CHECK(!ParseInt32(teststr, &n)); // no embedded NULs // Overflow and underflow - BOOST_CHECK(!ParseInt32("-2147483649", NULL)); - BOOST_CHECK(!ParseInt32("2147483648", NULL)); - BOOST_CHECK(!ParseInt32("-32482348723847471234", NULL)); - BOOST_CHECK(!ParseInt32("32482348723847471234", NULL)); + BOOST_CHECK(!ParseInt32("-2147483649", nullptr)); + BOOST_CHECK(!ParseInt32("2147483648", nullptr)); + BOOST_CHECK(!ParseInt32("-32482348723847471234", nullptr)); + BOOST_CHECK(!ParseInt32("32482348723847471234", nullptr)); } BOOST_AUTO_TEST_CASE(test_ParseInt64) { int64_t n; // Valid values - BOOST_CHECK(ParseInt64("1234", NULL)); + BOOST_CHECK(ParseInt64("1234", nullptr)); BOOST_CHECK(ParseInt64("0", &n) && n == 0LL); BOOST_CHECK(ParseInt64("1234", &n) && n == 1234LL); BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal @@ -377,17 +377,17 @@ BOOST_AUTO_TEST_CASE(test_ParseInt64) std::string teststr(test_bytes, sizeof(test_bytes)); BOOST_CHECK(!ParseInt64(teststr, &n)); // no embedded NULs // Overflow and underflow - BOOST_CHECK(!ParseInt64("-9223372036854775809", NULL)); - BOOST_CHECK(!ParseInt64("9223372036854775808", NULL)); - BOOST_CHECK(!ParseInt64("-32482348723847471234", NULL)); - BOOST_CHECK(!ParseInt64("32482348723847471234", NULL)); + BOOST_CHECK(!ParseInt64("-9223372036854775809", nullptr)); + BOOST_CHECK(!ParseInt64("9223372036854775808", nullptr)); + BOOST_CHECK(!ParseInt64("-32482348723847471234", nullptr)); + BOOST_CHECK(!ParseInt64("32482348723847471234", nullptr)); } BOOST_AUTO_TEST_CASE(test_ParseUInt32) { uint32_t n; // Valid values - BOOST_CHECK(ParseUInt32("1234", NULL)); + BOOST_CHECK(ParseUInt32("1234", nullptr)); BOOST_CHECK(ParseUInt32("0", &n) && n == 0); BOOST_CHECK(ParseUInt32("1234", &n) && n == 1234); BOOST_CHECK(ParseUInt32("01234", &n) && n == 1234); // no octal @@ -410,15 +410,15 @@ BOOST_AUTO_TEST_CASE(test_ParseUInt32) BOOST_CHECK(!ParseUInt32("-2147483648", &n)); BOOST_CHECK(!ParseUInt32("4294967296", &n)); BOOST_CHECK(!ParseUInt32("-1234", &n)); - BOOST_CHECK(!ParseUInt32("-32482348723847471234", NULL)); - BOOST_CHECK(!ParseUInt32("32482348723847471234", NULL)); + BOOST_CHECK(!ParseUInt32("-32482348723847471234", nullptr)); + BOOST_CHECK(!ParseUInt32("32482348723847471234", nullptr)); } BOOST_AUTO_TEST_CASE(test_ParseUInt64) { uint64_t n; // Valid values - BOOST_CHECK(ParseUInt64("1234", NULL)); + BOOST_CHECK(ParseUInt64("1234", nullptr)); BOOST_CHECK(ParseUInt64("0", &n) && n == 0LL); BOOST_CHECK(ParseUInt64("1234", &n) && n == 1234LL); BOOST_CHECK(ParseUInt64("01234", &n) && n == 1234LL); // no octal @@ -438,9 +438,9 @@ BOOST_AUTO_TEST_CASE(test_ParseUInt64) std::string teststr(test_bytes, sizeof(test_bytes)); BOOST_CHECK(!ParseUInt64(teststr, &n)); // no embedded NULs // Overflow and underflow - BOOST_CHECK(!ParseUInt64("-9223372036854775809", NULL)); - BOOST_CHECK(!ParseUInt64("18446744073709551616", NULL)); - BOOST_CHECK(!ParseUInt64("-32482348723847471234", NULL)); + BOOST_CHECK(!ParseUInt64("-9223372036854775809", nullptr)); + BOOST_CHECK(!ParseUInt64("18446744073709551616", nullptr)); + BOOST_CHECK(!ParseUInt64("-32482348723847471234", nullptr)); BOOST_CHECK(!ParseUInt64("-2147483648", &n)); BOOST_CHECK(!ParseUInt64("-9223372036854775808", &n)); BOOST_CHECK(!ParseUInt64("-1234", &n)); @@ -450,7 +450,7 @@ BOOST_AUTO_TEST_CASE(test_ParseDouble) { double n; // Valid values - BOOST_CHECK(ParseDouble("1234", NULL)); + BOOST_CHECK(ParseDouble("1234", nullptr)); BOOST_CHECK(ParseDouble("0", &n) && n == 0.0); BOOST_CHECK(ParseDouble("1234", &n) && n == 1234.0); BOOST_CHECK(ParseDouble("01234", &n) && n == 1234.0); // no octal @@ -470,8 +470,8 @@ BOOST_AUTO_TEST_CASE(test_ParseDouble) std::string teststr(test_bytes, sizeof(test_bytes)); BOOST_CHECK(!ParseDouble(teststr, &n)); // no embedded NULs // Overflow and underflow - BOOST_CHECK(!ParseDouble("-1e10000", NULL)); - BOOST_CHECK(!ParseDouble("1e10000", NULL)); + BOOST_CHECK(!ParseDouble("-1e10000", nullptr)); + BOOST_CHECK(!ParseDouble("1e10000", nullptr)); } BOOST_AUTO_TEST_CASE(test_FormatParagraph) diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 722f6ae059..f433aad889 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -69,7 +69,7 @@ public: while (vpblock.size() < height) { CBlockIndex* pindex = new CBlockIndex(); pindex->nHeight = vpblock.size(); - pindex->pprev = vpblock.size() > 0 ? vpblock.back() : NULL; + pindex->pprev = vpblock.size() > 0 ? vpblock.back() : nullptr; pindex->nTime = nTime; pindex->nVersion = nVersion; pindex->BuildSkip(); @@ -81,7 +81,7 @@ public: VersionBitsTester& TestStateSinceHeight(int height) { for (int i = 0; i < CHECKERS; i++) { if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(vpblock.empty() ? NULL : vpblock.back()) == height, strprintf("Test %i for StateSinceHeight", num)); + BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()) == height, strprintf("Test %i for StateSinceHeight", num)); } } num++; @@ -91,7 +91,7 @@ public: VersionBitsTester& TestDefined() { for (int i = 0; i < CHECKERS; i++) { if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_DEFINED, strprintf("Test %i for DEFINED", num)); + BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_DEFINED, strprintf("Test %i for DEFINED", num)); } } num++; @@ -101,7 +101,7 @@ public: VersionBitsTester& TestStarted() { for (int i = 0; i < CHECKERS; i++) { if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_STARTED, strprintf("Test %i for STARTED", num)); + BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_STARTED, strprintf("Test %i for STARTED", num)); } } num++; @@ -111,7 +111,7 @@ public: VersionBitsTester& TestLockedIn() { for (int i = 0; i < CHECKERS; i++) { if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_LOCKED_IN, strprintf("Test %i for LOCKED_IN", num)); + BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_LOCKED_IN, strprintf("Test %i for LOCKED_IN", num)); } } num++; @@ -121,7 +121,7 @@ public: VersionBitsTester& TestActive() { for (int i = 0; i < CHECKERS; i++) { if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE", num)); + BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE", num)); } } num++; @@ -131,14 +131,14 @@ public: VersionBitsTester& TestFailed() { for (int i = 0; i < CHECKERS; i++) { if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_FAILED, strprintf("Test %i for FAILED", num)); + BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_FAILED, strprintf("Test %i for FAILED", num)); } } num++; return *this; } - CBlockIndex * Tip() { return vpblock.size() ? vpblock.back() : NULL; } + CBlockIndex * Tip() { return vpblock.size() ? vpblock.back() : nullptr; } }; BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup) @@ -255,7 +255,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion) // Before MedianTimePast of the chain has crossed nStartTime, the bit // should not be set. - CBlockIndex *lastBlock = NULL; + CBlockIndex *lastBlock = nullptr; lastBlock = firstChain.Mine(2016, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0); diff --git a/src/timedata.cpp b/src/timedata.cpp index 099ed7f042..5113bb60db 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -81,7 +81,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) int64_t nMedian = vTimeOffsets.median(); std::vector<int64_t> vSorted = vTimeOffsets.sorted(); // Only let other nodes change our time by so much - if (abs64(nMedian) <= std::max<int64_t>(0, GetArg("-maxtimeadjustment", DEFAULT_MAX_TIME_ADJUSTMENT))) + if (abs64(nMedian) <= std::max<int64_t>(0, gArgs.GetArg("-maxtimeadjustment", DEFAULT_MAX_TIME_ADJUSTMENT))) { nTimeOffset = nMedian; } diff --git a/src/tinyformat.h b/src/tinyformat.h index 5022d46809..2e453e56bb 100644 --- a/src/tinyformat.h +++ b/src/tinyformat.h @@ -167,7 +167,7 @@ namespace tinyformat { class format_error: public std::runtime_error { public: - format_error(const std::string &what): std::runtime_error(what) { + explicit format_error(const std::string &what): std::runtime_error(what) { } }; @@ -498,7 +498,7 @@ class FormatArg FormatArg() {} template<typename T> - FormatArg(const T& value) + explicit FormatArg(const T& value) : m_value(static_cast<const void*>(&value)), m_formatImpl(&formatImpl<T>), m_toIntImpl(&toIntImpl<T>) @@ -867,7 +867,7 @@ class FormatListN : public FormatList public: #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES template<typename... Args> - FormatListN(const Args&... args) + explicit FormatListN(const Args&... args) : FormatList(&m_formatterStore[0], N), m_formatterStore { FormatArg(args)... } { static_assert(sizeof...(args) == N, "Number of args must be N"); } @@ -876,7 +876,7 @@ class FormatListN : public FormatList # define TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR(n) \ \ template<TINYFORMAT_ARGTYPES(n)> \ - FormatListN(TINYFORMAT_VARARGS(n)) \ + explicit FormatListN(TINYFORMAT_VARARGS(n)) \ : FormatList(&m_formatterStore[0], n) \ { assert(n == N); init(0, TINYFORMAT_PASSARGS(n)); } \ \ diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index ac13f73e70..1cea197666 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -76,7 +76,7 @@ public: /** Create a new TorControlConnection. */ - TorControlConnection(struct event_base *base); + explicit TorControlConnection(struct event_base *base); ~TorControlConnection(); /** @@ -121,7 +121,7 @@ private: }; TorControlConnection::TorControlConnection(struct event_base *_base): - base(_base), b_conn(0) + base(_base), b_conn(nullptr) { } @@ -138,8 +138,8 @@ void TorControlConnection::readcb(struct bufferevent *bev, void *ctx) size_t n_read_out = 0; char *line; assert(input); - // If there is not a whole line to read, evbuffer_readln returns NULL - while((line = evbuffer_readln(input, &n_read_out, EVBUFFER_EOL_CRLF)) != NULL) + // If there is not a whole line to read, evbuffer_readln returns nullptr + while((line = evbuffer_readln(input, &n_read_out, EVBUFFER_EOL_CRLF)) != nullptr) { std::string s(line, n_read_out); free(line); @@ -210,7 +210,7 @@ bool TorControlConnection::Connect(const std::string &target, const ConnectionCB b_conn = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); if (!b_conn) return false; - bufferevent_setcb(b_conn, TorControlConnection::readcb, NULL, TorControlConnection::eventcb, this); + bufferevent_setcb(b_conn, TorControlConnection::readcb, nullptr, TorControlConnection::eventcb, this); bufferevent_enable(b_conn, EV_READ|EV_WRITE); this->connected = _connected; this->disconnected = _disconnected; @@ -227,7 +227,7 @@ bool TorControlConnection::Disconnect() { if (b_conn) bufferevent_free(b_conn); - b_conn = 0; + b_conn = nullptr; return true; } @@ -333,7 +333,7 @@ static std::map<std::string,std::string> ParseTorReplyMapping(const std::string if (j == 3 && value[i] > '3') { j--; } - escaped_value.push_back(strtol(value.substr(i, j).c_str(), NULL, 8)); + escaped_value.push_back(strtol(value.substr(i, j).c_str(), nullptr, 8)); // Account for automatic incrementing at loop end i += j - 1; } else { @@ -367,7 +367,7 @@ static std::map<std::string,std::string> ParseTorReplyMapping(const std::string static std::pair<bool,std::string> ReadBinaryFile(const fs::path &filename, size_t maxsize=std::numeric_limits<size_t>::max()) { FILE *f = fsbridge::fopen(filename, "rb"); - if (f == NULL) + if (f == nullptr) return std::make_pair(false,""); std::string retval; char buffer[128]; @@ -393,7 +393,7 @@ static std::pair<bool,std::string> ReadBinaryFile(const fs::path &filename, size static bool WriteBinaryFile(const fs::path &filename, const std::string &data) { FILE *f = fsbridge::fopen(filename, "wb"); - if (f == NULL) + if (f == nullptr) return false; if (fwrite(data.data(), 1, data.size(), f) != data.size()) { fclose(f); @@ -476,7 +476,7 @@ TorController::~TorController() { if (reconnect_ev) { event_free(reconnect_ev); - reconnect_ev = 0; + reconnect_ev = nullptr; } if (service.IsValid()) { RemoveLocal(service); @@ -525,7 +525,7 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply& // Now that we know Tor is running setup the proxy for onion addresses // if -onion isn't set to something else. - if (GetArg("-onion", "") == "") { + if (gArgs.GetArg("-onion", "") == "") { CService resolved(LookupNumeric("127.0.0.1", 9050)); proxyType addrOnion = proxyType(resolved, true); SetProxy(NET_TOR, addrOnion); @@ -642,7 +642,7 @@ void TorController::protocolinfo_cb(TorControlConnection& _conn, const TorContro * cookie: hex-encoded ~/.tor/control_auth_cookie * password: "password" */ - std::string torpassword = GetArg("-torpassword", ""); + std::string torpassword = gArgs.GetArg("-torpassword", ""); if (!torpassword.empty()) { if (methods.count("HASHEDPASSWORD")) { LogPrint(BCLog::TOR, "tor: Using HASHEDPASSWORD authentication\n"); @@ -735,7 +735,7 @@ static boost::thread torControlThread; static void TorControlThread() { - TorController ctrl(gBase, GetArg("-torcontrol", DEFAULT_TOR_CONTROL)); + TorController ctrl(gBase, gArgs.GetArg("-torcontrol", DEFAULT_TOR_CONTROL)); event_base_dispatch(gBase); } @@ -770,7 +770,7 @@ void StopTorControl() if (gBase) { torControlThread.join(); event_base_free(gBase); - gBase = 0; + gBase = nullptr; } } diff --git a/src/txdb.cpp b/src/txdb.cpp index fd730c368a..797ae5713f 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -35,7 +35,7 @@ namespace { struct CoinEntry { COutPoint* outpoint; char key; - CoinEntry(const COutPoint* ptr) : outpoint(const_cast<COutPoint*>(ptr)), key(DB_COIN) {} + explicit CoinEntry(const COutPoint* ptr) : outpoint(const_cast<COutPoint*>(ptr)), key(DB_COIN) {} template<typename Stream> void Serialize(Stream &s) const { @@ -85,8 +85,8 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { CDBBatch batch(db); size_t count = 0; size_t changed = 0; - size_t batch_size = (size_t)GetArg("-dbbatchsize", nDefaultDbBatchSize); - int crash_simulate = GetArg("-dbcrashratio", 0); + size_t batch_size = (size_t)gArgs.GetArg("-dbbatchsize", nDefaultDbBatchSize); + int crash_simulate = gArgs.GetArg("-dbcrashratio", 0); assert(!hashBlock.IsNull()); uint256 old_tip = GetBestBlock(); @@ -422,5 +422,5 @@ bool CCoinsViewDB::Upgrade() { db.CompactRange({DB_COINS, uint256()}, key); uiInterface.SetProgressBreakAction(std::function<void(void)>()); LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE"); - return true; + return !ShutdownRequested(); } diff --git a/src/txdb.h b/src/txdb.h index adcbc73380..d1cd5a4250 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -64,12 +64,12 @@ struct CDiskTxPos : public CDiskBlockPos }; /** CCoinsView backed by the coin database (chainstate/) */ -class CCoinsViewDB : public CCoinsView +class CCoinsViewDB final : public CCoinsView { protected: CDBWrapper db; public: - CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); + explicit CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); bool GetCoin(const COutPoint &outpoint, Coin &coin) const override; bool HaveCoin(const COutPoint &outpoint) const override; @@ -109,7 +109,7 @@ private: class CBlockTreeDB : public CDBWrapper { public: - CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); + explicit CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); private: CBlockTreeDB(const CBlockTreeDB&); void operator=(const CBlockTreeDB&); diff --git a/src/txmempool.h b/src/txmempool.h index d272114a7c..5b0db5266e 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -45,7 +45,7 @@ struct LockPoints // values are still valid even after a reorg. CBlockIndex* maxInputBlock; - LockPoints() : height(0), time(0), maxInputBlock(NULL) { } + LockPoints() : height(0), time(0), maxInputBlock(nullptr) { } }; class CTxMemPool; @@ -167,7 +167,7 @@ struct update_ancestor_state struct update_fee_delta { - update_fee_delta(int64_t _feeDelta) : feeDelta(_feeDelta) { } + explicit update_fee_delta(int64_t _feeDelta) : feeDelta(_feeDelta) { } void operator() (CTxMemPoolEntry &e) { e.UpdateFeeDelta(feeDelta); } @@ -177,7 +177,7 @@ private: struct update_lock_points { - update_lock_points(const LockPoints& _lp) : lp(_lp) { } + explicit update_lock_points(const LockPoints& _lp) : lp(_lp) { } void operator() (CTxMemPoolEntry &e) { e.UpdateLockPoints(lp); } @@ -501,7 +501,7 @@ public: /** Create a new CTxMemPool. */ - CTxMemPool(CBlockPolicyEstimator* estimator = nullptr); + explicit CTxMemPool(CBlockPolicyEstimator* estimator = nullptr); /** * If sanity-checking is turned on, check makes sure the pool is @@ -592,7 +592,7 @@ public: * pvNoSpendsRemaining, if set, will be populated with the list of outpoints * which are not in mempool which no longer have any spends in this mempool. */ - void TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining=NULL); + void TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining=nullptr); /** Expire all transaction (and their dependencies) in the mempool older than time. Return the number of removed transactions. */ int Expire(int64_t time); @@ -606,7 +606,7 @@ public: return mapTx.size(); } - uint64_t GetTotalTxSize() + uint64_t GetTotalTxSize() const { LOCK(cs); return totalTxSize; diff --git a/src/uint256.h b/src/uint256.h index a92ce07f11..3ed694d723 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -111,7 +111,7 @@ public: class uint160 : public base_blob<160> { public: uint160() {} - uint160(const base_blob<160>& b) : base_blob<160>(b) {} + explicit uint160(const base_blob<160>& b) : base_blob<160>(b) {} explicit uint160(const std::vector<unsigned char>& vch) : base_blob<160>(vch) {} }; @@ -123,7 +123,7 @@ public: class uint256 : public base_blob<256> { public: uint256() {} - uint256(const base_blob<256>& b) : base_blob<256>(b) {} + explicit uint256(const base_blob<256>& b) : base_blob<256>(b) {} explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {} /** A cheap hash function that just returns 64 bits from the result, it can be diff --git a/src/undo.h b/src/undo.h index 0f9d041bbd..a720de4ac5 100644 --- a/src/undo.h +++ b/src/undo.h @@ -33,7 +33,7 @@ public: ::Serialize(s, CTxOutCompressor(REF(txout->out))); } - TxInUndoSerializer(const Coin* coin) : txout(coin) {} + explicit TxInUndoSerializer(const Coin* coin) : txout(coin) {} }; class TxInUndoDeserializer @@ -57,7 +57,7 @@ public: ::Unserialize(s, REF(CTxOutCompressor(REF(txout->out)))); } - TxInUndoDeserializer(Coin* coin) : txout(coin) {} + explicit TxInUndoDeserializer(Coin* coin) : txout(coin) {} }; static const size_t MIN_TRANSACTION_INPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxIn(), SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/univalue/lib/univalue_utffilter.h b/src/univalue/lib/univalue_utffilter.h index 0e330dce9c..2fb6a492d1 100644 --- a/src/univalue/lib/univalue_utffilter.h +++ b/src/univalue/lib/univalue_utffilter.h @@ -13,7 +13,7 @@ class JSONUTF8StringFilter { public: - JSONUTF8StringFilter(std::string &s): + explicit JSONUTF8StringFilter(std::string &s): str(s), is_valid(true), codepoint(0), state(0), surpair(0) { } diff --git a/src/util.cpp b/src/util.cpp index b76c173f90..4659ff73c6 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -144,7 +144,7 @@ public: // Securely erase the memory used by the PRNG RAND_cleanup(); // Shutdown OpenSSL library multithreading support - CRYPTO_set_locking_callback(NULL); + CRYPTO_set_locking_callback(nullptr); // Clear the set of locks now to maintain symmetry with the constructor. ppmutexOpenSSL.reset(); } @@ -173,8 +173,8 @@ static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT; * the OS/libc. When the shutdown sequence is fully audited and * tested, explicit destruction of these objects can be implemented. */ -static FILE* fileout = NULL; -static boost::mutex* mutexDebugLog = NULL; +static FILE* fileout = nullptr; +static boost::mutex* mutexDebugLog = nullptr; static std::list<std::string>* vMsgsBeforeOpenLog; static int FileWriteStr(const std::string &str, FILE *fp) @@ -184,7 +184,7 @@ static int FileWriteStr(const std::string &str, FILE *fp) static void DebugPrintInit() { - assert(mutexDebugLog == NULL); + assert(mutexDebugLog == nullptr); mutexDebugLog = new boost::mutex(); vMsgsBeforeOpenLog = new std::list<std::string>; } @@ -194,12 +194,12 @@ void OpenDebugLog() boost::call_once(&DebugPrintInit, debugPrintInitFlag); boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); - assert(fileout == NULL); + assert(fileout == nullptr); assert(vMsgsBeforeOpenLog); fs::path pathDebug = GetDataDir() / "debug.log"; fileout = fsbridge::fopen(pathDebug, "a"); if (fileout) { - setbuf(fileout, NULL); // unbuffered + setbuf(fileout, nullptr); // unbuffered // dump buffered messages from before we opened the log while (!vMsgsBeforeOpenLog->empty()) { FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); @@ -208,7 +208,7 @@ void OpenDebugLog() } delete vMsgsBeforeOpenLog; - vMsgsBeforeOpenLog = NULL; + vMsgsBeforeOpenLog = nullptr; } struct CLogCategoryDesc @@ -344,7 +344,7 @@ int LogPrintStr(const std::string &str) boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); // buffer if we haven't opened the log yet - if (fileout == NULL) { + if (fileout == nullptr) { assert(vMsgsBeforeOpenLog); ret = strTimestamped.length(); vMsgsBeforeOpenLog->push_back(strTimestamped); @@ -355,8 +355,8 @@ int LogPrintStr(const std::string &str) if (fReopenDebugLog) { fReopenDebugLog = false; fs::path pathDebug = GetDataDir() / "debug.log"; - if (fsbridge::freopen(pathDebug,"a",fileout) != NULL) - setbuf(fileout, NULL); // unbuffered + if (fsbridge::freopen(pathDebug,"a",fileout) != nullptr) + setbuf(fileout, nullptr); // unbuffered } ret = FileWriteStr(strTimestamped, fileout); @@ -419,49 +419,48 @@ void ArgsManager::ParseParameters(int argc, const char* const argv[]) } } -std::vector<std::string> ArgsManager::GetArgs(const std::string& strArg) +std::vector<std::string> ArgsManager::GetArgs(const std::string& strArg) const { LOCK(cs_args); - if (IsArgSet(strArg)) - return mapMultiArgs.at(strArg); + auto it = mapMultiArgs.find(strArg); + if (it != mapMultiArgs.end()) return it->second; return {}; } -bool ArgsManager::IsArgSet(const std::string& strArg) +bool ArgsManager::IsArgSet(const std::string& strArg) const { LOCK(cs_args); return mapArgs.count(strArg); } -std::string ArgsManager::GetArg(const std::string& strArg, const std::string& strDefault) +std::string ArgsManager::GetArg(const std::string& strArg, const std::string& strDefault) const { LOCK(cs_args); - if (mapArgs.count(strArg)) - return mapArgs[strArg]; + auto it = mapArgs.find(strArg); + if (it != mapArgs.end()) return it->second; return strDefault; } -int64_t ArgsManager::GetArg(const std::string& strArg, int64_t nDefault) +int64_t ArgsManager::GetArg(const std::string& strArg, int64_t nDefault) const { LOCK(cs_args); - if (mapArgs.count(strArg)) - return atoi64(mapArgs[strArg]); + auto it = mapArgs.find(strArg); + if (it != mapArgs.end()) return atoi64(it->second); return nDefault; } -bool ArgsManager::GetBoolArg(const std::string& strArg, bool fDefault) +bool ArgsManager::GetBoolArg(const std::string& strArg, bool fDefault) const { LOCK(cs_args); - if (mapArgs.count(strArg)) - return InterpretBool(mapArgs[strArg]); + auto it = mapArgs.find(strArg); + if (it != mapArgs.end()) return InterpretBool(it->second); return fDefault; } bool ArgsManager::SoftSetArg(const std::string& strArg, const std::string& strValue) { LOCK(cs_args); - if (mapArgs.count(strArg)) - return false; + if (IsArgSet(strArg)) return false; ForceSetArg(strArg, strValue); return true; } @@ -478,8 +477,7 @@ void ArgsManager::ForceSetArg(const std::string& strArg, const std::string& strV { LOCK(cs_args); mapArgs[strArg] = strValue; - mapMultiArgs[strArg].clear(); - mapMultiArgs[strArg].push_back(strValue); + mapMultiArgs[strArg] = {strValue}; } @@ -503,7 +501,7 @@ static std::string FormatException(const std::exception* pex, const char* pszThr { #ifdef WIN32 char pszModule[MAX_PATH] = ""; - GetModuleFileNameA(NULL, pszModule, sizeof(pszModule)); + GetModuleFileNameA(nullptr, pszModule, sizeof(pszModule)); #else const char* pszModule = "bitcoin"; #endif @@ -534,7 +532,7 @@ fs::path GetDefaultDataDir() #else fs::path pathRet; char* pszHome = getenv("HOME"); - if (pszHome == NULL || strlen(pszHome) == 0) + if (pszHome == nullptr || strlen(pszHome) == 0) pathRet = fs::path("/"); else pathRet = fs::path(pszHome); @@ -564,8 +562,8 @@ const fs::path &GetDataDir(bool fNetSpecific) if (!path.empty()) return path; - if (IsArgSet("-datadir")) { - path = fs::system_complete(GetArg("-datadir", "")); + if (gArgs.IsArgSet("-datadir")) { + path = fs::system_complete(gArgs.GetArg("-datadir", "")); if (!fs::is_directory(path)) { path = ""; return path; @@ -627,7 +625,7 @@ void ArgsManager::ReadConfigFile(const std::string& confPath) #ifndef WIN32 fs::path GetPidFile() { - fs::path pathPidFile(GetArg("-pid", BITCOIN_PID_FILENAME)); + fs::path pathPidFile(gArgs.GetArg("-pid", BITCOIN_PID_FILENAME)); if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile; return pathPidFile; } @@ -791,7 +789,7 @@ void ShrinkDebugFile() fclose(file); } } - else if (file != NULL) + else if (file != nullptr) fclose(file); } @@ -800,7 +798,7 @@ fs::path GetSpecialFolderPath(int nFolder, bool fCreate) { char pszPath[MAX_PATH] = ""; - if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate)) + if(SHGetSpecialFolderPathA(nullptr, pszPath, nFolder, fCreate)) { return fs::path(pszPath); } diff --git a/src/util.h b/src/util.h index e1bdfb1988..480a80c0a3 100644 --- a/src/util.h +++ b/src/util.h @@ -195,13 +195,20 @@ inline bool IsSwitchChar(char c) class ArgsManager { protected: - CCriticalSection cs_args; + mutable CCriticalSection cs_args; std::map<std::string, std::string> mapArgs; - std::map<std::string, std::vector<std::string> > mapMultiArgs; + std::map<std::string, std::vector<std::string>> mapMultiArgs; public: void ParseParameters(int argc, const char*const argv[]); void ReadConfigFile(const std::string& confPath); - std::vector<std::string> GetArgs(const std::string& strArg); + + /** + * Return a vector of strings of the given argument + * + * @param strArg Argument to get (e.g. "-foo") + * @return command-line arguments + */ + std::vector<std::string> GetArgs(const std::string& strArg) const; /** * Return true if the given argument has been manually set @@ -209,7 +216,7 @@ public: * @param strArg Argument to get (e.g. "-foo") * @return true if the argument has been set */ - bool IsArgSet(const std::string& strArg); + bool IsArgSet(const std::string& strArg) const; /** * Return string argument or default value @@ -218,7 +225,7 @@ public: * @param strDefault (e.g. "1") * @return command-line argument or default value */ - std::string GetArg(const std::string& strArg, const std::string& strDefault); + std::string GetArg(const std::string& strArg, const std::string& strDefault) const; /** * Return integer argument or default value @@ -227,7 +234,7 @@ public: * @param nDefault (e.g. 1) * @return command-line argument (0 if invalid number) or default value */ - int64_t GetArg(const std::string& strArg, int64_t nDefault); + int64_t GetArg(const std::string& strArg, int64_t nDefault) const; /** * Return boolean argument or default value @@ -236,7 +243,7 @@ public: * @param fDefault (true or false) * @return command-line argument or default value */ - bool GetBoolArg(const std::string& strArg, bool fDefault); + bool GetBoolArg(const std::string& strArg, bool fDefault) const; /** * Set an argument if it doesn't already have a value @@ -263,52 +270,6 @@ public: extern ArgsManager gArgs; -// wrappers using the global ArgsManager: -static inline void ParseParameters(int argc, const char*const argv[]) -{ - gArgs.ParseParameters(argc, argv); -} - -static inline void ReadConfigFile(const std::string& confPath) -{ - gArgs.ReadConfigFile(confPath); -} - -static inline bool SoftSetArg(const std::string& strArg, const std::string& strValue) -{ - return gArgs.SoftSetArg(strArg, strValue); -} - -static inline void ForceSetArg(const std::string& strArg, const std::string& strValue) -{ - gArgs.ForceSetArg(strArg, strValue); -} - -static inline bool IsArgSet(const std::string& strArg) -{ - return gArgs.IsArgSet(strArg); -} - -static inline std::string GetArg(const std::string& strArg, const std::string& strDefault) -{ - return gArgs.GetArg(strArg, strDefault); -} - -static inline int64_t GetArg(const std::string& strArg, int64_t nDefault) -{ - return gArgs.GetArg(strArg, nDefault); -} - -static inline bool GetBoolArg(const std::string& strArg, bool fDefault) -{ - return gArgs.GetBoolArg(strArg, fDefault); -} - -static inline bool SoftSetBoolArg(const std::string& strArg, bool fValue) -{ - return gArgs.SoftSetBoolArg(strArg, fValue); -} - /** * Format a string to be used as group of options in help messages * @@ -358,7 +319,7 @@ template <typename Callable> void TraceThread(const char* name, Callable func) throw; } catch (...) { - PrintExceptionContinue(NULL, name); + PrintExceptionContinue(nullptr, name); throw; } } diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h index 5839b07344..bc885ee167 100644 --- a/src/utilmoneystr.h +++ b/src/utilmoneystr.h @@ -14,6 +14,9 @@ #include "amount.h" +/* Do not use these functions to represent or parse monetary amounts to or from + * JSON but use AmountFromValue and ValueFromAmount for that. + */ std::string FormatMoney(const CAmount& n); bool ParseMoney(const std::string& str, CAmount& nRet); bool ParseMoney(const char* pszIn, CAmount& nRet); diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 9ee14070a2..fd233f6757 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -452,7 +452,7 @@ bool ParseInt32(const std::string& str, int32_t *out) { if (!ParsePrechecks(str)) return false; - char *endp = NULL; + char *endp = nullptr; errno = 0; // strtol will not set errno if valid long int n = strtol(str.c_str(), &endp, 10); if(out) *out = (int32_t)n; @@ -468,7 +468,7 @@ bool ParseInt64(const std::string& str, int64_t *out) { if (!ParsePrechecks(str)) return false; - char *endp = NULL; + char *endp = nullptr; errno = 0; // strtoll will not set errno if valid long long int n = strtoll(str.c_str(), &endp, 10); if(out) *out = (int64_t)n; @@ -485,7 +485,7 @@ bool ParseUInt32(const std::string& str, uint32_t *out) return false; if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoul accepts these by default if they fit in the range return false; - char *endp = NULL; + char *endp = nullptr; errno = 0; // strtoul will not set errno if valid unsigned long int n = strtoul(str.c_str(), &endp, 10); if(out) *out = (uint32_t)n; @@ -502,7 +502,7 @@ bool ParseUInt64(const std::string& str, uint64_t *out) return false; if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoull accepts these by default if they fit in the range return false; - char *endp = NULL; + char *endp = nullptr; errno = 0; // strtoull will not set errno if valid unsigned long long int n = strtoull(str.c_str(), &endp, 10); if(out) *out = (uint64_t)n; @@ -583,7 +583,7 @@ int64_t atoi64(const char* psz) #ifdef _MSC_VER return _atoi64(psz); #else - return strtoll(psz, NULL, 10); + return strtoll(psz, nullptr, 10); #endif } @@ -592,7 +592,7 @@ int64_t atoi64(const std::string& str) #ifdef _MSC_VER return _atoi64(str.c_str()); #else - return strtoll(str.c_str(), NULL, 10); + return strtoll(str.c_str(), nullptr, 10); #endif } diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index 707fdaad16..53da60e8f1 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -39,11 +39,11 @@ std::vector<unsigned char> ParseHex(const char* psz); std::vector<unsigned char> ParseHex(const std::string& str); signed char HexDigit(char c); bool IsHex(const std::string& str); -std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL); +std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = nullptr); std::string DecodeBase64(const std::string& str); std::string EncodeBase64(const unsigned char* pch, size_t len); std::string EncodeBase64(const std::string& str); -std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = NULL); +std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = nullptr); std::string DecodeBase32(const std::string& str); std::string EncodeBase32(const unsigned char* pch, size_t len); std::string EncodeBase32(const std::string& str); diff --git a/src/utiltime.cpp b/src/utiltime.cpp index e07069125d..4cc77dbfeb 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -21,7 +21,7 @@ int64_t GetTime() int64_t mocktime = nMockTime.load(std::memory_order_relaxed); if (mocktime) return mocktime; - time_t now = time(NULL); + time_t now = time(nullptr); assert(now > 0); return now; } diff --git a/src/validation.cpp b/src/validation.cpp index 405ff356f5..d1a8b8460a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -61,7 +61,7 @@ CCriticalSection cs_main; BlockMap mapBlockIndex; CChain chainActive; -CBlockIndex *pindexBestHeader = NULL; +CBlockIndex *pindexBestHeader = nullptr; CWaitableCriticalSection csBestBlock; CConditionVariable cvBlockChange; int nScriptCheckThreads = 0; @@ -177,9 +177,9 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc return chain.Genesis(); } -CCoinsViewDB *pcoinsdbview = NULL; -CCoinsViewCache *pcoinsTip = NULL; -CBlockTreeDB *pblocktree = NULL; +CCoinsViewDB *pcoinsdbview = nullptr; +CCoinsViewCache *pcoinsTip = nullptr; +CBlockTreeDB *pblocktree = nullptr; enum FlushStateMode { FLUSH_STATE_NONE, @@ -378,7 +378,7 @@ void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool f while (it != disconnectpool.queuedTx.get<insertion_order>().rend()) { // ignore validation errors in resurrected transactions CValidationState stateDummy; - if (!fAddToMempool || (*it)->IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, *it, false, NULL, NULL, true)) { + if (!fAddToMempool || (*it)->IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, *it, false, nullptr, nullptr, true)) { // If the transaction doesn't make it in to the mempool, remove any // transactions that depend on it (which would now be orphans). mempool.removeRecursive(**it, MemPoolRemovalReason::REORG); @@ -398,7 +398,7 @@ void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool f // We also need to remove any now-immature transactions mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); // Re-limit mempool size, in case we added any transactions - LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); + LimitMempoolSize(mempool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); } // Used to avoid mempool polluting consensus critical paths if CCoinsViewMempool @@ -456,7 +456,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool // Reject transactions with witness before segregated witness activates (override with -prematurewitness) bool witnessEnabled = IsWitnessEnabled(chainActive.Tip(), chainparams.GetConsensus()); - if (!GetBoolArg("-prematurewitness", false) && tx.HasWitness() && !witnessEnabled) { + if (!gArgs.GetBoolArg("-prematurewitness", false) && tx.HasWitness() && !witnessEnabled) { return state.DoS(0, false, REJECT_NONSTANDARD, "no-witness-yet", true); } @@ -611,7 +611,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, strprintf("%d", nSigOpsCost)); - CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize); + CAmount mempoolRejectFee = pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize); if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) { return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee)); } @@ -628,10 +628,10 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool // Calculate in-mempool ancestors, up to a limit. CTxMemPool::setEntries setAncestors; - size_t nLimitAncestors = GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); - size_t nLimitAncestorSize = GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000; - size_t nLimitDescendants = GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT); - size_t nLimitDescendantSize = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000; + size_t nLimitAncestors = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); + size_t nLimitAncestorSize = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000; + size_t nLimitDescendants = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT); + size_t nLimitDescendantSize = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000; std::string errString; if (!pool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) { return state.DoS(0, false, REJECT_NONSTANDARD, "too-long-mempool-chain", false, errString); @@ -783,7 +783,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS; if (!chainparams.RequireStandard()) { - scriptVerifyFlags = GetArg("-promiscuousmempoolflags", scriptVerifyFlags); + scriptVerifyFlags = gArgs.GetArg("-promiscuousmempoolflags", scriptVerifyFlags); } // Check against previous transactions @@ -860,7 +860,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool // trim mempool and check if tx was trimmed if (!fOverrideMempoolLimit) { - LimitMempoolSize(pool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); + LimitMempoolSize(pool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); if (!pool.exists(hash)) return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool full"); } @@ -899,7 +899,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa /** Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock */ bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow) { - CBlockIndex *pindexSlow = NULL; + CBlockIndex *pindexSlow = nullptr; LOCK(cs_main); @@ -1045,7 +1045,7 @@ bool IsInitialBlockDownload() return false; if (fImporting || fReindex) return true; - if (chainActive.Tip() == NULL) + if (chainActive.Tip() == nullptr) return true; if (chainActive.Tip()->nChainWork < UintToArith256(chainParams.GetConsensus().nMinimumChainWork)) return true; @@ -1056,12 +1056,12 @@ bool IsInitialBlockDownload() return false; } -CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL; +CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr; static void AlertNotify(const std::string& strMessage) { uiInterface.NotifyAlertChanged(); - std::string strCmd = GetArg("-alertnotify", ""); + std::string strCmd = gArgs.GetArg("-alertnotify", ""); if (strCmd.empty()) return; // Alert text should be plain ascii coming from a trusted source, but to @@ -1086,7 +1086,7 @@ static void CheckForkWarningConditions() // If our best fork is no longer within 72 blocks (+/- 12 hours if no one mines it) // of our head, drop it if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72) - pindexBestForkTip = NULL; + pindexBestForkTip = nullptr; if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (GetBlockProof(*chainActive.Tip()) * 6))) { @@ -1216,7 +1216,7 @@ static uint256 scriptExecutionCacheNonce(GetRandHash()); void InitScriptExecutionCache() { // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero, // setup_bytes creates the minimum possible cache (2 elements). - size_t nMaxCacheSize = std::min(std::max((int64_t)0, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); + size_t nMaxCacheSize = std::min(std::max((int64_t)0, gArgs.GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); size_t nElems = scriptExecutionCache.setup_bytes(nMaxCacheSize); LogPrintf("Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n", (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems); @@ -1226,7 +1226,7 @@ void InitScriptExecutionCache() { * Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts) * This does not modify the UTXO set. * - * If pvChecks is not NULL, script checks are pushed onto it instead of being performed inline. Any + * If pvChecks is not nullptr, script checks are pushed onto it instead of being performed inline. Any * script checks which are not necessary (eg due to script execution cache hits) are, obviously, * not pushed onto pvChecks/run. * @@ -1563,7 +1563,7 @@ private: int bit; public: - WarningBitsConditionChecker(int bitIn) : bit(bitIn) {} + explicit WarningBitsConditionChecker(int bitIn) : bit(bitIn) {} int64_t BeginTime(const Consensus::Params& params) const override { return 0; } int64_t EndTime(const Consensus::Params& params) const override { return std::numeric_limits<int64_t>::max(); } @@ -1633,7 +1633,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd AssertLockHeld(cs_main); assert(pindex); // pindex->phashBlock can be null if called by CreateNewBlock/TestBlockValidity - assert((pindex->phashBlock == NULL) || + assert((pindex->phashBlock == nullptr) || (*pindex->phashBlock == block.GetHash())); int64_t nTimeStart = GetTimeMicros(); @@ -1642,7 +1642,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); // verify that the view's current state corresponds to the previous block - uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash(); + uint256 hashPrevBlock = pindex->pprev == nullptr ? uint256() : pindex->pprev->GetBlockHash(); assert(hashPrevBlock == view.GetBestBlock()); // Special case for the genesis block, skipping connection of its transactions @@ -1733,7 +1733,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd CBlockUndo blockundo; - CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); + CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : nullptr); std::vector<int> prevheights; CAmount nFees = 0; @@ -1787,7 +1787,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd std::vector<CScriptCheck> vChecks; bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */ - if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, fCacheResults, txdata[i], nScriptCheckThreads ? &vChecks : NULL)) + if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, fCacheResults, txdata[i], nScriptCheckThreads ? &vChecks : nullptr)) return error("ConnectBlock(): CheckInputs on %s failed with %s", tx.GetHash().ToString(), FormatStateMessage(state)); control.Add(vChecks); @@ -1863,95 +1863,100 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd */ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &state, FlushStateMode mode, int nManualPruneHeight) { int64_t nMempoolUsage = mempool.DynamicMemoryUsage(); - LOCK2(cs_main, cs_LastBlockFile); + LOCK(cs_main); static int64_t nLastWrite = 0; static int64_t nLastFlush = 0; static int64_t nLastSetChain = 0; std::set<int> setFilesToPrune; bool fFlushForPrune = false; + bool fDoFullFlush = false; + int64_t nNow = 0; try { - if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0) && !fReindex) { - if (nManualPruneHeight > 0) { - FindFilesToPruneManual(setFilesToPrune, nManualPruneHeight); - } else { - FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight()); - fCheckForPruning = false; - } - if (!setFilesToPrune.empty()) { - fFlushForPrune = true; - if (!fHavePruned) { - pblocktree->WriteFlag("prunedblockfiles", true); - fHavePruned = true; - } - } - } - int64_t nNow = GetTimeMicros(); - // Avoid writing/flushing immediately after startup. - if (nLastWrite == 0) { - nLastWrite = nNow; - } - if (nLastFlush == 0) { - nLastFlush = nNow; - } - if (nLastSetChain == 0) { - nLastSetChain = nNow; - } - int64_t nMempoolSizeMax = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; - int64_t cacheSize = pcoinsTip->DynamicMemoryUsage(); - int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0); - // The cache is large and we're within 10% and 10 MiB of the limit, but we have time now (not in the middle of a block processing). - bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024); - // The cache is over the limit, we have to write now. - bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nTotalSpace; - // It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash. - bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000; - // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage. - bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000; - // Combine all conditions that result in a full cache flush. - bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune; - // Write blocks and block index to disk. - if (fDoFullFlush || fPeriodicWrite) { - // Depend on nMinDiskSpace to ensure we can write block index - if (!CheckDiskSpace(0)) - return state.Error("out of disk space"); - // First make sure all block and undo data is flushed to disk. - FlushBlockFile(); - // Then update all block file information (which may refer to block and undo files). - { - std::vector<std::pair<int, const CBlockFileInfo*> > vFiles; - vFiles.reserve(setDirtyFileInfo.size()); - for (std::set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) { - vFiles.push_back(std::make_pair(*it, &vinfoBlockFile[*it])); - setDirtyFileInfo.erase(it++); + { + LOCK(cs_LastBlockFile); + if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0) && !fReindex) { + if (nManualPruneHeight > 0) { + FindFilesToPruneManual(setFilesToPrune, nManualPruneHeight); + } else { + FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight()); + fCheckForPruning = false; } - std::vector<const CBlockIndex*> vBlocks; - vBlocks.reserve(setDirtyBlockIndex.size()); - for (std::set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) { - vBlocks.push_back(*it); - setDirtyBlockIndex.erase(it++); + if (!setFilesToPrune.empty()) { + fFlushForPrune = true; + if (!fHavePruned) { + pblocktree->WriteFlag("prunedblockfiles", true); + fHavePruned = true; + } } - if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) { - return AbortNode(state, "Failed to write to block index database"); + } + nNow = GetTimeMicros(); + // Avoid writing/flushing immediately after startup. + if (nLastWrite == 0) { + nLastWrite = nNow; + } + if (nLastFlush == 0) { + nLastFlush = nNow; + } + if (nLastSetChain == 0) { + nLastSetChain = nNow; + } + int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + int64_t cacheSize = pcoinsTip->DynamicMemoryUsage(); + int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0); + // The cache is large and we're within 10% and 10 MiB of the limit, but we have time now (not in the middle of a block processing). + bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024); + // The cache is over the limit, we have to write now. + bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nTotalSpace; + // It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash. + bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000; + // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage. + bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000; + // Combine all conditions that result in a full cache flush. + fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune; + // Write blocks and block index to disk. + if (fDoFullFlush || fPeriodicWrite) { + // Depend on nMinDiskSpace to ensure we can write block index + if (!CheckDiskSpace(0)) + return state.Error("out of disk space"); + // First make sure all block and undo data is flushed to disk. + FlushBlockFile(); + // Then update all block file information (which may refer to block and undo files). + { + std::vector<std::pair<int, const CBlockFileInfo*> > vFiles; + vFiles.reserve(setDirtyFileInfo.size()); + for (std::set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) { + vFiles.push_back(std::make_pair(*it, &vinfoBlockFile[*it])); + setDirtyFileInfo.erase(it++); + } + std::vector<const CBlockIndex*> vBlocks; + vBlocks.reserve(setDirtyBlockIndex.size()); + for (std::set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) { + vBlocks.push_back(*it); + setDirtyBlockIndex.erase(it++); + } + if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) { + return AbortNode(state, "Failed to write to block index database"); + } } + // Finally remove any pruned files + if (fFlushForPrune) + UnlinkPrunedFiles(setFilesToPrune); + nLastWrite = nNow; + } + // Flush best chain related state. This can only be done if the blocks / block index write was also done. + if (fDoFullFlush) { + // Typical Coin structures on disk are around 48 bytes in size. + // Pushing a new one to the database can cause it to be written + // twice (once in the log, and once in the tables). This is already + // an overestimation, as most will delete an existing entry or + // overwrite one. Still, use a conservative safety factor of 2. + if (!CheckDiskSpace(48 * 2 * 2 * pcoinsTip->GetCacheSize())) + return state.Error("out of disk space"); + // Flush the chainstate (which may refer to block index entries). + if (!pcoinsTip->Flush()) + return AbortNode(state, "Failed to write to coin database"); + nLastFlush = nNow; } - // Finally remove any pruned files - if (fFlushForPrune) - UnlinkPrunedFiles(setFilesToPrune); - nLastWrite = nNow; - } - // Flush best chain related state. This can only be done if the blocks / block index write was also done. - if (fDoFullFlush) { - // Typical Coin structures on disk are around 48 bytes in size. - // Pushing a new one to the database can cause it to be written - // twice (once in the log, and once in the tables). This is already - // an overestimation, as most will delete an existing entry or - // overwrite one. Still, use a conservative safety factor of 2. - if (!CheckDiskSpace(48 * 2 * 2 * pcoinsTip->GetCacheSize())) - return state.Error("out of disk space"); - // Flush the chainstate (which may refer to block index entries). - if (!pcoinsTip->Flush()) - return AbortNode(state, "Failed to write to coin database"); - nLastFlush = nNow; } if (fDoFullFlush || ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000)) { // Update best block in wallet (so we can detect restored wallets). @@ -2014,7 +2019,7 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { } } // Check the version of the last 100 blocks to see if we need to upgrade: - for (int i = 0; i < 100 && pindex != NULL; i++) + for (int i = 0; i < 100 && pindex != nullptr; i++) { int32_t nExpectedVersion = ComputeBlockVersion(pindex->pprev, chainParams.GetConsensus()); if (pindex->nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION && (pindex->nVersion & ~nExpectedVersion) != 0) @@ -2047,7 +2052,7 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { * should make the mempool consistent again by calling UpdateMempoolForReorg. * with cs_main held. * - * If disconnectpool is NULL, then no disconnected transactions are added to + * If disconnectpool is nullptr, then no disconnected transactions are added to * disconnectpool (note that the caller is responsible for mempool consistency * in any case). */ @@ -2103,7 +2108,7 @@ static int64_t nTimeChainState = 0; static int64_t nTimePostConnect = 0; struct PerBlockConnectTrace { - CBlockIndex* pindex = NULL; + CBlockIndex* pindex = nullptr; std::shared_ptr<const CBlock> pblock; std::shared_ptr<std::vector<CTransactionRef>> conflictedTxs; PerBlockConnectTrace() : conflictedTxs(std::make_shared<std::vector<CTransactionRef>>()) {} @@ -2130,7 +2135,7 @@ private: CTxMemPool &pool; public: - ConnectTrace(CTxMemPool &_pool) : blocksConnected(1), pool(_pool) { + explicit ConnectTrace(CTxMemPool &_pool) : blocksConnected(1), pool(_pool) { pool.NotifyEntryRemoved.connect(boost::bind(&ConnectTrace::NotifyEntryRemoved, this, _1, _2)); } @@ -2168,7 +2173,7 @@ public: }; /** - * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock + * Connect a new block to chainActive. pblock is either nullptr or a pointer to a CBlock * corresponding to pindexNew, to bypass loading it again from disk. * * The block is added to connectTrace if connection succeeds. @@ -2233,13 +2238,13 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, */ static CBlockIndex* FindMostWorkChain() { do { - CBlockIndex *pindexNew = NULL; + CBlockIndex *pindexNew = nullptr; // Find the best candidate header. { std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin(); if (it == setBlockIndexCandidates.rend()) - return NULL; + return nullptr; pindexNew = *it; } @@ -2258,7 +2263,7 @@ static CBlockIndex* FindMostWorkChain() { bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA); if (fFailedChain || fMissingData) { // Candidate chain is not usable (either invalid or missing data) - if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork)) + if (fFailedChain && (pindexBestInvalid == nullptr || pindexNew->nChainWork > pindexBestInvalid->nChainWork)) pindexBestInvalid = pindexNew; CBlockIndex *pindexFailed = pindexNew; // Remove the entire chain from the set. @@ -2299,7 +2304,7 @@ static void PruneBlockIndexCandidates() { /** * Try to make some progress towards making pindexMostWork the active block. - * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. + * pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork. */ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) { @@ -2385,8 +2390,8 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c static void NotifyHeaderTip() { bool fNotify = false; bool fInitialBlockDownload = false; - static CBlockIndex* pindexHeaderOld = NULL; - CBlockIndex* pindexHeader = NULL; + static CBlockIndex* pindexHeaderOld = nullptr; + CBlockIndex* pindexHeader = nullptr; { LOCK(cs_main); pindexHeader = pindexBestHeader; @@ -2405,7 +2410,7 @@ static void NotifyHeaderTip() { /** * Make the best chain active, in multiple steps. The result is either failure - * or an activated best chain. pblock is either NULL or a pointer to a block + * or an activated best chain. pblock is either nullptr or a pointer to a block * that is already loaded (to avoid loading it again from disk). */ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) { @@ -2414,9 +2419,9 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, // us in the middle of ProcessNewBlock - do not assume pblock is set // sanely for performance or correctness! - CBlockIndex *pindexMostWork = NULL; - CBlockIndex *pindexNewTip = NULL; - int nStopAtHeight = GetArg("-stopatheight", DEFAULT_STOPATHEIGHT); + CBlockIndex *pindexMostWork = nullptr; + CBlockIndex *pindexNewTip = nullptr; + int nStopAtHeight = gArgs.GetArg("-stopatheight", DEFAULT_STOPATHEIGHT); do { boost::this_thread::interruption_point(); if (ShutdownRequested()) @@ -2429,12 +2434,12 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, ConnectTrace connectTrace(mempool); // Destructed before cs_main is unlocked CBlockIndex *pindexOldTip = chainActive.Tip(); - if (pindexMostWork == NULL) { + if (pindexMostWork == nullptr) { pindexMostWork = FindMostWorkChain(); } // Whether we have anything to do at all. - if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip()) + if (pindexMostWork == nullptr || pindexMostWork == chainActive.Tip()) return true; bool fInvalidFound = false; @@ -2444,7 +2449,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, if (fInvalidFound) { // Wipe cache, we may need another branch now. - pindexMostWork = NULL; + pindexMostWork = nullptr; } pindexNewTip = chainActive.Tip(); pindexFork = chainActive.FindFork(pindexOldTip); @@ -2569,14 +2574,14 @@ bool ResetBlockFailureFlags(CBlockIndex *pindex) { } if (it->second == pindexBestInvalid) { // Reset invalid block marker if it was pointing to one of those. - pindexBestInvalid = NULL; + pindexBestInvalid = nullptr; } } it++; } // Remove the invalidity flag from all ancestors too. - while (pindex != NULL) { + while (pindex != nullptr) { if (pindex->nStatus & BLOCK_FAILED_MASK) { pindex->nStatus &= ~BLOCK_FAILED_MASK; setDirtyBlockIndex.insert(pindex); @@ -2613,7 +2618,7 @@ static CBlockIndex* AddToBlockIndex(const CBlockHeader& block) pindexNew->nTimeMax = (pindexNew->pprev ? std::max(pindexNew->pprev->nTimeMax, pindexNew->nTime) : pindexNew->nTime); pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew); pindexNew->RaiseValidity(BLOCK_VALID_TREE); - if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork) + if (pindexBestHeader == nullptr || pindexBestHeader->nChainWork < pindexNew->nChainWork) pindexBestHeader = pindexNew; setDirtyBlockIndex.insert(pindexNew); @@ -2636,7 +2641,7 @@ static bool ReceivedBlockTransactions(const CBlock &block, CValidationState& sta pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS); setDirtyBlockIndex.insert(pindexNew); - if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) { + if (pindexNew->pprev == nullptr || pindexNew->pprev->nChainTx) { // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS. std::deque<CBlockIndex*> queue; queue.push_back(pindexNew); @@ -2650,7 +2655,7 @@ static bool ReceivedBlockTransactions(const CBlock &block, CValidationState& sta LOCK(cs_nBlockSequenceId); pindex->nSequenceId = nBlockSequenceId++; } - if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) { + if (chainActive.Tip() == nullptr || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) { setBlockIndexCandidates.insert(pindex); } std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex); @@ -2830,22 +2835,6 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P return true; } -static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidationState& state, const CChainParams& chainparams, const uint256& hash) -{ - if (*pindexPrev->phashBlock == chainparams.GetConsensus().hashGenesisBlock) - return true; - - int nHeight = pindexPrev->nHeight+1; - // Don't accept any forks from the main chain prior to last checkpoint. - // GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our - // MapBlockIndex. - CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints()); - if (pcheckpoint && nHeight < pcheckpoint->nHeight) - return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), REJECT_CHECKPOINT, "bad-fork-prior-to-checkpoint"); - - return true; -} - bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params) { LOCK(cs_main); @@ -2886,7 +2875,7 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc std::vector<unsigned char> ret(32, 0x00); if (consensusParams.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) { if (commitpos == -1) { - uint256 witnessroot = BlockWitnessMerkleRoot(block, NULL); + uint256 witnessroot = BlockWitnessMerkleRoot(block, nullptr); CHash256().Write(witnessroot.begin(), 32).Write(ret.data(), 32).Finalize(witnessroot.begin()); CTxOut out; out.nValue = 0; @@ -2911,14 +2900,26 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc /** 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(). */ -static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) +static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) { - assert(pindexPrev != NULL); + assert(pindexPrev != nullptr); const int nHeight = pindexPrev->nHeight + 1; + // Check proof of work + const Consensus::Params& consensusParams = params.GetConsensus(); if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work"); + // Check against checkpoints + if (fCheckpointsEnabled) { + // Don't accept any forks from the main chain prior to last checkpoint. + // GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our + // MapBlockIndex. + CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(params.Checkpoints()); + if (pcheckpoint && nHeight < pcheckpoint->nHeight) + return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), REJECT_CHECKPOINT, "bad-fork-prior-to-checkpoint"); + } + // Check timestamp against prev if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) return state.Invalid(false, REJECT_INVALID, "time-too-old", "block's timestamp is too early"); @@ -2940,7 +2941,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) { - const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1; + const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1; // Start enforcing BIP113 (Median Time Past) using versionbits logic. int nLockTimeFlags = 0; @@ -3025,7 +3026,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state // Check for duplicate uint256 hash = block.GetHash(); BlockMap::iterator miSelf = mapBlockIndex.find(hash); - CBlockIndex *pindex = NULL; + CBlockIndex *pindex = nullptr; if (hash != chainparams.GetConsensus().hashGenesisBlock) { if (miSelf != mapBlockIndex.end()) { @@ -3042,22 +3043,17 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); // Get prev block index - CBlockIndex* pindexPrev = NULL; + CBlockIndex* pindexPrev = nullptr; BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) return state.DoS(10, error("%s: prev block not found", __func__), 0, "prev-blk-not-found"); pindexPrev = (*mi).second; if (pindexPrev->nStatus & BLOCK_FAILED_MASK) return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); - - assert(pindexPrev); - if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, hash)) - return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); - - if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev, GetAdjustedTime())) + if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, GetAdjustedTime())) return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); } - if (pindex == NULL) + if (pindex == nullptr) pindex = AddToBlockIndex(block); if (ppindex) @@ -3074,7 +3070,7 @@ bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, CValidatio { LOCK(cs_main); for (const CBlockHeader& header : headers) { - CBlockIndex *pindex = NULL; // Use a temp pindex instead of ppindex to avoid a const_cast + CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast if (!AcceptBlockHeader(header, state, chainparams, &pindex)) { return false; } @@ -3087,7 +3083,7 @@ bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, CValidatio return true; } -/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */ +/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const CDiskBlockPos* dbp, bool* fNewBlock) { const CBlock& block = *pblock; @@ -3095,7 +3091,7 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation if (fNewBlock) *fNewBlock = false; AssertLockHeld(cs_main); - CBlockIndex *pindexDummy = NULL; + CBlockIndex *pindexDummy = nullptr; CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy; if (!AcceptBlockHeader(block, state, chainparams, &pindex)) @@ -3148,11 +3144,11 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation try { unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); CDiskBlockPos blockPos; - if (dbp != NULL) + if (dbp != nullptr) blockPos = *dbp; - if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL)) + if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != nullptr)) return error("AcceptBlock(): FindBlockPos failed"); - if (dbp == NULL) + if (dbp == nullptr) if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) AbortNode(state, "Failed to write block"); if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.GetConsensus())) @@ -3170,7 +3166,7 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool *fNewBlock) { { - CBlockIndex *pindex = NULL; + CBlockIndex *pindex = nullptr; if (fNewBlock) *fNewBlock = false; CValidationState state; // Ensure that CheckBlock() passes before calling AcceptBlock, as @@ -3181,7 +3177,7 @@ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<cons if (ret) { // Store to disk - ret = AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, NULL, fNewBlock); + ret = AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, nullptr, fNewBlock); } CheckBlockIndex(chainparams.GetConsensus()); if (!ret) { @@ -3203,16 +3199,13 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, { AssertLockHeld(cs_main); assert(pindexPrev && pindexPrev == chainActive.Tip()); - if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, block.GetHash())) - return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); - CCoinsViewCache viewNew(pcoinsTip); CBlockIndex indexDummy(block); indexDummy.pprev = pindexPrev; indexDummy.nHeight = pindexPrev->nHeight + 1; // NOTE: CheckBlockHeader is called by CheckBlock - if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev, GetAdjustedTime())) + if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, GetAdjustedTime())) return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state)); if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot)) return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); @@ -3288,7 +3281,7 @@ static void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPr assert(fPruneMode && nManualPruneHeight > 0); LOCK2(cs_main, cs_LastBlockFile); - if (chainActive.Tip() == NULL) + if (chainActive.Tip() == nullptr) return; // last block to prune is the lesser of (user-specified height, MIN_BLOCKS_TO_KEEP from the tip) @@ -3330,7 +3323,7 @@ void PruneBlockFilesManual(int nManualPruneHeight) static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight) { LOCK2(cs_main, cs_LastBlockFile); - if (chainActive.Tip() == NULL || nPruneTarget == 0) { + if (chainActive.Tip() == nullptr || nPruneTarget == 0) { return; } if ((uint64_t)chainActive.Tip()->nHeight <= nPruneAfterHeight) { @@ -3388,7 +3381,7 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes) static FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly) { if (pos.IsNull()) - return NULL; + return nullptr; fs::path path = GetBlockPosFilename(pos, prefix); fs::create_directories(path.parent_path()); FILE* file = fsbridge::fopen(path, "rb+"); @@ -3396,13 +3389,13 @@ static FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fRe file = fsbridge::fopen(path, "wb+"); if (!file) { LogPrintf("Unable to open file %s\n", path.string()); - return NULL; + return nullptr; } if (pos.nPos) { if (fseek(file, pos.nPos, SEEK_SET)) { LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string()); fclose(file); - return NULL; + return nullptr; } } return file; @@ -3425,7 +3418,7 @@ fs::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix) CBlockIndex * InsertBlockIndex(uint256 hash) { if (hash.IsNull()) - return NULL; + return nullptr; // Return existing BlockMap::iterator mi = mapBlockIndex.find(hash); @@ -3477,13 +3470,13 @@ bool static LoadBlockIndexDB(const CChainParams& chainparams) pindex->nChainTx = pindex->nTx; } } - if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL)) + if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == nullptr)) setBlockIndexCandidates.insert(pindex); if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork)) pindexBestInvalid = pindex; if (pindex->pprev) pindex->BuildSkip(); - if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex))) + if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == nullptr || CBlockIndexWorkComparator()(pindexBestHeader, pindex))) pindexBestHeader = pindex; } @@ -3581,7 +3574,7 @@ CVerifyDB::~CVerifyDB() bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) { LOCK(cs_main); - if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL) + if (chainActive.Tip() == nullptr || chainActive.Tip()->pprev == nullptr) return true; // Verify blocks in the best chain @@ -3591,7 +3584,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); CCoinsViewCache coins(coinsview); CBlockIndex* pindexState = chainActive.Tip(); - CBlockIndex* pindexFailure = NULL; + CBlockIndex* pindexFailure = nullptr; int nGoodTransactions = 0; CValidationState state; int reportDone = 0; @@ -3784,7 +3777,7 @@ bool RewindBlockIndex(const CChainParams& params) // of the blockchain). break; } - if (!DisconnectTip(state, params, NULL)) { + if (!DisconnectTip(state, params, nullptr)) { return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight); } // Occasionally flush state to disk. @@ -3833,7 +3826,7 @@ bool RewindBlockIndex(const CChainParams& params) } } - if (chainActive.Tip() != NULL) { + if (chainActive.Tip() != nullptr) { // We can't prune block index candidates based on our tip if we have // no tip due to chainActive being empty! PruneBlockIndexCandidates(); @@ -3858,9 +3851,9 @@ void UnloadBlockIndex() { LOCK(cs_main); setBlockIndexCandidates.clear(); - chainActive.SetTip(NULL); - pindexBestInvalid = NULL; - pindexBestHeader = NULL; + chainActive.SetTip(nullptr); + pindexBestInvalid = nullptr; + pindexBestHeader = nullptr; mempool.clear(); mapBlocksUnlinked.clear(); vinfoBlockFile.clear(); @@ -3899,7 +3892,7 @@ bool LoadBlockIndex(const CChainParams& chainparams) LogPrintf("Initializing databases...\n"); // Use the provided setting for -txindex in the new database - fTxIndex = GetBoolArg("-txindex", DEFAULT_TXINDEX); + fTxIndex = gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX); pblocktree->WriteFlag("txindex", fTxIndex); } return true; @@ -3996,7 +3989,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) { LOCK(cs_main); CValidationState state; - if (AcceptBlock(pblock, state, chainparams, NULL, true, dbp, NULL)) + if (AcceptBlock(pblock, state, chainparams, nullptr, true, dbp, nullptr)) nLoaded++; if (state.IsError()) break; @@ -4030,7 +4023,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB head.ToString()); LOCK(cs_main); CValidationState dummy; - if (AcceptBlock(pblockrecursive, dummy, chainparams, NULL, true, &it->second, NULL)) + if (AcceptBlock(pblockrecursive, dummy, chainparams, nullptr, true, &it->second, nullptr)) { nLoaded++; queue.push_back(pblockrecursive->GetHash()); @@ -4077,35 +4070,35 @@ void static CheckBlockIndex(const Consensus::Params& consensusParams) assert(forward.size() == mapBlockIndex.size()); - std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL); + std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(nullptr); CBlockIndex *pindex = rangeGenesis.first->second; rangeGenesis.first++; - assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL. + assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent nullptr. // Iterate over the entire block tree, using depth-first search. // Along the way, remember whether there are blocks on the path from genesis // block being explored which are the first to have certain properties. size_t nNodes = 0; int nHeight = 0; - CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid. - CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA. - CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0. - CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not). - CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not). - CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not). - CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not). - while (pindex != NULL) { + CBlockIndex* pindexFirstInvalid = nullptr; // Oldest ancestor of pindex which is invalid. + CBlockIndex* pindexFirstMissing = nullptr; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA. + CBlockIndex* pindexFirstNeverProcessed = nullptr; // Oldest ancestor of pindex for which nTx == 0. + CBlockIndex* pindexFirstNotTreeValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not). + CBlockIndex* pindexFirstNotTransactionsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not). + CBlockIndex* pindexFirstNotChainValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not). + CBlockIndex* pindexFirstNotScriptsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not). + while (pindex != nullptr) { nNodes++; - if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex; - if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex; - if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex; - if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex; - if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex; - if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex; - if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex; + if (pindexFirstInvalid == nullptr && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex; + if (pindexFirstMissing == nullptr && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex; + if (pindexFirstNeverProcessed == nullptr && pindex->nTx == 0) pindexFirstNeverProcessed = pindex; + if (pindex->pprev != nullptr && pindexFirstNotTreeValid == nullptr && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex; + if (pindex->pprev != nullptr && pindexFirstNotTransactionsValid == nullptr && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex; + if (pindex->pprev != nullptr && pindexFirstNotChainValid == nullptr && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex; + if (pindex->pprev != nullptr && pindexFirstNotScriptsValid == nullptr && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex; // Begin: actual consistency checks. - if (pindex->pprev == NULL) { + if (pindex->pprev == nullptr) { // Genesis block checks. assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match. assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block. @@ -4124,26 +4117,26 @@ void static CheckBlockIndex(const Consensus::Params& consensusParams) if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA); assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent. // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set. - assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned). - assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0)); + assert((pindexFirstNeverProcessed != nullptr) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned). + assert((pindexFirstNotTransactionsValid != nullptr) == (pindex->nChainTx == 0)); assert(pindex->nHeight == nHeight); // nHeight must be consistent. - assert(pindex->pprev == NULL || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's. + assert(pindex->pprev == nullptr || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's. assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks. - assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid - if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid - if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid - if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid - if (pindexFirstInvalid == NULL) { + assert(pindexFirstNotTreeValid == nullptr); // All mapBlockIndex entries must at least be TREE valid + if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == nullptr); // TREE valid implies all parents are TREE valid + if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == nullptr); // CHAIN valid implies all parents are CHAIN valid + if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == nullptr); // SCRIPTS valid implies all parents are SCRIPTS valid + if (pindexFirstInvalid == nullptr) { // Checks for not-invalid blocks. assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents. } - if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) { - if (pindexFirstInvalid == NULL) { + if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == nullptr) { + if (pindexFirstInvalid == nullptr) { // If this block sorts at least as good as the current tip and // is valid and we have all data for its parents, it must be in // setBlockIndexCandidates. chainActive.Tip() must also be there // even if some data has been pruned. - if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) { + if (pindexFirstMissing == nullptr || pindex == chainActive.Tip()) { assert(setBlockIndexCandidates.count(pindex)); } // If some parent is missing, then it could be that this block was in @@ -4164,13 +4157,13 @@ void static CheckBlockIndex(const Consensus::Params& consensusParams) } rangeUnlinked.first++; } - if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) { + if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != nullptr && pindexFirstInvalid == nullptr) { // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked. assert(foundInUnlinked); } if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA - if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked. - if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) { + if (pindexFirstMissing == nullptr) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked. + if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == nullptr && pindexFirstMissing != nullptr) { // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent. assert(fHavePruned); // We must have pruned. // This block may have entered mapBlocksUnlinked if: @@ -4182,7 +4175,7 @@ void static CheckBlockIndex(const Consensus::Params& consensusParams) // So if this block is itself better than chainActive.Tip() and it wasn't in // setBlockIndexCandidates, then it must be in mapBlocksUnlinked. if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) { - if (pindexFirstInvalid == NULL) { + if (pindexFirstInvalid == nullptr) { assert(foundInUnlinked); } } @@ -4203,13 +4196,13 @@ void static CheckBlockIndex(const Consensus::Params& consensusParams) while (pindex) { // We are going to either move to a parent or a sibling of pindex. // If pindex was the first with a certain property, unset the corresponding variable. - if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL; - if (pindex == pindexFirstMissing) pindexFirstMissing = NULL; - if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL; - if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL; - if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL; - if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL; - if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL; + if (pindex == pindexFirstInvalid) pindexFirstInvalid = nullptr; + if (pindex == pindexFirstMissing) pindexFirstMissing = nullptr; + if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = nullptr; + if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = nullptr; + if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = nullptr; + if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = nullptr; + if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = nullptr; // Find our parent. CBlockIndex* pindexPar = pindex->pprev; // Find which child we just visited. @@ -4270,7 +4263,7 @@ static const uint64_t MEMPOOL_DUMP_VERSION = 1; bool LoadMempool(void) { const CChainParams& chainparams = Params(); - int64_t nExpiryTimeout = GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60; + int64_t nExpiryTimeout = gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60; FILE* filestr = fsbridge::fopen(GetDataDir() / "mempool.dat", "rb"); CAutoFile file(filestr, SER_DISK, CLIENT_VERSION); if (file.IsNull()) { @@ -4306,7 +4299,7 @@ bool LoadMempool(void) CValidationState state; if (nTime + nExpiryTimeout > nNow) { LOCK(cs_main); - AcceptToMemoryPoolWithTime(chainparams, mempool, state, tx, true, NULL, nTime, NULL, false, 0); + AcceptToMemoryPoolWithTime(chainparams, mempool, state, tx, true, nullptr, nTime, nullptr, false, 0); if (state.IsValid()) { ++count; } else { @@ -4382,10 +4375,10 @@ void DumpMempool(void) //! Guess how far we are in the verification process at the given block index double GuessVerificationProgress(const ChainTxData& data, CBlockIndex *pindex) { - if (pindex == NULL) + if (pindex == nullptr) return 0.0; - int64_t nNow = time(NULL); + int64_t nNow = time(nullptr); double fTxTotal; diff --git a/src/validation.h b/src/validation.h index b44b72d2d4..d0f6cdc135 100644 --- a/src/validation.h +++ b/src/validation.h @@ -246,7 +246,7 @@ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<cons * @param[in] chainparams The params for the chain we want to connect to * @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers */ -bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, CValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex=NULL); +bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, CValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex=nullptr); /** Check whether enough disk space is available for an incoming block */ bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); @@ -255,7 +255,7 @@ FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly = false); /** Translation to a filesystem path */ fs::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix); /** Import blocks from an external file */ -bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp = NULL); +bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp = nullptr); /** Ensures we have a genesis block in the block tree, possibly writing one to disk. */ bool LoadGenesisBlock(const CChainParams& chainparams); /** Load the block tree and coins database from disk, @@ -300,7 +300,7 @@ void PruneBlockFilesManual(int nManualPruneHeight); /** (try to) add transaction to memory pool * plTxnReplaced will be appended to with all transactions replaced from mempool **/ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree, - bool* pfMissingInputs, std::list<CTransactionRef>* plTxnReplaced = NULL, + bool* pfMissingInputs, std::list<CTransactionRef>* plTxnReplaced = nullptr, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0); /** Convert CValidationState to a human-readable message for logging */ @@ -346,7 +346,7 @@ bool TestLockPointValidity(const LockPoints* lp); * * See consensus/consensus.h for flag definitions. */ -bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp = NULL, bool useExistingLockPoints = false); +bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp = nullptr, bool useExistingLockPoints = false); /** * Closure representing one script verification @@ -365,7 +365,7 @@ private: PrecomputedTransactionData *txdata; public: - CScriptCheck(): amount(0), ptxTo(0), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {} + CScriptCheck(): amount(0), ptxTo(nullptr), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {} CScriptCheck(const CScript& scriptPubKeyIn, const CAmount amountIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn, PrecomputedTransactionData* txdataIn) : scriptPubKey(scriptPubKeyIn), amount(amountIn), ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR), txdata(txdataIn) { } diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index bf20d606f8..be5029dec3 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -30,7 +30,7 @@ struct MainSignalsInstance { // our own queue here :( SingleThreadedSchedulerClient m_schedulerClient; - MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {} + explicit MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {} }; static CMainSignals g_signals; diff --git a/src/versionbits.cpp b/src/versionbits.cpp index 8047e17aa8..64ae939672 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -28,14 +28,14 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* int64_t nTimeTimeout = EndTime(params); // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1. - if (pindexPrev != NULL) { + if (pindexPrev != nullptr) { pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod)); } // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known std::vector<const CBlockIndex*> vToCompute; while (cache.count(pindexPrev) == 0) { - if (pindexPrev == NULL) { + if (pindexPrev == nullptr) { // The genesis block is by definition defined. cache[pindexPrev] = THRESHOLD_DEFINED; break; @@ -107,12 +107,12 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* // return the numerical statistics of blocks signalling the specified BIP9 condition in this current period BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params) const { - BIP9Stats stats; + BIP9Stats stats = {}; stats.period = Period(params); stats.threshold = Threshold(params); - if (pindex == NULL) + if (pindex == nullptr) return stats; // Find beginning of period @@ -150,12 +150,12 @@ int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex* // right now pindexPrev points to the block prior to the block that we are computing for, thus: // if we are computing for the last block of a period, then pindexPrev points to the second to last block of the period, and // if we are computing for the first block of a period, then pindexPrev points to the last block of the previous period. - // The parent of the genesis block is represented by NULL. + // The parent of the genesis block is represented by nullptr. pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod)); const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod); - while (previousPeriodParent != NULL && GetStateFor(previousPeriodParent, params, cache) == initialState) { + while (previousPeriodParent != nullptr && GetStateFor(previousPeriodParent, params, cache) == initialState) { pindexPrev = previousPeriodParent; previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod); } @@ -185,7 +185,7 @@ protected: } public: - VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {} + explicit VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {} uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; } }; diff --git a/src/versionbits.h b/src/versionbits.h index f4dfb71515..71dc0c8500 100644 --- a/src/versionbits.h +++ b/src/versionbits.h @@ -27,7 +27,7 @@ enum ThresholdState { // A map that gives the state for blocks whose height is a multiple of Period(). // The map is indexed by the block's parent, however, so all keys in the map -// will either be NULL or a block with (height + 1) % Period() == 0. +// will either be nullptr or a block with (height + 1) % Period() == 0. typedef std::map<const CBlockIndex*, ThresholdState> ThresholdConditionCache; struct VBDeploymentInfo { diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index 1dc44e424f..f1e8a25650 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -113,7 +113,6 @@ public: class CCryptoKeyStore : public CBasicKeyStore { private: - CryptedKeyMap mapCryptedKeys; CKeyingMaterial vMasterKey; @@ -131,6 +130,7 @@ protected: bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); bool Unlock(const CKeyingMaterial& vMasterKeyIn); + CryptedKeyMap mapCryptedKeys; public: CCryptoKeyStore() : fUseCrypto(false), fDecryptionThoroughlyChecked(false) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index da2d180756..d2fe4866fa 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -47,7 +47,7 @@ void CDBEnv::Reset() fMockDb = false; } -CDBEnv::CDBEnv() : dbenv(NULL) +CDBEnv::CDBEnv() : dbenv(nullptr) { Reset(); } @@ -56,7 +56,7 @@ CDBEnv::~CDBEnv() { EnvShutdown(); delete dbenv; - dbenv = NULL; + dbenv = nullptr; } void CDBEnv::Close() @@ -78,7 +78,7 @@ bool CDBEnv::Open(const fs::path& pathIn) LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); unsigned int nEnvFlags = 0; - if (GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB)) + if (gArgs.GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB)) nEnvFlags |= DB_PRIVATE; dbenv->set_lg_dir(pathLogDir.string().c_str()); @@ -101,8 +101,10 @@ bool CDBEnv::Open(const fs::path& pathIn) DB_RECOVER | nEnvFlags, S_IRUSR | S_IWUSR); - if (ret != 0) + if (ret != 0) { + dbenv->close(0); return error("CDBEnv::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret)); + } fDbEnvInit = true; fMockDb = false; @@ -125,7 +127,7 @@ void CDBEnv::MakeMock() dbenv->set_lk_max_objects(10000); dbenv->set_flags(DB_AUTO_COMMIT, 1); dbenv->log_set_config(DB_LOG_IN_MEMORY, 1); - int ret = dbenv->open(NULL, + int ret = dbenv->open(nullptr, DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | @@ -147,10 +149,10 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type assert(mapFileUseCount.count(strFile) == 0); Db db(dbenv, 0); - int result = db.verify(strFile.c_str(), NULL, NULL, 0); + int result = db.verify(strFile.c_str(), nullptr, nullptr, 0); if (result == 0) return VERIFY_OK; - else if (recoverFunc == NULL) + else if (recoverFunc == nullptr) return RECOVER_FAIL; // Try to recover: @@ -170,7 +172,7 @@ bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*reco int64_t now = GetTime(); newFilename = strprintf("%s.%d.bak", filename, now); - int result = bitdb.dbenv->dbrename(NULL, filename.c_str(), NULL, + int result = bitdb.dbenv->dbrename(nullptr, filename.c_str(), nullptr, newFilename.c_str(), DB_AUTO_COMMIT); if (result == 0) LogPrintf("Renamed %s to %s\n", filename, newFilename); @@ -190,15 +192,15 @@ bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*reco LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size()); std::unique_ptr<Db> pdbCopy(new Db(bitdb.dbenv, 0)); - int ret = pdbCopy->open(NULL, // Txn pointer + int ret = pdbCopy->open(nullptr, // Txn pointer filename.c_str(), // Filename "main", // Logical db name DB_BTREE, // Database type DB_CREATE, // Flags 0); - if (ret > 0) - { + if (ret > 0) { LogPrintf("Cannot create database file %s\n", filename); + pdbCopy->close(0); return false; } @@ -299,7 +301,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C std::stringstream strDump; Db db(dbenv, 0); - int result = db.verify(strFile.c_str(), NULL, &strDump, flags); + int result = db.verify(strFile.c_str(), nullptr, &strDump, flags); if (result == DB_VERIFY_BAD) { LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.\n"); if (!fAggressive) { @@ -357,7 +359,7 @@ void CDBEnv::CheckpointLSN(const std::string& strFile) } -CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb(NULL), activeTxn(NULL) +CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr) { fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); fFlushOnClose = fFlushOnCloseIn; @@ -367,7 +369,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb } const std::string &strFilename = dbw.strFile; - bool fCreate = strchr(pszMode, 'c') != NULL; + bool fCreate = strchr(pszMode, 'c') != nullptr; unsigned int nFlags = DB_THREAD; if (fCreate) nFlags |= DB_CREATE; @@ -380,7 +382,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb strFile = strFilename; ++env->mapFileUseCount[strFile]; pdb = env->mapDb[strFile]; - if (pdb == NULL) { + if (pdb == nullptr) { int ret; pdb = new Db(env->dbenv, 0); @@ -392,8 +394,8 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb throw std::runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFile)); } - ret = pdb->open(NULL, // Txn pointer - fMockDb ? NULL : strFile.c_str(), // Filename + ret = pdb->open(nullptr, // Txn pointer + fMockDb ? nullptr : strFile.c_str(), // Filename fMockDb ? strFile.c_str() : "main", // Logical db name DB_BTREE, // Database type nFlags, // Flags @@ -401,7 +403,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb if (ret != 0) { delete pdb; - pdb = NULL; + pdb = nullptr; --env->mapFileUseCount[strFile]; strFile = ""; throw std::runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename)); @@ -429,7 +431,7 @@ void CDB::Flush() if (fReadOnly) nMinutes = 1; - env->dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0); + env->dbenv->txn_checkpoint(nMinutes ? gArgs.GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0); } void CWalletDBWrapper::IncrementUpdateCounter() @@ -443,8 +445,8 @@ void CDB::Close() return; if (activeTxn) activeTxn->abort(); - activeTxn = NULL; - pdb = NULL; + activeTxn = nullptr; + pdb = nullptr; if (fFlushOnClose) Flush(); @@ -459,12 +461,12 @@ void CDBEnv::CloseDb(const std::string& strFile) { { LOCK(cs_db); - if (mapDb[strFile] != NULL) { + if (mapDb[strFile] != nullptr) { // Close the database handle Db* pdb = mapDb[strFile]; pdb->close(0); delete pdb; - mapDb[strFile] = NULL; + mapDb[strFile] = nullptr; } } } @@ -492,7 +494,7 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip) CDB db(dbw, "r"); Db* pdbCopy = new Db(env->dbenv, 0); - int ret = pdbCopy->open(NULL, // Txn pointer + int ret = pdbCopy->open(nullptr, // Txn pointer strFileRes.c_str(), // Filename "main", // Logical db name DB_BTREE, // Database type @@ -527,7 +529,7 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip) } Dbt datKey(ssKey.data(), ssKey.size()); Dbt datValue(ssValue.data(), ssValue.size()); - int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE); + int ret2 = pdbCopy->put(nullptr, &datKey, &datValue, DB_NOOVERWRITE); if (ret2 > 0) fSuccess = false; } @@ -536,15 +538,17 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip) env->CloseDb(strFile); if (pdbCopy->close(0)) fSuccess = false; - delete pdbCopy; + } else { + pdbCopy->close(0); } + delete pdbCopy; } if (fSuccess) { Db dbA(env->dbenv, 0); - if (dbA.remove(strFile.c_str(), NULL, 0)) + if (dbA.remove(strFile.c_str(), nullptr, 0)) fSuccess = false; Db dbB(env->dbenv, 0); - if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0)) + if (dbB.rename(strFileRes.c_str(), nullptr, strFile.c_str(), 0)) fSuccess = false; } if (!fSuccess) diff --git a/src/wallet/db.h b/src/wallet/db.h index 4f3ad0c42d..6f3cfe9557 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -45,7 +45,7 @@ public: void Reset(); void MakeMock(); - bool IsMock() { return fMockDb; } + bool IsMock() const { return fMockDb; } /** * Verify that database file strFile is OK. If it is not, @@ -77,10 +77,10 @@ public: DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC) { - DbTxn* ptxn = NULL; - int ret = dbenv->txn_begin(NULL, &ptxn, flags); + DbTxn* ptxn = nullptr; + int ret = dbenv->txn_begin(nullptr, &ptxn, flags); if (!ptxn || ret != 0) - return NULL; + return nullptr; return ptxn; } }; @@ -191,7 +191,7 @@ public: int ret = pdb->get(activeTxn, &datKey, &datValue, 0); memory_cleanse(datKey.get_data(), datKey.get_size()); bool success = false; - if (datValue.get_data() != NULL) { + if (datValue.get_data() != nullptr) { // Unserialize value try { CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); @@ -282,11 +282,11 @@ public: Dbc* GetCursor() { if (!pdb) - return NULL; - Dbc* pcursor = NULL; - int ret = pdb->cursor(NULL, &pcursor, 0); + return nullptr; + Dbc* pcursor = nullptr; + int ret = pdb->cursor(nullptr, &pcursor, 0); if (ret != 0) - return NULL; + return nullptr; return pcursor; } @@ -306,7 +306,7 @@ public: int ret = pcursor->get(&datKey, &datValue, fFlags); if (ret != 0) return ret; - else if (datKey.get_data() == NULL || datValue.get_data() == NULL) + else if (datKey.get_data() == nullptr || datValue.get_data() == nullptr) return 99999; // Convert to streams @@ -342,7 +342,7 @@ public: if (!pdb || !activeTxn) return false; int ret = activeTxn->commit(0); - activeTxn = NULL; + activeTxn = nullptr; return (ret == 0); } @@ -351,7 +351,7 @@ public: if (!pdb || !activeTxn) return false; int ret = activeTxn->abort(); - activeTxn = NULL; + activeTxn = nullptr; return (ret == 0); } @@ -366,7 +366,7 @@ public: return Write(std::string("version"), nVersion); } - bool static Rewrite(CWalletDBWrapper& dbw, const char* pszSkip = NULL); + bool static Rewrite(CWalletDBWrapper& dbw, const char* pszSkip = nullptr); }; #endif // BITCOIN_WALLET_DB_H diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index 4bfd8726a5..4c0e3a5fe1 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -76,12 +76,12 @@ CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, const CCoin vErrors.clear(); bumpedTxid.SetNull(); AssertLockHeld(pWallet->cs_wallet); - if (!pWallet->mapWallet.count(txid)) { + auto it = pWallet->mapWallet.find(txid); + if (it == pWallet->mapWallet.end()) { vErrors.push_back("Invalid or non-wallet transaction id"); currentResult = BumpFeeResult::INVALID_ADDRESS_OR_KEY; return; } - auto it = pWallet->mapWallet.find(txid); const CWalletTx& wtx = it->second; if (!preconditionChecks(pWallet, wtx)) { @@ -193,7 +193,7 @@ CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, const CCoin // This may occur if the user set TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps, // in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a // moment earlier. In this case, we report an error to the user, who may use totalFee to make an adjustment. - CFeeRate minMempoolFeeRate = mempool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); + CFeeRate minMempoolFeeRate = mempool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); if (nNewFeeRate.GetFeePerK() < minMempoolFeeRate.GetFeePerK()) { vErrors.push_back(strprintf("New fee rate (%s) is less than the minimum fee rate (%s) to get into the mempool. totalFee value should to be at least %s or settxfee value should be at least %s to add transaction.", FormatMoney(nNewFeeRate.GetFeePerK()), FormatMoney(minMempoolFeeRate.GetFeePerK()), FormatMoney(minMempoolFeeRate.GetFee(maxNewTxSize)), FormatMoney(minMempoolFeeRate.GetFeePerK()))); currentResult = BumpFeeResult::WALLET_ERROR; @@ -241,12 +241,13 @@ bool CFeeBumper::commit(CWallet *pWallet) if (!vErrors.empty() || currentResult != BumpFeeResult::OK) { return false; } - if (txid.IsNull() || !pWallet->mapWallet.count(txid)) { + auto it = txid.IsNull() ? pWallet->mapWallet.end() : pWallet->mapWallet.find(txid); + if (it == pWallet->mapWallet.end()) { vErrors.push_back("Invalid or non-wallet transaction id"); currentResult = BumpFeeResult::MISC_ERROR; return false; } - CWalletTx& oldWtx = pWallet->mapWallet[txid]; + CWalletTx& oldWtx = it->second; // make sure the transaction still has no descendants and hasn't been mined in the meantime if (!preconditionChecks(pWallet, oldWtx)) { diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 5abf32480a..67c6d9ec64 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -619,9 +619,8 @@ UniValue dumpwallet(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); std::map<CTxDestination, int64_t> mapKeyBirth; - std::set<CKeyID> setKeyPool; + const std::map<CKeyID, int64_t>& mapKeyPool = pwallet->GetAllReserveKeys(); pwallet->GetKeyBirthTimes(mapKeyBirth); - pwallet->GetAllReserveKeys(setKeyPool); // sort time/key pairs std::vector<std::pair<int64_t, CKeyID> > vKeyBirth; @@ -666,7 +665,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) file << strprintf("label=%s", EncodeDumpString(pwallet->mapAddressBook[keyid].name)); } else if (keyid == masterKeyID) { file << "hdmaster=1"; - } else if (setKeyPool.count(keyid)) { + } else if (mapKeyPool.count(keyid)) { file << "reserve=1"; } else if (pwallet->mapKeyMetadata[keyid].hdKeypath == "m") { file << "inactivehdmaster=1"; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 27f84bfb7c..3fd8879ed4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1123,7 +1123,7 @@ public: CWallet * const pwallet; CScriptID result; - Witnessifier(CWallet *_pwallet) : pwallet(_pwallet) {} + explicit Witnessifier(CWallet *_pwallet) : pwallet(_pwallet) {} bool operator()(const CNoDestination &dest) const { return false; } @@ -1134,7 +1134,7 @@ public: SignatureData sigs; // This check is to make sure that the script we created can actually be solved for and signed by us // if we were to have the private keys. This is just to make sure that the script is valid and that, - // if found in a transaction, we would still accept and relay that transcation. + // if found in a transaction, we would still accept and relay that transaction. if (!ProduceSignature(DummySignatureCreator(pwallet), witscript, sigs) || !VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) { return false; @@ -1159,7 +1159,7 @@ public: SignatureData sigs; // This check is to make sure that the script we created can actually be solved for and signed by us // if we were to have the private keys. This is just to make sure that the script is valid and that, - // if found in a transaction, we would still accept and relay that transcation. + // if found in a transaction, we would still accept and relay that transaction. if (!ProduceSignature(DummySignatureCreator(pwallet), witscript, sigs) || !VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) { return false; @@ -1197,7 +1197,7 @@ UniValue addwitnessaddress(const JSONRPCRequest& request) { LOCK(cs_main); - if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()) && !GetBoolArg("-walletprematurewitness", false)) { + if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()) && !gArgs.GetBoolArg("-walletprematurewitness", false)) { throw JSONRPCError(RPC_WALLET_ERROR, "Segregated witness not enabled on network"); } } @@ -1644,10 +1644,10 @@ UniValue listtransactions(const JSONRPCRequest& request) for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { CWalletTx *const pwtx = (*it).second.first; - if (pwtx != 0) + if (pwtx != nullptr) ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter); CAccountingEntry *const pacentry = (*it).second.second; - if (pacentry != 0) + if (pacentry != nullptr) AcentryToJSON(*pacentry, strAccount, ret); if ((int)ret.size() >= (nCount+nFrom)) break; @@ -1818,8 +1818,8 @@ UniValue listsinceblock(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); - const CBlockIndex* pindex = NULL; // Block index of the specified block or the common ancestor, if the block provided was in a deactivated chain. - const CBlockIndex* paltindex = NULL; // Block index of the specified block, even if it's in a deactivated chain. + const CBlockIndex* pindex = nullptr; // Block index of the specified block or the common ancestor, if the block provided was in a deactivated chain. + const CBlockIndex* paltindex = nullptr; // Block index of the specified block, even if it's in a deactivated chain. int target_confirms = 1; isminefilter filter = ISMINE_SPENDABLE; @@ -1874,10 +1874,11 @@ UniValue listsinceblock(const JSONRPCRequest& request) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); } for (const CTransactionRef& tx : block.vtx) { - if (pwallet->mapWallet.count(tx->GetHash()) > 0) { + auto it = pwallet->mapWallet.find(tx->GetHash()); + if (it != pwallet->mapWallet.end()) { // We want all transactions regardless of confirmation count to appear here, // even negative confirmation ones, hence the big negative. - ListTransactions(pwallet, pwallet->mapWallet[tx->GetHash()], "*", -100000000, true, removed, filter); + ListTransactions(pwallet, it->second, "*", -100000000, true, removed, filter); } } paltindex = paltindex->pprev; @@ -1957,10 +1958,11 @@ UniValue gettransaction(const JSONRPCRequest& request) filter = filter | ISMINE_WATCH_ONLY; UniValue entry(UniValue::VOBJ); - if (!pwallet->mapWallet.count(hash)) { + auto it = pwallet->mapWallet.find(hash); + if (it == pwallet->mapWallet.end()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); } - const CWalletTx& wtx = pwallet->mapWallet[hash]; + const CWalletTx& wtx = it->second; CAmount nCredit = wtx.GetCredit(filter); CAmount nDebit = wtx.GetDebit(filter); @@ -2599,7 +2601,7 @@ UniValue resendwallettransactions(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); if (!pwallet->GetBroadcastTransactions()) { - throw JSONRPCError(RPC_INVALID_REQUEST, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast"); + throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast"); } std::vector<uint256> txids = pwallet->ResendWalletTransactionsBefore(GetTime(), g_connman.get()); @@ -2725,10 +2727,10 @@ UniValue listunspent(const JSONRPCRequest& request) UniValue results(UniValue::VARR); std::vector<COutput> vecOutputs; - assert(pwallet != NULL); + assert(pwallet != nullptr); LOCK2(cs_main, pwallet->cs_wallet); - pwallet->AvailableCoins(vecOutputs, !include_unsafe, NULL, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth); + pwallet->AvailableCoins(vecOutputs, !include_unsafe, nullptr, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth); for (const COutput& out : vecOutputs) { CTxDestination address; const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey; @@ -3202,7 +3204,7 @@ static const CRPCCommand commands[] = void RegisterWalletRPCCommands(CRPCTable &t) { - if (GetBoolArg("-disablewallet", false)) + if (gArgs.GetBoolArg("-disablewallet", false)) return; for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index 31e2f6a699..db0808b93b 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -14,7 +14,7 @@ void RegisterWalletRPCCommands(CRPCTable &t); * Figures out what wallet, if any, to use for a JSONRPCRequest. * * @param[in] request JSONRPCRequest that wishes to access a wallet - * @return NULL if no wallet should be used, or a pointer to the CWallet + * @return nullptr if no wallet should be used, or a pointer to the CWallet */ CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request); diff --git a/src/wallet/test/crypto_tests.cpp b/src/wallet/test/crypto_tests.cpp index 744063624c..98d957b322 100644 --- a/src/wallet/test/crypto_tests.cpp +++ b/src/wallet/test/crypto_tests.cpp @@ -48,7 +48,7 @@ bool OldEncrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> bool fOk = true; EVP_CIPHER_CTX_init(ctx); - if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; + if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, chKey, chIV) != 0; if (fOk) fOk = EVP_EncryptUpdate(ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0; if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0; EVP_CIPHER_CTX_cleanup(ctx); @@ -76,7 +76,7 @@ bool OldDecrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial bool fOk = true; EVP_CIPHER_CTX_init(ctx); - if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; + if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, chKey, chIV) != 0; if (fOk) fOk = EVP_DecryptUpdate(ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0; if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0; EVP_CIPHER_CTX_cleanup(ctx); diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index 922fcc8e89..e2f48c45ab 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -28,7 +28,7 @@ WalletTestingSetup::~WalletTestingSetup() { UnregisterValidationInterface(pwalletMain); delete pwalletMain; - pwalletMain = NULL; + pwalletMain = nullptr; bitdb.Flush(true); bitdb.Reset(); diff --git a/src/wallet/test/wallet_test_fixture.h b/src/wallet/test/wallet_test_fixture.h index 97a6d98397..9373b7907c 100644 --- a/src/wallet/test/wallet_test_fixture.h +++ b/src/wallet/test/wallet_test_fixture.h @@ -10,7 +10,7 @@ /** Testing setup and teardown for wallet. */ struct WalletTestingSetup: public TestingSetup { - WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); + explicit WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~WalletTestingSetup(); }; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 18cc3bd028..c32726aeb0 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -12,6 +12,7 @@ #include "consensus/consensus.h" #include "consensus/validation.h" #include "fs.h" +#include "init.h" #include "key.h" #include "keystore.h" #include "validation.h" @@ -80,12 +81,44 @@ std::string COutput::ToString() const return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->tx->vout[i].nValue)); } +class CAffectedKeysVisitor : public boost::static_visitor<void> { +private: + const CKeyStore &keystore; + std::vector<CKeyID> &vKeys; + +public: + CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {} + + void Process(const CScript &script) { + txnouttype type; + std::vector<CTxDestination> vDest; + int nRequired; + if (ExtractDestinations(script, type, vDest, nRequired)) { + for (const CTxDestination &dest : vDest) + boost::apply_visitor(*this, dest); + } + } + + void operator()(const CKeyID &keyId) { + if (keystore.HaveKey(keyId)) + vKeys.push_back(keyId); + } + + void operator()(const CScriptID &scriptId) { + CScript script; + if (keystore.GetCScript(scriptId, script)) + Process(script); + } + + void operator()(const CNoDestination &none) {} +}; + const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const { LOCK(cs_wallet); std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash); if (it == mapWallet.end()) - return NULL; + return nullptr; return &(it->second); } @@ -182,10 +215,10 @@ bool CWallet::AddKeyPubKeyWithDB(CWalletDB &walletdb, const CKey& secret, const pwalletdbEncryption = &walletdb; } if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) { - if (needsDB) pwalletdbEncryption = NULL; + if (needsDB) pwalletdbEncryption = nullptr; return false; } - if (needsDB) pwalletdbEncryption = NULL; + if (needsDB) pwalletdbEncryption = nullptr; // check if we need to remove from watch-only CScript script; @@ -463,7 +496,7 @@ void CWallet::Flush(bool shutdown) bool CWallet::Verify() { - if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) + if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return true; uiInterface.InitMessage(_("Verifying wallet(s)...")); @@ -495,7 +528,7 @@ bool CWallet::Verify() return InitError(strError); } - if (GetBoolArg("-salvagewallet", false)) { + if (gArgs.GetBoolArg("-salvagewallet", false)) { // Recover readable keypairs: CWallet dummyWallet; std::string backup_filename; @@ -525,7 +558,7 @@ void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> ran // So: find smallest nOrderPos: int nMinOrderPos = std::numeric_limits<int>::max(); - const CWalletTx* copyFrom = NULL; + const CWalletTx* copyFrom = nullptr; for (TxSpends::iterator it = range.first; it != range.second; ++it) { const uint256& hash = it->second; @@ -590,8 +623,9 @@ void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid) void CWallet::AddToSpends(const uint256& wtxid) { - assert(mapWallet.count(wtxid)); - CWalletTx& thisTx = mapWallet[wtxid]; + auto it = mapWallet.find(wtxid); + assert(it != mapWallet.end()); + CWalletTx& thisTx = it->second; if (thisTx.IsCoinBase()) // Coinbases don't spend anything! return; @@ -640,7 +674,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) pwalletdbEncryption = new CWalletDB(*dbw); if (!pwalletdbEncryption->TxnBegin()) { delete pwalletdbEncryption; - pwalletdbEncryption = NULL; + pwalletdbEncryption = nullptr; return false; } pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); @@ -665,7 +699,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) } delete pwalletdbEncryption; - pwalletdbEncryption = NULL; + pwalletdbEncryption = nullptr; Lock(); Unlock(strWalletPassphrase); @@ -706,13 +740,13 @@ DBErrors CWallet::ReorderTransactions() for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { CWalletTx* wtx = &((*it).second); - txByTime.insert(std::make_pair(wtx->nTimeReceived, TxPair(wtx, (CAccountingEntry*)0))); + txByTime.insert(std::make_pair(wtx->nTimeReceived, TxPair(wtx, nullptr))); } std::list<CAccountingEntry> acentries; walletdb.ListAccountCreditDebit("", acentries); for (CAccountingEntry& entry : acentries) { - txByTime.insert(std::make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry))); + txByTime.insert(std::make_pair(entry.nTime, TxPair(nullptr, &entry))); } nOrderPosNext = 0; @@ -721,7 +755,7 @@ DBErrors CWallet::ReorderTransactions() { CWalletTx *const pwtx = (*it).second.first; CAccountingEntry *const pacentry = (*it).second.second; - int64_t& nOrderPos = (pwtx != 0) ? pwtx->nOrderPos : pacentry->nOrderPos; + int64_t& nOrderPos = (pwtx != nullptr) ? pwtx->nOrderPos : pacentry->nOrderPos; if (nOrderPos == -1) { @@ -906,7 +940,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) { wtx.nTimeReceived = GetAdjustedTime(); wtx.nOrderPos = IncOrderPosNext(&walletdb); - wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0))); + wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, nullptr))); wtx.nTimeSmart = ComputeTimeSmart(wtx); AddToSpends(hash); } @@ -953,7 +987,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED); // notify an external script when a wallet transaction comes in or is updated - std::string strCmd = GetArg("-walletnotify", ""); + std::string strCmd = gArgs.GetArg("-walletnotify", ""); if ( !strCmd.empty()) { @@ -971,11 +1005,12 @@ bool CWallet::LoadToWallet(const CWalletTx& wtxIn) mapWallet[hash] = wtxIn; CWalletTx& wtx = mapWallet[hash]; wtx.BindWallet(this); - wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0))); + wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, nullptr))); AddToSpends(hash); for (const CTxIn& txin : wtx.tx->vin) { - if (mapWallet.count(txin.prevout.hash)) { - CWalletTx& prevtx = mapWallet[txin.prevout.hash]; + auto it = mapWallet.find(txin.prevout.hash); + if (it != mapWallet.end()) { + CWalletTx& prevtx = it->second; if (prevtx.nIndex == -1 && !prevtx.hashUnset()) { MarkConflicted(prevtx.hashBlock, wtx.GetHash()); } @@ -988,7 +1023,7 @@ bool CWallet::LoadToWallet(const CWalletTx& wtxIn) /** * Add a transaction to the wallet, or update it. pIndex and posInBlock should * be set when the transaction was known to be included in a block. When - * pIndex == NULL, then wallet state is not updated in AddToWallet, but + * pIndex == nullptr, then wallet state is not updated in AddToWallet, but * notifications happen and cached balances are marked dirty. * * If fUpdate is true, existing transactions will be updated. @@ -1004,7 +1039,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const CBlockI { AssertLockHeld(cs_wallet); - if (pIndex != NULL) { + if (pIndex != nullptr) { for (const CTxIn& txin : tx.vin) { std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.prevout); while (range.first != range.second) { @@ -1021,10 +1056,34 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const CBlockI if (fExisted && !fUpdate) return false; if (fExisted || IsMine(tx) || IsFromMe(tx)) { + /* Check if any keys in the wallet keypool that were supposed to be unused + * have appeared in a new transaction. If so, remove those keys from the keypool. + * This can happen when restoring an old wallet backup that does not contain + * the mostly recently created transactions from newer versions of the wallet. + */ + + // loop though all outputs + for (const CTxOut& txout: tx.vout) { + // extract addresses and check if they match with an unused keypool key + std::vector<CKeyID> vAffected; + CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey); + for (const CKeyID &keyid : vAffected) { + std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid); + if (mi != m_pool_key_to_index.end()) { + LogPrintf("%s: Detected a used keypool key, mark all keypool key up to this key as used\n", __func__); + MarkReserveKeysAsUsed(mi->second); + + if (!TopUpKeyPool()) { + LogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__); + } + } + } + } + CWalletTx wtx(this, ptx); // Get merkle branch if transaction was found in a block - if (pIndex != NULL) + if (pIndex != nullptr) wtx.SetMerkleBranch(pIndex, posInBlock); return AddToWallet(wtx, false); @@ -1050,8 +1109,9 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) std::set<uint256> done; // Can't mark abandoned if confirmed or in mempool - assert(mapWallet.count(hashTx)); - CWalletTx& origtx = mapWallet[hashTx]; + auto it = mapWallet.find(hashTx); + assert(it != mapWallet.end()); + CWalletTx& origtx = it->second; if (origtx.GetDepthInMainChain() > 0 || origtx.InMempool()) { return false; } @@ -1062,8 +1122,9 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) uint256 now = *todo.begin(); todo.erase(now); done.insert(now); - assert(mapWallet.count(now)); - CWalletTx& wtx = mapWallet[now]; + auto it = mapWallet.find(now); + assert(it != mapWallet.end()); + CWalletTx& wtx = it->second; int currentconfirm = wtx.GetDepthInMainChain(); // If the orig tx was not in block, none of its spends can be assert(currentconfirm <= 0); @@ -1088,8 +1149,10 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) // available of the outputs it spends. So force those to be recomputed for (const CTxIn& txin : wtx.tx->vin) { - if (mapWallet.count(txin.prevout.hash)) - mapWallet[txin.prevout.hash].MarkDirty(); + auto it = mapWallet.find(txin.prevout.hash); + if (it != mapWallet.end()) { + it->second.MarkDirty(); + } } } } @@ -1127,8 +1190,9 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) uint256 now = *todo.begin(); todo.erase(now); done.insert(now); - assert(mapWallet.count(now)); - CWalletTx& wtx = mapWallet[now]; + auto it = mapWallet.find(now); + assert(it != mapWallet.end()); + CWalletTx& wtx = it->second; int currentconfirm = wtx.GetDepthInMainChain(); if (conflictconfirms < currentconfirm) { // Block is 'more conflicted' than current confirm; update. @@ -1147,10 +1211,11 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) } // If a transaction changes 'conflicted' state, that changes the balance // available of the outputs it spends. So force those to be recomputed - for (const CTxIn& txin : wtx.tx->vin) - { - if (mapWallet.count(txin.prevout.hash)) - mapWallet[txin.prevout.hash].MarkDirty(); + for (const CTxIn& txin : wtx.tx->vin) { + auto it = mapWallet.find(txin.prevout.hash); + if (it != mapWallet.end()) { + it->second.MarkDirty(); + } } } } @@ -1165,10 +1230,11 @@ void CWallet::SyncTransaction(const CTransactionRef& ptx, const CBlockIndex *pin // If a transaction changes 'conflicted' state, that changes the balance // available of the outputs it spends. So force those to be // recomputed, also: - for (const CTxIn& txin : tx.vin) - { - if (mapWallet.count(txin.prevout.hash)) - mapWallet[txin.prevout.hash].MarkDirty(); + for (const CTxIn& txin : tx.vin) { + auto it = mapWallet.find(txin.prevout.hash); + if (it != mapWallet.end()) { + it->second.MarkDirty(); + } } } @@ -1648,7 +1714,7 @@ bool CWalletTx::RelayWalletTransaction(CConnman* connman) std::set<uint256> CWalletTx::GetConflicts() const { std::set<uint256> result; - if (pwallet != NULL) + if (pwallet != nullptr) { uint256 myHash = GetHash(); result = pwallet->GetConflicts(myHash); @@ -1737,7 +1803,7 @@ CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const { - if (pwallet == 0) + if (pwallet == nullptr) return 0; // Must wait until coinbase is safely deep enough in the chain before valuing it @@ -1781,7 +1847,7 @@ CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const { - if (pwallet == 0) + if (pwallet == nullptr) return 0; // Must wait until coinbase is safely deep enough in the chain before valuing it @@ -1845,7 +1911,7 @@ bool CWalletTx::IsTrusted() const { // Transactions not sent by us: not trusted const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash); - if (parent == NULL) + if (parent == nullptr) return false; const CTxOut& parentOut = parent->tx->vout[txin.prevout.n]; if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE) @@ -2444,8 +2510,8 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm ++it; } - size_t nMaxChainLength = std::min(GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT), GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)); - bool fRejectLongChains = GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS); + size_t nMaxChainLength = std::min(gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT), gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)); + bool fRejectLongChains = gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS); bool res = nTargetValue <= nValueFromPresetInputs || SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, 0, vCoins, setCoinsRet, nValueRet) || @@ -2514,7 +2580,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC if (nChangePosInOut != -1) { tx.vout.insert(tx.vout.begin() + nChangePosInOut, wtx.tx->vout[nChangePosInOut]); - // we dont have the normal Create/Commit cycle, and dont want to risk reusing change, + // we don't have the normal Create/Commit cycle, and don't want to risk reusing change, // so just remove the key from the keypool here. reservekey.KeepKey(); } @@ -2880,15 +2946,15 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT } } - if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) { + if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) { // Lastly, ensure this tx will pass the mempool's chain limits LockPoints lp; CTxMemPoolEntry entry(wtxNew.tx, 0, 0, 0, false, 0, lp); CTxMemPool::setEntries setAncestors; - size_t nLimitAncestors = GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); - size_t nLimitAncestorSize = GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000; - size_t nLimitDescendants = GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT); - size_t nLimitDescendantSize = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000; + size_t nLimitAncestors = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); + size_t nLimitAncestorSize = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000; + size_t nLimitDescendants = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT); + size_t nLimitDescendantSize = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000; std::string errString; if (!mempool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) { strFailReason = _("Transaction has too long of a mempool chain"); @@ -2969,7 +3035,7 @@ bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, CWalletDB *pwa laccentries.push_back(acentry); CAccountingEntry & entry = laccentries.back(); - wtxOrdered.insert(std::make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry))); + wtxOrdered.insert(std::make_pair(entry.nOrderPos, TxPair(nullptr, &entry))); return true; } @@ -3015,7 +3081,7 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_c if (feeCalc) feeCalc->reason = FeeReason::FALLBACK; } // Obey mempool min fee when using smart fee estimation - CAmount min_mempool_fee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nTxBytes); + CAmount min_mempool_fee = pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nTxBytes); if (fee_needed < min_mempool_fee) { fee_needed = min_mempool_fee; if (feeCalc) feeCalc->reason = FeeReason::MEMPOOL_MIN; @@ -3050,15 +3116,18 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet) LOCK(cs_wallet); setInternalKeyPool.clear(); setExternalKeyPool.clear(); + m_pool_key_to_index.clear(); // Note: can't top-up keypool here, because wallet is locked. // User will be prompted to unlock wallet the next operation // that requires a new key. } } + // This wallet is in its first run if all of these are empty + fFirstRunRet = mapKeys.empty() && mapCryptedKeys.empty() && mapWatchKeys.empty() && setWatchOnly.empty() && mapScripts.empty(); + if (nLoadWalletRet != DB_LOAD_OK) return nLoadWalletRet; - fFirstRunRet = !vchDefaultKey.IsValid(); uiInterface.LoadWallet(this); @@ -3068,7 +3137,6 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet) DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut) { AssertLockHeld(cs_wallet); // mapWallet - vchDefaultKey = CPubKey(); DBErrors nZapSelectTxRet = CWalletDB(*dbw,"cr+").ZapSelectTx(vHashIn, vHashOut); for (uint256 hash : vHashOut) mapWallet.erase(hash); @@ -3079,6 +3147,7 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256 { setInternalKeyPool.clear(); setExternalKeyPool.clear(); + m_pool_key_to_index.clear(); // Note: can't top-up keypool here, because wallet is locked. // User will be prompted to unlock wallet the next operation // that requires a new key. @@ -3096,7 +3165,6 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256 DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx) { - vchDefaultKey = CPubKey(); DBErrors nZapWalletTxRet = CWalletDB(*dbw,"cr+").ZapWalletTx(vWtx); if (nZapWalletTxRet == DB_NEED_REWRITE) { @@ -3105,6 +3173,7 @@ DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx) LOCK(cs_wallet); setInternalKeyPool.clear(); setExternalKeyPool.clear(); + m_pool_key_to_index.clear(); // Note: can't top-up keypool here, because wallet is locked. // User will be prompted to unlock wallet the next operation // that requires a new key. @@ -3171,14 +3240,6 @@ const std::string& CWallet::GetAccountName(const CScript& scriptPubKey) const return DEFAULT_ACCOUNT_NAME; } -bool CWallet::SetDefaultKey(const CPubKey &vchPubKey) -{ - if (!CWalletDB(*dbw).WriteDefaultKey(vchPubKey)) - return false; - vchDefaultKey = vchPubKey; - return true; -} - /** * Mark old keypool keys as used, * and generate all new keys @@ -3199,6 +3260,8 @@ bool CWallet::NewKeyPool() } setExternalKeyPool.clear(); + m_pool_key_to_index.clear(); + if (!TopUpKeyPool()) { return false; } @@ -3213,6 +3276,25 @@ size_t CWallet::KeypoolCountExternalKeys() return setExternalKeyPool.size(); } +void CWallet::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool) +{ + AssertLockHeld(cs_wallet); + if (keypool.fInternal) { + setInternalKeyPool.insert(nIndex); + } else { + setExternalKeyPool.insert(nIndex); + } + m_max_keypool_index = std::max(m_max_keypool_index, nIndex); + m_pool_key_to_index[keypool.vchPubKey.GetID()] = nIndex; + + // If no metadata exists yet, create a default with the pool key's + // creation time. Note that this may be overwritten by actually + // stored metadata for that key later, which is fine. + CKeyID keyid = keypool.vchPubKey.GetID(); + if (mapKeyMetadata.count(keyid) == 0) + mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime); +} + bool CWallet::TopUpKeyPool(unsigned int kpSize) { { @@ -3226,7 +3308,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) if (kpSize > 0) nTargetSize = kpSize; else - nTargetSize = std::max(GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0); + nTargetSize = std::max(gArgs.GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0); // count amount of available keys (internal, external) // make sure the keypool of external and internal keys fits the user selected target (-keypool) @@ -3249,7 +3331,8 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys? int64_t index = ++m_max_keypool_index; - if (!walletdb.WritePool(index, CKeyPool(GenerateNewKey(walletdb, internal), internal))) { + CPubKey pubkey(GenerateNewKey(walletdb, internal)); + if (!walletdb.WritePool(index, CKeyPool(pubkey, internal))) { throw std::runtime_error(std::string(__func__) + ": writing generated key failed"); } @@ -3258,6 +3341,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) } else { setExternalKeyPool.insert(index); } + m_pool_key_to_index[pubkey.GetID()] = index; } if (missingInternal + missingExternal > 0) { LogPrintf("keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size(), setInternalKeyPool.size()); @@ -3299,6 +3383,7 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRe } assert(keypool.vchPubKey.IsValid()); + m_pool_key_to_index.erase(keypool.vchPubKey.GetID()); LogPrintf("keypool reserve %d\n", nIndex); } } @@ -3311,7 +3396,7 @@ void CWallet::KeepKey(int64_t nIndex) LogPrintf("keypool keep %d\n", nIndex); } -void CWallet::ReturnKey(int64_t nIndex, bool fInternal) +void CWallet::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey) { // Return to key pool { @@ -3321,6 +3406,7 @@ void CWallet::ReturnKey(int64_t nIndex, bool fInternal) } else { setExternalKeyPool.insert(nIndex); } + m_pool_key_to_index[pubkey.GetID()] = nIndex; } LogPrintf("keypool return %d\n", nIndex); } @@ -3550,38 +3636,32 @@ void CReserveKey::KeepKey() void CReserveKey::ReturnKey() { if (nIndex != -1) { - pwallet->ReturnKey(nIndex, fInternal); + pwallet->ReturnKey(nIndex, fInternal, vchPubKey); } nIndex = -1; vchPubKey = CPubKey(); } -static void LoadReserveKeysToSet(std::set<CKeyID>& setAddress, const std::set<int64_t>& setKeyPool, CWalletDB& walletdb) { - for (const int64_t& id : setKeyPool) - { - CKeyPool keypool; - if (!walletdb.ReadPool(id, keypool)) - throw std::runtime_error(std::string(__func__) + ": read failed"); - assert(keypool.vchPubKey.IsValid()); - CKeyID keyID = keypool.vchPubKey.GetID(); - setAddress.insert(keyID); - } -} - -void CWallet::GetAllReserveKeys(std::set<CKeyID>& setAddress) const +void CWallet::MarkReserveKeysAsUsed(int64_t keypool_id) { - setAddress.clear(); + AssertLockHeld(cs_wallet); + bool internal = setInternalKeyPool.count(keypool_id); + if (!internal) assert(setExternalKeyPool.count(keypool_id)); + std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : &setExternalKeyPool; + auto it = setKeyPool->begin(); CWalletDB walletdb(*dbw); + while (it != std::end(*setKeyPool)) { + const int64_t& index = *(it); + if (index > keypool_id) break; // set*KeyPool is ordered - LOCK2(cs_main, cs_wallet); - LoadReserveKeysToSet(setAddress, setInternalKeyPool, walletdb); - LoadReserveKeysToSet(setAddress, setExternalKeyPool, walletdb); - - for (const CKeyID& keyID : setAddress) { - if (!HaveKey(keyID)) { - throw std::runtime_error(std::string(__func__) + ": unknown key in key pool"); + CKeyPool keypool; + if (walletdb.ReadPool(index, keypool)) { //TODO: This should be unnecessary + m_pool_key_to_index.erase(keypool.vchPubKey.GetID()); } + walletdb.ErasePool(index); + LogPrintf("keypool index %d removed\n", index); + it = setKeyPool->erase(it); } } @@ -3634,38 +3714,6 @@ void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) const /** @} */ // end of Actions -class CAffectedKeysVisitor : public boost::static_visitor<void> { -private: - const CKeyStore &keystore; - std::vector<CKeyID> &vKeys; - -public: - CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {} - - void Process(const CScript &script) { - txnouttype type; - std::vector<CTxDestination> vDest; - int nRequired; - if (ExtractDestinations(script, type, vDest, nRequired)) { - for (const CTxDestination &dest : vDest) - boost::apply_visitor(*this, dest); - } - } - - void operator()(const CKeyID &keyId) { - if (keystore.HaveKey(keyId)) - vKeys.push_back(keyId); - } - - void operator()(const CScriptID &scriptId) { - CScript script; - if (keystore.GetCScript(scriptId, script)) - Process(script); - } - - void operator()(const CNoDestination &none) {} -}; - void CWallet::GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const { AssertLockHeld(cs_wallet); // mapKeyMetadata mapKeyBirth.clear(); @@ -3882,7 +3930,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) // needed to restore wallet transaction meta data after -zapwallettxes std::vector<CWalletTx> vWtx; - if (GetBoolArg("-zapwallettxes", false)) { + if (gArgs.GetBoolArg("-zapwallettxes", false)) { uiInterface.InitMessage(_("Zapping all transactions from wallet...")); std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile)); @@ -3890,11 +3938,11 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DB_LOAD_OK) { InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); - return NULL; + return nullptr; } delete tempWallet; - tempWallet = NULL; + tempWallet = nullptr; } uiInterface.InitMessage(_("Loading wallet...")); @@ -3908,7 +3956,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) { if (nLoadWalletRet == DB_CORRUPT) { InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); - return NULL; + return nullptr; } else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { @@ -3918,22 +3966,22 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) } else if (nLoadWalletRet == DB_TOO_NEW) { InitError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, _(PACKAGE_NAME))); - return NULL; + return nullptr; } else if (nLoadWalletRet == DB_NEED_REWRITE) { InitError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME))); - return NULL; + return nullptr; } else { InitError(strprintf(_("Error loading %s"), walletFile)); - return NULL; + return nullptr; } } - if (GetBoolArg("-upgradewallet", fFirstRun)) + if (gArgs.GetBoolArg("-upgradewallet", fFirstRun)) { - int nMaxVersion = GetArg("-upgradewallet", 0); + int nMaxVersion = gArgs.GetArg("-upgradewallet", 0); if (nMaxVersion == 0) // the -upgradewallet without argument case { LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST); @@ -3945,7 +3993,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) if (nMaxVersion < walletInstance->GetVersion()) { InitError(_("Cannot downgrade wallet")); - return NULL; + return nullptr; } walletInstance->SetMaxVersion(nMaxVersion); } @@ -3953,7 +4001,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) if (fFirstRun) { // Create new keyUser and set as default key - if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && !walletInstance->IsHDEnabled()) { + if (gArgs.GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && !walletInstance->IsHDEnabled()) { // ensure this wallet.dat can only be opened by clients supporting HD with chain split walletInstance->SetMinVersion(FEATURE_HD_SPLIT); @@ -3963,26 +4011,24 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) if (!walletInstance->SetHDMasterKey(masterPubKey)) throw std::runtime_error(std::string(__func__) + ": Storing master key failed"); } - CPubKey newDefaultKey; - if (walletInstance->GetKeyFromPool(newDefaultKey, false)) { - walletInstance->SetDefaultKey(newDefaultKey); - if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive")) { - InitError(_("Cannot write default address") += "\n"); - return NULL; - } + + // Top up the keypool + if (!walletInstance->TopUpKeyPool()) { + InitError(_("Unable to generate initial keys") += "\n"); + return NULL; } walletInstance->SetBestChain(chainActive.GetLocator()); } - else if (IsArgSet("-usehd")) { - bool useHD = GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET); + else if (gArgs.IsArgSet("-usehd")) { + bool useHD = gArgs.GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET); if (walletInstance->IsHDEnabled() && !useHD) { InitError(strprintf(_("Error loading %s: You can't disable HD on an already existing HD wallet"), walletFile)); - return NULL; + return nullptr; } if (!walletInstance->IsHDEnabled() && useHD) { InitError(strprintf(_("Error loading %s: You can't enable HD on an already existing non-HD wallet"), walletFile)); - return NULL; + return nullptr; } } @@ -3990,8 +4036,11 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) RegisterValidationInterface(walletInstance); + // Try to top up keypool. No-op if the wallet is locked. + walletInstance->TopUpKeyPool(); + CBlockIndex *pindexRescan = chainActive.Genesis(); - if (!GetBoolArg("-rescan", false)) + if (!gArgs.GetBoolArg("-rescan", false)) { CWalletDB walletdb(*walletInstance->dbw); CBlockLocator locator; @@ -4011,7 +4060,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) if (pindexRescan != block) { InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)")); - return NULL; + return nullptr; } } @@ -4031,7 +4080,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) walletInstance->dbw->IncrementUpdateCounter(); // Restore wallet transaction metadata after -zapwallettxes=1 - if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2") + if (gArgs.GetBoolArg("-zapwallettxes", false) && gArgs.GetArg("-zapwallettxes", "1") != "2") { CWalletDB walletdb(*walletInstance->dbw); @@ -4055,7 +4104,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) } } } - walletInstance->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST)); + walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST)); { LOCK(walletInstance->cs_wallet); @@ -4069,7 +4118,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) bool CWallet::InitLoadWallet() { - if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { + if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { LogPrintf("Wallet disabled!\n"); return true; } @@ -4101,29 +4150,29 @@ void CWallet::postInitProcess(CScheduler& scheduler) bool CWallet::ParameterInteraction() { - SoftSetArg("-wallet", DEFAULT_WALLET_DAT); + gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT); const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1; - if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) + if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return true; - if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && SoftSetBoolArg("-walletbroadcast", false)) { + if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && gArgs.SoftSetBoolArg("-walletbroadcast", false)) { LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__); } - if (GetBoolArg("-salvagewallet", false)) { + if (gArgs.GetBoolArg("-salvagewallet", false)) { if (is_multiwallet) { return InitError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet")); } // Rewrite just private keys: rescan to find transactions - if (SoftSetBoolArg("-rescan", true)) { + if (gArgs.SoftSetBoolArg("-rescan", true)) { LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); } } - int zapwallettxes = GetArg("-zapwallettxes", 0); + int zapwallettxes = gArgs.GetArg("-zapwallettxes", 0); // -zapwallettxes implies dropping the mempool on startup - if (zapwallettxes != 0 && SoftSetBoolArg("-persistmempool", false)) { + if (zapwallettxes != 0 && gArgs.SoftSetBoolArg("-persistmempool", false)) { LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -persistmempool=0\n", __func__, zapwallettxes); } @@ -4132,61 +4181,61 @@ bool CWallet::ParameterInteraction() if (is_multiwallet) { return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes")); } - if (SoftSetBoolArg("-rescan", true)) { + if (gArgs.SoftSetBoolArg("-rescan", true)) { LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -rescan=1\n", __func__, zapwallettxes); } } if (is_multiwallet) { - if (GetBoolArg("-upgradewallet", false)) { + if (gArgs.GetBoolArg("-upgradewallet", false)) { return InitError(strprintf("%s is only allowed with a single wallet file", "-upgradewallet")); } } - if (GetBoolArg("-sysperms", false)) + if (gArgs.GetBoolArg("-sysperms", false)) return InitError("-sysperms is not allowed in combination with enabled wallet functionality"); - if (GetArg("-prune", 0) && GetBoolArg("-rescan", false)) + if (gArgs.GetArg("-prune", 0) && gArgs.GetBoolArg("-rescan", false)) return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.")); if (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB) InitWarning(AmountHighWarn("-minrelaytxfee") + " " + _("The wallet will avoid paying less than the minimum relay fee.")); - if (IsArgSet("-mintxfee")) + if (gArgs.IsArgSet("-mintxfee")) { CAmount n = 0; - if (!ParseMoney(GetArg("-mintxfee", ""), n) || 0 == n) - return InitError(AmountErrMsg("mintxfee", GetArg("-mintxfee", ""))); + if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) + return InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", ""))); if (n > HIGH_TX_FEE_PER_KB) InitWarning(AmountHighWarn("-mintxfee") + " " + _("This is the minimum transaction fee you pay on every transaction.")); CWallet::minTxFee = CFeeRate(n); } - if (IsArgSet("-fallbackfee")) + if (gArgs.IsArgSet("-fallbackfee")) { CAmount nFeePerK = 0; - if (!ParseMoney(GetArg("-fallbackfee", ""), nFeePerK)) - return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), GetArg("-fallbackfee", ""))); + if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) + return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", ""))); if (nFeePerK > HIGH_TX_FEE_PER_KB) InitWarning(AmountHighWarn("-fallbackfee") + " " + _("This is the transaction fee you may pay when fee estimates are not available.")); CWallet::fallbackFee = CFeeRate(nFeePerK); } - if (IsArgSet("-discardfee")) + if (gArgs.IsArgSet("-discardfee")) { CAmount nFeePerK = 0; - if (!ParseMoney(GetArg("-discardfee", ""), nFeePerK)) - return InitError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), GetArg("-discardfee", ""))); + if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) + return InitError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", ""))); if (nFeePerK > HIGH_TX_FEE_PER_KB) InitWarning(AmountHighWarn("-discardfee") + " " + _("This is the transaction fee you may discard if change is smaller than dust at this level")); CWallet::m_discard_rate = CFeeRate(nFeePerK); } - if (IsArgSet("-paytxfee")) + if (gArgs.IsArgSet("-paytxfee")) { CAmount nFeePerK = 0; - if (!ParseMoney(GetArg("-paytxfee", ""), nFeePerK)) - return InitError(AmountErrMsg("paytxfee", GetArg("-paytxfee", ""))); + if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) + return InitError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", ""))); if (nFeePerK > HIGH_TX_FEE_PER_KB) InitWarning(AmountHighWarn("-paytxfee") + " " + _("This is the transaction fee you will pay if you send a transaction.")); @@ -4195,26 +4244,26 @@ bool CWallet::ParameterInteraction() if (payTxFee < ::minRelayTxFee) { return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"), - GetArg("-paytxfee", ""), ::minRelayTxFee.ToString())); + gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString())); } } - if (IsArgSet("-maxtxfee")) + if (gArgs.IsArgSet("-maxtxfee")) { CAmount nMaxFee = 0; - if (!ParseMoney(GetArg("-maxtxfee", ""), nMaxFee)) - return InitError(AmountErrMsg("maxtxfee", GetArg("-maxtxfee", ""))); + if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee)) + return InitError(AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", ""))); if (nMaxFee > HIGH_MAX_TX_FEE) InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); maxTxFee = nMaxFee; if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) { return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), - GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString())); + gArgs.GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString())); } } - nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); - bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); - fWalletRbf = GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF); + nTxConfirmTarget = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); + bSpendZeroConfChange = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); + fWalletRbf = gArgs.GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF); return true; } @@ -4281,5 +4330,5 @@ int CMerkleTx::GetBlocksToMaturity() const bool CMerkleTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state) { - return ::AcceptToMemoryPool(mempool, state, tx, true, NULL, NULL, false, nAbsurdFee); + return ::AcceptToMemoryPool(mempool, state, tx, true, nullptr, nullptr, false, nAbsurdFee); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 3a02d1305d..cfe156e238 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -208,7 +208,7 @@ public: Init(); } - CMerkleTx(CTransactionRef arg) + explicit CMerkleTx(CTransactionRef arg) { SetTx(std::move(arg)); Init(); @@ -342,7 +342,7 @@ public: CWalletTx() { - Init(NULL); + Init(nullptr); } CWalletTx(const CWallet* pwalletIn, CTransactionRef arg) : CMerkleTx(std::move(arg)) @@ -386,7 +386,7 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { if (ser_action.ForRead()) - Init(NULL); + Init(nullptr); char fSpent = false; if (!ser_action.ForRead()) @@ -548,7 +548,7 @@ public: //! todo: add something to note what created it (user, getnewaddress, change) //! maybe should have a map<string, string> property map - CWalletKey(int64_t nExpires=0); + explicit CWalletKey(int64_t nExpires=0); ADD_SERIALIZE_METHODS; @@ -651,7 +651,7 @@ private: * 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. */ -class CWallet : public CCryptoKeyStore, public CValidationInterface +class CWallet final : public CCryptoKeyStore, public CValidationInterface { private: static std::atomic<bool> fFlushScheduled; @@ -663,7 +663,7 @@ private: * all coins from coinControl are selected; Never select unconfirmed coins * if they are not ours */ - bool SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const; + bool SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = nullptr) const; CWalletDB *pwalletdbEncryption; @@ -694,7 +694,7 @@ private: /* Used by TransactionAddedToMemorypool/BlockConnected/Disconnected. * Should be called with pindexBlock and posInBlock if this is for a transaction that is included in a block. */ - void SyncTransaction(const CTransactionRef& tx, const CBlockIndex *pindex = NULL, int posInBlock = 0); + void SyncTransaction(const CTransactionRef& tx, const CBlockIndex *pindex = nullptr, int posInBlock = 0); /* the HD chain data model (external chain counters) */ CHDChain hdChain; @@ -705,6 +705,7 @@ private: std::set<int64_t> setInternalKeyPool; std::set<int64_t> setExternalKeyPool; int64_t m_max_keypool_index; + std::map<CKeyID, int64_t> m_pool_key_to_index; int64_t nTimeFirstKey; @@ -747,22 +748,7 @@ public: } } - void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool) - { - if (keypool.fInternal) { - setInternalKeyPool.insert(nIndex); - } else { - setExternalKeyPool.insert(nIndex); - } - m_max_keypool_index = std::max(m_max_keypool_index, nIndex); - - // If no metadata exists yet, create a default with the pool key's - // creation time. Note that this may be overwritten by actually - // stored metadata for that key later, which is fine. - CKeyID keyid = keypool.vchPubKey.GetID(); - if (mapKeyMetadata.count(keyid) == 0) - mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime); - } + void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool); // Map from Key ID (for regular keys) or Script ID (for watch-only keys) to // key metadata. @@ -779,7 +765,7 @@ public: } // Create wallet with passed-in database handle - CWallet(std::unique_ptr<CWalletDBWrapper> dbw_in) : dbw(std::move(dbw_in)) + explicit CWallet(std::unique_ptr<CWalletDBWrapper> dbw_in) : dbw(std::move(dbw_in)) { SetNull(); } @@ -787,7 +773,7 @@ public: ~CWallet() { delete pwalletdbEncryption; - pwalletdbEncryption = NULL; + pwalletdbEncryption = nullptr; } void SetNull() @@ -795,7 +781,7 @@ public: nWalletVersion = FEATURE_BASE; nWalletMaxVersion = FEATURE_BASE; nMasterKeyMaxID = 0; - pwalletdbEncryption = NULL; + pwalletdbEncryption = nullptr; nOrderPosNext = 0; nAccountingEntryNumber = 0; nNextResend = 0; @@ -821,19 +807,17 @@ public: std::map<CTxDestination, CAddressBookData> mapAddressBook; - CPubKey vchDefaultKey; - std::set<COutPoint> setLockedCoins; const CWalletTx* GetWalletTx(const uint256& hash) const; //! check whether we are allowed to upgrade (or already support) to the named feature - bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } + bool CanSupportFeature(enum WalletFeature wf) const { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } /** * populate vCoins with vector of available COutputs. */ - void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe=true, const CCoinControl *coinControl = NULL, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t& nMaximumCount = 0, const int& nMinDepth = 0, const int& nMaxDepth = 9999999) const; + void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe=true, const CCoinControl *coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t& nMaximumCount = 0, const int& nMinDepth = 0, const int& nMaxDepth = 9999999) const; /** * Return list of available coins and locked coins grouped by non-change output address. @@ -922,7 +906,7 @@ public: * Increment the next transaction order id * @return next transaction order id */ - int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL); + int64_t IncOrderPosNext(CWalletDB *pwalletdb = nullptr); DBErrors ReorderTransactions(); bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = ""); bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew = false); @@ -990,10 +974,14 @@ public: bool TopUpKeyPool(unsigned int kpSize = 0); void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal); void KeepKey(int64_t nIndex); - void ReturnKey(int64_t nIndex, bool fInternal); + void ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey); bool GetKeyFromPool(CPubKey &key, bool internal = false); int64_t GetOldestKeyPoolTime(); - void GetAllReserveKeys(std::set<CKeyID>& setAddress) const; + /** + * Marks all keys in the keypool up to and including reserve_key as used. + */ + void MarkReserveKeysAsUsed(int64_t keypool_id); + const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; } std::set< std::set<CTxDestination> > GetAddressGroupings(); std::map<CTxDestination, CAmount> GetAddressBalances(); @@ -1048,10 +1036,8 @@ public: return setInternalKeyPool.size() + setExternalKeyPool.size(); } - bool SetDefaultKey(const CPubKey &vchPubKey); - //! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower - bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false); + bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = nullptr, bool fExplicit = false); //! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format) bool SetMaxVersion(int nVersion); @@ -1145,7 +1131,7 @@ public: }; /** A key allocated from the key pool. */ -class CReserveKey : public CReserveScript +class CReserveKey final : public CReserveScript { protected: CWallet* pwallet; @@ -1153,7 +1139,7 @@ protected: CPubKey vchPubKey; bool fInternal; public: - CReserveKey(CWallet* pwalletIn) + explicit CReserveKey(CWallet* pwalletIn) { nIndex = -1; pwallet = pwalletIn; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 65a28af46d..12da3cce64 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -130,11 +130,6 @@ bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext) return WriteIC(std::string("orderposnext"), nOrderPosNext); } -bool CWalletDB::WriteDefaultKey(const CPubKey& vchPubKey) -{ - return WriteIC(std::string("defaultkey"), vchPubKey); -} - bool CWalletDB::ReadPool(int64_t nPool, CKeyPool& keypool) { return batch.Read(std::make_pair(std::string("pool"), nPool), keypool); @@ -452,7 +447,14 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "defaultkey") { - ssValue >> pwallet->vchDefaultKey; + // We don't want or need the default key, but if there is one set, + // we want to make sure that it is valid so that we can detect corruption + CPubKey vchPubKey; + ssValue >> vchPubKey; + if (!vchPubKey.IsValid()) { + strErr = "Error reading wallet database: Default Key corrupt"; + return false; + } } else if (strType == "pool") { @@ -522,7 +524,6 @@ bool CWalletDB::IsKeyType(const std::string& strType) DBErrors CWalletDB::LoadWallet(CWallet* pwallet) { - pwallet->vchDefaultKey = CPubKey(); CWalletScanState wss; bool fNoncriticalErrors = false; DBErrors result = DB_LOAD_OK; @@ -565,7 +566,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) { // losing keys is considered a catastrophic error, anything else // we assume the user can live with: - if (IsKeyType(strType)) + if (IsKeyType(strType) || strType == "defaultkey") result = DB_CORRUPT; else { @@ -573,7 +574,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) fNoncriticalErrors = true; // ... but do warn the user there is something wrong. if (strType == "tx") // Rescan if there is a bad transaction record: - SoftSetBoolArg("-rescan", true); + gArgs.SoftSetBoolArg("-rescan", true); } } if (!strErr.empty()) @@ -621,7 +622,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) pwallet->laccentries.clear(); ListAccountCreditDebit("*", pwallet->laccentries); for (CAccountingEntry& entry : pwallet->laccentries) { - pwallet->wtxOrdered.insert(make_pair(entry.nOrderPos, CWallet::TxPair((CWalletTx*)0, &entry))); + pwallet->wtxOrdered.insert(make_pair(entry.nOrderPos, CWallet::TxPair(nullptr, &entry))); } return result; @@ -751,7 +752,7 @@ void MaybeCompactWalletDB() if (fOneThread.exchange(true)) { return; } - if (!GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) { + if (!gArgs.GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) { return; } @@ -787,7 +788,7 @@ bool CWalletDB::Recover(const std::string& filename, std::string& out_backup_fil { // recover without a key filter callback // results in recovering all record types - return CWalletDB::Recover(filename, NULL, NULL, out_backup_filename); + return CWalletDB::Recover(filename, nullptr, nullptr, out_backup_filename); } bool CWalletDB::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue) diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index d78f143ebd..4f8ea185d5 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -105,7 +105,7 @@ public: { SetNull(); } - CKeyMetadata(int64_t nCreateTime_) + explicit CKeyMetadata(int64_t nCreateTime_) { SetNull(); nCreateTime = nCreateTime_; @@ -162,7 +162,7 @@ private: } public: - CWalletDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool _fFlushOnClose = true) : + explicit CWalletDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool _fFlushOnClose = true) : batch(dbw, pszMode, _fFlushOnClose), m_dbw(dbw) { @@ -191,8 +191,6 @@ public: bool WriteOrderPosNext(int64_t nOrderPosNext); - bool WriteDefaultKey(const CPubKey& vchPubKey); - bool ReadPool(int64_t nPool, CKeyPool& keypool); bool WritePool(int64_t nPool, const CKeyPool& keypool); bool ErasePool(int64_t nPool); diff --git a/src/warnings.cpp b/src/warnings.cpp index 75ccfeb116..d4e33b701a 100644 --- a/src/warnings.cpp +++ b/src/warnings.cpp @@ -51,7 +51,7 @@ std::string GetWarnings(const std::string& strFor) strGUI = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"); } - if (GetBoolArg("-testsafemode", DEFAULT_TESTSAFEMODE)) + if (gArgs.GetBoolArg("-testsafemode", DEFAULT_TESTSAFEMODE)) strStatusBar = strRPC = strGUI = "testsafemode enabled"; // Misc warnings like out of disk space and clock is wrong diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h index 77cf5141e2..7828822149 100644 --- a/src/zmq/zmqabstractnotifier.h +++ b/src/zmq/zmqabstractnotifier.h @@ -15,7 +15,7 @@ typedef CZMQAbstractNotifier* (*CZMQNotifierFactory)(); class CZMQAbstractNotifier { public: - CZMQAbstractNotifier() : psocket(0) { } + CZMQAbstractNotifier() : psocket(nullptr) { } virtual ~CZMQAbstractNotifier(); template <typename T> diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index c063898056..9909395d84 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -15,7 +15,7 @@ void zmqError(const char *str) LogPrint(BCLog::ZMQ, "zmq: Error: %s, errno=%s\n", str, zmq_strerror(errno)); } -CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) +CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(nullptr) { } @@ -31,7 +31,7 @@ CZMQNotificationInterface::~CZMQNotificationInterface() CZMQNotificationInterface* CZMQNotificationInterface::Create() { - CZMQNotificationInterface* notificationInterface = NULL; + CZMQNotificationInterface* notificationInterface = nullptr; std::map<std::string, CZMQNotifierFactory> factories; std::list<CZMQAbstractNotifier*> notifiers; @@ -43,10 +43,10 @@ CZMQNotificationInterface* CZMQNotificationInterface::Create() for (std::map<std::string, CZMQNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i) { std::string arg("-zmq" + i->first); - if (IsArgSet(arg)) + if (gArgs.IsArgSet(arg)) { CZMQNotifierFactory factory = i->second; - std::string address = GetArg(arg, ""); + std::string address = gArgs.GetArg(arg, ""); CZMQAbstractNotifier *notifier = factory(); notifier->SetType(i->first); notifier->SetAddress(address); @@ -62,7 +62,7 @@ CZMQNotificationInterface* CZMQNotificationInterface::Create() if (!notificationInterface->Initialize()) { delete notificationInterface; - notificationInterface = NULL; + notificationInterface = nullptr; } } @@ -120,7 +120,7 @@ void CZMQNotificationInterface::Shutdown() } zmq_ctx_destroy(pcontext); - pcontext = 0; + pcontext = nullptr; } } diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index eec6f7bc64..cb92216fa4 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -13,7 +13,7 @@ class CBlockIndex; class CZMQAbstractNotifier; -class CZMQNotificationInterface : public CValidationInterface +class CZMQNotificationInterface final : public CValidationInterface { public: virtual ~CZMQNotificationInterface(); diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 700c39f66e..ab54e2bb8b 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -126,7 +126,7 @@ void CZMQAbstractPublishNotifier::Shutdown() zmq_close(psocket); } - psocket = 0; + psocket = nullptr; } bool CZMQAbstractPublishNotifier::SendMessage(const char *command, const void* data, size_t size) @@ -136,7 +136,7 @@ bool CZMQAbstractPublishNotifier::SendMessage(const char *command, const void* d /* send three parts, command & data & a LE 4byte sequence number */ unsigned char msgseq[sizeof(uint32_t)]; WriteLE32(&msgseq[0], nSequence); - int rc = zmq_send_multipart(psocket, command, strlen(command), data, size, msgseq, (size_t)sizeof(uint32_t), (void*)0); + int rc = zmq_send_multipart(psocket, command, strlen(command), data, size, msgseq, (size_t)sizeof(uint32_t), nullptr); if (rc == -1) return false; diff --git a/test/functional/README.md b/test/functional/README.md index 96fe0becce..44efda33d3 100644 --- a/test/functional/README.md +++ b/test/functional/README.md @@ -90,7 +90,7 @@ on nodes 2 and up. - Implement a (generator) function called `get_tests()` which yields `TestInstance`s. Each `TestInstance` consists of: - - a list of `[object, outcome, hash]` entries + - A list of `[object, outcome, hash]` entries * `object` is a `CBlock`, `CTransaction`, or `CBlockHeader`. `CBlock`'s and `CTransaction`'s are tested for acceptance. `CBlockHeader`s can be used so that the test runner can deliver diff --git a/test/functional/bip65-cltv-p2p.py b/test/functional/bip65-cltv-p2p.py index bb83042f35..7e5e4cf682 100755 --- a/test/functional/bip65-cltv-p2p.py +++ b/test/functional/bip65-cltv-p2p.py @@ -4,173 +4,162 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test BIP65 (CHECKLOCKTIMEVERIFY). -Connect to a single node. -Mine 2 (version 3) blocks (save the coinbases for later). -Generate 98 more version 3 blocks, verify the node accepts. -Mine 749 version 4 blocks, verify the node accepts. -Check that the new CLTV rules are not enforced on the 750th version 4 block. -Check that the new CLTV rules are enforced on the 751st version 4 block. -Mine 199 new version blocks. -Mine 1 old-version block. -Mine 1 new version block. -Mine 1 old version block, see that the node rejects. +Test that the CHECKLOCKTIMEVERIFY soft-fork activates at (regtest) block height +1351. """ -from test_framework.test_framework import ComparisonTestFramework +from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.mininode import CTransaction, NetworkThread +from test_framework.mininode import * from test_framework.blocktools import create_coinbase, create_block -from test_framework.comptool import TestInstance, TestManager -from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP +from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP, CScriptNum from io import BytesIO -import time + +CLTV_HEIGHT = 1351 + +# Reject codes that we might receive in this test +REJECT_INVALID = 16 +REJECT_OBSOLETE = 17 +REJECT_NONSTANDARD = 64 def cltv_invalidate(tx): '''Modify the signature in vin 0 of the tx to fail CLTV Prepends -1 CLTV DROP in the scriptSig itself. + + TODO: test more ways that transactions using CLTV could be invalid (eg + locktime requirements fail, sequence time requirements fail, etc). ''' tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP] + list(CScript(tx.vin[0].scriptSig))) - -class BIP65Test(ComparisonTestFramework): +def cltv_validate(node, tx, height): + '''Modify the signature in vin 0 of the tx to pass CLTV + Prepends <height> CLTV DROP in the scriptSig, and sets + the locktime to height''' + tx.vin[0].nSequence = 0 + tx.nLockTime = height + + # Need to re-sign, since nSequence and nLockTime changed + signed_result = node.signrawtransaction(ToHex(tx)) + new_tx = CTransaction() + new_tx.deserialize(BytesIO(hex_str_to_bytes(signed_result['hex']))) + + new_tx.vin[0].scriptSig = CScript([CScriptNum(height), OP_CHECKLOCKTIMEVERIFY, OP_DROP] + + list(CScript(new_tx.vin[0].scriptSig))) + return new_tx + +def create_transaction(node, coinbase, to_address, amount): + from_txid = node.getblock(coinbase)['tx'][0] + inputs = [{ "txid" : from_txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = node.createrawtransaction(inputs, outputs) + signresult = node.signrawtransaction(rawtx) + tx = CTransaction() + tx.deserialize(BytesIO(hex_str_to_bytes(signresult['hex']))) + return tx + +class BIP65Test(BitcoinTestFramework): def __init__(self): super().__init__() self.num_nodes = 1 - self.extra_args = [['-whitelist=127.0.0.1', '-blockversion=3']] + self.extra_args = [['-promiscuousmempoolflags=1', '-whitelist=127.0.0.1']] + self.setup_clean_chain = True def run_test(self): - test = TestManager(self, self.options.tmpdir) - test.add_all_connections(self.nodes) + node0 = NodeConnCB() + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], node0)) + node0.add_connection(connections[0]) + NetworkThread().start() # Start up network handling in another thread - test.run() - - def create_transaction(self, node, coinbase, to_address, amount): - from_txid = node.getblock(coinbase)['tx'][0] - inputs = [{ "txid" : from_txid, "vout" : 0}] - outputs = { to_address : amount } - rawtx = node.createrawtransaction(inputs, outputs) - signresult = node.signrawtransaction(rawtx) - tx = CTransaction() - f = BytesIO(hex_str_to_bytes(signresult['hex'])) - tx.deserialize(f) - return tx - - def get_tests(self): - - self.coinbase_blocks = self.nodes[0].generate(2) - height = 3 # height of the next block to build - self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) + + # wait_for_verack ensures that the P2P connection is fully up. + node0.wait_for_verack() + + self.log.info("Mining %d blocks", CLTV_HEIGHT - 2) + self.coinbase_blocks = self.nodes[0].generate(CLTV_HEIGHT - 2) self.nodeaddress = self.nodes[0].getnewaddress() - self.last_block_time = int(time.time()) - - ''' 398 more version 3 blocks ''' - test_blocks = [] - for i in range(398): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 3 - block.rehash() - block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance(test_blocks, sync_every_block=False) - - ''' Mine 749 version 4 blocks ''' - test_blocks = [] - for i in range(749): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 4 - block.rehash() - block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance(test_blocks, sync_every_block=False) - - ''' - Check that the new CLTV rules are not enforced in the 750th - version 3 block. - ''' - spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[0], self.nodeaddress, 1.0) + + self.log.info("Test that an invalid-according-to-CLTV transaction can still appear in a block") + + spendtx = create_transaction(self.nodes[0], self.coinbase_blocks[0], + self.nodeaddress, 1.0) cltv_invalidate(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 4 + tip = self.nodes[0].getbestblockhash() + block_time = self.nodes[0].getblockheader(tip)['mediantime'] + 1 + block = create_block(int(tip, 16), create_coinbase(CLTV_HEIGHT - 1), block_time) + block.nVersion = 3 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() - block.rehash() block.solve() - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance([[block, True]]) - - ''' Mine 199 new version blocks on last valid tip ''' - test_blocks = [] - for i in range(199): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 4 - block.rehash() - block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance(test_blocks, sync_every_block=False) - - ''' Mine 1 old version block ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + node0.send_and_ping(msg_block(block)) + assert_equal(self.nodes[0].getbestblockhash(), block.hash) + + self.log.info("Test that blocks must now be at least version 4") + tip = block.sha256 + block_time += 1 + block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time) block.nVersion = 3 - block.rehash() block.solve() - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance([[block, True]]) + node0.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) - ''' Mine 1 new version block ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + assert wait_until(lambda: "reject" in node0.last_message.keys()) + with mininode_lock: + assert_equal(node0.last_message["reject"].code, REJECT_OBSOLETE) + assert_equal(node0.last_message["reject"].reason, b'bad-version(0x00000003)') + assert_equal(node0.last_message["reject"].data, block.sha256) + del node0.last_message["reject"] + + self.log.info("Test that invalid-according-to-cltv transactions cannot appear in a block") block.nVersion = 4 - block.rehash() - block.solve() - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance([[block, True]]) - - ''' - Check that the new CLTV rules are enforced in the 951st version 4 - block. - ''' - spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[1], self.nodeaddress, 1.0) + + spendtx = create_transaction(self.nodes[0], self.coinbase_blocks[1], + self.nodeaddress, 1.0) cltv_invalidate(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 4 + # First we show that this tx is valid except for CLTV by getting it + # accepted to the mempool (which we can achieve with + # -promiscuousmempoolflags). + node0.send_and_ping(msg_tx(spendtx)) + assert spendtx.hash in self.nodes[0].getrawmempool() + + # Now we verify that a block with this transaction is invalid. block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() - block.rehash() block.solve() - self.last_block_time += 1 - yield TestInstance([[block, False]]) - ''' Mine 1 old version block, should be invalid ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 3 - block.rehash() + node0.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) + + assert wait_until (lambda: "reject" in node0.last_message.keys()) + with mininode_lock: + assert node0.last_message["reject"].code in [REJECT_INVALID, REJECT_NONSTANDARD] + assert_equal(node0.last_message["reject"].data, block.sha256) + if node0.last_message["reject"].code == REJECT_INVALID: + # Generic rejection when a block is invalid + assert_equal(node0.last_message["reject"].reason, b'block-validation-failed') + else: + assert b'Negative locktime' in node0.last_message["reject"].reason + + self.log.info("Test that a version 4 block with a valid-according-to-CLTV transaction is accepted") + spendtx = cltv_validate(self.nodes[0], spendtx, CLTV_HEIGHT - 1) + spendtx.rehash() + + block.vtx.pop(1) + block.vtx.append(spendtx) + block.hashMerkleRoot = block.calc_merkle_root() block.solve() - self.last_block_time += 1 - yield TestInstance([[block, False]]) + + node0.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + if __name__ == '__main__': BIP65Test().main() diff --git a/test/functional/bip65-cltv.py b/test/functional/bip65-cltv.py deleted file mode 100755 index ddf932c746..0000000000 --- a/test/functional/bip65-cltv.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2015-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. -"""Test the CHECKLOCKTIMEVERIFY (BIP65) soft-fork logic.""" - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * - -class BIP65Test(BitcoinTestFramework): - def __init__(self): - super().__init__() - self.num_nodes = 3 - self.setup_clean_chain = False - self.extra_args = [[], ["-blockversion=3"], ["-blockversion=4"]] - - def setup_network(self): - self.setup_nodes() - connect_nodes(self.nodes[1], 0) - connect_nodes(self.nodes[2], 0) - self.sync_all() - - def run_test(self): - cnt = self.nodes[0].getblockcount() - - # Mine some old-version blocks - self.nodes[1].generate(200) - cnt += 100 - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 100): - raise AssertionError("Failed to mine 100 version=3 blocks") - - # Mine 750 new-version blocks - for i in range(15): - self.nodes[2].generate(50) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 850): - raise AssertionError("Failed to mine 750 version=4 blocks") - - # TODO: check that new CHECKLOCKTIMEVERIFY rules are not enforced - - # Mine 1 new-version block - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 851): - raise AssertionError("Failed to mine a version=4 blocks") - - # TODO: check that new CHECKLOCKTIMEVERIFY rules are enforced - - # Mine 198 new-version blocks - for i in range(2): - self.nodes[2].generate(99) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1049): - raise AssertionError("Failed to mine 198 version=4 blocks") - - # Mine 1 old-version block - self.nodes[1].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1050): - raise AssertionError("Failed to mine a version=3 block after 949 version=4 blocks") - - # Mine 1 new-version blocks - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1051): - raise AssertionError("Failed to mine a version=4 block") - - # Mine 1 old-version blocks. This should fail - assert_raises_jsonrpc(-1,"CreateNewBlock: TestBlockValidity failed: bad-version(0x00000003)", self.nodes[1].generate, 1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1051): - raise AssertionError("Accepted a version=3 block after 950 version=4 blocks") - - # Mine 1 new-version blocks - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1052): - raise AssertionError("Failed to mine a version=4 block") - -if __name__ == '__main__': - BIP65Test().main() diff --git a/test/functional/bipdersig-p2p.py b/test/functional/bipdersig-p2p.py index 31c7ebba90..38a9009544 100755 --- a/test/functional/bipdersig-p2p.py +++ b/test/functional/bipdersig-p2p.py @@ -4,28 +4,24 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test BIP66 (DER SIG). -Connect to a single node. -Mine 2 (version 2) blocks (save the coinbases for later). -Generate 98 more version 2 blocks, verify the node accepts. -Mine 749 version 3 blocks, verify the node accepts. -Check that the new DERSIG rules are not enforced on the 750th version 3 block. -Check that the new DERSIG rules are enforced on the 751st version 3 block. -Mine 199 new version blocks. -Mine 1 old-version block. -Mine 1 new version block. -Mine 1 old version block, see that the node rejects. +Test that the DERSIG soft-fork activates at (regtest) height 1251. """ -from test_framework.test_framework import ComparisonTestFramework +from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.mininode import CTransaction, NetworkThread +from test_framework.mininode import * from test_framework.blocktools import create_coinbase, create_block -from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript from io import BytesIO -import time -# A canonical signature consists of: +DERSIG_HEIGHT = 1251 + +# Reject codes that we might receive in this test +REJECT_INVALID = 16 +REJECT_OBSOLETE = 17 +REJECT_NONSTANDARD = 64 + +# A canonical signature consists of: # <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype> def unDERify(tx): """ @@ -40,143 +36,122 @@ def unDERify(tx): else: newscript.append(i) tx.vin[0].scriptSig = CScript(newscript) - -class BIP66Test(ComparisonTestFramework): + +def create_transaction(node, coinbase, to_address, amount): + from_txid = node.getblock(coinbase)['tx'][0] + inputs = [{ "txid" : from_txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = node.createrawtransaction(inputs, outputs) + signresult = node.signrawtransaction(rawtx) + tx = CTransaction() + tx.deserialize(BytesIO(hex_str_to_bytes(signresult['hex']))) + return tx + +class BIP66Test(BitcoinTestFramework): def __init__(self): super().__init__() self.num_nodes = 1 + self.extra_args = [['-promiscuousmempoolflags=1', '-whitelist=127.0.0.1']] + self.setup_clean_chain = True def run_test(self): - test = TestManager(self, self.options.tmpdir) - test.add_all_connections(self.nodes) + node0 = NodeConnCB() + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], node0)) + node0.add_connection(connections[0]) NetworkThread().start() # Start up network handling in another thread - test.run() - - def create_transaction(self, node, coinbase, to_address, amount): - from_txid = node.getblock(coinbase)['tx'][0] - inputs = [{ "txid" : from_txid, "vout" : 0}] - outputs = { to_address : amount } - rawtx = node.createrawtransaction(inputs, outputs) - signresult = node.signrawtransaction(rawtx) - tx = CTransaction() - f = BytesIO(hex_str_to_bytes(signresult['hex'])) - tx.deserialize(f) - return tx - - def get_tests(self): - - self.coinbase_blocks = self.nodes[0].generate(2) - height = 3 # height of the next block to build - self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) + + # wait_for_verack ensures that the P2P connection is fully up. + node0.wait_for_verack() + + self.log.info("Mining %d blocks", DERSIG_HEIGHT - 2) + self.coinbase_blocks = self.nodes[0].generate(DERSIG_HEIGHT - 2) self.nodeaddress = self.nodes[0].getnewaddress() - self.last_block_time = int(time.time()) - - ''' 298 more version 2 blocks ''' - test_blocks = [] - for i in range(298): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 2 - block.rehash() - block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance(test_blocks, sync_every_block=False) - - ''' Mine 749 version 3 blocks ''' - test_blocks = [] - for i in range(749): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 3 - block.rehash() - block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance(test_blocks, sync_every_block=False) - - ''' - Check that the new DERSIG rules are not enforced in the 750th - version 3 block. - ''' - spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[0], self.nodeaddress, 1.0) + + self.log.info("Test that a transaction with non-DER signature can still appear in a block") + + spendtx = create_transaction(self.nodes[0], self.coinbase_blocks[0], + self.nodeaddress, 1.0) unDERify(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 3 + tip = self.nodes[0].getbestblockhash() + block_time = self.nodes[0].getblockheader(tip)['mediantime'] + 1 + block = create_block(int(tip, 16), create_coinbase(DERSIG_HEIGHT - 1), block_time) + block.nVersion = 2 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance([[block, True]]) - - ''' Mine 199 new version blocks on last valid tip ''' - test_blocks = [] - for i in range(199): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 3 - block.rehash() - block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance(test_blocks, sync_every_block=False) - - ''' Mine 1 old version block ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + node0.send_and_ping(msg_block(block)) + assert_equal(self.nodes[0].getbestblockhash(), block.hash) + + self.log.info("Test that blocks must now be at least version 3") + tip = block.sha256 + block_time += 1 + block = create_block(tip, create_coinbase(DERSIG_HEIGHT), block_time) block.nVersion = 2 block.rehash() block.solve() - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance([[block, True]]) + node0.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) - ''' Mine 1 new version block ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + assert wait_until(lambda: "reject" in node0.last_message.keys()) + with mininode_lock: + assert_equal(node0.last_message["reject"].code, REJECT_OBSOLETE) + assert_equal(node0.last_message["reject"].reason, b'bad-version(0x00000002)') + assert_equal(node0.last_message["reject"].data, block.sha256) + del node0.last_message["reject"] + + self.log.info("Test that transactions with non-DER signatures cannot appear in a block") block.nVersion = 3 - block.rehash() - block.solve() - self.last_block_time += 1 - self.tip = block.sha256 - height += 1 - yield TestInstance([[block, True]]) - - ''' - Check that the new DERSIG rules are enforced in the 951st version 3 - block. - ''' - spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[1], self.nodeaddress, 1.0) + + spendtx = create_transaction(self.nodes[0], self.coinbase_blocks[1], + self.nodeaddress, 1.0) unDERify(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 3 + # First we show that this tx is valid except for DERSIG by getting it + # accepted to the mempool (which we can achieve with + # -promiscuousmempoolflags). + node0.send_and_ping(msg_tx(spendtx)) + assert spendtx.hash in self.nodes[0].getrawmempool() + + # Now we verify that a block with this transaction is invalid. block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() - self.last_block_time += 1 - yield TestInstance([[block, False]]) - ''' Mine 1 old version block, should be invalid ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) - block.nVersion = 2 + node0.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) + + assert wait_until (lambda: "reject" in node0.last_message.keys()) + with mininode_lock: + # We can receive different reject messages depending on whether + # bitcoind is running with multiple script check threads. If script + # check threads are not in use, then transaction script validation + # happens sequentially, and bitcoind produces more specific reject + # reasons. + assert node0.last_message["reject"].code in [REJECT_INVALID, REJECT_NONSTANDARD] + assert_equal(node0.last_message["reject"].data, block.sha256) + if node0.last_message["reject"].code == REJECT_INVALID: + # Generic rejection when a block is invalid + assert_equal(node0.last_message["reject"].reason, b'block-validation-failed') + else: + assert b'Non-canonical DER signature' in node0.last_message["reject"].reason + + self.log.info("Test that a version 3 block with a DERSIG-compliant transaction is accepted") + block.vtx[1] = create_transaction(self.nodes[0], + self.coinbase_blocks[1], self.nodeaddress, 1.0) + block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() - self.last_block_time += 1 - yield TestInstance([[block, False]]) + + node0.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) if __name__ == '__main__': BIP66Test().main() diff --git a/test/functional/bipdersig.py b/test/functional/bipdersig.py deleted file mode 100755 index 41f88fb664..0000000000 --- a/test/functional/bipdersig.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 -# 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. -"""Test the BIP66 changeover logic.""" - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * - -class BIP66Test(BitcoinTestFramework): - def __init__(self): - super().__init__() - self.num_nodes = 3 - self.setup_clean_chain = False - self.extra_args = [[], ["-blockversion=2"], ["-blockversion=3"]] - - def setup_network(self): - self.setup_nodes() - connect_nodes(self.nodes[1], 0) - connect_nodes(self.nodes[2], 0) - self.sync_all() - - def run_test(self): - cnt = self.nodes[0].getblockcount() - - # Mine some old-version blocks - self.nodes[1].generate(100) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 100): - raise AssertionError("Failed to mine 100 version=2 blocks") - - # Mine 750 new-version blocks - for i in range(15): - self.nodes[2].generate(50) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 850): - raise AssertionError("Failed to mine 750 version=3 blocks") - - # TODO: check that new DERSIG rules are not enforced - - # Mine 1 new-version block - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 851): - raise AssertionError("Failed to mine a version=3 blocks") - - # TODO: check that new DERSIG rules are enforced - - # Mine 198 new-version blocks - for i in range(2): - self.nodes[2].generate(99) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1049): - raise AssertionError("Failed to mine 198 version=3 blocks") - - # Mine 1 old-version block - self.nodes[1].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1050): - raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks") - - # Mine 1 new-version blocks - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1051): - raise AssertionError("Failed to mine a version=3 block") - - # Mine 1 old-version blocks. This should fail - assert_raises_jsonrpc(-1, "CreateNewBlock: TestBlockValidity failed: bad-version(0x00000002)", self.nodes[1].generate, 1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1051): - raise AssertionError("Accepted a version=2 block after 950 version=3 blocks") - - # Mine 1 new-version blocks - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1052): - raise AssertionError("Failed to mine a version=3 block") - -if __name__ == '__main__': - BIP66Test().main() diff --git a/test/functional/blockchain.py b/test/functional/blockchain.py index a7034e6bcd..0812e1b0df 100755 --- a/test/functional/blockchain.py +++ b/test/functional/blockchain.py @@ -139,13 +139,13 @@ class BlockchainTest(BitcoinTestFramework): self.nodes[0].generate(6) assert_equal(self.nodes[0].getblockcount(), 206) self.log.debug('Node should not stop at this height') - assert_raises(subprocess.TimeoutExpired, lambda: self.bitcoind_processes[0].wait(timeout=3)) + assert_raises(subprocess.TimeoutExpired, lambda: self.nodes[0].process.wait(timeout=3)) try: self.nodes[0].generate(1) except (ConnectionError, http.client.BadStatusLine): pass # The node already shut down before response self.log.debug('Node should stop at this height...') - self.bitcoind_processes[0].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) + self.nodes[0].process.wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) self.nodes[0] = self.start_node(0, self.options.tmpdir) assert_equal(self.nodes[0].getblockcount(), 207) diff --git a/test/functional/bumpfee.py b/test/functional/bumpfee.py index 9237f09240..9633ffdebb 100755 --- a/test/functional/bumpfee.py +++ b/test/functional/bumpfee.py @@ -41,8 +41,7 @@ class BumpFeeTest(BitcoinTestFramework): self.nodes = self.start_nodes(self.num_nodes, self.options.tmpdir, extra_args) # Encrypt wallet for test_locked_wallet_fails test - self.nodes[1].encryptwallet(WALLET_PASSPHRASE) - self.bitcoind_processes[1].wait() + self.nodes[1].node_encrypt_wallet(WALLET_PASSPHRASE) self.nodes[1] = self.start_node(1, self.options.tmpdir, extra_args[1]) self.nodes[1].walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT) @@ -90,7 +89,7 @@ def test_simple_bumpfee_succeeds(rbf_node, peer_node, dest_address): bumped_tx = rbf_node.bumpfee(rbfid) assert_equal(bumped_tx["errors"], []) assert bumped_tx["fee"] - abs(rbftx["fee"]) > 0 - # check that bumped_tx propogates, original tx was evicted and has a wallet conflict + # check that bumped_tx propagates, original tx was evicted and has a wallet conflict sync_mempools((rbf_node, peer_node)) assert bumped_tx["txid"] in rbf_node.getrawmempool() assert bumped_tx["txid"] in peer_node.getrawmempool() diff --git a/test/functional/example_test.py b/test/functional/example_test.py index 1ba5f756cd..79940a4264 100755 --- a/test/functional/example_test.py +++ b/test/functional/example_test.py @@ -58,6 +58,10 @@ class BaseNode(NodeConnCB): message.block.calc_sha256() self.block_receive_map[message.block.sha256] += 1 + def on_inv(self, conn, message): + """Override the standard on_inv callback""" + pass + def custom_function(): """Do some custom behaviour @@ -196,12 +200,12 @@ class ExampleTest(BitcoinTestFramework): node2.add_connection(connections[1]) node2.wait_for_verack() - self.log.info("Wait for node2 reach current tip. Test that it has propogated all the blocks to us") + self.log.info("Wait for node2 reach current tip. Test that it has propagated all the blocks to us") + getdata_request = msg_getdata() for block in blocks: - getdata_request = msg_getdata() getdata_request.inv.append(CInv(2, block)) - node2.send_message(getdata_request) + node2.send_message(getdata_request) # wait_until() will loop until a predicate condition is met. Use it to test properties of the # NodeConnCB objects. diff --git a/test/functional/fundrawtransaction.py b/test/functional/fundrawtransaction.py index e52e773918..f2f4efcf28 100755 --- a/test/functional/fundrawtransaction.py +++ b/test/functional/fundrawtransaction.py @@ -451,8 +451,7 @@ class RawTransactionsTest(BitcoinTestFramework): self.stop_node(0) self.stop_node(2) self.stop_node(3) - self.nodes[1].encryptwallet("test") - self.bitcoind_processes[1].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) + self.nodes[1].node_encrypt_wallet("test") self.nodes = self.start_nodes(self.num_nodes, self.options.tmpdir) # This test is not meant to test fee estimation and we'd like diff --git a/test/functional/getblocktemplate_longpoll.py b/test/functional/getblocktemplate_longpoll.py index bbe1dda5f7..cca30e2688 100755 --- a/test/functional/getblocktemplate_longpoll.py +++ b/test/functional/getblocktemplate_longpoll.py @@ -17,7 +17,7 @@ class LongpollThread(threading.Thread): self.longpollid = templat['longpollid'] # create a new connection to the node, we can't use the same # connection from two threads - self.node = get_rpc_proxy(node.url, 1, timeout=600) + self.node = get_rpc_proxy(node.url, 1, timeout=600, coveragedir=node.coverage_dir) def run(self): self.node.getblocktemplate({'longpollid':self.longpollid}) diff --git a/test/functional/keypool-topup.py b/test/functional/keypool-topup.py new file mode 100755 index 0000000000..da29f697e3 --- /dev/null +++ b/test/functional/keypool-topup.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# Copyright (c) 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. +"""Test HD Wallet keypool restore function. + +Two nodes. Node1 is under test. Node0 is providing transactions and generating blocks. + +- Start node1, shutdown and backup wallet. +- Generate 110 keys (enough to drain the keypool). Store key 90 (in the initial keypool) and key 110 (beyond the initial keypool). Send funds to key 90 and key 110. +- Stop node1, clear the datadir, move wallet file back into the datadir and restart node1. +- connect node1 to node0. Verify that they sync and node1 receives its funds.""" +import shutil + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + connect_nodes_bi, + sync_blocks, +) + +class KeypoolRestoreTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 2 + self.extra_args = [['-usehd=0'], ['-usehd=1', '-keypool=100', '-keypoolmin=20']] + + def run_test(self): + self.tmpdir = self.options.tmpdir + self.nodes[0].generate(101) + + self.log.info("Make backup of wallet") + + self.stop_node(1) + + shutil.copyfile(self.tmpdir + "/node1/regtest/wallet.dat", self.tmpdir + "/wallet.bak") + self.nodes[1] = self.start_node(1, self.tmpdir, self.extra_args[1]) + connect_nodes_bi(self.nodes, 0, 1) + + self.log.info("Generate keys for wallet") + + for _ in range(90): + addr_oldpool = self.nodes[1].getnewaddress() + for _ in range(20): + addr_extpool = self.nodes[1].getnewaddress() + + self.log.info("Send funds to wallet") + + self.nodes[0].sendtoaddress(addr_oldpool, 10) + self.nodes[0].generate(1) + self.nodes[0].sendtoaddress(addr_extpool, 5) + self.nodes[0].generate(1) + sync_blocks(self.nodes) + + self.log.info("Restart node with wallet backup") + + self.stop_node(1) + + shutil.copyfile(self.tmpdir + "/wallet.bak", self.tmpdir + "/node1/regtest/wallet.dat") + + self.log.info("Verify keypool is restored and balance is correct") + + self.nodes[1] = self.start_node(1, self.tmpdir, self.extra_args[1]) + connect_nodes_bi(self.nodes, 0, 1) + self.sync_all() + + assert_equal(self.nodes[1].getbalance(), 15) + assert_equal(self.nodes[1].listtransactions()[0]['category'], "receive") + + # Check that we have marked all keys up to the used keypool key as used + assert_equal(self.nodes[1].validateaddress(self.nodes[1].getnewaddress())['hdkeypath'], "m/0'/0'/110'") + +if __name__ == '__main__': + KeypoolRestoreTest().main() diff --git a/test/functional/keypool.py b/test/functional/keypool.py index e8be559918..3e7bb0ee07 100755 --- a/test/functional/keypool.py +++ b/test/functional/keypool.py @@ -17,8 +17,7 @@ class KeyPoolTest(BitcoinTestFramework): assert(addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['hdmasterkeyid']) # Encrypt wallet and wait to terminate - nodes[0].encryptwallet('test') - self.bitcoind_processes[0].wait() + nodes[0].node_encrypt_wallet('test') # Restart node 0 nodes[0] = self.start_node(0, self.options.tmpdir) # Keep creating keys diff --git a/test/functional/multiwallet.py b/test/functional/multiwallet.py index 5679f40503..fc6e8e325f 100755 --- a/test/functional/multiwallet.py +++ b/test/functional/multiwallet.py @@ -35,11 +35,15 @@ class MultiWalletTest(BitcoinTestFramework): self.nodes[0] = self.start_node(0, self.options.tmpdir, self.extra_args[0]) - w1 = self.nodes[0] / "wallet/w1" + w1 = self.nodes[0].get_wallet_rpc("w1") + w2 = self.nodes[0].get_wallet_rpc("w2") + w3 = self.nodes[0].get_wallet_rpc("w3") + wallet_bad = self.nodes[0].get_wallet_rpc("bad") + w1.generate(1) # accessing invalid wallet fails - assert_raises_jsonrpc(-18, "Requested wallet does not exist or is not loaded", (self.nodes[0] / "wallet/bad").getwalletinfo) + assert_raises_jsonrpc(-18, "Requested wallet does not exist or is not loaded", wallet_bad.getwalletinfo) # accessing wallet RPC without using wallet endpoint fails assert_raises_jsonrpc(-19, "Wallet file not specified", self.nodes[0].getwalletinfo) @@ -50,14 +54,12 @@ class MultiWalletTest(BitcoinTestFramework): w1_name = w1_info['walletname'] assert_equal(w1_name, "w1") - # check w1 wallet balance - w2 = self.nodes[0] / "wallet/w2" + # check w2 wallet balance w2_info = w2.getwalletinfo() assert_equal(w2_info['immature_balance'], 0) w2_name = w2_info['walletname'] assert_equal(w2_name, "w2") - w3 = self.nodes[0] / "wallet/w3" w3_name = w3.getwalletinfo()['walletname'] assert_equal(w3_name, "w3") diff --git a/test/functional/net.py b/test/functional/net.py index 3ba3764cf9..1e63d38035 100755 --- a/test/functional/net.py +++ b/test/functional/net.py @@ -85,7 +85,7 @@ class NetTest(BitcoinTestFramework): added_nodes = self.nodes[0].getaddednodeinfo(ip_port) assert_equal(len(added_nodes), 1) assert_equal(added_nodes[0]['addednode'], ip_port) - # check that a non-existant node returns an error + # check that a non-existent node returns an error assert_raises_jsonrpc(-24, "Node has not been added", self.nodes[0].getaddednodeinfo, '1.1.1.1') diff --git a/test/functional/pruning.py b/test/functional/pruning.py index 0af91e0658..3e00a34ac4 100755 --- a/test/functional/pruning.py +++ b/test/functional/pruning.py @@ -136,7 +136,7 @@ class PruneTest(BitcoinTestFramework): self.log.info("Invalidating block %s at height %d" % (badhash,invalidheight)) self.nodes[1].invalidateblock(badhash) - # We've now switched to our previously mined-24 block fork on node 1, but thats not what we want + # We've now switched to our previously mined-24 block fork on node 1, but that's not what we want # So invalidate that fork as well, until we're on the same chain as node 0/2 (but at an ancestor 288 blocks ago) mainchainhash = self.nodes[0].getblockhash(invalidheight - 1) curhash = self.nodes[1].getblockhash(invalidheight - 1) @@ -199,7 +199,7 @@ class PruneTest(BitcoinTestFramework): goalbesthash = self.mainchainhash2 # As of 0.10 the current block download logic is not able to reorg to the original chain created in - # create_chain_with_stale_blocks because it doesn't know of any peer thats on that chain from which to + # create_chain_with_stale_blocks because it doesn't know of any peer that's on that chain from which to # redownload its missing blocks. # Invalidate the reorg_test chain in node 0 as well, it can successfully switch to the original chain # because it has all the block data. diff --git a/test/functional/rawtransactions.py b/test/functional/rawtransactions.py index 6272fc69b7..b6b90d6781 100755 --- a/test/functional/rawtransactions.py +++ b/test/functional/rawtransactions.py @@ -2,7 +2,7 @@ # 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. -"""Test the rawtranscation RPCs. +"""Test the rawtransaction RPCs. Test the following RPCs: - createrawtransaction diff --git a/test/functional/resendwallettransactions.py b/test/functional/resendwallettransactions.py new file mode 100755 index 0000000000..5059aa106e --- /dev/null +++ b/test/functional/resendwallettransactions.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# Copyright (c) 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. +"""Test resendwallettransactions RPC.""" + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_raises_jsonrpc + +class ResendWalletTransactionsTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.extra_args = [['--walletbroadcast=false']] + self.num_nodes = 1 + + def run_test(self): + # Should raise RPC_WALLET_ERROR (-4) if walletbroadcast is disabled. + assert_raises_jsonrpc(-4, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast", self.nodes[0].resendwallettransactions) + + # Should return an empty array if there aren't unconfirmed wallet transactions. + self.stop_node(0) + self.nodes[0] = self.start_node(0, self.options.tmpdir) + assert_equal(self.nodes[0].resendwallettransactions(), []) + + # Should return an array with the unconfirmed wallet transaction. + txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1) + assert_equal(self.nodes[0].resendwallettransactions(), [txid]) + +if __name__ == '__main__': + ResendWalletTransactionsTest().main() diff --git a/test/functional/rpcbind_test.py b/test/functional/rpcbind_test.py index 951685aa76..20808207b2 100755 --- a/test/functional/rpcbind_test.py +++ b/test/functional/rpcbind_test.py @@ -37,7 +37,7 @@ class RPCBindTest(BitcoinTestFramework): base_args += ['-rpcallowip=' + x for x in allow_ips] binds = ['-rpcbind='+addr for addr in addresses] self.nodes = self.start_nodes(self.num_nodes, self.options.tmpdir, [base_args + binds], connect_to) - pid = self.bitcoind_processes[0].pid + pid = self.nodes[0].process.pid assert_equal(set(get_bind_addrs(pid)), set(expected)) self.stop_nodes() @@ -49,7 +49,7 @@ class RPCBindTest(BitcoinTestFramework): base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] self.nodes = self.start_nodes(self.num_nodes, self.options.tmpdir, [base_args]) # connect to node through non-loopback interface - node = get_rpc_proxy(rpc_url(get_datadir_path(self.options.tmpdir, 0), 0, "%s:%d" % (rpchost, rpcport)), 0) + node = get_rpc_proxy(rpc_url(get_datadir_path(self.options.tmpdir, 0), 0, "%s:%d" % (rpchost, rpcport)), 0, coveragedir=self.options.coveragedir) node.getnetworkinfo() self.stop_nodes() diff --git a/test/functional/sendheaders.py b/test/functional/sendheaders.py index 44c357c6db..e47e07fb86 100755 --- a/test/functional/sendheaders.py +++ b/test/functional/sendheaders.py @@ -121,9 +121,6 @@ class TestNode(NodeConnCB): message.headers[-1].calc_sha256() self.last_blockhash_announced = message.headers[-1].sha256 - def on_block(self, conn, message): - self.last_message["block"].calc_sha256() - # Test whether the last announcement we received had the # right header or the right inv # inv and headers should be lists of block hashes diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 8d698a7327..7903bb0045 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -5,14 +5,12 @@ """Base class for RPC testing.""" from collections import deque -import errno from enum import Enum -import http.client import logging import optparse import os +import pdb import shutil -import subprocess import sys import tempfile import time @@ -20,6 +18,7 @@ import traceback from .authproxy import JSONRPCException from . import coverage +from .test_node import TestNode from .util import ( MAX_NODES, PortSeed, @@ -27,12 +26,9 @@ from .util import ( check_json_precision, connect_nodes_bi, disconnect_nodes, - get_rpc_proxy, initialize_datadir, - get_datadir_path, log_filename, p2p_port, - rpc_url, set_node_times, sync_blocks, sync_mempools, @@ -69,7 +65,6 @@ class BitcoinTestFramework(object): self.num_nodes = 4 self.setup_clean_chain = False self.nodes = [] - self.bitcoind_processes = {} self.mocktime = 0 def add_options(self, parser): @@ -125,6 +120,8 @@ class BitcoinTestFramework(object): help="Write tested RPC commands into this directory") parser.add_option("--configfile", dest="configfile", help="Location of the test framework config file") + parser.add_option("--pdbonfailure", dest="pdbonfailure", default=False, action="store_true", + help="Attach a python debugger if test fails") self.add_options(parser) (self.options, self.args) = parser.parse_args() @@ -162,6 +159,10 @@ class BitcoinTestFramework(object): except KeyboardInterrupt as e: self.log.warning("Exiting after keyboard interrupt") + if success == TestStatus.FAILED and self.options.pdbonfailure: + print("Testcase failed. Attaching python debugger. Enter ? for help") + pdb.set_trace() + if not self.options.noshutdown: self.log.info("Stopping nodes") if self.nodes: @@ -206,64 +207,62 @@ class BitcoinTestFramework(object): def start_node(self, i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None, stderr=None): """Start a bitcoind and return RPC connection to it""" - datadir = os.path.join(dirname, "node" + str(i)) + if extra_args is None: + extra_args = [] if binary is None: binary = os.getenv("BITCOIND", "bitcoind") - args = [binary, "-datadir=" + datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-logtimemicros", "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", "-mocktime=" + str(self.mocktime), "-uacomment=testnode%d" % i] - if extra_args is not None: - args.extend(extra_args) - self.bitcoind_processes[i] = subprocess.Popen(args, stderr=stderr) - self.log.debug("initialize_chain: bitcoind started, waiting for RPC to come up") - self._wait_for_bitcoind_start(self.bitcoind_processes[i], datadir, i, rpchost) - self.log.debug("initialize_chain: RPC successfully started") - proxy = get_rpc_proxy(rpc_url(datadir, i, rpchost), i, timeout=timewait) + node = TestNode(i, dirname, extra_args, rpchost, timewait, binary, stderr, self.mocktime, coverage_dir=self.options.coveragedir) + node.start() + node.wait_for_rpc_connection() - if self.options.coveragedir: - coverage.write_all_rpc_commands(self.options.coveragedir, proxy) + if self.options.coveragedir is not None: + coverage.write_all_rpc_commands(self.options.coveragedir, node.rpc) - return proxy + return node def start_nodes(self, num_nodes, dirname, extra_args=None, rpchost=None, timewait=None, binary=None): """Start multiple bitcoinds, return RPC connections to them""" if extra_args is None: - extra_args = [None] * num_nodes + extra_args = [[]] * num_nodes if binary is None: binary = [None] * num_nodes assert_equal(len(extra_args), num_nodes) assert_equal(len(binary), num_nodes) - rpcs = [] + nodes = [] try: for i in range(num_nodes): - rpcs.append(self.start_node(i, dirname, extra_args[i], rpchost, timewait=timewait, binary=binary[i])) + nodes.append(TestNode(i, dirname, extra_args[i], rpchost, timewait=timewait, binary=binary[i], stderr=None, mocktime=self.mocktime, coverage_dir=self.options.coveragedir)) + nodes[i].start() + for node in nodes: + node.wait_for_rpc_connection() except: # If one node failed to start, stop the others - # TODO: abusing self.nodes in this way is a little hacky. - # Eventually we should do a better job of tracking nodes - self.nodes.extend(rpcs) self.stop_nodes() - self.nodes = [] raise - return rpcs + + if self.options.coveragedir is not None: + for node in nodes: + coverage.write_all_rpc_commands(self.options.coveragedir, node.rpc) + + return nodes def stop_node(self, i): """Stop a bitcoind test node""" - - self.log.debug("Stopping node %d" % i) - try: - self.nodes[i].stop() - except http.client.CannotSendRequest as e: - self.log.exception("Unable to stop node") - return_code = self.bitcoind_processes[i].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) - del self.bitcoind_processes[i] - assert_equal(return_code, 0) + self.nodes[i].stop_node() + while not self.nodes[i].is_node_stopped(): + time.sleep(0.1) def stop_nodes(self): """Stop multiple bitcoind test nodes""" + for node in self.nodes: + # Issue RPC to stop nodes + node.stop_node() - for i in range(len(self.nodes)): - self.stop_node(i) - assert not self.bitcoind_processes.values() # All connections must be gone now + for node in self.nodes: + # Wait for nodes to stop + while not node.is_node_stopped(): + time.sleep(0.1) def assert_start_raises_init_error(self, i, dirname, extra_args=None, expected_msg=None): with tempfile.SpooledTemporaryFile(max_size=2**16) as log_stderr: @@ -272,6 +271,8 @@ class BitcoinTestFramework(object): self.stop_node(i) except Exception as e: assert 'bitcoind exited' in str(e) # node must have shutdown + self.nodes[i].running = False + self.nodes[i].process = None if expected_msg is not None: log_stderr.seek(0) stderr = log_stderr.read().decode('utf-8') @@ -285,7 +286,7 @@ class BitcoinTestFramework(object): raise AssertionError(assert_msg) def wait_for_node_exit(self, i, timeout): - self.bitcoind_processes[i].wait(timeout) + self.nodes[i].process.wait(timeout) def split_network(self): """ @@ -382,18 +383,13 @@ class BitcoinTestFramework(object): args = [os.getenv("BITCOIND", "bitcoind"), "-server", "-keypool=1", "-datadir=" + datadir, "-discover=0"] if i > 0: args.append("-connect=127.0.0.1:" + str(p2p_port(0))) - self.bitcoind_processes[i] = subprocess.Popen(args) - self.log.debug("initialize_chain: bitcoind started, waiting for RPC to come up") - self._wait_for_bitcoind_start(self.bitcoind_processes[i], datadir, i) - self.log.debug("initialize_chain: RPC successfully started") + self.nodes.append(TestNode(i, cachedir, extra_args=[], rpchost=None, timewait=None, binary=None, stderr=None, mocktime=self.mocktime, coverage_dir=None)) + self.nodes[i].args = args + self.nodes[i].start() - self.nodes = [] - for i in range(MAX_NODES): - try: - self.nodes.append(get_rpc_proxy(rpc_url(get_datadir_path(cachedir, i), i), i)) - except: - self.log.exception("Error connecting to node %d" % i) - sys.exit(1) + # Wait for RPC connections to be ready + for node in self.nodes: + node.wait_for_rpc_connection() # Create a 200-block-long chain; each of the 4 first nodes # gets 25 mature blocks and 25 immature. @@ -437,30 +433,6 @@ class BitcoinTestFramework(object): for i in range(num_nodes): initialize_datadir(test_dir, i) - def _wait_for_bitcoind_start(self, process, datadir, i, rpchost=None): - """Wait for bitcoind to start. - - This means that RPC is accessible and fully initialized. - Raise an exception if bitcoind exits during initialization.""" - while True: - if process.poll() is not None: - raise Exception('bitcoind exited with status %i during initialization' % process.returncode) - try: - # Check if .cookie file to be created - rpc = get_rpc_proxy(rpc_url(datadir, i, rpchost), i, coveragedir=self.options.coveragedir) - rpc.getblockcount() - break # break out of loop on success - except IOError as e: - if e.errno != errno.ECONNREFUSED: # Port not yet open? - raise # unknown IO error - except JSONRPCException as e: # Initialization phase - if e.error['code'] != -28: # RPC in warmup? - raise # unknown JSON RPC exception - except ValueError as e: # cookie file not found and no rpcuser or rpcassword. bitcoind still starting - if "No RPC credentials" not in str(e): - raise - time.sleep(0.25) - class ComparisonTestFramework(BitcoinTestFramework): """Test framework for doing p2p comparison testing diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py new file mode 100755 index 0000000000..4b5dc9a792 --- /dev/null +++ b/test/functional/test_framework/test_node.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 +# Copyright (c) 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. +"""Class for bitcoind node under test""" + +import errno +import http.client +import logging +import os +import subprocess +import time + +from .util import ( + assert_equal, + get_rpc_proxy, + rpc_url, +) +from .authproxy import JSONRPCException + +class TestNode(): + """A class for representing a bitcoind node under test. + + This class contains: + + - state about the node (whether it's running, etc) + - a Python subprocess.Popen object representing the running process + - an RPC connection to the node + + To make things easier for the test writer, a bit of magic is happening under the covers. + Any unrecognised messages will be dispatched to the RPC connection.""" + + def __init__(self, i, dirname, extra_args, rpchost, timewait, binary, stderr, mocktime, coverage_dir): + self.index = i + self.datadir = os.path.join(dirname, "node" + str(i)) + self.rpchost = rpchost + self.rpc_timeout = timewait + if binary is None: + self.binary = os.getenv("BITCOIND", "bitcoind") + else: + self.binary = binary + self.stderr = stderr + self.coverage_dir = coverage_dir + # Most callers will just need to add extra args to the standard list below. For those callers that need more flexibity, they can just set the args property directly. + self.extra_args = extra_args + self.args = [self.binary, "-datadir=" + self.datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-logtimemicros", "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", "-mocktime=" + str(mocktime), "-uacomment=testnode%d" % i] + + self.running = False + self.process = None + self.rpc_connected = False + self.rpc = None + self.url = None + self.log = logging.getLogger('TestFramework.node%d' % i) + + def __getattr__(self, *args, **kwargs): + """Dispatches any unrecognised messages to the RPC connection.""" + assert self.rpc_connected and self.rpc is not None, "Error: no RPC connection" + return self.rpc.__getattr__(*args, **kwargs) + + def start(self): + """Start the node.""" + self.process = subprocess.Popen(self.args + self.extra_args, stderr=self.stderr) + self.running = True + self.log.debug("bitcoind started, waiting for RPC to come up") + + def wait_for_rpc_connection(self): + """Sets up an RPC connection to the bitcoind process. Returns False if unable to connect.""" + timeout_s = 60 # Wait for up to 60 seconds for the RPC server to respond + poll_per_s = 4 # Poll at a rate of four times per second + for _ in range(timeout_s*poll_per_s): + assert not self.process.poll(), "bitcoind exited with status %i during initialization" % self.process.returncode + try: + self.rpc = get_rpc_proxy(rpc_url(self.datadir, self.index, self.rpchost), self.index, coveragedir=self.coverage_dir) + self.rpc.getblockcount() + # If the call to getblockcount() succeeds then the RPC connection is up + self.rpc_connected = True + self.url = self.rpc.url + self.log.debug("RPC successfully started") + return + except IOError as e: + if e.errno != errno.ECONNREFUSED: # Port not yet open? + raise # unknown IO error + except JSONRPCException as e: # Initialization phase + if e.error['code'] != -28: # RPC in warmup? + raise # unknown JSON RPC exception + except ValueError as e: # cookie file not found and no rpcuser or rpcassword. bitcoind still starting + if "No RPC credentials" not in str(e): + raise + time.sleep(1.0 / poll_per_s) + raise AssertionError("Unable to connect to bitcoind") + + def get_wallet_rpc(self, wallet_name): + assert self.rpc_connected + assert self.rpc + wallet_path = "wallet/%s" % wallet_name + return self.rpc / wallet_path + + def stop_node(self): + """Stop the node.""" + if not self.running: + return + self.log.debug("Stopping node") + try: + self.stop() + except http.client.CannotSendRequest: + self.log.exception("Unable to stop node.") + + def is_node_stopped(self): + """Checks whether the node has stopped. + + Returns True if the node has stopped. False otherwise. + This method is responsible for freeing resources (self.process).""" + if not self.running: + return True + return_code = self.process.poll() + if return_code is not None: + # process has stopped. Assert that it didn't return an error code. + assert_equal(return_code, 0) + self.running = False + self.process = None + self.log.debug("Node stopped") + return True + return False + + def node_encrypt_wallet(self, passphrase): + """"Encrypts the wallet. + + This causes bitcoind to shutdown, so this method takes + care of cleaning up resources.""" + self.encryptwallet(passphrase) + while not self.is_node_stopped(): + time.sleep(0.1) + self.rpc = None + self.rpc_connected = False diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index acca72aa86..4098fd8615 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -204,7 +204,7 @@ def rpc_port(n): return PORT_MIN + PORT_RANGE + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES) def rpc_url(datadir, i, rpchost=None): - rpc_u, rpc_p = get_auth_cookie(datadir, i) + rpc_u, rpc_p = get_auth_cookie(datadir) host = '127.0.0.1' port = rpc_port(i) if rpchost: @@ -232,7 +232,7 @@ def initialize_datadir(dirname, n): def get_datadir_path(dirname, n): return os.path.join(dirname, "node" + str(n)) -def get_auth_cookie(datadir, n): +def get_auth_cookie(datadir): user = None password = None if os.path.isfile(os.path.join(datadir, "bitcoin.conf")): diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index a043560ea8..d248a6c005 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -79,6 +79,7 @@ BASE_SCRIPTS= [ 'rawtransactions.py', 'reindex.py', # vv Tests less than 30s vv + 'keypool-topup.py', 'zmq_test.py', 'mempool_resurrect_test.py', 'txn_doublespend.py --mineblock', @@ -115,7 +116,10 @@ BASE_SCRIPTS= [ 'listsinceblock.py', 'p2p-leaktests.py', 'wallet-encryption.py', + 'bipdersig-p2p.py', + 'bip65-cltv-p2p.py', 'uptime.py', + 'resendwallettransactions.py', ] EXTENDED_SCRIPTS = [ @@ -138,10 +142,6 @@ EXTENDED_SCRIPTS = [ 'rpcbind_test.py', # vv Tests less than 30s vv 'assumevalid.py', - 'bip65-cltv.py', - 'bip65-cltv-p2p.py', - 'bipdersig-p2p.py', - 'bipdersig.py', 'example_test.py', 'txn_doublespend.py', 'txn_clone.py --mineblock', @@ -170,7 +170,7 @@ def main(): Help text and arguments for individual test script:''', formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface') - parser.add_argument('--exclude', '-x', help='specify a comma-seperated-list of scripts to exclude.') + parser.add_argument('--exclude', '-x', help='specify a comma-separated-list of scripts to exclude.') parser.add_argument('--extended', action='store_true', help='run the extended test suite in addition to the basic tests') parser.add_argument('--force', '-f', action='store_true', help='run tests even on platforms where they are disabled by default (e.g. windows).') parser.add_argument('--help', '-h', '-?', action='store_true', help='print help text and exit') @@ -352,7 +352,7 @@ def print_results(test_results, max_len_name, runtime): class TestHandler: """ - Trigger the testscrips passed in via the list. + Trigger the test scripts passed in via the list. """ def __init__(self, num_tests_parallel, tests_dir, tmpdir, test_list=None, flags=None): diff --git a/test/functional/wallet-dump.py b/test/functional/wallet-dump.py index 569cc46e6c..61ad00330b 100755 --- a/test/functional/wallet-dump.py +++ b/test/functional/wallet-dump.py @@ -94,8 +94,7 @@ class WalletDumpTest(BitcoinTestFramework): assert_equal(found_addr_rsv, 90*2) # 90 keys plus 100% internal keys #encrypt wallet, restart, unlock and dump - self.nodes[0].encryptwallet('test') - self.bitcoind_processes[0].wait() + self.nodes[0].node_encrypt_wallet('test') self.nodes[0] = self.start_node(0, self.options.tmpdir, self.extra_args[0]) self.nodes[0].walletpassphrase('test', 10) # Should be a no-op: diff --git a/test/functional/wallet-encryption.py b/test/functional/wallet-encryption.py index ba72918fe1..8fea4140db 100755 --- a/test/functional/wallet-encryption.py +++ b/test/functional/wallet-encryption.py @@ -30,8 +30,7 @@ class WalletEncryptionTest(BitcoinTestFramework): assert_equal(len(privkey), 52) # Encrypt the wallet - self.nodes[0].encryptwallet(passphrase) - self.bitcoind_processes[0].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) + self.nodes[0].node_encrypt_wallet(passphrase) self.nodes[0] = self.start_node(0, self.options.tmpdir) # Test that the wallet is encrypted diff --git a/test/functional/wallet-hd.py b/test/functional/wallet-hd.py index dfd3dc83c5..751512301e 100755 --- a/test/functional/wallet-hd.py +++ b/test/functional/wallet-hd.py @@ -9,7 +9,6 @@ from test_framework.util import ( assert_equal, connect_nodes_bi, ) -import os import shutil @@ -43,7 +42,7 @@ class WalletHDTest(BitcoinTestFramework): non_hd_add = self.nodes[0].getnewaddress() self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add)) - # This should be enough to keep the master key and the non-HD key + # This should be enough to keep the master key and the non-HD key self.nodes[1].backupwallet(tmpdir + "/hd.bak") #self.nodes[1].dumpwallet(tmpdir + "/hd.dump") @@ -55,7 +54,7 @@ class WalletHDTest(BitcoinTestFramework): for i in range(num_hd_adds): hd_add = self.nodes[1].getnewaddress() hd_info = self.nodes[1].validateaddress(hd_add) - assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(i+1)+"'") + assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(i)+"'") assert_equal(hd_info["hdmasterkeyid"], masterkeyid) self.nodes[0].sendtoaddress(hd_add, 1) self.nodes[0].generate(1) @@ -72,24 +71,27 @@ class WalletHDTest(BitcoinTestFramework): self.log.info("Restore backup ...") self.stop_node(1) - os.remove(self.options.tmpdir + "/node1/regtest/wallet.dat") + # we need to delete the complete regtest directory + # otherwise node1 would auto-recover all funds in flag the keypool keys as used + shutil.rmtree(tmpdir + "/node1/regtest/blocks") + shutil.rmtree(tmpdir + "/node1/regtest/chainstate") shutil.copyfile(tmpdir + "/hd.bak", tmpdir + "/node1/regtest/wallet.dat") self.nodes[1] = self.start_node(1, self.options.tmpdir, self.extra_args[1]) - #connect_nodes_bi(self.nodes, 0, 1) # Assert that derivation is deterministic hd_add_2 = None for _ in range(num_hd_adds): hd_add_2 = self.nodes[1].getnewaddress() hd_info_2 = self.nodes[1].validateaddress(hd_add_2) - assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/"+str(_+1)+"'") + assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/"+str(_)+"'") assert_equal(hd_info_2["hdmasterkeyid"], masterkeyid) assert_equal(hd_add, hd_add_2) + connect_nodes_bi(self.nodes, 0, 1) + self.sync_all() # Needs rescan self.stop_node(1) self.nodes[1] = self.start_node(1, self.options.tmpdir, self.extra_args[1] + ['-rescan']) - #connect_nodes_bi(self.nodes, 0, 1) assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1) # send a tx and make sure its using the internal chain for the changeoutput @@ -99,7 +101,7 @@ class WalletHDTest(BitcoinTestFramework): for out in outs: if out['value'] != 1: keypath = self.nodes[1].validateaddress(out['scriptPubKey']['addresses'][0])['hdkeypath'] - + assert_equal(keypath[0:7], "m/0'/1'") if __name__ == '__main__': diff --git a/test/util/data/tt-delin1-out.json b/test/util/data/tt-delin1-out.json index f6dfbb51cc..0b3235dd4a 100644 --- a/test/util/data/tt-delin1-out.json +++ b/test/util/data/tt-delin1-out.json @@ -189,7 +189,7 @@ ], "vout": [ { - "value": 1.3782, + "value": 1.37820000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", diff --git a/test/util/data/tt-delout1-out.json b/test/util/data/tt-delout1-out.json index 6769ed79ff..5b69d0cd86 100644 --- a/test/util/data/tt-delout1-out.json +++ b/test/util/data/tt-delout1-out.json @@ -198,7 +198,7 @@ ], "vout": [ { - "value": 1.3782, + "value": 1.37820000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", diff --git a/test/util/data/tt-locktime317000-out.json b/test/util/data/tt-locktime317000-out.json index 82b64df075..cf1ebcdf38 100644 --- a/test/util/data/tt-locktime317000-out.json +++ b/test/util/data/tt-locktime317000-out.json @@ -198,7 +198,7 @@ ], "vout": [ { - "value": 1.3782, + "value": 1.37820000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", diff --git a/test/util/data/txcreate1.json b/test/util/data/txcreate1.json index 36741044c9..edb091f946 100644 --- a/test/util/data/txcreate1.json +++ b/test/util/data/txcreate1.json @@ -36,7 +36,7 @@ ], "vout": [ { - "value": 0.18, + "value": 0.18000000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", @@ -49,7 +49,7 @@ } }, { - "value": 4.00, + "value": 4.00000000, "n": 1, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG", diff --git a/test/util/data/txcreate2.json b/test/util/data/txcreate2.json index 23fe7ace67..cca00f752b 100644 --- a/test/util/data/txcreate2.json +++ b/test/util/data/txcreate2.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 0.00, + "value": 0.00000000, "n": 0, "scriptPubKey": { "asm": "", diff --git a/test/util/data/txcreatedata1.json b/test/util/data/txcreatedata1.json index e65a1859eb..e66a6bb9a5 100644 --- a/test/util/data/txcreatedata1.json +++ b/test/util/data/txcreatedata1.json @@ -18,7 +18,7 @@ ], "vout": [ { - "value": 0.18, + "value": 0.18000000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", @@ -31,7 +31,7 @@ } }, { - "value": 4.00, + "value": 4.00000000, "n": 1, "scriptPubKey": { "asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", diff --git a/test/util/data/txcreatedata2.json b/test/util/data/txcreatedata2.json index 8f1544e1c0..0f8edcafdd 100644 --- a/test/util/data/txcreatedata2.json +++ b/test/util/data/txcreatedata2.json @@ -18,7 +18,7 @@ ], "vout": [ { - "value": 0.18, + "value": 0.18000000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", @@ -31,7 +31,7 @@ } }, { - "value": 0.00, + "value": 0.00000000, "n": 1, "scriptPubKey": { "asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", diff --git a/test/util/data/txcreatedata_seq0.json b/test/util/data/txcreatedata_seq0.json index e52401f418..4b5a7cab4a 100644 --- a/test/util/data/txcreatedata_seq0.json +++ b/test/util/data/txcreatedata_seq0.json @@ -18,7 +18,7 @@ ], "vout": [ { - "value": 0.18, + "value": 0.18000000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", diff --git a/test/util/data/txcreatedata_seq1.json b/test/util/data/txcreatedata_seq1.json index 093ff4a56b..771ff1bb10 100644 --- a/test/util/data/txcreatedata_seq1.json +++ b/test/util/data/txcreatedata_seq1.json @@ -27,7 +27,7 @@ ], "vout": [ { - "value": 0.18, + "value": 0.18000000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", diff --git a/test/util/data/txcreatemultisig1.json b/test/util/data/txcreatemultisig1.json index 0cc530836a..7c814dad83 100644 --- a/test/util/data/txcreatemultisig1.json +++ b/test/util/data/txcreatemultisig1.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 1.00, + "value": 1.00000000, "n": 0, "scriptPubKey": { "asm": "2 02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d 02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485 3 OP_CHECKMULTISIG", diff --git a/test/util/data/txcreatemultisig2.json b/test/util/data/txcreatemultisig2.json index 8ad2ffdc65..7d94ce7396 100644 --- a/test/util/data/txcreatemultisig2.json +++ b/test/util/data/txcreatemultisig2.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 1.00, + "value": 1.00000000, "n": 0, "scriptPubKey": { "asm": "OP_HASH160 1c6fbaf46d64221e80cbae182c33ddf81b9294ac OP_EQUAL", diff --git a/test/util/data/txcreatemultisig3.json b/test/util/data/txcreatemultisig3.json index 086bf44b8a..06e093e224 100644 --- a/test/util/data/txcreatemultisig3.json +++ b/test/util/data/txcreatemultisig3.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 1.00, + "value": 1.00000000, "n": 0, "scriptPubKey": { "asm": "0 e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05", diff --git a/test/util/data/txcreatemultisig4.json b/test/util/data/txcreatemultisig4.json index d23ccc045e..9a5d2f4a06 100644 --- a/test/util/data/txcreatemultisig4.json +++ b/test/util/data/txcreatemultisig4.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 1.00, + "value": 1.00000000, "n": 0, "scriptPubKey": { "asm": "OP_HASH160 6edf12858999f0dae74f9c692e6694ee3621b2ac OP_EQUAL", diff --git a/test/util/data/txcreateoutpubkey1.json b/test/util/data/txcreateoutpubkey1.json index f10aaecf7a..2704ed7673 100644 --- a/test/util/data/txcreateoutpubkey1.json +++ b/test/util/data/txcreateoutpubkey1.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 0.00, + "value": 0.00000000, "n": 0, "scriptPubKey": { "asm": "02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 OP_CHECKSIG", diff --git a/test/util/data/txcreateoutpubkey2.json b/test/util/data/txcreateoutpubkey2.json index 5a473b76c3..5144722230 100644 --- a/test/util/data/txcreateoutpubkey2.json +++ b/test/util/data/txcreateoutpubkey2.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 0.00, + "value": 0.00000000, "n": 0, "scriptPubKey": { "asm": "0 a2516e770582864a6a56ed21a102044e388c62e3", diff --git a/test/util/data/txcreateoutpubkey3.json b/test/util/data/txcreateoutpubkey3.json index b8389b8f7e..0a5d489e15 100644 --- a/test/util/data/txcreateoutpubkey3.json +++ b/test/util/data/txcreateoutpubkey3.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 0.00, + "value": 0.00000000, "n": 0, "scriptPubKey": { "asm": "OP_HASH160 a5ab14c9804d0d8bf02f1aea4e82780733ad0a83 OP_EQUAL", diff --git a/test/util/data/txcreatescript1.json b/test/util/data/txcreatescript1.json index 823168e9fb..5072452fed 100644 --- a/test/util/data/txcreatescript1.json +++ b/test/util/data/txcreatescript1.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 0.00, + "value": 0.00000000, "n": 0, "scriptPubKey": { "asm": "OP_DROP", diff --git a/test/util/data/txcreatescript2.json b/test/util/data/txcreatescript2.json index d4c7e10c78..94b669ffb6 100644 --- a/test/util/data/txcreatescript2.json +++ b/test/util/data/txcreatescript2.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 0.00, + "value": 0.00000000, "n": 0, "scriptPubKey": { "asm": "OP_HASH160 71ed53322d470bb96657deb786b94f97dd46fb15 OP_EQUAL", diff --git a/test/util/data/txcreatescript3.json b/test/util/data/txcreatescript3.json index 001e69511f..980da2fb31 100644 --- a/test/util/data/txcreatescript3.json +++ b/test/util/data/txcreatescript3.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 0.00, + "value": 0.00000000, "n": 0, "scriptPubKey": { "asm": "0 0bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6", diff --git a/test/util/data/txcreatescript4.json b/test/util/data/txcreatescript4.json index 20094bcd44..eecdf858b7 100644 --- a/test/util/data/txcreatescript4.json +++ b/test/util/data/txcreatescript4.json @@ -9,7 +9,7 @@ ], "vout": [ { - "value": 0.00, + "value": 0.00000000, "n": 0, "scriptPubKey": { "asm": "OP_HASH160 6a2c482f4985f57e702f325816c90e3723ca81ae OP_EQUAL", diff --git a/test/util/data/txcreatesignv1.json b/test/util/data/txcreatesignv1.json index 519d3ab066..92a3f76a07 100644 --- a/test/util/data/txcreatesignv1.json +++ b/test/util/data/txcreatesignv1.json @@ -18,7 +18,7 @@ ], "vout": [ { - "value": 0.001, + "value": 0.00100000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG", |