aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--Makefile.am5
-rw-r--r--configure.ac2
-rwxr-xr-xcontrib/macdeploy/custom_dsstore.py2
-rw-r--r--depends/builders/darwin.mk18
-rw-r--r--depends/packages/qt.mk1
-rw-r--r--doc/build-unix.md1
-rw-r--r--doc/descriptors.md41
-rw-r--r--doc/release-notes.md241
-rw-r--r--share/qt/Info.plist.in3
-rw-r--r--share/setup.nsi.in1
-rw-r--r--src/blockencodings.h9
-rw-r--r--src/httpserver.cpp10
-rw-r--r--src/netaddress.cpp1
-rw-r--r--src/netaddress.h2
-rw-r--r--src/qt/bitcoin.cpp8
-rw-r--r--src/qt/test/addressbooktests.cpp12
-rw-r--r--src/qt/test/wallettests.cpp11
-rw-r--r--src/rpc/client.cpp1
-rw-r--r--src/rpc/mining.cpp4
-rw-r--r--src/rpc/misc.cpp2
-rw-r--r--src/script/sign.h3
-rw-r--r--src/test/blockencodings_tests.cpp45
-rw-r--r--src/test/net_tests.cpp38
-rw-r--r--src/utilstrencodings.cpp1
-rw-r--r--src/utilstrencodings.h1
-rw-r--r--src/validation.cpp2
-rw-r--r--src/wallet/rpcwallet.cpp25
-rw-r--r--src/wallet/test/wallet_tests.cpp44
-rw-r--r--src/wallet/wallet.cpp13
-rw-r--r--src/wallet/wallet.h3
-rwxr-xr-xtest/functional/example_test.py12
-rwxr-xr-xtest/functional/feature_bip68_sequence.py3
-rwxr-xr-xtest/functional/feature_block.py79
-rwxr-xr-xtest/functional/feature_blocksdir.py3
-rwxr-xr-xtest/functional/feature_cltv.py3
-rwxr-xr-xtest/functional/feature_config_args.py3
-rwxr-xr-xtest/functional/feature_csv_activation.py3
-rwxr-xr-xtest/functional/feature_dbcrash.py3
-rwxr-xr-xtest/functional/feature_dersig.py3
-rwxr-xr-xtest/functional/feature_fee_estimation.py8
-rwxr-xr-xtest/functional/feature_logging.py3
-rwxr-xr-xtest/functional/feature_maxuploadtarget.py3
-rwxr-xr-xtest/functional/feature_minchainwork.py3
-rwxr-xr-xtest/functional/feature_notifications.py3
-rwxr-xr-xtest/functional/feature_nulldummy.py5
-rwxr-xr-xtest/functional/feature_pruning.py19
-rwxr-xr-xtest/functional/feature_rbf.py25
-rwxr-xr-xtest/functional/feature_reindex.py3
-rwxr-xr-xtest/functional/feature_segwit.py27
-rwxr-xr-xtest/functional/feature_versionbits_warning.py3
-rwxr-xr-xtest/functional/interface_bitcoin_cli.py3
-rwxr-xr-xtest/functional/interface_rest.py3
-rwxr-xr-xtest/functional/interface_zmq.py32
-rwxr-xr-xtest/functional/mempool_accept.py3
-rwxr-xr-xtest/functional/mempool_limit.py3
-rwxr-xr-xtest/functional/mempool_packages.py5
-rwxr-xr-xtest/functional/mempool_persist.py3
-rwxr-xr-xtest/functional/mempool_reorg.py3
-rwxr-xr-xtest/functional/mempool_resurrect.py8
-rwxr-xr-xtest/functional/mempool_spend_coinbase.py3
-rwxr-xr-xtest/functional/mining_basic.py3
-rwxr-xr-xtest/functional/mining_getblocktemplate_longpoll.py4
-rwxr-xr-xtest/functional/mining_prioritisetransaction.py3
-rwxr-xr-xtest/functional/p2p_compactblocks.py3
-rwxr-xr-xtest/functional/p2p_feefilter.py3
-rwxr-xr-xtest/functional/p2p_fingerprint.py3
-rwxr-xr-xtest/functional/p2p_invalid_block.py21
-rwxr-xr-xtest/functional/p2p_invalid_locator.py3
-rwxr-xr-xtest/functional/p2p_invalid_tx.py12
-rwxr-xr-xtest/functional/p2p_leak.py3
-rwxr-xr-xtest/functional/p2p_node_network_limited.py3
-rwxr-xr-xtest/functional/p2p_segwit.py225
-rwxr-xr-xtest/functional/p2p_sendheaders.py3
-rwxr-xr-xtest/functional/p2p_unrequested_blocks.py3
-rwxr-xr-xtest/functional/rpc_blockchain.py8
-rwxr-xr-xtest/functional/rpc_createmultisig.py5
-rwxr-xr-xtest/functional/rpc_deprecated.py3
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py3
-rwxr-xr-xtest/functional/rpc_getchaintips.py17
-rwxr-xr-xtest/functional/rpc_help.py57
-rwxr-xr-xtest/functional/rpc_invalidateblock.py3
-rwxr-xr-xtest/functional/rpc_preciousblock.py3
-rwxr-xr-xtest/functional/rpc_psbt.py7
-rwxr-xr-xtest/functional/rpc_rawtransaction.py5
-rwxr-xr-xtest/functional/rpc_scantxoutset.py4
-rwxr-xr-xtest/functional/rpc_signmessage.py3
-rwxr-xr-xtest/functional/rpc_signrawtransaction.py12
-rwxr-xr-xtest/functional/rpc_txoutproof.py3
-rwxr-xr-xtest/functional/rpc_zmq.py9
-rwxr-xr-xtest/functional/test_framework/mininode.py10
-rwxr-xr-xtest/functional/test_framework/test_framework.py87
-rwxr-xr-xtest/functional/test_framework/test_node.py34
-rwxr-xr-xtest/functional/test_runner.py10
-rwxr-xr-xtest/functional/wallet_abandonconflict.py3
-rwxr-xr-xtest/functional/wallet_address_types.py6
-rwxr-xr-xtest/functional/wallet_backup.py3
-rwxr-xr-xtest/functional/wallet_balance.py133
-rwxr-xr-xtest/functional/wallet_basic.py16
-rwxr-xr-xtest/functional/wallet_bumpfee.py9
-rwxr-xr-xtest/functional/wallet_disableprivatekeys.py3
-rwxr-xr-xtest/functional/wallet_dump.py103
-rwxr-xr-xtest/functional/wallet_encryption.py3
-rwxr-xr-xtest/functional/wallet_fallbackfee.py3
-rwxr-xr-xtest/functional/wallet_groups.py5
-rwxr-xr-xtest/functional/wallet_hd.py3
-rwxr-xr-xtest/functional/wallet_import_rescan.py37
-rwxr-xr-xtest/functional/wallet_importmulti.py3
-rwxr-xr-xtest/functional/wallet_importprunedfunds.py3
-rwxr-xr-xtest/functional/wallet_keypool.py3
-rwxr-xr-xtest/functional/wallet_keypool_topup.py3
-rwxr-xr-xtest/functional/wallet_labels.py3
-rwxr-xr-xtest/functional/wallet_listreceivedby.py16
-rwxr-xr-xtest/functional/wallet_listsinceblock.py3
-rwxr-xr-xtest/functional/wallet_listtransactions.py10
-rwxr-xr-xtest/functional/wallet_multiwallet.py3
-rwxr-xr-xtest/functional/wallet_resendwallettransactions.py3
-rwxr-xr-xtest/functional/wallet_txn_clone.py3
-rwxr-xr-xtest/functional/wallet_txn_doublespend.py3
-rwxr-xr-xtest/functional/wallet_zapwallettxes.py3
120 files changed, 1215 insertions, 580 deletions
diff --git a/.travis.yml b/.travis.yml
index aafdc2e89d..91b5af0f31 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,3 @@
-sudo: required
dist: trusty
os: linux
language: minimal
@@ -143,12 +142,11 @@ jobs:
BITCOIN_CONFIG="--enable-gui --enable-reduce-exports --enable-werror"
- stage: lint
env:
- sudo: false
cache: false
language: python
python: '3.6'
install:
- - travis_retry pip install flake8
+ - travis_retry pip install flake8==3.5.0
before_script:
- git fetch --unshallow
script:
diff --git a/Makefile.am b/Makefile.am
index 10dda65b21..8972c47f4f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,6 +19,7 @@ endif
BITCOIND_BIN=$(top_builddir)/src/$(BITCOIN_DAEMON_NAME)$(EXEEXT)
BITCOIN_QT_BIN=$(top_builddir)/src/qt/$(BITCOIN_GUI_NAME)$(EXEEXT)
BITCOIN_CLI_BIN=$(top_builddir)/src/$(BITCOIN_CLI_NAME)$(EXEEXT)
+BITCOIN_TX_BIN=$(top_builddir)/src/$(BITCOIN_TX_NAME)$(EXEEXT)
BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT)
empty :=
@@ -74,6 +75,7 @@ $(BITCOIN_WIN_INSTALLER): all-recursive
STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIND_BIN) $(top_builddir)/release
STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_QT_BIN) $(top_builddir)/release
STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_CLI_BIN) $(top_builddir)/release
+ STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_TX_BIN) $(top_builddir)/release
@test -f $(MAKENSIS) && $(MAKENSIS) -V2 $(top_builddir)/share/setup.nsi || \
echo error: could not build $@
@echo built $@
@@ -167,6 +169,9 @@ $(BITCOIND_BIN): FORCE
$(BITCOIN_CLI_BIN): FORCE
$(MAKE) -C src $(@F)
+$(BITCOIN_TX_BIN): FORCE
+ $(MAKE) -C src $(@F)
+
if USE_LCOV
LCOV_FILTER_PATTERN=-p "/usr/include/" -p "src/leveldb/" -p "src/bench/" -p "src/univalue" -p "src/crypto/ctaes" -p "src/secp256k1"
diff --git a/configure.ac b/configure.ac
index 44ca821a2a..812e0a8269 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 17)
define(_CLIENT_VERSION_REVISION, 0)
-define(_CLIENT_VERSION_BUILD, 0)
+define(_CLIENT_VERSION_BUILD, 1)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2018)
define(_COPYRIGHT_HOLDERS,[The %s developers])
diff --git a/contrib/macdeploy/custom_dsstore.py b/contrib/macdeploy/custom_dsstore.py
index 6fa134972a..c29f83a91e 100755
--- a/contrib/macdeploy/custom_dsstore.py
+++ b/contrib/macdeploy/custom_dsstore.py
@@ -13,7 +13,7 @@ package_name_ns = sys.argv[2]
ds = DSStore.open(output_file, 'w+')
ds['.']['bwsp'] = {
'ShowStatusBar': False,
- 'WindowBounds': b'{{300, 280}, {500, 343}}',
+ 'WindowBounds': '{{300, 280}, {500, 343}}',
'ContainerShowSidebar': False,
'SidebarWidth': 0,
'ShowTabView': False,
diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk
index 27f550ab03..c7671c1548 100644
--- a/depends/builders/darwin.mk
+++ b/depends/builders/darwin.mk
@@ -1,13 +1,13 @@
-build_darwin_CC: = $(shell xcrun -f clang)
-build_darwin_CXX: = $(shell xcrun -f clang++)
-build_darwin_AR: = $(shell xcrun -f ar)
-build_darwin_RANLIB: = $(shell xcrun -f ranlib)
-build_darwin_STRIP: = $(shell xcrun -f strip)
-build_darwin_OTOOL: = $(shell xcrun -f otool)
-build_darwin_NM: = $(shell xcrun -f nm)
+build_darwin_CC:=$(shell xcrun -f clang)
+build_darwin_CXX:=$(shell xcrun -f clang++)
+build_darwin_AR:=$(shell xcrun -f ar)
+build_darwin_RANLIB:=$(shell xcrun -f ranlib)
+build_darwin_STRIP:=$(shell xcrun -f strip)
+build_darwin_OTOOL:=$(shell xcrun -f otool)
+build_darwin_NM:=$(shell xcrun -f nm)
build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool)
-build_darwin_SHA256SUM = shasum -a 256
-build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o
+build_darwin_SHA256SUM=shasum -a 256
+build_darwin_DOWNLOAD=curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o
#darwin host on darwin builder. overrides darwin host preferences.
darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION)
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index 65ecadb43b..113b8dbc3b 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -119,6 +119,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/build-unix.md b/doc/build-unix.md
index a01ff59fa6..4a09bed2b2 100644
--- a/doc/build-unix.md
+++ b/doc/build-unix.md
@@ -279,6 +279,7 @@ To build executables for ARM:
cd depends
make HOST=arm-linux-gnueabihf NO_QT=1
cd ..
+ ./autogen.sh
./configure --prefix=$PWD/depends/arm-linux-gnueabihf --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++
make
diff --git a/doc/descriptors.md b/doc/descriptors.md
index c23ac06e8f..47e15e0502 100644
--- a/doc/descriptors.md
+++ b/doc/descriptors.md
@@ -22,19 +22,19 @@ Output descriptors currently support:
## Examples
-- `pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)` represents a P2PK output.
-- `pkh(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)` represents a P2PKH output.
-- `wpkh(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9)` represents a P2WPKH output.
-- `sh(wpkh(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))` represents a P2SH-P2WPKH output.
-- `combo(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)` represents a P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH output.
-- `sh(wsh(pkh(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13)))` represents a (overly complicated) P2SH-P2WSH-P2PKH output.
-- `multi(1,022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)` represents a bare *1-of-2* multisig.
-- `sh(multi(2,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe))` represents a P2SH *2-of-2* multisig.
-- `wsh(multi(2,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,03774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a))` represents a P2WSH *2-of-3* multisig.
-- `sh(wsh(multi(1,03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8,03499fdf9e895e719cfd64e67f07d38e3226aa7b63678949e6e49b241a60e823e4,02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e)))` represents a P2SH-P2WSH *1-of-3* multisig.
-- `pk(xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8)` refers to a single P2PK output, using the public key part from the specified xpub.
-- `pkh(xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw/1'/2)` refers to a single P2PKH output, using child key *1'/2* of the specified xpub.
-- `wsh(multi(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/1/0/*))` refers to a chain of *1-of-2* P2WSH multisig outputs, using public keys taken from two HD chains with corresponding derivation paths.
+- `pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)` describes a P2PK output with the specified public key.
+- `pkh(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)` describes a P2PKH output with the specified public key.
+- `wpkh(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9)` describes a P2WPKH output with the specified public key.
+- `sh(wpkh(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))` describes a P2SH-P2WPKH output with the specified public key.
+- `combo(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)` describes any P2PK, P2PKH, P2WPKH, or P2SH-P2WPKH output with the specified public key.
+- `sh(wsh(pkh(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13)))` describes an (overly complicated) P2SH-P2WSH-P2PKH output with the specified public key.
+- `multi(1,022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)` describes a bare *1-of-2* multisig output with keys in the specified order.
+- `sh(multi(2,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe))` describes a P2SH *2-of-2* multisig output with keys in the specified order.
+- `wsh(multi(2,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,03774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a))` describes a P2WSH *2-of-3* multisig output with keys in the specified order.
+- `sh(wsh(multi(1,03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8,03499fdf9e895e719cfd64e67f07d38e3226aa7b63678949e6e49b241a60e823e4,02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e)))` describes a P2SH-P2WSH *1-of-3* multisig output with keys in the specified order.
+- `pk(xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8)` describes a P2PK output with the public key of the specified xpub.
+- `pkh(xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw/1'/2)` describes a P2PKH output with child key *1'/2* of the specified xpub.
+- `wsh(multi(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*))` describes a set of *1-of-2* P2WSH multisig outputs where the first multisig key is the *1/0/`i`* child of the first specified xpub and the second multisig key is the *0/0/`i`* child of the second specified xpub, and `i` is any number in a configurable range (`0-1000` by default).
## Reference
@@ -91,6 +91,15 @@ on Bitcoin's OP_CHECKMULTISIG opcode. To support these, we introduce the
multisig policy, where any *k* out of the *n* provided public keys must
sign.
+Key order is significant. A `multi()` expression describes a multisig script
+with keys in the specified order, and in a search for TXOs, it will not match
+outputs with multisig scriptPubKeys that have the same keys in a different
+order. Also, to prevent a combinatorial explosion of the search space, if more
+than one of the `multi()` key arguments is a BIP32 wildcard path ending in `/*`
+or `*'`, the `multi()` expression only matches multisig scripts with the `i`th
+child key from each wildcard path in lockstep, rather than scripts with any
+combination of child keys from each wildcard path.
+
### BIP32 derived keys and chains
Most modern wallet software and hardware uses keys that are derived using
@@ -101,7 +110,7 @@ path consists of a sequence of 0 or more integers (in the range
*0..2<sup>31</sup>-1*) each optionally followed by `'` or `h`, and
separated by `/` characters. The string may optionally end with the
literal `/*` or `/*'` (or `/*h`) to refer to all unhardened or hardened
-child keys instead.
+child keys in a configurable range (by default `0-1000`, inclusive).
Whenever a public key is described using a hardened derivation step, the
script cannot be computed without access to the corresponding private
@@ -119,6 +128,6 @@ steps, or for dumping wallet descriptors including private key material.
In order to easily represent the sets of scripts currently supported by
existing Bitcoin Core wallets, a convenience function `combo` is
-provided, which takes as input a public key, and constructs the P2PK,
+provided, which takes as input a public key, and describes a set of P2PK,
P2PKH, P2WPKH, and P2SH-P2WPH scripts for that key. In case the key is
-uncompressed, it only constructs P2PK and P2PKH.
+uncompressed, the set only includes P2PK and P2PKH scripts. \ No newline at end of file
diff --git a/doc/release-notes.md b/doc/release-notes.md
index a24a13408b..ea9a45347d 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -1,9 +1,9 @@
(note: this is a temporary file, to be added-to by anybody, and moved to
release-notes at release time)
-Bitcoin Core version *version* is now available from:
+Bitcoin Core version 0.17.x is now available from:
- <https://bitcoincore.org/bin/bitcoin-core-*version*/>
+ <https://bitcoincore.org/bin/bitcoin-core-0.17.x/>
This is a new major version release, including new features, various bugfixes
and performance improvements, as well as updated translations.
@@ -24,7 +24,9 @@ shut down (which might take a few minutes for older versions), then run the
installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on Mac)
or `bitcoind`/`bitcoin-qt` (on Linux).
-The first time you run version 0.15.0, your chainstate database will be converted to a
+If your node has a txindex, the txindex db will be migrated the first time you run 0.17.0 or newer, which may take up to a few hours. Your node will not be functional until this migration completes.
+
+The first time you run version 0.15.0 or newer, 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.
@@ -56,217 +58,46 @@ frequently tested on them.
From 0.17.0 onwards macOS <10.10 is no longer supported. 0.17.0 is built using Qt 5.9.x, which doesn't
support versions of macOS older than 10.10.
+Known issues
+============
+
+...
+
Notable changes
===============
-Changed command-line options
-----------------------------
-
-- `-includeconf=<file>` can be used to include additional configuration files.
- Only works inside the `bitcoin.conf` file, not inside included files or from
- command-line. Multiple files may be included. Can be disabled from command-
- line via `-noincludeconf`. Note that multi-argument commands like
- `-includeconf` will override preceding `-noincludeconf`, i.e.
-
- noincludeconf=1
- includeconf=relative.conf
-
- as bitcoin.conf will still include `relative.conf`.
-
-GUI changes
------------
+...
+
+0.17.x change log
+=================
+
+`listtransactions` label support
+--------------------------------
-- Block storage can be limited under Preferences, in the Main tab. Undoing this setting requires downloading the full blockchain again. This mode is incompatible with -txindex and -rescan.
-
-RPC changes
-------------
-
-### Low-level changes
-
-- The `createrawtransaction` RPC will now accept an array or dictionary (kept for compatibility) for the `outputs` parameter. This means the order of transaction outputs can be specified by the client.
-- The `fundrawtransaction` RPC will reject the previously deprecated `reserveChangeKey` option.
-- `sendmany` now shuffles outputs to improve privacy, so any previously expected behavior with regards to output ordering can no longer be relied upon.
-- The new RPC `testmempoolaccept` can be used to test acceptance of a transaction to the mempool without adding it.
-- JSON transaction decomposition now includes a `weight` field which provides
- the transaction's exact weight. This is included in REST /rest/tx/ and
- /rest/block/ endpoints when in json mode. This is also included in `getblock`
- (with verbosity=2), `listsinceblock`, `listtransactions`, and
- `getrawtransaction` RPC commands.
-- New `fees` field introduced in `getrawmempool`, `getmempoolancestors`, `getmempooldescendants` and
- `getmempoolentry` when verbosity is set to `true` with sub-fields `ancestor`, `base`, `modified`
- and `descendant` denominated in BTC. This new field deprecates previous fee fields, such as
- `fee`, `modifiedfee`, `ancestorfee` and `descendantfee`.
-- The new RPC `getzmqnotifications` returns information about active ZMQ
- notifications.
-
-External wallet files
----------------------
-
-The `-wallet=<path>` option now accepts full paths instead of requiring wallets
-to be located in the -walletdir directory.
-
-Newly created wallet format
----------------------------
-
-If `-wallet=<path>` is specified with a path that does not exist, it will now
-create a wallet directory at the specified location (containing a wallet.dat
-data file, a db.log file, and database/log.?????????? files) instead of just
-creating a data file at the path and storing log files in the parent
-directory. This should make backing up wallets more straightforward than
-before because the specified wallet path can just be directly archived without
-having to look in the parent directory for transaction log files.
-
-For backwards compatibility, wallet paths that are names of existing data files
-in the `-walletdir` directory will continue to be accepted and interpreted the
-same as before.
-
-Dynamic loading and creation of wallets
----------------------------------------
-
-Previously, wallets could only be loaded or created at startup, by specifying `-wallet` parameters on the command line or in the bitcoin.conf file. It is now possible to load, create and unload wallets dynamically at runtime:
-
-- Existing wallets can be loaded by calling the `loadwallet` RPC. The wallet can be specified as file/directory basename (which must be located in the `walletdir` directory), or as an absolute path to a file/directory.
-- New wallets can be created (and loaded) by calling the `createwallet` RPC. The provided name must not match a wallet file in the `walletdir` directory or the name of a wallet that is currently loaded.
-- Loaded wallets can be unloaded by calling the `unloadwallet` RPC.
-
-This feature is currently only available through the RPC interface.
-
-Coin selection
---------------
-- A new `-avoidpartialspends` flag has been added (default=false). If enabled, the wallet will try to spend UTXO's that point at the same destination
- together. This is a privacy increase, as there will no longer be cases where a wallet will inadvertently spend only parts of the coins sent to
- the same address (note that if someone were to send coins to that address after it was used, those coins will still be included in future
- coin selections).
-
-Configuration sections for testnet and regtest
-----------------------------------------------
-
-It is now possible for a single configuration file to set different
-options for different networks. This is done by using sections or by
-prefixing the option with the network, such as:
-
- main.uacomment=bitcoin
- test.uacomment=bitcoin-testnet
- regtest.uacomment=regtest
- [main]
- mempoolsize=300
- [test]
- mempoolsize=100
- [regtest]
- mempoolsize=20
-
-The `addnode=`, `connect=`, `port=`, `bind=`, `rpcport=`, `rpcbind=`
-and `wallet=` options will only apply to mainnet when specified in the
-configuration file, unless a network is specified.
-
-'label' and 'account' APIs for wallet
--------------------------------------
-
-A new 'label' API has been introduced for the wallet. This is intended as a
-replacement for the deprecated 'account' API. The 'account' can continue to
-be used in V0.17 by starting bitcoind with the '-deprecatedrpc=accounts'
-argument, and will be fully removed in V0.18.
-
-The label RPC methods mirror the account functionality, with the following functional differences:
-
-- Labels can be set on any address, not just receiving addresses. This functionality was previously only available through the GUI.
-- Labels can be deleted by reassigning all addresses using the `setlabel` RPC method.
-- There isn't support for sending transactions _from_ a label, or for determining which label a transaction was sent from.
-- Labels do not have a balance.
-
-Here are the changes to RPC methods:
-
-| Deprecated Method | New Method | Notes |
-| :---------------------- | :-------------------- | :-----------|
-| `getaccount` | `getaddressinfo` | `getaddressinfo` returns a json object with address information instead of just the name of the account as a string. |
-| `getaccountaddress` | n/a | There is no replacement for `getaccountaddress` since labels do not have an associated receive address. |
-| `getaddressesbyaccount` | `getaddressesbylabel` | `getaddressesbylabel` returns a json object with the addresses as keys, instead of a list of strings. |
-| `getreceivedbyaccount` | `getreceivedbylabel` | _no change in behavior_ |
-| `listaccounts` | `listlabels` | `listlabels` does not return a balance or accept `minconf` and `watchonly` arguments. |
-| `listreceivedbyaccount` | `listreceivedbylabel` | Both methods return new `label` fields, along with `account` fields for backward compatibility. |
-| `move` | n/a | _no replacement_ |
-| `sendfrom` | n/a | _no replacement_ |
-| `setaccount` | `setlabel` | Both methods now: <ul><li>allow assigning labels to any address, instead of raising an error if the address is not receiving address.<li>delete the previous label associated with an address when the final address using that label is reassigned to a different label, instead of making an implicit `getaccountaddress` call to ensure the previous label still has a receiving address. |
-
-| Changed Method | Notes |
-| :--------------------- | :------ |
-| `addmultisigaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility if running with '-deprecatedrpc=accounts'. |
-| `getnewaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. if running with '-deprecatedrpc=accounts' |
-| `listunspent` | Returns new `label` fields. `account` field will be returned for backward compatibility if running with '-deprecatedrpc=accounts' |
-| `sendmany` | The `account` named parameter has been renamed to `dummy`. If provided, the `dummy` parameter must be set to the empty string, unless running with the `-deprecatedrpc=accounts` argument (in which case functionality is unchanged). |
-| `listtransactions` | The `account` named parameter has been renamed to `dummy`. If provided, the `dummy` parameter must be set to the string `*`, unless running with the `-deprecatedrpc=accounts` argument (in which case functionality is unchanged). |
-| `getbalance` | `account`, `minconf` and `include_watchonly` parameters are deprecated, and can only be used if running with '-deprecatedrpc=accounts' |
-
-Low-level RPC changes
----------------------
-
-- When bitcoin is not started with any `-wallet=<path>` options, the name of
- the default wallet returned by `getwalletinfo` and `listwallets` RPCs is
- now the empty string `""` instead of `"wallet.dat"`. If bitcoin is started
- with any `-wallet=<path>` options, there is no change in behavior, and the
- name of any wallet is just its `<path>` string.
-- Passing an empty string (`""`) as the `address_type` parameter to
- `getnewaddress`, `getrawchangeaddress`, `addmultisigaddress`,
- `fundrawtransaction` RPCs is now an error. Previously, this would fall back
- to using the default address type. It is still possible to pass null or leave
- the parameter unset to use the default address type.
-
-- Bare multisig outputs to our keys are no longer automatically treated as
- incoming payments. As this feature was only available for multisig outputs for
- which you had all private keys in your wallet, there was generally no use for
- them compared to single-key schemes. Furthermore, no address format for such
- outputs is defined, and wallet software can't easily send to it. These outputs
- will no longer show up in `listtransactions`, `listunspent`, or contribute to
- your balance, unless they are explicitly watched (using `importaddress` or
- `importmulti` with hex script argument). `signrawtransaction*` also still
- works for them.
-
-- The `getwalletinfo` RPC method now returns an `hdseedid` value, which is always the same as the incorrectly-named `hdmasterkeyid` value. `hdmasterkeyid` will be removed in V0.18.
-- The `getaddressinfo` RPC method now returns an `hdseedid` value, which is always the same as the incorrectly-named `hdmasterkeyid` value. `hdmasterkeyid` will be removed in V0.18.
-
-Other API changes
------------------
-
-- The `inactivehdmaster` property in the `dumpwallet` output has been corrected to `inactivehdseed`
-
-### Logging
-
-- The log timestamp format is now ISO 8601 (e.g. "2018-02-28T12:34:56Z").
-
-- When running bitcoind with `-debug` but without `-daemon`, logging to stdout
- is now the default behavior. Setting `-printtoconsole=1` no longer implicitly
- disables logging to debug.log. Instead, logging to file can be explicitly disabled
- by setting `-debuglogfile=0`.
-
-Transaction index changes
--------------------------
-
-The transaction index is now built separately from the main node procedure,
-meaning the `-txindex` flag can be toggled without a full reindex. If bitcoind
-is run with `-txindex` on a node that is already partially or fully synced
-without one, the transaction index will be built in the background and become
-available once caught up. When switching from running `-txindex` to running
-without the flag, the transaction index database will *not* be deleted
-automatically, meaning it could be turned back on at a later time without a full
-resync.
-
-Miner block size removed
-------------------------
-
-The `-blockmaxsize` option for miners to limit their blocks' sizes was
-deprecated in V0.15.1, and has now been removed. Miners should use the
-`-blockmaxweight` option if they want to limit the weight of their blocks'
-weights.
-
-Python Support
---------------
-
-Support for Python 2 has been discontinued for all test files and tools.
+The `listtransactions` RPC `account` parameter which was deprecated in 0.17.0
+and renamed to `dummy` has been un-deprecated and renamed again to `label`.
+
+When bitcoin is configured with the `-deprecatedrpc=accounts` setting, specifying
+a label/account/dummy argument will return both outgoing and incoming
+transactions. Without the `-deprecatedrpc=accounts` setting, it will only return
+incoming transactions (because it used to be possible to create transactions
+spending from specific accounts, but this is no longer possible with labels).
+
+When `-deprecatedrpc=accounts` is set, it's possible to pass the empty string ""
+to list transactions that don't have any label. Without
+`-deprecatedrpc=accounts`, passing the empty string is an error because returning
+only non-labeled transactions is not generally useful behavior and can cause
+confusion.
Credits
=======
Thanks to everyone who directly contributed to this release:
+...
+
+And to those that reported security issues:
+
+...
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in
index 17b4ee47de..0c0335a1e8 100644
--- a/share/qt/Info.plist.in
+++ b/share/qt/Info.plist.in
@@ -99,6 +99,9 @@
<key>LSAppNapIsDisabled</key>
<string>True</string>
+
+ <key>NSRequiresAquaSystemAppearance</key>
+ <string>True</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.finance</string>
diff --git a/share/setup.nsi.in b/share/setup.nsi.in
index b58a84e02d..6542370f97 100644
--- a/share/setup.nsi.in
+++ b/share/setup.nsi.in
@@ -80,6 +80,7 @@ Section -Main SEC0000
SetOutPath $INSTDIR\daemon
File @abs_top_srcdir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@
File @abs_top_srcdir@/release/@BITCOIN_CLI_NAME@@EXEEXT@
+ File @abs_top_srcdir@/release/@BITCOIN_TX_NAME@@EXEEXT@
SetOutPath $INSTDIR\doc
File /r /x Makefile* @abs_top_srcdir@/doc\*.*
SetOutPath $INSTDIR
diff --git a/src/blockencodings.h b/src/blockencodings.h
index fad1f56f54..0c2b83ebcf 100644
--- a/src/blockencodings.h
+++ b/src/blockencodings.h
@@ -52,12 +52,12 @@ public:
}
}
- uint16_t offset = 0;
+ int32_t offset = 0;
for (size_t j = 0; j < indexes.size(); j++) {
- if (uint64_t(indexes[j]) + uint64_t(offset) > std::numeric_limits<uint16_t>::max())
+ if (int32_t(indexes[j]) + offset > std::numeric_limits<uint16_t>::max())
throw std::ios_base::failure("indexes overflowed 16 bits");
indexes[j] = indexes[j] + offset;
- offset = indexes[j] + 1;
+ offset = int32_t(indexes[j]) + 1;
}
} else {
for (size_t i = 0; i < indexes.size(); i++) {
@@ -186,6 +186,9 @@ public:
READWRITE(prefilledtxn);
+ if (BlockTxCount() > std::numeric_limits<uint16_t>::max())
+ throw std::ios_base::failure("indexes overflowed 16 bits");
+
if (ser_action.ForRead())
FillShortTxIDSelector();
}
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index 8962fe6a42..2a76d0d46a 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -224,21 +224,25 @@ static void http_request_cb(struct evhttp_request* req, void* arg)
}
std::unique_ptr<HTTPRequest> hreq(new HTTPRequest(req));
- LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n",
- RequestMethodString(hreq->GetRequestMethod()), hreq->GetURI(), hreq->GetPeer().ToString());
-
// Early address-based allow check
if (!ClientAllowed(hreq->GetPeer())) {
+ LogPrint(BCLog::HTTP, "HTTP request from %s rejected: Client network is not allowed RPC access\n",
+ hreq->GetPeer().ToString());
hreq->WriteReply(HTTP_FORBIDDEN);
return;
}
// Early reject unknown HTTP methods
if (hreq->GetRequestMethod() == HTTPRequest::UNKNOWN) {
+ LogPrint(BCLog::HTTP, "HTTP request from %s rejected: Unknown HTTP request method\n",
+ hreq->GetPeer().ToString());
hreq->WriteReply(HTTP_BADMETHOD);
return;
}
+ LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n",
+ RequestMethodString(hreq->GetRequestMethod()), SanitizeString(hreq->GetURI(), SAFE_CHARS_URI).substr(0, 100), hreq->GetPeer().ToString());
+
// Find registered handler for prefix
std::string strURI = hreq->GetURI();
std::string path;
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index 778c2700f9..9c6daefef6 100644
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -17,7 +17,6 @@ static const unsigned char g_internal_prefix[] = { 0xFD, 0x6B, 0x88, 0xC0, 0x87,
CNetAddr::CNetAddr()
{
memset(ip, 0, sizeof(ip));
- scopeId = 0;
}
void CNetAddr::SetIP(const CNetAddr& ipIn)
diff --git a/src/netaddress.h b/src/netaddress.h
index cc0e4d4f12..dc55d8b1a8 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -33,7 +33,7 @@ class CNetAddr
{
protected:
unsigned char ip[16]; // in network byte order
- uint32_t scopeId; // for scoped/link-local ipv6 addresses
+ uint32_t scopeId{0}; // for scoped/link-local ipv6 addresses
public:
CNetAddr();
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index d3ec67e441..edb6e9bc81 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -50,7 +50,6 @@
#include <QThread>
#include <QTimer>
#include <QTranslator>
-#include <QSslConfiguration>
#if defined(QT_STATICPLUGIN)
#include <QtPlugin>
@@ -576,13 +575,6 @@ int main(int argc, char *argv[])
#ifdef Q_OS_MAC
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
#endif
-#if QT_VERSION >= 0x050500
- // Because of the POODLE attack it is recommended to disable SSLv3 (https://disablessl3.com/),
- // so set SSL protocols to TLS1.0+.
- QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration();
- sslconf.setProtocol(QSsl::TlsV1_0OrLater);
- QSslConfiguration::setDefaultConfiguration(sslconf);
-#endif
// Register meta types used for QMetaObject::invokeMethod
qRegisterMetaType< bool* >();
diff --git a/src/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp
index c3d33c76d4..3525846044 100644
--- a/src/qt/test/addressbooktests.cpp
+++ b/src/qt/test/addressbooktests.cpp
@@ -17,6 +17,7 @@
#include <key_io.h>
#include <wallet/wallet.h>
+#include <QApplication>
#include <QTimer>
#include <QMessageBox>
@@ -139,5 +140,16 @@ void TestAddAddressesToSendBook()
void AddressBookTests::addressBookTests()
{
+#ifdef Q_OS_MAC
+ if (QApplication::platformName() == "minimal") {
+ // Disable for mac on "minimal" platform to avoid crashes inside the Qt
+ // framework when it tries to look up unimplemented cocoa functions,
+ // and fails to handle returned nulls
+ // (https://bugreports.qt.io/browse/QTBUG-49686).
+ QWARN("Skipping AddressBookTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke "
+ "with 'test_bitcoin-qt -platform cocoa' on mac, or else use a linux or windows build.");
+ return;
+ }
+#endif
TestAddAddressesToSendBook();
}
diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp
index c314dadde4..9598d64845 100644
--- a/src/qt/test/wallettests.cpp
+++ b/src/qt/test/wallettests.cpp
@@ -243,5 +243,16 @@ void TestGUI()
void WalletTests::walletTests()
{
+#ifdef Q_OS_MAC
+ if (QApplication::platformName() == "minimal") {
+ // Disable for mac on "minimal" platform to avoid crashes inside the Qt
+ // framework when it tries to look up unimplemented cocoa functions,
+ // and fails to handle returned nulls
+ // (https://bugreports.qt.io/browse/QTBUG-49686).
+ QWARN("Skipping WalletTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke "
+ "with 'test_bitcoin-qt -platform cocoa' on mac, or else use a linux or windows build.");
+ return;
+ }
+#endif
TestGUI();
}
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index c7f3e38ac0..9fa0420160 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -45,7 +45,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listreceivedbyaddress", 0, "minconf" },
{ "listreceivedbyaddress", 1, "include_empty" },
{ "listreceivedbyaddress", 2, "include_watchonly" },
- { "listreceivedbyaddress", 3, "address_filter" },
{ "listreceivedbyaccount", 0, "minconf" },
{ "listreceivedbyaccount", 1, "include_empty" },
{ "listreceivedbyaccount", 2, "include_watchonly" },
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index e751587dc7..9da3c1493b 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -361,8 +361,8 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
"}\n"
"\nExamples:\n"
- + HelpExampleCli("getblocktemplate", "")
- + HelpExampleRpc("getblocktemplate", "")
+ + HelpExampleCli("getblocktemplate", "{\"rules\": [\"segwit\"]}")
+ + HelpExampleRpc("getblocktemplate", "{\"rules\": [\"segwit\"]}")
);
LOCK(cs_main);
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 0644d7c6c2..88d662878e 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -474,7 +474,7 @@ static const CRPCCommand commands[] =
{ "control", "getmemoryinfo", &getmemoryinfo, {"mode"} },
{ "control", "logging", &logging, {"include", "exclude"}},
{ "util", "validateaddress", &validateaddress, {"address"} }, /* uses wallet if enabled */
- { "util", "createmultisig", &createmultisig, {"nrequired","keys"} },
+ { "util", "createmultisig", &createmultisig, {"nrequired","keys","address_type"} },
{ "util", "verifymessage", &verifymessage, {"address","signature","message"} },
{ "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} },
diff --git a/src/script/sign.h b/src/script/sign.h
index 7ade715ee2..245b15410f 100644
--- a/src/script/sign.h
+++ b/src/script/sign.h
@@ -188,6 +188,9 @@ template<typename Stream>
void SerializeHDKeypaths(Stream& s, const std::map<CPubKey, std::vector<uint32_t>>& hd_keypaths, uint8_t type)
{
for (auto keypath_pair : hd_keypaths) {
+ if (!keypath_pair.first.IsValid()) {
+ throw std::ios_base::failure("Invalid CPubKey being serialized");
+ }
SerializeToVector(s, type, MakeSpan(keypath_pair.first));
WriteCompactSize(s, keypath_pair.second.size() * sizeof(uint32_t));
for (auto& path : keypath_pair.second) {
diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp
index d2c7c8cb1d..df62c5ac92 100644
--- a/src/test/blockencodings_tests.cpp
+++ b/src/test/blockencodings_tests.cpp
@@ -344,4 +344,49 @@ BOOST_AUTO_TEST_CASE(TransactionsRequestSerializationTest) {
BOOST_CHECK_EQUAL(req1.indexes[3], req2.indexes[3]);
}
+BOOST_AUTO_TEST_CASE(TransactionsRequestDeserializationMaxTest) {
+ // Check that the highest legal index is decoded correctly
+ BlockTransactionsRequest req0;
+ req0.blockhash = InsecureRand256();
+ req0.indexes.resize(1);
+ req0.indexes[0] = 0xffff;
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << req0;
+
+ BlockTransactionsRequest req1;
+ stream >> req1;
+ BOOST_CHECK_EQUAL(req0.indexes.size(), req1.indexes.size());
+ BOOST_CHECK_EQUAL(req0.indexes[0], req1.indexes[0]);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionsRequestDeserializationOverflowTest) {
+ // Any set of index deltas that starts with N values that sum to (0x10000 - N)
+ // causes the edge-case overflow that was originally not checked for. Such
+ // a request cannot be created by serializing a real BlockTransactionsRequest
+ // due to the overflow, so here we'll serialize from raw deltas.
+ BlockTransactionsRequest req0;
+ req0.blockhash = InsecureRand256();
+ req0.indexes.resize(3);
+ req0.indexes[0] = 0x7000;
+ req0.indexes[1] = 0x10000 - 0x7000 - 2;
+ req0.indexes[2] = 0;
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << req0.blockhash;
+ WriteCompactSize(stream, req0.indexes.size());
+ WriteCompactSize(stream, req0.indexes[0]);
+ WriteCompactSize(stream, req0.indexes[1]);
+ WriteCompactSize(stream, req0.indexes[2]);
+
+ BlockTransactionsRequest req1;
+ try {
+ stream >> req1;
+ // before patch: deserialize above succeeds and this check fails, demonstrating the overflow
+ BOOST_CHECK(req1.indexes[1] < req1.indexes[2]);
+ // this shouldn't be reachable before or after patch
+ BOOST_CHECK(0);
+ } catch(std::ios_base::failure &) {
+ // deserialize should fail
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index 4c56938ec9..ae4841de5a 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -189,4 +189,42 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
BOOST_CHECK(pnode2->fFeeler == false);
}
+// prior to PR #14728, this test triggers an undefined behavior
+BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)
+{
+ // set up local addresses; all that's necessary to reproduce the bug is
+ // that a normal IPv4 address is among the entries, but if this address is
+ // !IsRoutable the undefined behavior is easier to trigger deterministically
+ {
+ LOCK(cs_mapLocalHost);
+ in_addr ipv4AddrLocal;
+ ipv4AddrLocal.s_addr = 0x0100007f;
+ CNetAddr addr = CNetAddr(ipv4AddrLocal);
+ LocalServiceInfo lsi;
+ lsi.nScore = 23;
+ lsi.nPort = 42;
+ mapLocalHost[addr] = lsi;
+ }
+
+ // create a peer with an IPv4 address
+ in_addr ipv4AddrPeer;
+ ipv4AddrPeer.s_addr = 0xa0b0c001;
+ CAddress addr = CAddress(CService(ipv4AddrPeer, 7777), NODE_NETWORK);
+ std::unique_ptr<CNode> pnode = MakeUnique<CNode>(0, NODE_NETWORK, 0, INVALID_SOCKET, addr, 0, 0, CAddress{}, std::string{}, false);
+ pnode->fSuccessfullyConnected.store(true);
+
+ // the peer claims to be reaching us via IPv6
+ in6_addr ipv6AddrLocal;
+ memset(ipv6AddrLocal.s6_addr, 0, 16);
+ ipv6AddrLocal.s6_addr[0] = 0xcc;
+ CAddress addrLocal = CAddress(CService(ipv6AddrLocal, 7777), NODE_NETWORK);
+ pnode->SetAddrLocal(addrLocal);
+
+ // before patch, this causes undefined behavior detectable with clang's -fsanitize=memory
+ AdvertiseLocal(&*pnode);
+
+ // suppress no-checks-run warning; if this test fails, it's by triggering a sanitizer
+ BOOST_CHECK(1);
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp
index a06d88cb19..3c6e333a62 100644
--- a/src/utilstrencodings.cpp
+++ b/src/utilstrencodings.cpp
@@ -19,6 +19,7 @@ static const std::string SAFE_CHARS[] =
CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT
CHARS_ALPHA_NUM + " .,;-_?@", // SAFE_CHARS_UA_COMMENT
CHARS_ALPHA_NUM + ".-_", // SAFE_CHARS_FILENAME
+ CHARS_ALPHA_NUM + "!*'();:@&=+$,/?#[]-_.~%", // SAFE_CHARS_URI
};
std::string SanitizeString(const std::string& str, int rule)
diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h
index 5f2211b5dc..0a06bc3f85 100644
--- a/src/utilstrencodings.h
+++ b/src/utilstrencodings.h
@@ -25,6 +25,7 @@ enum SafeChars
SAFE_CHARS_DEFAULT, //!< The full set of allowed chars
SAFE_CHARS_UA_COMMENT, //!< BIP-0014 subset
SAFE_CHARS_FILENAME, //!< Chars allowed in filenames
+ SAFE_CHARS_URI, //!< Chars allowed in URIs (RFC 3986)
};
/**
diff --git a/src/validation.cpp b/src/validation.cpp
index fceb135854..d3908fc1d8 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -3130,7 +3130,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
// Check transactions
for (const auto& tx : block.vtx)
- if (!CheckTransaction(*tx, state, false))
+ if (!CheckTransaction(*tx, state, true))
return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(),
strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), state.GetDebugMessage()));
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index b268e9a877..0a9242327b 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -1805,9 +1805,14 @@ static void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const
bool fAllAccounts = (strAccount == std::string("*"));
bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
+ bool list_sent = fAllAccounts;
+
+ if (IsDeprecatedRPCEnabled("accounts")) {
+ list_sent |= strAccount == strSentAccount;
+ }
+
// Sent
- if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
- {
+ if (list_sent) {
for (const COutputEntry& s : listSent)
{
UniValue entry(UniValue::VOBJ);
@@ -1901,12 +1906,14 @@ UniValue listtransactions(const JSONRPCRequest& request)
std::string help_text {};
if (!IsDeprecatedRPCEnabled("accounts")) {
- help_text = "listtransactions (dummy count skip include_watchonly)\n"
- "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
+ help_text = "listtransactions (label count skip include_watchonly)\n"
+ "\nIf a label name is provided, this will return only incoming transactions paying to addresses with the specified label.\n"
+ "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions.\n"
"Note that the \"account\" argument and \"otheraccount\" return value have been removed in V0.17. To use this RPC with an \"account\" argument, restart\n"
"bitcoind with -deprecatedrpc=accounts\n"
"\nArguments:\n"
- "1. \"dummy\" (string, optional) If set, should be \"*\" for backwards compatibility.\n"
+ "1. \"label\" (string, optional) If set, should be a valid label name to return only incoming transactions\n"
+ " with the specified label, or \"*\" to disable filtering and return all transactions.\n"
"2. count (numeric, optional, default=10) The number of transactions to return\n"
"3. skip (numeric, optional, default=0) The number of transactions to skip\n"
"4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
@@ -2012,8 +2019,8 @@ UniValue listtransactions(const JSONRPCRequest& request)
std::string strAccount = "*";
if (!request.params[0].isNull()) {
strAccount = request.params[0].get_str();
- if (!IsDeprecatedRPCEnabled("accounts") && strAccount != "*") {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Dummy value must be set to \"*\"");
+ if (!IsDeprecatedRPCEnabled("accounts") && strAccount.empty()) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Label argument must be a valid label name or \"*\".");
}
}
int nCount = 10;
@@ -3725,6 +3732,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]);
}
@@ -4808,7 +4817,7 @@ static const CRPCCommand commands[] =
{ "wallet", "listlockunspent", &listlockunspent, {} },
{ "wallet", "listreceivedbyaddress", &listreceivedbyaddress, {"minconf","include_empty","include_watchonly","address_filter"} },
{ "wallet", "listsinceblock", &listsinceblock, {"blockhash","target_confirmations","include_watchonly","include_removed"} },
- { "wallet", "listtransactions", &listtransactions, {"account|dummy","count","skip","include_watchonly"} },
+ { "wallet", "listtransactions", &listtransactions, {"account|label|dummy","count","skip","include_watchonly"} },
{ "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
{ "wallet", "listwallets", &listwallets, {} },
{ "wallet", "loadwallet", &loadwallet, {"filename"} },
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index f44311b0be..c474547b7e 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -16,6 +16,7 @@
#include <validation.h>
#include <wallet/coincontrol.h>
#include <wallet/test/wallet_test_fixture.h>
+#include <policy/policy.h>
#include <boost/test/unit_test.hpp>
#include <univalue.h>
@@ -374,4 +375,47 @@ BOOST_FIXTURE_TEST_CASE(wallet_disableprivkeys, TestChain100Setup)
BOOST_CHECK(!wallet->GetKeyFromPool(pubkey, false));
}
+// Explicit calculation which is used to test the wallet constant
+// We get the same virtual size due to rounding(weight/4) for both use_max_sig values
+static size_t CalculateNestedKeyhashInputSize(bool use_max_sig)
+{
+ // Generate ephemeral valid pubkey
+ CKey key;
+ key.MakeNewKey(true);
+ CPubKey pubkey = key.GetPubKey();
+
+ // Generate pubkey hash
+ uint160 key_hash(Hash160(pubkey.begin(), pubkey.end()));
+
+ // Create inner-script to enter into keystore. Key hash can't be 0...
+ CScript inner_script = CScript() << OP_0 << std::vector<unsigned char>(key_hash.begin(), key_hash.end());
+
+ // Create outer P2SH script for the output
+ uint160 script_id(Hash160(inner_script.begin(), inner_script.end()));
+ CScript script_pubkey = CScript() << OP_HASH160 << std::vector<unsigned char>(script_id.begin(), script_id.end()) << OP_EQUAL;
+
+ // Add inner-script to key store and key to watchonly
+ CBasicKeyStore keystore;
+ keystore.AddCScript(inner_script);
+ keystore.AddKeyPubKey(key, pubkey);
+
+ // Fill in dummy signatures for fee calculation.
+ SignatureData sig_data;
+
+ if (!ProduceSignature(keystore, use_max_sig ? DUMMY_MAXIMUM_SIGNATURE_CREATOR : DUMMY_SIGNATURE_CREATOR, script_pubkey, sig_data)) {
+ // We're hand-feeding it correct arguments; shouldn't happen
+ assert(false);
+ }
+
+ CTxIn tx_in;
+ UpdateInput(tx_in, sig_data);
+ return (size_t)GetVirtualTransactionInputSize(tx_in);
+}
+
+BOOST_FIXTURE_TEST_CASE(dummy_input_size_test, TestChain100Setup)
+{
+ BOOST_CHECK_EQUAL(CalculateNestedKeyhashInputSize(false), DUMMY_NESTED_P2WPKH_INPUT_SIZE);
+ BOOST_CHECK_EQUAL(CalculateNestedKeyhashInputSize(true), DUMMY_NESTED_P2WPKH_INPUT_SIZE);
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 5a7fdf9a85..060325921f 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1607,8 +1607,6 @@ int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* wallet,
CMutableTransaction txn;
txn.vin.push_back(CTxIn(COutPoint()));
if (!wallet->DummySignInput(txn.vin[0], txout, use_max_sig)) {
- // This should never happen, because IsAllFromMe(ISMINE_SPENDABLE)
- // implies that we can sign for every input.
return -1;
}
return GetVirtualTransactionInputSize(txn.vin[0]);
@@ -2832,7 +2830,14 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
if (pick_new_inputs) {
nValueIn = 0;
setCoins.clear();
- coin_selection_params.change_spend_size = CalculateMaximumSignedInputSize(change_prototype_txout, this);
+ int change_spend_size = CalculateMaximumSignedInputSize(change_prototype_txout, this);
+ // If the wallet doesn't know how to sign change output, assume p2sh-p2wpkh
+ // as lower-bound to allow BnB to do it's thing
+ if (change_spend_size == -1) {
+ coin_selection_params.change_spend_size = DUMMY_NESTED_P2WPKH_INPUT_SIZE;
+ } else {
+ coin_selection_params.change_spend_size = (size_t)change_spend_size;
+ }
coin_selection_params.effective_fee = nFeeRateNeeded;
if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, coin_control, coin_selection_params, bnb_used))
{
@@ -2846,6 +2851,8 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
return false;
}
}
+ } else {
+ bnb_used = false;
}
const CAmount nChange = nValueIn - nValueToSelect;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 57b22c0e49..7b791ae416 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -64,6 +64,9 @@ static const bool DEFAULT_WALLET_RBF = false;
static const bool DEFAULT_WALLETBROADCAST = true;
static const bool DEFAULT_DISABLE_WALLET = false;
+//! Pre-calculated constants for input size estimation in *virtual size*
+static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE = 91;
+
class CBlockIndex;
class CCoinControl;
class COutput;
diff --git a/test/functional/example_test.py b/test/functional/example_test.py
index 714d977380..8d954b70f6 100755
--- a/test/functional/example_test.py
+++ b/test/functional/example_test.py
@@ -15,8 +15,8 @@ from collections import defaultdict
# Avoid wildcard * imports if possible
from test_framework.blocktools import (create_block, create_coinbase)
+from test_framework.messages import CInv
from test_framework.mininode import (
- CInv,
P2PInterface,
mininode_lock,
msg_block,
@@ -67,10 +67,11 @@ def custom_function():
# self.log.info("running custom_function") # Oops! Can't run self.log outside the BitcoinTestFramework
pass
+
class ExampleTest(BitcoinTestFramework):
# Each functional test is a subclass of the BitcoinTestFramework class.
- # Override the set_test_params(), add_options(), setup_chain(), setup_network()
+ # Override the set_test_params(), skip_test_if_missing_module(), add_options(), setup_chain(), setup_network()
# and setup_nodes() methods to customize the test setup as required.
def set_test_params(self):
@@ -84,6 +85,9 @@ class ExampleTest(BitcoinTestFramework):
# self.log.info("I've finished set_test_params") # Oops! Can't run self.log before run_test()
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
# Use add_options() to add specific command-line options for your test.
# In practice this is not used very much, since the tests are mostly written
# to be run in automated environments without command-line options.
@@ -111,7 +115,7 @@ class ExampleTest(BitcoinTestFramework):
# sync_all() should not include node2, since we're not expecting it to
# sync.
connect_nodes(self.nodes[0], 1)
- self.sync_all([self.nodes[0:1]])
+ self.sync_all([self.nodes[0:2]])
# Use setup_nodes() to customize the node start behaviour (for example if
# you don't want to start all nodes at the start of the test).
@@ -135,7 +139,7 @@ class ExampleTest(BitcoinTestFramework):
# Generating a block on one of the nodes will get us out of IBD
blocks = [int(self.nodes[0].generate(nblocks=1)[0], 16)]
- self.sync_all([self.nodes[0:1]])
+ self.sync_all([self.nodes[0:2]])
# Notice above how we called an RPC by calling a method with the same
# name on the node object. Notice also how we used a keyword argument
diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py
index 4a9445f503..8466f851ca 100755
--- a/test/functional/feature_bip68_sequence.py
+++ b/test/functional/feature_bip68_sequence.py
@@ -25,6 +25,9 @@ class BIP68Test(BitcoinTestFramework):
self.num_nodes = 2
self.extra_args = [[], ["-acceptnonstdtxn=0"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index 79ed902871..a1ded5200c 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -75,6 +75,9 @@ class FullBlockTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.extra_args = [[]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
node = self.nodes[0] # convenience reference to the node
@@ -169,7 +172,7 @@ class FullBlockTest(BitcoinTestFramework):
self.log.info("Reject a block where the miner creates too much coinbase reward")
self.move_tip(6)
b9 = self.next_block(9, spend=out[4], additional_coinbase_value=1)
- self.sync_blocks([b9], False, 16, b'bad-cb-amount', reconnect=True)
+ self.sync_blocks([b9], success=False, reject_code=16, reject_reason=b'bad-cb-amount', reconnect=True)
# Create a fork that ends in a block with too much fee (the one that causes the reorg)
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@@ -181,7 +184,7 @@ class FullBlockTest(BitcoinTestFramework):
self.sync_blocks([b10], False)
b11 = self.next_block(11, spend=out[4], additional_coinbase_value=1)
- self.sync_blocks([b11], False, 16, b'bad-cb-amount', reconnect=True)
+ self.sync_blocks([b11], success=False, reject_code=16, reject_reason=b'bad-cb-amount', reconnect=True)
# Try again, but with a valid fork first
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@@ -194,7 +197,7 @@ class FullBlockTest(BitcoinTestFramework):
b13 = self.next_block(13, spend=out[4])
self.save_spendable_output()
b14 = self.next_block(14, spend=out[5], additional_coinbase_value=1)
- self.sync_blocks([b12, b13, b14], False, 16, b'bad-cb-amount', reconnect=True)
+ self.sync_blocks([b12, b13, b14], success=False, reject_code=16, reject_reason=b'bad-cb-amount', reconnect=True)
# New tip should be b13.
assert_equal(node.getbestblockhash(), b13.hash)
@@ -213,7 +216,7 @@ class FullBlockTest(BitcoinTestFramework):
self.log.info("Reject a block with too many checksigs")
too_many_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS))
b16 = self.next_block(16, spend=out[6], script=too_many_checksigs)
- self.sync_blocks([b16], False, 16, b'bad-blk-sigops', reconnect=True)
+ self.sync_blocks([b16], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
# Attempt to spend a transaction created on a different fork
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@@ -222,7 +225,7 @@ class FullBlockTest(BitcoinTestFramework):
self.log.info("Reject a block with a spend from a re-org'ed out tx")
self.move_tip(15)
b17 = self.next_block(17, spend=txout_b3)
- self.sync_blocks([b17], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True)
+ self.sync_blocks([b17], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
# Attempt to spend a transaction created on a different fork (on a fork this time)
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@@ -235,7 +238,7 @@ class FullBlockTest(BitcoinTestFramework):
self.sync_blocks([b18], False)
b19 = self.next_block(19, spend=out[6])
- self.sync_blocks([b19], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True)
+ self.sync_blocks([b19], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
# Attempt to spend a coinbase at depth too low
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@@ -244,7 +247,7 @@ class FullBlockTest(BitcoinTestFramework):
self.log.info("Reject a block spending an immature coinbase.")
self.move_tip(15)
b20 = self.next_block(20, spend=out[7])
- self.sync_blocks([b20], False, 16, b'bad-txns-premature-spend-of-coinbase')
+ self.sync_blocks([b20], success=False, reject_code=16, reject_reason=b'bad-txns-premature-spend-of-coinbase')
# Attempt to spend a coinbase at depth too low (on a fork this time)
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@@ -257,7 +260,7 @@ class FullBlockTest(BitcoinTestFramework):
self.sync_blocks([b21], False)
b22 = self.next_block(22, spend=out[5])
- self.sync_blocks([b22], False, 16, b'bad-txns-premature-spend-of-coinbase')
+ self.sync_blocks([b22], success=False, reject_code=16, reject_reason=b'bad-txns-premature-spend-of-coinbase')
# Create a block on either side of MAX_BLOCK_BASE_SIZE and make sure its accepted/rejected
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@@ -286,7 +289,7 @@ class FullBlockTest(BitcoinTestFramework):
tx.vout = [CTxOut(0, script_output)]
b24 = self.update_block(24, [tx])
assert_equal(len(b24.serialize()), MAX_BLOCK_BASE_SIZE + 1)
- self.sync_blocks([b24], False, 16, b'bad-blk-length', reconnect=True)
+ self.sync_blocks([b24], success=False, reject_code=16, reject_reason=b'bad-blk-length', reconnect=True)
b25 = self.next_block(25, spend=out[7])
self.sync_blocks([b25], False)
@@ -304,7 +307,7 @@ class FullBlockTest(BitcoinTestFramework):
# update_block causes the merkle root to get updated, even with no new
# transactions, and updates the required state.
b26 = self.update_block(26, [])
- self.sync_blocks([b26], False, 16, b'bad-cb-length', reconnect=True)
+ self.sync_blocks([b26], success=False, reject_code=16, reject_reason=b'bad-cb-length', reconnect=True)
# Extend the b26 chain to make sure bitcoind isn't accepting b26
b27 = self.next_block(27, spend=out[7])
@@ -316,7 +319,7 @@ class FullBlockTest(BitcoinTestFramework):
b28.vtx[0].vin[0].scriptSig = b'\x00' * 101
b28.vtx[0].rehash()
b28 = self.update_block(28, [])
- self.sync_blocks([b28], False, 16, b'bad-cb-length', reconnect=True)
+ self.sync_blocks([b28], success=False, reject_code=16, reject_reason=b'bad-cb-length', reconnect=True)
# Extend the b28 chain to make sure bitcoind isn't accepting b28
b29 = self.next_block(29, spend=out[7])
@@ -352,7 +355,7 @@ class FullBlockTest(BitcoinTestFramework):
too_many_multisigs = CScript([OP_CHECKMULTISIG] * (MAX_BLOCK_SIGOPS // 20))
b32 = self.next_block(32, spend=out[9], script=too_many_multisigs)
assert_equal(get_legacy_sigopcount_block(b32), MAX_BLOCK_SIGOPS + 1)
- self.sync_blocks([b32], False, 16, b'bad-blk-sigops', reconnect=True)
+ self.sync_blocks([b32], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
# CHECKMULTISIGVERIFY
self.log.info("Accept a block with the max number of OP_CHECKMULTISIGVERIFY sigops")
@@ -365,7 +368,7 @@ class FullBlockTest(BitcoinTestFramework):
self.log.info("Reject a block with too many OP_CHECKMULTISIGVERIFY sigops")
too_many_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * (MAX_BLOCK_SIGOPS // 20))
b34 = self.next_block(34, spend=out[10], script=too_many_multisigs)
- self.sync_blocks([b34], False, 16, b'bad-blk-sigops', reconnect=True)
+ self.sync_blocks([b34], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
# CHECKSIGVERIFY
self.log.info("Accept a block with the max number of OP_CHECKSIGVERIFY sigops")
@@ -378,7 +381,7 @@ class FullBlockTest(BitcoinTestFramework):
self.log.info("Reject a block with too many OP_CHECKSIGVERIFY sigops")
too_many_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS))
b36 = self.next_block(36, spend=out[11], script=too_many_checksigs)
- self.sync_blocks([b36], False, 16, b'bad-blk-sigops', reconnect=True)
+ self.sync_blocks([b36], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
# Check spending of a transaction in a block which failed to connect
#
@@ -395,12 +398,12 @@ class FullBlockTest(BitcoinTestFramework):
txout_b37 = b37.vtx[1]
tx = self.create_and_sign_transaction(out[11], 0)
b37 = self.update_block(37, [tx])
- self.sync_blocks([b37], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True)
+ self.sync_blocks([b37], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
# attempt to spend b37's first non-coinbase tx, at which point b37 was still considered valid
self.move_tip(35)
b38 = self.next_block(38, spend=txout_b37)
- self.sync_blocks([b38], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True)
+ self.sync_blocks([b38], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
# Check P2SH SigOp counting
#
@@ -492,7 +495,7 @@ class FullBlockTest(BitcoinTestFramework):
tx.rehash()
new_txs.append(tx)
self.update_block(40, new_txs)
- self.sync_blocks([b40], False, 16, b'bad-blk-sigops', reconnect=True)
+ self.sync_blocks([b40], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
# same as b40, but one less sigop
self.log.info("Accept a block with the max number of P2SH sigops")
@@ -555,7 +558,7 @@ class FullBlockTest(BitcoinTestFramework):
self.block_heights[b45.sha256] = self.block_heights[self.tip.sha256] + 1
self.tip = b45
self.blocks[45] = b45
- self.sync_blocks([b45], False, 16, b'bad-cb-missing', reconnect=True)
+ self.sync_blocks([b45], success=False, reject_code=16, reject_reason=b'bad-cb-missing', reconnect=True)
self.log.info("Reject a block with no transactions")
self.move_tip(44)
@@ -570,7 +573,7 @@ class FullBlockTest(BitcoinTestFramework):
self.tip = b46
assert 46 not in self.blocks
self.blocks[46] = b46
- self.sync_blocks([b46], False, 16, b'bad-blk-length', reconnect=True)
+ self.sync_blocks([b46], success=False, reject_code=16, reject_reason=b'bad-blk-length', reconnect=True)
self.log.info("Reject a block with invalid work")
self.move_tip(44)
@@ -593,7 +596,7 @@ class FullBlockTest(BitcoinTestFramework):
b49 = self.next_block(49)
b49.hashMerkleRoot += 1
b49.solve()
- self.sync_blocks([b49], False, 16, b'bad-txnmrklroot', reconnect=True)
+ self.sync_blocks([b49], success=False, reject_code=16, reject_reason=b'bad-txnmrklroot', reconnect=True)
self.log.info("Reject a block with incorrect POW limit")
self.move_tip(44)
@@ -607,7 +610,7 @@ class FullBlockTest(BitcoinTestFramework):
b51 = self.next_block(51)
cb2 = create_coinbase(51, self.coinbase_pubkey)
b51 = self.update_block(51, [cb2])
- self.sync_blocks([b51], False, 16, b'bad-cb-multiple', reconnect=True)
+ self.sync_blocks([b51], success=False, reject_code=16, reject_reason=b'bad-cb-multiple', reconnect=True)
self.log.info("Reject a block with duplicate transactions")
# Note: txns have to be in the right position in the merkle tree to trigger this error
@@ -615,7 +618,7 @@ class FullBlockTest(BitcoinTestFramework):
b52 = self.next_block(52, spend=out[15])
tx = self.create_tx(b52.vtx[1], 0, 1)
b52 = self.update_block(52, [tx, tx])
- self.sync_blocks([b52], False, 16, b'bad-txns-duplicate', reconnect=True)
+ self.sync_blocks([b52], success=False, reject_code=16, reject_reason=b'bad-txns-duplicate', reconnect=True)
# Test block timestamps
# -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15)
@@ -682,7 +685,7 @@ class FullBlockTest(BitcoinTestFramework):
assert_equal(len(b56.vtx), 3)
b56 = self.update_block(56, [tx1])
assert_equal(b56.hash, b57.hash)
- self.sync_blocks([b56], False, 16, b'bad-txns-duplicate', reconnect=True)
+ self.sync_blocks([b56], success=False, reject_code=16, reject_reason=b'bad-txns-duplicate', reconnect=True)
# b57p2 - a good block with 6 tx'es, don't submit until end
self.move_tip(55)
@@ -702,7 +705,7 @@ class FullBlockTest(BitcoinTestFramework):
assert_equal(b56p2.hash, b57p2.hash)
assert_equal(len(b56p2.vtx), 6)
b56p2 = self.update_block("b56p2", [tx3, tx4])
- self.sync_blocks([b56p2], False, 16, b'bad-txns-duplicate', reconnect=True)
+ self.sync_blocks([b56p2], success=False, reject_code=16, reject_reason=b'bad-txns-duplicate', reconnect=True)
self.move_tip("57p2")
self.sync_blocks([b57p2], True)
@@ -727,7 +730,7 @@ class FullBlockTest(BitcoinTestFramework):
tx.vout.append(CTxOut(0, b""))
tx.calc_sha256()
b58 = self.update_block(58, [tx])
- self.sync_blocks([b58], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True)
+ self.sync_blocks([b58], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
# tx with output value > input value
self.log.info("Reject a block with a transaction with outputs > inputs")
@@ -735,7 +738,7 @@ class FullBlockTest(BitcoinTestFramework):
b59 = self.next_block(59)
tx = self.create_and_sign_transaction(out[17], 51 * COIN)
b59 = self.update_block(59, [tx])
- self.sync_blocks([b59], False, 16, b'bad-txns-in-belowout', reconnect=True)
+ self.sync_blocks([b59], success=False, reject_code=16, reject_reason=b'bad-txns-in-belowout', reconnect=True)
# reset to good chain
self.move_tip(57)
@@ -759,7 +762,7 @@ class FullBlockTest(BitcoinTestFramework):
b61.vtx[0].rehash()
b61 = self.update_block(61, [])
assert_equal(b60.vtx[0].serialize(), b61.vtx[0].serialize())
- self.sync_blocks([b61], False, 16, b'bad-txns-BIP30', reconnect=True)
+ self.sync_blocks([b61], success=False, reject_code=16, reject_reason=b'bad-txns-BIP30', reconnect=True)
# Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests)
#
@@ -776,7 +779,7 @@ class FullBlockTest(BitcoinTestFramework):
assert(tx.vin[0].nSequence < 0xffffffff)
tx.calc_sha256()
b62 = self.update_block(62, [tx])
- self.sync_blocks([b62], False, 16, b'bad-txns-nonfinal')
+ self.sync_blocks([b62], success=False, reject_code=16, reject_reason=b'bad-txns-nonfinal')
# Test a non-final coinbase is also rejected
#
@@ -790,7 +793,7 @@ class FullBlockTest(BitcoinTestFramework):
b63.vtx[0].vin[0].nSequence = 0xDEADBEEF
b63.vtx[0].rehash()
b63 = self.update_block(63, [])
- self.sync_blocks([b63], False, 16, b'bad-txns-nonfinal')
+ self.sync_blocks([b63], success=False, reject_code=16, reject_reason=b'bad-txns-nonfinal')
# This checks that a block with a bloated VARINT between the block_header and the array of tx such that
# the block is > MAX_BLOCK_BASE_SIZE with the bloated varint, but <= MAX_BLOCK_BASE_SIZE without the bloated varint,
@@ -824,7 +827,7 @@ class FullBlockTest(BitcoinTestFramework):
tx.vin.append(CTxIn(COutPoint(b64a.vtx[1].sha256, 0)))
b64a = self.update_block("64a", [tx])
assert_equal(len(b64a.serialize()), MAX_BLOCK_BASE_SIZE + 8)
- self.sync_blocks([b64a], False, 1, b'error parsing message')
+ self.sync_blocks([b64a], success=False, reject_code=1, reject_reason=b'error parsing message')
# bitcoind doesn't disconnect us for sending a bloated block, but if we subsequently
# resend the header message, it won't send us the getdata message again. Just
@@ -866,7 +869,7 @@ class FullBlockTest(BitcoinTestFramework):
tx1 = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue)
tx2 = self.create_and_sign_transaction(tx1, 1)
b66 = self.update_block(66, [tx2, tx1])
- self.sync_blocks([b66], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True)
+ self.sync_blocks([b66], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
# Attempt to double-spend a transaction created in a block
#
@@ -881,7 +884,7 @@ class FullBlockTest(BitcoinTestFramework):
tx2 = self.create_and_sign_transaction(tx1, 1)
tx3 = self.create_and_sign_transaction(tx1, 2)
b67 = self.update_block(67, [tx1, tx2, tx3])
- self.sync_blocks([b67], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True)
+ self.sync_blocks([b67], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
# More tests of block subsidy
#
@@ -900,7 +903,7 @@ class FullBlockTest(BitcoinTestFramework):
b68 = self.next_block(68, additional_coinbase_value=10)
tx = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue - 9)
b68 = self.update_block(68, [tx])
- self.sync_blocks([b68], False, 16, b'bad-cb-amount', reconnect=True)
+ self.sync_blocks([b68], success=False, reject_code=16, reject_reason=b'bad-cb-amount', reconnect=True)
self.log.info("Accept a block claiming the correct subsidy in the coinbase transaction")
self.move_tip(65)
@@ -924,7 +927,7 @@ class FullBlockTest(BitcoinTestFramework):
tx.vin.append(CTxIn(COutPoint(bogus_tx.sha256, 0), b"", 0xffffffff))
tx.vout.append(CTxOut(1, b""))
b70 = self.update_block(70, [tx])
- self.sync_blocks([b70], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True)
+ self.sync_blocks([b70], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
# Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks)
#
@@ -949,7 +952,7 @@ class FullBlockTest(BitcoinTestFramework):
assert_equal(b72.sha256, b71.sha256)
self.move_tip(71)
- self.sync_blocks([b71], False, 16, b'bad-txns-duplicate', reconnect=True)
+ self.sync_blocks([b71], success=False, reject_code=16, reject_reason=b'bad-txns-duplicate', reconnect=True)
self.move_tip(72)
self.sync_blocks([b72], True)
@@ -987,7 +990,7 @@ class FullBlockTest(BitcoinTestFramework):
tx = self.create_and_sign_transaction(out[22], 1, CScript(a))
b73 = self.update_block(73, [tx])
assert_equal(get_legacy_sigopcount_block(b73), MAX_BLOCK_SIGOPS + 1)
- self.sync_blocks([b73], False, 16, b'bad-blk-sigops', reconnect=True)
+ self.sync_blocks([b73], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
# b74/75 - if we push an invalid script element, all prevous sigops are counted,
# but sigops after the element are not counted.
@@ -1011,7 +1014,7 @@ class FullBlockTest(BitcoinTestFramework):
a[MAX_BLOCK_SIGOPS + 4] = 0xff
tx = self.create_and_sign_transaction(out[22], 1, CScript(a))
b74 = self.update_block(74, [tx])
- self.sync_blocks([b74], False, 16, b'bad-blk-sigops', reconnect=True)
+ self.sync_blocks([b74], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
self.move_tip(72)
b75 = self.next_block(75)
@@ -1160,7 +1163,7 @@ class FullBlockTest(BitcoinTestFramework):
b89a = self.next_block("89a", spend=out[32])
tx = self.create_tx(tx1, 0, 0, CScript([OP_TRUE]))
b89a = self.update_block("89a", [tx])
- self.sync_blocks([b89a], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True)
+ self.sync_blocks([b89a], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
self.log.info("Test a re-org of one week's worth of blocks (1088 blocks)")
diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py
index 56f91651a8..1296cdb497 100755
--- a/test/functional/feature_blocksdir.py
+++ b/test/functional/feature_blocksdir.py
@@ -16,6 +16,9 @@ class BlocksdirTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 1
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.stop_node(0)
shutil.rmtree(self.nodes[0].datadir)
diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py
index 8460291831..9a53b62abd 100755
--- a/test/functional/feature_cltv.py
+++ b/test/functional/feature_cltv.py
@@ -57,6 +57,9 @@ class BIP65Test(BitcoinTestFramework):
self.extra_args = [['-whitelist=127.0.0.1']]
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.nodes[0].add_p2p_connection(P2PInterface())
diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py
index 9be59b32b4..1124119e2b 100755
--- a/test/functional/feature_config_args.py
+++ b/test/functional/feature_config_args.py
@@ -14,6 +14,9 @@ class ConfArgsTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 1
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def test_config_file_parser(self):
# Assume node is stopped
diff --git a/test/functional/feature_csv_activation.py b/test/functional/feature_csv_activation.py
index af14feb471..a2796efa2a 100755
--- a/test/functional/feature_csv_activation.py
+++ b/test/functional/feature_csv_activation.py
@@ -145,6 +145,9 @@ class BIP68_112_113Test(BitcoinTestFramework):
self.setup_clean_chain = True
self.extra_args = [['-whitelist=127.0.0.1', '-blockversion=4', '-addresstype=legacy']]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def generate_blocks(self, number, version, test_blocks=None):
if test_blocks is None:
test_blocks = []
diff --git a/test/functional/feature_dbcrash.py b/test/functional/feature_dbcrash.py
index d612dbe2bc..ae1eacf2d7 100755
--- a/test/functional/feature_dbcrash.py
+++ b/test/functional/feature_dbcrash.py
@@ -63,6 +63,9 @@ class ChainstateWriteCrashTest(BitcoinTestFramework):
self.node3_args = ["-blockmaxweight=4000000"]
self.extra_args = [self.node0_args, self.node1_args, self.node2_args, self.node3_args]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
self.add_nodes(self.num_nodes, extra_args=self.extra_args)
self.start_nodes()
diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py
index 53e94c436a..f9e1ef0231 100755
--- a/test/functional/feature_dersig.py
+++ b/test/functional/feature_dersig.py
@@ -45,6 +45,9 @@ class BIP66Test(BitcoinTestFramework):
self.extra_args = [['-whitelist=127.0.0.1']]
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.nodes[0].add_p2p_connection(P2PInterface())
diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py
index 709910f2e4..aaab4279b5 100755
--- a/test/functional/feature_fee_estimation.py
+++ b/test/functional/feature_fee_estimation.py
@@ -126,6 +126,9 @@ class EstimateFeeTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 3
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
"""
We'll setup the network to have 3 nodes that all mine with different parameters.
@@ -168,6 +171,11 @@ class EstimateFeeTest(BitcoinTestFramework):
newmem.append(utx)
self.memutxo = newmem
+ def import_deterministic_coinbase_privkeys(self):
+ self.start_nodes()
+ super().import_deterministic_coinbase_privkeys()
+ self.stop_nodes()
+
def run_test(self):
self.log.info("This test is time consuming, please be patient")
self.log.info("Splitting inputs so we can generate tx's")
diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py
index 8bb7e02695..a74c413440 100755
--- a/test/functional/feature_logging.py
+++ b/test/functional/feature_logging.py
@@ -15,6 +15,9 @@ class LoggingTest(BitcoinTestFramework):
self.num_nodes = 1
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def relative_log_path(self, name):
return os.path.join(self.nodes[0].datadir, "regtest", name)
diff --git a/test/functional/feature_maxuploadtarget.py b/test/functional/feature_maxuploadtarget.py
index a81ebb4220..87c318de9a 100755
--- a/test/functional/feature_maxuploadtarget.py
+++ b/test/functional/feature_maxuploadtarget.py
@@ -40,6 +40,9 @@ class MaxUploadTest(BitcoinTestFramework):
# Cache for utxos, as the listunspent may take a long time later in the test
self.utxo_cache = []
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
# Before we connect anything, we first set the time on the node
# to be in the past, otherwise things break because the CNode
diff --git a/test/functional/feature_minchainwork.py b/test/functional/feature_minchainwork.py
index a1cced0bc7..5d180c2244 100755
--- a/test/functional/feature_minchainwork.py
+++ b/test/functional/feature_minchainwork.py
@@ -31,6 +31,9 @@ class MinimumChainWorkTest(BitcoinTestFramework):
self.extra_args = [[], ["-minimumchainwork=0x65"], ["-minimumchainwork=0x65"]]
self.node_min_work = [0, 101, 101]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
# This test relies on the chain setup being:
# node0 <- node1 <- node2
diff --git a/test/functional/feature_notifications.py b/test/functional/feature_notifications.py
index 71e5e493aa..25a7329a0d 100755
--- a/test/functional/feature_notifications.py
+++ b/test/functional/feature_notifications.py
@@ -13,6 +13,9 @@ class NotificationsTest(BitcoinTestFramework):
self.num_nodes = 2
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
self.block_filename = os.path.join(self.options.tmpdir, "blocks.txt")
diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py
index 9d1805ec2d..a79cc3d34b 100755
--- a/test/functional/feature_nulldummy.py
+++ b/test/functional/feature_nulldummy.py
@@ -44,9 +44,12 @@ class NULLDUMMYTest(BitcoinTestFramework):
# normal segwit activation here (and don't use the default always-on behaviour).
self.extra_args = [['-whitelist=127.0.0.1', '-vbparams=segwit:0:999999999999', '-addresstype=legacy', "-deprecatedrpc=addwitnessaddress"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.address = self.nodes[0].getnewaddress()
- self.ms_address = self.nodes[0].addmultisigaddress(1,[self.address])['address']
+ self.ms_address = self.nodes[0].addmultisigaddress(1, [self.address])['address']
self.wit_address = self.nodes[0].addwitnessaddress(self.address)
self.wit_ms_address = self.nodes[0].addmultisigaddress(1, [self.address], '', 'p2sh-segwit')['address']
diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py
index c8f4b7f8b5..772151dc4b 100755
--- a/test/functional/feature_pruning.py
+++ b/test/functional/feature_pruning.py
@@ -33,15 +33,20 @@ class PruneTest(BitcoinTestFramework):
# Create nodes 0 and 1 to mine.
# Create node 2 to test pruning.
- self.full_node_default_args = ["-maxreceivebuffer=20000", "-checkblocks=5", "-limitdescendantcount=100", "-limitdescendantsize=5000", "-limitancestorcount=100", "-limitancestorsize=5000" ]
+ self.full_node_default_args = ["-maxreceivebuffer=20000", "-checkblocks=5", "-limitdescendantcount=100", "-limitdescendantsize=5000", "-limitancestorcount=100", "-limitancestorsize=5000"]
# Create nodes 3 and 4 to test manual pruning (they will be re-started with manual pruning later)
# Create nodes 5 to test wallet in prune mode, but do not connect
- self.extra_args = [self.full_node_default_args,
- self.full_node_default_args,
- ["-maxreceivebuffer=20000", "-prune=550"],
- ["-maxreceivebuffer=20000"],
- ["-maxreceivebuffer=20000"],
- ["-prune=550"]]
+ self.extra_args = [
+ self.full_node_default_args,
+ self.full_node_default_args,
+ ["-maxreceivebuffer=20000", "-prune=550"],
+ ["-maxreceivebuffer=20000"],
+ ["-maxreceivebuffer=20000"],
+ ["-prune=550"],
+ ]
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
def setup_network(self):
self.setup_nodes()
diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py
index 6105da810c..d78d75dbad 100755
--- a/test/functional/feature_rbf.py
+++ b/test/functional/feature_rbf.py
@@ -61,17 +61,26 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
return COutPoint(int(txid, 16), 0)
-class ReplaceByFeeTest(BitcoinTestFramework):
+class ReplaceByFeeTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
- self.extra_args= [["-maxorphantx=1000",
- "-whitelist=127.0.0.1",
- "-limitancestorcount=50",
- "-limitancestorsize=101",
- "-limitdescendantcount=200",
- "-limitdescendantsize=101"],
- ["-mempoolreplacement=0"]]
+ self.extra_args = [
+ [
+ "-maxorphantx=1000",
+ "-whitelist=127.0.0.1",
+ "-limitancestorcount=50",
+ "-limitancestorsize=101",
+ "-limitdescendantcount=200",
+ "-limitdescendantsize=101",
+ ],
+ [
+ "-mempoolreplacement=0",
+ ],
+ ]
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
def run_test(self):
# Leave IBD
diff --git a/test/functional/feature_reindex.py b/test/functional/feature_reindex.py
index f30e1191e3..3727eeaeae 100755
--- a/test/functional/feature_reindex.py
+++ b/test/functional/feature_reindex.py
@@ -18,6 +18,9 @@ class ReindexTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 1
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def reindex(self, justchainstate=False):
self.nodes[0].generate(3)
blockcount = self.nodes[0].getblockcount()
diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py
index 13d7758e13..2cbfc26e89 100755
--- a/test/functional/feature_segwit.py
+++ b/test/functional/feature_segwit.py
@@ -46,9 +46,30 @@ class SegWitTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 3
# This test tests SegWit both pre and post-activation, so use the normal BIP9 activation.
- self.extra_args = [["-rpcserialversion=0", "-vbparams=segwit:0:999999999999", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"],
- ["-blockversion=4", "-rpcserialversion=1", "-vbparams=segwit:0:999999999999", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"],
- ["-blockversion=536870915", "-vbparams=segwit:0:999999999999", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"]]
+ self.extra_args = [
+ [
+ "-rpcserialversion=0",
+ "-vbparams=segwit:0:999999999999",
+ "-addresstype=legacy",
+ "-deprecatedrpc=addwitnessaddress",
+ ],
+ [
+ "-blockversion=4",
+ "-rpcserialversion=1",
+ "-vbparams=segwit:0:999999999999",
+ "-addresstype=legacy",
+ "-deprecatedrpc=addwitnessaddress",
+ ],
+ [
+ "-blockversion=536870915",
+ "-vbparams=segwit:0:999999999999",
+ "-addresstype=legacy",
+ "-deprecatedrpc=addwitnessaddress",
+ ],
+ ]
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
def setup_network(self):
super().setup_network()
diff --git a/test/functional/feature_versionbits_warning.py b/test/functional/feature_versionbits_warning.py
index 896c36fa53..cf77720437 100755
--- a/test/functional/feature_versionbits_warning.py
+++ b/test/functional/feature_versionbits_warning.py
@@ -31,6 +31,9 @@ class VersionBitsWarningTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 1
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
# Open and close to create zero-length file
diff --git a/test/functional/interface_bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py
index d3b85ce948..f311858bee 100755
--- a/test/functional/interface_bitcoin_cli.py
+++ b/test/functional/interface_bitcoin_cli.py
@@ -12,6 +12,9 @@ class TestBitcoinCli(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 1
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
"""Main test logic"""
diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py
index 41a1b4a35d..afa9de580f 100755
--- a/test/functional/interface_rest.py
+++ b/test/functional/interface_rest.py
@@ -43,6 +43,9 @@ class RESTTest (BitcoinTestFramework):
self.num_nodes = 2
self.extra_args = [["-rest"], []]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def test_rest_request(self, uri, http_method='GET', req_type=ReqType.JSON, body='', status=200, ret_type=RetType.JSON):
rest_uri = '/rest' + uri
if req_type == ReqType.JSON:
diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py
index 72de696259..c853ba7e3f 100755
--- a/test/functional/interface_zmq.py
+++ b/test/functional/interface_zmq.py
@@ -5,15 +5,16 @@
"""Test the ZMQ notification interface."""
import struct
-from test_framework.test_framework import (
- BitcoinTestFramework, skip_if_no_bitcoind_zmq, skip_if_no_py3_zmq)
+from test_framework.test_framework import BitcoinTestFramework
from test_framework.messages import CTransaction
-from test_framework.util import (assert_equal,
- bytes_to_hex_str,
- hash256,
- )
+from test_framework.util import (
+ assert_equal,
+ bytes_to_hex_str,
+ hash256,
+)
from io import BytesIO
+
class ZMQSubscriber:
def __init__(self, socket, topic):
self.sequence = 0
@@ -37,9 +38,18 @@ class ZMQTest (BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_py3_zmq()
+ self.skip_if_no_bitcoind_zmq()
+ self.skip_if_no_wallet()
+
def setup_nodes(self):
- skip_if_no_py3_zmq()
- skip_if_no_bitcoind_zmq(self)
+ # Import keys
+ self.add_nodes(self.num_nodes)
+ self.start_nodes()
+ super().import_deterministic_coinbase_privkeys()
+ self.stop_nodes()
+
import zmq
# Initialize ZMQ context and socket.
@@ -59,10 +69,12 @@ class ZMQTest (BitcoinTestFramework):
self.rawblock = ZMQSubscriber(socket, b"rawblock")
self.rawtx = ZMQSubscriber(socket, b"rawtx")
- self.extra_args = [["-zmqpub%s=%s" % (sub.topic.decode(), address) for sub in [self.hashblock, self.hashtx, self.rawblock, self.rawtx]], []]
- self.add_nodes(self.num_nodes, self.extra_args)
+ self.nodes[0].extra_args = ["-zmqpub%s=%s" % (sub.topic.decode(), address) for sub in [self.hashblock, self.hashtx, self.rawblock, self.rawtx]]
self.start_nodes()
+ def import_deterministic_coinbase_privkeys(self):
+ pass
+
def run_test(self):
try:
self._zmq_test()
diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
index 44426a0ff7..8847777ba7 100755
--- a/test/functional/mempool_accept.py
+++ b/test/functional/mempool_accept.py
@@ -40,6 +40,9 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
'-acceptnonstdtxn=0', # Try to mimic main-net
]] * self.num_nodes
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def check_mempool_result(self, result_expected, *args, **kwargs):
"""Wrapper to check result of testmempoolaccept on node_0's mempool"""
result_test = self.nodes[0].testmempoolaccept(*args, **kwargs)
diff --git a/test/functional/mempool_limit.py b/test/functional/mempool_limit.py
index 55422b67df..c0918893cd 100755
--- a/test/functional/mempool_limit.py
+++ b/test/functional/mempool_limit.py
@@ -15,6 +15,9 @@ class MempoolLimitTest(BitcoinTestFramework):
self.num_nodes = 1
self.extra_args = [["-maxmempool=5", "-spendzeroconfchange=0"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
txouts = gen_return_txouts()
relayfee = self.nodes[0].getnetworkinfo()['relayfee']
diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py
index da254181fe..9336547a6b 100755
--- a/test/functional/mempool_packages.py
+++ b/test/functional/mempool_packages.py
@@ -18,6 +18,9 @@ class MempoolPackagesTest(BitcoinTestFramework):
self.num_nodes = 2
self.extra_args = [["-maxorphantx=1000"], ["-maxorphantx=1000", "-limitancestorcount=5"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
# Build a transaction that spends parent_txid:vout
# Return amount sent
def chain_transaction(self, node, parent_txid, vout, value, fee, num_outputs):
@@ -34,7 +37,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
return (txid, send_value)
def run_test(self):
- ''' Mine some blocks and have them mature. '''
+ # Mine some blocks and have them mature.
self.nodes[0].generate(101)
utxo = self.nodes[0].listunspent(10)
txid = utxo[0]['txid']
diff --git a/test/functional/mempool_persist.py b/test/functional/mempool_persist.py
index 6e5f89efb8..b4e9d967fd 100755
--- a/test/functional/mempool_persist.py
+++ b/test/functional/mempool_persist.py
@@ -47,6 +47,9 @@ class MempoolPersistTest(BitcoinTestFramework):
self.num_nodes = 3
self.extra_args = [[], ["-persistmempool=0"], []]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
chain_height = self.nodes[0].getblockcount()
assert_equal(chain_height, 200)
diff --git a/test/functional/mempool_reorg.py b/test/functional/mempool_reorg.py
index faa00d56cf..123f0b4c28 100755
--- a/test/functional/mempool_reorg.py
+++ b/test/functional/mempool_reorg.py
@@ -17,6 +17,9 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
alert_filename = None # Set by setup_network
def run_test(self):
diff --git a/test/functional/mempool_resurrect.py b/test/functional/mempool_resurrect.py
index 23939f0be5..845beb551e 100755
--- a/test/functional/mempool_resurrect.py
+++ b/test/functional/mempool_resurrect.py
@@ -13,6 +13,9 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
node0_address = self.nodes[0].getnewaddress()
# Spend block 1/2/3's coinbase transactions
@@ -44,12 +47,11 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
tx = self.nodes[0].gettransaction(txid)
assert(tx["confirmations"] > 0)
- # Use invalidateblock to re-org back; all transactions should
- # end up unconfirmed and back in the mempool
+ # Use invalidateblock to re-org back
for node in self.nodes:
node.invalidateblock(blocks[0])
- # mempool should be empty, all txns confirmed
+ # All txns should be back in mempool with 0 confirmations
assert_equal(set(self.nodes[0].getrawmempool()), set(spends1_id+spends2_id))
for txid in spends1_id+spends2_id:
tx = self.nodes[0].gettransaction(txid)
diff --git a/test/functional/mempool_spend_coinbase.py b/test/functional/mempool_spend_coinbase.py
index ce3bc3b7e0..854d506f0d 100755
--- a/test/functional/mempool_spend_coinbase.py
+++ b/test/functional/mempool_spend_coinbase.py
@@ -21,6 +21,9 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
chain_height = self.nodes[0].getblockcount()
assert_equal(chain_height, 200)
diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py
index fa20a2d2f4..5b53df832a 100755
--- a/test/functional/mining_basic.py
+++ b/test/functional/mining_basic.py
@@ -31,6 +31,9 @@ class MiningTest(BitcoinTestFramework):
self.num_nodes = 2
self.setup_clean_chain = False
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
node = self.nodes[0]
diff --git a/test/functional/mining_getblocktemplate_longpoll.py b/test/functional/mining_getblocktemplate_longpoll.py
index 2bcbe8db7b..7d27a2a83a 100755
--- a/test/functional/mining_getblocktemplate_longpoll.py
+++ b/test/functional/mining_getblocktemplate_longpoll.py
@@ -28,6 +28,9 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.log.info("Warning: this test will take about 70 seconds in the best case. Be patient.")
self.nodes[0].generate(10)
@@ -70,4 +73,3 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
if __name__ == '__main__':
GetBlockTemplateLPTest().main()
-
diff --git a/test/functional/mining_prioritisetransaction.py b/test/functional/mining_prioritisetransaction.py
index bb0cc082ab..92590717f3 100755
--- a/test/functional/mining_prioritisetransaction.py
+++ b/test/functional/mining_prioritisetransaction.py
@@ -16,6 +16,9 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
self.num_nodes = 2
self.extra_args = [["-printpriority=1"], ["-printpriority=1"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
# Test `prioritisetransaction` required parameters
assert_raises_rpc_error(-1, "prioritisetransaction", self.nodes[0].prioritisetransaction)
diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py
index 5cec5dc6f0..3a5bdf806b 100755
--- a/test/functional/p2p_compactblocks.py
+++ b/test/functional/p2p_compactblocks.py
@@ -102,6 +102,9 @@ class CompactBlocksTest(BitcoinTestFramework):
self.extra_args = [["-vbparams=segwit:0:0"], ["-vbparams=segwit:0:999999999999", "-txindex", "-deprecatedrpc=addwitnessaddress"]]
self.utxos = []
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def build_block_on_tip(self, node, segwit=False):
height = node.getblockcount()
tip = node.getbestblockhash()
diff --git a/test/functional/p2p_feefilter.py b/test/functional/p2p_feefilter.py
index 3bc7734e75..d589519e45 100755
--- a/test/functional/p2p_feefilter.py
+++ b/test/functional/p2p_feefilter.py
@@ -42,6 +42,9 @@ class FeeFilterTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
node1 = self.nodes[1]
node0 = self.nodes[0]
diff --git a/test/functional/p2p_fingerprint.py b/test/functional/p2p_fingerprint.py
index 4a6ffced93..884fb4b063 100755
--- a/test/functional/p2p_fingerprint.py
+++ b/test/functional/p2p_fingerprint.py
@@ -30,6 +30,9 @@ class P2PFingerprintTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 1
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
# Build a chain of blocks on top of given one
def build_chain(self, nblocks, prev_hash, prev_height, prev_median_time):
blocks = []
diff --git a/test/functional/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py
index e910bedd09..a46b0a02a6 100755
--- a/test/functional/p2p_invalid_block.py
+++ b/test/functional/p2p_invalid_block.py
@@ -24,6 +24,9 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.extra_args = [["-whitelist=127.0.0.1"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
# Add p2p connection to node0
node = self.nodes[0] # convenience reference to the node
@@ -42,7 +45,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
# Save the coinbase for later
block1 = block
tip = block.sha256
- node.p2p.send_blocks_and_test([block1], node, True)
+ node.p2p.send_blocks_and_test([block1], node, success=True)
self.log.info("Mature the block.")
node.generate(100)
@@ -77,9 +80,19 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
block2.vtx.append(tx2)
assert_equal(block2.hashMerkleRoot, block2.calc_merkle_root())
assert_equal(orig_hash, block2.rehash())
- assert(block2_orig.vtx != block2.vtx)
+ assert block2_orig.vtx != block2.vtx
+
+ node.p2p.send_blocks_and_test([block2], node, success=False, reject_code=16, reject_reason=b'bad-txns-duplicate')
+
+ # Check transactions for duplicate inputs
+ self.log.info("Test duplicate input block.")
- node.p2p.send_blocks_and_test([block2], node, False, False, 16, b'bad-txns-duplicate')
+ block2_orig.vtx[2].vin.append(block2_orig.vtx[2].vin[0])
+ block2_orig.vtx[2].rehash()
+ block2_orig.hashMerkleRoot = block2_orig.calc_merkle_root()
+ block2_orig.rehash()
+ block2_orig.solve()
+ node.p2p.send_blocks_and_test([block2_orig], node, success=False, reject_reason=b'bad-txns-inputs-duplicate')
self.log.info("Test very broken block.")
@@ -92,7 +105,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
block3.rehash()
block3.solve()
- node.p2p.send_blocks_and_test([block3], node, False, False, 16, b'bad-cb-amount')
+ node.p2p.send_blocks_and_test([block3], node, success=False, reject_code=16, reject_reason=b'bad-cb-amount')
if __name__ == '__main__':
InvalidBlockRequestTest().main()
diff --git a/test/functional/p2p_invalid_locator.py b/test/functional/p2p_invalid_locator.py
index 3b1654f920..4cc43a4fa4 100755
--- a/test/functional/p2p_invalid_locator.py
+++ b/test/functional/p2p_invalid_locator.py
@@ -15,6 +15,9 @@ class InvalidLocatorTest(BitcoinTestFramework):
self.num_nodes = 1
self.setup_clean_chain = False
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
node = self.nodes[0] # convenience reference to the node
node.generate(1) # Get node out of IBD
diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py
index 0aa5e21103..5cf0a75ab2 100755
--- a/test/functional/p2p_invalid_tx.py
+++ b/test/functional/p2p_invalid_tx.py
@@ -26,6 +26,9 @@ class InvalidTxRequestTest(BitcoinTestFramework):
self.num_nodes = 1
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def bootstrap_p2p(self, *, num_connections=1):
"""Add a P2P connection to the node.
@@ -136,11 +139,16 @@ class InvalidTxRequestTest(BitcoinTestFramework):
# restart node with sending BIP61 messages disabled, check that it disconnects without sending the reject message
self.log.info('Test a transaction that is rejected, with BIP61 disabled')
- self.restart_node(0, ['-enablebip61=0','-persistmempool=0'])
+ self.restart_node(0, ['-enablebip61=0', '-persistmempool=0'])
self.reconnect_p2p(num_connections=1)
- node.p2p.send_txs_and_test([tx1], node, success=False, expect_disconnect=True)
+ with node.assert_debug_log(expected_msgs=[
+ "{} from peer=0 was not accepted: mandatory-script-verify-flag-failed (Invalid OP_IF construction) (code 16)".format(tx1.hash),
+ "disconnecting peer=0",
+ ]):
+ node.p2p.send_txs_and_test([tx1], node, success=False, expect_disconnect=True)
# send_txs_and_test will have waited for disconnect, so we can safely check that no reject has been received
assert_equal(node.p2p.reject_code_received, None)
+
if __name__ == '__main__':
InvalidTxRequestTest().main()
diff --git a/test/functional/p2p_leak.py b/test/functional/p2p_leak.py
index dcbf833e7c..05354d17e1 100755
--- a/test/functional/p2p_leak.py
+++ b/test/functional/p2p_leak.py
@@ -93,6 +93,9 @@ class P2PLeakTest(BitcoinTestFramework):
self.num_nodes = 1
self.extra_args = [['-banscore=' + str(banscore)]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
no_version_bannode = self.nodes[0].add_p2p_connection(CNodeNoVersionBan(), send_version=False, wait_for_verack=False)
no_version_idlenode = self.nodes[0].add_p2p_connection(CNodeNoVersionIdle(), send_version=False, wait_for_verack=False)
diff --git a/test/functional/p2p_node_network_limited.py b/test/functional/p2p_node_network_limited.py
index c987bf4b05..ef9c71dc02 100755
--- a/test/functional/p2p_node_network_limited.py
+++ b/test/functional/p2p_node_network_limited.py
@@ -34,6 +34,9 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
self.num_nodes = 3
self.extra_args = [['-prune=550', '-addrmantest'], [], []]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def disconnect_all(self):
disconnect_nodes(self.nodes[0], 1)
disconnect_nodes(self.nodes[1], 0)
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index be79a13237..f5ff646978 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -119,7 +119,7 @@ def get_virtual_size(witness_block):
vsize = int((3 * base_size + total_size + 3) / 4)
return vsize
-def test_transaction_acceptance(rpc, p2p, tx, with_witness, accepted, reason=None):
+def test_transaction_acceptance(node, p2p, tx, with_witness, accepted, reason=None):
"""Send a transaction to the node and check that it's accepted to the mempool
- Submit the transaction over the p2p interface
@@ -129,13 +129,13 @@ def test_transaction_acceptance(rpc, p2p, tx, with_witness, accepted, reason=Non
tx_message = msg_witness_tx(tx)
p2p.send_message(tx_message)
p2p.sync_with_ping()
- assert_equal(tx.hash in rpc.getrawmempool(), accepted)
+ assert_equal(tx.hash in node.getrawmempool(), accepted)
if (reason is not None and not accepted):
# Check the rejection reason as well.
with mininode_lock:
assert_equal(p2p.last_message["reject"].reason, reason)
-def test_witness_block(rpc, p2p, block, accepted, with_witness=True, reason=None):
+def test_witness_block(node, p2p, block, accepted, with_witness=True, reason=None):
"""Send a block to the node and check that it's accepted
- Submit the block over the p2p interface
@@ -145,7 +145,7 @@ def test_witness_block(rpc, p2p, block, accepted, with_witness=True, reason=None
else:
p2p.send_message(msg_block(block))
p2p.sync_with_ping()
- assert_equal(rpc.getbestblockhash() == block.hash, accepted)
+ assert_equal(node.getbestblockhash() == block.hash, accepted)
if (reason is not None and not accepted):
# Check the rejection reason as well.
with mininode_lock:
@@ -198,6 +198,9 @@ class SegWitTest(BitcoinTestFramework):
# This test tests SegWit both pre and post-activation, so use the normal BIP9 activation.
self.extra_args = [["-whitelist=127.0.0.1", "-vbparams=segwit:0:999999999999"], ["-whitelist=127.0.0.1", "-acceptnonstdtxn=0", "-vbparams=segwit:0:999999999999"], ["-whitelist=127.0.0.1", "-vbparams=segwit:0:0"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
self.setup_nodes()
connect_nodes(self.nodes[0], 1)
@@ -349,7 +352,7 @@ class SegWitTest(BitcoinTestFramework):
self.update_witness_block_with_transactions(block, [tx])
# Sending witness data before activation is not allowed (anti-spam
# rule).
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
wait_until(lambda: 'reject' in self.test_node.last_message and self.test_node.last_message["reject"].reason == b"unexpected-witness")
# But it should not be permanently marked bad...
@@ -380,20 +383,20 @@ class SegWitTest(BitcoinTestFramework):
self.test_node.announce_block_and_wait_for_getdata(block1, use_header=False)
assert(self.test_node.last_message["getdata"].inv[0].type == blocktype)
- test_witness_block(self.nodes[0].rpc, self.test_node, block1, True)
+ test_witness_block(self.nodes[0], self.test_node, block1, True)
block2 = self.build_next_block(version=4)
block2.solve()
self.test_node.announce_block_and_wait_for_getdata(block2, use_header=True)
assert(self.test_node.last_message["getdata"].inv[0].type == blocktype)
- test_witness_block(self.nodes[0].rpc, self.test_node, block2, True)
+ test_witness_block(self.nodes[0], self.test_node, block2, True)
block3 = self.build_next_block(version=(VB_TOP_BITS | (1 << 15)))
block3.solve()
self.test_node.announce_block_and_wait_for_getdata(block3, use_header=True)
assert(self.test_node.last_message["getdata"].inv[0].type == blocktype)
- test_witness_block(self.nodes[0].rpc, self.test_node, block3, True)
+ test_witness_block(self.nodes[0], self.test_node, block3, True)
# Check that we can getdata for witness blocks or regular blocks,
# and the right thing happens.
@@ -423,7 +426,7 @@ class SegWitTest(BitcoinTestFramework):
# This gives us a witness commitment.
assert(len(block.vtx[0].wit.vtxinwit) == 1)
assert(len(block.vtx[0].wit.vtxinwit[0].scriptWitness.stack) == 1)
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Now try to retrieve it...
rpc_block = self.nodes[0].getblock(block.hash, False)
non_wit_block = self.test_node.request_block(block.sha256, 2)
@@ -640,11 +643,11 @@ class SegWitTest(BitcoinTestFramework):
# its from)
assert_equal(len(self.nodes[0].getrawmempool()), 0)
assert_equal(len(self.nodes[1].getrawmempool()), 0)
- test_transaction_acceptance(self.nodes[0].rpc, self.old_node, tx, with_witness=True, accepted=False)
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=False)
+ test_transaction_acceptance(self.nodes[0], self.old_node, tx, with_witness=True, accepted=False)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=True, accepted=False)
# But eliminating the witness should fix it
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True)
# Cleanup: mine the first transaction and update utxo
self.nodes[0].generate(1)
@@ -674,7 +677,7 @@ class SegWitTest(BitcoinTestFramework):
p2sh_tx.rehash()
# Mine it on test_node to create the confirmed output.
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_tx, with_witness=True, accepted=True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_tx, with_witness=True, accepted=True)
self.nodes[0].generate(1)
sync_blocks(self.nodes)
@@ -689,7 +692,7 @@ class SegWitTest(BitcoinTestFramework):
# This is always accepted, since the mempool policy is to consider segwit as always active
# and thus allow segwit outputs
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx, with_witness=True, accepted=True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, tx, with_witness=True, accepted=True)
# Now create something that looks like a P2PKH output. This won't be spendable.
script_pubkey = CScript([OP_0, hash160(witness_hash)])
@@ -701,7 +704,7 @@ class SegWitTest(BitcoinTestFramework):
tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program]
tx2.rehash()
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx2, with_witness=True, accepted=True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, tx2, with_witness=True, accepted=True)
# Now update self.utxo for later tests.
tx3 = CTransaction()
@@ -723,7 +726,7 @@ class SegWitTest(BitcoinTestFramework):
tx3.vout = [tx3_out]
tx3.rehash()
assert_equal(self.nodes[0].testmempoolaccept([bytes_to_hex_str(tx3.serialize_with_witness())]), [{'txid': tx3.hash, 'allowed': True}])
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=True)
self.nodes[0].generate(1)
sync_blocks(self.nodes)
@@ -760,10 +763,10 @@ class SegWitTest(BitcoinTestFramework):
tx.rehash()
# Verify mempool acceptance and block validity
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True)
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True, with_witness=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True, with_witness=True)
sync_blocks(self.nodes)
# Now test attempts to spend the output.
@@ -777,12 +780,12 @@ 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].rpc, self.test_node, spend_tx, with_witness=False, accepted=False)
+ 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'])
spend_tx.rehash()
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, spend_tx, with_witness=False, accepted=False)
+ 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.
@@ -792,7 +795,7 @@ class SegWitTest(BitcoinTestFramework):
spend_tx.wit.vtxinwit[0].scriptWitness.stack = [b'a', witness_program]
# Verify mempool acceptance
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, spend_tx, with_witness=True, accepted=True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=True, accepted=True)
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [spend_tx])
@@ -800,7 +803,7 @@ class SegWitTest(BitcoinTestFramework):
# This no longer works before activation, because SCRIPT_VERIFY_WITNESS
# is always set.
# TODO: rewrite this test to make clear that it only works after activation.
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Update self.utxo
self.utxo.pop(0)
@@ -821,7 +824,7 @@ class SegWitTest(BitcoinTestFramework):
assert(msg_witness_block(block).serialize() != msg_block(block).serialize())
# This empty block should be valid.
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Try to tweak the nonce
block_2 = self.build_next_block()
@@ -832,7 +835,7 @@ class SegWitTest(BitcoinTestFramework):
assert(block_2.vtx[0].vout[-1] != block.vtx[0].vout[-1])
# This should also be valid.
- test_witness_block(self.nodes[0].rpc, self.test_node, block_2, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block_2, accepted=True)
# Now test commitments with actual transactions
tx = CTransaction()
@@ -864,7 +867,7 @@ class SegWitTest(BitcoinTestFramework):
block_3.rehash()
block_3.solve()
- test_witness_block(self.nodes[0].rpc, self.test_node, block_3, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block_3, accepted=False)
# Add a different commitment with different nonce, but in the
# right location, and with some funds burned(!).
@@ -878,7 +881,7 @@ class SegWitTest(BitcoinTestFramework):
block_3.rehash()
assert(len(block_3.vtx[0].vout) == 4) # 3 OP_returns
block_3.solve()
- test_witness_block(self.nodes[0].rpc, self.test_node, block_3, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block_3, accepted=True)
# Finally test that a block with no witness transactions can
# omit the commitment.
@@ -890,7 +893,7 @@ class SegWitTest(BitcoinTestFramework):
block_4.vtx.append(tx3)
block_4.hashMerkleRoot = block_4.calc_merkle_root()
block_4.solve()
- test_witness_block(self.nodes[0].rpc, self.test_node, block_4, with_witness=False, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block_4, with_witness=False, accepted=True)
# Update available utxo's for use in later test.
self.utxo.pop(0)
@@ -930,11 +933,11 @@ class SegWitTest(BitcoinTestFramework):
# Change the nonce -- should not cause the block to be permanently
# failed
block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(1)]
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Changing the witness reserved value doesn't change the block hash
block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(0)]
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
@subtest
def test_witness_block_size(self):
@@ -998,7 +1001,7 @@ class SegWitTest(BitcoinTestFramework):
# limit
assert(len(block.serialize(True)) > 2 * 1024 * 1024)
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Now resize the second transaction to make the block fit.
cur_length = len(block.vtx[-1].wit.vtxinwit[0].scriptWitness.stack[0])
@@ -1008,7 +1011,7 @@ class SegWitTest(BitcoinTestFramework):
block.solve()
assert(get_virtual_size(block) == MAX_BLOCK_BASE_SIZE)
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Update available utxo's
self.utxo.pop(0)
@@ -1071,7 +1074,7 @@ class SegWitTest(BitcoinTestFramework):
self.update_witness_block_with_transactions(block, [tx])
# Extra witness data should not be allowed.
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Try extra signature data. Ok if we're not spending a witness output.
block.vtx[1].wit.vtxinwit = []
@@ -1080,7 +1083,7 @@ class SegWitTest(BitcoinTestFramework):
add_witness_commitment(block)
block.solve()
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Now try extra witness/signature data on an input that DOES require a
# witness
@@ -1096,7 +1099,7 @@ class SegWitTest(BitcoinTestFramework):
self.update_witness_block_with_transactions(block, [tx2])
# This has extra witness data, so it should fail.
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Now get rid of the extra witness, but add extra scriptSig data
tx2.vin[0].scriptSig = CScript([OP_TRUE])
@@ -1108,7 +1111,7 @@ class SegWitTest(BitcoinTestFramework):
block.solve()
# This has extra signature data for a witness input, so it should fail.
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Now get rid of the extra scriptsig on the witness input, and verify
# success (even with extra scriptsig data in the non-witness input)
@@ -1117,7 +1120,7 @@ class SegWitTest(BitcoinTestFramework):
add_witness_commitment(block)
block.solve()
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Update utxo for later tests
self.utxo.pop(0)
@@ -1147,14 +1150,14 @@ class SegWitTest(BitcoinTestFramework):
tx2.rehash()
self.update_witness_block_with_transactions(block, [tx, tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Now reduce the length of the stack element
tx2.wit.vtxinwit[0].scriptWitness.stack[0] = b'a' * (MAX_SCRIPT_ELEMENT_SIZE)
add_witness_commitment(block)
block.solve()
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Update the utxo for later tests
self.utxo.pop()
@@ -1188,7 +1191,7 @@ class SegWitTest(BitcoinTestFramework):
self.update_witness_block_with_transactions(block, [tx, tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Try again with one less byte in the witness program
witness_program = CScript([b'a' * 520] * 19 + [OP_DROP] * 62 + [OP_TRUE])
@@ -1203,7 +1206,7 @@ class SegWitTest(BitcoinTestFramework):
tx2.rehash()
block.vtx = [block.vtx[0]]
self.update_witness_block_with_transactions(block, [tx, tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
self.utxo.pop()
self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue))
@@ -1227,7 +1230,7 @@ class SegWitTest(BitcoinTestFramework):
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Try various ways to spend tx that should all break.
# This "broken" transaction serializer will not normalize
@@ -1262,7 +1265,7 @@ class SegWitTest(BitcoinTestFramework):
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Now try using a too short vtxinwit
tx2.wit.vtxinwit.pop()
@@ -1270,7 +1273,7 @@ class SegWitTest(BitcoinTestFramework):
block.vtx = [block.vtx[0]]
self.update_witness_block_with_transactions(block, [tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Now make one of the intermediate witnesses be incorrect
tx2.wit.vtxinwit.append(CTxInWitness())
@@ -1279,13 +1282,13 @@ class SegWitTest(BitcoinTestFramework):
block.vtx = [block.vtx[0]]
self.update_witness_block_with_transactions(block, [tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Fix the broken witness and the block should be accepted.
tx2.wit.vtxinwit[5].scriptWitness.stack = [b'a', witness_program]
block.vtx = [block.vtx[0]]
self.update_witness_block_with_transactions(block, [tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
self.utxo.pop()
self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue))
@@ -1314,11 +1317,11 @@ class SegWitTest(BitcoinTestFramework):
# Verify that unnecessary witnesses are rejected.
self.test_node.announce_tx_and_wait_for_getdata(tx)
assert_equal(len(self.nodes[0].getrawmempool()), 0)
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=False)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=True, accepted=False)
# Verify that removing the witness succeeds.
self.test_node.announce_tx_and_wait_for_getdata(tx)
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True)
# Now try to add extra witness data to a valid witness tx.
witness_program = CScript([OP_TRUE])
@@ -1343,24 +1346,24 @@ class SegWitTest(BitcoinTestFramework):
# Node will not be blinded to the transaction
self.std_node.announce_tx_and_wait_for_getdata(tx3)
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx3, True, False, b'tx-size')
+ test_transaction_acceptance(self.nodes[1], self.std_node, tx3, True, False, b'tx-size')
self.std_node.announce_tx_and_wait_for_getdata(tx3)
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx3, True, False, b'tx-size')
+ test_transaction_acceptance(self.nodes[1], self.std_node, tx3, True, False, b'tx-size')
# Remove witness stuffing, instead add extra witness push on stack
tx3.vout[0] = CTxOut(tx2.vout[0].nValue - 1000, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))
tx3.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), witness_program]
tx3.rehash()
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, with_witness=True, accepted=True)
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=False)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx2, with_witness=True, accepted=True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=False)
# Get rid of the extra witness, and verify acceptance.
tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_program]
# Also check that old_node gets a tx announcement, even though this is
# a witness transaction.
self.old_node.wait_for_inv([CInv(1, tx2.sha256)]) # wait until tx2 was inv'ed
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=True)
self.old_node.wait_for_inv([CInv(1, tx3.sha256)])
# Test that getrawtransaction returns correct witness information
@@ -1400,7 +1403,7 @@ class SegWitTest(BitcoinTestFramework):
tx.rehash()
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
self.utxo.pop(0)
for i in range(NUM_SEGWIT_VERSIONS):
self.utxo.append(UTXO(tx.sha256, i, split_value))
@@ -1417,8 +1420,8 @@ class SegWitTest(BitcoinTestFramework):
tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")]
tx.vout = [CTxOut(self.utxo[0].nValue - 1000, script_pubkey)]
tx.rehash()
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx, with_witness=True, accepted=False)
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, tx, with_witness=True, accepted=False)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=True, accepted=True)
self.utxo.pop(0)
temp_utxo.append(UTXO(tx.sha256, 0, tx.vout[0].nValue))
@@ -1437,8 +1440,8 @@ class SegWitTest(BitcoinTestFramework):
tx2.rehash()
# Gets accepted to test_node, because standardness of outputs isn't
# checked with fRequireStandard
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, with_witness=True, accepted=True)
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx2, with_witness=True, accepted=False)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx2, with_witness=True, accepted=True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, tx2, with_witness=True, accepted=False)
temp_utxo.pop() # last entry in temp_utxo was the output we just spent
temp_utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue))
@@ -1454,7 +1457,7 @@ class SegWitTest(BitcoinTestFramework):
tx3.rehash()
# Spending a higher version witness output is not allowed by policy,
# even with fRequireStandard=false.
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=False)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=False)
self.test_node.sync_with_ping()
with mininode_lock:
assert(b"reserved for soft-fork upgrades" in self.test_node.last_message["reject"].reason)
@@ -1462,7 +1465,7 @@ class SegWitTest(BitcoinTestFramework):
# Building a block with the transaction must be valid, however.
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx2, tx3])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
sync_blocks(self.nodes)
# Add utxo to our list
@@ -1480,7 +1483,7 @@ class SegWitTest(BitcoinTestFramework):
# This next line will rehash the coinbase and update the merkle
# root, and solve.
self.update_witness_block_with_transactions(block, [])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
spend_tx = CTransaction()
spend_tx.vin = [CTxIn(COutPoint(block.vtx[0].sha256, 0), b"")]
@@ -1494,13 +1497,13 @@ class SegWitTest(BitcoinTestFramework):
sync_blocks(self.nodes)
block2 = self.build_next_block()
self.update_witness_block_with_transactions(block2, [spend_tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block2, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block2, accepted=False)
# Advancing one more block should allow the spend.
self.nodes[0].generate(1)
block2 = self.build_next_block()
self.update_witness_block_with_transactions(block2, [spend_tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block2, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block2, accepted=True)
sync_blocks(self.nodes)
@subtest
@@ -1532,7 +1535,7 @@ class SegWitTest(BitcoinTestFramework):
# Confirm it in a block.
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Now try to spend it. Send it to a P2WSH output, which we'll
# use in the next test.
@@ -1551,11 +1554,11 @@ class SegWitTest(BitcoinTestFramework):
tx2.rehash()
# Should fail policy test.
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
# But passes consensus.
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Test 2: P2WSH
# Try to spend the P2WSH output created in last test.
@@ -1571,11 +1574,11 @@ class SegWitTest(BitcoinTestFramework):
sign_p2pk_witness_input(witness_program, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key)
# Should fail policy test.
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx3, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
# But passes consensus.
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx3])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Test 3: P2SH(P2WSH)
# Try to spend the P2SH output created in the last test.
@@ -1588,10 +1591,10 @@ class SegWitTest(BitcoinTestFramework):
sign_p2pk_witness_input(witness_program, tx4, 0, SIGHASH_ALL, tx3.vout[0].nValue, key)
# Should fail policy test.
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx4, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx4, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx4])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Test 4: Uncompressed pubkeys should still be valid in non-segwit
# transactions.
@@ -1603,10 +1606,10 @@ class SegWitTest(BitcoinTestFramework):
tx5.vin[0].scriptSig = CScript([signature, pubkey])
tx5.rehash()
# Should pass policy and consensus.
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx5, True, True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx5, True, True)
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx5])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
self.utxo.append(UTXO(tx5.sha256, 0, tx5.vout[0].nValue))
@subtest
@@ -1626,11 +1629,11 @@ class SegWitTest(BitcoinTestFramework):
tx.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey))
tx.rehash()
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=True, accepted=True)
# Mine this transaction in preparation for following tests.
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
sync_blocks(self.nodes)
self.utxo.pop(0)
@@ -1647,19 +1650,19 @@ class SegWitTest(BitcoinTestFramework):
# Too-large input value
sign_p2pk_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue + 1, key)
self.update_witness_block_with_transactions(block, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Too-small input value
sign_p2pk_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue - 1, key)
block.vtx.pop() # remove last tx
self.update_witness_block_with_transactions(block, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Now try correct value
sign_p2pk_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue, key)
block.vtx.pop()
self.update_witness_block_with_transactions(block, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
prev_utxo = UTXO(tx.sha256, 0, tx.vout[0].nValue)
@@ -1683,7 +1686,7 @@ class SegWitTest(BitcoinTestFramework):
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
block = self.build_next_block()
used_sighash_single_out_of_bounds = False
@@ -1725,7 +1728,7 @@ class SegWitTest(BitcoinTestFramework):
# Test the block periodically, if we're close to maxblocksize
if (get_virtual_size(block) > MAX_BLOCK_BASE_SIZE - 1000):
self.update_witness_block_with_transactions(block, [])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
block = self.build_next_block()
if (not used_sighash_single_out_of_bounds):
@@ -1733,7 +1736,7 @@ class SegWitTest(BitcoinTestFramework):
# Test the transactions we've added to the block
if (len(block.vtx) > 1):
self.update_witness_block_with_transactions(block, [])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Now test witness version 0 P2PKH transactions
pubkeyhash = hash160(pubkey)
@@ -1755,7 +1758,7 @@ class SegWitTest(BitcoinTestFramework):
tx2.vin[0].scriptSig = CScript([signature, pubkey])
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx, tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
# Move the signature to the witness.
block.vtx.pop()
@@ -1765,7 +1768,7 @@ class SegWitTest(BitcoinTestFramework):
tx2.rehash()
self.update_witness_block_with_transactions(block, [tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
temp_utxos.pop(0)
@@ -1786,7 +1789,7 @@ class SegWitTest(BitcoinTestFramework):
index += 1
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
for i in range(len(tx.vout)):
self.utxo.append(UTXO(tx.sha256, i, tx.vout[i].nValue))
@@ -1808,7 +1811,7 @@ class SegWitTest(BitcoinTestFramework):
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))
tx.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey))
tx.rehash()
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, False, True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx, False, True)
self.nodes[0].generate(1)
sync_blocks(self.nodes)
@@ -1825,18 +1828,18 @@ class SegWitTest(BitcoinTestFramework):
tx2.rehash()
# This will be rejected due to a policy check:
# No witness is allowed, since it is not a witness program but a p2sh program
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx2, True, False, b'bad-witness-nonstandard')
+ test_transaction_acceptance(self.nodes[1], self.std_node, tx2, True, False, b'bad-witness-nonstandard')
# If we send without witness, it should be accepted.
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx2, False, True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, tx2, False, True)
# Now create a new anyone-can-spend utxo for the next test.
tx3 = CTransaction()
tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), CScript([p2sh_program])))
tx3.vout.append(CTxOut(tx2.vout[0].nValue - 1000, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])))
tx3.rehash()
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, False, True)
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, False, True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx2, False, True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx3, False, True)
self.nodes[0].generate(1)
sync_blocks(self.nodes)
@@ -1872,7 +1875,7 @@ class SegWitTest(BitcoinTestFramework):
tx.vout.append(CTxOut(outputvalue, CScript([OP_HASH160, p2sh, OP_EQUAL])))
tx.rehash()
txid = tx.sha256
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True)
self.nodes[0].generate(1)
sync_blocks(self.nodes)
@@ -1897,45 +1900,45 @@ class SegWitTest(BitcoinTestFramework):
# Testing native P2WSH
# Witness stack size, excluding witnessScript, over 100 is non-standard
p2wsh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]]
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[0], True, False, b'bad-witness-nonstandard')
+ test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[0], True, False, b'bad-witness-nonstandard')
# Non-standard nodes should accept
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[0], True, True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[0], True, True)
# Stack element size over 80 bytes is non-standard
p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]]
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[1], True, False, b'bad-witness-nonstandard')
+ test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[1], True, False, b'bad-witness-nonstandard')
# Non-standard nodes should accept
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[1], True, True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[1], True, True)
# Standard nodes should accept if element size is not over 80 bytes
p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]]
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[1], True, True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[1], True, True)
# witnessScript size at 3600 bytes is standard
p2wsh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]]
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[2], True, True)
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[2], True, True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[2], True, True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[2], True, True)
# witnessScript size at 3601 bytes is non-standard
p2wsh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]]
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[3], True, False, b'bad-witness-nonstandard')
+ test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[3], True, False, b'bad-witness-nonstandard')
# Non-standard nodes should accept
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[3], True, True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[3], True, True)
# Repeating the same tests with P2SH-P2WSH
p2sh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]]
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[0], True, False, b'bad-witness-nonstandard')
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[0], True, True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[0], True, False, b'bad-witness-nonstandard')
+ test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[0], True, True)
p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]]
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[1], True, False, b'bad-witness-nonstandard')
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[1], True, True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, False, b'bad-witness-nonstandard')
+ test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[1], True, True)
p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]]
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[1], True, True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, True)
p2sh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]]
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[2], True, True)
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[2], True, True)
+ test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[2], True, True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[2], True, True)
p2sh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]]
- test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[3], True, False, b'bad-witness-nonstandard')
- test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[3], True, True)
+ test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[3], True, False, b'bad-witness-nonstandard')
+ test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[3], True, True)
self.nodes[0].generate(1) # Mine and clean up the mempool of non-standard node
# Valid but non-standard transactions in a block should be accepted by standard node
@@ -2011,7 +2014,7 @@ class SegWitTest(BitcoinTestFramework):
block_1 = self.build_next_block()
self.update_witness_block_with_transactions(block_1, [tx])
- test_witness_block(self.nodes[0].rpc, self.test_node, block_1, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block_1, accepted=True)
tx2 = CTransaction()
# If we try to spend the first n-1 outputs from tx, that should be
@@ -2028,7 +2031,7 @@ class SegWitTest(BitcoinTestFramework):
block_2 = self.build_next_block()
self.update_witness_block_with_transactions(block_2, [tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block_2, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block_2, accepted=False)
# Try dropping the last input in tx2, and add an output that has
# too many sigops (contributing to legacy sigop count).
@@ -2041,14 +2044,14 @@ class SegWitTest(BitcoinTestFramework):
tx2.rehash()
block_3 = self.build_next_block()
self.update_witness_block_with_transactions(block_3, [tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block_3, accepted=False)
+ test_witness_block(self.nodes[0], self.test_node, block_3, accepted=False)
# If we drop the last checksig in this output, the tx should succeed.
block_4 = self.build_next_block()
tx2.vout[-1].scriptPubKey = CScript([OP_CHECKSIG] * (checksig_count - 1))
tx2.rehash()
self.update_witness_block_with_transactions(block_4, [tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block_4, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block_4, accepted=True)
# Reset the tip back down for the next test
sync_blocks(self.nodes)
@@ -2064,7 +2067,7 @@ class SegWitTest(BitcoinTestFramework):
tx2.wit.vtxinwit[-1].scriptWitness.stack = [witness_program_justright]
tx2.rehash()
self.update_witness_block_with_transactions(block_5, [tx2])
- test_witness_block(self.nodes[0].rpc, self.test_node, block_5, accepted=True)
+ test_witness_block(self.nodes[0], self.test_node, block_5, accepted=True)
# TODO: test p2sh sigop counting
diff --git a/test/functional/p2p_sendheaders.py b/test/functional/p2p_sendheaders.py
index 9cc496d510..9a782c0bb9 100755
--- a/test/functional/p2p_sendheaders.py
+++ b/test/functional/p2p_sendheaders.py
@@ -208,6 +208,9 @@ class SendHeadersTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 2
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def mine_blocks(self, count):
"""Mine count blocks and return the new tip."""
diff --git a/test/functional/p2p_unrequested_blocks.py b/test/functional/p2p_unrequested_blocks.py
index 2e86954aba..232274f59e 100755
--- a/test/functional/p2p_unrequested_blocks.py
+++ b/test/functional/p2p_unrequested_blocks.py
@@ -66,6 +66,9 @@ class AcceptBlockTest(BitcoinTestFramework):
self.num_nodes = 2
self.extra_args = [[], ["-minimumchainwork=0x10"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
# Node0 will be used to test behavior of processing unrequested blocks
# from peers which are not whitelisted, while Node1 will be used for
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index d681cdc8ab..00317a2c08 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -47,9 +47,13 @@ from test_framework.mininode import (
class BlockchainTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
- self.extra_args = [['-stopatheight=207', '-prune=1']]
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
def run_test(self):
+ self.restart_node(0, extra_args=['-stopatheight=207', '-prune=1']) # Set extra args with pruning after rescan is complete
+
self._test_getblockchaininfo()
self._test_getchaintxstats()
self._test_gettxoutsetinfo()
@@ -169,7 +173,7 @@ class BlockchainTest(BitcoinTestFramework):
assert_equal(res['transactions'], 200)
assert_equal(res['height'], 200)
assert_equal(res['txouts'], 200)
- assert_equal(res['bogosize'], 17000),
+ assert_equal(res['bogosize'], 15000),
assert_equal(res['bestblock'], node.getblockhash(200))
size = res['disk_size']
assert size > 6400
diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py
index f346e1ebfc..3cc35a7b9a 100755
--- a/test/functional/rpc_createmultisig.py
+++ b/test/functional/rpc_createmultisig.py
@@ -12,8 +12,11 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 3
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def get_keys(self):
- node0,node1,node2 = self.nodes
+ node0, node1, node2 = self.nodes
self.add = [node1.getnewaddress() for _ in range(self.nkeys)]
self.pub = [node1.getaddressinfo(a)["pubkey"] for a in self.add]
self.priv = [node1.dumpprivkey(a) for a in self.add]
diff --git a/test/functional/rpc_deprecated.py b/test/functional/rpc_deprecated.py
index deffe4e6bd..cd6e5511c4 100755
--- a/test/functional/rpc_deprecated.py
+++ b/test/functional/rpc_deprecated.py
@@ -12,6 +12,9 @@ class DeprecatedRpcTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.extra_args = [[], ["-deprecatedrpc=validateaddress", "-deprecatedrpc=accounts"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
# This test should be used to verify correct behaviour of deprecated
# RPC methods with and without the -deprecatedrpc flags. For example:
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index a806de43b4..daa890ab15 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -29,6 +29,9 @@ class RawTransactionsTest(BitcoinTestFramework):
self.num_nodes = 4
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self, split=False):
self.setup_nodes()
diff --git a/test/functional/rpc_getchaintips.py b/test/functional/rpc_getchaintips.py
index 07929ca0a1..bc19c60dde 100755
--- a/test/functional/rpc_getchaintips.py
+++ b/test/functional/rpc_getchaintips.py
@@ -17,15 +17,18 @@ class GetChainTipsTest (BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
- def run_test (self):
- tips = self.nodes[0].getchaintips ()
- assert_equal (len (tips), 1)
- assert_equal (tips[0]['branchlen'], 0)
- assert_equal (tips[0]['height'], 200)
- assert_equal (tips[0]['status'], 'active')
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
+ def run_test(self):
+ tips = self.nodes[0].getchaintips()
+ assert_equal(len(tips), 1)
+ assert_equal(tips[0]['branchlen'], 0)
+ assert_equal(tips[0]['height'], 200)
+ assert_equal(tips[0]['status'], 'active')
# Split the network and build two chains of different lengths.
- self.split_network ()
+ self.split_network()
self.nodes[0].generate(10)
self.nodes[2].generate(20)
self.sync_all([self.nodes[:2], self.nodes[2:]])
diff --git a/test/functional/rpc_help.py b/test/functional/rpc_help.py
new file mode 100755
index 0000000000..78d6e78aed
--- /dev/null
+++ b/test/functional/rpc_help.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+# Copyright (c) 2018 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test RPC help output."""
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import assert_equal, assert_raises_rpc_error
+
+import os
+
+
+class HelpRpcTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+
+ def run_test(self):
+ self.test_categories()
+ self.dump_help()
+
+ def test_categories(self):
+ node = self.nodes[0]
+
+ # wrong argument count
+ assert_raises_rpc_error(-1, 'help', node.help, 'foo', 'bar')
+
+ # invalid argument
+ assert_raises_rpc_error(-1, 'JSON value is not a string as expected', node.help, 0)
+
+ # help of unknown command
+ assert_equal(node.help('foo'), 'help: unknown command: foo')
+
+ # command titles
+ titles = [line[3:-3] for line in node.help().splitlines() if line.startswith('==')]
+
+ components = ['Blockchain', 'Control', 'Generating', 'Mining', 'Network', 'Rawtransactions', 'Util']
+
+ if self.is_wallet_compiled():
+ components.append('Wallet')
+
+ if self.is_zmq_compiled():
+ components.append('Zmq')
+
+ assert_equal(titles, components)
+
+ def dump_help(self):
+ dump_dir = os.path.join(self.options.tmpdir, 'rpc_help_dump')
+ os.mkdir(dump_dir)
+ calls = [line.split(' ', 1)[0] for line in self.nodes[0].help().splitlines() if line and not line.startswith('==')]
+ for call in calls:
+ with open(os.path.join(dump_dir, call), 'w', encoding='utf-8') as f:
+ # Make sure the node can generate the help at runtime without crashing
+ f.write(self.nodes[0].help(call))
+
+
+if __name__ == '__main__':
+ HelpRpcTest().main()
diff --git a/test/functional/rpc_invalidateblock.py b/test/functional/rpc_invalidateblock.py
index f40710ef74..84f7cd05fb 100755
--- a/test/functional/rpc_invalidateblock.py
+++ b/test/functional/rpc_invalidateblock.py
@@ -14,6 +14,9 @@ class InvalidateTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 3
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
self.setup_nodes()
diff --git a/test/functional/rpc_preciousblock.py b/test/functional/rpc_preciousblock.py
index 1e20d1a046..f383b82bb5 100755
--- a/test/functional/rpc_preciousblock.py
+++ b/test/functional/rpc_preciousblock.py
@@ -38,6 +38,9 @@ class PreciousTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 3
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
self.setup_nodes()
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py
index d558de5fe1..7c8c6c9af0 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -20,6 +20,9 @@ class PSBTTest(BitcoinTestFramework):
self.setup_clean_chain = False
self.num_nodes = 3
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
# Create and fund a raw tx for sending 10 BTC
psbtx1 = self.nodes[0].walletcreatefundedpsbt([], {self.nodes[2].getnewaddress():10})['psbt']
@@ -166,6 +169,10 @@ class PSBTTest(BitcoinTestFramework):
assert_equal(decoded_psbt["tx"]["locktime"], 0)
+ # Make sure change address wallet does not have P2SH innerscript access to results in success
+ # when attempting BnB coin selection
+ self.nodes[0].walletcreatefundedpsbt([], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height+2, {"changeAddress":self.nodes[1].getnewaddress()}, False)
+
# BIP 174 Test Vectors
# Check that unknown values are just passed through
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index 1e3ada26f8..d86b546c7d 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -44,6 +44,9 @@ class RawTransactionsTest(BitcoinTestFramework):
self.num_nodes = 3
self.extra_args = [["-addresstype=legacy"], ["-addresstype=legacy"], ["-addresstype=legacy"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self, split=False):
super().setup_network()
connect_nodes_bi(self.nodes, 0, 2)
@@ -358,7 +361,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# decoderawtransaction tests
# witness transaction
- encrawtx = "010000000001010000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000ffffffff0100e1f50500000000000000000000"
+ encrawtx = "010000000001010000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000ffffffff0100e1f50500000000000102616100000000"
decrawtx = self.nodes[0].decoderawtransaction(encrawtx, True) # decode as witness transaction
assert_equal(decrawtx['vout'][0]['value'], Decimal('1.00000000'))
assert_raises_rpc_error(-22, 'TX decode failed', self.nodes[0].decoderawtransaction, encrawtx, False) # force decode as non-witness transaction
diff --git a/test/functional/rpc_scantxoutset.py b/test/functional/rpc_scantxoutset.py
index ceb38e969a..96f9ccdbdb 100755
--- a/test/functional/rpc_scantxoutset.py
+++ b/test/functional/rpc_scantxoutset.py
@@ -14,6 +14,10 @@ class ScantxoutsetTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.log.info("Mining blocks...")
self.nodes[0].generate(110)
diff --git a/test/functional/rpc_signmessage.py b/test/functional/rpc_signmessage.py
index 449c4075bd..ad0e29b451 100755
--- a/test/functional/rpc_signmessage.py
+++ b/test/functional/rpc_signmessage.py
@@ -13,6 +13,9 @@ class SignMessagesTest(BitcoinTestFramework):
self.num_nodes = 1
self.extra_args = [["-addresstype=legacy"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
message = 'This is just a test message'
diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/rpc_signrawtransaction.py
index 32b099294f..823892a349 100755
--- a/test/functional/rpc_signrawtransaction.py
+++ b/test/functional/rpc_signrawtransaction.py
@@ -14,6 +14,9 @@ class SignRawTransactionsTest(BitcoinTestFramework):
self.num_nodes = 1
self.extra_args = [["-deprecatedrpc=signrawtransaction"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def successful_signing_test(self):
"""Create and sign a valid raw transaction with one input.
@@ -46,6 +49,14 @@ class SignRawTransactionsTest(BitcoinTestFramework):
rawTxSigned2 = self.nodes[0].signrawtransaction(rawTx, inputs, privKeys)
assert_equal(rawTxSigned, rawTxSigned2)
+ def test_with_lock_outputs(self):
+ """Test correct error reporting when trying to sign a locked output"""
+ self.nodes[0].encryptwallet("password")
+ self.restart_node(0)
+ 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.
@@ -147,6 +158,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/rpc_txoutproof.py b/test/functional/rpc_txoutproof.py
index f9f8574646..867ba25022 100755
--- a/test/functional/rpc_txoutproof.py
+++ b/test/functional/rpc_txoutproof.py
@@ -15,6 +15,9 @@ class MerkleBlockTest(BitcoinTestFramework):
# Nodes 0/1 are "wallet" nodes, Nodes 2/3 are used for testing
self.extra_args = [[], [], [], ["-txindex"]]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
self.setup_nodes()
connect_nodes(self.nodes[0], 1)
diff --git a/test/functional/rpc_zmq.py b/test/functional/rpc_zmq.py
index 6dbc726d5e..bfa6b06f67 100755
--- a/test/functional/rpc_zmq.py
+++ b/test/functional/rpc_zmq.py
@@ -4,8 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test for the ZMQ RPC methods."""
-from test_framework.test_framework import (
- BitcoinTestFramework, skip_if_no_py3_zmq, skip_if_no_bitcoind_zmq)
+from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
@@ -17,9 +16,11 @@ class RPCZMQTest(BitcoinTestFramework):
self.num_nodes = 1
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_py3_zmq()
+ self.skip_if_no_bitcoind_zmq()
+
def run_test(self):
- skip_if_no_py3_zmq()
- skip_if_no_bitcoind_zmq(self)
self._test_getzmqnotifications()
def _test_getzmqnotifications(self):
diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py
index d1ddbbe8ee..034e83aaae 100755
--- a/test/functional/test_framework/mininode.py
+++ b/test/functional/test_framework/mininode.py
@@ -482,7 +482,7 @@ class P2PDataStore(P2PInterface):
self.reject_code_received = message.code
self.reject_reason_received = message.reason
- def send_blocks_and_test(self, blocks, rpc, success=True, request_block=True, reject_code=None, reject_reason=None, timeout=60):
+ def send_blocks_and_test(self, blocks, node, *, success=True, request_block=True, reject_code=None, reject_reason=None, timeout=60):
"""Send blocks to test node and test whether the tip advances.
- add all blocks to our block_store
@@ -508,16 +508,16 @@ class P2PDataStore(P2PInterface):
wait_until(lambda: blocks[-1].sha256 in self.getdata_requests, timeout=timeout, lock=mininode_lock)
if success:
- wait_until(lambda: rpc.getbestblockhash() == blocks[-1].hash, timeout=timeout)
+ wait_until(lambda: node.getbestblockhash() == blocks[-1].hash, timeout=timeout)
else:
- assert rpc.getbestblockhash() != blocks[-1].hash
+ assert node.getbestblockhash() != blocks[-1].hash
if reject_code is not None:
wait_until(lambda: self.reject_code_received == reject_code, lock=mininode_lock)
if reject_reason is not None:
wait_until(lambda: self.reject_reason_received == reject_reason, lock=mininode_lock)
- def send_txs_and_test(self, txs, rpc, success=True, expect_disconnect=False, reject_code=None, reject_reason=None):
+ def send_txs_and_test(self, txs, node, *, success=True, expect_disconnect=False, reject_code=None, reject_reason=None):
"""Send txs to test node and test whether they're accepted to the mempool.
- add all txs to our tx_store
@@ -541,7 +541,7 @@ class P2PDataStore(P2PInterface):
else:
self.sync_with_ping()
- raw_mempool = rpc.getrawmempool()
+ raw_mempool = node.getrawmempool()
if success:
# Check that all txs are now in the mempool
for tx in txs:
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index b876d9bd76..57c985b2a2 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -44,6 +44,13 @@ TEST_EXIT_FAILED = 1
TEST_EXIT_SKIPPED = 77
+class SkipTest(Exception):
+ """This exception is raised to skip a test"""
+
+ def __init__(self, message):
+ self.message = message
+
+
class BitcoinTestMetaClass(type):
"""Metaclass for BitcoinTestFramework.
@@ -156,8 +163,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
try:
if self.options.usecli and not self.supports_cli:
raise SkipTest("--usecli specified but test does not support using CLI")
+ self.skip_test_if_missing_module()
self.setup_chain()
self.setup_network()
+ self.import_deterministic_coinbase_privkeys()
self.run_test()
success = TestStatus.PASSED
except JSONRPCException as e:
@@ -220,6 +229,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
"""Override this method to add command-line options to the test"""
pass
+ def skip_test_if_missing_module(self):
+ """Override this method to skip a test if a module is not compiled"""
+ pass
+
def setup_chain(self):
"""Override this method to customize blockchain setup"""
self.log.info("Initializing test directory " + self.options.tmpdir)
@@ -247,6 +260,19 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.add_nodes(self.num_nodes, extra_args)
self.start_nodes()
+ def import_deterministic_coinbase_privkeys(self):
+ if self.setup_clean_chain:
+ return
+
+ for n in self.nodes:
+ try:
+ n.getwalletinfo()
+ except JSONRPCException as e:
+ assert str(e).startswith('Method not found')
+ continue
+
+ n.importprivkey(n.get_deterministic_priv_key()[1])
+
def run_test(self):
"""Tests must override this method to define test logic"""
raise NotImplementedError
@@ -415,7 +441,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
# Create cache directories, run bitcoinds:
for i in range(MAX_NODES):
datadir = initialize_datadir(self.options.cachedir, i)
- args = [self.options.bitcoind, "-datadir=" + datadir]
+ args = [self.options.bitcoind, "-datadir=" + datadir, '-disablewallet']
if i > 0:
args.append("-connect=127.0.0.1:" + str(p2p_port(0)))
self.nodes.append(TestNode(i, get_datadir_path(self.options.cachedir, i), extra_conf=["bind=127.0.0.1"], extra_args=[], rpchost=None, timewait=self.rpc_timewait, bitcoind=self.options.bitcoind, bitcoin_cli=self.options.bitcoincli, mocktime=self.mocktime, coverage_dir=None))
@@ -439,7 +465,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
for peer in range(4):
for j in range(25):
set_node_times(self.nodes, block_time)
- self.nodes[peer].generate(1)
+ self.nodes[peer].generatetoaddress(1, self.nodes[peer].get_deterministic_priv_key()[0])
block_time += 10 * 60
# Must sync before next peer starts generating blocks
sync_blocks(self.nodes)
@@ -453,8 +479,9 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
return os.path.join(get_datadir_path(self.options.cachedir, n), "regtest", *paths)
for i in range(MAX_NODES):
+ os.rmdir(cache_path(i, 'wallets')) # Remove empty wallets dir
for entry in os.listdir(cache_path(i)):
- if entry not in ['wallets', 'chainstate', 'blocks']:
+ if entry not in ['chainstate', 'blocks']:
os.remove(cache_path(i, entry))
for i in range(self.num_nodes):
@@ -471,25 +498,45 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
for i in range(self.num_nodes):
initialize_datadir(self.options.tmpdir, i)
+ def skip_if_no_py3_zmq(self):
+ """Attempt to import the zmq package and skip the test if the import fails."""
+ try:
+ import zmq # noqa
+ except ImportError:
+ raise SkipTest("python3-zmq module not available.")
+
+ def skip_if_no_bitcoind_zmq(self):
+ """Skip the running test if bitcoind has not been compiled with zmq support."""
+ if not self.is_zmq_compiled():
+ raise SkipTest("bitcoind has not been built with zmq enabled.")
+
+ def skip_if_no_wallet(self):
+ """Skip the running test if wallet has not been compiled."""
+ if not self.is_wallet_compiled():
+ raise SkipTest("wallet has not been compiled.")
+
+ def skip_if_no_cli(self):
+ """Skip the running test if bitcoin-cli has not been compiled."""
+ if not self.is_cli_compiled():
+ raise SkipTest("bitcoin-cli has not been compiled.")
+
+ def is_cli_compiled(self):
+ """Checks whether bitcoin-cli was compiled."""
+ config = configparser.ConfigParser()
+ config.read_file(open(self.options.configfile))
-class SkipTest(Exception):
- """This exception is raised to skip a test"""
- def __init__(self, message):
- self.message = message
-
+ return config["components"].getboolean("ENABLE_UTILS")
-def skip_if_no_py3_zmq():
- """Attempt to import the zmq package and skip the test if the import fails."""
- try:
- import zmq # noqa
- except ImportError:
- raise SkipTest("python3-zmq module not available.")
+ def is_wallet_compiled(self):
+ """Checks whether the wallet module was compiled."""
+ config = configparser.ConfigParser()
+ config.read_file(open(self.options.configfile))
+ return config["components"].getboolean("ENABLE_WALLET")
-def skip_if_no_bitcoind_zmq(test_instance):
- """Skip the running test if bitcoind has not been compiled with zmq support."""
- config = configparser.ConfigParser()
- config.read_file(open(test_instance.options.configfile))
+ def is_zmq_compiled(self):
+ """Checks whether the zmq module was compiled."""
+ config = configparser.ConfigParser()
+ config.read_file(open(self.options.configfile))
- if not config["components"].getboolean("ENABLE_ZMQ"):
- raise SkipTest("bitcoind has not been built with zmq enabled.")
+ return config["components"].getboolean("ENABLE_ZMQ")
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 0d00cc2082..908dda94c5 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -4,6 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Class for bitcoind node under test"""
+import contextlib
import decimal
import errno
from enum import Enum
@@ -96,6 +97,22 @@ class TestNode():
self.p2ps = []
+ def get_deterministic_priv_key(self):
+ """Return a deterministic priv key in base58, that only depends on the node's index"""
+ PRIV_KEYS = [
+ # adress , privkey
+ ('mjTkW3DjgyZck4KbiRusZsqTgaYTxdSz6z', 'cVpF924EspNh8KjYsfhgY96mmxvT6DgdWiTYMtMjuM74hJaU5psW'),
+ ('msX6jQXvxiNhx3Q62PKeLPrhrqZQdSimTg', 'cUxsWyKyZ9MAQTaAhUQWJmBbSvHMwSmuv59KgxQV7oZQU3PXN3KE'),
+ ('mnonCMyH9TmAsSj3M59DsbH8H63U3RKoFP', 'cTrh7dkEAeJd6b3MRX9bZK8eRmNqVCMH3LSUkE3dSFDyzjU38QxK'),
+ ('mqJupas8Dt2uestQDvV2NH3RU8uZh2dqQR', 'cVuKKa7gbehEQvVq717hYcbE9Dqmq7KEBKqWgWrYBa2CKKrhtRim'),
+ ('msYac7Rvd5ywm6pEmkjyxhbCDKqWsVeYws', 'cQDCBuKcjanpXDpCqacNSjYfxeQj8G6CAtH1Dsk3cXyqLNC4RPuh'),
+ ('n2rnuUnwLgXqf9kk2kjvVm8R5BZK1yxQBi', 'cQakmfPSLSqKHyMFGwAqKHgWUiofJCagVGhiB4KCainaeCSxeyYq'),
+ ('myzuPxRwsf3vvGzEuzPfK9Nf2RfwauwYe6', 'cQMpDLJwA8DBe9NcQbdoSb1BhmFxVjWD5gRyrLZCtpuF9Zi3a9RK'),
+ ('mumwTaMtbxEPUswmLBBN3vM9oGRtGBrys8', 'cSXmRKXVcoouhNNVpcNKFfxsTsToY5pvB9DVsFksF1ENunTzRKsy'),
+ ('mpV7aGShMkJCZgbW7F6iZgrvuPHjZjH9qg', 'cSoXt6tm3pqy43UMabY6eUTmR3eSUYFtB2iNQDGgb3VUnRsQys2k'),
+ ]
+ return PRIV_KEYS[self.index]
+
def _node_msg(self, msg: str) -> str:
"""Return a modified msg that identifies this node by its index as a debugging aid."""
return "[node %d] %s" % (self.index, msg)
@@ -229,6 +246,23 @@ class TestNode():
def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT):
wait_until(self.is_node_stopped, timeout=timeout)
+ @contextlib.contextmanager
+ def assert_debug_log(self, expected_msgs):
+ debug_log = os.path.join(self.datadir, 'regtest', 'debug.log')
+ with open(debug_log, encoding='utf-8') as dl:
+ dl.seek(0, 2)
+ prev_size = dl.tell()
+ try:
+ yield
+ finally:
+ with open(debug_log, encoding='utf-8') as dl:
+ dl.seek(prev_size)
+ log = dl.read()
+ print_log = " - " + "\n - ".join(log.splitlines())
+ for expected_msg in expected_msgs:
+ if re.search(re.escape(expected_msg), log, flags=re.MULTILINE) is None:
+ self._raise_assertion_error('Expected message "{}" does not partially match log:\n\n{}\n\n'.format(expected_msg, print_log))
+
def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, match=ErrorMatch.FULL_TEXT, *args, **kwargs):
"""Attempt to start the node and expect it to raise an error.
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index feea2a327a..0befab6c64 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -124,6 +124,7 @@ BASE_SCRIPTS = [
'wallet_importprunedfunds.py',
'rpc_zmq.py',
'rpc_signmessage.py',
+ 'wallet_balance.py',
'feature_nulldummy.py',
'mempool_accept.py',
'wallet_import_rescan.py',
@@ -152,6 +153,7 @@ BASE_SCRIPTS = [
'p2p_node_network_limited.py',
'feature_blocksdir.py',
'feature_config_args.py',
+ 'rpc_help.py',
'feature_help.py',
# Don't append tests at the end to avoid merge conflicts
# Put them in a random line within the section that fits their approximate run-time
@@ -235,8 +237,6 @@ def main():
logging.debug("Temporary test directory at %s" % tmpdir)
- enable_wallet = config["components"].getboolean("ENABLE_WALLET")
- enable_utils = config["components"].getboolean("ENABLE_UTILS")
enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND")
if config["environment"]["EXEEXT"] == ".exe" and not args.force:
@@ -245,9 +245,9 @@ def main():
print("Tests currently disabled on Windows by default. Use --force option to enable")
sys.exit(0)
- if not (enable_wallet and enable_utils and enable_bitcoind):
- print("No functional tests to run. Wallet, utils, and bitcoind must all be enabled")
- print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make")
+ if not enable_bitcoind:
+ print("No functional tests to run.")
+ print("Rerun ./configure with --with-daemon and then make")
sys.exit(0)
# Build list of tests
diff --git a/test/functional/wallet_abandonconflict.py b/test/functional/wallet_abandonconflict.py
index 8a57b55ca9..e5ac2c8bd4 100755
--- a/test/functional/wallet_abandonconflict.py
+++ b/test/functional/wallet_abandonconflict.py
@@ -20,6 +20,9 @@ class AbandonConflictTest(BitcoinTestFramework):
self.num_nodes = 2
self.extra_args = [["-minrelaytxfee=0.00001"], []]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.nodes[1].generate(100)
sync_blocks(self.nodes)
diff --git a/test/functional/wallet_address_types.py b/test/functional/wallet_address_types.py
index 01c7b6366a..9b398ef346 100755
--- a/test/functional/wallet_address_types.py
+++ b/test/functional/wallet_address_types.py
@@ -63,6 +63,7 @@ from test_framework.util import (
sync_mempools,
)
+
class AddressTypeTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 6
@@ -72,9 +73,12 @@ class AddressTypeTest(BitcoinTestFramework):
["-addresstype=p2sh-segwit", "-changetype=bech32"],
["-addresstype=bech32"],
["-changetype=p2sh-segwit"],
- []
+ [],
]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
self.setup_nodes()
diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py
index 4ef8f4776b..32ec385fa1 100755
--- a/test/functional/wallet_backup.py
+++ b/test/functional/wallet_backup.py
@@ -45,6 +45,9 @@ class WalletBackupTest(BitcoinTestFramework):
# nodes 1, 2,3 are spenders, let's give them a keypool=100
self.extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self, split=False):
self.setup_nodes()
connect_nodes(self.nodes[0], 3)
diff --git a/test/functional/wallet_balance.py b/test/functional/wallet_balance.py
new file mode 100755
index 0000000000..05c97e0340
--- /dev/null
+++ b/test/functional/wallet_balance.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python3
+# Copyright (c) 2018 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test the wallet balance RPC methods."""
+from decimal import Decimal
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import (
+ assert_equal,
+ assert_raises_rpc_error,
+)
+
+RANDOM_COINBASE_ADDRESS = 'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ'
+
+def create_transactions(node, address, amt, fees):
+ # Create and sign raw transactions from node to address for amt.
+ # Creates a transaction for each fee and returns an array
+ # of the raw transactions.
+ utxos = node.listunspent(0)
+
+ # Create transactions
+ inputs = []
+ ins_total = 0
+ for utxo in utxos:
+ inputs.append({"txid": utxo["txid"], "vout": utxo["vout"]})
+ ins_total += utxo['amount']
+ if ins_total > amt:
+ break
+
+ txs = []
+ for fee in fees:
+ outputs = {address: amt, node.getrawchangeaddress(): ins_total - amt - fee}
+ raw_tx = node.createrawtransaction(inputs, outputs, 0, True)
+ raw_tx = node.signrawtransactionwithwallet(raw_tx)
+ txs.append(raw_tx)
+
+ return txs
+
+class WalletTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 2
+ self.setup_clean_chain = True
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
+ def run_test(self):
+ # Check that nodes don't own any UTXOs
+ assert_equal(len(self.nodes[0].listunspent()), 0)
+ assert_equal(len(self.nodes[1].listunspent()), 0)
+
+ self.log.info("Mining one block for each node")
+
+ self.nodes[0].generate(1)
+ self.sync_all()
+ self.nodes[1].generate(1)
+ self.nodes[1].generatetoaddress(100, RANDOM_COINBASE_ADDRESS)
+ self.sync_all()
+
+ assert_equal(self.nodes[0].getbalance(), 50)
+ assert_equal(self.nodes[1].getbalance(), 50)
+
+ self.log.info("Test getbalance with different arguments")
+ assert_equal(self.nodes[0].getbalance("*"), 50)
+ assert_equal(self.nodes[0].getbalance("*", 1), 50)
+ assert_equal(self.nodes[0].getbalance("*", 1, True), 50)
+ assert_equal(self.nodes[0].getbalance(minconf=1), 50)
+
+ # Send 40 BTC from 0 to 1 and 60 BTC from 1 to 0.
+ txs = create_transactions(self.nodes[0], self.nodes[1].getnewaddress(), 40, [Decimal('0.01')])
+ self.nodes[0].sendrawtransaction(txs[0]['hex'])
+ self.nodes[1].sendrawtransaction(txs[0]['hex']) # sending on both nodes is faster than waiting for propagation
+
+ self.sync_all()
+ txs = create_transactions(self.nodes[1], self.nodes[0].getnewaddress(), 60, [Decimal('0.01'), Decimal('0.02')])
+ self.nodes[1].sendrawtransaction(txs[0]['hex'])
+ self.nodes[0].sendrawtransaction(txs[0]['hex']) # sending on both nodes is faster than waiting for propagation
+ self.sync_all()
+
+ # First argument of getbalance must be set to "*"
+ assert_raises_rpc_error(-32, "dummy first argument must be excluded or set to \"*\"", self.nodes[1].getbalance, "")
+
+ self.log.info("Test getbalance and getunconfirmedbalance with unconfirmed inputs")
+
+ # getbalance without any arguments includes unconfirmed transactions, but not untrusted transactions
+ assert_equal(self.nodes[0].getbalance(), Decimal('9.99')) # change from node 0's send
+ assert_equal(self.nodes[1].getbalance(), Decimal('29.99')) # change from node 1's send
+ # Same with minconf=0
+ assert_equal(self.nodes[0].getbalance(minconf=0), Decimal('9.99'))
+ assert_equal(self.nodes[1].getbalance(minconf=0), Decimal('29.99'))
+ # getbalance with a minconf incorrectly excludes coins that have been spent more recently than the minconf blocks ago
+ # TODO: fix getbalance tracking of coin spentness depth
+ assert_equal(self.nodes[0].getbalance(minconf=1), Decimal('0'))
+ assert_equal(self.nodes[1].getbalance(minconf=1), Decimal('0'))
+ # getunconfirmedbalance
+ assert_equal(self.nodes[0].getunconfirmedbalance(), Decimal('60')) # output of node 1's spend
+ assert_equal(self.nodes[1].getunconfirmedbalance(), Decimal('0')) # Doesn't include output of node 0's send since it was spent
+
+ # Node 1 bumps the transaction fee and resends
+ self.nodes[1].sendrawtransaction(txs[1]['hex'])
+ self.sync_all()
+
+ self.log.info("Test getbalance and getunconfirmedbalance with conflicted unconfirmed inputs")
+
+ assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], Decimal('60')) # output of node 1's send
+ assert_equal(self.nodes[0].getunconfirmedbalance(), Decimal('60'))
+ assert_equal(self.nodes[1].getwalletinfo()["unconfirmed_balance"], Decimal('0')) # Doesn't include output of node 0's send since it was spent
+ assert_equal(self.nodes[1].getunconfirmedbalance(), Decimal('0'))
+
+ self.nodes[1].generatetoaddress(1, RANDOM_COINBASE_ADDRESS)
+ self.sync_all()
+
+ # balances are correct after the transactions are confirmed
+ assert_equal(self.nodes[0].getbalance(), Decimal('69.99')) # node 1's send plus change from node 0's send
+ assert_equal(self.nodes[1].getbalance(), Decimal('29.98')) # change from node 0's send
+
+ # Send total balance away from node 1
+ txs = create_transactions(self.nodes[1], self.nodes[0].getnewaddress(), Decimal('29.97'), [Decimal('0.01')])
+ self.nodes[1].sendrawtransaction(txs[0]['hex'])
+ self.nodes[1].generatetoaddress(2, RANDOM_COINBASE_ADDRESS)
+ self.sync_all()
+
+ # getbalance with a minconf incorrectly excludes coins that have been spent more recently than the minconf blocks ago
+ # TODO: fix getbalance tracking of coin spentness depth
+ # getbalance with minconf=3 should still show the old balance
+ assert_equal(self.nodes[1].getbalance(minconf=3), Decimal('0'))
+
+ # getbalance with minconf=2 will show the new balance.
+ assert_equal(self.nodes[1].getbalance(minconf=2), Decimal('0'))
+
+if __name__ == '__main__':
+ WalletTest().main()
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index ea0346543a..d8ab390afa 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -23,6 +23,9 @@ class WalletTest(BitcoinTestFramework):
self.num_nodes = 4
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
self.add_nodes(4)
self.start_node(0)
@@ -64,15 +67,6 @@ class WalletTest(BitcoinTestFramework):
assert_equal(self.nodes[1].getbalance(), 50)
assert_equal(self.nodes[2].getbalance(), 0)
- # Check getbalance with different arguments
- assert_equal(self.nodes[0].getbalance("*"), 50)
- assert_equal(self.nodes[0].getbalance("*", 1), 50)
- assert_equal(self.nodes[0].getbalance("*", 1, True), 50)
- assert_equal(self.nodes[0].getbalance(minconf=1), 50)
-
- # first argument of getbalance must be excluded or set to "*"
- assert_raises_rpc_error(-32, "dummy first argument must be excluded or set to \"*\"", self.nodes[0].getbalance, "")
-
# Check that only first and second nodes have UTXOs
utxos = self.nodes[0].listunspent()
assert_equal(len(utxos), 1)
@@ -239,10 +233,6 @@ class WalletTest(BitcoinTestFramework):
assert(txid1 in self.nodes[3].getrawmempool())
- # Exercise balance rpcs
- assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], 1)
- assert_equal(self.nodes[0].getunconfirmedbalance(), 1)
-
# check if we can list zero value tx as available coins
# 1. create raw_tx
# 2. hex-changed one output to 0.0
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index dd95bb5e22..b9fe6c66c5 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -31,8 +31,13 @@ class BumpFeeTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
- self.extra_args = [["-deprecatedrpc=addwitnessaddress", "-walletrbf={}".format(i)]
- for i in range(self.num_nodes)]
+ self.extra_args = [[
+ "-deprecatedrpc=addwitnessaddress",
+ "-walletrbf={}".format(i),
+ ] for i in range(self.num_nodes)]
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
def run_test(self):
# Encrypt wallet for test_locked_wallet_fails test
diff --git a/test/functional/wallet_disableprivatekeys.py b/test/functional/wallet_disableprivatekeys.py
index 0ba2cfe9be..34ff525255 100755
--- a/test/functional/wallet_disableprivatekeys.py
+++ b/test/functional/wallet_disableprivatekeys.py
@@ -17,6 +17,9 @@ class DisablePrivateKeysTest(BitcoinTestFramework):
self.num_nodes = 1
self.supports_cli = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
node = self.nodes[0]
self.log.info("Test disableprivatekeys creation.")
diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py
index 63316d9644..db731b2a34 100755
--- a/test/functional/wallet_dump.py
+++ b/test/functional/wallet_dump.py
@@ -29,50 +29,54 @@ def read_dump(file_name, addrs, script_addrs, hd_master_addr_old):
# only read non comment lines
if line[0] != "#" and len(line) > 10:
# split out some data
- key_label, comment = line.split("#")
- # key = key_label.split(" ")[0]
- keytype = key_label.split(" ")[2]
- if len(comment) > 1:
- addr_keypath = comment.split(" addr=")[1]
- addr = addr_keypath.split(" ")[0]
+ key_date_label, comment = line.split("#")
+ key_date_label = key_date_label.split(" ")
+ # key = key_date_label[0]
+ date = key_date_label[1]
+ keytype = key_date_label[2]
+ if not len(comment) or date.startswith('1970'):
+ continue
+
+ addr_keypath = comment.split(" addr=")[1]
+ addr = addr_keypath.split(" ")[0]
+ keypath = None
+ if keytype == "inactivehdseed=1":
+ # ensure the old master is still available
+ assert (hd_master_addr_old == addr)
+ elif keytype == "hdseed=1":
+ # ensure we have generated a new hd master key
+ assert (hd_master_addr_old != addr)
+ hd_master_addr_ret = addr
+ elif keytype == "script=1":
+ # scripts don't have keypaths
keypath = None
- if keytype == "inactivehdseed=1":
- # ensure the old master is still available
- assert(hd_master_addr_old == addr)
- elif keytype == "hdseed=1":
- # ensure we have generated a new hd master key
- assert(hd_master_addr_old != addr)
- hd_master_addr_ret = addr
- elif keytype == "script=1":
- # scripts don't have keypaths
- keypath = None
- else:
- keypath = addr_keypath.rstrip().split("hdkeypath=")[1]
-
- # count key types
- for addrObj in addrs:
- if addrObj['address'] == addr.split(",")[0] and addrObj['hdkeypath'] == keypath and keytype == "label=":
- # a labeled entry in the wallet should contain both a native address
- # and the p2sh-p2wpkh address that was added at wallet setup
- if len(addr.split(",")) == 2:
- addr_list = addr.split(",")
- # the entry should be of the first key in the wallet
- assert_equal(addrs[0]['address'], addr_list[0])
- witness_addr_ret = addr_list[1]
- found_addr += 1
- break
- elif keytype == "change=1":
- found_addr_chg += 1
- break
- elif keytype == "reserve=1":
- found_addr_rsv += 1
- break
-
- # count scripts
- for script_addr in script_addrs:
- if script_addr == addr.rstrip() and keytype == "script=1":
- found_script_addr += 1
- break
+ else:
+ keypath = addr_keypath.rstrip().split("hdkeypath=")[1]
+
+ # count key types
+ for addrObj in addrs:
+ if addrObj['address'] == addr.split(",")[0] and addrObj['hdkeypath'] == keypath and keytype == "label=":
+ # a labeled entry in the wallet should contain both a native address
+ # and the p2sh-p2wpkh address that was added at wallet setup
+ if len(addr.split(",")) == 2:
+ addr_list = addr.split(",")
+ # the entry should be of the first key in the wallet
+ assert_equal(addrs[0]['address'], addr_list[0])
+ witness_addr_ret = addr_list[1]
+ found_addr += 1
+ break
+ elif keytype == "change=1":
+ found_addr_chg += 1
+ break
+ elif keytype == "reserve=1":
+ found_addr_rsv += 1
+ break
+
+ # count scripts
+ for script_addr in script_addrs:
+ if script_addr == addr.rstrip() and keytype == "script=1":
+ found_script_addr += 1
+ break
return found_addr, found_script_addr, found_addr_chg, found_addr_rsv, hd_master_addr_ret, witness_addr_ret
@@ -83,6 +87,9 @@ class WalletDumpTest(BitcoinTestFramework):
self.extra_args = [["-keypool=90", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"]]
self.rpc_timeout = 120
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self, split=False):
self.add_nodes(self.num_nodes, extra_args=self.extra_args)
self.start_nodes()
@@ -116,9 +123,9 @@ class WalletDumpTest(BitcoinTestFramework):
read_dump(wallet_unenc_dump, addrs, script_addrs, None)
assert_equal(found_addr, test_addr_count) # all keys must be in the dump
assert_equal(found_script_addr, 2) # all scripts must be in the dump
- assert_equal(found_addr_chg, 50) # 50 blocks where mined
- assert_equal(found_addr_rsv, 90*2) # 90 keys plus 100% internal keys
- assert_equal(witness_addr_ret, witness_addr) # p2sh-p2wsh address added to the first key
+ assert_equal(found_addr_chg, 0) # 0 blocks where mined
+ assert_equal(found_addr_rsv, 90 * 2) # 90 keys plus 100% internal keys
+ assert_equal(witness_addr_ret, witness_addr) # p2sh-p2wsh address added to the first key
#encrypt wallet, restart, unlock and dump
self.nodes[0].node_encrypt_wallet('test')
@@ -132,8 +139,8 @@ class WalletDumpTest(BitcoinTestFramework):
read_dump(wallet_enc_dump, addrs, script_addrs, hd_master_addr_unenc)
assert_equal(found_addr, test_addr_count)
assert_equal(found_script_addr, 2)
- assert_equal(found_addr_chg, 90*2 + 50) # old reserve keys are marked as change now
- assert_equal(found_addr_rsv, 90*2)
+ assert_equal(found_addr_chg, 90 * 2) # old reserve keys are marked as change now
+ assert_equal(found_addr_rsv, 90 * 2)
assert_equal(witness_addr_ret, witness_addr)
# Overwriting should fail
diff --git a/test/functional/wallet_encryption.py b/test/functional/wallet_encryption.py
index cec9660259..d8c27b09d9 100755
--- a/test/functional/wallet_encryption.py
+++ b/test/functional/wallet_encryption.py
@@ -19,6 +19,9 @@ class WalletEncryptionTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 1
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
passphrase = "WalletPassphrase"
passphrase2 = "SecondWalletPassphrase"
diff --git a/test/functional/wallet_fallbackfee.py b/test/functional/wallet_fallbackfee.py
index 91dbae8939..0c67982bbe 100755
--- a/test/functional/wallet_fallbackfee.py
+++ b/test/functional/wallet_fallbackfee.py
@@ -11,6 +11,9 @@ class WalletRBFTest(BitcoinTestFramework):
self.num_nodes = 1
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.nodes[0].generate(101)
diff --git a/test/functional/wallet_groups.py b/test/functional/wallet_groups.py
index 12dac145bd..9d61483868 100755
--- a/test/functional/wallet_groups.py
+++ b/test/functional/wallet_groups.py
@@ -23,7 +23,10 @@ class WalletGroupTest(BitcoinTestFramework):
self.extra_args = [[], [], ['-avoidpartialspends']]
self.rpc_timewait = 120
- def run_test (self):
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
+ def run_test(self):
# Mine some coins
self.nodes[0].generate(110)
diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py
index 2a5f1934b7..48e71f6c40 100755
--- a/test/functional/wallet_hd.py
+++ b/test/functional/wallet_hd.py
@@ -21,6 +21,9 @@ class WalletHDTest(BitcoinTestFramework):
self.num_nodes = 2
self.extra_args = [[], ['-keypool=0']]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
# Make sure can't switch off usehd after wallet creation
self.stop_node(1)
diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py
index 0c6359976a..b6e3a4bcd5 100755
--- a/test/functional/wallet_import_rescan.py
+++ b/test/functional/wallet_import_rescan.py
@@ -46,11 +46,11 @@ class Variant(collections.namedtuple("Variant", "call data rescan prune")):
if self.call == Call.single:
if self.data == Data.address:
- response = self.try_rpc(self.node.importaddress, address=self.address["address"], rescan=rescan)
+ response = self.try_rpc(self.node.importaddress, address=self.address["address"], label=self.label, rescan=rescan)
elif self.data == Data.pub:
- response = self.try_rpc(self.node.importpubkey, pubkey=self.address["pubkey"], rescan=rescan)
+ response = self.try_rpc(self.node.importpubkey, pubkey=self.address["pubkey"], label=self.label, rescan=rescan)
elif self.data == Data.priv:
- response = self.try_rpc(self.node.importprivkey, privkey=self.key, rescan=rescan)
+ response = self.try_rpc(self.node.importprivkey, privkey=self.key, label=self.label, rescan=rescan)
assert_equal(response, None)
elif self.call == Call.multi:
@@ -61,18 +61,32 @@ class Variant(collections.namedtuple("Variant", "call data rescan prune")):
"timestamp": timestamp + TIMESTAMP_WINDOW + (1 if self.rescan == Rescan.late_timestamp else 0),
"pubkeys": [self.address["pubkey"]] if self.data == Data.pub else [],
"keys": [self.key] if self.data == Data.priv else [],
+ "label": self.label,
"watchonly": self.data != Data.priv
}], {"rescan": self.rescan in (Rescan.yes, Rescan.late_timestamp)})
assert_equal(response, [{"success": True}])
def check(self, txid=None, amount=None, confirmations=None):
- """Verify that listreceivedbyaddress returns expected values."""
+ """Verify that listtransactions/listreceivedbyaddress return expected values."""
+
+ txs = self.node.listtransactions(label=self.label, count=10000, skip=0, include_watchonly=True)
+ assert_equal(len(txs), self.expected_txs)
addresses = self.node.listreceivedbyaddress(minconf=0, include_watchonly=True, address_filter=self.address['address'])
if self.expected_txs:
assert_equal(len(addresses[0]["txids"]), self.expected_txs)
if txid is not None:
+ tx, = [tx for tx in txs if tx["txid"] == txid]
+ assert_equal(tx["label"], self.label)
+ assert_equal(tx["address"], self.address["address"])
+ assert_equal(tx["amount"], amount)
+ assert_equal(tx["category"], "receive")
+ assert_equal(tx["label"], self.label)
+ assert_equal(tx["txid"], txid)
+ assert_equal(tx["confirmations"], confirmations)
+ assert_equal("trusted" not in tx, True)
+
address, = [ad for ad in addresses if txid in ad["txids"]]
assert_equal(address["address"], self.address["address"])
assert_equal(address["amount"], self.expected_balance)
@@ -109,6 +123,9 @@ class ImportRescanTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2 + len(IMPORT_NODES)
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
extra_args = [["-addresstype=legacy"] for _ in range(self.num_nodes)]
for i, import_node in enumerate(IMPORT_NODES, 2):
@@ -116,15 +133,25 @@ class ImportRescanTest(BitcoinTestFramework):
extra_args[i] += ["-prune=1"]
self.add_nodes(self.num_nodes, extra_args=extra_args)
+
+ # Import keys
+ self.start_nodes(extra_args=[[]] * self.num_nodes)
+ super().import_deterministic_coinbase_privkeys()
+ self.stop_nodes()
+
self.start_nodes()
for i in range(1, self.num_nodes):
connect_nodes(self.nodes[i], 0)
+ def import_deterministic_coinbase_privkeys(self):
+ pass
+
def run_test(self):
# Create one transaction on node 0 with a unique amount for
# each possible type of wallet import RPC.
for i, variant in enumerate(IMPORT_VARIANTS):
- variant.address = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress())
+ variant.label = "label {} {}".format(i, variant)
+ variant.address = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress(variant.label))
variant.key = self.nodes[1].dumpprivkey(variant.address["address"])
variant.initial_amount = 10 - (i + 1) / 4.0
variant.initial_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.initial_amount)
diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py
index 5f19e1e2c6..3dd296d603 100755
--- a/test/functional/wallet_importmulti.py
+++ b/test/functional/wallet_importmulti.py
@@ -12,6 +12,9 @@ class ImportMultiTest (BitcoinTestFramework):
self.extra_args = [["-addresstype=legacy"], ["-addresstype=legacy"]]
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def setup_network(self):
self.setup_nodes()
diff --git a/test/functional/wallet_importprunedfunds.py b/test/functional/wallet_importprunedfunds.py
index 57fc754d35..26b181db33 100755
--- a/test/functional/wallet_importprunedfunds.py
+++ b/test/functional/wallet_importprunedfunds.py
@@ -16,6 +16,9 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 2
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.log.info("Mining blocks...")
self.nodes[0].generate(101)
diff --git a/test/functional/wallet_keypool.py b/test/functional/wallet_keypool.py
index f52dce04dd..acc336e4d5 100755
--- a/test/functional/wallet_keypool.py
+++ b/test/functional/wallet_keypool.py
@@ -13,6 +13,9 @@ class KeyPoolTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
nodes = self.nodes
addr_before_encrypting = nodes[0].getnewaddress()
diff --git a/test/functional/wallet_keypool_topup.py b/test/functional/wallet_keypool_topup.py
index f6b88e6225..f1a441c399 100755
--- a/test/functional/wallet_keypool_topup.py
+++ b/test/functional/wallet_keypool_topup.py
@@ -27,6 +27,9 @@ class KeypoolRestoreTest(BitcoinTestFramework):
self.num_nodes = 2
self.extra_args = [[], ['-keypool=100']]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
wallet_path = os.path.join(self.nodes[1].datadir, "regtest", "wallets", "wallet.dat")
wallet_backup_path = os.path.join(self.nodes[1].datadir, "wallet.bak")
diff --git a/test/functional/wallet_labels.py b/test/functional/wallet_labels.py
index 0817054149..6f9123a089 100755
--- a/test/functional/wallet_labels.py
+++ b/test/functional/wallet_labels.py
@@ -30,6 +30,9 @@ class WalletLabelsTest(BitcoinTestFramework):
"""Don't connect nodes."""
self.setup_nodes()
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
"""Run the test twice - once using the accounts API and once using the labels API."""
self.log.info("Test accounts API")
diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py
index 09a7c72347..9e8667c600 100755
--- a/test/functional/wallet_listreceivedby.py
+++ b/test/functional/wallet_listreceivedby.py
@@ -18,6 +18,14 @@ class ReceivedByTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
+ def import_deterministic_coinbase_privkeys(self):
+ assert_equal(0, len(self.nodes[1].listreceivedbyaddress(minconf=0, include_empty=True, include_watchonly=True)))
+ super().import_deterministic_coinbase_privkeys()
+ self.num_cb_reward_addresses = len(self.nodes[1].listreceivedbyaddress(minconf=0, include_empty=True, include_watchonly=True))
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
# Generate block to get out of IBD
self.nodes[0].generate(1)
@@ -60,11 +68,15 @@ class ReceivedByTest(BitcoinTestFramework):
res = self.nodes[1].listreceivedbyaddress(minconf=0, include_empty=True, include_watchonly=True, address_filter=addr)
assert_array_result(res, {"address": addr}, expected)
assert_equal(len(res), 1)
+ # Test for regression on CLI calls with address string (#14173)
+ cli_res = self.nodes[1].cli.listreceivedbyaddress(0, True, True, addr)
+ assert_array_result(cli_res, {"address": addr}, expected)
+ assert_equal(len(cli_res), 1)
# Error on invalid address
assert_raises_rpc_error(-4, "address_filter parameter was invalid", self.nodes[1].listreceivedbyaddress, minconf=0, include_empty=True, include_watchonly=True, address_filter="bamboozling")
# Another address receive money
res = self.nodes[1].listreceivedbyaddress(0, True, True)
- assert_equal(len(res), 2) # Right now 2 entries
+ assert_equal(len(res), 2 + self.num_cb_reward_addresses) # Right now 2 entries
other_addr = self.nodes[1].getnewaddress()
txid2 = self.nodes[0].sendtoaddress(other_addr, 0.1)
self.nodes[0].generate(1)
@@ -81,7 +93,7 @@ class ReceivedByTest(BitcoinTestFramework):
assert_equal(len(res), 1)
# Should be two entries though without filter
res = self.nodes[1].listreceivedbyaddress(0, True, True)
- assert_equal(len(res), 3) # Became 3 entries
+ assert_equal(len(res), 3 + self.num_cb_reward_addresses) # Became 3 entries
# Not on random addr
other_addr = self.nodes[0].getnewaddress() # note on node[0]! just a random addr
diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py
index 847b48aa89..53e671cd3b 100755
--- a/test/functional/wallet_listsinceblock.py
+++ b/test/functional/wallet_listsinceblock.py
@@ -12,6 +12,9 @@ class ListSinceBlockTest (BitcoinTestFramework):
self.num_nodes = 4
self.setup_clean_chain = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.nodes[2].generate(101)
self.sync_all()
diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py
index 4dc3ff4b26..00a6b9c393 100755
--- a/test/functional/wallet_listtransactions.py
+++ b/test/functional/wallet_listtransactions.py
@@ -27,6 +27,9 @@ class ListTransactionsTest(BitcoinTestFramework):
self.num_nodes = 2
self.enable_mocktime()
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
# Simple send, 0 to 1:
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
@@ -94,9 +97,10 @@ class ListTransactionsTest(BitcoinTestFramework):
txid = self.nodes[1].sendtoaddress(multisig["address"], 0.1)
self.nodes[1].generate(1)
self.sync_all()
- assert not [tx for tx in self.nodes[0].listtransactions(dummy="*", count=100, skip=0, include_watchonly=False) if "label" in tx and tx["label"] == "watchonly"]
- txs = [tx for tx in self.nodes[0].listtransactions(dummy="*", count=100, skip=0, include_watchonly=True) if "label" in tx and tx['label'] == 'watchonly']
- assert_array_result(txs, {"category": "receive", "amount": Decimal("0.1")}, {"txid": txid})
+ assert len(self.nodes[0].listtransactions(label="watchonly", count=100, skip=0, include_watchonly=False)) == 0
+ assert_array_result(self.nodes[0].listtransactions(label="watchonly", count=100, skip=0, include_watchonly=True),
+ {"category": "receive", "amount": Decimal("0.1")},
+ {"txid": txid, "label": "watchonly"})
self.run_rbf_opt_in_test()
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index 0690dcf92d..435821ec48 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -23,6 +23,9 @@ class MultiWalletTest(BitcoinTestFramework):
self.num_nodes = 2
self.supports_cli = True
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
node = self.nodes[0]
diff --git a/test/functional/wallet_resendwallettransactions.py b/test/functional/wallet_resendwallettransactions.py
index 8995aa743f..00bf58d709 100755
--- a/test/functional/wallet_resendwallettransactions.py
+++ b/test/functional/wallet_resendwallettransactions.py
@@ -12,6 +12,9 @@ class ResendWalletTransactionsTest(BitcoinTestFramework):
self.num_nodes = 1
self.extra_args = [['--walletbroadcast=false']]
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
# Should raise RPC_WALLET_ERROR (-4) if walletbroadcast is disabled.
assert_raises_rpc_error(-4, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast", self.nodes[0].resendwallettransactions)
diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py
index 4ca4ee14e9..d78c105c17 100755
--- a/test/functional/wallet_txn_clone.py
+++ b/test/functional/wallet_txn_clone.py
@@ -16,6 +16,9 @@ class TxnMallTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def add_options(self, parser):
parser.add_argument("--mineblock", dest="mine_block", default=False, action="store_true",
help="Test double-spend of 1-confirmed transaction")
diff --git a/test/functional/wallet_txn_doublespend.py b/test/functional/wallet_txn_doublespend.py
index 6811f6ab73..f114d5ab68 100755
--- a/test/functional/wallet_txn_doublespend.py
+++ b/test/functional/wallet_txn_doublespend.py
@@ -18,6 +18,9 @@ class TxnMallTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def add_options(self, parser):
parser.add_argument("--mineblock", dest="mine_block", default=False, action="store_true",
help="Test double-spend of 1-confirmed transaction")
diff --git a/test/functional/wallet_zapwallettxes.py b/test/functional/wallet_zapwallettxes.py
index cbd142d1ee..adebff360a 100755
--- a/test/functional/wallet_zapwallettxes.py
+++ b/test/functional/wallet_zapwallettxes.py
@@ -26,6 +26,9 @@ class ZapWalletTXesTest (BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 2
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
def run_test(self):
self.log.info("Mining blocks...")
self.nodes[0].generate(1)