aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml2
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md31
-rw-r--r--configure.ac32
-rw-r--r--depends/packages/qt.mk1
-rw-r--r--doc/man/Makefile.am8
-rw-r--r--doc/release-notes-14282.md6
-rw-r--r--doc/release-notes/release-notes-0.14.3.md118
-rw-r--r--doc/release-notes/release-notes-0.15.2.md118
-rw-r--r--src/Makefile.am7
-rw-r--r--src/Makefile.test.include2
-rw-r--r--src/amount.h1
-rw-r--r--src/bench/ccoins_caching.cpp16
-rw-r--r--src/bitcoin-tx.cpp11
-rw-r--r--src/core_io.h11
-rw-r--r--src/core_read.cpp9
-rw-r--r--src/init.cpp2
-rw-r--r--src/net.h3
-rw-r--r--src/net_processing.cpp7
-rw-r--r--src/net_processing.h5
-rw-r--r--src/rest.cpp9
-rw-r--r--src/test/blockfilter_tests.cpp9
-rw-r--r--src/test/test_bitcoin.h2
-rw-r--r--src/utilmoneystr.cpp2
-rw-r--r--src/wallet/coinselection.h2
-rw-r--r--src/wallet/rpcwallet.cpp2
-rw-r--r--src/wallet/wallet.cpp14
-rw-r--r--test/config.ini.in2
-rw-r--r--test/functional/README.md7
-rwxr-xr-xtest/functional/p2p_segwit.py14
-rwxr-xr-xtest/functional/rpc_signrawtransaction.py9
-rwxr-xr-xtest/functional/test_framework/messages.py173
-rw-r--r--test/functional/test_framework/script.py9
-rwxr-xr-xtest/functional/test_framework/test_framework.py2
-rwxr-xr-xtest/functional/test_runner.py10
-rwxr-xr-xtest/functional/wallet_hd.py6
-rwxr-xr-xtest/lint/check-doc.py2
-rw-r--r--test/util/data/bitcoin-util-test.json60
37 files changed, 595 insertions, 129 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 84cd596bbd..d7ce2224e9 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -55,5 +55,5 @@ test_script:
- ps: src\bench_bitcoin.exe -evals=1 -scaling=0
- ps: python test\util\bitcoin-util-test.py
- cmd: python test\util\rpcauth-test.py
-- cmd: python test\functional\test_runner.py --force --quiet --combinedlogslen=4000 --exclude "wallet_multiwallet,wallet_multiwallet.py --usecli"
+- cmd: python test\functional\test_runner.py --force --quiet --combinedlogslen=4000 --exclude wallet_multiwallet
deploy: off
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000000..00d5478c4e
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,31 @@
+Pull requests without a rationale and clear improvement may be closed
+immediately.
+
+Please provide clear motivation for your patch and explain how it improves
+Bitcoin Core user experience or Bitcoin Core developer experience
+significantly.
+
+* Any test improvements or new tests that improve coverage are always welcome.
+* All other changes should have accompanying unit tests (see `src/test/`) or
+ functional tests (see `test/`). Contributors should note which tests cover
+ modified code. If no tests exist for a region of modified code, new tests
+ should accompany the change.
+* Bug fixes are most welcome when they come with steps to reproduce or an
+ explanation of the potential issue as well as reasoning for the way the bug
+ was fixed.
+* Features are welcome, but might be rejected due to design or scope issues.
+ If a feature is based on a lot of dependencies, contributors should first
+ consider building the system outside of Bitcoin Core, if possible.
+* Refactoring changes are only accepted if they are required for a feature or
+ bug fix or otherwise improve developer experience significantly. For example,
+ most "code style" refactoring changes require a thorough explanation why they
+ are useful, what downsides they have and why they *significantly* improve
+ developer experience or avoid serious programming bugs. Note that code style
+ is often a subjective matter. Unless they are explicitly mentioned to be
+ preferred in the [developer notes](/doc/developer-notes.md), stylistic code
+ changes are usually rejected.
+
+Bitcoin Core has a thorough review process and even the most trivial change
+needs to pass a lot of eyes and requires non-zero or even substantial time
+effort to review. There is a huge lack of active reviewers on the project, so
+patches often sit for a long time.
diff --git a/configure.ac b/configure.ac
index 4d84aacce1..72bd785e2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -406,6 +406,18 @@ AC_ARG_WITH([utils],
[build_bitcoin_utils=$withval],
[build_bitcoin_utils=yes])
+AC_ARG_ENABLE([util-cli],
+ [AS_HELP_STRING([--enable-util-cli],
+ [build bitcoin-cli])],
+ [build_bitcoin_cli=$enableval],
+ [build_bitcoin_cli=$build_bitcoin_utils])
+
+AC_ARG_ENABLE([util-tx],
+ [AS_HELP_STRING([--enable-util-tx],
+ [build bitcoin-tx])],
+ [build_bitcoin_tx=$enableval],
+ [build_bitcoin_tx=$build_bitcoin_utils])
+
AC_ARG_WITH([libs],
[AS_HELP_STRING([--with-libs],
[build libraries (default=yes)])],
@@ -886,7 +898,7 @@ BITCOIN_QT_INIT
dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
BITCOIN_QT_CONFIGURE([$use_pkgconfig])
-if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then
+if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnononononono; then
use_boost=no
else
use_boost=yes
@@ -1074,7 +1086,7 @@ if test x$use_pkgconfig = xyes; then
if test x$use_qr != xno; then
BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])])
fi
- if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then
+ if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests != xnonononono; then
PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)])
if test x$TARGET_OS != xwindows; then
PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads],, [AC_MSG_ERROR(libevent_pthreads not found.)])
@@ -1099,7 +1111,7 @@ else
AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),)
AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing))
- if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then
+ if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests != xnonononono; then
AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),)
AC_CHECK_LIB([event],[main],EVENT_LIBS=-levent,AC_MSG_ERROR(libevent missing))
if test x$TARGET_OS != xwindows; then
@@ -1164,7 +1176,7 @@ dnl univalue check
need_bundled_univalue=yes
-if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then
+if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnononononono; then
need_bundled_univalue=no
else
@@ -1214,9 +1226,13 @@ AC_MSG_CHECKING([whether to build bitcoind])
AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes])
AC_MSG_RESULT($build_bitcoind)
-AC_MSG_CHECKING([whether to build utils (bitcoin-cli bitcoin-tx)])
-AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes])
-AC_MSG_RESULT($build_bitcoin_utils)
+AC_MSG_CHECKING([whether to build bitcoin-cli])
+AM_CONDITIONAL([BUILD_BITCOIN_CLI], [test x$build_bitcoin_cli = xyes])
+AC_MSG_RESULT($build_bitcoin_cli)
+
+AC_MSG_CHECKING([whether to build bitcoin-tx])
+AM_CONDITIONAL([BUILD_BITCOIN_TX], [test x$build_bitcoin_tx = xyes])
+AC_MSG_RESULT($build_bitcoin_tx)
AC_MSG_CHECKING([whether to build libraries])
AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes])
@@ -1342,7 +1358,7 @@ else
AC_MSG_RESULT([no])
fi
-if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnononononono; then
+if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnonononononono; then
AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-bench or --enable-tests])
fi
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index 5286f89c30..d15f147cd7 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -120,6 +120,7 @@ define $(package)_extract_cmds
endef
define $(package)_preprocess_cmds
+ sed -i.old "s|FT_Get_Font_Format|FT_Get_X11_Font_Format|" qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp && \
sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \
sed -i.old "/updateqm.depends =/d" qttranslations/translations/translations.pro && \
sed -i.old "s/src_plugins.depends = src_sql src_network/src_plugins.depends = src_network/" qtbase/src/src.pro && \
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
index 08ff4d6ac1..9b36319e64 100644
--- a/doc/man/Makefile.am
+++ b/doc/man/Makefile.am
@@ -8,6 +8,10 @@ if ENABLE_QT
dist_man1_MANS+=bitcoin-qt.1
endif
-if BUILD_BITCOIN_UTILS
- dist_man1_MANS+=bitcoin-cli.1 bitcoin-tx.1
+if BUILD_BITCOIN_CLI
+ dist_man1_MANS+=bitcoin-cli.1
+endif
+
+if BUILD_BITCOIN_TX
+ dist_man1_MANS+=bitcoin-tx.1
endif
diff --git a/doc/release-notes-14282.md b/doc/release-notes-14282.md
new file mode 100644
index 0000000000..e6d8e0b70c
--- /dev/null
+++ b/doc/release-notes-14282.md
@@ -0,0 +1,6 @@
+Low-level RPC changes
+----------------------
+
+`-usehd` was removed in version 0.16. From that version onwards, all new
+wallets created are hierarchical deterministic wallets. Version 0.18 makes
+specifying `-usehd` invalid config.
diff --git a/doc/release-notes/release-notes-0.14.3.md b/doc/release-notes/release-notes-0.14.3.md
new file mode 100644
index 0000000000..8259152f0b
--- /dev/null
+++ b/doc/release-notes/release-notes-0.14.3.md
@@ -0,0 +1,118 @@
+Bitcoin Core version *0.14.3* is now available from:
+
+ <https://bitcoin.org/bin/bitcoin-core-0.14.3/>
+
+This is a new minor version release, including various bugfixes and
+performance improvements.
+
+Please report bugs using the issue tracker at github:
+
+ <https://github.com/bitcoin/bitcoin/issues>
+
+To receive security and update notifications, please subscribe to:
+
+ <https://bitcoincore.org/en/list/announcements/join/>
+
+Compatibility
+==============
+
+Bitcoin Core is extensively tested on multiple operating systems using
+the Linux kernel, macOS 10.8+, and Windows Vista and later.
+
+Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support),
+No attempt is made to prevent installing or running the software on Windows XP, you
+can still do so at your own risk but be aware that there are known instabilities and issues.
+Please do not report issues about Windows XP to the issue tracker.
+
+Bitcoin Core should also work on most other Unix-like systems but is not
+frequently tested on them.
+
+Notable changes
+===============
+
+Denial-of-Service vulnerability CVE-2018-17144
+ -------------------------------
+
+A denial-of-service vulnerability exploitable by miners has been discovered in
+Bitcoin Core versions 0.14.0 up to 0.16.2. It is recommended to upgrade any of
+the vulnerable versions to 0.14.3, 0.15.2 or 0.16.3 as soon as possible.
+
+Known Bugs
+==========
+
+Since 0.14.0 the approximate transaction fee shown in Bitcoin-Qt when using coin
+control and smart fee estimation does not reflect any change in target from the
+smart fee slider. It will only present an approximate fee calculated using the
+default target. The fee calculated using the correct target is still applied to
+the transaction and shown in the final send confirmation dialog.
+
+0.14.3 Change log
+=================
+
+Detailed release notes follow. This overview includes changes that affect
+behavior, not code moves, refactors and string updates. For convenience in locating
+the code changes and accompanying discussion, both the pull request and
+git merge commit are mentioned.
+
+### Consensus
+- #14247 `52965fb` Fix crash bug with duplicate inputs within a transaction (TheBlueMatt, sdaftuar)
+
+### RPC and other APIs
+
+- #10445 `87a21d5` Fix: make CCoinsViewDbCursor::Seek work for missing keys (Pieter Wuille, Gregory Maxwell)
+- #9853 Return correct error codes in setban(), fundrawtransaction(), removeprunedfunds(), bumpfee(), blockchain.cpp (John Newbery)
+
+
+### P2P protocol and network code
+
+- #10234 `d289b56` [net] listbanned RPC and QT should show correct banned subnets (John Newbery)
+
+### Build system
+
+
+### Miscellaneous
+
+- #10451 `3612219` contrib/init/bitcoind.openrcconf: Don't disable wallet by default (Luke Dashjr)
+- #10250 `e23cef0` Fix some empty vector references (Pieter Wuille)
+- #10196 `d28d583` PrioritiseTransaction updates the mempool tx counter (Suhas Daftuar)
+- #9497 `e207342` Fix CCheckQueue IsIdle (potential) race condition and remove dangerous constructors. (Jeremy Rubin)
+
+### GUI
+
+- #9481 `7abe7bb` Give fallback fee a reasonable indent (Luke Dashjr)
+- #9481 `3e4d7bf` Qt/Send: Figure a decent warning colour from theme (Luke Dashjr)
+- #9481 `e207342` Show more significant warning if we fall back to the default fee (Jonas Schnelli)
+
+### Wallet
+
+- #10308 `28b8b8b` Securely erase potentially sensitive keys/values (tjps)
+- #10265 `ff13f59` Make sure pindex is non-null before possibly referencing in LogPrintf call. (Karl-Johan Alm)
+
+Credits
+=======
+
+Thanks to everyone who directly contributed to this release:
+
+- Cory Fields
+- CryptAxe
+- fanquake
+- Jeremy Rubin
+- John Newbery
+- Jonas Schnelli
+- Gregory Maxwell
+- Karl-Johan Alm
+- Luke Dashjr
+- MarcoFalke
+- Matt Corallo
+- Mikerah
+- Pieter Wuille
+- practicalswift
+- Suhas Daftuar
+- Thomas Snider
+- Tjps
+- Wladimir J. van der Laan
+
+And to those that reported security issues:
+
+- awemany (for CVE-2018-17144, previously credited as "anonymous reporter")
+
diff --git a/doc/release-notes/release-notes-0.15.2.md b/doc/release-notes/release-notes-0.15.2.md
new file mode 100644
index 0000000000..1f58279051
--- /dev/null
+++ b/doc/release-notes/release-notes-0.15.2.md
@@ -0,0 +1,118 @@
+Bitcoin Core version *0.15.2* is now available from:
+
+ <https://bitcoincore.org/bin/bitcoin-core-0.15.2/>
+
+This is a new minor version release, including various bugfixes and
+performance improvements, as well as updated translations.
+
+Please report bugs using the issue tracker at GitHub:
+
+ <https://github.com/bitcoin/bitcoin/issues>
+
+To receive security and update notifications, please subscribe to:
+
+ <https://bitcoincore.org/en/list/announcements/join/>
+
+How to Upgrade
+==============
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on Mac)
+or `bitcoind`/`bitcoin-qt` (on Linux).
+
+The first time you run version 0.15.0 or higher, your chainstate database will
+be converted to a new format, which will take anywhere from a few minutes to
+half an hour, depending on the speed of your machine.
+
+The file format of `fee_estimates.dat` changed in version 0.15.0. Hence, a
+downgrade from version 0.15 or upgrade to version 0.15 will cause all fee
+estimates to be discarded.
+
+Note that the block database format also changed in version 0.8.0 and there is no
+automatic upgrade code from before version 0.8 to version 0.15.0. Upgrading
+directly from 0.7.x and earlier without redownloading the blockchain is not supported.
+However, as usual, old wallet versions are still supported.
+
+Downgrading warning
+-------------------
+
+The chainstate database for this release is not compatible with previous
+releases, so if you run 0.15 and then decide to switch back to any
+older version, you will need to run the old release with the `-reindex-chainstate`
+option to rebuild the chainstate data structures in the old format.
+
+If your node has pruning enabled, this will entail re-downloading and
+processing the entire blockchain.
+
+Compatibility
+==============
+
+Bitcoin Core is extensively tested on multiple operating systems using
+the Linux kernel, macOS 10.8+, and Windows Vista and later. Windows XP is not supported.
+
+Bitcoin Core should also work on most other Unix-like systems but is not
+frequently tested on them.
+
+
+Notable changes
+===============
+
+Denial-of-Service vulnerability CVE-2018-17144
+-------------------------------
+
+A denial-of-service vulnerability exploitable by miners has been discovered in
+Bitcoin Core versions 0.14.0 up to 0.16.2. It is recommended to upgrade any of
+the vulnerable versions to 0.15.2 or 0.16.3 as soon as possible.
+
+0.15.2 Change log
+=================
+
+### Build system
+
+- #11995 `9bb1a16` depends: Fix Qt build with XCode 9.2(fanquake)
+- #12946 `93b9a61` depends: Fix Qt build with XCode 9.3(fanquake)
+- #13544 `9fd3e00` depends: Update Qt download url (fanquake)
+- #11847 `cb7ef31` Make boost::multi_index comparators const (sdaftuar)
+
+### Consensus
+- #14247 `4b8a3f5` Fix crash bug with duplicate inputs within a transaction (TheBlueMatt, sdaftuar)
+
+### RPC
+- #11676 `7af2457` contrib/init: Update openrc-run filename (Luke Dashjr)
+- #11277 `7026845` Fix uninitialized URI in batch RPC requests (Russell Yanofsky)
+
+### Wallet
+- #11289 `3f1db56` Wrap dumpwallet warning and note scripts aren't dumped (MeshCollider)
+- #11289 `42ea47d` Add wallet backup text to import*, add* and dumpwallet RPCs (MeshCollider)
+- #11590 `6372a75` [Wallet] always show help-line of wallet encryption calls (Jonas Schnelli)
+
+### bitcoin-tx
+
+- #11554 `a69cc07` Sanity-check script sizes in bitcoin-tx (TheBlueMatt)
+
+### Tests
+- #11277 `3a6cdd4` Add test for multiwallet batch RPC calls (Russell Yanofsky)
+- #11647 `1c8c7f8` Add missing batch rpc calls to python coverage logs (Russell Yanofsky)
+- #11277 `1036c43` Add missing multiwallet rpc calls to python coverage logs (Russell Yanofsky)
+- #11277 `305f768` Limit AuthServiceProxyWrapper.\_\_getattr\_\_ wrapping (Russell Yanofsky)
+- #11277 `2eea279` Make AuthServiceProxy.\_batch method usable (Russell Yanofsky)
+
+Credits
+=======
+
+Thanks to everyone who directly contributed to this release:
+
+- fanquake
+- Jonas Schnelli
+- Luke Dashjr
+- Matt Corallo
+- MeshCollider
+- Russell Yanofsky
+- Suhas Daftuar
+- Wladimir J. van der Laan
+
+And to those that reported security issues:
+
+- awemany (for CVE-2018-17144, previously credited as "anonymous reporter")
+
diff --git a/src/Makefile.am b/src/Makefile.am
index a1b9b4cb82..7a2e9fa5e8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -83,8 +83,11 @@ if BUILD_BITCOIND
bin_PROGRAMS += bitcoind
endif
-if BUILD_BITCOIN_UTILS
- bin_PROGRAMS += bitcoin-cli bitcoin-tx
+if BUILD_BITCOIN_CLI
+ bin_PROGRAMS += bitcoin-cli
+endif
+if BUILD_BITCOIN_TX
+ bin_PROGRAMS += bitcoin-tx
endif
.PHONY: FORCE check-symbols check-security
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 269a6ff805..8a537ed4f6 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -174,8 +174,10 @@ bitcoin_test_clean : FORCE
rm -f $(CLEAN_BITCOIN_TEST) $(test_test_bitcoin_OBJECTS) $(TEST_BINARY)
check-local: $(BITCOIN_TESTS:.cpp=.cpp.test)
+if BUILD_BITCOIN_TX
@echo "Running test/util/bitcoin-util-test.py..."
$(PYTHON) $(top_builddir)/test/util/bitcoin-util-test.py
+endif
@echo "Running test/util/rpcauth-test.py..."
$(PYTHON) $(top_builddir)/test/util/rpcauth-test.py
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
diff --git a/src/amount.h b/src/amount.h
index 2bd367cba2..449fd1b15f 100644
--- a/src/amount.h
+++ b/src/amount.h
@@ -12,7 +12,6 @@
typedef int64_t CAmount;
static const CAmount COIN = 100000000;
-static const CAmount CENT = 1000000;
/** No amount larger than this (in satoshi) is valid.
*
diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp
index db303eeead..b8d82c0a89 100644
--- a/src/bench/ccoins_caching.cpp
+++ b/src/bench/ccoins_caching.cpp
@@ -12,8 +12,8 @@
// FIXME: Dedup with SetupDummyInputs in test/transaction_tests.cpp.
//
// Helper: create two dummy transactions, each with
-// two outputs. The first has 11 and 50 CENT outputs
-// paid to a TX_PUBKEY, the second 21 and 22 CENT outputs
+// two outputs. The first has 11 and 50 COIN outputs
+// paid to a TX_PUBKEY, the second 21 and 22 COIN outputs
// paid to a TX_PUBKEYHASH.
//
static std::vector<CMutableTransaction>
@@ -31,16 +31,16 @@ SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsViewCache& coinsRet)
// Create some dummy input transactions
dummyTransactions[0].vout.resize(2);
- dummyTransactions[0].vout[0].nValue = 11 * CENT;
+ dummyTransactions[0].vout[0].nValue = 11 * COIN;
dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
- dummyTransactions[0].vout[1].nValue = 50 * CENT;
+ dummyTransactions[0].vout[1].nValue = 50 * COIN;
dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
AddCoins(coinsRet, dummyTransactions[0], 0);
dummyTransactions[1].vout.resize(2);
- dummyTransactions[1].vout[0].nValue = 21 * CENT;
+ dummyTransactions[1].vout[0].nValue = 21 * COIN;
dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID());
- dummyTransactions[1].vout[1].nValue = 22 * CENT;
+ dummyTransactions[1].vout[1].nValue = 22 * COIN;
dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID());
AddCoins(coinsRet, dummyTransactions[1], 0);
@@ -72,7 +72,7 @@ static void CCoinsCaching(benchmark::State& state)
t1.vin[2].prevout.n = 1;
t1.vin[2].scriptSig << std::vector<unsigned char>(65, 0) << std::vector<unsigned char>(33, 4);
t1.vout.resize(2);
- t1.vout[0].nValue = 90 * CENT;
+ t1.vout[0].nValue = 90 * COIN;
t1.vout[0].scriptPubKey << OP_1;
// Benchmark.
@@ -80,7 +80,7 @@ static void CCoinsCaching(benchmark::State& state)
bool success = AreInputsStandard(t1, coins);
assert(success);
CAmount value = coins.GetValueIn(t1);
- assert(value == (50 + 21 + 22) * CENT);
+ assert(value == (50 + 21 + 22) * COIN);
}
}
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 9ee3e8eee7..a3fcb87675 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -240,10 +240,10 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu
throw std::runtime_error("TX input missing separator");
// extract and validate TXID
- std::string strTxid = vStrInputParts[0];
- if ((strTxid.size() != 64) || !IsHex(strTxid))
+ uint256 txid;
+ if (!ParseHashStr(vStrInputParts[0], txid)) {
throw std::runtime_error("invalid TX input txid");
- uint256 txid(uint256S(strTxid));
+ }
static const unsigned int minTxOutSz = 9;
static const unsigned int maxVout = MAX_BLOCK_WEIGHT / (WITNESS_SCALE_FACTOR * minTxOutSz);
@@ -590,7 +590,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
if (!prevOut.checkObject(types))
throw std::runtime_error("prevtxs internal object typecheck fail");
- uint256 txid = ParseHashStr(prevOut["txid"].get_str(), "txid");
+ uint256 txid;
+ if (!ParseHashStr(prevOut["txid"].get_str(), txid)) {
+ throw std::runtime_error("txid must be hexadecimal string (not '" + prevOut["txid"].get_str() + "')");
+ }
const int nOut = prevOut["vout"].get_int();
if (nOut < 0)
diff --git a/src/core_io.h b/src/core_io.h
index d53a45c0cb..2c3b64d81e 100644
--- a/src/core_io.h
+++ b/src/core_io.h
@@ -25,7 +25,16 @@ std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDeco
bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness = false, bool try_witness = true);
bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
-uint256 ParseHashStr(const std::string&, const std::string& strName);
+
+/**
+ * Parse a hex string into 256 bits
+ * @param[in] strHex a hex-formatted, 64-character string
+ * @param[out] result the result of the parasing
+ * @returns true if successful, false if not
+ *
+ * @see ParseHashV for an RPC-oriented version of this
+ */
+bool ParseHashStr(const std::string& strHex, uint256& result);
std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error);
int ParseSighashString(const UniValue& sighash);
diff --git a/src/core_read.cpp b/src/core_read.cpp
index b02016c014..301f99bc1c 100644
--- a/src/core_read.cpp
+++ b/src/core_read.cpp
@@ -193,14 +193,13 @@ bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx,
return true;
}
-uint256 ParseHashStr(const std::string& strHex, const std::string& strName)
+bool ParseHashStr(const std::string& strHex, uint256& result)
{
- if (!IsHex(strHex)) // Note: IsHex("") is false
- throw std::runtime_error(strName + " must be hexadecimal string (not '" + strHex + "')");
+ if ((strHex.size() != 64) || !IsHex(strHex))
+ return false;
- uint256 result;
result.SetHex(strHex);
- return result;
+ return true;
}
std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName)
diff --git a/src/init.cpp b/src/init.cpp
index 00d97629f7..f9efaf7dc1 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -323,7 +323,7 @@ void SetupServerArgs()
// Hidden Options
std::vector<std::string> hidden_args = {"-h", "-help",
- "-dbcrashratio", "-forcecompactdb", "-usehd",
+ "-dbcrashratio", "-forcecompactdb",
// GUI args. These will be overwritten by SetupUIArgs for the GUI
"-allowselfsignedrootcertificates", "-choosedatadir", "-lang=<lang>", "-min", "-resetguisettings", "-rootcertificates=<file>", "-splash", "-uiplatform"};
diff --git a/src/net.h b/src/net.h
index 9f6c426ab7..c43429c7f3 100644
--- a/src/net.h
+++ b/src/net.h
@@ -149,6 +149,7 @@ public:
nLocalServices = connOptions.nLocalServices;
nMaxConnections = connOptions.nMaxConnections;
nMaxOutbound = std::min(connOptions.nMaxOutbound, connOptions.nMaxConnections);
+ m_use_addrman_outgoing = connOptions.m_use_addrman_outgoing;
nMaxAddnode = connOptions.nMaxAddnode;
nMaxFeeler = connOptions.nMaxFeeler;
nBestHeight = connOptions.nBestHeight;
@@ -174,6 +175,7 @@ public:
void Stop();
void Interrupt();
bool GetNetworkActive() const { return fNetworkActive; };
+ bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; };
void SetNetworkActive(bool active);
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, bool fOneShot = false, bool fFeeler = false, bool manual_connection = false);
bool CheckIncomingNonce(uint64_t nonce);
@@ -416,6 +418,7 @@ private:
int nMaxOutbound;
int nMaxAddnode;
int nMaxFeeler;
+ bool m_use_addrman_outgoing;
std::atomic<int> nBestHeight;
CClientUIInterface* clientInterface;
NetEventsInterface* m_msgproc;
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index b48a3bd221..a1b6e021ae 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -3144,8 +3144,6 @@ void PeerLogicValidation::EvictExtraOutboundPeers(int64_t time_in_seconds)
NodeId worst_peer = -1;
int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
- LOCK(cs_main);
-
connman->ForEachNode([&](CNode* pnode) {
AssertLockHeld(cs_main);
@@ -3193,6 +3191,8 @@ void PeerLogicValidation::EvictExtraOutboundPeers(int64_t time_in_seconds)
void PeerLogicValidation::CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams)
{
+ LOCK(cs_main);
+
if (connman == nullptr) return;
int64_t time_in_seconds = GetTime();
@@ -3200,10 +3200,9 @@ void PeerLogicValidation::CheckForStaleTipAndEvictPeers(const Consensus::Params
EvictExtraOutboundPeers(time_in_seconds);
if (time_in_seconds > m_stale_tip_check_time) {
- LOCK(cs_main);
// Check whether our tip is stale, and if so, allow using an extra
// outbound peer
- if (TipMayBeStale(consensusParams)) {
+ if (!fImporting && !fReindex && connman->GetNetworkActive() && connman->GetUseAddrmanOutgoing() && TipMayBeStale(consensusParams)) {
LogPrintf("Potential stale tip detected, will try using extra outbound peer (last tip update: %d seconds ago)\n", time_in_seconds - g_last_tip_update);
connman->SetTryNewOutboundPeer(true);
} else if (connman->GetTryNewOutboundPeer()) {
diff --git a/src/net_processing.h b/src/net_processing.h
index 04904399dd..0113e25f7e 100644
--- a/src/net_processing.h
+++ b/src/net_processing.h
@@ -9,6 +9,9 @@
#include <net.h>
#include <validationinterface.h>
#include <consensus/params.h>
+#include <sync.h>
+
+extern CCriticalSection cs_main;
/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
@@ -65,7 +68,7 @@ public:
/** Evict extra outbound peers. If we think our tip may be stale, connect to an extra outbound */
void CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams);
/** If we have extra outbound peers, try to disconnect the one with the oldest block announcement */
- void EvictExtraOutboundPeers(int64_t time_in_seconds);
+ void EvictExtraOutboundPeers(int64_t time_in_seconds) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
private:
int64_t m_stale_tip_check_time; //!< Next time to check for stale tip
diff --git a/src/rest.cpp b/src/rest.cpp
index 7792844992..1850c0b7a6 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -105,15 +105,6 @@ static std::string AvailableDataFormatsString()
return formats;
}
-static bool ParseHashStr(const std::string& strReq, uint256& v)
-{
- if (!IsHex(strReq) || (strReq.size() != 64))
- return false;
-
- v.SetHex(strReq);
- return true;
-}
-
static bool CheckWarmup(HTTPRequest* req)
{
std::string statusmessage;
diff --git a/src/test/blockfilter_tests.cpp b/src/test/blockfilter_tests.cpp
index 773de343ea..4941ebd483 100644
--- a/src/test/blockfilter_tests.cpp
+++ b/src/test/blockfilter_tests.cpp
@@ -114,7 +114,8 @@ BOOST_AUTO_TEST_CASE(blockfilters_json_test)
unsigned int pos = 0;
/*int block_height =*/ test[pos++].get_int();
- /*uint256 block_hash =*/ ParseHashStr(test[pos++].get_str(), "block_hash");
+ uint256 block_hash;
+ BOOST_CHECK(ParseHashStr(test[pos++].get_str(), block_hash));
CBlock block;
BOOST_REQUIRE(DecodeHexBlk(block, test[pos++].get_str()));
@@ -129,9 +130,11 @@ BOOST_AUTO_TEST_CASE(blockfilters_json_test)
tx_undo.vprevout.emplace_back(txout, 0, false);
}
- uint256 prev_filter_header_basic = ParseHashStr(test[pos++].get_str(), "prev_filter_header_basic");
+ uint256 prev_filter_header_basic;
+ BOOST_CHECK(ParseHashStr(test[pos++].get_str(), prev_filter_header_basic));
std::vector<unsigned char> filter_basic = ParseHex(test[pos++].get_str());
- uint256 filter_header_basic = ParseHashStr(test[pos++].get_str(), "filter_header_basic");
+ uint256 filter_header_basic;
+ BOOST_CHECK(ParseHashStr(test[pos++].get_str(), filter_header_basic));
BlockFilter computed_filter_basic(BlockFilterType::BASIC, block, block_undo);
BOOST_CHECK(computed_filter_basic.GetFilter().GetEncoded() == filter_basic);
diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h
index b87d9bea5d..3872767133 100644
--- a/src/test/test_bitcoin.h
+++ b/src/test/test_bitcoin.h
@@ -37,6 +37,8 @@ static inline uint64_t InsecureRandBits(int bits) { return insecure_rand_ctx.ran
static inline uint64_t InsecureRandRange(uint64_t range) { return insecure_rand_ctx.randrange(range); }
static inline bool InsecureRandBool() { return insecure_rand_ctx.randbool(); }
+static constexpr CAmount CENT{1000000};
+
/** Basic testing setup.
* This just configures logging and chain parameters.
*/
diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp
index a9af59a11d..326ef9b27a 100644
--- a/src/utilmoneystr.cpp
+++ b/src/utilmoneystr.cpp
@@ -48,7 +48,7 @@ bool ParseMoney(const char* pszIn, CAmount& nRet)
if (*p == '.')
{
p++;
- int64_t nMult = CENT*10;
+ int64_t nMult = COIN / 10;
while (isdigit(*p) && (nMult > 0))
{
nUnits += nMult * (*p++ - '0');
diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h
index 6d755d0969..5348401f45 100644
--- a/src/wallet/coinselection.h
+++ b/src/wallet/coinselection.h
@@ -10,7 +10,7 @@
#include <random.h>
//! target minimum change amount
-static const CAmount MIN_CHANGE = CENT;
+static constexpr CAmount MIN_CHANGE{COIN / 100};
//! final minimum change amount after paying for fees
static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE/2;
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index cca50a4ee4..7d0219201e 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -3109,6 +3109,8 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request)
// Sign the transaction
LOCK2(cs_main, pwallet->cs_wallet);
+ EnsureWalletIsUnlocked(pwallet);
+
return SignTransaction(mtx, request.params[1], pwallet, false, request.params[2]);
}
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 678d8ddd4d..afe47d986e 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -3989,10 +3989,6 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(const std::string& name,
if (fFirstRun)
{
// ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key
- if (!gArgs.GetBoolArg("-usehd", true)) {
- InitError(strprintf(_("Error creating %s: You can't create non-HD wallets with this version."), walletFile));
- return nullptr;
- }
walletInstance->SetMinVersion(FEATURE_LATEST);
if ((wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
@@ -4020,16 +4016,6 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(const std::string& name,
if (!walletInstance->mapKeys.empty() || !walletInstance->mapCryptedKeys.empty()) {
InitWarning(strprintf(_("Warning: Private keys detected in wallet {%s} with disabled private keys"), walletFile));
}
- } else if (gArgs.IsArgSet("-usehd")) {
- bool useHD = gArgs.GetBoolArg("-usehd", true);
- if (walletInstance->IsHDEnabled() && !useHD) {
- InitError(strprintf(_("Error loading %s: You can't disable HD on an already existing HD wallet"), walletFile));
- return nullptr;
- }
- if (!walletInstance->IsHDEnabled() && useHD) {
- InitError(strprintf(_("Error loading %s: You can't enable HD on an already existing non-HD wallet"), walletFile));
- return nullptr;
- }
}
if (!gArgs.GetArg("-addresstype", "").empty() && !ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
diff --git a/test/config.ini.in b/test/config.ini.in
index a1119dc739..28abee2a3d 100644
--- a/test/config.ini.in
+++ b/test/config.ini.in
@@ -14,6 +14,6 @@ RPCAUTH=@abs_top_srcdir@/share/rpcauth/rpcauth.py
[components]
# Which components are enabled. These are commented out by `configure` if they were disabled when running config.
@ENABLE_WALLET_TRUE@ENABLE_WALLET=true
-@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=true
+@BUILD_BITCOIN_CLI_TRUE@ENABLE_CLI=true
@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=true
@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=true
diff --git a/test/functional/README.md b/test/functional/README.md
index 6929ab5991..d40052ac93 100644
--- a/test/functional/README.md
+++ b/test/functional/README.md
@@ -60,6 +60,11 @@ don't have test cases for.
- When calling RPCs with lots of arguments, consider using named keyword
arguments instead of positional arguments to make the intent of the call
clear to readers.
+- Many of the core test framework classes such as `CBlock` and `CTransaction`
+ don't allow new attributes to be added to their objects at runtime like
+ typical Python objects allow. This helps prevent unpredictable side effects
+ from typographical errors or usage of the objects outside of their intended
+ purpose.
#### RPC and P2P definitions
@@ -72,7 +77,7 @@ P2P messages. These can be found in the following source files:
#### Using the P2P interface
-- `mininode.py` contains all the definitions for objects that pass
+- `messages.py` contains all the definitions for objects that pass
over the network (`CBlock`, `CTransaction`, etc, along with the network-level
wrappers for them, `msg_block`, `msg_tx`, etc).
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index de12ab1ed6..afbbfa8992 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -205,7 +205,7 @@ class SegWitTest(BitcoinTestFramework):
height = self.nodes[0].getblockcount() + 1
block_time = self.nodes[0].getblockheader(tip)["mediantime"] + 1
block = create_block(int(tip, 16), create_coinbase(height), block_time)
- block.version = version
+ block.nVersion = version
block.rehash()
return block
@@ -769,12 +769,16 @@ class SegWitTest(BitcoinTestFramework):
# will require a witness to spend a witness program regardless of
# segwit activation. Note that older bitcoind's that are not
# segwit-aware would also reject this for failing CLEANSTACK.
- test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False)
+ with self.nodes[0].assert_debug_log(
+ expected_msgs=(spend_tx.hash, 'was not accepted: non-mandatory-script-verify-flag (Witness program was passed an empty witness)')):
+ test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False)
- # Try to put the witness script in the script_sig, should also fail.
- spend_tx.vin[0].script_sig = CScript([p2wsh_pubkey, b'a'])
+ # Try to put the witness script in the scriptSig, should also fail.
+ spend_tx.vin[0].scriptSig = CScript([p2wsh_pubkey, b'a'])
spend_tx.rehash()
- test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False)
+ with self.nodes[0].assert_debug_log(
+ expected_msgs=('Not relaying invalid transaction {}'.format(spend_tx.hash), 'was not accepted: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)')):
+ test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False)
# Now put the witness script in the witness, should succeed after
# segwit activates.
diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/rpc_signrawtransaction.py
index 5c07f2ccae..291538df64 100755
--- a/test/functional/rpc_signrawtransaction.py
+++ b/test/functional/rpc_signrawtransaction.py
@@ -45,6 +45,14 @@ class SignRawTransactionsTest(BitcoinTestFramework):
# 2) No script verification error occurred
assert 'errors' not in rawTxSigned
+ def test_with_lock_outputs(self):
+ """Test correct error reporting when trying to sign a locked output"""
+ self.nodes[0].encryptwallet("password")
+
+ rawTx = '020000000156b958f78e3f24e0b2f4e4db1255426b0902027cb37e3ddadb52e37c3557dddb0000000000ffffffff01c0a6b929010000001600149a2ee8c77140a053f36018ac8124a6ececc1668a00000000'
+
+ assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first", self.nodes[0].signrawtransactionwithwallet, rawTx)
+
def script_verification_error_test(self):
"""Create and sign a raw transaction with valid (vin 0), invalid (vin 1) and one missing (vin 2) input script.
@@ -138,6 +146,7 @@ class SignRawTransactionsTest(BitcoinTestFramework):
def run_test(self):
self.successful_signing_test()
self.script_verification_error_test()
+ self.test_with_lock_outputs()
if __name__ == '__main__':
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 0a3907cba4..8e9372767d 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -13,7 +13,11 @@ CBlock, CTransaction, CBlockHeader, CTxIn, CTxOut, etc....:
msg_block, msg_tx, msg_headers, etc.:
data structures that represent network messages
-ser_*, deser_*: functions that handle serialization/deserialization."""
+ser_*, deser_*: functions that handle serialization/deserialization.
+
+Classes use __slots__ to ensure extraneous attributes aren't accidentally added
+by tests, compromising their intended effect.
+"""
from codecs import encode
import copy
import hashlib
@@ -185,7 +189,10 @@ def ToHex(obj):
# Objects that map to bitcoind objects, which can be serialized/deserialized
-class CAddress():
+
+class CAddress:
+ __slots__ = ("ip", "nServices", "pchReserved", "port", "time")
+
def __init__(self):
self.time = 0
self.nServices = 1
@@ -215,7 +222,10 @@ class CAddress():
return "CAddress(nServices=%i ip=%s port=%i)" % (self.nServices,
self.ip, self.port)
-class CInv():
+
+class CInv:
+ __slots__ = ("hash", "type")
+
typemap = {
0: "Error",
1: "TX",
@@ -244,7 +254,9 @@ class CInv():
% (self.typemap[self.type], self.hash)
-class CBlockLocator():
+class CBlockLocator:
+ __slots__ = ("nVersion", "vHave")
+
def __init__(self):
self.nVersion = MY_VERSION
self.vHave = []
@@ -264,7 +276,9 @@ class CBlockLocator():
% (self.nVersion, repr(self.vHave))
-class COutPoint():
+class COutPoint:
+ __slots__ = ("hash", "n")
+
def __init__(self, hash=0, n=0):
self.hash = hash
self.n = n
@@ -283,7 +297,9 @@ class COutPoint():
return "COutPoint(hash=%064x n=%i)" % (self.hash, self.n)
-class CTxIn():
+class CTxIn:
+ __slots__ = ("nSequence", "prevout", "scriptSig")
+
def __init__(self, outpoint=None, scriptSig=b"", nSequence=0):
if outpoint is None:
self.prevout = COutPoint()
@@ -311,7 +327,9 @@ class CTxIn():
self.nSequence)
-class CTxOut():
+class CTxOut:
+ __slots__ = ("nValue", "scriptPubKey")
+
def __init__(self, nValue=0, scriptPubKey=b""):
self.nValue = nValue
self.scriptPubKey = scriptPubKey
@@ -332,7 +350,9 @@ class CTxOut():
bytes_to_hex_str(self.scriptPubKey))
-class CScriptWitness():
+class CScriptWitness:
+ __slots__ = ("stack",)
+
def __init__(self):
# stack is a vector of strings
self.stack = []
@@ -347,7 +367,9 @@ class CScriptWitness():
return True
-class CTxInWitness():
+class CTxInWitness:
+ __slots__ = ("scriptWitness",)
+
def __init__(self):
self.scriptWitness = CScriptWitness()
@@ -364,7 +386,9 @@ class CTxInWitness():
return self.scriptWitness.is_null()
-class CTxWitness():
+class CTxWitness:
+ __slots__ = ("vtxinwit",)
+
def __init__(self):
self.vtxinwit = []
@@ -392,7 +416,10 @@ class CTxWitness():
return True
-class CTransaction():
+class CTransaction:
+ __slots__ = ("hash", "nLockTime", "nVersion", "sha256", "vin", "vout",
+ "wit")
+
def __init__(self, tx=None):
if tx is None:
self.nVersion = 1
@@ -496,7 +523,10 @@ class CTransaction():
% (self.nVersion, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime)
-class CBlockHeader():
+class CBlockHeader:
+ __slots__ = ("hash", "hashMerkleRoot", "hashPrevBlock", "nBits", "nNonce",
+ "nTime", "nVersion", "sha256")
+
def __init__(self, header=None):
if header is None:
self.set_null()
@@ -565,6 +595,8 @@ class CBlockHeader():
class CBlock(CBlockHeader):
+ __slots__ = ("vtx",)
+
def __init__(self, header=None):
super(CBlock, self).__init__(header)
self.vtx = []
@@ -636,7 +668,9 @@ class CBlock(CBlockHeader):
time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx))
-class PrefilledTransaction():
+class PrefilledTransaction:
+ __slots__ = ("index", "tx")
+
def __init__(self, index=0, tx = None):
self.index = index
self.tx = tx
@@ -664,8 +698,12 @@ class PrefilledTransaction():
def __repr__(self):
return "PrefilledTransaction(index=%d, tx=%s)" % (self.index, repr(self.tx))
+
# This is what we send on the wire, in a cmpctblock message.
-class P2PHeaderAndShortIDs():
+class P2PHeaderAndShortIDs:
+ __slots__ = ("header", "nonce", "prefilled_txn", "prefilled_txn_length",
+ "shortids", "shortids_length")
+
def __init__(self):
self.header = CBlockHeader()
self.nonce = 0
@@ -703,9 +741,11 @@ class P2PHeaderAndShortIDs():
def __repr__(self):
return "P2PHeaderAndShortIDs(header=%s, nonce=%d, shortids_length=%d, shortids=%s, prefilled_txn_length=%d, prefilledtxn=%s" % (repr(self.header), self.nonce, self.shortids_length, repr(self.shortids), self.prefilled_txn_length, repr(self.prefilled_txn))
+
# P2P version of the above that will use witness serialization (for compact
# block version 2)
class P2PHeaderAndShortWitnessIDs(P2PHeaderAndShortIDs):
+ __slots__ = ()
def serialize(self):
return super(P2PHeaderAndShortWitnessIDs, self).serialize(with_witness=True)
@@ -715,9 +755,12 @@ def calculate_shortid(k0, k1, tx_hash):
expected_shortid &= 0x0000ffffffffffff
return expected_shortid
+
# This version gets rid of the array lengths, and reinterprets the differential
# encoding into indices that can be used for lookup.
-class HeaderAndShortIDs():
+class HeaderAndShortIDs:
+ __slots__ = ("header", "nonce", "prefilled_txn", "shortids", "use_witness")
+
def __init__(self, p2pheaders_and_shortids = None):
self.header = CBlockHeader()
self.nonce = 0
@@ -778,7 +821,8 @@ class HeaderAndShortIDs():
return "HeaderAndShortIDs(header=%s, nonce=%d, shortids=%s, prefilledtxn=%s" % (repr(self.header), self.nonce, repr(self.shortids), repr(self.prefilled_txn))
-class BlockTransactionsRequest():
+class BlockTransactionsRequest:
+ __slots__ = ("blockhash", "indexes")
def __init__(self, blockhash=0, indexes = None):
self.blockhash = blockhash
@@ -818,7 +862,8 @@ class BlockTransactionsRequest():
return "BlockTransactionsRequest(hash=%064x indexes=%s)" % (self.blockhash, repr(self.indexes))
-class BlockTransactions():
+class BlockTransactions:
+ __slots__ = ("blockhash", "transactions")
def __init__(self, blockhash=0, transactions = None):
self.blockhash = blockhash
@@ -840,7 +885,10 @@ class BlockTransactions():
def __repr__(self):
return "BlockTransactions(hash=%064x transactions=%s)" % (self.blockhash, repr(self.transactions))
-class CPartialMerkleTree():
+
+class CPartialMerkleTree:
+ __slots__ = ("fBad", "nTransactions", "vBits", "vHash")
+
def __init__(self):
self.nTransactions = 0
self.vHash = []
@@ -868,7 +916,10 @@ class CPartialMerkleTree():
def __repr__(self):
return "CPartialMerkleTree(nTransactions=%d, vHash=%s, vBits=%s)" % (self.nTransactions, repr(self.vHash), repr(self.vBits))
-class CMerkleBlock():
+
+class CMerkleBlock:
+ __slots__ = ("header", "txn")
+
def __init__(self):
self.header = CBlockHeader()
self.txn = CPartialMerkleTree()
@@ -888,7 +939,9 @@ class CMerkleBlock():
# Objects that correspond to messages on the wire
-class msg_version():
+class msg_version:
+ __slots__ = ("addrFrom", "addrTo", "nNonce", "nRelay", "nServices",
+ "nStartingHeight", "nTime", "nVersion", "strSubVer")
command = b"version"
def __init__(self):
@@ -945,7 +998,8 @@ class msg_version():
self.strSubVer, self.nStartingHeight, self.nRelay)
-class msg_verack():
+class msg_verack:
+ __slots__ = ()
command = b"verack"
def __init__(self):
@@ -961,7 +1015,8 @@ class msg_verack():
return "msg_verack()"
-class msg_addr():
+class msg_addr:
+ __slots__ = ("addrs",)
command = b"addr"
def __init__(self):
@@ -977,7 +1032,8 @@ class msg_addr():
return "msg_addr(addrs=%s)" % (repr(self.addrs))
-class msg_inv():
+class msg_inv:
+ __slots__ = ("inv",)
command = b"inv"
def __init__(self, inv=None):
@@ -996,7 +1052,8 @@ class msg_inv():
return "msg_inv(inv=%s)" % (repr(self.inv))
-class msg_getdata():
+class msg_getdata:
+ __slots__ = ("inv",)
command = b"getdata"
def __init__(self, inv=None):
@@ -1012,7 +1069,8 @@ class msg_getdata():
return "msg_getdata(inv=%s)" % (repr(self.inv))
-class msg_getblocks():
+class msg_getblocks:
+ __slots__ = ("locator", "hashstop")
command = b"getblocks"
def __init__(self):
@@ -1035,7 +1093,8 @@ class msg_getblocks():
% (repr(self.locator), self.hashstop)
-class msg_tx():
+class msg_tx:
+ __slots__ = ("tx",)
command = b"tx"
def __init__(self, tx=CTransaction()):
@@ -1050,13 +1109,16 @@ class msg_tx():
def __repr__(self):
return "msg_tx(tx=%s)" % (repr(self.tx))
+
class msg_witness_tx(msg_tx):
+ __slots__ = ()
def serialize(self):
return self.tx.serialize_with_witness()
-class msg_block():
+class msg_block:
+ __slots__ = ("block",)
command = b"block"
def __init__(self, block=None):
@@ -1074,9 +1136,12 @@ class msg_block():
def __repr__(self):
return "msg_block(block=%s)" % (repr(self.block))
+
# for cases where a user needs tighter control over what is sent over the wire
# note that the user must supply the name of the command, and the data
-class msg_generic():
+class msg_generic:
+ __slots__ = ("command", "data")
+
def __init__(self, command, data=None):
self.command = command
self.data = data
@@ -1087,13 +1152,16 @@ class msg_generic():
def __repr__(self):
return "msg_generic()"
-class msg_witness_block(msg_block):
+class msg_witness_block(msg_block):
+ __slots__ = ()
def serialize(self):
r = self.block.serialize(with_witness=True)
return r
-class msg_getaddr():
+
+class msg_getaddr:
+ __slots__ = ()
command = b"getaddr"
def __init__(self):
@@ -1109,7 +1177,8 @@ class msg_getaddr():
return "msg_getaddr()"
-class msg_ping():
+class msg_ping:
+ __slots__ = ("nonce",)
command = b"ping"
def __init__(self, nonce=0):
@@ -1127,7 +1196,8 @@ class msg_ping():
return "msg_ping(nonce=%08x)" % self.nonce
-class msg_pong():
+class msg_pong:
+ __slots__ = ("nonce",)
command = b"pong"
def __init__(self, nonce=0):
@@ -1145,7 +1215,8 @@ class msg_pong():
return "msg_pong(nonce=%08x)" % self.nonce
-class msg_mempool():
+class msg_mempool:
+ __slots__ = ()
command = b"mempool"
def __init__(self):
@@ -1160,7 +1231,9 @@ class msg_mempool():
def __repr__(self):
return "msg_mempool()"
-class msg_sendheaders():
+
+class msg_sendheaders:
+ __slots__ = ()
command = b"sendheaders"
def __init__(self):
@@ -1180,7 +1253,8 @@ class msg_sendheaders():
# number of entries
# vector of hashes
# hash_stop (hash of last desired block header, 0 to get as many as possible)
-class msg_getheaders():
+class msg_getheaders:
+ __slots__ = ("hashstop", "locator",)
command = b"getheaders"
def __init__(self):
@@ -1205,7 +1279,8 @@ class msg_getheaders():
# headers message has
# <count> <vector of block headers>
-class msg_headers():
+class msg_headers:
+ __slots__ = ("headers",)
command = b"headers"
def __init__(self, headers=None):
@@ -1225,7 +1300,8 @@ class msg_headers():
return "msg_headers(headers=%s)" % repr(self.headers)
-class msg_reject():
+class msg_reject:
+ __slots__ = ("code", "data", "message", "reason")
command = b"reject"
REJECT_MALFORMED = 1
@@ -1256,7 +1332,9 @@ class msg_reject():
return "msg_reject: %s %d %s [%064x]" \
% (self.message, self.code, self.reason, self.data)
-class msg_feefilter():
+
+class msg_feefilter:
+ __slots__ = ("feerate",)
command = b"feefilter"
def __init__(self, feerate=0):
@@ -1273,7 +1351,9 @@ class msg_feefilter():
def __repr__(self):
return "msg_feefilter(feerate=%08x)" % self.feerate
-class msg_sendcmpct():
+
+class msg_sendcmpct:
+ __slots__ = ("announce", "version")
command = b"sendcmpct"
def __init__(self):
@@ -1293,7 +1373,9 @@ class msg_sendcmpct():
def __repr__(self):
return "msg_sendcmpct(announce=%s, version=%lu)" % (self.announce, self.version)
-class msg_cmpctblock():
+
+class msg_cmpctblock:
+ __slots__ = ("header_and_shortids",)
command = b"cmpctblock"
def __init__(self, header_and_shortids = None):
@@ -1311,7 +1393,9 @@ class msg_cmpctblock():
def __repr__(self):
return "msg_cmpctblock(HeaderAndShortIDs=%s)" % repr(self.header_and_shortids)
-class msg_getblocktxn():
+
+class msg_getblocktxn:
+ __slots__ = ("block_txn_request",)
command = b"getblocktxn"
def __init__(self):
@@ -1329,7 +1413,9 @@ class msg_getblocktxn():
def __repr__(self):
return "msg_getblocktxn(block_txn_request=%s)" % (repr(self.block_txn_request))
-class msg_blocktxn():
+
+class msg_blocktxn:
+ __slots__ = ("block_transactions",)
command = b"blocktxn"
def __init__(self):
@@ -1346,7 +1432,10 @@ class msg_blocktxn():
def __repr__(self):
return "msg_blocktxn(block_transactions=%s)" % (repr(self.block_transactions))
+
class msg_witness_blocktxn(msg_blocktxn):
+ __slots__ = ()
+
def serialize(self):
r = b""
r += self.block_transactions.serialize(with_witness=True)
diff --git a/test/functional/test_framework/script.py b/test/functional/test_framework/script.py
index 375d6334f7..2fe44010ba 100644
--- a/test/functional/test_framework/script.py
+++ b/test/functional/test_framework/script.py
@@ -26,7 +26,7 @@ def hash160(s):
_opcode_instances = []
class CScriptOp(int):
"""A single script opcode"""
- __slots__ = []
+ __slots__ = ()
@staticmethod
def encode_op_pushdata(d):
@@ -361,8 +361,11 @@ class CScriptTruncatedPushDataError(CScriptInvalidError):
self.data = data
super(CScriptTruncatedPushDataError, self).__init__(msg)
+
# This is used, eg, for blockchain heights in coinbase scripts (bip34)
-class CScriptNum():
+class CScriptNum:
+ __slots__ = ("value",)
+
def __init__(self, d=0):
self.value = d
@@ -393,6 +396,8 @@ class CScript(bytes):
iter(script) however does iterate by opcode.
"""
+ __slots__ = ()
+
@classmethod
def __coerce_instance(cls, other):
# Coerce other into bytes
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index 9a589240a8..97710bd6cd 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -525,7 +525,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
config = configparser.ConfigParser()
config.read_file(open(self.options.configfile))
- return config["components"].getboolean("ENABLE_UTILS")
+ return config["components"].getboolean("ENABLE_CLI")
def is_wallet_compiled(self):
"""Checks whether the wallet module was compiled."""
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 28437f8925..d9960460d9 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -285,11 +285,13 @@ def main():
# Remove the test cases that the user has explicitly asked to exclude.
if args.exclude:
- exclude_tests = [re.sub("\.py$", "", test) + (".py" if ".py" not in test else "") for test in args.exclude.split(',')]
+ exclude_tests = [test.split('.py')[0] for test in args.exclude.split(',')]
for exclude_test in exclude_tests:
- if exclude_test in test_list:
- test_list.remove(exclude_test)
- else:
+ # Remove <test_name>.py and <test_name>.py --arg from the test list
+ exclude_list = [test for test in test_list if test.split('.py')[0] == exclude_test]
+ for exclude_item in exclude_list:
+ test_list.remove(exclude_item)
+ if not exclude_list:
print("{}WARNING!{} Test '{}' not found in current test list.".format(BOLD[1], BOLD[0], exclude_test))
if not test_list:
diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py
index 48e71f6c40..eb42531693 100755
--- a/test/functional/wallet_hd.py
+++ b/test/functional/wallet_hd.py
@@ -25,12 +25,6 @@ class WalletHDTest(BitcoinTestFramework):
self.skip_if_no_wallet()
def run_test(self):
- # Make sure can't switch off usehd after wallet creation
- self.stop_node(1)
- self.nodes[1].assert_start_raises_init_error(['-usehd=0'], "Error: Error loading : You can't disable HD on an already existing HD wallet")
- self.start_node(1)
- connect_nodes_bi(self.nodes, 0, 1)
-
# Make sure we use hd, keep masterkeyid
masterkeyid = self.nodes[1].getwalletinfo()['hdseedid']
assert_equal(masterkeyid, self.nodes[1].getwalletinfo()['hdmasterkeyid'])
diff --git a/test/lint/check-doc.py b/test/lint/check-doc.py
index 7b056dab32..b0d9f87958 100755
--- a/test/lint/check-doc.py
+++ b/test/lint/check-doc.py
@@ -22,7 +22,7 @@ CMD_ROOT_DIR = '`git rev-parse --show-toplevel`/{}'.format(FOLDER_GREP)
CMD_GREP_ARGS = r"git grep --perl-regexp '{}' -- {} ':(exclude){}'".format(REGEX_ARG, CMD_ROOT_DIR, FOLDER_TEST)
CMD_GREP_DOCS = r"git grep --perl-regexp '{}' {}".format(REGEX_DOC, CMD_ROOT_DIR)
# list unsupported, deprecated and duplicate args as they need no documentation
-SET_DOC_OPTIONAL = set(['-h', '-help', '-dbcrashratio', '-forcecompactdb', '-usehd'])
+SET_DOC_OPTIONAL = set(['-h', '-help', '-dbcrashratio', '-forcecompactdb'])
def main():
diff --git a/test/util/data/bitcoin-util-test.json b/test/util/data/bitcoin-util-test.json
index f2213f4f2e..761923a818 100644
--- a/test/util/data/bitcoin-util-test.json
+++ b/test/util/data/bitcoin-util-test.json
@@ -105,6 +105,30 @@
{ "exec": "./bitcoin-tx",
"args":
["-create",
+ "in=Z897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0"],
+ "return_code": 1,
+ "error_txt": "error: invalid TX input txid",
+ "description": "Tests the check for an invalid txid invalid hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=5897de6bd6:0"],
+ "return_code": 1,
+ "error_txt": "error: invalid TX input txid",
+ "description": "Tests the check for an invalid txid valid hex but too short"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f12:0"],
+ "return_code": 1,
+ "error_txt": "error: invalid TX input txid",
+ "description": "Tests the check for an invalid txid valid hex but too long"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
"replaceable=0foo"],
"return_code": 1,
@@ -282,6 +306,42 @@
},
{ "exec": "./bitcoin-tx",
"args":
+ ["-create",
+ "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
+ "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
+ "set=prevtxs:[{\"txid\":\"Zd49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59412\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]",
+ "sign=ALL",
+ "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
+ "return_code": 1,
+ "error_txt": "error: txid must be hexadecimal string (not 'Zd49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59412')",
+ "description": "Tests the check for invalid txid due to invalid hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
+ "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
+ "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc594\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]",
+ "sign=ALL",
+ "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
+ "return_code": 1,
+ "error_txt": "error: txid must be hexadecimal string (not '4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc594')",
+ "description": "Tests the check for invalid txid valid hex, but too short"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
+ "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
+ "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc5948512\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]",
+ "sign=ALL",
+ "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
+ "return_code": 1,
+ "error_txt": "error: txid must be hexadecimal string (not '4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc5948512')",
+ "description": "Tests the check for invalid txid valid hex, but too long"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
["-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397", "nversion=1"],
"output_cmp": "txcreateoutpubkey1.hex",
"description": "Creates a new transaction with a single pay-to-pubkey output"