aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE.md2
-rw-r--r--.travis.yml32
-rwxr-xr-x.travis/test_04_install.sh2
-rw-r--r--CONTRIBUTING.md3
-rw-r--r--COPYING4
-rw-r--r--build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in6
-rw-r--r--configure.ac2
-rw-r--r--contrib/debian/copyright2
-rwxr-xr-xcontrib/macdeploy/custom_dsstore.py2
-rw-r--r--depends/packages/bdb.mk1
-rw-r--r--doc/developer-notes.md31
-rw-r--r--doc/man/bitcoin-cli.143
-rw-r--r--doc/man/bitcoin-qt.168
-rw-r--r--doc/man/bitcoin-tx.119
-rw-r--r--doc/man/bitcoind.169
-rw-r--r--doc/release-notes-14060.md21
-rw-r--r--doc/release-notes-14477.md5
-rw-r--r--doc/release-notes-14565.md5
-rw-r--r--doc/release-notes-pr13381.md29
-rw-r--r--doc/release-notes.md107
-rw-r--r--src/amount.h2
-rw-r--r--src/compat.h9
-rw-r--r--src/consensus/tx_verify.cpp2
-rw-r--r--src/fs.h2
-rw-r--r--src/init.cpp7
-rw-r--r--src/key_io.cpp2
-rw-r--r--src/net.cpp181
-rw-r--r--src/net.h8
-rw-r--r--src/netbase.cpp21
-rw-r--r--src/noui.h2
-rw-r--r--src/qt/bitcoin.cpp4
-rw-r--r--src/qt/bitcoingui.cpp30
-rw-r--r--src/qt/bitcoingui.h4
-rw-r--r--src/qt/forms/optionsdialog.ui2
-rw-r--r--src/qt/guiconstants.h1
-rw-r--r--src/qt/networkstyle.cpp2
-rw-r--r--src/qt/notificator.cpp20
-rw-r--r--src/qt/notificator.h6
-rw-r--r--src/qt/rpcconsole.cpp41
-rw-r--r--src/qt/rpcconsole.h12
-rw-r--r--src/qt/walletframe.cpp31
-rw-r--r--src/qt/walletframe.h8
-rw-r--r--src/qt/walletmodel.cpp8
-rw-r--r--src/qt/walletmodel.h3
-rw-r--r--src/rest.cpp17
-rw-r--r--src/rpc/blockchain.cpp57
-rw-r--r--src/rpc/blockchain.h4
-rw-r--r--src/rpc/net.cpp14
-rw-r--r--src/streams.h26
-rw-r--r--src/test/blockchain_tests.cpp7
-rw-r--r--src/test/key_io_tests.cpp2
-rw-r--r--src/test/script_p2sh_tests.cpp24
-rw-r--r--src/test/streams_tests.cpp10
-rw-r--r--src/test/transaction_tests.cpp8
-rw-r--r--src/test/txvalidation_tests.cpp2
-rw-r--r--src/threadinterrupt.h2
-rw-r--r--src/validation.cpp10
-rw-r--r--src/wallet/test/wallet_tests.cpp4
-rw-r--r--test/functional/data/invalid_txs.py180
-rwxr-xr-xtest/functional/feature_assumevalid.py2
-rwxr-xr-xtest/functional/feature_block.py77
-rwxr-xr-xtest/functional/feature_dbcrash.py2
-rwxr-xr-xtest/functional/feature_pruning.py2
-rwxr-xr-xtest/functional/mempool_accept.py2
-rwxr-xr-xtest/functional/p2p_invalid_locator.py2
-rwxr-xr-xtest/functional/p2p_invalid_tx.py24
-rwxr-xr-xtest/functional/rpc_bind.py2
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py2
-rwxr-xr-xtest/functional/rpc_net.py4
-rwxr-xr-xtest/functional/rpc_rawtransaction.py2
-rw-r--r--test/functional/test_framework/blocktools.py2
-rwxr-xr-xtest/functional/test_framework/test_framework.py40
-rwxr-xr-xtest/functional/wallet_backup.py2
-rwxr-xr-xtest/functional/wallet_dump.py2
-rwxr-xr-xtest/functional/wallet_groups.py2
-rwxr-xr-xtest/functional/wallet_listtransactions.py3
-rwxr-xr-xtest/lint/lint-python-dead-code.sh2
-rw-r--r--test/sanitizer_suppressions/ubsan1
78 files changed, 904 insertions, 499 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 55cebc008f..8768a8ca6b 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -17,5 +17,7 @@ If the node is "stuck" during sync or giving "block checksum mismatch" errors, p
<!-- What type of machine are you observing the error on (OS/CPU and disk type)? -->
+<!-- For the GUI-related issue on Linux provide names and versions of a distro, a desktop environment and a graphical shell (if relevant). -->
+
<!-- Any extra information that might be useful in the debugging process. -->
<!--- This is normally the contents of a `debug.log` or `config.log` file. Raw text or a link to a pastebin type site are preferred. -->
diff --git a/.travis.yml b/.travis.yml
index 7abc6e8ffd..6181726fb6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,4 @@
-dist: trusty
+dist: xenial
os: linux
language: minimal
cache:
@@ -38,8 +38,9 @@ after_script:
- echo $TRAVIS_COMMIT_LOG
jobs:
include:
-# lint stage
+
- stage: lint
+ name: 'lint'
env:
cache: false
language: python
@@ -50,8 +51,9 @@ jobs:
- set -o errexit; source .travis/lint_05_before_script.sh
script:
- set -o errexit; source .travis/lint_06_script.sh
-# ARM
+
- stage: test
+ name: 'ARM [GOAL: install] [no unit or functional tests]'
env: >-
HOST=arm-linux-gnueabihf
PACKAGES="python3 g++-arm-linux-gnueabihf"
@@ -61,39 +63,44 @@ jobs:
# -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1"
# This could be removed once the ABI change warning does not show up by default
BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CXXFLAGS=-Wno-psabi"
-# Win32
+
- stage: test
+ name: 'Win32 [GOAL: deploy] [no gui tests]'
env: >-
HOST=i686-w64-mingw32
DPKG_ADD_ARCH="i386"
PACKAGES="python3 nsis g++-mingw-w64-i686 wine-binfmt wine32"
GOAL="deploy"
BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests"
-# Win64
+
- stage: test
+ name: 'Win64 [GOAL: deploy] [no gui tests]'
env: >-
HOST=x86_64-w64-mingw32
PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64"
GOAL="deploy"
BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests"
-# 32-bit + dash
+
- stage: test
+ name: '32-bit + dash [GOAL: install]'
env: >-
HOST=i686-pc-linux-gnu
PACKAGES="g++-multilib python3-zmq"
GOAL="install"
BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++"
CONFIG_SHELL="/bin/dash"
-# x86_64 Linux (uses qt5 dev package instead of depends Qt to speed up build and avoid timeout)
+
- stage: test
+ name: 'x86_64 Linux [GOAL: install] [bionic] [uses qt5 dev package instead of depends Qt to speed up build and avoid timeout]'
env: >-
HOST=x86_64-unknown-linux-gnu
PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools protobuf-compiler libdbus-1-dev libharfbuzz-dev libprotobuf-dev"
DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1"
GOAL="install"
BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --enable-debug CXXFLAGS=\"-g0 -O2\""
-# x86_64 Linux (xenial, no depends, only system libs, sanitizers: thread (TSan))
+
- stage: test
+ name: 'x86_64 Linux [GOAL: install] [xenial] [no depends, only system libs, sanitizers: thread (TSan), no wallet]'
env: >-
HOST=x86_64-unknown-linux-gnu
DOCKER_NAME_TAG=ubuntu:16.04
@@ -101,8 +108,9 @@ jobs:
NO_DEPENDS=1
GOAL="install"
BITCOIN_CONFIG="--enable-zmq --disable-wallet --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER --with-sanitizers=thread --disable-hardening --disable-asm CC=clang CXX=clang++"
-# x86_64 Linux (no depends, only system libs, sanitizers: address/leak (ASan + LSan) + undefined (UBSan) + integer)
+
- stage: test
+ name: 'x86_64 Linux [GOAL: install] [bionic] [no depends, only system libs, sanitizers: address/leak (ASan + LSan) + undefined (UBSan) + integer]'
env: >-
HOST=x86_64-unknown-linux-gnu
PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev"
@@ -110,16 +118,18 @@ jobs:
FUNCTIONAL_TESTS_CONFIG="--exclude wallet_multiwallet.py" # Temporarily suppress ASan heap-use-after-free (see issue #14163)
GOAL="install"
BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER --with-sanitizers=address,integer,undefined CC=clang CXX=clang++"
-# x86_64 Linux, No wallet
+
- stage: test
+ name: 'x86_64 Linux [GOAL: install] [bionic] [no wallet]'
env: >-
HOST=x86_64-unknown-linux-gnu
PACKAGES="python3-zmq"
DEP_OPTS="NO_WALLET=1"
GOAL="install"
BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
-# Cross-Mac
+
- stage: test
+ name: 'macOS 10.10 [GOAL: deploy]'
env: >-
HOST=x86_64-apple-darwin14
PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git"
diff --git a/.travis/test_04_install.sh b/.travis/test_04_install.sh
index 3f74158117..a111387f10 100755
--- a/.travis/test_04_install.sh
+++ b/.travis/test_04_install.sh
@@ -15,6 +15,8 @@ export UBSAN_OPTIONS="suppressions=${TRAVIS_BUILD_DIR}/test/sanitizer_suppressio
env | grep -E '^(BITCOIN_CONFIG|CCACHE_|WINEDEBUG|LC_ALL|BOOST_TEST_RANDOM|CONFIG_SHELL|(ASAN|LSAN|TSAN|UBSAN)_OPTIONS)' | tee /tmp/env
if [[ $HOST = *-mingw32 ]]; then
DOCKER_ADMIN="--cap-add SYS_ADMIN"
+elif [[ $BITCOIN_CONFIG = *--with-sanitizers=*address* ]]; then # If ran with (ASan + LSan), Docker needs access to ptrace (https://github.com/google/sanitizers/issues/764)
+ DOCKER_ADMIN="--cap-add SYS_PTRACE"
fi
DOCKER_ID=$(docker run $DOCKER_ADMIN -idt --mount type=bind,src=$TRAVIS_BUILD_DIR,dst=$TRAVIS_BUILD_DIR --mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR -w $TRAVIS_BUILD_DIR --env-file /tmp/env $DOCKER_NAME_TAG)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 08b2fa609e..139fe7dc52 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -25,7 +25,8 @@ Most communication about Bitcoin Core development happens on IRC, in the
#bitcoin-core-dev channel on Freenode. The easiest way to participate on IRC is
with the web client, [webchat.freenode.net](https://webchat.freenode.net/). Chat
history logs can be found
-on [botbot.me](https://botbot.me/freenode/bitcoin-core-dev/).
+on [http://www.erisian.com.au/bitcoin-core-dev/](http://www.erisian.com.au/bitcoin-core-dev/)
+and [http://gnusha.org/bitcoin-core-dev/](http://gnusha.org/bitcoin-core-dev/).
Discussion about code base improvements happens in GitHub issues and on pull
requests.
diff --git a/COPYING b/COPYING
index 9704b9c94c..9d54ecbde1 100644
--- a/COPYING
+++ b/COPYING
@@ -1,7 +1,7 @@
The MIT License (MIT)
-Copyright (c) 2009-2018 The Bitcoin Core developers
-Copyright (c) 2009-2018 Bitcoin Developers
+Copyright (c) 2009-2019 The Bitcoin Core developers
+Copyright (c) 2009-2019 Bitcoin Developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in b/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in
index 0a165d0b75..e66277123a 100644
--- a/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in
+++ b/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in
@@ -154,12 +154,6 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="..\..\src\rpc\net.cpp">
- <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\netrpc.obj</ObjectFileName>
- <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)\netrpc.obj</ObjectFileName>
- <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)\netrpc.obj</ObjectFileName>
- <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)\netrpc.obj</ObjectFileName>
- </ClCompile>
@SOURCE_FILES@
</ItemGroup>
<ItemGroup>
diff --git a/configure.ac b/configure.ac
index 2d34b83047..4b34082270 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,7 @@ define(_CLIENT_VERSION_REVISION, 99)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_RC, 0)
define(_CLIENT_VERSION_IS_RELEASE, false)
-define(_COPYRIGHT_YEAR, 2018)
+define(_COPYRIGHT_YEAR, 2019)
define(_COPYRIGHT_HOLDERS,[The %s developers])
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitcoin Core]])
AC_INIT([Bitcoin Core],m4_join([.], _CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MINOR, _CLIENT_VERSION_REVISION, m4_if(_CLIENT_VERSION_BUILD, [0], [], _CLIENT_VERSION_BUILD))m4_if(_CLIENT_VERSION_RC, [0], [], [rc]_CLIENT_VERSION_RC),[https://github.com/bitcoin/bitcoin/issues],[bitcoin],[https://bitcoincore.org/])
diff --git a/contrib/debian/copyright b/contrib/debian/copyright
index e5b9cbaa40..2d5b0188d2 100644
--- a/contrib/debian/copyright
+++ b/contrib/debian/copyright
@@ -5,7 +5,7 @@ Upstream-Contact: Satoshi Nakamoto <satoshin@gmx.com>
Source: https://github.com/bitcoin/bitcoin
Files: *
-Copyright: 2009-2018, Bitcoin Core Developers
+Copyright: 2009-2019, Bitcoin Core Developers
License: Expat
Comment: The Bitcoin Core Developers encompasses the current developers listed on bitcoin.org,
as well as the numerous contributors to the project.
diff --git a/contrib/macdeploy/custom_dsstore.py b/contrib/macdeploy/custom_dsstore.py
index c29f83a91e..dc1c1882dd 100755
--- a/contrib/macdeploy/custom_dsstore.py
+++ b/contrib/macdeploy/custom_dsstore.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2013-2017 The Bitcoin Core developers
+# Copyright (c) 2013-2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
import biplist
diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk
index 6c9876c2c7..3cd2e28858 100644
--- a/depends/packages/bdb.mk
+++ b/depends/packages/bdb.mk
@@ -10,6 +10,7 @@ $(package)_config_opts=--disable-shared --enable-cxx --disable-replication
$(package)_config_opts_mingw32=--enable-mingw
$(package)_config_opts_linux=--with-pic
$(package)_cxxflags=-std=c++11
+$(package)_cppflags_mingw32=-DUNICODE -D_UNICODE
endef
define $(package)_preprocess_cmds
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index a6df17ddd8..e0def4ea27 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -7,8 +7,8 @@ Developer Notes
- [Developer Notes](#developer-notes)
- [Coding Style (General)](#coding-style-general)
- [Coding Style (C++)](#coding-style-c)
- - [Doxygen comments](#doxygen-comments)
- [Coding Style (Python)](#coding-style-python)
+ - [Coding Style (Doxygen-compatible comments)](#coding-style-doxygen-compatible-comments)
- [Development tips and tricks](#development-tips-and-tricks)
- [Compiling for debugging](#compiling-for-debugging)
- [Compiling for gprof profiling](#compiling-for-gprof-profiling)
@@ -120,10 +120,17 @@ public:
} // namespace foo
```
-Doxygen comments
------------------
+Coding Style (Python)
+---------------------
+
+Refer to [/test/functional/README.md#style-guidelines](/test/functional/README.md#style-guidelines).
-To facilitate the generation of documentation, use doxygen-compatible comment blocks for functions, methods and fields.
+Coding Style (Doxygen-compatible comments)
+------------------------------------------
+
+Bitcoin Core uses [Doxygen](http://www.doxygen.nl/) to generate its official documentation.
+
+Use Doxygen-compatible comment blocks for functions, methods, and fields.
For example, to describe a function use:
```c++
@@ -156,7 +163,7 @@ int var; //!< Detailed description after the member
```
or
-```cpp
+```c++
//! Description before the member
int var;
```
@@ -176,15 +183,15 @@ Not OK (used plenty in the current source, but not picked up):
//
```
-A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
-but if possible use one of the above styles.
-
-Documentation can be generated with `make docs` and cleaned up with `make clean-docs`.
+A full list of comment syntaxes picked up by Doxygen can be found at https://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
+but the above styles are favored.
-Coding Style (Python)
----------------------
+Documentation can be generated with `make docs` and cleaned up with `make clean-docs`. The resulting files are located in `doc/doxygen/html`; open `index.html` to view the homepage.
-Refer to [/test/functional/README.md#style-guidelines](/test/functional/README.md#style-guidelines).
+Before running `make docs`, you will need to install dependencies `doxygen` and `dot`. For example, on MacOS via Homebrew:
+```
+brew install doxygen --with-graphviz
+```
Development tips and tricks
---------------------------
diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1
index bf24d929bc..553addfa84 100644
--- a/doc/man/bitcoin-cli.1
+++ b/doc/man/bitcoin-cli.1
@@ -1,17 +1,21 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
-.TH BITCOIN-CLI "1" "July 2018" "bitcoin-cli v0.16.99.0" "User Commands"
+.TH BITCOIN-CLI "1" "December 2018" "bitcoin-cli v0.17.99.0" "User Commands"
.SH NAME
-bitcoin-cli \- manual page for bitcoin-cli v0.16.99.0
+bitcoin-cli \- manual page for bitcoin-cli v0.17.99.0
+.SH SYNOPSIS
+.B bitcoin-cli
+[\fI\,options\/\fR] \fI\,<command> \/\fR[\fI\,params\/\fR] \fI\,Send command to Bitcoin Core\/\fR
+.br
+.B bitcoin-cli
+[\fI\,options\/\fR] \fI\,-named <command> \/\fR[\fI\,name=value\/\fR]... \fI\,Send command to Bitcoin Core (with named arguments)\/\fR
+.br
+.B bitcoin-cli
+[\fI\,options\/\fR] \fI\,help List commands\/\fR
+.br
+.B bitcoin-cli
+[\fI\,options\/\fR] \fI\,help <command> Get help for a command\/\fR
.SH DESCRIPTION
-Bitcoin Core RPC client version v0.16.99.0
-.SS "Usage:"
-.TP
-bitcoin\-cli [options] <command> [params]
-Send command to Bitcoin Core
-.IP
-bitcoin\-cli [options] \fB\-named\fR <command> [name=value] ... Send command to Bitcoin Core (with named arguments)
-bitcoin\-cli [options] help List commands
-bitcoin\-cli [options] help <command> Get help for a command
+Bitcoin Core RPC client version v0.17.99.0
.SH OPTIONS
.HP
\-?
@@ -59,7 +63,8 @@ Password for JSON\-RPC connections
.HP
\fB\-rpcport=\fR<port>
.IP
-Connect to JSON\-RPC on <port> (default: 8332 or testnet: 18332)
+Connect to JSON\-RPC on <port> (default: 8332, testnet: 18332, regtest:
+18443)
.HP
\fB\-rpcuser=\fR<user>
.IP
@@ -72,20 +77,20 @@ Wait for RPC server to start
\fB\-rpcwallet=\fR<walletname>
.IP
Send RPC for non\-default wallet on RPC server (needs to exactly match
-corresponding \fB\-wallet\fR option passed to bitcoind)
+corresponding \fB\-wallet\fR option passed to bitcoind). This changes
+the RPC endpoint used, e.g.
+http://127.0.0.1:8332/wallet/<walletname>
.HP
\fB\-stdin\fR
.IP
Read extra arguments from standard input, one per line until EOF/Ctrl\-D
-(recommended for sensitive information such as passphrases).
-When combined with \fB\-stdinrpcpass\fR, the first line from standard
-input is used for the RPC password.
+(recommended for sensitive information such as passphrases). When
+combined with \fB\-stdinrpcpass\fR, the first line from standard input
+is used for the RPC password.
.HP
\fB\-stdinrpcpass\fR
-.TP
-Read RPC password from standard input as a single line.
-When combined
.IP
+Read RPC password from standard input as a single line. When combined
with \fB\-stdin\fR, the first line from standard input is used for the
RPC password.
.HP
diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1
index 3a18c9f49f..1d87acd3de 100644
--- a/doc/man/bitcoin-qt.1
+++ b/doc/man/bitcoin-qt.1
@@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
-.TH BITCOIN-QT "1" "July 2018" "bitcoin-qt v0.16.99.0" "User Commands"
+.TH BITCOIN-QT "1" "December 2018" "bitcoin-qt v0.17.99.0" "User Commands"
.SH NAME
-bitcoin-qt \- manual page for bitcoin-qt v0.16.99.0
+bitcoin-qt \- manual page for bitcoin-qt v0.17.99.0
+.SH SYNOPSIS
+.B bitcoin-qt
+[\fI\,command-line options\/\fR]
.SH DESCRIPTION
-Bitcoin Core version v0.16.99.0 (64\-bit)
-Usage:
-.IP
-bitcoin\-qt [command\-line options]
+Bitcoin Core version v0.17.99.0 (64\-bit)
.SH OPTIONS
.HP
\-?
@@ -23,9 +23,9 @@ long fork (%s in cmd is replaced by message)
If this block is in the chain assume that it and its ancestors are valid
and potentially skip their script verification (0 to verify all,
default:
-0000000000000000005214481d2d96f898e3d5416e43359c145944a909d242e0,
+0000000000000000002e63058c023a9a1de233554f28c7b21380b6c9003f36a8,
testnet:
-0000000002e9e7b00e1f6dc5123a04aad68dd0f0968d8c7aa45f6640795c37b1)
+0000000000000037a8cd3e06cd5edbfe9dd1dbcc5dacab279376ef7cfc2b4c75)
.HP
\fB\-blocknotify=\fR<cmd>
.IP
@@ -61,7 +61,8 @@ Set database cache size in megabytes (4 to 16384, default: 450)
\fB\-debuglogfile=\fR<file>
.IP
Specify location of debug log file. Relative paths will be prefixed by a
-net\-specific datadir location. (0 to disable; default: debug.log)
+net\-specific datadir location. (\fB\-nodebuglogfile\fR to disable;
+default: debug.log)
.HP
\fB\-includeconf=\fR<file>
.IP
@@ -108,7 +109,7 @@ blocks if a target size in MiB is provided. This mode is
incompatible with \fB\-txindex\fR and \fB\-rescan\fR. Warning: Reverting this
setting requires re\-downloading the entire blockchain. (default:
0 = disable pruning blocks, 1 = allow manual pruning via RPC,
->550 = automatically prune block files to stay under the
+>=550 = automatically prune block files to stay under the
specified target size in MiB)
.HP
\fB\-reindex\fR
@@ -117,7 +118,9 @@ Rebuild chain state and block index from the blk*.dat files on disk
.HP
\fB\-reindex\-chainstate\fR
.IP
-Rebuild chain state from the currently indexed blocks
+Rebuild chain state from the currently indexed blocks. When in pruning
+mode or if blocks on disk might be corrupted, use full \fB\-reindex\fR
+instead.
.HP
\fB\-sysperms\fR
.IP
@@ -157,7 +160,7 @@ for IPv6
.HP
\fB\-connect=\fR<ip>
.IP
-Connect only to the specified node; \fB\-connect\fR=\fI\,0\/\fR disables automatic
+Connect only to the specified node; \fB\-noconnect\fR disables automatic
connections (the rules for this peer are the same as for
\fB\-addnode\fR). This option can be specified multiple times to connect
to multiple nodes.
@@ -178,7 +181,7 @@ unless \fB\-connect\fR used)
.HP
\fB\-enablebip61\fR
.IP
-Send reject messages per BIP61 (default: 1)
+Send reject messages per BIP61 (default: 0)
.HP
\fB\-externalip=\fR<ip>
.IP
@@ -221,8 +224,8 @@ Tries to keep outbound traffic under the given target (in MiB per 24h),
.HP
\fB\-onion=\fR<ip:port>
.IP
-Use separate SOCKS5 proxy to reach peers via Tor hidden services
-(default: \fB\-proxy\fR)
+Use separate SOCKS5 proxy to reach peers via Tor hidden services, set
+\fB\-noonion\fR to disable (default: \fB\-proxy\fR)
.HP
\fB\-onlynet=\fR<net>
.IP
@@ -242,11 +245,13 @@ Relay non\-P2SH multisig (default: 1)
.HP
\fB\-port=\fR<port>
.IP
-Listen for connections on <port> (default: 8333 or testnet: 18333)
+Listen for connections on <port> (default: 8333, testnet: 18333,
+regtest: 18444)
.HP
\fB\-proxy=\fR<ip:port>
.IP
-Connect through SOCKS5 proxy
+Connect through SOCKS5 proxy, set \fB\-noproxy\fR to disable (default:
+disabled)
.HP
\fB\-proxyrandomize\fR
.IP
@@ -393,8 +398,7 @@ Send transactions with full\-RBF opt\-in enabled (RPC only, default: 0)
.IP
Delete all wallet transactions and only recover those parts of the
blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g.
-account owner and payment request information, 2 = drop tx meta
-data)
+payment request information, 2 = drop tx meta data)
.PP
ZeroMQ notification options:
.HP
@@ -418,7 +422,7 @@ Debugging/Testing options:
.HP
\fB\-debug=\fR<category>
.IP
-Output debugging information (default: 0, supplying <category> is
+Output debugging information (default: \fB\-nodebug\fR, supplying <category> is
optional). If <category> is not supplied or if <category> = 1,
output all debugging information. <category> can be: net, tor,
mempool, http, bench, zmq, db, rpc, estimatefee, addrman,
@@ -433,7 +437,7 @@ or more specified categories.
.HP
\fB\-help\-debug\fR
.IP
-Show all debugging options (usage: \fB\-\-help\fR \fB\-help\-debug\fR)
+Print help message with debugging options and exit
.HP
\fB\-logips\fR
.IP
@@ -452,7 +456,7 @@ transaction; setting this too low may abort large transactions
\fB\-printtoconsole\fR
.IP
Send trace/debug info to console (default: 1 when no \fB\-daemon\fR. To disable
-logging to file, set debuglogfile=0)
+logging to file, set \fB\-nodebuglogfile\fR)
.HP
\fB\-shrinkdebugfile\fR
.IP
@@ -529,8 +533,8 @@ option can be specified multiple times
.HP
\fB\-rpcauth=\fR<userpw>
.IP
-Username and hashed password for JSON\-RPC connections. The field
-<userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A
+Username and HMAC\-SHA\-256 hashed password for JSON\-RPC connections. The
+field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A
canonical python script is included in share/rpcauth. The client
then connects normally using the
rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This
@@ -538,12 +542,12 @@ option can be specified multiple times
.HP
\fB\-rpcbind=\fR<addr>[:port]
.IP
-Bind to given address to listen for JSON\-RPC connections. This option is
-ignored unless \fB\-rpcallowip\fR is also passed. Port is optional and
-overrides \fB\-rpcport\fR. Use [host]:port notation for IPv6. This
-option can be specified multiple times (default: 127.0.0.1 and
-::1 i.e., localhost, or if \fB\-rpcallowip\fR has been specified,
-0.0.0.0 and :: i.e., all addresses)
+Bind to given address to listen for JSON\-RPC connections. Do not expose
+the RPC server to untrusted networks such as the public internet!
+This option is ignored unless \fB\-rpcallowip\fR is also passed. Port is
+optional and overrides \fB\-rpcport\fR. Use [host]:port notation for
+IPv6. This option can be specified multiple times (default:
+127.0.0.1 and ::1 i.e., localhost)
.HP
\fB\-rpccookiefile=\fR<loc>
.IP
@@ -556,8 +560,8 @@ Password for JSON\-RPC connections
.HP
\fB\-rpcport=\fR<port>
.IP
-Listen for JSON\-RPC connections on <port> (default: 8332 or testnet:
-18332)
+Listen for JSON\-RPC connections on <port> (default: 8332, testnet:
+18332, regtest: 18443)
.HP
\fB\-rpcserialversion\fR
.IP
diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1
index e1b81bad6c..f16c68ca14 100644
--- a/doc/man/bitcoin-tx.1
+++ b/doc/man/bitcoin-tx.1
@@ -1,16 +1,15 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
-.TH BITCOIN-TX "1" "July 2018" "bitcoin-tx v0.16.99.0" "User Commands"
+.TH BITCOIN-TX "1" "December 2018" "bitcoin-tx v0.17.99.0" "User Commands"
.SH NAME
-bitcoin-tx \- manual page for bitcoin-tx v0.16.99.0
+bitcoin-tx \- manual page for bitcoin-tx v0.17.99.0
+.SH SYNOPSIS
+.B bitcoin-tx
+[\fI\,options\/\fR] \fI\,<hex-tx> \/\fR[\fI\,commands\/\fR] \fI\,Update hex-encoded bitcoin transaction\/\fR
+.br
+.B bitcoin-tx
+[\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] \fI\,Create hex-encoded bitcoin transaction\/\fR
.SH DESCRIPTION
-Bitcoin Core bitcoin\-tx utility version v0.16.99.0
-.SS "Usage:"
-.TP
-bitcoin\-tx [options] <hex\-tx> [commands]
-Update hex\-encoded bitcoin transaction
-.TP
-bitcoin\-tx [options] \fB\-create\fR [commands]
-Create hex\-encoded bitcoin transaction
+Bitcoin Core bitcoin\-tx utility version v0.17.99.0
.SH OPTIONS
.HP
\-?
diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1
index d0ba131cde..5c4b1cd03b 100644
--- a/doc/man/bitcoind.1
+++ b/doc/man/bitcoind.1
@@ -1,13 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
-.TH BITCOIND "1" "July 2018" "bitcoind v0.16.99.0" "User Commands"
+.TH BITCOIND "1" "December 2018" "bitcoind v0.17.99.0" "User Commands"
.SH NAME
-bitcoind \- manual page for bitcoind v0.16.99.0
+bitcoind \- manual page for bitcoind v0.17.99.0
+.SH SYNOPSIS
+.B bitcoind
+[\fI\,options\/\fR] \fI\,Start Bitcoin Core Daemon\/\fR
.SH DESCRIPTION
-Bitcoin Core Daemon version v0.16.99.0
-.SS "Usage:"
-.TP
-bitcoind [options]
-Start Bitcoin Core Daemon
+Bitcoin Core Daemon version v0.17.99.0
.SH OPTIONS
.HP
\-?
@@ -24,9 +23,9 @@ long fork (%s in cmd is replaced by message)
If this block is in the chain assume that it and its ancestors are valid
and potentially skip their script verification (0 to verify all,
default:
-0000000000000000005214481d2d96f898e3d5416e43359c145944a909d242e0,
+0000000000000000002e63058c023a9a1de233554f28c7b21380b6c9003f36a8,
testnet:
-0000000002e9e7b00e1f6dc5123a04aad68dd0f0968d8c7aa45f6640795c37b1)
+0000000000000037a8cd3e06cd5edbfe9dd1dbcc5dacab279376ef7cfc2b4c75)
.HP
\fB\-blocknotify=\fR<cmd>
.IP
@@ -62,7 +61,8 @@ Set database cache size in megabytes (4 to 16384, default: 450)
\fB\-debuglogfile=\fR<file>
.IP
Specify location of debug log file. Relative paths will be prefixed by a
-net\-specific datadir location. (0 to disable; default: debug.log)
+net\-specific datadir location. (\fB\-nodebuglogfile\fR to disable;
+default: debug.log)
.HP
\fB\-includeconf=\fR<file>
.IP
@@ -109,7 +109,7 @@ blocks if a target size in MiB is provided. This mode is
incompatible with \fB\-txindex\fR and \fB\-rescan\fR. Warning: Reverting this
setting requires re\-downloading the entire blockchain. (default:
0 = disable pruning blocks, 1 = allow manual pruning via RPC,
->550 = automatically prune block files to stay under the
+>=550 = automatically prune block files to stay under the
specified target size in MiB)
.HP
\fB\-reindex\fR
@@ -118,7 +118,9 @@ Rebuild chain state and block index from the blk*.dat files on disk
.HP
\fB\-reindex\-chainstate\fR
.IP
-Rebuild chain state from the currently indexed blocks
+Rebuild chain state from the currently indexed blocks. When in pruning
+mode or if blocks on disk might be corrupted, use full \fB\-reindex\fR
+instead.
.HP
\fB\-sysperms\fR
.IP
@@ -158,7 +160,7 @@ for IPv6
.HP
\fB\-connect=\fR<ip>
.IP
-Connect only to the specified node; \fB\-connect\fR=\fI\,0\/\fR disables automatic
+Connect only to the specified node; \fB\-noconnect\fR disables automatic
connections (the rules for this peer are the same as for
\fB\-addnode\fR). This option can be specified multiple times to connect
to multiple nodes.
@@ -179,7 +181,7 @@ unless \fB\-connect\fR used)
.HP
\fB\-enablebip61\fR
.IP
-Send reject messages per BIP61 (default: 1)
+Send reject messages per BIP61 (default: 0)
.HP
\fB\-externalip=\fR<ip>
.IP
@@ -222,8 +224,8 @@ Tries to keep outbound traffic under the given target (in MiB per 24h),
.HP
\fB\-onion=\fR<ip:port>
.IP
-Use separate SOCKS5 proxy to reach peers via Tor hidden services
-(default: \fB\-proxy\fR)
+Use separate SOCKS5 proxy to reach peers via Tor hidden services, set
+\fB\-noonion\fR to disable (default: \fB\-proxy\fR)
.HP
\fB\-onlynet=\fR<net>
.IP
@@ -243,11 +245,13 @@ Relay non\-P2SH multisig (default: 1)
.HP
\fB\-port=\fR<port>
.IP
-Listen for connections on <port> (default: 8333 or testnet: 18333)
+Listen for connections on <port> (default: 8333, testnet: 18333,
+regtest: 18444)
.HP
\fB\-proxy=\fR<ip:port>
.IP
-Connect through SOCKS5 proxy
+Connect through SOCKS5 proxy, set \fB\-noproxy\fR to disable (default:
+disabled)
.HP
\fB\-proxyrandomize\fR
.IP
@@ -394,8 +398,7 @@ Send transactions with full\-RBF opt\-in enabled (RPC only, default: 0)
.IP
Delete all wallet transactions and only recover those parts of the
blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g.
-account owner and payment request information, 2 = drop tx meta
-data)
+payment request information, 2 = drop tx meta data)
.PP
ZeroMQ notification options:
.HP
@@ -419,7 +422,7 @@ Debugging/Testing options:
.HP
\fB\-debug=\fR<category>
.IP
-Output debugging information (default: 0, supplying <category> is
+Output debugging information (default: \fB\-nodebug\fR, supplying <category> is
optional). If <category> is not supplied or if <category> = 1,
output all debugging information. <category> can be: net, tor,
mempool, http, bench, zmq, db, rpc, estimatefee, addrman,
@@ -434,7 +437,7 @@ or more specified categories.
.HP
\fB\-help\-debug\fR
.IP
-Show all debugging options (usage: \fB\-\-help\fR \fB\-help\-debug\fR)
+Print help message with debugging options and exit
.HP
\fB\-logips\fR
.IP
@@ -453,7 +456,7 @@ transaction; setting this too low may abort large transactions
\fB\-printtoconsole\fR
.IP
Send trace/debug info to console (default: 1 when no \fB\-daemon\fR. To disable
-logging to file, set debuglogfile=0)
+logging to file, set \fB\-nodebuglogfile\fR)
.HP
\fB\-shrinkdebugfile\fR
.IP
@@ -530,8 +533,8 @@ option can be specified multiple times
.HP
\fB\-rpcauth=\fR<userpw>
.IP
-Username and hashed password for JSON\-RPC connections. The field
-<userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A
+Username and HMAC\-SHA\-256 hashed password for JSON\-RPC connections. The
+field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A
canonical python script is included in share/rpcauth. The client
then connects normally using the
rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This
@@ -539,12 +542,12 @@ option can be specified multiple times
.HP
\fB\-rpcbind=\fR<addr>[:port]
.IP
-Bind to given address to listen for JSON\-RPC connections. This option is
-ignored unless \fB\-rpcallowip\fR is also passed. Port is optional and
-overrides \fB\-rpcport\fR. Use [host]:port notation for IPv6. This
-option can be specified multiple times (default: 127.0.0.1 and
-::1 i.e., localhost, or if \fB\-rpcallowip\fR has been specified,
-0.0.0.0 and :: i.e., all addresses)
+Bind to given address to listen for JSON\-RPC connections. Do not expose
+the RPC server to untrusted networks such as the public internet!
+This option is ignored unless \fB\-rpcallowip\fR is also passed. Port is
+optional and overrides \fB\-rpcport\fR. Use [host]:port notation for
+IPv6. This option can be specified multiple times (default:
+127.0.0.1 and ::1 i.e., localhost)
.HP
\fB\-rpccookiefile=\fR<loc>
.IP
@@ -557,8 +560,8 @@ Password for JSON\-RPC connections
.HP
\fB\-rpcport=\fR<port>
.IP
-Listen for JSON\-RPC connections on <port> (default: 8332 or testnet:
-18332)
+Listen for JSON\-RPC connections on <port> (default: 8332, testnet:
+18332, regtest: 18443)
.HP
\fB\-rpcserialversion\fR
.IP
diff --git a/doc/release-notes-14060.md b/doc/release-notes-14060.md
deleted file mode 100644
index 2cc5ab49fb..0000000000
--- a/doc/release-notes-14060.md
+++ /dev/null
@@ -1,21 +0,0 @@
-Configuration
--------------
-
-The outbound message high water mark of the ZMQ PUB sockets are now
-configurable via the options:
-
-`-zmqpubhashtxhwm=n`
-
-`-zmqpubhashblockhwm=n`
-
-`-zmqpubrawblockhwm=n`
-
-`-zmqpubrawtxhwm=n`
-
-Each high water mark value must be an integer greater than or equal to 0.
-The high water mark limits the maximum number of messages that ZMQ will
-queue in memory for any single subscriber. A value of 0 means no limit.
-When not specified, the default value continues to be 1000.
-When a ZMQ PUB socket reaches its high water mark for a subscriber, then
-additional messages to the subscriber are dropped until the number of
-queued messages again falls below the high water mark value.
diff --git a/doc/release-notes-14477.md b/doc/release-notes-14477.md
deleted file mode 100644
index bb8c0a623e..0000000000
--- a/doc/release-notes-14477.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Miscellaneous RPC changes
-------------
-
-- `getaddressinfo` now reports `solvable`, a boolean indicating whether all information necessary for signing is present in the wallet (ignoring private keys).
-- `getaddressinfo`, `listunspent`, and `scantxoutset` have a new output field `desc`, an output descriptor that encapsulates all signing information and key paths for the address (only available when `solvable` is true for `getaddressinfo` and `listunspent`).
diff --git a/doc/release-notes-14565.md b/doc/release-notes-14565.md
deleted file mode 100644
index 38d76fee46..0000000000
--- a/doc/release-notes-14565.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Low-level RPC changes
----------------------
-
-The `importmulti` RPC will now contain a new per-request `warnings` field with strings
-that explain when fields are being ignored or inconsistant, if any.
diff --git a/doc/release-notes-pr13381.md b/doc/release-notes-pr13381.md
deleted file mode 100644
index 75faad9906..0000000000
--- a/doc/release-notes-pr13381.md
+++ /dev/null
@@ -1,29 +0,0 @@
-RPC importprivkey: new label behavior
--------------------------------------
-
-Previously, `importprivkey` automatically added the default empty label
-("") to all addresses associated with the imported private key. Now it
-defaults to using any existing label for those addresses. For example:
-
-- Old behavior: you import a watch-only address with the label "cold
- wallet". Later, you import the corresponding private key using the
- default settings. The address's label is changed from "cold wallet"
- to "".
-
-- New behavior: you import a watch-only address with the label "cold
- wallet". Later, you import the corresponding private key using the
- default settings. The address's label remains "cold wallet".
-
-In both the previous and current case, if you directly specify a label
-during the import, that label will override whatever previous label the
-addresses may have had. Also in both cases, if none of the addresses
-previously had a label, they will still receive the default empty label
-(""). Examples:
-
-- You import a watch-only address with the label "temporary". Later you
- import the corresponding private key with the label "final". The
- address's label will be changed to "final".
-
-- You use the default settings to import a private key for an address that
- was not previously in the wallet. Its addresses will receive the default
- empty label ("").
diff --git a/doc/release-notes.md b/doc/release-notes.md
index 9465258310..53b5a2119f 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -47,8 +47,9 @@ processing the entire blockchain.
Compatibility
==============
-Bitcoin Core is extensively tested on multiple operating systems using
-the Linux kernel, macOS 10.10+, and Windows 7 and newer (Windows XP is not supported).
+Bitcoin Core is supported and extensively tested on operating systems using
+the Linux kernel, macOS 10.10+, and Windows 7 and newer. It is not recommended
+to use Bitcoin Core on unsupported systems.
Bitcoin Core should also work on most other Unix-like systems but is not
frequently tested on them.
@@ -71,16 +72,44 @@ Mining
- Calls to `getblocktemplate` will fail if the segwit rule is not specified.
Calling `getblocktemplate` without segwit specified is almost certainly
a misconfiguration since doing so results in lower rewards for the miner.
-
-Command line option changes
----------------------------
-
-The `-enablebip61` command line option (introduced in Bitcoin Core 0.17.0) is
-used to toggle sending of BIP 61 reject messages. Reject messages have no use
-case on the P2P network and are only logged for debugging by most network
-nodes. The option will now by default be off for improved privacy and security
-as well as reduced upload usage. The option can explicitly be turned on for
-local-network debugging purposes.
+ Failed calls will produce an error message describing how to enable the
+ segwit rule.
+
+Configuration option changes
+----------------------------
+
+- A warning is printed if an unrecognized section name is used in the
+ configuration file. Recognized sections are `[test]`, `[main]`, and
+ `[regtest]`.
+
+- Four new options are available for configuring the maximum number of
+ messages that ZMQ will queue in memory (the "high water mark") before
+ dropping additional messages. The default value is 1,000, the same as
+ was used for previous releases. See the [ZMQ
+ documentation](https://github.com/bitcoin/bitcoin/blob/master/doc/zmq.md#usage)
+ for details.
+
+- The `enablebip61` option (introduced in Bitcoin Core 0.17.0) is
+ used to toggle sending of BIP 61 reject messages. Reject messages have no use
+ case on the P2P network and are only logged for debugging by most network
+ nodes. The option will now by default be off for improved privacy and security
+ as well as reduced upload usage. The option can explicitly be turned on for
+ local-network debugging purposes.
+
+- The `rpcallowip` option can no longer be used to automatically listen
+ on all network interfaces. Instead, the `rpcbind` parameter must also
+ be used to specify the IP addresses to listen on. Listening for RPC
+ commands over a public network connection is insecure and should be
+ disabled, so a warning is now printed if a user selects such a
+ configuration. If you need to expose RPC in order to use a tool
+ like Docker, ensure you only bind RPC to your localhost, e.g. `docker
+ run [...] -p 127.0.0.1:8332:8332` (this is an extra `:8332` over the
+ normal Docker port specification).
+
+- The `rpcpassword` option now causes a startup error if the password
+ set in the configuration file contains a hash character (#), as it's
+ ambiguous whether the hash character is meant for the password or as a
+ comment.
Documentation
-------------
@@ -167,7 +196,7 @@ Updated RPCs
Note: some low-level RPC changes mainly useful for testing are described
in the Low-level Changes section below.
-- The `getpeerinfo` RPC now returns an additional "minfeefilter" field
+- The `getpeerinfo` RPC now returns an additional `minfeefilter` field
set to the peer's BIP133 fee filter. You can use this to detect that
you have peers that are willing to accept transactions below the
default minimum relay fee.
@@ -189,8 +218,50 @@ in the Low-level Changes section below.
P2SH-P2WPKH, and P2SH-P2WSH. Requests for P2WSH and P2SH-P2WSH accept
an additional `witnessscript` parameter.
+- The `importmulti` RPC now returns an additional `warnings` field for
+ each request with an array of strings explaining when fields are being
+ ignored or are inconsistent, if there are any.
+
+- The `getaddressinfo` RPC now returns an additional `solvable` boolean
+ field when Bitcoin Core knows enough about the address's scriptPubKey,
+ optional redeemScript, and optional witnessScript in order for the
+ wallet to be able to generate an unsigned input spending funds sent to
+ that address.
+
+- The `getaddressinfo`, `listunspent`, and `scantxoutset` RPCs now
+ return an additional `desc` field that contains an output descriptor
+ containing all key paths and signing information for the address
+ (except for the private key). The `desc` field is only returned for
+ `getaddressinfo` and `listunspent` when the address is solvable.
+
+- The `importprivkey` RPC will preserve previously-set labels for
+ addresses or public keys corresponding to the private key being
+ imported. For example, if you imported a watch-only address with the
+ label "cold wallet" in earlier releases of Bitcoin Core, subsequently
+ importing the private key would default to resetting the address's
+ label to the default empty-string label (""). In this release, the
+ previous label of "cold wallet" will be retained. If you optionally
+ specify any label besides the default when calling `importprivkey`,
+ the new label will be applied to the address.
+
- See the [Mining](#mining) section for changes to `getblocktemplate`.
+Graphical User Interface (GUI)
+------------------------------
+
+- A new Window menu is added alongside the existing File, Settings, and
+ Help menus. Several items from the other menus that opened new
+ windows have been moved to this new Window menu.
+
+- In the Send tab, the checkbox for "pay only the required fee"
+ has been removed. Instead, the user can simply decrease the value in
+ the Custom Feerate field all the way down to the node's configured
+ minimum relay fee.
+
+- In the Overview tab, the watch-only balance will be the only
+ balance shown if the wallet was created using the `createwallet` RPC
+ and the `disable_private_keys` parameter was set to true.
+
Low-level changes
=================
@@ -215,6 +286,16 @@ Configuration
deterministic wallets. This release makes specifying `-usehd` an
invalid configuration option.
+Changes for particular platforms
+--------------------------------
+
+- On macOS, Bitcoin Core now opts out of application CPU throttling
+ ("app nap") during initial blockchain download, when catching up from
+ over 100 blocks behind the current chain tip, or when reindexing chain
+ data. This helps prevent these operations from taking an excessively
+ long time because the operating system is attempting to conserve
+ power.
+
Credits
=======
diff --git a/src/amount.h b/src/amount.h
index 449fd1b15f..47968e80b1 100644
--- a/src/amount.h
+++ b/src/amount.h
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/compat.h b/src/compat.h
index 049579c365..7b164d5630 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -92,8 +92,15 @@ typedef void* sockopt_arg_type;
typedef char* sockopt_arg_type;
#endif
+// Note these both should work with the current usage of poll, but best to be safe
+// WIN32 poll is broken https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/
+// __APPLE__ poll is broke https://github.com/bitcoin/bitcoin/pull/14336#issuecomment-437384408
+#if defined(__linux__)
+#define USE_POLL
+#endif
+
bool static inline IsSelectableSocket(const SOCKET& s) {
-#ifdef WIN32
+#if defined(USE_POLL) || defined(WIN32)
return true;
#else
return (s < FD_SETSIZE);
diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp
index b17a8bb31d..0a7eacfb91 100644
--- a/src/consensus/tx_verify.cpp
+++ b/src/consensus/tx_verify.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2017 The Bitcoin Core developers
+// Copyright (c) 2017-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/fs.h b/src/fs.h
index bdccb15232..8af81f173b 100644
--- a/src/fs.h
+++ b/src/fs.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 The Bitcoin Core developers
+// Copyright (c) 2017-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/init.cpp b/src/init.cpp
index a3a7c5a3bb..18c145a023 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -953,8 +953,13 @@ bool AppInitParameterInteraction()
// Trim requested connection counts, to fit into system limitations
// <int> in std::min<int>(...) to work around FreeBSD compilation issue described in #2695
- nMaxConnections = std::max(std::min<int>(nMaxConnections, FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS), 0);
nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS + MAX_ADDNODE_CONNECTIONS);
+#ifdef USE_POLL
+ int fd_max = nFD;
+#else
+ int fd_max = FD_SETSIZE;
+#endif
+ nMaxConnections = std::max(std::min<int>(nMaxConnections, fd_max - nBind - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS), 0);
if (nFD < MIN_CORE_FILEDESCRIPTORS)
return InitError(_("Not enough file descriptors available."));
nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS, nMaxConnections);
diff --git a/src/key_io.cpp b/src/key_io.cpp
index 282385f50d..d998089535 100644
--- a/src/key_io.cpp
+++ b/src/key_io.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 The Bitcoin Core developers
+// Copyright (c) 2014-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/net.cpp b/src/net.cpp
index e595fb0b0b..902830f79c 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2018 The Bitcoin Core developers
+// Copyright (c) 2009-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -26,6 +26,10 @@
#include <fcntl.h>
#endif
+#ifdef USE_POLL
+#include <poll.h>
+#endif
+
#ifdef USE_UPNP
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/miniwget.h>
@@ -33,6 +37,7 @@
#include <miniupnpc/upnperrors.h>
#endif
+#include <unordered_map>
#include <math.h>
@@ -71,7 +76,11 @@ enum BindFlags {
BF_WHITELIST = (1U << 2),
};
-const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
+// The set of sockets cannot be modified while waiting
+// The sleep time needs to be small to avoid new sockets stalling
+static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
+
+const std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // SHA256("localhostnonce")[0:8]
@@ -778,7 +787,6 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete
nBytes -= handled;
if (msg.complete()) {
-
//store received bytes per message command
//to prevent a memory DOS, only allow valid commands
mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand);
@@ -1258,28 +1266,10 @@ void CConnman::InactivityCheck(CNode *pnode)
}
}
-void CConnman::SocketHandler()
+bool CConnman::GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
{
- //
- // Find which sockets have data to receive
- //
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 50000; // frequency to poll pnode->vSend
-
- fd_set fdsetRecv;
- fd_set fdsetSend;
- fd_set fdsetError;
- FD_ZERO(&fdsetRecv);
- FD_ZERO(&fdsetSend);
- FD_ZERO(&fdsetError);
- SOCKET hSocketMax = 0;
- bool have_fds = false;
-
for (const ListenSocket& hListenSocket : vhListenSocket) {
- FD_SET(hListenSocket.socket, &fdsetRecv);
- hSocketMax = std::max(hSocketMax, hListenSocket.socket);
- have_fds = true;
+ recv_set.insert(hListenSocket.socket);
}
{
@@ -1308,46 +1298,151 @@ void CConnman::SocketHandler()
if (pnode->hSocket == INVALID_SOCKET)
continue;
- FD_SET(pnode->hSocket, &fdsetError);
- hSocketMax = std::max(hSocketMax, pnode->hSocket);
- have_fds = true;
-
+ error_set.insert(pnode->hSocket);
if (select_send) {
- FD_SET(pnode->hSocket, &fdsetSend);
+ send_set.insert(pnode->hSocket);
continue;
}
if (select_recv) {
- FD_SET(pnode->hSocket, &fdsetRecv);
+ recv_set.insert(pnode->hSocket);
}
}
}
- int nSelect = select(have_fds ? hSocketMax + 1 : 0,
- &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
+ return !recv_set.empty() || !send_set.empty() || !error_set.empty();
+}
+
+#ifdef USE_POLL
+void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
+{
+ std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
+ if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
+ interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
+ return;
+ }
+
+ std::unordered_map<SOCKET, struct pollfd> pollfds;
+ for (SOCKET socket_id : recv_select_set) {
+ pollfds[socket_id].fd = socket_id;
+ pollfds[socket_id].events |= POLLIN;
+ }
+
+ for (SOCKET socket_id : send_select_set) {
+ pollfds[socket_id].fd = socket_id;
+ pollfds[socket_id].events |= POLLOUT;
+ }
+
+ for (SOCKET socket_id : error_select_set) {
+ pollfds[socket_id].fd = socket_id;
+ // These flags are ignored, but we set them for clarity
+ pollfds[socket_id].events |= POLLERR|POLLHUP;
+ }
+
+ std::vector<struct pollfd> vpollfds;
+ vpollfds.reserve(pollfds.size());
+ for (auto it : pollfds) {
+ vpollfds.push_back(std::move(it.second));
+ }
+
+ if (poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS) < 0) return;
+
+ if (interruptNet) return;
+
+ for (struct pollfd pollfd_entry : vpollfds) {
+ if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
+ if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
+ if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
+ }
+}
+#else
+void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
+{
+ std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
+ if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
+ interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
+ return;
+ }
+
+ //
+ // Find which sockets have data to receive
+ //
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000; // frequency to poll pnode->vSend
+
+ fd_set fdsetRecv;
+ fd_set fdsetSend;
+ fd_set fdsetError;
+ FD_ZERO(&fdsetRecv);
+ FD_ZERO(&fdsetSend);
+ FD_ZERO(&fdsetError);
+ SOCKET hSocketMax = 0;
+
+ for (SOCKET hSocket : recv_select_set) {
+ FD_SET(hSocket, &fdsetRecv);
+ hSocketMax = std::max(hSocketMax, hSocket);
+ }
+
+ for (SOCKET hSocket : send_select_set) {
+ FD_SET(hSocket, &fdsetSend);
+ hSocketMax = std::max(hSocketMax, hSocket);
+ }
+
+ for (SOCKET hSocket : error_select_set) {
+ FD_SET(hSocket, &fdsetError);
+ hSocketMax = std::max(hSocketMax, hSocket);
+ }
+
+ int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
+
if (interruptNet)
return;
if (nSelect == SOCKET_ERROR)
{
- if (have_fds)
- {
- int nErr = WSAGetLastError();
- LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
- for (unsigned int i = 0; i <= hSocketMax; i++)
- FD_SET(i, &fdsetRecv);
- }
+ int nErr = WSAGetLastError();
+ LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
+ for (unsigned int i = 0; i <= hSocketMax; i++)
+ FD_SET(i, &fdsetRecv);
FD_ZERO(&fdsetSend);
FD_ZERO(&fdsetError);
- if (!interruptNet.sleep_for(std::chrono::milliseconds(timeout.tv_usec/1000)))
+ if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
return;
}
+ for (SOCKET hSocket : recv_select_set) {
+ if (FD_ISSET(hSocket, &fdsetRecv)) {
+ recv_set.insert(hSocket);
+ }
+ }
+
+ for (SOCKET hSocket : send_select_set) {
+ if (FD_ISSET(hSocket, &fdsetSend)) {
+ send_set.insert(hSocket);
+ }
+ }
+
+ for (SOCKET hSocket : error_select_set) {
+ if (FD_ISSET(hSocket, &fdsetError)) {
+ error_set.insert(hSocket);
+ }
+ }
+}
+#endif
+
+void CConnman::SocketHandler()
+{
+ std::set<SOCKET> recv_set, send_set, error_set;
+ SocketEvents(recv_set, send_set, error_set);
+
+ if (interruptNet) return;
+
//
// Accept new connections
//
for (const ListenSocket& hListenSocket : vhListenSocket)
{
- if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
+ if (hListenSocket.socket != INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0)
{
AcceptConnection(hListenSocket);
}
@@ -1378,9 +1473,9 @@ void CConnman::SocketHandler()
LOCK(pnode->cs_hSocket);
if (pnode->hSocket == INVALID_SOCKET)
continue;
- recvSet = FD_ISSET(pnode->hSocket, &fdsetRecv);
- sendSet = FD_ISSET(pnode->hSocket, &fdsetSend);
- errorSet = FD_ISSET(pnode->hSocket, &fdsetError);
+ recvSet = recv_set.count(pnode->hSocket) > 0;
+ sendSet = send_set.count(pnode->hSocket) > 0;
+ errorSet = error_set.count(pnode->hSocket) > 0;
}
if (recvSet || errorSet)
{
diff --git a/src/net.h b/src/net.h
index 775d0c8099..4af3318656 100644
--- a/src/net.h
+++ b/src/net.h
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2018 The Bitcoin Core developers
+// Copyright (c) 2009-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -346,6 +346,8 @@ private:
void DisconnectNodes();
void NotifyNumConnectionsChanged();
void InactivityCheck(CNode *pnode);
+ bool GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set);
+ void SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set);
void SocketHandler();
void ThreadSocketHandler();
void ThreadDNSAddressSeed();
@@ -548,6 +550,8 @@ struct LocalServiceInfo {
extern CCriticalSection cs_mapLocalHost;
extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(cs_mapLocalHost);
+
+extern const std::string NET_MESSAGE_COMMAND_OTHER;
typedef std::map<std::string, uint64_t> mapMsgCmdSize; //command, total bytes
class CNodeStats
@@ -694,8 +698,8 @@ public:
const uint64_t nKeyedNetGroup;
std::atomic_bool fPauseRecv;
std::atomic_bool fPauseSend;
-protected:
+protected:
mapMsgCmdSize mapSendBytesPerMsgCmd;
mapMsgCmdSize mapRecvBytesPerMsgCmd GUARDED_BY(cs_vRecv);
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 1c043fc981..355e21d4e6 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -21,6 +21,10 @@
#include <codecvt>
#endif
+#ifdef USE_POLL
+#include <poll.h>
+#endif
+
#if !defined(MSG_NOSIGNAL)
#define MSG_NOSIGNAL 0
#endif
@@ -264,11 +268,19 @@ static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, c
if (!IsSelectableSocket(hSocket)) {
return IntrRecvError::NetworkError;
}
- struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait));
+ int timeout_ms = std::min(endTime - curTime, maxWait);
+#ifdef USE_POLL
+ struct pollfd pollfd = {};
+ pollfd.fd = hSocket;
+ pollfd.events = POLLIN | POLLOUT;
+ int nRet = poll(&pollfd, 1, timeout_ms);
+#else
+ struct timeval tval = MillisToTimeval(timeout_ms);
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(hSocket, &fdset);
int nRet = select(hSocket + 1, &fdset, nullptr, nullptr, &tval);
+#endif
if (nRet == SOCKET_ERROR) {
return IntrRecvError::NetworkError;
}
@@ -499,11 +511,18 @@ bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, i
// WSAEINVAL is here because some legacy version of winsock uses it
if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL)
{
+#ifdef USE_POLL
+ struct pollfd pollfd = {};
+ pollfd.fd = hSocket;
+ pollfd.events = POLLIN | POLLOUT;
+ int nRet = poll(&pollfd, 1, nTimeout);
+#else
struct timeval timeout = MillisToTimeval(nTimeout);
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(hSocket, &fdset);
int nRet = select(hSocket + 1, nullptr, &fdset, nullptr, &timeout);
+#endif
if (nRet == 0)
{
LogPrint(BCLog::NET, "connection to %s timeout\n", addrConnect.ToString());
diff --git a/src/noui.h b/src/noui.h
index 169c2bbd7f..79a79a9af2 100644
--- a/src/noui.h
+++ b/src/noui.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2013-2014 The Bitcoin Core developers
+// Copyright (c) 2013-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index eaeb93a652..922987b7bc 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2018 The Bitcoin Core developers
+// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -431,7 +431,7 @@ void BitcoinApplication::addWallet(WalletModel* walletModel)
window->addWallet(walletModel);
if (m_wallet_models.empty()) {
- window->setCurrentWallet(walletModel->getWalletName());
+ window->setCurrentWallet(walletModel);
}
#ifdef ENABLE_BIP70
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 15e1b98fb4..0ca5b5fcdc 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2018 The Bitcoin Core developers
+// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -129,6 +129,7 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
if (QSystemTrayIcon::isSystemTrayAvailable()) {
createTrayIcon(networkStyle);
}
+ notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
// Create status bar
statusBar();
@@ -536,8 +537,7 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel)
unitDisplayControl->setOptionsModel(_clientModel->getOptionsModel());
OptionsModel* optionsModel = _clientModel->getOptionsModel();
- if(optionsModel)
- {
+ if (optionsModel && trayIcon) {
// be aware of the tray icon disable state change reported by the OptionsModel object.
connect(optionsModel, &OptionsModel::hideTrayIconChanged, this, &BitcoinGUI::setTrayIconVisible);
@@ -569,10 +569,9 @@ bool BitcoinGUI::addWallet(WalletModel *walletModel)
{
if(!walletFrame)
return false;
- const QString name = walletModel->getWalletName();
- QString display_name = name.isEmpty() ? "["+tr("default wallet")+"]" : name;
+ const QString display_name = walletModel->getDisplayName();
setWalletActionsEnabled(true);
- m_wallet_selector->addItem(display_name, name);
+ m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
if (m_wallet_selector->count() == 2) {
m_wallet_selector_label_action->setVisible(true);
m_wallet_selector_action->setVisible(true);
@@ -584,8 +583,7 @@ bool BitcoinGUI::addWallet(WalletModel *walletModel)
bool BitcoinGUI::removeWallet(WalletModel* walletModel)
{
if (!walletFrame) return false;
- QString name = walletModel->getWalletName();
- int index = m_wallet_selector->findData(name);
+ int index = m_wallet_selector->findData(QVariant::fromValue(walletModel));
m_wallet_selector->removeItem(index);
if (m_wallet_selector->count() == 0) {
setWalletActionsEnabled(false);
@@ -594,20 +592,20 @@ bool BitcoinGUI::removeWallet(WalletModel* walletModel)
m_wallet_selector_action->setVisible(false);
}
rpcConsole->removeWallet(walletModel);
- return walletFrame->removeWallet(name);
+ return walletFrame->removeWallet(walletModel);
}
-bool BitcoinGUI::setCurrentWallet(const QString& name)
+bool BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
{
if(!walletFrame)
return false;
- return walletFrame->setCurrentWallet(name);
+ return walletFrame->setCurrentWallet(wallet_model);
}
bool BitcoinGUI::setCurrentWalletBySelectorIndex(int index)
{
- QString internal_name = m_wallet_selector->itemData(index).toString();
- return setCurrentWallet(internal_name);
+ WalletModel* wallet_model = m_wallet_selector->itemData(index).value<WalletModel*>();
+ return setCurrentWallet(wallet_model);
}
void BitcoinGUI::removeAllWallets()
@@ -642,14 +640,10 @@ void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle)
assert(QSystemTrayIcon::isSystemTrayAvailable());
#ifndef Q_OS_MAC
- trayIcon = new QSystemTrayIcon(this);
+ trayIcon = new QSystemTrayIcon(networkStyle->getTrayAndWindowIcon(), this);
QString toolTip = tr("%1 client").arg(tr(PACKAGE_NAME)) + " " + networkStyle->getTitleAddText();
trayIcon->setToolTip(toolTip);
- trayIcon->setIcon(networkStyle->getTrayAndWindowIcon());
- trayIcon->hide();
#endif
-
- notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
}
void BitcoinGUI::createTrayIconMenu()
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index aeff5dae30..1324dd6625 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2018 The Bitcoin Core developers
+// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -206,7 +206,7 @@ public Q_SLOTS:
void message(const QString &title, const QString &message, unsigned int style, bool *ret = nullptr);
#ifdef ENABLE_WALLET
- bool setCurrentWallet(const QString& name);
+ bool setCurrentWallet(WalletModel* wallet_model);
bool setCurrentWalletBySelectorIndex(int index);
/** Set the UI status indicators based on the currently selected wallet.
*/
diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
index 8f34e6bc82..507d195b72 100644
--- a/src/qt/forms/optionsdialog.ui
+++ b/src/qt/forms/optionsdialog.ui
@@ -714,7 +714,7 @@
<item>
<widget class="QLabel" name="overriddenByCommandLineInfoLabel">
<property name="text">
- <string>Active command-line options that override above options:</string>
+ <string>Options set in this dialog are overridden by the command line or in the configuration file:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h
index 04b03a5435..4d6006c582 100644
--- a/src/qt/guiconstants.h
+++ b/src/qt/guiconstants.h
@@ -50,5 +50,6 @@ static const int MAX_URI_LENGTH = 255;
#define QAPP_ORG_DOMAIN "bitcoin.org"
#define QAPP_APP_NAME_DEFAULT "Bitcoin-Qt"
#define QAPP_APP_NAME_TESTNET "Bitcoin-Qt-testnet"
+#define QAPP_APP_NAME_REGTEST "Bitcoin-Qt-regtest"
#endif // BITCOIN_QT_GUICONSTANTS_H
diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp
index b134a139b0..da048d3211 100644
--- a/src/qt/networkstyle.cpp
+++ b/src/qt/networkstyle.cpp
@@ -17,7 +17,7 @@ static const struct {
} network_styles[] = {
{"main", QAPP_APP_NAME_DEFAULT, 0, 0, ""},
{"test", QAPP_APP_NAME_TESTNET, 70, 30, QT_TRANSLATE_NOOP("SplashScreen", "[testnet]")},
- {"regtest", QAPP_APP_NAME_TESTNET, 160, 30, "[regtest]"}
+ {"regtest", QAPP_APP_NAME_REGTEST, 160, 30, "[regtest]"}
};
static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles);
diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp
index 94505043dc..4b91c19761 100644
--- a/src/qt/notificator.cpp
+++ b/src/qt/notificator.cpp
@@ -39,7 +39,7 @@ Notificator::Notificator(const QString &_programName, QSystemTrayIcon *_trayIcon
mode(None),
trayIcon(_trayIcon)
#ifdef USE_DBUS
- ,interface(0)
+ ,interface(nullptr)
#endif
{
if(_trayIcon && _trayIcon->supportsMessages())
@@ -154,14 +154,14 @@ QVariant FreedesktopImage::toVariant(const QImage &img)
void Notificator::notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
{
- Q_UNUSED(cls);
- // Arguments for DBus call:
+ // https://developer.gnome.org/notification-spec/
+ // Arguments for DBus "Notify" call:
QList<QVariant> args;
// Program Name:
args.append(programName);
- // Unique ID of this notification type:
+ // Replaces ID; A value of 0 means that this notification won't replace any existing notifications:
args.append(0U);
// Application Icon, empty string
@@ -209,9 +209,8 @@ void Notificator::notifyDBus(Class cls, const QString &title, const QString &tex
}
#endif
-void Notificator::notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
+void Notificator::notifySystray(Class cls, const QString &title, const QString &text, int millisTimeout)
{
- Q_UNUSED(icon);
QSystemTrayIcon::MessageIcon sicon = QSystemTrayIcon::NoIcon;
switch(cls) // Set icon based on class
{
@@ -222,13 +221,12 @@ void Notificator::notifySystray(Class cls, const QString &title, const QString &
trayIcon->showMessage(title, text, sicon, millisTimeout);
}
-// Based on Qt's tray icon implementation
#ifdef Q_OS_MAC
-void Notificator::notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon) {
+void Notificator::notifyMacUserNotificationCenter(const QString &title, const QString &text)
+{
// icon is not supported by the user notification center yet. OSX will use the app icon.
MacNotificationHandler::instance()->showNotification(title, text);
}
-
#endif
void Notificator::notify(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
@@ -241,11 +239,11 @@ void Notificator::notify(Class cls, const QString &title, const QString &text, c
break;
#endif
case QSystemTray:
- notifySystray(cls, title, text, icon, millisTimeout);
+ notifySystray(cls, title, text, millisTimeout);
break;
#ifdef Q_OS_MAC
case UserNotificationCenter:
- notifyMacUserNotificationCenter(cls, title, text, icon);
+ notifyMacUserNotificationCenter(title, text);
break;
#endif
default:
diff --git a/src/qt/notificator.h b/src/qt/notificator.h
index 10b7b6c50a..7d80b43e43 100644
--- a/src/qt/notificator.h
+++ b/src/qt/notificator.h
@@ -57,7 +57,7 @@ private:
enum Mode {
None, /**< Ignore informational notifications, and show a modal pop-up dialog for Critical notifications. */
Freedesktop, /**< Use DBus org.freedesktop.Notifications */
- QSystemTray, /**< Use QSystemTray::showMessage */
+ QSystemTray, /**< Use QSystemTrayIcon::showMessage() */
UserNotificationCenter /**< Use the 10.8+ User Notification Center (Mac only) */
};
QString programName;
@@ -68,9 +68,9 @@ private:
void notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout);
#endif
- void notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout);
+ void notifySystray(Class cls, const QString &title, const QString &text, int millisTimeout);
#ifdef Q_OS_MAC
- void notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon);
+ void notifyMacUserNotificationCenter(const QString &title, const QString &text);
#endif
};
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 774a0d78e7..a6187685a9 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2018 The Bitcoin Core developers
+// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -85,7 +85,7 @@ public:
explicit RPCExecutor(interfaces::Node& node) : m_node(node) {}
public Q_SLOTS:
- void request(const QString &command, const QString &walletID);
+ void request(const QString &command, const WalletModel* wallet_model);
Q_SIGNALS:
void reply(int category, const QString &command);
@@ -148,7 +148,7 @@ public:
* @param[out] pstrFilteredOut Command line, filtered to remove any sensitive data
*/
-bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strResult, const std::string &strCommand, const bool fExecute, std::string * const pstrFilteredOut, const std::string *walletID)
+bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strResult, const std::string &strCommand, const bool fExecute, std::string * const pstrFilteredOut, const WalletModel* wallet_model)
{
std::vector< std::vector<std::string> > stack;
stack.push_back(std::vector<std::string>());
@@ -306,8 +306,8 @@ bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strRes
std::string method = stack.back()[0];
std::string uri;
#ifdef ENABLE_WALLET
- if (walletID) {
- QByteArray encodedName = QUrl::toPercentEncoding(QString::fromStdString(*walletID));
+ if (wallet_model) {
+ QByteArray encodedName = QUrl::toPercentEncoding(wallet_model->getWalletName());
uri = "/wallet/"+std::string(encodedName.constData(), encodedName.length());
}
#endif
@@ -387,7 +387,7 @@ bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strRes
}
}
-void RPCExecutor::request(const QString &command, const QString &walletID)
+void RPCExecutor::request(const QString &command, const WalletModel* wallet_model)
{
try
{
@@ -418,9 +418,7 @@ void RPCExecutor::request(const QString &command, const QString &walletID)
" example: getblock(getblockhash(0),true)[tx][0]\n\n")));
return;
}
- std::string wallet_id = walletID.toStdString();
- if (!RPCConsole::RPCExecuteCommandLine(m_node, result, executableCommand, nullptr, walletID.isNull() ? nullptr : &wallet_id))
- {
+ if (!RPCConsole::RPCExecuteCommandLine(m_node, result, executableCommand, nullptr, wallet_model)) {
Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \""));
return;
}
@@ -698,10 +696,8 @@ void RPCConsole::setClientModel(ClientModel *model)
#ifdef ENABLE_WALLET
void RPCConsole::addWallet(WalletModel * const walletModel)
{
- const QString name = walletModel->getWalletName();
- // use name for text and internal data object (to allow to move to a wallet id later)
- QString display_name = name.isEmpty() ? "["+tr("default wallet")+"]" : name;
- ui->WalletSelector->addItem(display_name, name);
+ // use name for text and wallet model for internal data object (to allow to move to a wallet id later)
+ ui->WalletSelector->addItem(walletModel->getDisplayName(), QVariant::fromValue(walletModel));
if (ui->WalletSelector->count() == 2 && !isVisible()) {
// First wallet added, set to default so long as the window isn't presently visible (and potentially in use)
ui->WalletSelector->setCurrentIndex(1);
@@ -714,8 +710,7 @@ void RPCConsole::addWallet(WalletModel * const walletModel)
void RPCConsole::removeWallet(WalletModel * const walletModel)
{
- const QString name = walletModel->getWalletName();
- ui->WalletSelector->removeItem(ui->WalletSelector->findData(name));
+ ui->WalletSelector->removeItem(ui->WalletSelector->findData(QVariant::fromValue(walletModel)));
if (ui->WalletSelector->count() == 2) {
ui->WalletSelector->setVisible(false);
ui->WalletSelectorLabel->setVisible(false);
@@ -910,25 +905,25 @@ void RPCConsole::on_lineEdit_returnPressed()
cmdBeforeBrowsing = QString();
- QString walletID;
+ WalletModel* wallet_model{nullptr};
#ifdef ENABLE_WALLET
const int wallet_index = ui->WalletSelector->currentIndex();
if (wallet_index > 0) {
- walletID = (QString)ui->WalletSelector->itemData(wallet_index).value<QString>();
+ wallet_model = ui->WalletSelector->itemData(wallet_index).value<WalletModel*>();
}
- if (m_last_wallet_id != walletID) {
- if (walletID.isNull()) {
- message(CMD_REQUEST, tr("Executing command without any wallet"));
+ if (m_last_wallet_model != wallet_model) {
+ if (wallet_model) {
+ message(CMD_REQUEST, tr("Executing command using \"%1\" wallet").arg(wallet_model->getWalletName()));
} else {
- message(CMD_REQUEST, tr("Executing command using \"%1\" wallet").arg(walletID));
+ message(CMD_REQUEST, tr("Executing command without any wallet"));
}
- m_last_wallet_id = walletID;
+ m_last_wallet_model = wallet_model;
}
#endif
message(CMD_REQUEST, QString::fromStdString(strFilteredCmd));
- Q_EMIT cmdRequest(cmd, walletID);
+ Q_EMIT cmdRequest(cmd, m_last_wallet_model);
cmd = QString::fromStdString(strFilteredCmd);
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 20dbf5ec95..6c000ba096 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2018 The Bitcoin Core developers
+// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -41,9 +41,9 @@ public:
explicit RPCConsole(interfaces::Node& node, const PlatformStyle *platformStyle, QWidget *parent);
~RPCConsole();
- static bool RPCParseCommandLine(interfaces::Node* node, std::string &strResult, const std::string &strCommand, bool fExecute, std::string * const pstrFilteredOut = nullptr, const std::string *walletID = nullptr);
- static bool RPCExecuteCommandLine(interfaces::Node& node, std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = nullptr, const std::string *walletID = nullptr) {
- return RPCParseCommandLine(&node, strResult, strCommand, true, pstrFilteredOut, walletID);
+ static bool RPCParseCommandLine(interfaces::Node* node, std::string &strResult, const std::string &strCommand, bool fExecute, std::string * const pstrFilteredOut = nullptr, const WalletModel* wallet_model = nullptr);
+ static bool RPCExecuteCommandLine(interfaces::Node& node, std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = nullptr, const WalletModel* wallet_model = nullptr) {
+ return RPCParseCommandLine(&node, strResult, strCommand, true, pstrFilteredOut, wallet_model);
}
void setClientModel(ClientModel *model);
@@ -133,7 +133,7 @@ public Q_SLOTS:
Q_SIGNALS:
// For RPC command executor
void stopExecutor();
- void cmdRequest(const QString &command, const QString &walletID);
+ void cmdRequest(const QString &command, const WalletModel* wallet_model);
private:
void startExecutor();
@@ -165,7 +165,7 @@ private:
int consoleFontSize = 0;
QCompleter *autoCompleter = nullptr;
QThread thread;
- QString m_last_wallet_id;
+ WalletModel* m_last_wallet_model{nullptr};
/** Update UI with latest network info from model. */
void updateNetworkState();
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index d15bd95b8e..4f8b6d363e 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2018 The Bitcoin Core developers
+// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -46,8 +46,7 @@ bool WalletFrame::addWallet(WalletModel *walletModel)
return false;
}
- const QString name = walletModel->getWalletName();
- if (mapWalletViews.count(name) > 0) {
+ if (mapWalletViews.count(walletModel) > 0) {
return false;
}
@@ -65,7 +64,7 @@ bool WalletFrame::addWallet(WalletModel *walletModel)
}
walletStack->addWidget(walletView);
- mapWalletViews[name] = walletView;
+ mapWalletViews[walletModel] = walletView;
// Ensure a walletView is able to show the main window
connect(walletView, &WalletView::showNormalIfMinimized, [this]{
@@ -77,24 +76,24 @@ bool WalletFrame::addWallet(WalletModel *walletModel)
return true;
}
-bool WalletFrame::setCurrentWallet(const QString& name)
+bool WalletFrame::setCurrentWallet(WalletModel* wallet_model)
{
- if (mapWalletViews.count(name) == 0)
+ if (mapWalletViews.count(wallet_model) == 0)
return false;
- WalletView *walletView = mapWalletViews.value(name);
+ WalletView *walletView = mapWalletViews.value(wallet_model);
walletStack->setCurrentWidget(walletView);
assert(walletView);
walletView->updateEncryptionStatus();
return true;
}
-bool WalletFrame::removeWallet(const QString &name)
+bool WalletFrame::removeWallet(WalletModel* wallet_model)
{
- if (mapWalletViews.count(name) == 0)
+ if (mapWalletViews.count(wallet_model) == 0)
return false;
- WalletView *walletView = mapWalletViews.take(name);
+ WalletView *walletView = mapWalletViews.take(wallet_model);
walletStack->removeWidget(walletView);
delete walletView;
return true;
@@ -102,7 +101,7 @@ bool WalletFrame::removeWallet(const QString &name)
void WalletFrame::removeAllWallets()
{
- QMap<QString, WalletView*>::const_iterator i;
+ QMap<WalletModel*, WalletView*>::const_iterator i;
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
walletStack->removeWidget(i.value());
mapWalletViews.clear();
@@ -120,35 +119,35 @@ bool WalletFrame::handlePaymentRequest(const SendCoinsRecipient &recipient)
void WalletFrame::showOutOfSyncWarning(bool fShow)
{
bOutOfSync = fShow;
- QMap<QString, WalletView*>::const_iterator i;
+ QMap<WalletModel*, WalletView*>::const_iterator i;
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
i.value()->showOutOfSyncWarning(fShow);
}
void WalletFrame::gotoOverviewPage()
{
- QMap<QString, WalletView*>::const_iterator i;
+ QMap<WalletModel*, WalletView*>::const_iterator i;
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
i.value()->gotoOverviewPage();
}
void WalletFrame::gotoHistoryPage()
{
- QMap<QString, WalletView*>::const_iterator i;
+ QMap<WalletModel*, WalletView*>::const_iterator i;
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
i.value()->gotoHistoryPage();
}
void WalletFrame::gotoReceiveCoinsPage()
{
- QMap<QString, WalletView*>::const_iterator i;
+ QMap<WalletModel*, WalletView*>::const_iterator i;
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
i.value()->gotoReceiveCoinsPage();
}
void WalletFrame::gotoSendCoinsPage(QString addr)
{
- QMap<QString, WalletView*>::const_iterator i;
+ QMap<WalletModel*, WalletView*>::const_iterator i;
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
i.value()->gotoSendCoinsPage(addr);
}
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
index 05ca569d7a..9fbc8b4d52 100644
--- a/src/qt/walletframe.h
+++ b/src/qt/walletframe.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2017 The Bitcoin Core developers
+// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -37,8 +37,8 @@ public:
void setClientModel(ClientModel *clientModel);
bool addWallet(WalletModel *walletModel);
- bool setCurrentWallet(const QString& name);
- bool removeWallet(const QString &name);
+ bool setCurrentWallet(WalletModel* wallet_model);
+ bool removeWallet(WalletModel* wallet_model);
void removeAllWallets();
bool handlePaymentRequest(const SendCoinsRecipient& recipient);
@@ -53,7 +53,7 @@ private:
QStackedWidget *walletStack;
BitcoinGUI *gui;
ClientModel *clientModel;
- QMap<QString, WalletView*> mapWalletViews;
+ QMap<WalletModel*, WalletView*> mapWalletViews;
bool bOutOfSync;
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index ba16fdd5e1..b7fa636494 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2018 The Bitcoin Core developers
+// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -578,6 +578,12 @@ QString WalletModel::getWalletName() const
return QString::fromStdString(m_wallet->getWalletName());
}
+QString WalletModel::getDisplayName() const
+{
+ const QString name = getWalletName();
+ return name.isEmpty() ? "["+tr("default wallet")+"]" : name;
+}
+
bool WalletModel::isMultiwallet()
{
return m_node.getWallets().size() > 1;
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index ec4c5a2a6c..2988682533 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2018 The Bitcoin Core developers
+// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -219,6 +219,7 @@ public:
interfaces::Wallet& wallet() const { return *m_wallet; }
QString getWalletName() const;
+ QString getDisplayName() const;
bool isMultiwallet();
diff --git a/src/rest.cpp b/src/rest.cpp
index 4988e6ed26..4f26e3afb5 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -136,10 +136,12 @@ static bool rest_headers(HTTPRequest* req,
if (!ParseHashStr(hashStr, hash))
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
+ const CBlockIndex* tip = nullptr;
std::vector<const CBlockIndex *> headers;
headers.reserve(count);
{
LOCK(cs_main);
+ tip = chainActive.Tip();
const CBlockIndex* pindex = LookupBlockIndex(hash);
while (pindex != nullptr && chainActive.Contains(pindex)) {
headers.push_back(pindex);
@@ -175,11 +177,8 @@ static bool rest_headers(HTTPRequest* req,
}
case RetFormat::JSON: {
UniValue jsonHeaders(UniValue::VARR);
- {
- LOCK(cs_main);
- for (const CBlockIndex *pindex : headers) {
- jsonHeaders.push_back(blockheaderToJSON(pindex));
- }
+ for (const CBlockIndex *pindex : headers) {
+ jsonHeaders.push_back(blockheaderToJSON(tip, pindex));
}
std::string strJSON = jsonHeaders.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
@@ -207,8 +206,10 @@ static bool rest_block(HTTPRequest* req,
CBlock block;
CBlockIndex* pblockindex = nullptr;
+ CBlockIndex* tip = nullptr;
{
LOCK(cs_main);
+ tip = chainActive.Tip();
pblockindex = LookupBlockIndex(hash);
if (!pblockindex) {
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
@@ -241,11 +242,7 @@ static bool rest_block(HTTPRequest* req,
}
case RetFormat::JSON: {
- UniValue objBlock;
- {
- LOCK(cs_main);
- objBlock = blockToJSON(block, pblockindex, showTxDetails);
- }
+ UniValue objBlock = blockToJSON(block, tip, pblockindex, showTxDetails);
std::string strJSON = objBlock.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
req->WriteReply(HTTP_OK, strJSON);
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index bd229e5efa..4846d7cc95 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -59,10 +59,7 @@ static CUpdatedBlock latestblock;
*/
double GetDifficulty(const CBlockIndex* blockindex)
{
- if (blockindex == nullptr)
- {
- return 1.0;
- }
+ assert(blockindex);
int nShift = (blockindex->nBits >> 24) & 0xff;
double dDiff =
@@ -82,15 +79,22 @@ double GetDifficulty(const CBlockIndex* blockindex)
return dDiff;
}
-UniValue blockheaderToJSON(const CBlockIndex* blockindex)
+static int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next)
+{
+ next = tip->GetAncestor(blockindex->nHeight + 1);
+ if (next && next->pprev == blockindex) {
+ return tip->nHeight - blockindex->nHeight + 1;
+ }
+ next = nullptr;
+ return blockindex == tip ? 1 : -1;
+}
+
+UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex)
{
- AssertLockHeld(cs_main);
UniValue result(UniValue::VOBJ);
result.pushKV("hash", blockindex->GetBlockHash().GetHex());
- int confirmations = -1;
- // Only report confirmations if the block is on the main chain
- if (chainActive.Contains(blockindex))
- confirmations = chainActive.Height() - blockindex->nHeight + 1;
+ const CBlockIndex* pnext;
+ int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
result.pushKV("confirmations", confirmations);
result.pushKV("height", blockindex->nHeight);
result.pushKV("version", blockindex->nVersion);
@@ -106,21 +110,17 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex)
if (blockindex->pprev)
result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
- CBlockIndex *pnext = chainActive.Next(blockindex);
if (pnext)
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
return result;
}
-UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails)
+UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails)
{
- AssertLockHeld(cs_main);
UniValue result(UniValue::VOBJ);
result.pushKV("hash", blockindex->GetBlockHash().GetHex());
- int confirmations = -1;
- // Only report confirmations if the block is on the main chain
- if (chainActive.Contains(blockindex))
- confirmations = chainActive.Height() - blockindex->nHeight + 1;
+ const CBlockIndex* pnext;
+ int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
result.pushKV("confirmations", confirmations);
result.pushKV("strippedsize", (int)::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS));
result.pushKV("size", (int)::GetSerializeSize(block, PROTOCOL_VERSION));
@@ -152,7 +152,6 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
if (blockindex->pprev)
result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
- CBlockIndex *pnext = chainActive.Next(blockindex);
if (pnext)
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
return result;
@@ -769,7 +768,7 @@ static UniValue getblockheader(const JSONRPCRequest& request)
return strHex;
}
- return blockheaderToJSON(pblockindex);
+ return blockheaderToJSON(chainActive.Tip(), pblockindex);
}
static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
@@ -871,7 +870,7 @@ static UniValue getblock(const JSONRPCRequest& request)
return strHex;
}
- return blockToJSON(block, pblockindex, verbosity >= 2);
+ return blockToJSON(block, chainActive.Tip(), pblockindex, verbosity >= 2);
}
struct CCoinsStats
@@ -1150,7 +1149,7 @@ static UniValue verifychain(const JSONRPCRequest& request)
}
/** Implementation of IsSuperMajority with better feedback */
-static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
+static UniValue SoftForkMajorityDesc(int version, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
{
UniValue rv(UniValue::VOBJ);
bool activated = false;
@@ -1170,7 +1169,7 @@ static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Con
return rv;
}
-static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
+static UniValue SoftForkDesc(const std::string &name, int version, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
{
UniValue rv(UniValue::VOBJ);
rv.pushKV("id", name);
@@ -1277,20 +1276,21 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
LOCK(cs_main);
+ const CBlockIndex* tip = chainActive.Tip();
UniValue obj(UniValue::VOBJ);
obj.pushKV("chain", Params().NetworkIDString());
obj.pushKV("blocks", (int)chainActive.Height());
obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1);
- obj.pushKV("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex());
- obj.pushKV("difficulty", (double)GetDifficulty(chainActive.Tip()));
- obj.pushKV("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast());
- obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip()));
+ obj.pushKV("bestblockhash", tip->GetBlockHash().GetHex());
+ obj.pushKV("difficulty", (double)GetDifficulty(tip));
+ obj.pushKV("mediantime", (int64_t)tip->GetMedianTimePast());
+ obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip));
obj.pushKV("initialblockdownload", IsInitialBlockDownload());
- obj.pushKV("chainwork", chainActive.Tip()->nChainWork.GetHex());
+ obj.pushKV("chainwork", tip->nChainWork.GetHex());
obj.pushKV("size_on_disk", CalculateCurrentUsage());
obj.pushKV("pruned", fPruneMode);
if (fPruneMode) {
- CBlockIndex* block = chainActive.Tip();
+ const CBlockIndex* block = tip;
assert(block);
while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
block = block->pprev;
@@ -1307,7 +1307,6 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
}
const Consensus::Params& consensusParams = Params().GetConsensus();
- CBlockIndex* tip = chainActive.Tip();
UniValue softforks(UniValue::VARR);
UniValue bip9_softforks(UniValue::VOBJ);
softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h
index add335eb8a..529132d033 100644
--- a/src/rpc/blockchain.h
+++ b/src/rpc/blockchain.h
@@ -27,7 +27,7 @@ double GetDifficulty(const CBlockIndex* blockindex);
void RPCNotifyBlockChange(bool ibd, const CBlockIndex *);
/** Block description to JSON */
-UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
+UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails = false);
/** Mempool information to JSON */
UniValue mempoolInfoToJSON();
@@ -36,7 +36,7 @@ UniValue mempoolInfoToJSON();
UniValue mempoolToJSON(bool fVerbose = false);
/** Block header to JSON */
-UniValue blockheaderToJSON(const CBlockIndex* blockindex);
+UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex);
/** Used by getblockstats to get feerates at different percentiles by weight */
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 4d6b260cc7..cc229367ba 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2009-2018 The Bitcoin Core developers
+// Copyright (c) 2009-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -109,11 +109,15 @@ static UniValue getpeerinfo(const JSONRPCRequest& request)
" \"whitelisted\": true|false, (boolean) Whether the peer is whitelisted\n"
" \"minfeefilter\": n, (numeric) The minimum fee rate for transactions this peer accepts\n"
" \"bytessent_per_msg\": {\n"
- " \"addr\": n, (numeric) The total bytes sent aggregated by message type\n"
+ " \"msg\": n, (numeric) The total bytes sent aggregated by message type\n"
+ " When a message type is not listed in this json object, the bytes sent are 0.\n"
+ " Only known message types can appear as keys in the object.\n"
" ...\n"
" },\n"
" \"bytesrecv_per_msg\": {\n"
- " \"addr\": n, (numeric) The total bytes received aggregated by message type\n"
+ " \"msg\": n, (numeric) The total bytes received aggregated by message type\n"
+ " When a message type is not listed in this json object, the bytes received are 0.\n"
+ " Only known message types can appear as keys in the object and all bytes received of unknown message types are listed under '"+NET_MESSAGE_COMMAND_OTHER+"'.\n"
" ...\n"
" }\n"
" }\n"
@@ -178,14 +182,14 @@ static UniValue getpeerinfo(const JSONRPCRequest& request)
obj.pushKV("minfeefilter", ValueFromAmount(stats.minFeeFilter));
UniValue sendPerMsgCmd(UniValue::VOBJ);
- for (const mapMsgCmdSize::value_type &i : stats.mapSendBytesPerMsgCmd) {
+ for (const auto& i : stats.mapSendBytesPerMsgCmd) {
if (i.second > 0)
sendPerMsgCmd.pushKV(i.first, i.second);
}
obj.pushKV("bytessent_per_msg", sendPerMsgCmd);
UniValue recvPerMsgCmd(UniValue::VOBJ);
- for (const mapMsgCmdSize::value_type &i : stats.mapRecvBytesPerMsgCmd) {
+ for (const auto& i : stats.mapRecvBytesPerMsgCmd) {
if (i.second > 0)
recvPerMsgCmd.pushKV(i.first, i.second);
}
diff --git a/src/streams.h b/src/streams.h
index d5565fe61f..0809c96be1 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -64,12 +64,6 @@ public:
size_t size() const { return stream->size(); }
};
-template<typename S>
-OverrideStream<S> WithOrVersion(S* s, int nVersionFlag)
-{
- return OverrideStream<S>(s, s->GetType(), s->GetVersion() | nVersionFlag);
-}
-
/* Minimal stream for overwriting and/or appending to an existing byte vector
*
* The referenced vector will grow as necessary
@@ -126,12 +120,6 @@ class CVectorWriter
{
return nType;
}
- void seek(size_t nSize)
- {
- nPos += nSize;
- if(nPos > vchData.size())
- vchData.resize(nPos);
- }
private:
const int nType;
const int nVersion;
@@ -158,9 +146,11 @@ public:
* @param[in] pos Starting position. Vector index where reads should start.
*/
VectorReader(int type, int version, const std::vector<unsigned char>& data, size_t pos)
- : m_type(type), m_version(version), m_data(data)
+ : m_type(type), m_version(version), m_data(data), m_pos(pos)
{
- seek(pos);
+ if (m_pos > m_data.size()) {
+ throw std::ios_base::failure("VectorReader(...): end of data (m_pos > m_data.size())");
+ }
}
/*
@@ -203,14 +193,6 @@ public:
memcpy(dst, m_data.data() + m_pos, n);
m_pos = pos_next;
}
-
- void seek(size_t n)
- {
- m_pos += n;
- if (m_pos > m_data.size()) {
- throw std::ios_base::failure("VectorReader::seek(): end of data");
- }
- }
};
/** Double ended buffer combining vector and stream-like interfaces.
diff --git a/src/test/blockchain_tests.cpp b/src/test/blockchain_tests.cpp
index 7d8ae46fb8..b61152985f 100644
--- a/src/test/blockchain_tests.cpp
+++ b/src/test/blockchain_tests.cpp
@@ -68,11 +68,4 @@ BOOST_AUTO_TEST_CASE(get_difficulty_for_very_high_target)
TestDifficulty(0x12345678, 5913134931067755359633408.0);
}
-// Verify that difficulty is 1.0 for an empty chain.
-BOOST_AUTO_TEST_CASE(get_difficulty_for_null_tip)
-{
- double difficulty = GetDifficulty(nullptr);
- RejectDifficultyMismatch(difficulty, 1.0);
-}
-
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/key_io_tests.cpp b/src/test/key_io_tests.cpp
index 1abaabd658..bf295042de 100644
--- a/src/test/key_io_tests.cpp
+++ b/src/test/key_io_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2017 The Bitcoin Core developers
+// Copyright (c) 2011-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp
index 1556b2f667..3a2a11ef98 100644
--- a/src/test/script_p2sh_tests.cpp
+++ b/src/test/script_p2sh_tests.cpp
@@ -213,14 +213,22 @@ BOOST_AUTO_TEST_CASE(is)
BOOST_CHECK(p2sh.IsPayToScriptHash());
// Not considered pay-to-script-hash if using one of the OP_PUSHDATA opcodes:
- static const unsigned char direct[] = { OP_HASH160, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL };
- BOOST_CHECK(CScript(direct, direct+sizeof(direct)).IsPayToScriptHash());
- static const unsigned char pushdata1[] = { OP_HASH160, OP_PUSHDATA1, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL };
- BOOST_CHECK(!CScript(pushdata1, pushdata1+sizeof(pushdata1)).IsPayToScriptHash());
- static const unsigned char pushdata2[] = { OP_HASH160, OP_PUSHDATA2, 20,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL };
- BOOST_CHECK(!CScript(pushdata2, pushdata2+sizeof(pushdata2)).IsPayToScriptHash());
- static const unsigned char pushdata4[] = { OP_HASH160, OP_PUSHDATA4, 20,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL };
- BOOST_CHECK(!CScript(pushdata4, pushdata4+sizeof(pushdata4)).IsPayToScriptHash());
+ std::vector<unsigned char> direct = {OP_HASH160, 20};
+ direct.insert(direct.end(), 20, 0);
+ direct.push_back(OP_EQUAL);
+ BOOST_CHECK(CScript(direct.begin(), direct.end()).IsPayToScriptHash());
+ std::vector<unsigned char> pushdata1 = {OP_HASH160, OP_PUSHDATA1, 20};
+ pushdata1.insert(pushdata1.end(), 20, 0);
+ pushdata1.push_back(OP_EQUAL);
+ BOOST_CHECK(!CScript(pushdata1.begin(), pushdata1.end()).IsPayToScriptHash());
+ std::vector<unsigned char> pushdata2 = {OP_HASH160, 20, 0};
+ pushdata2.insert(pushdata2.end(), 20, 0);
+ pushdata2.push_back(OP_EQUAL);
+ BOOST_CHECK(!CScript(pushdata2.begin(), pushdata2.end()).IsPayToScriptHash());
+ std::vector<unsigned char> pushdata4 = {OP_HASH160, 20, 0, 0, 0};
+ pushdata4.insert(pushdata4.end(), 20, 0);
+ pushdata4.push_back(OP_EQUAL);
+ BOOST_CHECK(!CScript(pushdata4.begin(), pushdata4.end()).IsPayToScriptHash());
CScript not_p2sh;
BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
index 26cf74830d..a1940eb80e 100644
--- a/src/test/streams_tests.cpp
+++ b/src/test/streams_tests.cpp
@@ -102,15 +102,15 @@ BOOST_AUTO_TEST_CASE(streams_vector_reader)
BOOST_CHECK_THROW(reader >> d, std::ios_base::failure);
// Read a 4 bytes as a signed int from the beginning of the buffer.
- reader.seek(-6);
- reader >> d;
+ VectorReader new_reader(SER_NETWORK, INIT_PROTO_VERSION, vch, 0);
+ new_reader >> d;
BOOST_CHECK_EQUAL(d, 67370753); // 1,255,3,4 in little-endian base-256
- BOOST_CHECK_EQUAL(reader.size(), 2);
- BOOST_CHECK(!reader.empty());
+ BOOST_CHECK_EQUAL(new_reader.size(), 2);
+ BOOST_CHECK(!new_reader.empty());
// Reading after end of byte vector throws an error even if the reader is
// not totally empty.
- BOOST_CHECK_THROW(reader >> d, std::ios_base::failure);
+ BOOST_CHECK_THROW(new_reader >> d, std::ios_base::failure);
}
BOOST_AUTO_TEST_CASE(bitstream_reader_writer)
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index d952054483..39cff3f463 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -414,7 +414,8 @@ static void ReplaceRedeemScript(CScript& script, const CScript& redeemScript)
script = PushAll(stack);
}
-BOOST_AUTO_TEST_CASE(test_big_witness_transaction) {
+BOOST_AUTO_TEST_CASE(test_big_witness_transaction)
+{
CMutableTransaction mtx;
mtx.nVersion = 1;
@@ -456,9 +457,8 @@ BOOST_AUTO_TEST_CASE(test_big_witness_transaction) {
}
CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION);
- auto vstream = WithOrVersion(&ssout, 0);
- vstream << mtx;
- CTransaction tx(deserialize, vstream);
+ ssout << mtx;
+ CTransaction tx(deserialize, ssout);
// check all inputs concurrently, with the cache
PrecomputedTransactionData txdata(tx);
diff --git a/src/test/txvalidation_tests.cpp b/src/test/txvalidation_tests.cpp
index 473ec5addf..c2777cd6d1 100644
--- a/src/test/txvalidation_tests.cpp
+++ b/src/test/txvalidation_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 The Bitcoin Core developers
+// Copyright (c) 2017-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/threadinterrupt.h b/src/threadinterrupt.h
index 9c6fccfcde..2743571379 100644
--- a/src/threadinterrupt.h
+++ b/src/threadinterrupt.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 The Bitcoin Core developers
+// Copyright (c) 2016-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/validation.cpp b/src/validation.cpp
index 00d7a60cb7..a18e449af6 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -3998,7 +3998,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
LogPrintf("[0%%]..."); /* Continued */
for (pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) {
boost::this_thread::interruption_point();
- int percentageDone = std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
+ const int percentageDone = std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
if (reportDone < percentageDone/10) {
// report every 10% step
LogPrintf("[%d%%]...", percentageDone); /* Continued */
@@ -4056,7 +4056,13 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
if (nCheckLevel >= 4) {
while (pindex != chainActive.Tip()) {
boost::this_thread::interruption_point();
- uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))), false);
+ const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)));
+ if (reportDone < percentageDone/10) {
+ // report every 10% step
+ LogPrintf("[%d%%]...", percentageDone); /* Continued */
+ reportDone = percentageDone/10;
+ }
+ uiInterface.ShowProgress(_("Verifying blocks..."), percentageDone, false);
pindex = chainActive.Next(pindex);
CBlock block;
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 1ed1926af2..0db22cf6fe 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2018 The Bitcoin Core developers
+// Copyright (c) 2012-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -47,7 +47,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
auto locked_chain = chain->lock();
- // Verify ScanForWalletTransactions accomodates a null start block.
+ // Verify ScanForWalletTransactions accommodates a null start block.
{
CWallet wallet(*chain, WalletLocation(), WalletDatabase::CreateDummy());
AddKey(wallet, coinbaseKey);
diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py
new file mode 100644
index 0000000000..02deae92f3
--- /dev/null
+++ b/test/functional/data/invalid_txs.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+# Copyright (c) 2015-2018 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""
+Templates for constructing various sorts of invalid transactions.
+
+These templates (or an iterator over all of them) can be reused in different
+contexts to test using a number of invalid transaction types.
+
+Hopefully this makes it easier to get coverage of a full variety of tx
+validation checks through different interfaces (AcceptBlock, AcceptToMemPool,
+etc.) without repeating ourselves.
+
+Invalid tx cases not covered here can be found by running:
+
+ $ diff \
+ <(grep -IREho "bad-txns[a-zA-Z-]+" src | sort -u) \
+ <(grep -IEho "bad-txns[a-zA-Z-]+" test/functional/data/invalid_txs.py | sort -u)
+
+"""
+import abc
+
+from test_framework.messages import CTransaction, CTxIn, CTxOut, COutPoint
+from test_framework import script as sc
+from test_framework.blocktools import create_tx_with_script, MAX_BLOCK_SIGOPS
+
+basic_p2sh = sc.CScript([sc.OP_HASH160, sc.hash160(sc.CScript([sc.OP_0])), sc.OP_EQUAL])
+
+
+class BadTxTemplate:
+ """Allows simple construction of a certain kind of invalid tx. Base class to be subclassed."""
+ __metaclass__ = abc.ABCMeta
+
+ # The expected error code given by bitcoind upon submission of the tx.
+ reject_reason = ""
+
+ # Only specified if it differs from mempool acceptance error.
+ block_reject_reason = ""
+
+ # Do we expect to be disconnected after submitting this tx?
+ expect_disconnect = False
+
+ # Is this tx considered valid when included in a block, but not for acceptance into
+ # the mempool (i.e. does it violate policy but not consensus)?
+ valid_in_block = False
+
+ def __init__(self, *, spend_tx=None, spend_block=None):
+ self.spend_tx = spend_block.vtx[0] if spend_block else spend_tx
+ self.spend_avail = sum(o.nValue for o in self.spend_tx.vout)
+ self.valid_txin = CTxIn(COutPoint(self.spend_tx.sha256, 0), b"", 0xffffffff)
+
+ @abc.abstractmethod
+ def get_tx(self, *args, **kwargs):
+ """Return a CTransaction that is invalid per the subclass."""
+ pass
+
+
+class OutputMissing(BadTxTemplate):
+ reject_reason = "bad-txns-vout-empty"
+ expect_disconnect = False
+
+ def get_tx(self):
+ tx = CTransaction()
+ tx.vin.append(self.valid_txin)
+ tx.calc_sha256()
+ return tx
+
+
+class InputMissing(BadTxTemplate):
+ reject_reason = "bad-txns-vin-empty"
+ expect_disconnect = False
+
+ def get_tx(self):
+ tx = CTransaction()
+ tx.vout.append(CTxOut(0, sc.CScript([sc.OP_TRUE] * 100)))
+ tx.calc_sha256()
+ return tx
+
+
+class SizeTooSmall(BadTxTemplate):
+ reject_reason = "tx-size-small"
+ expect_disconnect = False
+ valid_in_block = True
+
+ def get_tx(self):
+ tx = CTransaction()
+ tx.vin.append(self.valid_txin)
+ tx.vout.append(CTxOut(0, sc.CScript([sc.OP_TRUE])))
+ tx.calc_sha256()
+ return tx
+
+
+class BadInputOutpointIndex(BadTxTemplate):
+ # Won't be rejected - nonexistent outpoint index is treated as an orphan since the coins
+ # database can't distinguish between spent outpoints and outpoints which never existed.
+ reject_reason = None
+ expect_disconnect = False
+
+ def get_tx(self):
+ num_indices = len(self.spend_tx.vin)
+ bad_idx = num_indices + 100
+
+ tx = CTransaction()
+ tx.vin.append(CTxIn(COutPoint(self.spend_tx.sha256, bad_idx), b"", 0xffffffff))
+ tx.vout.append(CTxOut(0, basic_p2sh))
+ tx.calc_sha256()
+ return tx
+
+
+class DuplicateInput(BadTxTemplate):
+ reject_reason = 'bad-txns-inputs-duplicate'
+ expect_disconnect = True
+
+ def get_tx(self):
+ tx = CTransaction()
+ tx.vin.append(self.valid_txin)
+ tx.vin.append(self.valid_txin)
+ tx.vout.append(CTxOut(1, basic_p2sh))
+ tx.calc_sha256()
+ return tx
+
+
+class NonexistentInput(BadTxTemplate):
+ reject_reason = None # Added as an orphan tx.
+ expect_disconnect = False
+
+ def get_tx(self):
+ tx = CTransaction()
+ tx.vin.append(CTxIn(COutPoint(self.spend_tx.sha256 + 1, 0), b"", 0xffffffff))
+ tx.vin.append(self.valid_txin)
+ tx.vout.append(CTxOut(1, basic_p2sh))
+ tx.calc_sha256()
+ return tx
+
+
+class SpendTooMuch(BadTxTemplate):
+ reject_reason = 'bad-txns-in-belowout'
+ expect_disconnect = True
+
+ def get_tx(self):
+ return create_tx_with_script(
+ self.spend_tx, 0, script_pub_key=basic_p2sh, amount=(self.spend_avail + 1))
+
+
+class SpendNegative(BadTxTemplate):
+ reject_reason = 'bad-txns-vout-negative'
+ expect_disconnect = True
+
+ def get_tx(self):
+ return create_tx_with_script(self.spend_tx, 0, amount=-1)
+
+
+class InvalidOPIFConstruction(BadTxTemplate):
+ reject_reason = "mandatory-script-verify-flag-failed (Invalid OP_IF construction)"
+ expect_disconnect = True
+ valid_in_block = True
+
+ def get_tx(self):
+ return create_tx_with_script(
+ self.spend_tx, 0, script_sig=b'\x64' * 35,
+ amount=(self.spend_avail // 2))
+
+
+class TooManySigops(BadTxTemplate):
+ reject_reason = "bad-txns-too-many-sigops"
+ block_reject_reason = "bad-blk-sigops, out-of-bounds SigOpCount"
+ expect_disconnect = False
+
+ def get_tx(self):
+ lotsa_checksigs = sc.CScript([sc.OP_CHECKSIG] * (MAX_BLOCK_SIGOPS))
+ return create_tx_with_script(
+ self.spend_tx, 0,
+ script_pub_key=lotsa_checksigs,
+ amount=1)
+
+
+def iter_all_templates():
+ """Iterate through all bad transaction template types."""
+ return BadTxTemplate.__subclasses__()
diff --git a/test/functional/feature_assumevalid.py b/test/functional/feature_assumevalid.py
index 3d0467038d..12a4ce9aff 100755
--- a/test/functional/feature_assumevalid.py
+++ b/test/functional/feature_assumevalid.py
@@ -180,7 +180,7 @@ class AssumeValidTest(BitcoinTestFramework):
for i in range(2202):
p2p1.send_message(msg_block(self.blocks[i]))
# Syncing 2200 blocks can take a while on slow systems. Give it plenty of time to sync.
- p2p1.sync_with_ping(120)
+ p2p1.sync_with_ping(150)
assert_equal(self.nodes[1].getblock(self.nodes[1].getbestblockhash())['height'], 2202)
# Send blocks to node2. Block 102 will be rejected.
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index b741339351..244cde044e 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2015-2018 The Bitcoin Core developers
+# Copyright (c) 2015-2019 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 block processing."""
@@ -7,7 +7,13 @@ import copy
import struct
import time
-from test_framework.blocktools import create_block, create_coinbase, create_tx_with_script, get_legacy_sigopcount_block
+from test_framework.blocktools import (
+ create_block,
+ create_coinbase,
+ create_tx_with_script,
+ get_legacy_sigopcount_block,
+ MAX_BLOCK_SIGOPS,
+)
from test_framework.key import CECKey
from test_framework.messages import (
CBlock,
@@ -45,8 +51,7 @@ from test_framework.script import (
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
-
-MAX_BLOCK_SIGOPS = 20000
+from data import invalid_txs
# Use this class for tests that require behavior other than normal "mininode" behavior.
# For now, it is used to serialize a bloated varint (b64).
@@ -95,16 +100,21 @@ class FullBlockTest(BitcoinTestFramework):
self.save_spendable_output()
self.sync_blocks([b0])
+ # These constants chosen specifically to trigger an immature coinbase spend
+ # at a certain time below.
+ NUM_BUFFER_BLOCKS_TO_GENERATE = 99
+ NUM_OUTPUTS_TO_COLLECT = 33
+
# Allow the block to mature
blocks = []
- for i in range(99):
- blocks.append(self.next_block(5000 + i))
+ for i in range(NUM_BUFFER_BLOCKS_TO_GENERATE):
+ blocks.append(self.next_block("maturitybuffer.{}".format(i)))
self.save_spendable_output()
self.sync_blocks(blocks)
# collect spendable outputs now to avoid cluttering the code later on
out = []
- for i in range(33):
+ for i in range(NUM_OUTPUTS_TO_COLLECT):
out.append(self.get_spendable_output())
# Start by building a couple of blocks on top (which output is spent is
@@ -116,7 +126,48 @@ class FullBlockTest(BitcoinTestFramework):
b2 = self.next_block(2, spend=out[1])
self.save_spendable_output()
- self.sync_blocks([b1, b2])
+ self.sync_blocks([b1, b2], timeout=4)
+
+ # Select a txn with an output eligible for spending. This won't actually be spent,
+ # since we're testing submission of a series of blocks with invalid txns.
+ attempt_spend_tx = out[2]
+
+ # Submit blocks for rejection, each of which contains a single transaction
+ # (aside from coinbase) which should be considered invalid.
+ for TxTemplate in invalid_txs.iter_all_templates():
+ template = TxTemplate(spend_tx=attempt_spend_tx)
+
+ if template.valid_in_block:
+ continue
+
+ self.log.info("Reject block with invalid tx: %s", TxTemplate.__name__)
+ blockname = "for_invalid.%s" % TxTemplate.__name__
+ badblock = self.next_block(blockname)
+ badtx = template.get_tx()
+ if TxTemplate != invalid_txs.InputMissing:
+ self.sign_tx(badtx, attempt_spend_tx)
+ else:
+ # Segwit is active in regtest at this point, so to deserialize a
+ # transaction without any inputs correctly, we set the outputs
+ # to an empty list. This is a hack, as the serialization of an
+ # empty list of outputs is deserialized as flags==0 and thus
+ # deserialization of the outputs is skipped.
+ # A policy check requires "loose" txs to be of a minimum size,
+ # so vtx is not set to be empty in the TxTemplate class and we
+ # only apply the workaround where txs are not "loose", i.e. in
+ # blocks.
+ #
+ # The workaround has the purpose that both sides calculate
+ # the same tx hash in the merkle tree
+ badtx.vout = []
+ badtx.rehash()
+ badblock = self.update_block(blockname, [badtx])
+ self.sync_blocks(
+ [badblock], success=False,
+ reject_reason=(template.block_reject_reason or template.reject_reason),
+ reconnect=True, timeout=2)
+
+ self.move_tip(2)
# Fork like this:
#
@@ -1288,7 +1339,7 @@ class FullBlockTest(BitcoinTestFramework):
self.blocks[block_number] = block
return block
- def bootstrap_p2p(self):
+ def bootstrap_p2p(self, timeout=10):
"""Add a P2P connection to the node.
Helper to connect and wait for version handshake."""
@@ -1299,15 +1350,15 @@ class FullBlockTest(BitcoinTestFramework):
# an INV for the next block and receive two getheaders - one for the
# IBD and one for the INV. We'd respond to both and could get
# unexpectedly disconnected if the DoS score for that error is 50.
- self.nodes[0].p2p.wait_for_getheaders(timeout=5)
+ self.nodes[0].p2p.wait_for_getheaders(timeout=timeout)
- def reconnect_p2p(self):
+ def reconnect_p2p(self, timeout=60):
"""Tear down and bootstrap the P2P connection to the node.
The node gets disconnected several times in this test. This helper
method reconnects the p2p and restarts the network thread."""
self.nodes[0].disconnect_p2ps()
- self.bootstrap_p2p()
+ self.bootstrap_p2p(timeout=timeout)
def sync_blocks(self, blocks, success=True, reject_reason=None, force_send=False, reconnect=False, timeout=60):
"""Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block.
@@ -1316,7 +1367,7 @@ class FullBlockTest(BitcoinTestFramework):
self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_reason=reject_reason, force_send=force_send, timeout=timeout, expect_disconnect=reconnect)
if reconnect:
- self.reconnect_p2p()
+ self.reconnect_p2p(timeout=timeout)
if __name__ == '__main__':
diff --git a/test/functional/feature_dbcrash.py b/test/functional/feature_dbcrash.py
index 70d67aa53a..8b06cc7372 100755
--- a/test/functional/feature_dbcrash.py
+++ b/test/functional/feature_dbcrash.py
@@ -46,7 +46,7 @@ class ChainstateWriteCrashTest(BitcoinTestFramework):
self.num_nodes = 4
self.setup_clean_chain = False
# Need a bit of extra time for the nodes to start up for this test
- self.rpc_timewait = 90
+ self.rpc_timeout = 90
# Set -maxmempool=0 to turn off mempool memory sharing with dbcache
# Set -rpcservertimeout=900 to reduce socket disconnects in this
diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py
index 11c6712881..9a3f4fae45 100755
--- a/test/functional/feature_pruning.py
+++ b/test/functional/feature_pruning.py
@@ -29,7 +29,7 @@ class PruneTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 6
- self.rpc_timewait = 900
+ self.rpc_timeout = 900
# Create nodes 0 and 1 to mine.
# Create node 2 to test pruning.
diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
index 02f1cc4391..e2a219b85a 100755
--- a/test/functional/mempool_accept.py
+++ b/test/functional/mempool_accept.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2017 The Bitcoin Core developers
+# Copyright (c) 2017-2018 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 mempool acceptance of raw transactions."""
diff --git a/test/functional/p2p_invalid_locator.py b/test/functional/p2p_invalid_locator.py
index c8c752d1f7..33b7060060 100755
--- a/test/functional/p2p_invalid_locator.py
+++ b/test/functional/p2p_invalid_locator.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2015-2017 The Bitcoin Core developers
+# Copyright (c) 2015-2018 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 node responses to invalid locators.
diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py
index 58e129b57d..1b18dd3e58 100755
--- a/test/functional/p2p_invalid_tx.py
+++ b/test/functional/p2p_invalid_tx.py
@@ -5,7 +5,7 @@
"""Test node responses to invalid transactions.
In this test we connect to one node over p2p, and test tx requests."""
-from test_framework.blocktools import create_block, create_coinbase, create_tx_with_script
+from test_framework.blocktools import create_block, create_coinbase
from test_framework.messages import (
COIN,
COutPoint,
@@ -19,6 +19,7 @@ from test_framework.util import (
assert_equal,
wait_until,
)
+from data import invalid_txs
class InvalidTxRequestTest(BitcoinTestFramework):
@@ -63,12 +64,21 @@ class InvalidTxRequestTest(BitcoinTestFramework):
self.log.info("Mature the block.")
self.nodes[0].generatetoaddress(100, self.nodes[0].get_deterministic_priv_key().address)
- # b'\x64' is OP_NOTIF
- # Transaction will be rejected with code 16 (REJECT_INVALID)
- # and we get disconnected immediately
- self.log.info('Test a transaction that is rejected')
- tx1 = create_tx_with_script(block1.vtx[0], 0, script_sig=b'\x64' * 35, amount=50 * COIN - 12000)
- node.p2p.send_txs_and_test([tx1], node, success=False, expect_disconnect=True)
+ # Iterate through a list of known invalid transaction types, ensuring each is
+ # rejected. Some are consensus invalid and some just violate policy.
+ for BadTxTemplate in invalid_txs.iter_all_templates():
+ self.log.info("Testing invalid transaction: %s", BadTxTemplate.__name__)
+ template = BadTxTemplate(spend_block=block1)
+ tx = template.get_tx()
+ node.p2p.send_txs_and_test(
+ [tx], node, success=False,
+ expect_disconnect=template.expect_disconnect,
+ reject_reason=template.reject_reason,
+ )
+
+ if template.expect_disconnect:
+ self.log.info("Reconnecting to peer")
+ self.reconnect_p2p()
# Make two p2p connections to provide the node with orphans
# * p2ps[0] will send valid orphan txs (one with low fee)
diff --git a/test/functional/rpc_bind.py b/test/functional/rpc_bind.py
index c23aa13685..3938ca98dd 100755
--- a/test/functional/rpc_bind.py
+++ b/test/functional/rpc_bind.py
@@ -70,7 +70,7 @@ class RPCBindTest(BitcoinTestFramework):
self.log.info("Check for ipv6")
have_ipv6 = test_ipv6_local()
- if not have_ipv6 and not self.options.run_ipv4:
+ if not have_ipv6 and not (self.options.run_ipv4 or self.options.run_nonloopback):
raise SkipTest("This test requires ipv6 support.")
self.log.info("Check for non-loopback interface")
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index 0c61e9ab62..4f350953b2 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -32,7 +32,7 @@ class RawTransactionsTest(BitcoinTestFramework):
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
- def setup_network(self, split=False):
+ def setup_network(self):
self.setup_nodes()
connect_nodes_bi(self.nodes, 0, 1)
diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py
index 0affddcf05..b12eb1d9ec 100755
--- a/test/functional/rpc_net.py
+++ b/test/functional/rpc_net.py
@@ -67,8 +67,8 @@ class NetTest(BitcoinTestFramework):
peer_info_after_ping = self.nodes[0].getpeerinfo()
for before, after in zip(peer_info, peer_info_after_ping):
- assert_greater_than_or_equal(after['bytesrecv_per_msg']['pong'], before['bytesrecv_per_msg']['pong'] + 32)
- assert_greater_than_or_equal(after['bytessent_per_msg']['ping'], before['bytessent_per_msg']['ping'] + 32)
+ assert_greater_than_or_equal(after['bytesrecv_per_msg'].get('pong', 0), before['bytesrecv_per_msg'].get('pong', 0) + 32)
+ assert_greater_than_or_equal(after['bytessent_per_msg'].get('ping', 0), before['bytessent_per_msg'].get('ping', 0) + 32)
def _test_getnetworkinginfo(self):
assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True)
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index fc012e6e3a..5b9dbef68d 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -47,7 +47,7 @@ class RawTransactionsTest(BitcoinTestFramework):
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
- def setup_network(self, split=False):
+ def setup_network(self):
super().setup_network()
connect_nodes_bi(self.nodes, 0, 2)
diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py
index 81cce1167b..7679ea5398 100644
--- a/test/functional/test_framework/blocktools.py
+++ b/test/functional/test_framework/blocktools.py
@@ -41,6 +41,8 @@ from .script import (
from .util import assert_equal
from io import BytesIO
+MAX_BLOCK_SIGOPS = 20000
+
# From BIP141
WITNESS_COMMITMENT_HEADER = b"\xaa\x21\xa9\xed"
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index 21bf35597e..352fa32b5b 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -95,7 +95,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.nodes = []
self.network_thread = None
self.mocktime = 0
- self.rpc_timewait = 60 # Wait for up to 60 seconds for the RPC server to respond
+ self.rpc_timeout = 60 # Wait for up to 60 seconds for the RPC server to respond
self.supports_cli = False
self.bind_to_localhost_only = True
self.set_test_params()
@@ -301,7 +301,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
i,
get_datadir_path(self.options.tmpdir, i),
rpchost=rpchost,
- timewait=self.rpc_timewait,
+ timewait=self.rpc_timeout,
bitcoind=binary[i],
bitcoin_cli=self.options.bitcoincli,
mocktime=self.mocktime,
@@ -388,21 +388,6 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
sync_blocks(group)
sync_mempools(group)
- def enable_mocktime(self):
- """Enable mocktime for the script.
-
- mocktime may be needed for scripts that use the cached version of the
- blockchain. If the cached version of the blockchain is used without
- mocktime then the mempools will not sync due to IBD.
-
- For backward compatibility of the python scripts with previous
- versions of the cache, this helper function sets mocktime to Jan 1,
- 2014 + (201 * 10 * 60)"""
- self.mocktime = 1388534400 + (201 * 10 * 60)
-
- def disable_mocktime(self):
- self.mocktime = 0
-
# Private helper methods. These should not be accessed by the subclass test scripts.
def _start_logging(self):
@@ -460,7 +445,18 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
args = [self.options.bitcoind, "-datadir=" + datadir, '-disablewallet']
if i > 0:
args.append("-connect=127.0.0.1:" + str(p2p_port(0)))
- self.nodes.append(TestNode(i, get_datadir_path(self.options.cachedir, i), extra_conf=["bind=127.0.0.1"], extra_args=[], rpchost=None, timewait=self.rpc_timewait, bitcoind=self.options.bitcoind, bitcoin_cli=self.options.bitcoincli, mocktime=self.mocktime, coverage_dir=None))
+ self.nodes.append(TestNode(
+ i,
+ get_datadir_path(self.options.cachedir, i),
+ extra_conf=["bind=127.0.0.1"],
+ extra_args=[],
+ rpchost=None,
+ timewait=self.rpc_timeout,
+ bitcoind=self.options.bitcoind,
+ bitcoin_cli=self.options.bitcoincli,
+ mocktime=self.mocktime,
+ coverage_dir=None,
+ ))
self.nodes[i].args = args
self.start_node(i)
@@ -468,6 +464,11 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
for node in self.nodes:
node.wait_for_rpc_connection()
+ # For backward compatibility of the python scripts with previous
+ # versions of the cache, set mocktime to Jan 1,
+ # 2014 + (201 * 10 * 60)"""
+ self.mocktime = 1388534400 + (201 * 10 * 60)
+
# Create a 200-block-long chain; each of the 4 first nodes
# gets 25 mature blocks and 25 immature.
# Note: To preserve compatibility with older versions of
@@ -475,7 +476,6 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
#
# blocks are created with timestamps 10 minutes apart
# starting from 2010 minutes in the past
- self.enable_mocktime()
block_time = self.mocktime - (201 * 10 * 60)
for i in range(2):
for peer in range(4):
@@ -489,7 +489,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
# Shut them down, and clean up cache directories:
self.stop_nodes()
self.nodes = []
- self.disable_mocktime()
+ self.mocktime = 0
def cache_path(n, *paths):
return os.path.join(get_datadir_path(self.options.cachedir, n), "regtest", *paths)
diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py
index 32ec385fa1..dd3750203a 100755
--- a/test/functional/wallet_backup.py
+++ b/test/functional/wallet_backup.py
@@ -48,7 +48,7 @@ class WalletBackupTest(BitcoinTestFramework):
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
- def setup_network(self, split=False):
+ def setup_network(self):
self.setup_nodes()
connect_nodes(self.nodes[0], 3)
connect_nodes(self.nodes[1], 3)
diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py
index 20cb816ee8..3f39654bb8 100755
--- a/test/functional/wallet_dump.py
+++ b/test/functional/wallet_dump.py
@@ -94,7 +94,7 @@ class WalletDumpTest(BitcoinTestFramework):
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
- def setup_network(self, split=False):
+ def setup_network(self):
self.add_nodes(self.num_nodes, extra_args=self.extra_args)
self.start_nodes()
diff --git a/test/functional/wallet_groups.py b/test/functional/wallet_groups.py
index 9d61483868..5452433acf 100755
--- a/test/functional/wallet_groups.py
+++ b/test/functional/wallet_groups.py
@@ -21,7 +21,7 @@ class WalletGroupTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 3
self.extra_args = [[], [], ['-avoidpartialspends']]
- self.rpc_timewait = 120
+ self.rpc_timeout = 120
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py
index 8ca0387268..17f044bf65 100755
--- a/test/functional/wallet_listtransactions.py
+++ b/test/functional/wallet_listtransactions.py
@@ -25,12 +25,13 @@ def tx_from_hex(hexstring):
class ListTransactionsTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
- self.enable_mocktime()
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
def run_test(self):
+ self.nodes[0].generate(1) # Get out of IBD
+ self.sync_all()
# Simple send, 0 to 1:
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
self.sync_all()
diff --git a/test/lint/lint-python-dead-code.sh b/test/lint/lint-python-dead-code.sh
index 4561b0db30..1b897cd131 100755
--- a/test/lint/lint-python-dead-code.sh
+++ b/test/lint/lint-python-dead-code.sh
@@ -16,4 +16,4 @@ fi
vulture \
--min-confidence 60 \
--ignore-names "argtypes,connection_lost,connection_made,converter,data_received,daemon,errcheck,get_ecdh_key,get_privkey,is_compressed,is_fullyvalid,msg_generic,on_*,optionxform,restype,set_privkey" \
- $(git ls-files -- "*.py" ":(exclude)contrib/")
+ $(git ls-files -- "*.py" ":(exclude)contrib/" ":(exclude)test/functional/data/invalid_txs.py")
diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index e90d5c2ac0..f0107f1361 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -29,7 +29,6 @@ unsigned-integer-overflow:policy/fees.cpp
unsigned-integer-overflow:prevector.h
unsigned-integer-overflow:script/interpreter.cpp
unsigned-integer-overflow:stl_bvector.h
-unsigned-integer-overflow:streams.h
unsigned-integer-overflow:txmempool.cpp
unsigned-integer-overflow:util/strencodings.cpp
unsigned-integer-overflow:validation.cpp