aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/debian/changelog125
-rw-r--r--contrib/debian/control55
-rwxr-xr-xcontrib/debian/rules4
-rwxr-xr-xcontrib/devtools/github-merge.py2
-rwxr-xr-xdepends/config.guess12
-rwxr-xr-xdepends/config.sub14
-rw-r--r--depends/packages/boost.mk6
-rw-r--r--depends/packages/dbus.mk6
-rw-r--r--depends/packages/libevent.mk6
-rw-r--r--depends/packages/native_ccache.mk4
-rw-r--r--doc/developer-notes.md7
-rw-r--r--src/Makefile.am3
-rw-r--r--src/amount.h45
-rw-r--r--src/bench/checkblock.cpp4
-rw-r--r--src/bitcoin-cli.cpp4
-rw-r--r--src/chainparams.cpp38
-rw-r--r--src/chainparams.h16
-rw-r--r--src/chainparamsbase.cpp19
-rw-r--r--src/chainparamsbase.h10
-rw-r--r--src/httprpc.cpp4
-rw-r--r--src/httpserver.cpp12
-rw-r--r--src/init.cpp75
-rw-r--r--src/miner.cpp1
-rw-r--r--src/net.cpp10
-rw-r--r--src/net.h1
-rw-r--r--src/policy/feerate.cpp (renamed from src/amount.cpp)2
-rw-r--r--src/policy/feerate.h54
-rw-r--r--src/policy/fees.h1
-rw-r--r--src/policy/policy.cpp39
-rw-r--r--src/policy/policy.h6
-rw-r--r--src/primitives/transaction.h37
-rw-r--r--src/qt/coincontroldialog.cpp7
-rw-r--r--src/qt/guiutil.cpp2
-rw-r--r--src/qt/paymentserver.cpp12
-rw-r--r--src/random.cpp55
-rw-r--r--src/rpc/blockchain.cpp40
-rw-r--r--src/rpc/client.cpp2
-rw-r--r--src/rpc/server.cpp14
-rw-r--r--src/support/cleanse.h1
-rw-r--r--src/test/addrman_tests.cpp195
-rw-r--r--src/test/amount_tests.cpp1
-rw-r--r--src/test/main_tests.cpp7
-rw-r--r--src/test/miner_tests.cpp3
-rw-r--r--src/test/pow_tests.cpp32
-rw-r--r--src/test/util_tests.cpp77
-rw-r--r--src/test/versionbits_tests.cpp6
-rw-r--r--src/txmempool.h20
-rw-r--r--src/util.cpp45
-rw-r--r--src/util.h63
-rw-r--r--src/utiltime.cpp14
-rw-r--r--src/utiltime.h2
-rw-r--r--src/validation.h1
-rw-r--r--src/wallet/coincontrol.h1
-rw-r--r--src/wallet/db.h43
-rw-r--r--src/wallet/feebumper.cpp2
-rw-r--r--src/wallet/rpcwallet.cpp4
-rw-r--r--src/wallet/wallet.cpp10
-rw-r--r--src/wallet/wallet.h1
-rwxr-xr-xtest/functional/blockchain.py9
-rwxr-xr-xtest/functional/disablewallet.py2
-rwxr-xr-xtest/functional/disconnect_ban.py8
-rwxr-xr-xtest/functional/net.py1
-rwxr-xr-xtest/functional/rpcnamedargs.py1
-rwxr-xr-xtest/functional/sendheaders.py16
-rwxr-xr-xtest/functional/signmessages.py1
-rwxr-xr-xtest/functional/test_framework/mininode.py2
-rwxr-xr-xtest/functional/wallet-accounts.py1
-rwxr-xr-xtest/functional/wallet-hd.py1
68 files changed, 812 insertions, 512 deletions
diff --git a/contrib/debian/changelog b/contrib/debian/changelog
index 110bfe03ef..33dab9b638 100644
--- a/contrib/debian/changelog
+++ b/contrib/debian/changelog
@@ -1,3 +1,122 @@
+bitcoin (0.14.1-trusty4) trusty; urgency=medium
+
+ * Re-enable UPnP support.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Fri, 05 May 2017 13:28:00 -0400
+
+bitcoin (0.14.1-trusty3) trusty; urgency=medium
+
+ * Build with qt5 if we are on a non-Ubuntu (ie non-Unity) distro.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Thu, 04 May 2017 17:13:00 -0400
+
+bitcoin (0.14.1-trusty2) trusty; urgency=medium
+
+ * Bump minimum boost version in deps.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Thu, 04 May 2017 17:12:00 -0400
+
+bitcoin (0.14.1-trusty1) trusty; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Sat, 22 Apr 2017 17:10:00 -0400
+
+bitcoin (0.14.0-trusty1) trusty; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Wed, 08 Mar 2017 10:30:00 -0500
+
+bitcoin (0.13.2-trusty1) trusty; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Thu, 05 Jan 2017 09:59:00 -0500
+
+bitcoin (0.13.1-trusty2) trusty; urgency=medium
+
+ * Revert to Qt4, due to https://github.com/bitcoin/bitcoin/issues/9038
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Mon, 31 Oct 2016 11:16:00 -0400
+
+bitcoin (0.13.1-trusty1) trusty; urgency=medium
+
+ * New upstream release.
+ * Backport updated bitcoin-qt.desktop from upstream master
+ * Add zmq dependency
+ * Switch to Qt5 (breaks precise, but that was already broken by C++11)
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Thu, 27 Oct 2016 17:32:00 -0400
+
+bitcoin (0.13.0-trusty1) trusty; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Sun, 04 Sep 2016 22:09:00 -0400
+
+bitcoin (0.12.1-trusty1) trusty; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Mon, 18 Apr 2016 14:26:00 -0700
+
+bitcoin (0.12.0-trusty6) trusty; urgency=medium
+
+ * Fix program-options dep.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Fri, 25 Mar 2016 21:41:00 -0700
+
+bitcoin (0.12.0-trusty5) trusty; urgency=medium
+
+ * Test explicit --with-gui
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 23 Feb 2015 23:25:00 -0800
+
+bitcoin (0.12.0-trusty4) trusty; urgency=medium
+
+ * Fix libevent-dev dep.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 23 Feb 2015 23:25:00 -0800
+
+bitcoin (0.12.0-trusty3) trusty; urgency=medium
+
+ * Fix precise boost dep.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 23 Feb 2015 19:55:00 -0800
+
+bitcoin (0.12.0-trusty2) trusty; urgency=medium
+
+ * Fix libevent dep.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 23 Feb 2015 19:53:00 -0800
+
+bitcoin (0.12.0-trusty1) trusty; urgency=medium
+
+ * New upstream release
+ * Various updates to contrib/debian were merged, a few were not
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 23 Feb 2015 19:29:00 -0800
+
+bitcoin (0.11.2-trusty1) trusty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Fri, 13 Nov 2015 18:39:00 -0800
+
+bitcoin (0.11.1-trusty2) trusty; urgency=low
+
+ * Remove minupnpc builddep.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Wed, 14 Oct 2015 23:06:00 -1000
+
+bitcoin (0.11.1-trusty1) trusty; urgency=high
+
+ * New upstream release.
+ * Disable all UPnP support.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Wed, 14 Oct 2015 13:57:00 -1000
+
bitcoin (0.11.0-precise1) precise; urgency=medium
* New upstream release.
@@ -179,7 +298,7 @@ bitcoin (0.5.3-natty0) natty; urgency=low
bitcoin (0.5.2-natty1) natty; urgency=low
* Remove mentions on anonymity in package descriptions and manpage.
- These should never have been there, bitcoin isn't anonymous without
+ These should never have been there, bitcoin isnt anonymous without
a ton of work that virtually no users will ever be willing and
capable of doing
@@ -220,7 +339,7 @@ bitcoin (0.5.0~rc1-natty1) natty; urgency=low
* Add test_bitcoin to build test
* Fix clean
- * Remove unnecessary build-dependancies
+ * Remove uneccessary build-dependancies
-- Matt Corallo <matt@bluematt.me> Wed, 26 Oct 2011 14:37:18 -0400
@@ -380,7 +499,7 @@ bitcoin (0.3.20.01~dfsg-1) unstable; urgency=low
bitcoin (0.3.19~dfsg-6) unstable; urgency=low
- * Fix override aggressive optimizations.
+ * Fix override agressive optimizations.
* Fix tighten build-dependencies to really fit backporting to Lenny:
+ Add fallback build-dependency on libdb4.6++-dev.
+ Tighten unversioned Boost build-dependencies to recent versions,
diff --git a/contrib/debian/control b/contrib/debian/control
index fce6bc0118..0d6ad25e24 100644
--- a/contrib/debian/control
+++ b/contrib/debian/control
@@ -1,27 +1,30 @@
Source: bitcoin
Section: utils
Priority: optional
-Maintainer: Jonas Smedegaard <dr@jones.dk>
-Uploaders: Micah Anderson <micah@debian.org>
+Maintainer: Matt Corallo <matt@mattcorallo.com>
+Uploaders: Matt Corallo <matt@mattcorallo.com>
Build-Depends: debhelper,
devscripts,
automake,
libtool,
bash-completion,
- libboost-system-dev (>> 1.35) | libboost-system1.35-dev,
libdb4.8++-dev,
libssl-dev,
pkg-config,
- libminiupnpc8-dev | libminiupnpc-dev (>> 1.6),
- libboost-filesystem-dev (>> 1.35) | libboost-filesystem1.35-dev,
- libboost-program-options-dev (>> 1.35) | libboost-program-options1.35-dev,
- libboost-thread-dev (>> 1.35) | libboost-thread1.35-dev,
- libboost-test-dev (>> 1.35) | libboost-test1.35-dev,
- qt4-qmake,
- libqt4-dev,
+ libevent-dev,
+ libboost-system1.48-dev | libboost-system-dev (>> 1.47),
+ libboost-filesystem1.48-dev | libboost-filesystem-dev (>> 1.47),
+ libboost-program-options1.48-dev | libboost-program-options-dev (>> 1.47),
+ libboost-thread1.48-dev | libboost-thread-dev (>> 1.47),
+ libboost-test1.48-dev | libboost-test-dev (>> 1.47),
+ libboost-chrono1.48-dev | libboost-chrono-dev (>> 1.47),
+ libminiupnpc8-dev | libminiupnpc-dev,
+ qt4-qmake, libqt4-dev,
+ qttools5-dev-tools, qttools5-dev,
libqrencode-dev,
libprotobuf-dev, protobuf-compiler,
- python
+ python,
+ libzmq3-dev
Standards-Version: 3.9.2
Homepage: https://bitcoincore.org/
Vcs-Git: git://github.com/bitcoin/bitcoin.git
@@ -31,11 +34,11 @@ Package: bitcoind
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: peer-to-peer network based digital currency - daemon
- Bitcoin is an experimental new digital currency that enables instant
- payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer
- technology to operate with no central authority: managing transactions
- and issuing money are carried out collectively by the network. Bitcoin Core
- is the name of the open source software which enables the use of this currency.
+ Bitcoin is a free open source peer-to-peer electronic cash system that
+ is completely decentralized, without the need for a central server or
+ trusted parties. Users hold the crypto keys to their own money and
+ transact directly with each other, with the help of a P2P network to
+ check for double-spending.
.
This package provides the daemon, bitcoind, and the CLI tool
bitcoin-cli to interact with the daemon.
@@ -44,11 +47,11 @@ Package: bitcoin-qt
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: peer-to-peer network based digital currency - Qt GUI
- Bitcoin is an experimental new digital currency that enables instant
- payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer
- technology to operate with no central authority: managing transactions
- and issuing money are carried out collectively by the network. Bitcoin Core
- is the name of the open source software which enables the use of this currency.
+ Bitcoin is a free open source peer-to-peer electronic cash system that
+ is completely decentralized, without the need for a central server or
+ trusted parties. Users hold the crypto keys to their own money and
+ transact directly with each other, with the help of a P2P network to
+ check for double-spending.
.
This package provides Bitcoin-Qt, a GUI for Bitcoin based on Qt.
@@ -56,11 +59,11 @@ Package: bitcoin-tx
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: peer-to-peer digital currency - standalone transaction tool
- Bitcoin is an experimental new digital currency that enables instant
- payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer
- technology to operate with no central authority: managing transactions
- and issuing money are carried out collectively by the network. Bitcoin Core
- is the name of the open source software which enables the use of this currency.
+ Bitcoin is a free open source peer-to-peer electronic cash system that
+ is completely decentralized, without the need for a central server or
+ trusted parties. Users hold the crypto keys to their own money and
+ transact directly with each other, with the help of a P2P network to
+ check for double-spending.
.
This package provides bitcoin-tx, a command-line transaction creation
tool which can be used without a bitcoin daemon. Some means of
diff --git a/contrib/debian/rules b/contrib/debian/rules
index 3896d2caa3..6885e38521 100755
--- a/contrib/debian/rules
+++ b/contrib/debian/rules
@@ -12,10 +12,12 @@ override_dh_auto_clean:
if [ -f Makefile ]; then $(MAKE) distclean; fi
rm -rf Makefile.in aclocal.m4 configure src/Makefile.in src/bitcoin-config.h.in src/build-aux src/qt/Makefile.in src/qt/test/Makefile.in src/test/Makefile.in
+QT=$(shell dpkg-vendor --derives-from Ubuntu && echo qt4 || echo qt5)
+
# Yea, autogen should be run on the source archive, but I like doing git archive
override_dh_auto_configure:
./autogen.sh
- ./configure
+ ./configure --with-gui=$(QT)
override_dh_auto_test:
make check
diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py
index 03ccf5b624..8fce648fc2 100755
--- a/contrib/devtools/github-merge.py
+++ b/contrib/devtools/github-merge.py
@@ -15,7 +15,7 @@
# In case of a clean merge that is accepted by the user, the local branch with
# name $BRANCH is overwritten with the merged result, and optionally pushed.
from __future__ import division,print_function,unicode_literals
-import os,sys
+import os
from sys import stdin,stdout,stderr
import argparse
import hashlib
diff --git a/depends/config.guess b/depends/config.guess
index bbd48b60e8..69ed3e573b 100755
--- a/depends/config.guess
+++ b/depends/config.guess
@@ -2,7 +2,7 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2017 Free Software Foundation, Inc.
-timestamp='2017-01-01'
+timestamp='2017-03-05'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -837,10 +837,11 @@ EOF
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_PROCESSOR} in
amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=x86_64 ;;
+ i386)
+ UNAME_PROCESSOR=i586 ;;
esac
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
@@ -1343,6 +1344,9 @@ EOF
NSR-?:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit ;;
+ NSX-?:NONSTOP_KERNEL:*:*)
+ echo nsx-tandem-nsk${UNAME_RELEASE}
+ exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
exit ;;
diff --git a/depends/config.sub b/depends/config.sub
index 7e792b4ae1..40ea5dfe11 100755
--- a/depends/config.sub
+++ b/depends/config.sub
@@ -2,7 +2,7 @@
# Configuration validation subroutine script.
# Copyright 1992-2017 Free Software Foundation, Inc.
-timestamp='2017-01-01'
+timestamp='2017-04-02'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -263,7 +263,7 @@ case $basic_machine in
| fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
- | i370 | i860 | i960 | ia64 \
+ | i370 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
@@ -315,6 +315,7 @@ case $basic_machine in
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \
+ | wasm32 \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
@@ -388,7 +389,7 @@ case $basic_machine in
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
+ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
@@ -446,6 +447,7 @@ case $basic_machine in
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| visium-* \
+ | wasm32-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@@ -948,6 +950,9 @@ case $basic_machine in
nsr-tandem)
basic_machine=nsr-tandem
;;
+ nsx-tandem)
+ basic_machine=nsx-tandem
+ ;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
@@ -1243,6 +1248,9 @@ case $basic_machine in
basic_machine=a29k-wrs
os=-vxworks
;;
+ wasm32)
+ basic_machine=wasm32-unknown
+ ;;
w65*)
basic_machine=w65-wdc
os=-none
diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk
index 57d96e4821..bf773ccd14 100644
--- a/depends/packages/boost.mk
+++ b/depends/packages/boost.mk
@@ -1,8 +1,8 @@
package=boost
-$(package)_version=1_63_0
-$(package)_download_path=https://sourceforge.net/projects/boost/files/boost/1.63.0
+$(package)_version=1_64_0
+$(package)_download_path=https://dl.bintray.com/boostorg/release/1.64.0/source/
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
-$(package)_sha256_hash=beae2529f759f6b3bf3f4969a19c2e9d6f0c503edcb2de4a61d1428519fcb3b0
+$(package)_sha256_hash=7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332
define $(package)_set_vars
$(package)_config_opts_release=variant=release
diff --git a/depends/packages/dbus.mk b/depends/packages/dbus.mk
index 90ddcb923f..bbe0375409 100644
--- a/depends/packages/dbus.mk
+++ b/depends/packages/dbus.mk
@@ -1,8 +1,8 @@
package=dbus
-$(package)_version=1.10.14
-$(package)_download_path=http://dbus.freedesktop.org/releases/dbus
+$(package)_version=1.10.18
+$(package)_download_path=https://dbus.freedesktop.org/releases/dbus
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=23238f70353e38ce5ca183ebc9525c0d97ac00ef640ad29cf794782af6e6a083
+$(package)_sha256_hash=6049ddd5f3f3e2618f615f1faeda0a115104423a7996b7aa73e2f36e38cc514a
$(package)_dependencies=expat
define $(package)_set_vars
diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk
index 70f345e71d..00231d75d5 100644
--- a/depends/packages/libevent.mk
+++ b/depends/packages/libevent.mk
@@ -1,8 +1,8 @@
package=libevent
-$(package)_version=2.1.7
+$(package)_version=2.1.8-stable
$(package)_download_path=https://github.com/libevent/libevent/archive/
-$(package)_file_name=release-$($(package)_version)-rc.tar.gz
-$(package)_sha256_hash=548362d202e22fe24d4c3fad38287b4f6d683e6c21503341373b89785fa6f991
+$(package)_file_name=release-$($(package)_version).tar.gz
+$(package)_sha256_hash=316ddb401745ac5d222d7c529ef1eada12f58f6376a66c1118eee803cb70f83d
define $(package)_preprocess_cmds
./autogen.sh
diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk
index 4ed61a49e9..966804ce8b 100644
--- a/depends/packages/native_ccache.mk
+++ b/depends/packages/native_ccache.mk
@@ -1,8 +1,8 @@
package=native_ccache
-$(package)_version=3.3.3
+$(package)_version=3.3.4
$(package)_download_path=https://samba.org/ftp/ccache
$(package)_file_name=ccache-$($(package)_version).tar.bz2
-$(package)_sha256_hash=2985bc5e32ebe38d2958d508eb54ddcad39eed909489c0c2988035214597ca54
+$(package)_sha256_hash=fa9d7f38367431bc86b19ad107d709ca7ecf1574fdacca01698bdf0a47cd8567
define $(package)_set_vars
$(package)_config_opts=
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index fd75ada79f..cf860a1bf2 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -343,10 +343,9 @@ Strings and formatting
Variable names
--------------
-The shadowing warning (`-Wshadow`) is enabled by default. It prevents issues rising
-from using a different variable with the same name.
-
-Please name variables so that their names do not shadow variables defined in the source code.
+Although the shadowing warning (`-Wshadow`) is not enabled by default (it prevents issues rising
+from using a different variable with the same name),
+please name variables so that their names do not shadow variables defined in the source code.
E.g. in member initializers, prepend `_` to the argument name shadowing the
member name:
diff --git a/src/Makefile.am b/src/Makefile.am
index c4f933dae1..14d55a944f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -116,6 +116,7 @@ BITCOIN_CORE_H = \
netbase.h \
netmessagemaker.h \
noui.h \
+ policy/feerate.h \
policy/fees.h \
policy/policy.h \
policy/rbf.h \
@@ -301,7 +302,6 @@ libbitcoin_consensus_a_SOURCES = \
libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_common_a_SOURCES = \
- amount.cpp \
base58.cpp \
chainparams.cpp \
coins.cpp \
@@ -312,6 +312,7 @@ libbitcoin_common_a_SOURCES = \
keystore.cpp \
netaddress.cpp \
netbase.cpp \
+ policy/feerate.cpp \
protocol.cpp \
scheduler.cpp \
script/sign.cpp \
diff --git a/src/amount.h b/src/amount.h
index 93060f7193..2bd367cba2 100644
--- a/src/amount.h
+++ b/src/amount.h
@@ -6,10 +6,7 @@
#ifndef BITCOIN_AMOUNT_H
#define BITCOIN_AMOUNT_H
-#include "serialize.h"
-
-#include <stdlib.h>
-#include <string>
+#include <stdint.h>
/** Amount in satoshis (Can be negative) */
typedef int64_t CAmount;
@@ -17,8 +14,6 @@ typedef int64_t CAmount;
static const CAmount COIN = 100000000;
static const CAmount CENT = 1000000;
-extern const std::string CURRENCY_UNIT;
-
/** No amount larger than this (in satoshi) is valid.
*
* Note that this constant is *not* the total money supply, which in Bitcoin
@@ -31,42 +26,4 @@ extern const std::string CURRENCY_UNIT;
static const CAmount MAX_MONEY = 21000000 * COIN;
inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
-/**
- * Fee rate in satoshis per kilobyte: CAmount / kB
- */
-class CFeeRate
-{
-private:
- CAmount nSatoshisPerK; // unit is satoshis-per-1,000-bytes
-public:
- /** Fee rate of 0 satoshis per kB */
- CFeeRate() : nSatoshisPerK(0) { }
- explicit CFeeRate(const CAmount& _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { }
- /** Constructor for a fee rate in satoshis per kB. The size in bytes must not exceed (2^63 - 1)*/
- CFeeRate(const CAmount& nFeePaid, size_t nBytes);
- CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; }
- /**
- * Return the fee in satoshis for the given size in bytes.
- */
- CAmount GetFee(size_t nBytes) const;
- /**
- * Return the fee in satoshis for a size of 1000 bytes
- */
- CAmount GetFeePerK() const { return GetFee(1000); }
- friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; }
- friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; }
- friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; }
- friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; }
- friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; }
- CFeeRate& operator+=(const CFeeRate& a) { nSatoshisPerK += a.nSatoshisPerK; return *this; }
- std::string ToString() const;
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action) {
- READWRITE(nSatoshisPerK);
- }
-};
-
#endif // BITCOIN_AMOUNT_H
diff --git a/src/bench/checkblock.cpp b/src/bench/checkblock.cpp
index c6c932454a..195388839e 100644
--- a/src/bench/checkblock.cpp
+++ b/src/bench/checkblock.cpp
@@ -40,7 +40,7 @@ static void DeserializeAndCheckBlockTest(benchmark::State& state)
char a = '\0';
stream.write(&a, 1); // Prevent compaction
- Consensus::Params params = Params(CBaseChainParams::MAIN).GetConsensus();
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
while (state.KeepRunning()) {
CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here
@@ -48,7 +48,7 @@ static void DeserializeAndCheckBlockTest(benchmark::State& state)
assert(stream.Rewind(sizeof(block_bench::block413567)));
CValidationState validationState;
- assert(CheckBlock(block, validationState, params));
+ assert(CheckBlock(block, validationState, chainParams->GetConsensus()));
}
}
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 5edd43d41e..885b787b4d 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -30,6 +30,8 @@ static const int CONTINUE_EXECUTION=-1;
std::string HelpMessageCli()
{
+ const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
+ const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
std::string strUsage;
strUsage += HelpMessageGroup(_("Options:"));
strUsage += HelpMessageOpt("-?", _("This help message"));
@@ -38,7 +40,7 @@ std::string HelpMessageCli()
AppendParamsHelpMessages(strUsage);
strUsage += HelpMessageOpt("-named", strprintf(_("Pass named instead of positional arguments (default: %s)"), DEFAULT_NAMED));
strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), DEFAULT_RPCCONNECT));
- strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), BaseParams(CBaseChainParams::MAIN).RPCPort(), BaseParams(CBaseChainParams::TESTNET).RPCPort()));
+ strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()));
strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 1dc29826af..5055fb3e0a 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -55,6 +55,12 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
+void CChainParams::UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
+{
+ consensus.vDeployments[d].nStartTime = nStartTime;
+ consensus.vDeployments[d].nTimeout = nTimeout;
+}
+
/**
* Main network
*/
@@ -165,7 +171,6 @@ public:
};
}
};
-static CMainParams mainParams;
/**
* Testnet (v3)
@@ -253,7 +258,6 @@ public:
}
};
-static CTestNetParams testNetParams;
/**
* Regression test
@@ -326,42 +330,34 @@ public:
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();
}
-
- void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
- {
- consensus.vDeployments[d].nStartTime = nStartTime;
- consensus.vDeployments[d].nTimeout = nTimeout;
- }
};
-static CRegTestParams regTestParams;
-static CChainParams *pCurrentParams = 0;
+static std::unique_ptr<CChainParams> globalChainParams;
const CChainParams &Params() {
- assert(pCurrentParams);
- return *pCurrentParams;
+ assert(globalChainParams);
+ return *globalChainParams;
}
-CChainParams& Params(const std::string& chain)
+std::unique_ptr<CChainParams> CreateChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN)
- return mainParams;
+ return std::unique_ptr<CChainParams>(new CMainParams());
else if (chain == CBaseChainParams::TESTNET)
- return testNetParams;
+ return std::unique_ptr<CChainParams>(new CTestNetParams());
else if (chain == CBaseChainParams::REGTEST)
- return regTestParams;
- else
- throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
+ return std::unique_ptr<CChainParams>(new CRegTestParams());
+ throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}
void SelectParams(const std::string& network)
{
SelectBaseParams(network);
- pCurrentParams = &Params(network);
+ globalChainParams = CreateChainParams(network);
}
-void UpdateRegtestBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
+void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
{
- regTestParams.UpdateBIP9Parameters(d, nStartTime, nTimeout);
+ globalChainParams->UpdateBIP9Parameters(d, nStartTime, nTimeout);
}
diff --git a/src/chainparams.h b/src/chainparams.h
index 4fe88c691c..e5312d1080 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -11,6 +11,7 @@
#include "primitives/block.h"
#include "protocol.h"
+#include <memory>
#include <vector>
struct CDNSSeedData {
@@ -75,6 +76,7 @@ public:
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
const CCheckpointData& Checkpoints() const { return checkpointData; }
const ChainTxData& TxData() const { return chainTxData; }
+ void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout);
protected:
CChainParams() {}
@@ -95,15 +97,17 @@ protected:
};
/**
- * Return the currently selected parameters. This won't change after app
- * startup, except for unit tests.
+ * Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.
+ * @returns a CChainParams* of the chosen chain.
+ * @throws a std::runtime_error if the chain is not supported.
*/
-const CChainParams &Params();
+std::unique_ptr<CChainParams> CreateChainParams(const std::string& chain);
/**
- * @returns CChainParams for the given BIP70 chain name.
+ * Return the currently selected parameters. This won't change after app
+ * startup, except for unit tests.
*/
-CChainParams& Params(const std::string& chain);
+const CChainParams &Params();
/**
* Sets the params returned by Params() to those for the given BIP70 chain name.
@@ -114,6 +118,6 @@ void SelectParams(const std::string& chain);
/**
* Allows modifying the BIP9 regtest parameters.
*/
-void UpdateRegtestBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout);
+void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout);
#endif // BITCOIN_CHAINPARAMS_H
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
index d013cc1450..43c9a13c54 100644
--- a/src/chainparamsbase.cpp
+++ b/src/chainparamsbase.cpp
@@ -35,7 +35,6 @@ public:
nRPCPort = 8332;
}
};
-static CBaseMainParams mainParams;
/**
* Testnet (v3)
@@ -49,7 +48,6 @@ public:
strDataDir = "testnet3";
}
};
-static CBaseTestNetParams testNetParams;
/*
* Regression test
@@ -63,31 +61,30 @@ public:
strDataDir = "regtest";
}
};
-static CBaseRegTestParams regTestParams;
-static CBaseChainParams* pCurrentBaseParams = 0;
+static std::unique_ptr<CBaseChainParams> globalChainBaseParams;
const CBaseChainParams& BaseParams()
{
- assert(pCurrentBaseParams);
- return *pCurrentBaseParams;
+ assert(globalChainBaseParams);
+ return *globalChainBaseParams;
}
-CBaseChainParams& BaseParams(const std::string& chain)
+std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN)
- return mainParams;
+ return std::unique_ptr<CBaseChainParams>(new CBaseMainParams());
else if (chain == CBaseChainParams::TESTNET)
- return testNetParams;
+ return std::unique_ptr<CBaseChainParams>(new CBaseTestNetParams());
else if (chain == CBaseChainParams::REGTEST)
- return regTestParams;
+ return std::unique_ptr<CBaseChainParams>(new CBaseRegTestParams());
else
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}
void SelectBaseParams(const std::string& chain)
{
- pCurrentBaseParams = &BaseParams(chain);
+ globalChainBaseParams = CreateBaseChainParams(chain);
}
std::string ChainNameFromCommandLine()
diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h
index 84350cf65b..fc101f5b77 100644
--- a/src/chainparamsbase.h
+++ b/src/chainparamsbase.h
@@ -5,6 +5,7 @@
#ifndef BITCOIN_CHAINPARAMSBASE_H
#define BITCOIN_CHAINPARAMSBASE_H
+#include <memory>
#include <string>
#include <vector>
@@ -31,6 +32,13 @@ protected:
};
/**
+ * Creates and returns a std::unique_ptr<CBaseChainParams> of the chosen chain.
+ * @returns a CBaseChainParams* of the chosen chain.
+ * @throws a std::runtime_error if the chain is not supported.
+ */
+std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain);
+
+/**
* Append the help messages for the chainparams options to the
* parameter string.
*/
@@ -42,8 +50,6 @@ void AppendParamsHelpMessages(std::string& strUsage, bool debugHelp=true);
*/
const CBaseChainParams& BaseParams();
-CBaseChainParams& BaseParams(const std::string& chain);
-
/** Sets the params returned by Params() to those for the given network. */
void SelectBaseParams(const std::string& chain);
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
index 21c64c5c83..18a9819edd 100644
--- a/src/httprpc.cpp
+++ b/src/httprpc.cpp
@@ -93,9 +93,9 @@ static bool multiUserAuthorized(std::string strUserPass)
std::string strUser = strUserPass.substr(0, strUserPass.find(":"));
std::string strPass = strUserPass.substr(strUserPass.find(":") + 1);
- if (mapMultiArgs.count("-rpcauth") > 0) {
+ if (gArgs.IsArgSet("-rpcauth")) {
//Search for multi-user login/pass "rpcauth" from config
- BOOST_FOREACH(std::string strRPCAuth, mapMultiArgs.at("-rpcauth"))
+ BOOST_FOREACH(std::string strRPCAuth, gArgs.GetArgs("-rpcauth"))
{
std::vector<std::string> vFields;
boost::split(vFields, strRPCAuth, boost::is_any_of(":$"));
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index e7df23295d..0d1cba3fd2 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -196,9 +196,8 @@ static bool InitHTTPAllowList()
LookupHost("::1", localv6, false);
rpc_allow_subnets.push_back(CSubNet(localv4, 8)); // always allow IPv4 local subnet
rpc_allow_subnets.push_back(CSubNet(localv6)); // always allow IPv6 localhost
- if (mapMultiArgs.count("-rpcallowip")) {
- const std::vector<std::string>& vAllow = mapMultiArgs.at("-rpcallowip");
- for (std::string strAllow : vAllow) {
+ if (gArgs.IsArgSet("-rpcallowip")) {
+ for (const std::string& strAllow : gArgs.GetArgs("-rpcallowip")) {
CSubNet subnet;
LookupSubNet(strAllow.c_str(), subnet);
if (!subnet.IsValid()) {
@@ -321,12 +320,11 @@ static bool HTTPBindAddresses(struct evhttp* http)
if (IsArgSet("-rpcbind")) {
LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n");
}
- } else if (mapMultiArgs.count("-rpcbind")) { // Specific bind address
- const std::vector<std::string>& vbind = mapMultiArgs.at("-rpcbind");
- for (std::vector<std::string>::const_iterator i = vbind.begin(); i != vbind.end(); ++i) {
+ } else if (gArgs.IsArgSet("-rpcbind")) { // Specific bind address
+ for (const std::string& strRPCBind : gArgs.GetArgs("-rpcbind")) {
int port = defaultPort;
std::string host;
- SplitHostPort(*i, port, host);
+ SplitHostPort(strRPCBind, port, host);
endpoints.push_back(std::make_pair(host, port));
}
} else { // No specific bind address specified, bind to any
diff --git a/src/init.cpp b/src/init.cpp
index 266e1731eb..93b4c80c01 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -25,6 +25,7 @@
#include "netbase.h"
#include "net.h"
#include "net_processing.h"
+#include "policy/feerate.h"
#include "policy/fees.h"
#include "policy/policy.h"
#include "rpc/server.h"
@@ -328,6 +329,10 @@ void OnRPCPreCommand(const CRPCCommand& cmd)
std::string HelpMessage(HelpMessageMode mode)
{
+ const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
+ const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
+ const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN);
+ const auto testnetChainParams = CreateChainParams(CBaseChainParams::TESTNET);
const bool showDebug = GetBoolArg("-help-debug", false);
// When adding new options to the categories, please keep and ensure alphabetical ordering.
@@ -339,7 +344,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)"));
if (showDebug)
strUsage += HelpMessageOpt("-blocksonly", strprintf(_("Whether to operate in a blocks only mode (default: %u)"), DEFAULT_BLOCKSONLY));
- strUsage +=HelpMessageOpt("-assumevalid=<hex>", strprintf(_("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: %s, testnet: %s)"), Params(CBaseChainParams::MAIN).GetConsensus().defaultAssumeValid.GetHex(), Params(CBaseChainParams::TESTNET).GetConsensus().defaultAssumeValid.GetHex()));
+ strUsage +=HelpMessageOpt("-assumevalid=<hex>", strprintf(_("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: %s, testnet: %s)"), defaultChainParams->GetConsensus().defaultAssumeValid.GetHex(), testnetChainParams->GetConsensus().defaultAssumeValid.GetHex()));
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME));
if (mode == HMM_BITCOIND)
{
@@ -393,7 +398,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)"));
strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG));
strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), DEFAULT_PEERBLOOMFILTERS));
- strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort()));
+ strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort()));
strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy"));
strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE));
strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect"));
@@ -430,8 +435,8 @@ std::string HelpMessage(HelpMessageMode mode)
{
strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), DEFAULT_CHECKBLOCKS));
strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), DEFAULT_CHECKLEVEL));
- strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks()));
- strUsage += HelpMessageOpt("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks()));
+ strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", defaultChainParams->DefaultConsistencyChecks()));
+ strUsage += HelpMessageOpt("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u)", defaultChainParams->DefaultConsistencyChecks()));
strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED));
strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", DEFAULT_DISABLE_SAFEMODE));
strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", DEFAULT_TESTSAFEMODE));
@@ -472,7 +477,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageGroup(_("Node relay options:"));
if (showDebug) {
- strUsage += HelpMessageOpt("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", !Params(CBaseChainParams::TESTNET).RequireStandard()));
+ strUsage += HelpMessageOpt("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", defaultChainParams->RequireStandard()));
strUsage += HelpMessageOpt("-incrementalrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to define cost of relay, used for mempool limiting and BIP 125 replacement. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_INCREMENTAL_RELAY_FEE)));
strUsage += HelpMessageOpt("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to defined dust, the value of an output such that it will cost about 1/3 of its value in fees at this fee rate to spend it. (default: %s)", CURRENCY_UNIT, FormatMoney(DUST_RELAY_TX_FEE)));
}
@@ -500,7 +505,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcauth=<userpw>", _("Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. The client then connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This option can be specified multiple times"));
- strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), BaseParams(CBaseChainParams::MAIN).RPCPort(), BaseParams(CBaseChainParams::TESTNET).RPCPort()));
+ strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()));
strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"));
strUsage += HelpMessageOpt("-rpcserialversion", strprintf(_("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)"), DEFAULT_RPC_SERIALIZE_VERSION));
strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS));
@@ -741,7 +746,7 @@ void InitParameterInteraction()
LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__);
}
- if (mapMultiArgs.count("-connect") && mapMultiArgs.at("-connect").size() > 0) {
+ if (gArgs.IsArgSet("-connect")) {
// when only connecting to trusted nodes, do not seed via DNS, or listen by default
if (SoftSetBoolArg("-dnsseed", false))
LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__);
@@ -895,8 +900,8 @@ bool AppInitParameterInteraction()
// Make sure enough file descriptors are available
int nBind = std::max(
- (mapMultiArgs.count("-bind") ? mapMultiArgs.at("-bind").size() : 0) +
- (mapMultiArgs.count("-whitebind") ? mapMultiArgs.at("-whitebind").size() : 0), size_t(1));
+ (gArgs.IsArgSet("-bind") ? gArgs.GetArgs("-bind").size() : 0) +
+ (gArgs.IsArgSet("-whitebind") ? gArgs.GetArgs("-whitebind").size() : 0), size_t(1));
nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
nMaxConnections = std::max(nUserMaxConnections, 0);
@@ -911,9 +916,9 @@ bool AppInitParameterInteraction()
InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections));
// ********************************************************* Step 3: parameter-to-internal-flags
- if (mapMultiArgs.count("-debug") > 0) {
+ if (gArgs.IsArgSet("-debug")) {
// Special-case: if -debug=0/-nodebug is set, turn off debugging messages
- const std::vector<std::string>& categories = mapMultiArgs.at("-debug");
+ const std::vector<std::string> categories = gArgs.GetArgs("-debug");
if (find(categories.begin(), categories.end(), std::string("0")) == categories.end()) {
for (const auto& cat : categories) {
@@ -928,9 +933,8 @@ bool AppInitParameterInteraction()
}
// Now remove the logging categories which were explicitly excluded
- if (mapMultiArgs.count("-debugexclude") > 0) {
- const std::vector<std::string>& excludedCategories = mapMultiArgs.at("-debugexclude");
- for (const auto& cat : excludedCategories) {
+ if (gArgs.IsArgSet("-debugexclude")) {
+ for (const std::string& cat : gArgs.GetArgs("-debugexclude")) {
uint32_t flag = 0;
if (!GetLogCategory(&flag, &cat)) {
InitWarning(strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat));
@@ -1100,15 +1104,14 @@ bool AppInitParameterInteraction()
fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end());
}
- if (mapMultiArgs.count("-bip9params")) {
+ if (gArgs.IsArgSet("-bip9params")) {
// Allow overriding BIP9 parameters for testing
if (!chainparams.MineBlocksOnDemand()) {
return InitError("BIP9 parameters may only be overridden on regtest.");
}
- const std::vector<std::string>& deployments = mapMultiArgs.at("-bip9params");
- for (auto i : deployments) {
+ for (const std::string& strDeployment : gArgs.GetArgs("-bip9params")) {
std::vector<std::string> vDeploymentParams;
- boost::split(vDeploymentParams, i, boost::is_any_of(":"));
+ boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
if (vDeploymentParams.size() != 3) {
return InitError("BIP9 parameters malformed, expecting deployment:start:end");
}
@@ -1123,7 +1126,7 @@ bool AppInitParameterInteraction()
for (int j=0; j<(int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j)
{
if (vDeploymentParams[0].compare(VersionBitsDeploymentInfo[j].name) == 0) {
- UpdateRegtestBIP9Parameters(Consensus::DeploymentPos(j), nStartTime, nTimeout);
+ UpdateBIP9Parameters(Consensus::DeploymentPos(j), nStartTime, nTimeout);
found = true;
LogPrintf("Setting BIP9 activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout);
break;
@@ -1254,8 +1257,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
// sanitize comments per BIP-0014, format user agent and check total size
std::vector<std::string> uacomments;
- if (mapMultiArgs.count("-uacomment")) {
- BOOST_FOREACH(std::string cmt, mapMultiArgs.at("-uacomment"))
+ if (gArgs.IsArgSet("-uacomment")) {
+ BOOST_FOREACH(std::string cmt, gArgs.GetArgs("-uacomment"))
{
if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT))
return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt));
@@ -1268,9 +1271,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
strSubVersion.size(), MAX_SUBVERSION_LENGTH));
}
- if (mapMultiArgs.count("-onlynet")) {
+ if (gArgs.IsArgSet("-onlynet")) {
std::set<enum Network> nets;
- BOOST_FOREACH(const std::string& snet, mapMultiArgs.at("-onlynet")) {
+ BOOST_FOREACH(const std::string& snet, gArgs.GetArgs("-onlynet")) {
enum Network net = ParseNetwork(snet);
if (net == NET_UNROUTABLE)
return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet));
@@ -1283,8 +1286,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
}
}
- if (mapMultiArgs.count("-whitelist")) {
- BOOST_FOREACH(const std::string& net, mapMultiArgs.at("-whitelist")) {
+ if (gArgs.IsArgSet("-whitelist")) {
+ BOOST_FOREACH(const std::string& net, gArgs.GetArgs("-whitelist")) {
CSubNet subnet;
LookupSubNet(net.c_str(), subnet);
if (!subnet.IsValid())
@@ -1345,16 +1348,16 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
if (fListen) {
bool fBound = false;
- if (mapMultiArgs.count("-bind")) {
- BOOST_FOREACH(const std::string& strBind, mapMultiArgs.at("-bind")) {
+ if (gArgs.IsArgSet("-bind")) {
+ BOOST_FOREACH(const std::string& strBind, gArgs.GetArgs("-bind")) {
CService addrBind;
if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
return InitError(ResolveErrMsg("bind", strBind));
fBound |= Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
}
}
- if (mapMultiArgs.count("-whitebind")) {
- BOOST_FOREACH(const std::string& strBind, mapMultiArgs.at("-whitebind")) {
+ if (gArgs.IsArgSet("-whitebind")) {
+ BOOST_FOREACH(const std::string& strBind, gArgs.GetArgs("-whitebind")) {
CService addrBind;
if (!Lookup(strBind.c_str(), addrBind, 0, false))
return InitError(ResolveErrMsg("whitebind", strBind));
@@ -1363,7 +1366,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
fBound |= Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST));
}
}
- if (!mapMultiArgs.count("-bind") && !mapMultiArgs.count("-whitebind")) {
+ if (!gArgs.IsArgSet("-bind") && !gArgs.IsArgSet("-whitebind")) {
struct in_addr inaddr_any;
inaddr_any.s_addr = INADDR_ANY;
fBound |= Bind(connman, CService(in6addr_any, GetListenPort()), BF_NONE);
@@ -1373,8 +1376,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
return InitError(_("Failed to listen on any port. Use -listen=0 if you want this."));
}
- if (mapMultiArgs.count("-externalip")) {
- BOOST_FOREACH(const std::string& strAddr, mapMultiArgs.at("-externalip")) {
+ if (gArgs.IsArgSet("-externalip")) {
+ BOOST_FOREACH(const std::string& strAddr, gArgs.GetArgs("-externalip")) {
CService addrLocal;
if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid())
AddLocal(addrLocal, LOCAL_MANUAL);
@@ -1383,8 +1386,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
}
}
- if (mapMultiArgs.count("-seednode")) {
- BOOST_FOREACH(const std::string& strDest, mapMultiArgs.at("-seednode"))
+ if (gArgs.IsArgSet("-seednode")) {
+ BOOST_FOREACH(const std::string& strDest, gArgs.GetArgs("-seednode"))
connman.AddOneShot(strDest);
}
@@ -1610,9 +1613,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
std::vector<fs::path> vImportFiles;
- if (mapMultiArgs.count("-loadblock"))
+ if (gArgs.IsArgSet("-loadblock"))
{
- BOOST_FOREACH(const std::string& strFile, mapMultiArgs.at("-loadblock"))
+ BOOST_FOREACH(const std::string& strFile, gArgs.GetArgs("-loadblock"))
vImportFiles.push_back(strFile);
}
diff --git a/src/miner.cpp b/src/miner.cpp
index 69a89bd617..9d2959723a 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -15,6 +15,7 @@
#include "hash.h"
#include "validation.h"
#include "net.h"
+#include "policy/feerate.h"
#include "policy/policy.h"
#include "pow.h"
#include "primitives/transaction.h"
diff --git a/src/net.cpp b/src/net.cpp
index 1d90804627..dd375e580f 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1670,12 +1670,12 @@ void CConnman::ProcessOneShot()
void CConnman::ThreadOpenConnections()
{
// Connect to specific addresses
- if (mapMultiArgs.count("-connect") && mapMultiArgs.at("-connect").size() > 0)
+ if (gArgs.IsArgSet("-connect") && gArgs.GetArgs("-connect").size() > 0)
{
for (int64_t nLoop = 0;; nLoop++)
{
ProcessOneShot();
- BOOST_FOREACH(const std::string& strAddr, mapMultiArgs.at("-connect"))
+ BOOST_FOREACH(const std::string& strAddr, gArgs.GetArgs("-connect"))
{
CAddress addr(CService(), NODE_NONE);
OpenNetworkConnection(addr, false, NULL, strAddr.c_str());
@@ -1877,8 +1877,8 @@ void CConnman::ThreadOpenAddedConnections()
{
{
LOCK(cs_vAddedNodes);
- if (mapMultiArgs.count("-addnode"))
- vAddedNodes = mapMultiArgs.at("-addnode");
+ if (gArgs.IsArgSet("-addnode"))
+ vAddedNodes = gArgs.GetArgs("-addnode");
}
while (true)
@@ -2289,7 +2289,7 @@ bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options c
threadOpenAddedConnections = std::thread(&TraceThread<std::function<void()> >, "addcon", std::function<void()>(std::bind(&CConnman::ThreadOpenAddedConnections, this)));
// Initiate outbound connections unless connect=0
- if (!mapMultiArgs.count("-connect") || mapMultiArgs.at("-connect").size() != 1 || mapMultiArgs.at("-connect")[0] != "0")
+ if (!gArgs.IsArgSet("-connect") || gArgs.GetArgs("-connect").size() != 1 || gArgs.GetArgs("-connect")[0] != "0")
threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(std::bind(&CConnman::ThreadOpenConnections, this)));
// Process messages
diff --git a/src/net.h b/src/net.h
index 8b0ebc0ffe..bea04bc580 100644
--- a/src/net.h
+++ b/src/net.h
@@ -14,6 +14,7 @@
#include "hash.h"
#include "limitedmap.h"
#include "netaddress.h"
+#include "policy/feerate.h"
#include "protocol.h"
#include "random.h"
#include "streams.h"
diff --git a/src/amount.cpp b/src/policy/feerate.cpp
index a5f6bc3cd9..a089c02284 100644
--- a/src/amount.cpp
+++ b/src/policy/feerate.cpp
@@ -3,7 +3,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "amount.h"
+#include "feerate.h"
#include "tinyformat.h"
diff --git a/src/policy/feerate.h b/src/policy/feerate.h
new file mode 100644
index 0000000000..e82268b095
--- /dev/null
+++ b/src/policy/feerate.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_POLICY_FEERATE_H
+#define BITCOIN_POLICY_FEERATE_H
+
+#include "amount.h"
+#include "serialize.h"
+
+#include <string>
+
+extern const std::string CURRENCY_UNIT;
+
+/**
+ * Fee rate in satoshis per kilobyte: CAmount / kB
+ */
+class CFeeRate
+{
+private:
+ CAmount nSatoshisPerK; // unit is satoshis-per-1,000-bytes
+public:
+ /** Fee rate of 0 satoshis per kB */
+ CFeeRate() : nSatoshisPerK(0) { }
+ explicit CFeeRate(const CAmount& _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { }
+ /** Constructor for a fee rate in satoshis per kB. The size in bytes must not exceed (2^63 - 1)*/
+ CFeeRate(const CAmount& nFeePaid, size_t nBytes);
+ CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; }
+ /**
+ * Return the fee in satoshis for the given size in bytes.
+ */
+ CAmount GetFee(size_t nBytes) const;
+ /**
+ * Return the fee in satoshis for a size of 1000 bytes
+ */
+ CAmount GetFeePerK() const { return GetFee(1000); }
+ friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; }
+ friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; }
+ friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; }
+ friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; }
+ friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; }
+ CFeeRate& operator+=(const CFeeRate& a) { nSatoshisPerK += a.nSatoshisPerK; return *this; }
+ std::string ToString() const;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action) {
+ READWRITE(nSatoshisPerK);
+ }
+};
+
+#endif // BITCOIN_POLICY_FEERATE_H
diff --git a/src/policy/fees.h b/src/policy/fees.h
index 34f07c7270..15876574d2 100644
--- a/src/policy/fees.h
+++ b/src/policy/fees.h
@@ -6,6 +6,7 @@
#define BITCOIN_POLICYESTIMATOR_H
#include "amount.h"
+#include "feerate.h"
#include "uint256.h"
#include "random.h"
#include "sync.h"
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
index 6f8b6c2953..2b19a6714b 100644
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -15,6 +15,43 @@
#include <boost/foreach.hpp>
+CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFee)
+{
+ // "Dust" is defined in terms of dustRelayFee,
+ // which has units satoshis-per-kilobyte.
+ // If you'd pay more than 1/3 in fees
+ // to spend something, then we consider it dust.
+ // A typical spendable non-segwit txout is 34 bytes big, and will
+ // need a CTxIn of at least 148 bytes to spend:
+ // so dust is a spendable txout less than
+ // 546*dustRelayFee/1000 (in satoshis).
+ // A typical spendable segwit txout is 31 bytes big, and will
+ // need a CTxIn of at least 67 bytes to spend:
+ // so dust is a spendable txout less than
+ // 294*dustRelayFee/1000 (in satoshis).
+ if (txout.scriptPubKey.IsUnspendable())
+ return 0;
+
+ size_t nSize = GetSerializeSize(txout, SER_DISK, 0);
+ int witnessversion = 0;
+ std::vector<unsigned char> witnessprogram;
+
+ if (txout.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
+ // sum the sizes of the parts of a transaction input
+ // with 75% segwit discount applied to the script size.
+ nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
+ } else {
+ nSize += (32 + 4 + 1 + 107 + 4); // the 148 mentioned above
+ }
+
+ return 3 * dustRelayFee.GetFee(nSize);
+}
+
+bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFee)
+{
+ return (txout.nValue < GetDustThreshold(txout, dustRelayFee));
+}
+
/**
* Check transaction inputs to mitigate two
* potential denial-of-service attacks:
@@ -106,7 +143,7 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnes
else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
reason = "bare-multisig";
return false;
- } else if (txout.IsDust(dustRelayFee)) {
+ } else if (IsDust(txout, ::dustRelayFee)) {
reason = "dust";
return false;
}
diff --git a/src/policy/policy.h b/src/policy/policy.h
index 6df541bc0f..2c2ea9d5b8 100644
--- a/src/policy/policy.h
+++ b/src/policy/policy.h
@@ -7,12 +7,14 @@
#define BITCOIN_POLICY_POLICY_H
#include "consensus/consensus.h"
+#include "feerate.h"
#include "script/interpreter.h"
#include "script/standard.h"
#include <string>
class CCoinsViewCache;
+class CTxOut;
/** Default for -blockmaxsize, which controls the maximum size of block the mining code will create **/
static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000;
@@ -72,6 +74,10 @@ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_
static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUENCE |
LOCKTIME_MEDIAN_TIME_PAST;
+CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFee);
+
+bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFee);
+
bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType, const bool witnessEnabled = false);
/**
* Check for standard transaction types
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index 5059030309..00ac0b92b5 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -161,43 +161,6 @@ public:
return (nValue == -1);
}
- CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const
- {
- // "Dust" is defined in terms of CTransaction::minRelayTxFee,
- // which has units satoshis-per-kilobyte.
- // If you'd pay more than 1/3 in fees
- // to spend something, then we consider it dust.
- // A typical spendable non-segwit txout is 34 bytes big, and will
- // need a CTxIn of at least 148 bytes to spend:
- // so dust is a spendable txout less than
- // 546*minRelayTxFee/1000 (in satoshis).
- // A typical spendable segwit txout is 31 bytes big, and will
- // need a CTxIn of at least 67 bytes to spend:
- // so dust is a spendable txout less than
- // 294*minRelayTxFee/1000 (in satoshis).
- if (scriptPubKey.IsUnspendable())
- return 0;
-
- size_t nSize = GetSerializeSize(*this, SER_DISK, 0);
- int witnessversion = 0;
- std::vector<unsigned char> witnessprogram;
-
- if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
- // sum the sizes of the parts of a transaction input
- // with 75% segwit discount applied to the script size.
- nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
- } else {
- nSize += (32 + 4 + 1 + 107 + 4); // the 148 mentioned above
- }
-
- return 3 * minRelayTxFee.GetFee(nSize);
- }
-
- bool IsDust(const CFeeRate &minRelayTxFee) const
- {
- return (nValue < GetDustThreshold(minRelayTxFee));
- }
-
friend bool operator==(const CTxOut& a, const CTxOut& b)
{
return (a.nValue == b.nValue &&
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 38ad6e9aab..2a331d4fae 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -434,8 +434,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
{
CTxOut txout(amount, (CScript)std::vector<unsigned char>(24, 0));
txDummy.vout.push_back(txout);
- if (txout.IsDust(dustRelayFee))
- fDust = true;
+ fDust |= IsDust(txout, ::dustRelayFee);
}
}
@@ -527,10 +526,10 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
if (nChange > 0 && nChange < MIN_CHANGE)
{
CTxOut txout(nChange, (CScript)std::vector<unsigned char>(24, 0));
- if (txout.IsDust(dustRelayFee))
+ if (IsDust(txout, ::dustRelayFee))
{
if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust
- nChange = txout.GetDustThreshold(dustRelayFee);
+ nChange = GetDustThreshold(txout, ::dustRelayFee);
else
{
nPayFee += nChange;
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 3f3f9b9ccb..bffa81137b 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -251,7 +251,7 @@ bool isDust(const QString& address, const CAmount& amount)
CTxDestination dest = CBitcoinAddress(address.toStdString()).Get();
CScript script = GetScriptForDestination(dest);
CTxOut txOut(amount, script);
- return txOut.IsDust(dustRelayFee);
+ return IsDust(txOut, ::dustRelayFee);
}
QString HtmlEscape(const QString& str, bool fMultiLine)
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index dd75f12076..c31a7a478d 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -219,14 +219,16 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[])
if (GUIUtil::parseBitcoinURI(arg, &r) && !r.address.isEmpty())
{
CBitcoinAddress address(r.address.toStdString());
+ auto tempChainParams = CreateChainParams(CBaseChainParams::MAIN);
- if (address.IsValid(Params(CBaseChainParams::MAIN)))
+ if (address.IsValid(*tempChainParams))
{
SelectParams(CBaseChainParams::MAIN);
}
- else if (address.IsValid(Params(CBaseChainParams::TESTNET)))
- {
- SelectParams(CBaseChainParams::TESTNET);
+ else {
+ tempChainParams = CreateChainParams(CBaseChainParams::TESTNET);
+ if (address.IsValid(*tempChainParams))
+ SelectParams(CBaseChainParams::TESTNET);
}
}
}
@@ -580,7 +582,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen
// Extract and check amounts
CTxOut txOut(sendingTo.second, sendingTo.first);
- if (txOut.IsDust(dustRelayFee)) {
+ if (IsDust(txOut, ::dustRelayFee)) {
Q_EMIT message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).")
.arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)),
CClientUIInterface::MSG_ERROR);
diff --git a/src/random.cpp b/src/random.cpp
index 6187f16290..3b9df3edaa 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -16,6 +16,8 @@
#include <stdlib.h>
#include <limits>
+#include <chrono>
+#include <thread>
#ifndef WIN32
#include <sys/time.h>
@@ -32,6 +34,8 @@
#include <sys/sysctl.h>
#endif
+#include <mutex>
+
#include <openssl/err.h>
#include <openssl/rand.h>
@@ -43,15 +47,22 @@ static void RandFailure()
static inline int64_t GetPerformanceCounter()
{
- int64_t nCounter = 0;
-#ifdef WIN32
- QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
+ // Read the hardware time stamp counter when available.
+ // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
+#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+ return __rdtsc();
+#elif !defined(_MSC_VER) && defined(__i386__)
+ uint64_t r = 0;
+ __asm__ volatile ("rdtsc" : "=A"(r)); // Constrain the r variable to the eax:edx pair.
+ return r;
+#elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
+ uint64_t r1 = 0, r2 = 0;
+ __asm__ volatile ("rdtsc" : "=a"(r1), "=d"(r2)); // Constrain r1 to rax and r2 to rdx.
+ return (r2 << 32) | r1;
#else
- timeval t;
- gettimeofday(&t, NULL);
- nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
+ // Fall back to using C++11 clock (usually microsecond or nanosecond precision)
+ return std::chrono::high_resolution_clock::now().time_since_epoch().count();
#endif
- return nCounter;
}
void RandAddSeed()
@@ -192,6 +203,10 @@ void GetRandBytes(unsigned char* buf, int num)
}
}
+static std::mutex cs_rng_state;
+static unsigned char rng_state[32] = {0};
+static uint64_t rng_counter = 0;
+
void GetStrongRandBytes(unsigned char* out, int num)
{
assert(num <= 32);
@@ -207,8 +222,17 @@ void GetStrongRandBytes(unsigned char* out, int num)
GetOSRand(buf);
hasher.Write(buf, 32);
+ // Combine with and update state
+ {
+ std::unique_lock<std::mutex> lock(cs_rng_state);
+ hasher.Write(rng_state, sizeof(rng_state));
+ hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter));
+ ++rng_counter;
+ hasher.Finalize(buf);
+ memcpy(rng_state, buf + 32, 32);
+ }
+
// Produce output
- hasher.Finalize(buf);
memcpy(out, buf, num);
memory_cleanse(buf, 64);
}
@@ -254,6 +278,8 @@ FastRandomContext::FastRandomContext(const uint256& seed) : requires_seed(false)
bool Random_SanityCheck()
{
+ uint64_t start = GetPerformanceCounter();
+
/* This does not measure the quality of randomness, but it does test that
* OSRandom() overwrites all 32 bytes of the output given a maximum
* number of tries.
@@ -280,7 +306,18 @@ bool Random_SanityCheck()
tries += 1;
} while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
- return (num_overwritten == NUM_OS_RANDOM_BYTES); /* If this failed, bailed out after too many tries */
+ if (num_overwritten != NUM_OS_RANDOM_BYTES) return false; /* If this failed, bailed out after too many tries */
+
+ // Check that GetPerformanceCounter increases at least during a GetOSRand() call + 1ms sleep.
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ uint64_t stop = GetPerformanceCounter();
+ if (stop == start) return false;
+
+ // We called GetPerformanceCounter. Use it as entropy.
+ RAND_add((const unsigned char*)&start, sizeof(start), 1);
+ RAND_add((const unsigned char*)&stop, sizeof(stop), 1);
+
+ return true;
}
FastRandomContext::FastRandomContext(bool fDeterministic) : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0)
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 8599795d21..9d72a23e6d 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -13,6 +13,7 @@
#include "consensus/validation.h"
#include "validation.h"
#include "core_io.h"
+#include "policy/feerate.h"
#include "policy/policy.h"
#include "primitives/transaction.h"
#include "rpc/server.h"
@@ -687,13 +688,16 @@ UniValue getblock(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw std::runtime_error(
- "getblock \"blockhash\" ( verbose )\n"
- "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
- "If verbose is true, returns an Object with information about block <hash>.\n"
+ "getblock \"blockhash\" ( verbosity ) \n"
+ "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
+ "If verbosity is 1, returns an Object with information about block <hash>.\n"
+ "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n"
"\nArguments:\n"
"1. \"blockhash\" (string, required) The block hash\n"
- "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
- "\nResult (for verbose = true):\n"
+ "2. verbosity (numeric, optional, default=1) 0 for hex encoded data, 1 for a json object, and 2 for json object with transaction data\n"
+ "\nResult (for verbosity = 0):\n"
+ "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
+ "\nResult (for verbosity = 1):\n"
"{\n"
" \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
" \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
@@ -717,8 +721,14 @@ UniValue getblock(const JSONRPCRequest& request)
" \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
" \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
"}\n"
- "\nResult (for verbose=false):\n"
- "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
+ "\nResult (for verbosity = 2):\n"
+ "{\n"
+ " ..., Same output as verbosity = 1.\n"
+ " \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n"
+ " ,...\n"
+ " ],\n"
+ " ,... Same output as verbosity = 1.\n"
+ "}\n"
"\nExamples:\n"
+ HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
@@ -729,9 +739,13 @@ UniValue getblock(const JSONRPCRequest& request)
std::string strHash = request.params[0].get_str();
uint256 hash(uint256S(strHash));
- bool fVerbose = true;
- if (request.params.size() > 1)
- fVerbose = request.params[1].get_bool();
+ int verbosity = 1;
+ if (request.params.size() > 1) {
+ if(request.params[1].isNum())
+ verbosity = request.params[1].get_int();
+ else
+ verbosity = request.params[1].get_bool() ? 1 : 0;
+ }
if (mapBlockIndex.count(hash) == 0)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
@@ -750,7 +764,7 @@ UniValue getblock(const JSONRPCRequest& request)
// block).
throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
- if (!fVerbose)
+ if (verbosity <= 0)
{
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
ssBlock << block;
@@ -758,7 +772,7 @@ UniValue getblock(const JSONRPCRequest& request)
return strHex;
}
- return blockToJSON(block, pblockindex);
+ return blockToJSON(block, pblockindex, verbosity >= 2);
}
struct CCoinsStats
@@ -1488,7 +1502,7 @@ static const CRPCCommand commands[] =
{ "blockchain", "getchaintxstats", &getchaintxstats, true, {"nblocks", "blockhash"} },
{ "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
{ "blockchain", "getblockcount", &getblockcount, true, {} },
- { "blockchain", "getblock", &getblock, true, {"blockhash","verbose"} },
+ { "blockchain", "getblock", &getblock, true, {"blockhash","verbosity|verbose"} },
{ "blockchain", "getblockhash", &getblockhash, true, {"height"} },
{ "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} },
{ "blockchain", "getchaintips", &getchaintips, true, {} },
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 8454e99d3c..dc916a1fdb 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -77,7 +77,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listunspent", 0, "minconf" },
{ "listunspent", 1, "maxconf" },
{ "listunspent", 2, "addresses" },
- { "getblock", 1, "verbose" },
+ { "getblock", 1, "verbosity" },
{ "getblockheader", 1, "verbose" },
{ "getchaintxstats", 0, "nblocks" },
{ "gettransaction", 1, "include_watchonly" },
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index 5c493428d8..ea93e8cc74 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -22,6 +22,8 @@
#include <boost/signals2/signal.hpp>
#include <boost/thread.hpp>
#include <boost/algorithm/string/case_conv.hpp> // for to_upper()
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
#include <memory> // for unique_ptr
#include <unordered_map>
@@ -432,8 +434,16 @@ static inline JSONRPCRequest transformNamedArguments(const JSONRPCRequest& in, c
}
// Process expected parameters.
int hole = 0;
- for (const std::string &argName: argNames) {
- auto fr = argsIn.find(argName);
+ for (const std::string &argNamePattern: argNames) {
+ std::vector<std::string> vargNames;
+ boost::algorithm::split(vargNames, argNamePattern, boost::algorithm::is_any_of("|"));
+ auto fr = argsIn.end();
+ for (const std::string & argName : vargNames) {
+ fr = argsIn.find(argName);
+ if (fr != argsIn.end()) {
+ break;
+ }
+ }
if (fr != argsIn.end()) {
for (int i = 0; i < hole; ++i) {
// Fill hole between specified parameters with JSON nulls,
diff --git a/src/support/cleanse.h b/src/support/cleanse.h
index 3e02aa8fd1..f020216c73 100644
--- a/src/support/cleanse.h
+++ b/src/support/cleanse.h
@@ -8,6 +8,7 @@
#include <stdlib.h>
+// Attempt to overwrite data in the specified memory span.
void memory_cleanse(void *ptr, size_t len);
#endif // BITCOIN_SUPPORT_CLEANSE_H
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
index 39fa381dd0..3812490ec0 100644
--- a/src/test/addrman_tests.cpp
+++ b/src/test/addrman_tests.cpp
@@ -84,36 +84,43 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
CNetAddr source = ResolveIP("252.2.2.2");
- // Test 1: Does Addrman respond correctly when empty.
- BOOST_CHECK(addrman.size() == 0);
+ // Test: Does Addrman respond correctly when empty.
+ BOOST_CHECK_EQUAL(addrman.size(), 0);
CAddrInfo addr_null = addrman.Select();
- BOOST_CHECK(addr_null.ToString() == "[::]:0");
+ BOOST_CHECK_EQUAL(addr_null.ToString(), "[::]:0");
- // Test 2: Does Addrman::Add work as expected.
+ // Test: Does Addrman::Add work as expected.
CService addr1 = ResolveService("250.1.1.1", 8333);
- addrman.Add(CAddress(addr1, NODE_NONE), source);
- BOOST_CHECK(addrman.size() == 1);
+ BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
+ BOOST_CHECK_EQUAL(addrman.size(), 1);
CAddrInfo addr_ret1 = addrman.Select();
- BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333");
+ BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333");
- // Test 3: Does IP address deduplication work correctly.
+ // Test: Does IP address deduplication work correctly.
// Expected dup IP should not be added.
CService addr1_dup = ResolveService("250.1.1.1", 8333);
- addrman.Add(CAddress(addr1_dup, NODE_NONE), source);
- BOOST_CHECK(addrman.size() == 1);
+ BOOST_CHECK(!addrman.Add(CAddress(addr1_dup, NODE_NONE), source));
+ BOOST_CHECK_EQUAL(addrman.size(), 1);
- // Test 5: New table has one addr and we add a diff addr we should
+ // Test: New table has one addr and we add a diff addr we should
// have two addrs.
CService addr2 = ResolveService("250.1.1.2", 8333);
- addrman.Add(CAddress(addr2, NODE_NONE), source);
- BOOST_CHECK(addrman.size() == 2);
+ BOOST_CHECK(addrman.Add(CAddress(addr2, NODE_NONE), source));
+ BOOST_CHECK_EQUAL(addrman.size(), 2);
- // Test 6: AddrMan::Clear() should empty the new table.
+ // Test: AddrMan::Clear() should empty the new table.
addrman.Clear();
- BOOST_CHECK(addrman.size() == 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0);
CAddrInfo addr_null2 = addrman.Select();
- BOOST_CHECK(addr_null2.ToString() == "[::]:0");
+ BOOST_CHECK_EQUAL(addr_null2.ToString(), "[::]:0");
+
+ // Test: AddrMan::Add multiple addresses works as expected
+ std::vector<CAddress> vAddr;
+ vAddr.push_back(CAddress(ResolveService("250.1.1.3", 8333), NODE_NONE));
+ vAddr.push_back(CAddress(ResolveService("250.1.1.4", 8333), NODE_NONE));
+ BOOST_CHECK(addrman.Add(vAddr, source));
+ BOOST_CHECK_EQUAL(addrman.size(), 2);
}
BOOST_AUTO_TEST_CASE(addrman_ports)
@@ -125,26 +132,26 @@ BOOST_AUTO_TEST_CASE(addrman_ports)
CNetAddr source = ResolveIP("252.2.2.2");
- BOOST_CHECK(addrman.size() == 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0);
// Test 7; Addr with same IP but diff port does not replace existing addr.
CService addr1 = ResolveService("250.1.1.1", 8333);
addrman.Add(CAddress(addr1, NODE_NONE), source);
- BOOST_CHECK(addrman.size() == 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1);
CService addr1_port = ResolveService("250.1.1.1", 8334);
addrman.Add(CAddress(addr1_port, NODE_NONE), source);
- BOOST_CHECK(addrman.size() == 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1);
CAddrInfo addr_ret2 = addrman.Select();
- BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333");
+ BOOST_CHECK_EQUAL(addr_ret2.ToString(), "250.1.1.1:8333");
- // Test 8: Add same IP but diff port to tried table, it doesn't get added.
+ // Test: Add same IP but diff port to tried table, it doesn't get added.
// Perhaps this is not ideal behavior but it is the current behavior.
addrman.Good(CAddress(addr1_port, NODE_NONE));
- BOOST_CHECK(addrman.size() == 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1);
bool newOnly = true;
CAddrInfo addr_ret3 = addrman.Select(newOnly);
- BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333");
+ BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333");
}
@@ -157,25 +164,25 @@ BOOST_AUTO_TEST_CASE(addrman_select)
CNetAddr source = ResolveIP("252.2.2.2");
- // Test 9: Select from new with 1 addr in new.
+ // Test: Select from new with 1 addr in new.
CService addr1 = ResolveService("250.1.1.1", 8333);
addrman.Add(CAddress(addr1, NODE_NONE), source);
- BOOST_CHECK(addrman.size() == 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1);
bool newOnly = true;
CAddrInfo addr_ret1 = addrman.Select(newOnly);
- BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333");
+ BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333");
- // Test 10: move addr to tried, select from new expected nothing returned.
+ // Test: move addr to tried, select from new expected nothing returned.
addrman.Good(CAddress(addr1, NODE_NONE));
- BOOST_CHECK(addrman.size() == 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1);
CAddrInfo addr_ret2 = addrman.Select(newOnly);
- BOOST_CHECK(addr_ret2.ToString() == "[::]:0");
+ BOOST_CHECK_EQUAL(addr_ret2.ToString(), "[::]:0");
CAddrInfo addr_ret3 = addrman.Select();
- BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333");
+ BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333");
- BOOST_CHECK(addrman.size() == 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1);
// Add three addresses to new table.
@@ -199,10 +206,10 @@ BOOST_AUTO_TEST_CASE(addrman_select)
addrman.Add(CAddress(addr7, NODE_NONE), ResolveService("250.1.1.3", 8333));
addrman.Good(CAddress(addr7, NODE_NONE));
- // Test 11: 6 addrs + 1 addr from last test = 7.
- BOOST_CHECK(addrman.size() == 7);
+ // Test: 6 addrs + 1 addr from last test = 7.
+ BOOST_CHECK_EQUAL(addrman.size(), 7);
- // Test 12: Select pulls from new and tried regardless of port number.
+ // Test: Select pulls from new and tried regardless of port number.
std::set<uint16_t> ports;
for (int i = 0; i < 20; ++i) {
ports.insert(addrman.Select().GetPort());
@@ -219,24 +226,24 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions)
CNetAddr source = ResolveIP("252.2.2.2");
- BOOST_CHECK(addrman.size() == 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0);
for (unsigned int i = 1; i < 18; i++) {
CService addr = ResolveService("250.1.1." + boost::to_string(i));
addrman.Add(CAddress(addr, NODE_NONE), source);
- //Test 13: No collision in new table yet.
- BOOST_CHECK(addrman.size() == i);
+ //Test: No collision in new table yet.
+ BOOST_CHECK_EQUAL(addrman.size(), i);
}
- //Test 14: new table collision!
+ //Test: new table collision!
CService addr1 = ResolveService("250.1.1.18");
addrman.Add(CAddress(addr1, NODE_NONE), source);
- BOOST_CHECK(addrman.size() == 17);
+ BOOST_CHECK_EQUAL(addrman.size(), 17);
CService addr2 = ResolveService("250.1.1.19");
addrman.Add(CAddress(addr2, NODE_NONE), source);
- BOOST_CHECK(addrman.size() == 18);
+ BOOST_CHECK_EQUAL(addrman.size(), 18);
}
BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
@@ -248,25 +255,25 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
CNetAddr source = ResolveIP("252.2.2.2");
- BOOST_CHECK(addrman.size() == 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0);
for (unsigned int i = 1; i < 80; i++) {
CService addr = ResolveService("250.1.1." + boost::to_string(i));
addrman.Add(CAddress(addr, NODE_NONE), source);
addrman.Good(CAddress(addr, NODE_NONE));
- //Test 15: No collision in tried table yet.
+ //Test: No collision in tried table yet.
BOOST_CHECK_EQUAL(addrman.size(), i);
}
- //Test 16: tried table collision!
+ //Test: tried table collision!
CService addr1 = ResolveService("250.1.1.80");
addrman.Add(CAddress(addr1, NODE_NONE), source);
- BOOST_CHECK(addrman.size() == 79);
+ BOOST_CHECK_EQUAL(addrman.size(), 79);
CService addr2 = ResolveService("250.1.1.81");
addrman.Add(CAddress(addr2, NODE_NONE), source);
- BOOST_CHECK(addrman.size() == 80);
+ BOOST_CHECK_EQUAL(addrman.size(), 80);
}
BOOST_AUTO_TEST_CASE(addrman_find)
@@ -276,7 +283,7 @@ BOOST_AUTO_TEST_CASE(addrman_find)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- BOOST_CHECK(addrman.size() == 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0);
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE);
@@ -289,23 +296,20 @@ BOOST_AUTO_TEST_CASE(addrman_find)
addrman.Add(addr2, source2);
addrman.Add(addr3, source1);
- // Test 17: ensure Find returns an IP matching what we searched on.
+ // Test: ensure Find returns an IP matching what we searched on.
CAddrInfo* info1 = addrman.Find(addr1);
- BOOST_CHECK(info1);
- if (info1)
- BOOST_CHECK(info1->ToString() == "250.1.2.1:8333");
+ BOOST_REQUIRE(info1);
+ BOOST_CHECK_EQUAL(info1->ToString(), "250.1.2.1:8333");
// Test 18; Find does not discriminate by port number.
CAddrInfo* info2 = addrman.Find(addr2);
- BOOST_CHECK(info2);
- if (info2 && info1)
- BOOST_CHECK(info2->ToString() == info1->ToString());
+ BOOST_REQUIRE(info2);
+ BOOST_CHECK_EQUAL(info2->ToString(), info1->ToString());
- // Test 19: Find returns another IP matching what we searched on.
+ // Test: Find returns another IP matching what we searched on.
CAddrInfo* info3 = addrman.Find(addr3);
- BOOST_CHECK(info3);
- if (info3)
- BOOST_CHECK(info3->ToString() == "251.255.2.1:8333");
+ BOOST_REQUIRE(info3);
+ BOOST_CHECK_EQUAL(info3->ToString(), "251.255.2.1:8333");
}
BOOST_AUTO_TEST_CASE(addrman_create)
@@ -315,7 +319,7 @@ BOOST_AUTO_TEST_CASE(addrman_create)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- BOOST_CHECK(addrman.size() == 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0);
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
CNetAddr source1 = ResolveIP("250.1.2.1");
@@ -323,11 +327,11 @@ BOOST_AUTO_TEST_CASE(addrman_create)
int nId;
CAddrInfo* pinfo = addrman.Create(addr1, source1, &nId);
- // Test 20: The result should be the same as the input addr.
- BOOST_CHECK(pinfo->ToString() == "250.1.2.1:8333");
+ // Test: The result should be the same as the input addr.
+ BOOST_CHECK_EQUAL(pinfo->ToString(), "250.1.2.1:8333");
CAddrInfo* info2 = addrman.Find(addr1);
- BOOST_CHECK(info2->ToString() == "250.1.2.1:8333");
+ BOOST_CHECK_EQUAL(info2->ToString(), "250.1.2.1:8333");
}
@@ -338,7 +342,7 @@ BOOST_AUTO_TEST_CASE(addrman_delete)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- BOOST_CHECK(addrman.size() == 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0);
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
CNetAddr source1 = ResolveIP("250.1.2.1");
@@ -346,10 +350,10 @@ BOOST_AUTO_TEST_CASE(addrman_delete)
int nId;
addrman.Create(addr1, source1, &nId);
- // Test 21: Delete should actually delete the addr.
- BOOST_CHECK(addrman.size() == 1);
+ // Test: Delete should actually delete the addr.
+ BOOST_CHECK_EQUAL(addrman.size(), 1);
addrman.Delete(nId);
- BOOST_CHECK(addrman.size() == 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0);
CAddrInfo* info2 = addrman.Find(addr1);
BOOST_CHECK(info2 == NULL);
}
@@ -361,11 +365,11 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- // Test 22: Sanity check, GetAddr should never return anything if addrman
+ // Test: Sanity check, GetAddr should never return anything if addrman
// is empty.
- BOOST_CHECK(addrman.size() == 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0);
std::vector<CAddress> vAddr1 = addrman.GetAddr();
- BOOST_CHECK(vAddr1.size() == 0);
+ BOOST_CHECK_EQUAL(vAddr1.size(), 0);
CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE);
addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false
@@ -380,7 +384,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
CNetAddr source1 = ResolveIP("250.1.2.1");
CNetAddr source2 = ResolveIP("250.2.3.3");
- // Test 23: Ensure GetAddr works with new addresses.
+ // Test: Ensure GetAddr works with new addresses.
addrman.Add(addr1, source1);
addrman.Add(addr2, source2);
addrman.Add(addr3, source1);
@@ -388,21 +392,20 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
addrman.Add(addr5, source1);
// GetAddr returns 23% of addresses, 23% of 5 is 1 rounded down.
- BOOST_CHECK(addrman.GetAddr().size() == 1);
+ BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1);
- // Test 24: Ensure GetAddr works with new and tried addresses.
+ // Test: Ensure GetAddr works with new and tried addresses.
addrman.Good(CAddress(addr1, NODE_NONE));
addrman.Good(CAddress(addr2, NODE_NONE));
- BOOST_CHECK(addrman.GetAddr().size() == 1);
+ BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1);
- // Test 25: Ensure GetAddr still returns 23% when addrman has many addrs.
+ // Test: Ensure GetAddr still returns 23% when addrman has many addrs.
for (unsigned int i = 1; i < (8 * 256); i++) {
int octet1 = i % 256;
- int octet2 = (i / 256) % 256;
- int octet3 = (i / (256 * 2)) % 256;
- std::string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23";
+ int octet2 = i >> 8 % 256;
+ std::string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + ".1.23";
CAddress addr = CAddress(ResolveService(strAddr), NODE_NONE);
-
+
// Ensure that for all addrs in addrman, isTerrible == false.
addr.nTime = GetAdjustedTime();
addrman.Add(addr, ResolveIP(strAddr));
@@ -412,10 +415,10 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
std::vector<CAddress> vAddr = addrman.GetAddr();
size_t percent23 = (addrman.size() * 23) / 100;
- BOOST_CHECK(vAddr.size() == percent23);
- BOOST_CHECK(vAddr.size() == 461);
+ BOOST_CHECK_EQUAL(vAddr.size(), percent23);
+ BOOST_CHECK_EQUAL(vAddr.size(), 461);
// (Addrman.size() < number of addresses added) due to address collisions.
- BOOST_CHECK(addrman.size() == 2007);
+ BOOST_CHECK_EQUAL(addrman.size(), 2006);
}
@@ -438,13 +441,13 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
- BOOST_CHECK(info1.GetTriedBucket(nKey1) == 40);
+ BOOST_CHECK_EQUAL(info1.GetTriedBucket(nKey1), 40);
- // Test 26: Make sure key actually randomizes bucket placement. A fail on
+ // Test: Make sure key actually randomizes bucket placement. A fail on
// this test could be a security issue.
BOOST_CHECK(info1.GetTriedBucket(nKey1) != info1.GetTriedBucket(nKey2));
- // Test 27: Two addresses with same IP but different ports can map to
+ // Test: Two addresses with same IP but different ports can map to
// different buckets because they have different keys.
CAddrInfo info2 = CAddrInfo(addr2, source1);
@@ -459,9 +462,9 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
int bucket = infoi.GetTriedBucket(nKey1);
buckets.insert(bucket);
}
- // Test 28: IP addresses in the same group (\16 prefix for IPv4) should
+ // Test: IP addresses in the same group (\16 prefix for IPv4) should
// never get more than 8 buckets
- BOOST_CHECK(buckets.size() == 8);
+ BOOST_CHECK_EQUAL(buckets.size(), 8);
buckets.clear();
for (int j = 0; j < 255; j++) {
@@ -471,9 +474,9 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
int bucket = infoj.GetTriedBucket(nKey1);
buckets.insert(bucket);
}
- // Test 29: IP addresses in the different groups should map to more than
+ // Test: IP addresses in the different groups should map to more than
// 8 buckets.
- BOOST_CHECK(buckets.size() == 160);
+ BOOST_CHECK_EQUAL(buckets.size(), 160);
}
BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
@@ -493,16 +496,18 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
- BOOST_CHECK(info1.GetNewBucket(nKey1) == 786);
+ // Test: Make sure the buckets are what we expect
+ BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1), 786);
+ BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, source1), 786);
- // Test 30: Make sure key actually randomizes bucket placement. A fail on
+ // Test: Make sure key actually randomizes bucket placement. A fail on
// this test could be a security issue.
BOOST_CHECK(info1.GetNewBucket(nKey1) != info1.GetNewBucket(nKey2));
- // Test 31: Ports should not effect bucket placement in the addr
+ // Test: Ports should not effect bucket placement in the addr
CAddrInfo info2 = CAddrInfo(addr2, source1);
BOOST_CHECK(info1.GetKey() != info2.GetKey());
- BOOST_CHECK(info1.GetNewBucket(nKey1) == info2.GetNewBucket(nKey1));
+ BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1), info2.GetNewBucket(nKey1));
std::set<int> buckets;
for (int i = 0; i < 255; i++) {
@@ -512,9 +517,9 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
int bucket = infoi.GetNewBucket(nKey1);
buckets.insert(bucket);
}
- // Test 32: IP addresses in the same group (\16 prefix for IPv4) should
+ // Test: IP addresses in the same group (\16 prefix for IPv4) should
// always map to the same bucket.
- BOOST_CHECK(buckets.size() == 1);
+ BOOST_CHECK_EQUAL(buckets.size(), 1);
buckets.clear();
for (int j = 0; j < 4 * 255; j++) {
@@ -525,7 +530,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
int bucket = infoj.GetNewBucket(nKey1);
buckets.insert(bucket);
}
- // Test 33: IP addresses in the same source groups should map to no more
+ // Test: IP addresses in the same source groups should map to no more
// than 64 buckets.
BOOST_CHECK(buckets.size() <= 64);
@@ -537,7 +542,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
int bucket = infoj.GetNewBucket(nKey1);
buckets.insert(bucket);
}
- // Test 34: IP addresses in the different source groups should map to more
+ // Test: IP addresses in the different source groups should map to more
// than 64 buckets.
BOOST_CHECK(buckets.size() > 64);
}
diff --git a/src/test/amount_tests.cpp b/src/test/amount_tests.cpp
index c95def5e87..952cf901f0 100644
--- a/src/test/amount_tests.cpp
+++ b/src/test/amount_tests.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "amount.h"
+#include "policy/feerate.h"
#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp
index d52104b4cc..656aec606b 100644
--- a/src/test/main_tests.cpp
+++ b/src/test/main_tests.cpp
@@ -39,17 +39,18 @@ static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval)
BOOST_AUTO_TEST_CASE(block_subsidy_test)
{
- TestBlockSubsidyHalvings(Params(CBaseChainParams::MAIN).GetConsensus()); // As in main
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
+ TestBlockSubsidyHalvings(chainParams->GetConsensus()); // As in main
TestBlockSubsidyHalvings(150); // As in regtest
TestBlockSubsidyHalvings(1000); // Just another interval
}
BOOST_AUTO_TEST_CASE(subsidy_limit_test)
{
- const Consensus::Params& consensusParams = Params(CBaseChainParams::MAIN).GetConsensus();
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
CAmount nSum = 0;
for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) {
- CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);
+ CAmount nSubsidy = GetBlockSubsidy(nHeight, chainParams->GetConsensus());
BOOST_CHECK(nSubsidy <= 50 * COIN);
nSum += nSubsidy * 1000;
BOOST_CHECK(MoneyRange(nSum));
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 41f42c7b88..fadff612d4 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -194,7 +194,8 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey,
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
{
// Note that by default, these tests run with size accounting enabled.
- const CChainParams& chainparams = Params(CBaseChainParams::MAIN);
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
+ const CChainParams& chainparams = *chainParams;
CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
std::unique_ptr<CBlockTemplate> pblocktemplate;
CMutableTransaction tx,tx2;
diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp
index 4ca6f1caf0..3b79f8000d 100644
--- a/src/test/pow_tests.cpp
+++ b/src/test/pow_tests.cpp
@@ -16,69 +16,59 @@ BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup)
/* Test calculation of next difficulty target with no constraints applying */
BOOST_AUTO_TEST_CASE(get_next_work)
{
- SelectParams(CBaseChainParams::MAIN);
- const Consensus::Params& params = Params().GetConsensus();
-
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
int64_t nLastRetargetTime = 1261130161; // Block #30240
CBlockIndex pindexLast;
pindexLast.nHeight = 32255;
pindexLast.nTime = 1262152739; // Block #32255
pindexLast.nBits = 0x1d00ffff;
- BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00d86a);
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00d86a);
}
/* Test the constraint on the upper bound for next work */
BOOST_AUTO_TEST_CASE(get_next_work_pow_limit)
{
- SelectParams(CBaseChainParams::MAIN);
- const Consensus::Params& params = Params().GetConsensus();
-
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
int64_t nLastRetargetTime = 1231006505; // Block #0
CBlockIndex pindexLast;
pindexLast.nHeight = 2015;
pindexLast.nTime = 1233061996; // Block #2015
pindexLast.nBits = 0x1d00ffff;
- BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00ffff);
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00ffff);
}
/* Test the constraint on the lower bound for actual time taken */
BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual)
{
- SelectParams(CBaseChainParams::MAIN);
- const Consensus::Params& params = Params().GetConsensus();
-
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
int64_t nLastRetargetTime = 1279008237; // Block #66528
CBlockIndex pindexLast;
pindexLast.nHeight = 68543;
pindexLast.nTime = 1279297671; // Block #68543
pindexLast.nBits = 0x1c05a3f4;
- BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1c0168fd);
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1c0168fd);
}
/* Test the constraint on the upper bound for actual time taken */
BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual)
{
- SelectParams(CBaseChainParams::MAIN);
- const Consensus::Params& params = Params().GetConsensus();
-
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time
CBlockIndex pindexLast;
pindexLast.nHeight = 46367;
pindexLast.nTime = 1269211443; // Block #46367
pindexLast.nBits = 0x1c387f6f;
- BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00e1fd);
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00e1fd);
}
BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
{
- SelectParams(CBaseChainParams::MAIN);
- const Consensus::Params& params = Params().GetConsensus();
-
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
std::vector<CBlockIndex> blocks(10000);
for (int i = 0; i < 10000; i++) {
blocks[i].pprev = i ? &blocks[i - 1] : NULL;
blocks[i].nHeight = i;
- blocks[i].nTime = 1269211443 + i * params.nPowTargetSpacing;
+ blocks[i].nTime = 1269211443 + i * chainParams->GetConsensus().nPowTargetSpacing;
blocks[i].nBits = 0x207fffff; /* target 0x7fffff000... */
blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0);
}
@@ -88,7 +78,7 @@ BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
CBlockIndex *p2 = &blocks[GetRand(10000)];
CBlockIndex *p3 = &blocks[GetRand(10000)];
- int64_t tdiff = GetBlockProofEquivalentTime(*p1, *p2, *p3, params);
+ int64_t tdiff = GetBlockProofEquivalentTime(*p1, *p2, *p3, chainParams->GetConsensus());
BOOST_CHECK_EQUAL(tdiff, p1->GetBlockTime() - p2->GetBlockTime());
}
}
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 5da4907f06..10330c0c23 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -17,8 +17,6 @@
#include <boost/test/unit_test.hpp>
-extern std::map<std::string, std::string> mapArgs;
-
BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(util_criticalsection)
@@ -100,52 +98,67 @@ BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat)
BOOST_CHECK_EQUAL(DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", 1317425777), "Fri, 30 Sep 2011 23:36:17 +0000");
}
+class TestArgsManager : public ArgsManager
+{
+public:
+ std::map<std::string, std::string>& GetMapArgs()
+ {
+ return mapArgs;
+ };
+ const std::map<std::string, std::vector<std::string> >& GetMapMultiArgs()
+ {
+ return mapMultiArgs;
+ };
+};
+
BOOST_AUTO_TEST_CASE(util_ParseParameters)
{
+ TestArgsManager testArgs;
const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"};
- ParseParameters(0, (char**)argv_test);
- BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty());
+ testArgs.ParseParameters(0, (char**)argv_test);
+ BOOST_CHECK(testArgs.GetMapArgs().empty() && testArgs.GetMapMultiArgs().empty());
- ParseParameters(1, (char**)argv_test);
- BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty());
+ testArgs.ParseParameters(1, (char**)argv_test);
+ BOOST_CHECK(testArgs.GetMapArgs().empty() && testArgs.GetMapMultiArgs().empty());
- ParseParameters(5, (char**)argv_test);
+ testArgs.ParseParameters(5, (char**)argv_test);
// expectation: -ignored is ignored (program name argument),
// -a, -b and -ccc end up in map, -d ignored because it is after
// a non-option argument (non-GNU option parsing)
- BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3);
- BOOST_CHECK(IsArgSet("-a") && IsArgSet("-b") && IsArgSet("-ccc")
- && !IsArgSet("f") && !IsArgSet("-d"));
- BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc")
- && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d"));
-
- BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple");
- BOOST_CHECK(mapMultiArgs.at("-ccc").size() == 2);
+ BOOST_CHECK(testArgs.GetMapArgs().size() == 3 && testArgs.GetMapMultiArgs().size() == 3);
+ BOOST_CHECK(testArgs.IsArgSet("-a") && testArgs.IsArgSet("-b") && testArgs.IsArgSet("-ccc")
+ && !testArgs.IsArgSet("f") && !testArgs.IsArgSet("-d"));
+ BOOST_CHECK(testArgs.GetMapMultiArgs().count("-a") && testArgs.GetMapMultiArgs().count("-b") && testArgs.GetMapMultiArgs().count("-ccc")
+ && !testArgs.GetMapMultiArgs().count("f") && !testArgs.GetMapMultiArgs().count("-d"));
+
+ BOOST_CHECK(testArgs.GetMapArgs()["-a"] == "" && testArgs.GetMapArgs()["-ccc"] == "multiple");
+ BOOST_CHECK(testArgs.GetArgs("-ccc").size() == 2);
}
BOOST_AUTO_TEST_CASE(util_GetArg)
{
- mapArgs.clear();
- mapArgs["strtest1"] = "string...";
+ TestArgsManager testArgs;
+ testArgs.GetMapArgs().clear();
+ testArgs.GetMapArgs()["strtest1"] = "string...";
// strtest2 undefined on purpose
- mapArgs["inttest1"] = "12345";
- mapArgs["inttest2"] = "81985529216486895";
+ testArgs.GetMapArgs()["inttest1"] = "12345";
+ testArgs.GetMapArgs()["inttest2"] = "81985529216486895";
// inttest3 undefined on purpose
- mapArgs["booltest1"] = "";
+ testArgs.GetMapArgs()["booltest1"] = "";
// booltest2 undefined on purpose
- mapArgs["booltest3"] = "0";
- mapArgs["booltest4"] = "1";
-
- BOOST_CHECK_EQUAL(GetArg("strtest1", "default"), "string...");
- BOOST_CHECK_EQUAL(GetArg("strtest2", "default"), "default");
- BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345);
- BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895LL);
- BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1);
- BOOST_CHECK_EQUAL(GetBoolArg("booltest1", false), true);
- BOOST_CHECK_EQUAL(GetBoolArg("booltest2", false), false);
- BOOST_CHECK_EQUAL(GetBoolArg("booltest3", false), false);
- BOOST_CHECK_EQUAL(GetBoolArg("booltest4", false), true);
+ testArgs.GetMapArgs()["booltest3"] = "0";
+ testArgs.GetMapArgs()["booltest4"] = "1";
+
+ BOOST_CHECK_EQUAL(testArgs.GetArg("strtest1", "default"), "string...");
+ BOOST_CHECK_EQUAL(testArgs.GetArg("strtest2", "default"), "default");
+ BOOST_CHECK_EQUAL(testArgs.GetArg("inttest1", -1), 12345);
+ BOOST_CHECK_EQUAL(testArgs.GetArg("inttest2", -1), 81985529216486895LL);
+ BOOST_CHECK_EQUAL(testArgs.GetArg("inttest3", -1), -1);
+ BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest1", false), true);
+ BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest2", false), false);
+ BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest3", false), false);
+ BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest4", false), true);
}
BOOST_AUTO_TEST_CASE(util_FormatMoney)
diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp
index e2b5573abd..79405ec4d1 100644
--- a/src/test/versionbits_tests.cpp
+++ b/src/test/versionbits_tests.cpp
@@ -209,7 +209,8 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
}
// Sanity checks of version bit deployments
- const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus();
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
+ const Consensus::Params &mainnetParams = chainParams->GetConsensus();
for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
uint32_t bitmask = VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)i);
// Make sure that no deployment tries to set an invalid bit.
@@ -235,7 +236,8 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
{
// Check that ComputeBlockVersion will set the appropriate bit correctly
// on mainnet.
- const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus();
+ const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
+ const Consensus::Params &mainnetParams = chainParams->GetConsensus();
// Use the TESTDUMMY deployment for testing purposes.
int64_t bit = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit;
diff --git a/src/txmempool.h b/src/txmempool.h
index 92c4d9f9d4..9cb73fcc0c 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -16,6 +16,7 @@
#include "amount.h"
#include "coins.h"
#include "indirectmap.h"
+#include "policy/feerate.h"
#include "primitives/transaction.h"
#include "sync.h"
#include "random.h"
@@ -59,11 +60,6 @@ class CTxMemPool;
* (nCountWithDescendants, nSizeWithDescendants, and nModFeesWithDescendants) for
* all ancestors of the newly added transaction.
*
- * If updating the descendant state is skipped, we can mark the entry as
- * "dirty", and set nSizeWithDescendants/nModFeesWithDescendants to equal nTxSize/
- * nFee+feeDelta. (This can potentially happen during a reorg, where we limit the
- * amount of work we're willing to do to avoid consuming too much CPU.)
- *
*/
class CTxMemPoolEntry
@@ -82,9 +78,7 @@ private:
// Information about descendants of this transaction that are in the
// mempool; if we remove this transaction we must remove all of these
- // descendants as well. if nCountWithDescendants is 0, treat this entry as
- // dirty, and nSizeWithDescendants and nModFeesWithDescendants will not be
- // correct.
+ // descendants as well.
uint64_t nCountWithDescendants; //!< number of descendant transactions
uint64_t nSizeWithDescendants; //!< ... and size
CAmount nModFeesWithDescendants; //!< ... and total fees (all including us)
@@ -115,7 +109,7 @@ public:
size_t DynamicMemoryUsage() const { return nUsageSize; }
const LockPoints& GetLockPoints() const { return lockPoints; }
- // Adjusts the descendant state, if this entry is not dirty.
+ // Adjusts the descendant state.
void UpdateDescendantState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount);
// Adjusts the ancestor state
void UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int modifySigOps);
@@ -398,14 +392,6 @@ enum class MemPoolRemovalReason {
* CalculateMemPoolAncestors() takes configurable limits that are designed to
* prevent these calculations from being too CPU intensive.
*
- * Adding transactions from a disconnected block can be very time consuming,
- * because we don't have a way to limit the number of in-mempool descendants.
- * To bound CPU processing, we limit the amount of work we're willing to do
- * to properly update the descendant information for a tx being added from
- * a disconnected block. If we would exceed the limit, then we instead mark
- * the entry as "dirty", and set the feerate for sorting purposes to be equal
- * the feerate of the transaction without any descendants.
- *
*/
class CTxMemPool
{
diff --git a/src/util.cpp b/src/util.cpp
index cf10ee4aa5..653a4f072a 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -13,7 +13,6 @@
#include "fs.h"
#include "random.h"
#include "serialize.h"
-#include "sync.h"
#include "utilstrencodings.h"
#include "utiltime.h"
@@ -92,10 +91,7 @@
const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf";
const char * const BITCOIN_PID_FILENAME = "bitcoind.pid";
-CCriticalSection cs_args;
-std::map<std::string, std::string> mapArgs;
-static std::map<std::string, std::vector<std::string> > _mapMultiArgs;
-const std::map<std::string, std::vector<std::string> >& mapMultiArgs = _mapMultiArgs;
+ArgsManager gArgs;
bool fPrintToConsole = false;
bool fPrintToDebugLog = true;
@@ -310,10 +306,14 @@ static std::string LogTimestampStr(const std::string &str, std::atomic_bool *fSt
return str;
if (*fStartedNewLine) {
- int64_t nTimeMicros = GetLogTimeMicros();
+ int64_t nTimeMicros = GetTimeMicros();
strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nTimeMicros/1000000);
if (fLogTimeMicros)
strStamped += strprintf(".%06d", nTimeMicros%1000000);
+ int64_t mocktime = GetMockTime();
+ if (mocktime) {
+ strStamped += " (mocktime: " + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", mocktime) + ")";
+ }
strStamped += ' ' + str;
} else
strStamped = str;
@@ -384,11 +384,11 @@ static void InterpretNegativeSetting(std::string& strKey, std::string& strValue)
}
}
-void ParseParameters(int argc, const char* const argv[])
+void ArgsManager::ParseParameters(int argc, const char* const argv[])
{
LOCK(cs_args);
mapArgs.clear();
- _mapMultiArgs.clear();
+ mapMultiArgs.clear();
for (int i = 1; i < argc; i++)
{
@@ -416,17 +416,23 @@ void ParseParameters(int argc, const char* const argv[])
InterpretNegativeSetting(str, strValue);
mapArgs[str] = strValue;
- _mapMultiArgs[str].push_back(strValue);
+ mapMultiArgs[str].push_back(strValue);
}
}
-bool IsArgSet(const std::string& strArg)
+std::vector<std::string> ArgsManager::GetArgs(const std::string& strArg)
+{
+ LOCK(cs_args);
+ return mapMultiArgs.at(strArg);
+}
+
+bool ArgsManager::IsArgSet(const std::string& strArg)
{
LOCK(cs_args);
return mapArgs.count(strArg);
}
-std::string GetArg(const std::string& strArg, const std::string& strDefault)
+std::string ArgsManager::GetArg(const std::string& strArg, const std::string& strDefault)
{
LOCK(cs_args);
if (mapArgs.count(strArg))
@@ -434,7 +440,7 @@ std::string GetArg(const std::string& strArg, const std::string& strDefault)
return strDefault;
}
-int64_t GetArg(const std::string& strArg, int64_t nDefault)
+int64_t ArgsManager::GetArg(const std::string& strArg, int64_t nDefault)
{
LOCK(cs_args);
if (mapArgs.count(strArg))
@@ -442,7 +448,7 @@ int64_t GetArg(const std::string& strArg, int64_t nDefault)
return nDefault;
}
-bool GetBoolArg(const std::string& strArg, bool fDefault)
+bool ArgsManager::GetBoolArg(const std::string& strArg, bool fDefault)
{
LOCK(cs_args);
if (mapArgs.count(strArg))
@@ -450,16 +456,16 @@ bool GetBoolArg(const std::string& strArg, bool fDefault)
return fDefault;
}
-bool SoftSetArg(const std::string& strArg, const std::string& strValue)
+bool ArgsManager::SoftSetArg(const std::string& strArg, const std::string& strValue)
{
LOCK(cs_args);
if (mapArgs.count(strArg))
return false;
- mapArgs[strArg] = strValue;
+ ForceSetArg(strArg, strValue);
return true;
}
-bool SoftSetBoolArg(const std::string& strArg, bool fValue)
+bool ArgsManager::SoftSetBoolArg(const std::string& strArg, bool fValue)
{
if (fValue)
return SoftSetArg(strArg, std::string("1"));
@@ -467,10 +473,11 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue)
return SoftSetArg(strArg, std::string("0"));
}
-void ForceSetArg(const std::string& strArg, const std::string& strValue)
+void ArgsManager::ForceSetArg(const std::string& strArg, const std::string& strValue)
{
LOCK(cs_args);
mapArgs[strArg] = strValue;
+ mapMultiArgs[strArg].push_back(strValue);
}
@@ -589,7 +596,7 @@ fs::path GetConfigFile(const std::string& confPath)
return pathConfigFile;
}
-void ReadConfigFile(const std::string& confPath)
+void ArgsManager::ReadConfigFile(const std::string& confPath)
{
fs::ifstream streamConfig(GetConfigFile(confPath));
if (!streamConfig.good())
@@ -608,7 +615,7 @@ void ReadConfigFile(const std::string& confPath)
InterpretNegativeSetting(strKey, strValue);
if (mapArgs.count(strKey) == 0)
mapArgs[strKey] = strValue;
- _mapMultiArgs[strKey].push_back(strValue);
+ mapMultiArgs[strKey].push_back(strValue);
}
}
// If datadir is changed in .conf file:
diff --git a/src/util.h b/src/util.h
index ed28070a3f..229478d835 100644
--- a/src/util.h
+++ b/src/util.h
@@ -16,6 +16,7 @@
#include "compat.h"
#include "fs.h"
+#include "sync.h"
#include "tinyformat.h"
#include "utiltime.h"
@@ -41,7 +42,6 @@ public:
boost::signals2::signal<std::string (const char* psz)> Translate;
};
-extern const std::map<std::string, std::vector<std::string> >& mapMultiArgs;
extern bool fPrintToConsole;
extern bool fPrintToDebugLog;
@@ -148,7 +148,6 @@ bool error(const char* fmt, const Args&... args)
}
void PrintExceptionContinue(const std::exception *pex, const char* pszThread);
-void ParseParameters(int argc, const char*const argv[]);
void FileCommit(FILE *file);
bool TruncateFile(FILE *file, unsigned int length);
int RaiseFileDescriptorLimit(int nMinFD);
@@ -163,7 +162,6 @@ fs::path GetConfigFile(const std::string& confPath);
fs::path GetPidFile();
void CreatePidFile(const fs::path &path, pid_t pid);
#endif
-void ReadConfigFile(const std::string& confPath);
#ifdef WIN32
fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
#endif
@@ -180,6 +178,16 @@ inline bool IsSwitchChar(char c)
#endif
}
+class ArgsManager
+{
+protected:
+ CCriticalSection cs_args;
+ std::map<std::string, std::string> mapArgs;
+ std::map<std::string, std::vector<std::string> > mapMultiArgs;
+public:
+ void ParseParameters(int argc, const char*const argv[]);
+ void ReadConfigFile(const std::string& confPath);
+ std::vector<std::string> GetArgs(const std::string& strArg);
/**
* Return true if the given argument has been manually set
*
@@ -235,6 +243,55 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue);
// Forces a arg setting, used only in testing
void ForceSetArg(const std::string& strArg, const std::string& strValue);
+};
+
+extern ArgsManager gArgs;
+
+// wrappers using the global ArgsManager:
+static inline void ParseParameters(int argc, const char*const argv[])
+{
+ gArgs.ParseParameters(argc, argv);
+}
+
+static inline void ReadConfigFile(const std::string& confPath)
+{
+ gArgs.ReadConfigFile(confPath);
+}
+
+static inline bool SoftSetArg(const std::string& strArg, const std::string& strValue)
+{
+ return gArgs.SoftSetArg(strArg, strValue);
+}
+
+static inline void ForceSetArg(const std::string& strArg, const std::string& strValue)
+{
+ gArgs.ForceSetArg(strArg, strValue);
+}
+
+static inline bool IsArgSet(const std::string& strArg)
+{
+ return gArgs.IsArgSet(strArg);
+}
+
+static inline std::string GetArg(const std::string& strArg, const std::string& strDefault)
+{
+ return gArgs.GetArg(strArg, strDefault);
+}
+
+static inline int64_t GetArg(const std::string& strArg, int64_t nDefault)
+{
+ return gArgs.GetArg(strArg, nDefault);
+}
+
+static inline bool GetBoolArg(const std::string& strArg, bool fDefault)
+{
+ return gArgs.GetBoolArg(strArg, fDefault);
+}
+
+static inline bool SoftSetBoolArg(const std::string& strArg, bool fValue)
+{
+ return gArgs.SoftSetBoolArg(strArg, fValue);
+}
/**
* Format a string to be used as group of options in help messages
diff --git a/src/utiltime.cpp b/src/utiltime.cpp
index 510f540b1d..e07069125d 100644
--- a/src/utiltime.cpp
+++ b/src/utiltime.cpp
@@ -31,6 +31,11 @@ void SetMockTime(int64_t nMockTimeIn)
nMockTime.store(nMockTimeIn, std::memory_order_relaxed);
}
+int64_t GetMockTime()
+{
+ return nMockTime.load(std::memory_order_relaxed);
+}
+
int64_t GetTimeMillis()
{
int64_t now = (boost::posix_time::microsec_clock::universal_time() -
@@ -52,15 +57,6 @@ int64_t GetSystemTimeInSeconds()
return GetTimeMicros()/1000000;
}
-/** Return a time useful for the debug log */
-int64_t GetLogTimeMicros()
-{
- int64_t mocktime = nMockTime.load(std::memory_order_relaxed);
- if (mocktime) return mocktime*1000000;
-
- return GetTimeMicros();
-}
-
void MilliSleep(int64_t n)
{
diff --git a/src/utiltime.h b/src/utiltime.h
index cc3290c631..8ae8540b89 100644
--- a/src/utiltime.h
+++ b/src/utiltime.h
@@ -23,8 +23,8 @@ int64_t GetTime();
int64_t GetTimeMillis();
int64_t GetTimeMicros();
int64_t GetSystemTimeInSeconds(); // Like GetTime(), but not mockable
-int64_t GetLogTimeMicros();
void SetMockTime(int64_t nMockTimeIn);
+int64_t GetMockTime();
void MilliSleep(int64_t n);
std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime);
diff --git a/src/validation.h b/src/validation.h
index c046ba9238..8ddceb2306 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -14,6 +14,7 @@
#include "coins.h"
#include "fs.h"
#include "protocol.h" // For CMessageHeader::MessageStartChars
+#include "policy/feerate.h"
#include "script/script_error.h"
#include "sync.h"
#include "versionbits.h"
diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h
index 4e93e929be..2aa26fb00a 100644
--- a/src/wallet/coincontrol.h
+++ b/src/wallet/coincontrol.h
@@ -5,6 +5,7 @@
#ifndef BITCOIN_WALLET_COINCONTROL_H
#define BITCOIN_WALLET_COINCONTROL_H
+#include "policy/feerate.h"
#include "primitives/transaction.h"
#include "wallet/wallet.h"
diff --git a/src/wallet/db.h b/src/wallet/db.h
index 1a46448cc7..3c6870d169 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -180,22 +180,23 @@ public:
Dbt datValue;
datValue.set_flags(DB_DBT_MALLOC);
int ret = pdb->get(activeTxn, &datKey, &datValue, 0);
- memset(datKey.get_data(), 0, datKey.get_size());
- if (datValue.get_data() == NULL)
- return false;
-
- // Unserialize value
- try {
- CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
- ssValue >> value;
- } catch (const std::exception&) {
- return false;
+ memory_cleanse(datKey.get_data(), datKey.get_size());
+ bool success = false;
+ if (datValue.get_data() != NULL) {
+ // Unserialize value
+ try {
+ CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
+ ssValue >> value;
+ success = true;
+ } catch (const std::exception&) {
+ // In this case success remains 'false'
+ }
+
+ // Clear and free memory
+ memory_cleanse(datValue.get_data(), datValue.get_size());
+ free(datValue.get_data());
}
-
- // Clear and free memory
- memset(datValue.get_data(), 0, datValue.get_size());
- free(datValue.get_data());
- return (ret == 0);
+ return ret == 0 && success;
}
template <typename K, typename T>
@@ -222,8 +223,8 @@ public:
int ret = pdb->put(activeTxn, &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
// Clear memory in case it was a private key
- memset(datKey.get_data(), 0, datKey.get_size());
- memset(datValue.get_data(), 0, datValue.get_size());
+ memory_cleanse(datKey.get_data(), datKey.get_size());
+ memory_cleanse(datValue.get_data(), datValue.get_size());
return (ret == 0);
}
@@ -245,7 +246,7 @@ public:
int ret = pdb->del(activeTxn, &datKey, 0);
// Clear memory
- memset(datKey.get_data(), 0, datKey.get_size());
+ memory_cleanse(datKey.get_data(), datKey.get_size());
return (ret == 0 || ret == DB_NOTFOUND);
}
@@ -265,7 +266,7 @@ public:
int ret = pdb->exists(activeTxn, &datKey, 0);
// Clear memory
- memset(datKey.get_data(), 0, datKey.get_size());
+ memory_cleanse(datKey.get_data(), datKey.get_size());
return (ret == 0);
}
@@ -308,8 +309,8 @@ public:
ssValue.write((char*)datValue.get_data(), datValue.get_size());
// Clear and free memory
- memset(datKey.get_data(), 0, datKey.get_size());
- memset(datValue.get_data(), 0, datValue.get_size());
+ memory_cleanse(datKey.get_data(), datKey.get_size());
+ memory_cleanse(datValue.get_data(), datValue.get_size());
free(datKey.get_data());
free(datValue.get_data());
return 0;
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp
index f5b63c1ecd..b3cb6a718c 100644
--- a/src/wallet/feebumper.cpp
+++ b/src/wallet/feebumper.cpp
@@ -214,7 +214,7 @@ CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, int newConf
// If the output would become dust, discard it (converting the dust to fee)
poutput->nValue -= nDelta;
- if (poutput->nValue <= poutput->GetDustThreshold(::dustRelayFee)) {
+ if (poutput->nValue <= GetDustThreshold(*poutput, ::dustRelayFee)) {
LogPrint(BCLog::RPC, "Bumping fee and discarding dust output\n");
nNewFee += poutput->nValue;
mtx.vout.erase(mtx.vout.begin() + nOutput);
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index d1e7485d04..fa67964ce8 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -12,6 +12,7 @@
#include "wallet/coincontrol.h"
#include "validation.h"
#include "net.h"
+#include "policy/feerate.h"
#include "policy/fees.h"
#include "policy/policy.h"
#include "policy/rbf.h"
@@ -729,7 +730,8 @@ UniValue getbalance(const JSONRPCRequest& request)
if (request.params.size() == 0)
return ValueFromAmount(pwallet->GetBalance());
- const std::string* account = request.params[0].get_str() != "*" ? &request.params[0].get_str() : nullptr;
+ const std::string& account_param = request.params[0].get_str();
+ const std::string* account = account_param != "*" ? &account_param : nullptr;
int nMinDepth = 1;
if (request.params.size() > 1)
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index fa82c9c9df..ea329d6ebe 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2449,7 +2449,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
}
}
- if (txout.IsDust(dustRelayFee))
+ if (IsDust(txout, ::dustRelayFee))
{
if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
{
@@ -2514,16 +2514,16 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
// We do not move dust-change to fees, because the sender would end up paying more than requested.
// This would be against the purpose of the all-inclusive feature.
// So instead we raise the change and deduct from the recipient.
- if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(dustRelayFee))
+ if (nSubtractFeeFromAmount > 0 && IsDust(newTxOut, ::dustRelayFee))
{
- CAmount nDust = newTxOut.GetDustThreshold(dustRelayFee) - newTxOut.nValue;
+ CAmount nDust = GetDustThreshold(newTxOut, ::dustRelayFee) - newTxOut.nValue;
newTxOut.nValue += nDust; // raise change until no more dust
for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
{
if (vecSend[i].fSubtractFeeFromAmount)
{
txNew.vout[i].nValue -= nDust;
- if (txNew.vout[i].IsDust(dustRelayFee))
+ if (IsDust(txNew.vout[i], ::dustRelayFee))
{
strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
return false;
@@ -2535,7 +2535,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
// Never create dust outputs; if we would, just
// add the dust to the fee.
- if (newTxOut.IsDust(dustRelayFee))
+ if (IsDust(newTxOut, ::dustRelayFee))
{
nChangePosInOut = -1;
nFeeRet += nChange;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 81f7ec59f5..179ea1b7ad 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -7,6 +7,7 @@
#define BITCOIN_WALLET_WALLET_H
#include "amount.h"
+#include "policy/feerate.h"
#include "streams.h"
#include "tinyformat.h"
#include "ui_interface.h"
diff --git a/test/functional/blockchain.py b/test/functional/blockchain.py
index 00ae3d7572..8596f1edaf 100755
--- a/test/functional/blockchain.py
+++ b/test/functional/blockchain.py
@@ -10,6 +10,7 @@ Test the following RPCs:
- getbestblockhash
- getblockhash
- getblockheader
+ - getnetworkhashps
- verifychain
Tests correspond to code in rpc/blockchain.cpp.
@@ -23,8 +24,6 @@ from test_framework.util import (
assert_raises_jsonrpc,
assert_is_hex_string,
assert_is_hash_string,
- start_nodes,
- connect_nodes_bi,
)
@@ -39,6 +38,7 @@ class BlockchainTest(BitcoinTestFramework):
self._test_gettxoutsetinfo()
self._test_getblockheader()
self._test_getdifficulty()
+ self._test_getnetworkhashps()
self.nodes[0].verifychain(4, 0)
def _test_gettxoutsetinfo(self):
@@ -85,5 +85,10 @@ class BlockchainTest(BitcoinTestFramework):
# binary => decimal => binary math is why we do this check
assert abs(difficulty * 2**31 - 1) < 0.0001
+ def _test_getnetworkhashps(self):
+ hashes_per_second = self.nodes[0].getnetworkhashps()
+ # This should be 2 hashes every 10 minutes or 1/300
+ assert abs(hashes_per_second * 300 - 1) < 0.0001
+
if __name__ == '__main__':
BlockchainTest().main()
diff --git a/test/functional/disablewallet.py b/test/functional/disablewallet.py
index 3f77a1828d..d344513414 100755
--- a/test/functional/disablewallet.py
+++ b/test/functional/disablewallet.py
@@ -21,6 +21,8 @@ class DisableWalletTest (BitcoinTestFramework):
self.extra_args = [["-disablewallet"]]
def run_test (self):
+ # Make sure wallet is really disabled
+ assert_raises_jsonrpc(-32601, 'Method not found', self.nodes[0].getwalletinfo)
x = self.nodes[0].validateaddress('3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy')
assert(x['isvalid'] == False)
x = self.nodes[0].validateaddress('mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
diff --git a/test/functional/disconnect_ban.py b/test/functional/disconnect_ban.py
index 50d79db903..f453fc0261 100755
--- a/test/functional/disconnect_ban.py
+++ b/test/functional/disconnect_ban.py
@@ -3,6 +3,7 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test node disconnect and ban behavior"""
+import time
from test_framework.mininode import wait_until
from test_framework.test_framework import BitcoinTestFramework
@@ -56,11 +57,16 @@ class DisconnectBanTest(BitcoinTestFramework):
self.log.info("setban: test persistence across node restart")
self.nodes[1].setban("127.0.0.0/32", "add")
self.nodes[1].setban("127.0.0.0/24", "add")
+ # Set the mocktime so we can control when bans expire
+ old_time = int(time.time())
+ self.nodes[1].setmocktime(old_time)
self.nodes[1].setban("192.168.0.1", "add", 1) # ban for 1 seconds
self.nodes[1].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) # ban for 1000 seconds
listBeforeShutdown = self.nodes[1].listbanned()
assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address'])
- assert wait_until(lambda: len(self.nodes[1].listbanned()) == 3, timeout=10)
+ # Move time forward by 3 seconds so the third ban has expired
+ self.nodes[1].setmocktime(old_time + 3)
+ assert_equal(len(self.nodes[1].listbanned()), 3)
stop_node(self.nodes[1], 1)
diff --git a/test/functional/net.py b/test/functional/net.py
index 16476f7d34..fb46064441 100755
--- a/test/functional/net.py
+++ b/test/functional/net.py
@@ -15,7 +15,6 @@ from test_framework.util import (
assert_raises_jsonrpc,
connect_nodes_bi,
p2p_port,
- start_nodes,
)
diff --git a/test/functional/rpcnamedargs.py b/test/functional/rpcnamedargs.py
index fd81b02ead..3b286000a1 100755
--- a/test/functional/rpcnamedargs.py
+++ b/test/functional/rpcnamedargs.py
@@ -8,7 +8,6 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_jsonrpc,
- start_nodes,
)
diff --git a/test/functional/sendheaders.py b/test/functional/sendheaders.py
index 97d64c0d98..44c357c6db 100755
--- a/test/functional/sendheaders.py
+++ b/test/functional/sendheaders.py
@@ -243,7 +243,7 @@ class SendHeadersTest(BitcoinTestFramework):
if i == 0:
# first request the block
test_node.get_data([tip])
- test_node.wait_for_block(tip, timeout=5)
+ test_node.wait_for_block(tip)
elif i == 1:
# next try requesting header and block
test_node.get_headers(locator=[old_tip], hashstop=tip)
@@ -258,7 +258,7 @@ class SendHeadersTest(BitcoinTestFramework):
new_block = create_block(tip, create_coinbase(height+1), block_time)
new_block.solve()
test_node.send_header_for_blocks([new_block])
- test_node.wait_for_getdata([new_block.sha256], timeout=5)
+ test_node.wait_for_getdata([new_block.sha256])
test_node.send_message(msg_block(new_block))
test_node.sync_with_ping() # make sure this block is processed
inv_node.clear_last_announcement()
@@ -297,18 +297,18 @@ class SendHeadersTest(BitcoinTestFramework):
if j == 0:
# Announce via inv
test_node.send_block_inv(tip)
- test_node.wait_for_getheaders(timeout=5)
+ test_node.wait_for_getheaders()
# Should have received a getheaders now
test_node.send_header_for_blocks(blocks)
# Test that duplicate inv's won't result in duplicate
# getdata requests, or duplicate headers announcements
[ inv_node.send_block_inv(x.sha256) for x in blocks ]
- test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=5)
+ test_node.wait_for_getdata([x.sha256 for x in blocks])
inv_node.sync_with_ping()
else:
# Announce via headers
test_node.send_header_for_blocks(blocks)
- test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=5)
+ test_node.wait_for_getdata([x.sha256 for x in blocks])
# Test that duplicate headers won't result in duplicate
# getdata requests (the check is further down)
inv_node.send_header_for_blocks(blocks)
@@ -495,7 +495,7 @@ class SendHeadersTest(BitcoinTestFramework):
with mininode_lock:
test_node.last_message.pop("getheaders", None)
test_node.send_header_for_blocks([blocks[1]])
- test_node.wait_for_getheaders(timeout=1)
+ test_node.wait_for_getheaders()
test_node.send_header_for_blocks(blocks)
test_node.wait_for_getdata([x.sha256 for x in blocks])
[ test_node.send_message(msg_block(x)) for x in blocks ]
@@ -518,7 +518,7 @@ class SendHeadersTest(BitcoinTestFramework):
with mininode_lock:
test_node.last_message.pop("getheaders", None)
test_node.send_header_for_blocks([blocks[i]])
- test_node.wait_for_getheaders(timeout=1)
+ test_node.wait_for_getheaders()
# Next header will connect, should re-set our count:
test_node.send_header_for_blocks([blocks[0]])
@@ -533,7 +533,7 @@ class SendHeadersTest(BitcoinTestFramework):
with mininode_lock:
test_node.last_message.pop("getheaders", None)
test_node.send_header_for_blocks([blocks[i%len(blocks)]])
- test_node.wait_for_getheaders(timeout=1)
+ test_node.wait_for_getheaders()
# Eventually this stops working.
test_node.send_header_for_blocks([blocks[-1]])
diff --git a/test/functional/signmessages.py b/test/functional/signmessages.py
index bfde8e40ec..42f6a9daaf 100755
--- a/test/functional/signmessages.py
+++ b/test/functional/signmessages.py
@@ -5,7 +5,6 @@
"""Test RPC commands for signing and verifying messages."""
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
class SignMessagesTest(BitcoinTestFramework):
diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py
index 70bba566c7..fb3ed1473a 100755
--- a/test/functional/test_framework/mininode.py
+++ b/test/functional/test_framework/mininode.py
@@ -1358,6 +1358,8 @@ class msg_reject(object):
# Helper function
def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf')):
+ if attempts == float('inf') and timeout == float('inf'):
+ timeout = 60
attempt = 0
elapsed = 0
diff --git a/test/functional/wallet-accounts.py b/test/functional/wallet-accounts.py
index 8dc1589117..e6635bea1c 100755
--- a/test/functional/wallet-accounts.py
+++ b/test/functional/wallet-accounts.py
@@ -15,7 +15,6 @@ RPCs tested are:
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
- start_nodes,
assert_equal,
)
diff --git a/test/functional/wallet-hd.py b/test/functional/wallet-hd.py
index bbf53e7dba..aab3b4bc2d 100755
--- a/test/functional/wallet-hd.py
+++ b/test/functional/wallet-hd.py
@@ -6,7 +6,6 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
- start_nodes,
start_node,
assert_equal,
connect_nodes_bi,