aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am18
-rw-r--r--configure.ac7
-rw-r--r--contrib/devtools/README.md8
-rwxr-xr-xcontrib/devtools/gen-manpages.sh12
-rw-r--r--depends/Makefile1
-rw-r--r--depends/hosts/default.mk4
-rw-r--r--depends/packages/openssl.mk1
-rw-r--r--doc/README_osx.md2
-rw-r--r--doc/REST-interface.md2
-rw-r--r--doc/build-windows.md2
-rw-r--r--doc/developer-notes.md2
-rw-r--r--doc/release-notes.md2
-rw-r--r--doc/release-notes/release-notes-0.16.0.md720
-rw-r--r--doc/translation_process.md2
-rw-r--r--doc/zmq.md2
-rw-r--r--src/Makefile.am7
-rw-r--r--src/Makefile.bench.include4
-rw-r--r--src/bench/coin_selection.cpp11
-rw-r--r--src/bench/prevector.cpp77
-rw-r--r--src/bench/prevector_destructor.cpp36
-rw-r--r--src/chainparams.cpp8
-rw-r--r--src/chainparams.h3
-rw-r--r--src/compat.h10
-rw-r--r--src/init.cpp6
-rw-r--r--src/leveldb/db/db_impl.cc2
-rw-r--r--src/leveldb/db/leveldbutil.cc1
-rw-r--r--src/leveldb/db/log_reader.cc2
-rw-r--r--src/leveldb/db/repair.cc2
-rw-r--r--src/leveldb/helpers/memenv/memenv.cc3
-rw-r--r--src/leveldb/include/leveldb/env.h9
-rw-r--r--src/leveldb/table/format.cc10
-rw-r--r--src/leveldb/util/env_posix.cc8
-rw-r--r--src/leveldb/util/env_win.cc3
-rw-r--r--src/net.cpp7
-rw-r--r--src/net.h1
-rw-r--r--src/net_processing.cpp13
-rw-r--r--src/netbase.cpp2
-rw-r--r--src/prevector.h114
-rw-r--r--src/protocol.cpp13
-rw-r--r--src/protocol.h12
-rw-r--r--src/qt/bitcoin.cpp2
-rw-r--r--src/qt/clientmodel.cpp2
-rw-r--r--src/qt/guiutil.cpp2
-rw-r--r--src/qt/rpcconsole.cpp9
-rw-r--r--src/qt/sendcoinsdialog.cpp1
-rw-r--r--src/qt/sendcoinsdialog.h3
-rw-r--r--src/qt/test/rpcnestedtests.cpp4
-rw-r--r--src/qt/transactiondesc.cpp2
-rw-r--r--src/qt/transactionview.cpp29
-rw-r--r--src/qt/transactionview.h4
-rw-r--r--src/qt/walletview.cpp6
-rw-r--r--src/rest.cpp2
-rw-r--r--src/rpc/blockchain.cpp30
-rw-r--r--src/rpc/client.cpp3
-rw-r--r--src/rpc/misc.cpp209
-rw-r--r--src/rpc/net.cpp2
-rw-r--r--src/rpc/rawtransaction.cpp351
-rw-r--r--src/rpc/rawtransaction.h15
-rw-r--r--src/rpc/util.cpp61
-rw-r--r--src/rpc/util.h9
-rw-r--r--src/test/checkqueue_tests.cpp8
-rw-r--r--src/test/net_tests.cpp2
-rw-r--r--src/test/rpc_tests.cpp12
-rw-r--r--src/test/test_bitcoin.cpp3
-rw-r--r--src/test/util_tests.cpp70
-rw-r--r--src/utilstrencodings.cpp4
-rw-r--r--src/validation.cpp1
-rw-r--r--src/wallet/fees.cpp3
-rw-r--r--src/wallet/init.cpp4
-rw-r--r--src/wallet/rpcdump.cpp4
-rw-r--r--src/wallet/rpcwallet.cpp386
-rw-r--r--src/wallet/rpcwallet.h3
-rw-r--r--src/wallet/test/wallet_test_fixture.cpp1
-rw-r--r--src/wallet/wallet.cpp18
-rw-r--r--src/wallet/wallet.h1
-rwxr-xr-xtest/functional/feature_bip68_sequence.py14
-rwxr-xr-xtest/functional/feature_bip9_softforks.py2
-rwxr-xr-xtest/functional/feature_cltv.py4
-rwxr-xr-xtest/functional/feature_csv_activation.py2
-rwxr-xr-xtest/functional/feature_dbcrash.py2
-rwxr-xr-xtest/functional/feature_dersig.py2
-rwxr-xr-xtest/functional/feature_fee_estimation.py2
-rwxr-xr-xtest/functional/feature_nulldummy.py2
-rwxr-xr-xtest/functional/feature_rbf.py2
-rwxr-xr-xtest/functional/feature_segwit.py32
-rwxr-xr-xtest/functional/interface_rest.py1
-rwxr-xr-xtest/functional/mempool_limit.py4
-rwxr-xr-xtest/functional/mempool_packages.py6
-rwxr-xr-xtest/functional/mempool_reorg.py2
-rwxr-xr-xtest/functional/mining_prioritisetransaction.py2
-rwxr-xr-xtest/functional/p2p_node_network_limited.py78
-rwxr-xr-xtest/functional/rpc_blockchain.py18
-rwxr-xr-xtest/functional/rpc_deprecated.py13
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py30
-rwxr-xr-xtest/functional/rpc_listtransactions.py10
-rwxr-xr-xtest/functional/rpc_rawtransaction.py28
-rwxr-xr-xtest/functional/rpc_signrawtransaction.py30
-rwxr-xr-xtest/functional/rpc_txoutproof.py6
-rw-r--r--test/functional/test_framework/blocktools.py4
-rwxr-xr-x[-rw-r--r--]test/functional/test_framework/messages.py17
-rwxr-xr-xtest/functional/test_framework/test_framework.py2
-rwxr-xr-xtest/functional/test_framework/test_node.py6
-rw-r--r--test/functional/test_framework/util.py13
-rwxr-xr-xtest/functional/test_runner.py1
-rwxr-xr-xtest/functional/wallet_abandonconflict.py6
-rwxr-xr-xtest/functional/wallet_address_types.py4
-rwxr-xr-xtest/functional/wallet_basic.py19
-rwxr-xr-xtest/functional/wallet_bumpfee.py12
-rwxr-xr-xtest/functional/wallet_dump.py8
-rwxr-xr-xtest/functional/wallet_fallbackfee.py28
-rwxr-xr-xtest/functional/wallet_hd.py10
-rwxr-xr-xtest/functional/wallet_import_rescan.py2
-rwxr-xr-xtest/functional/wallet_importmulti.py102
-rwxr-xr-xtest/functional/wallet_importprunedfunds.py14
-rwxr-xr-xtest/functional/wallet_keypool.py4
-rwxr-xr-xtest/functional/wallet_keypool_topup.py2
-rwxr-xr-xtest/functional/wallet_listsinceblock.py6
-rwxr-xr-xtest/functional/wallet_txn_clone.py2
-rwxr-xr-xtest/functional/wallet_txn_doublespend.py2
119 files changed, 2194 insertions, 777 deletions
diff --git a/Makefile.am b/Makefile.am
index b24daf9905..f345760f2d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -277,6 +277,22 @@ CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER)
DISTCHECK_CONFIGURE_FLAGS = --enable-man
-clean-local:
+doc/doxygen/.stamp: doc/Doxyfile FORCE
+ $(MKDIR_P) $(@D)
+ $(DOXYGEN) $^
+ $(AM_V_at) touch $@
+
+if HAVE_DOXYGEN
+docs: doc/doxygen/.stamp
+else
+docs:
+ @echo "error: doxygen not found"
+endif
+
+clean-docs:
+ rm -rf doc/doxygen
+
+clean-local: clean-docs
rm -rf coverage_percent.txt test_bitcoin.coverage/ total.coverage/ test/tmp/ cache/ $(OSX_APP)
rm -rf test/functional/__pycache__ test/functional/test_framework/__pycache__ test/cache
+
diff --git a/configure.ac b/configure.ac
index 2b6ee1dc3f..c2e34a52ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -93,6 +93,11 @@ AC_PATH_PROG(HEXDUMP,hexdump)
AC_PATH_TOOL(READELF, readelf)
AC_PATH_TOOL(CPPFILT, c++filt)
AC_PATH_TOOL(OBJCOPY, objcopy)
+AC_PATH_PROG(DOXYGEN, doxygen)
+if test -z "$DOXYGEN"; then
+ AC_MSG_WARN([Doxygen not found])
+fi
+AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])
AC_ARG_VAR(PYTHONPATH, Augments the default search path for python module files)
@@ -1260,7 +1265,7 @@ AC_SUBST(PROTOBUF_LIBS)
AC_SUBST(QR_LIBS)
AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist test/config.ini])
AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh])
-AC_CONFIG_FILES([doc/Doxyfile])
+AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])])
AC_CONFIG_LINKS([contrib/filter-lcov.py:contrib/filter-lcov.py])
AC_CONFIG_LINKS([test/functional/test_runner.py:test/functional/test_runner.py])
AC_CONFIG_LINKS([test/util/bitcoin-util-test.py:test/util/bitcoin-util-test.py])
diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md
index 67c5e15a15..8ca8fa9066 100644
--- a/contrib/devtools/README.md
+++ b/contrib/devtools/README.md
@@ -85,6 +85,14 @@ gen-manpages.sh
A small script to automatically create manpages in ../../doc/man by running the release binaries with the -help option.
This requires help2man which can be found at: https://www.gnu.org/software/help2man/
+With in-tree builds this tool can be run from any directory within the
+repostitory. To use this tool with out-of-tree builds set `BUILDDIR`. For
+example:
+
+```bash
+BUILDDIR=$PWD/build contrib/devtools/gen-manpages.sh
+```
+
git-subtree-check.sh
====================
diff --git a/contrib/devtools/gen-manpages.sh b/contrib/devtools/gen-manpages.sh
index 925d6a6252..27c80548c1 100755
--- a/contrib/devtools/gen-manpages.sh
+++ b/contrib/devtools/gen-manpages.sh
@@ -1,13 +1,15 @@
#!/bin/bash
TOPDIR=${TOPDIR:-$(git rev-parse --show-toplevel)}
-SRCDIR=${SRCDIR:-$TOPDIR/src}
+BUILDDIR=${BUILDDIR:-$TOPDIR}
+
+BINDIR=${BINDIR:-$BUILDDIR/src}
MANDIR=${MANDIR:-$TOPDIR/doc/man}
-BITCOIND=${BITCOIND:-$SRCDIR/bitcoind}
-BITCOINCLI=${BITCOINCLI:-$SRCDIR/bitcoin-cli}
-BITCOINTX=${BITCOINTX:-$SRCDIR/bitcoin-tx}
-BITCOINQT=${BITCOINQT:-$SRCDIR/qt/bitcoin-qt}
+BITCOIND=${BITCOIND:-$BINDIR/bitcoind}
+BITCOINCLI=${BITCOINCLI:-$BINDIR/bitcoin-cli}
+BITCOINTX=${BITCOINTX:-$BINDIR/bitcoin-tx}
+BITCOINQT=${BITCOINQT:-$BINDIR/qt/bitcoin-qt}
[ ! -x $BITCOIND ] && echo "$BITCOIND not found or not executable." && exit 1
diff --git a/depends/Makefile b/depends/Makefile
index 0ddd348e53..14e94ba453 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -21,7 +21,6 @@ BUILD_ID_SALT ?= salt
host:=$(BUILD)
ifneq ($(HOST),)
host:=$(HOST)
-host_toolchain:=$(HOST)-
endif
ifneq ($(DEBUG),)
diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk
index 6f60d6b3fd..144e5f88b7 100644
--- a/depends/hosts/default.mk
+++ b/depends/hosts/default.mk
@@ -1,3 +1,7 @@
+ifneq ($(host),$(build))
+host_toolchain:=$(host)-
+endif
+
default_host_CC = $(host_toolchain)gcc
default_host_CXX = $(host_toolchain)g++
default_host_AR = $(host_toolchain)ar
diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk
index 5ee9f17a63..37f0c28a52 100644
--- a/depends/packages/openssl.mk
+++ b/depends/packages/openssl.mk
@@ -47,6 +47,7 @@ $(package)_config_opts_linux=-fPIC -Wa,--noexecstack
$(package)_config_opts_x86_64_linux=linux-x86_64
$(package)_config_opts_i686_linux=linux-generic32
$(package)_config_opts_arm_linux=linux-generic32
+$(package)_config_opts_armv7l_linux=linux-generic32
$(package)_config_opts_aarch64_linux=linux-generic64
$(package)_config_opts_mipsel_linux=linux-generic32
$(package)_config_opts_mips_linux=linux-generic32
diff --git a/doc/README_osx.md b/doc/README_osx.md
index 2a4460478c..975be4be9e 100644
--- a/doc/README_osx.md
+++ b/doc/README_osx.md
@@ -1,4 +1,4 @@
-Deterministic OS X Dmg Notes.
+Deterministic OS X DMG Notes.
Working OS X DMGs are created in Linux by combining a recent clang,
the Apple binutils (ld, ar, etc) and DMG authoring tools.
diff --git a/doc/REST-interface.md b/doc/REST-interface.md
index f3dc124ece..7010edfcd3 100644
--- a/doc/REST-interface.md
+++ b/doc/REST-interface.md
@@ -45,7 +45,7 @@ Only supports JSON as output format.
* verificationprogress : (numeric) estimate of verification progress [0..1]
* chainwork : (string) total amount of work in active chain, in hexadecimal
* pruned : (boolean) if the blocks are subject to pruning
-* pruneheight : (numeric) heighest block available
+* pruneheight : (numeric) highest block available
* softforks : (array) status of softforks in progress
* bip9_softforks : (object) status of BIP9 softforks in progress
diff --git a/doc/build-windows.md b/doc/build-windows.md
index a10654c7ee..cff4ea9362 100644
--- a/doc/build-windows.md
+++ b/doc/build-windows.md
@@ -35,7 +35,7 @@ To install WSL on Windows 10 with Fall Creators Update installed (version >= 162
1. Enable the Windows Subsystem for Linux feature
* Open the Windows Features dialog (`OptionalFeatures.exe`)
- * Enable 'Windows Susbsystem for Linux'
+ * Enable 'Windows Subsystem for Linux'
* Click 'OK' and restart if necessary
2. Install Ubuntu
* Open Microsoft Store and search for Ubuntu or use [this link](https://www.microsoft.com/store/productId/9NBLGGH4MSV6)
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index 9dc63a1e4b..2ebfb59c08 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -132,6 +132,8 @@ Not OK (used plenty in the current source, but not picked up):
A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
but if possible use one of the above styles.
+Documentation can be generated with `make docs` and cleaned up with `make clean-docs`.
+
Development tips and tricks
---------------------------
diff --git a/doc/release-notes.md b/doc/release-notes.md
index 528cb81a38..ac49dc7909 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -48,7 +48,7 @@ Compatibility
==============
Bitcoin Core is extensively tested on multiple operating systems using
-the Linux kernel, macOS 10.8+, and Windows Vista and later. Windows XP is not supported.
+the Linux kernel, macOS 10.8+, and Windows 7 and newer (Windows XP is not supported).
Bitcoin Core should also work on most other Unix-like systems but is not
frequently tested on them.
diff --git a/doc/release-notes/release-notes-0.16.0.md b/doc/release-notes/release-notes-0.16.0.md
new file mode 100644
index 0000000000..8f158b3481
--- /dev/null
+++ b/doc/release-notes/release-notes-0.16.0.md
@@ -0,0 +1,720 @@
+Bitcoin Core version 0.16.0 is now available from:
+
+ <https://bitcoincore.org/bin/bitcoin-core-0.16.0/>
+
+This is a new major version release, including new features, various bugfixes
+and performance improvements, as well as updated translations.
+
+Please report bugs using the issue tracker at GitHub:
+
+ <https://github.com/bitcoin/bitcoin/issues>
+
+To receive security and update notifications, please subscribe to:
+
+ <https://bitcoincore.org/en/list/announcements/join/>
+
+How to Upgrade
+==============
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on Mac)
+or `bitcoind`/`bitcoin-qt` (on Linux).
+
+The first time you run version 0.15.0 or 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.
+
+Note that the block database format also changed in version 0.8.0 and there is no
+automatic upgrade code from before version 0.8 to version 0.15.0 or higher. Upgrading
+directly from 0.7.x and earlier without re-downloading the blockchain is not supported.
+However, as usual, old wallet versions are still supported.
+
+Downgrading warning
+-------------------
+
+Wallets created in 0.16 and later are not compatible with versions prior to 0.16
+and will not work if you try to use newly created wallets in older versions. Existing
+wallets that were created with older versions are not affected by this.
+
+Compatibility
+==============
+
+Bitcoin Core is extensively tested on multiple operating systems using
+the Linux kernel, macOS 10.8+, and Windows Vista and later. Windows XP is not supported.
+
+Bitcoin Core should also work on most other Unix-like systems but is not
+frequently tested on them.
+
+Notable changes
+===============
+
+Wallet changes
+---------------
+
+### Segwit Wallet
+
+Bitcoin Core 0.16.0 introduces full support for segwit in the wallet and user interfaces. A new `-addresstype` argument has been added, which supports `legacy`, `p2sh-segwit` (default), and `bech32` addresses. It controls what kind of addresses are produced by `getnewaddress`, `getaccountaddress`, and `createmultisigaddress`. A `-changetype` argument has also been added, with the same options, and by default equal to `-addresstype`, to control which kind of change is used.
+
+A new `address_type` parameter has been added to the `getnewaddress` and `addmultisigaddress` RPCs to specify which type of address to generate.
+A `change_type` argument has been added to the `fundrawtransaction` RPC to override the `-changetype` argument for specific transactions.
+
+- All segwit addresses created through `getnewaddress` or `*multisig` RPCs explicitly get their redeemscripts added to the wallet file. This means that downgrading after creating a segwit address will work, as long as the wallet file is up to date.
+- All segwit keys in the wallet get an implicit redeemscript added, without it being written to the file. This means recovery of an old backup will work, as long as you use new software.
+- All keypool keys that are seen used in transactions explicitly get their redeemscripts added to the wallet files. This means that downgrading after recovering from a backup that includes a segwit address will work
+
+Note that some RPCs do not yet support segwit addresses. Notably, `signmessage`/`verifymessage` doesn't support segwit addresses, nor does `importmulti` at this time. Support for segwit in those RPCs will continue to be added in future versions.
+
+P2WPKH change outputs are now used by default if any destination in the transaction is a P2WPKH or P2WSH output. This is done to ensure the change output is as indistinguishable from the other outputs as possible in either case.
+
+### BIP173 (Bech32) Address support ("bc1..." addresses)
+
+Full support for native segwit addresses (BIP173 / Bech32) has now been added.
+This includes the ability to send to BIP173 addresses (including non-v0 ones), and generating these
+addresses (including as default new addresses, see above).
+
+A checkbox has been added to the GUI to select whether a Bech32 address or P2SH-wrapped address should be generated when using segwit addresses. When launched with `-addresstype=bech32` it is checked by default. When launched with `-addresstype=legacy` it is unchecked and disabled.
+
+### HD-wallets by default
+
+Due to a backward-incompatible change in the wallet database, wallets created
+with version 0.16.0 will be rejected by previous versions. Also, version 0.16.0
+will only create hierarchical deterministic (HD) wallets. Note that this only applies
+to new wallets; wallets made with previous versions will not be upgraded to be HD.
+
+### Replace-By-Fee by default in GUI
+
+The send screen now uses BIP125 RBF by default, regardless of `-walletrbf`.
+There is a checkbox to mark the transaction as final.
+
+The RPC default remains unchanged: to use RBF, launch with `-walletrbf=1` or
+use the `replaceable` argument for individual transactions.
+
+### Wallets directory configuration (`-walletdir`)
+
+Bitcoin Core now has more flexibility in where the wallets directory can be
+located. Previously wallet database files were stored at the top level of the
+bitcoin data directory. The behavior is now:
+
+- For new installations (where the data directory doesn't already exist),
+ wallets will now be stored in a new `wallets/` subdirectory inside the data
+ directory by default.
+- For existing nodes (where the data directory already exists), wallets will be
+ stored in the data directory root by default. If a `wallets/` subdirectory
+ already exists in the data directory root, then wallets will be stored in the
+ `wallets/` subdirectory by default.
+- The location of the wallets directory can be overridden by specifying a
+ `-walletdir=<path>` option where `<path>` can be an absolute path to a
+ directory or directory symlink.
+
+Care should be taken when choosing the wallets directory location, as if it
+becomes unavailable during operation, funds may be lost.
+
+Build: Minimum GCC bumped to 4.8.x
+------------------------------------
+The minimum version of the GCC compiler required to compile Bitcoin Core is now 4.8. No effort will be
+made to support older versions of GCC. See discussion in issue #11732 for more information.
+The minimum version for the Clang compiler is still 3.3. Other minimum dependency versions can be found in `doc/dependencies.md` in the repository.
+
+Support for signalling pruned nodes (BIP159)
+---------------------------------------------
+Pruned nodes can now signal BIP159's NODE_NETWORK_LIMITED using service bits, in preparation for
+full BIP159 support in later versions. This would allow pruned nodes to serve the most recent blocks. However, the current change does not yet include support for connecting to these pruned peers.
+
+Performance: SHA256 assembly enabled by default
+-------------------------------------------------
+The SHA256 hashing optimizations for architectures supporting SSE4, which lead to ~50% speedups in SHA256 on supported hardware (~5% faster synchronization and block validation), have now been enabled by default. In previous versions they were enabled using the `--enable-experimental-asm` flag when building, but are now the default and no longer deemed experimental.
+
+GUI changes
+-----------
+- Uses of "µBTC" in the GUI now also show the more colloquial term "bits", specified in BIP176.
+- The option to reuse a previous address has now been removed. This was justified by the need to "resend" an invoice, but now that we have the request history, that need should be gone.
+- Support for searching by TXID has been added, rather than just address and label.
+- A "Use available balance" option has been added to the send coins dialog, to add the remaining available wallet balance to a transaction output.
+- A toggle for unblinding the password fields on the password dialog has been added.
+
+RPC changes
+------------
+
+### New `rescanblockchain` RPC
+
+A new RPC `rescanblockchain` has been added to manually invoke a blockchain rescan.
+The RPC supports start and end-height arguments for the rescan, and can be used in a
+multiwallet environment to rescan the blockchain at runtime.
+
+### New `savemempool` RPC
+A new `savemempool` RPC has been added which allows the current mempool to be saved to
+disk at any time to avoid it being lost due to crashes / power loss.
+
+### Safe mode disabled by default
+
+Safe mode is now disabled by default and must be manually enabled (with `-disablesafemode=0`) if you wish to use it. Safe mode is a feature that disables a subset of RPC calls - mostly related to the wallet and sending - automatically in case certain problem conditions with the network are detected. However, developers have come to regard these checks as not reliable enough to act on automatically. Even with safe mode disabled, they will still cause warnings in the `warnings` field of the `getneworkinfo` RPC and launch the `-alertnotify` command.
+
+### Renamed script for creating JSON-RPC credentials
+
+The `share/rpcuser/rpcuser.py` script was renamed to `share/rpcauth/rpcauth.py`. This script can be
+used to create `rpcauth` credentials for a JSON-RPC user.
+
+### Validateaddress improvements
+
+The `validateaddress` RPC output has been extended with a few new fields, and support for segwit addresses (both P2SH and Bech32). Specifically:
+* A new field `iswitness` is True for P2WPKH and P2WSH addresses ("bc1..." addresses), but not for P2SH-wrapped segwit addresses (see below).
+* The existing field `isscript` will now also report True for P2WSH addresses.
+* A new field `embedded` is present for all script addresses where the script is known and matches something that can be interpreted as a known address. This is particularly true for P2SH-P2WPKH and P2SH-P2WSH addresses. The value for `embedded` includes much of the information `validateaddress` would report if invoked directly on the embedded address.
+* For multisig scripts a new `pubkeys` field was added that reports the full public keys involved in the script (if known). This is a replacement for the existing `addresses` field (which reports the same information but encoded as P2PKH addresses), represented in a more useful and less confusing way. The `addresses` field remains present for non-segwit addresses for backward compatibility.
+* For all single-key addresses with known key (even when wrapped in P2SH or P2WSH), the `pubkey` field will be present. In particular, this means that invoking `validateaddress` on the output of `getnewaddress` will always report the `pubkey`, even when the address type is P2SH-P2WPKH.
+
+### Low-level changes
+
+- The deprecated RPC `getinfo` was removed. It is recommended that the more specific RPCs are used:
+ * `getblockchaininfo`
+ * `getnetworkinfo`
+ * `getwalletinfo`
+ * `getmininginfo`
+- The wallet RPC `getreceivedbyaddress` will return an error if called with an address not in the wallet.
+- The wallet RPC `addwitnessaddress` was deprecated and will be removed in version 0.17,
+ set the `address_type` argument of `getnewaddress`, or option `-addresstype=[bech32|p2sh-segwit]` instead.
+- `dumpwallet` now includes hex-encoded scripts from the wallet in the dumpfile, and
+ `importwallet` now imports these scripts, but corresponding addresses may not be added
+ correctly or a manual rescan may be required to find relevant transactions.
+- The RPC `getblockchaininfo` now includes an `errors` field.
+- A new `blockhash` parameter has been added to the `getrawtransaction` RPC which allows for a raw transaction to be fetched from a specific block if known, even without `-txindex` enabled.
+- The `decoderawtransaction` and `fundrawtransaction` RPCs now have optional `iswitness` parameters to override the
+ heuristic witness checks if necessary.
+- The `walletpassphrase` timeout is now clamped to 2^30 seconds.
+- Using addresses with the `createmultisig` RPC is now deprecated, and will be removed in a later version. Public keys should be used instead.
+- Blockchain rescans now no longer lock the wallet for the entire rescan process, so other RPCs can now be used at the same time (although results of balances / transactions may be incorrect or incomplete until the rescan is complete).
+- The `logging` RPC has now been made public rather than hidden.
+- An `initialblockdownload` boolean has been added to the `getblockchaininfo` RPC to indicate whether the node is currently in IBD or not.
+- `minrelaytxfee` is now included in the output of `getmempoolinfo`
+
+Other changed command-line options
+----------------------------------
+- `-debuglogfile=<file>` can be used to specify an alternative debug logging file.
+- bitcoin-cli now has an `-stdinrpcpass` option to allow the RPC password to be read from standard input.
+- The `-usehd` option has been removed.
+- bitcoin-cli now supports a new `-getinfo` flag which returns an output like that of the now-removed `getinfo` RPC.
+
+Testing changes
+----------------
+- The default regtest JSON-RPC port has been changed to 18443 to avoid conflict with testnet's default of 18332.
+- Segwit is now always active in regtest mode by default. Thus, if you upgrade a regtest node you will need to either -reindex or use the old rules by adding `vbparams=segwit:0:999999999999` to your regtest bitcoin.conf. Failure to do this will result in a CheckBlockIndex() assertion failure that will look like: Assertion `(pindexFirstNeverProcessed != nullptr) == (pindex->nChainTx == 0)' failed.
+
+0.16.0 change log
+------------------
+
+### Block and transaction handling
+- #10953 `aeed345` Combine scriptPubKey and amount as CTxOut in CScriptCheck (jl2012)
+- #11309 `93d20a7` Minor cleanups for AcceptToMemoryPool (morcos)
+- #11418 `38c201f` Add error string for CLEANSTACK script violation (maaku)
+- #11411 `339da9c` Change SignatureHash input index check to an assert (jimpo)
+- #11406 `e12522d` Add state message print to AcceptBlock failure message (TheBlueMatt)
+- #11062 `26fee4f` Mark mempool import fails that were found in mempool as 'already there' (kallewoof)
+- #11269 `61fb806` CTxMemPoolEntry::UpdateAncestorState: modifySiagOps param type (donaloconnor)
+- #11747 `e970396` Fix: Open files read only if requested (Elbandi)
+- #11737 `46d1ebf` Document partial validation in ConnectBlock() (sdaftuar)
+- #10699 `c090262` Make all script validation flags backward compatible (sipa)
+- #10279 `214046f` Add a CChainState class to validation.cpp to take another step towards clarifying internal interfaces (TheBlueMatt)
+- #11824 `d9fdac1` Block ActivateBestChain to empty validationinterface queue (TheBlueMatt)
+- #12127 `9501dc2` Remove unused mempool index (sdaftuar)
+- #12118 `44080a9` Sort mempool by min(feerate, ancestor_feerate) (sdaftuar)
+- #8498 `0e3a411` Minimize the number of times it is checked that no money... (jtimon)
+- #12368 `3f5012b` Hold mempool.cs for the duration of ATMP (TheBlueMatt)
+- #12401 `d44cd7e` Reset pblocktree before deleting LevelDB file (Sjors)
+- #12415 `f893824` Interrupt loading thread after shutdown request (promag)
+
+### P2P protocol and network code
+- #10596 `6866b49` Add vConnect to CConnman::Options (benma)
+- #10663 `9d31ed2` Split resolve out of connect (theuni)
+- #11113 `fef65c4` Ignore getheaders requests for very old side blocks (jimpo)
+- #11585 `5aeaa9c` addrman: Add missing lock in Clear() (CAddrMan) (practicalswift)
+- #11524 `5ef3b69` De-duplicate connection eviction logic (tjps)
+- #11580 `1f4375f` Do not send (potentially) invalid headers in response to getheaders (TheBlueMatt)
+- #11655 `aca77a4` Assert state.m_chain_sync.m_work_header in ConsiderEviction (practicalswift)
+- #11744 `3ff6ff5` Add missing locks in net.{cpp,h} (practicalswift)
+- #11740 `59d3dc8` Implement BIP159 NODE_NETWORK_LIMITED (pruned peers) *signaling only* (jonasschnelli)
+- #11583 `37ffa16` Do not make it trivial for inbound peers to generate log entries (TheBlueMatt)
+- #11363 `ba2f195` Split socket create/connect (theuni)
+- #11917 `bc66765` Add testnet DNS seed: seed.testnet.bitcoin.sprovoost.nl (Sjors)
+- #11512 `6e89de5` Use GetDesireableServiceFlags in seeds, dnsseeds, fixing static seed adding (TheBlueMatt)
+- #12262 `16bac24` Hardcoded seed update (laanwj)
+- #12270 `9cf6393` Update chainTxData for 0.16 (laanwj)
+- #12392 `0f61651` Fix ignoring tx data requests when fPauseSend is set on a peer (TheBlueMatt)
+
+### Wallet
+- #11039 `fc51565` Avoid second mapWallet lookup (promag)
+- #10952 `2621673` Remove vchDefaultKey and have better first run detection (achow101)
+- #11007 `fc5c237` Fix potential memory leak when loading a corrupted wallet file (practicalswift)
+- #10976 `07c92b9` Move some static functions out of wallet.h/cpp (ryanofsky)
+- #11117 `961901f` Prepare for non-Base58 addresses (sipa)
+- #10916 `e6ab88a` add missing lock to crypter GetKeys() (benma)
+- #10767 `791a0e6` Clarify wallet initialization / destruction interface (jnewbery)
+- #11250 `c22a53c` Bump wallet version to 159900 and remove the `usehd` option (achow101)
+- #11307 `4f7e37e` Display non-HD error on first run (MarcoFalke)
+- #11408 `69c7ece` Fix parameter name typo in ErasePurpose walletdb method (PierreRochard)
+- #11167 `aa624b6` Full BIP173 (Bech32) support (sipa)
+- #11594 `0ecc630` Improve -disablewallet parameter interaction (promag)
+- #10368 `77ba4bf` Remove helper conversion operator from wallet (kallewoof)
+- #11074 `99ec126` Assert that CWallet::SyncMetaData finds oldest transaction (BitonicEelis)
+- #11272 `e6e3fc3` CKeystore/CCrypter: move relevant implementation out of the header (jonasschnelli)
+- #10286 `927a1d7` Call wallet notify callbacks in scheduler thread (without cs_main) (TheBlueMatt)
+- #10600 `4ed8180` Make feebumper class stateless (ryanofsky)
+- #11466 `d080a7d` Specify custom wallet directory with -walletdir param (MeshCollider)
+- #11839 `8ab6c0b` Don't attempt mempool entry for wallet transactions on startup (instagibbs)
+- #11854 `2214954` Split up key and script metadata for better type safety (ryanofsky)
+- #11870 `ef8ba7d` Remove unnecessary mempool lock in ReacceptWalletTransactions (promag)
+- #11864 `2ae58d5` Make CWallet::FundTransaction atomic (promag)
+- #11886 `df71819` Clarify getbalance meaning a tiny bit in response to questions (TheBlueMatt)
+- #11923 `81c89e9` Remove unused fNoncriticalErrors variable from CWalletDB::FindWalletTx (PierreRochard)
+- #11726 `604e08c` Cleanups + nit fixes for walletdir PR (MeshCollider)
+- #11403 `d889c03` Segwit wallet support (sipa)
+- #11970 `b7450cd` Add test coverage for bitcoin-cli multiwallet calls (ryanofsky)
+- #11904 `66e3af7` Add a lock to the wallet directory (MeshCollider)
+- #12101 `c7978be` Clamp walletpassphrase timeout to 2^30 seconds and check its bounds (achow101)
+- #12210 `17180fa` Deprecate addwitnessaddress (laanwj)
+- #12220 `f4c942e` Error if relative -walletdir is specified (ryanofsky)
+- #11281 `8470e64` Avoid permanent cs_main/cs_wallet lock during RescanFromTime (jonasschnelli)
+- #12119 `9594139` Use P2WPKH change output if any destination is P2WPKH or P2WSH (Sjors)
+- #12213 `eadb2da` Add address type option to addmultisigaddress (promag)
+- #12276 `7936446` Remove duplicate mapWallet lookups (promag)
+
+### RPC and other APIs
+- #11008 `3841aaf` Enable disablesafemode by default (gmaxwell)
+- #11050 `7ed57d3` Avoid treating null RPC arguments different from missing arguments (ryanofsky)
+- #10997 `affe927` Add option -stdinrpcpass to bitcoin-cli to allow RPC password to be read from standard input (jharvell)
+- #11179 `e0e3cbb` Push down safe mode checks (laanwj)
+- #11203 `d745b4c` add wtxid to mempool entry output (sdaftuar)
+- #11099 `bc561b4` Add savemempool RPC (greenaddress)
+- #10838 `66a5b41` (finally) remove getinfo (TheBlueMatt)
+- #10753 `7fcd61b` test: Check RPC argument mapping (laanwj)
+- #11288 `0f8e095` More user-friendly error message when partially signing (MeshCollider)
+- #11031 `ef8340d` deprecate estimatefee (jnewbery)
+- #10858 `9a8e916` Add "errors" field to getblockchaininfo and unify "errors" field in get*info RPCs (achow101)
+- #11021 `90926db` Fix getchaintxstats() (AkioNak)
+- #11367 `3a93270` getblockchaininfo: Add disk_size, prune_target_size (esotericnonsense)
+- #11006 `a1d78b5` Improve shutdown process (promag)
+- #11529 `ff92fbf` Avoid slow transaction search with txindex enabled (promag)
+- #11618 `87d90ef` Lock cs_main in blockToJSON/blockheaderToJSON (practicalswift)
+- #11626 `998c304` Make `logging` RPC public (laanwj)
+- #11258 `033c786` Add initialblockdownload to getblockchaininfo (jnewbery)
+- #11087 `99bc0b4` Diagnose unsuitable outputs in lockunspent() (BitonicEelis)
+- #11710 `9388639` cli: Reject arguments to -getinfo (laanwj)
+- #11738 `d4267a3` Fix sendrawtransaction hang when sending a tx already in mempool (TheBlueMatt)
+- #11753 `32c9b57` clarify abortrescan rpc use (instagibbs)
+- #11191 `ef14f2e` Improve help text and behavior of RPC-logging (AkioNak)
+- #10874 `9e38d35` getblockchaininfo: Loop through the bip9 soft fork deployments instead of hard coding (achow101)
+- #10275 `497d0e0` Allow fetching tx directly from specified block in getrawtransaction (kallewoof)
+- #11178 `fee0370` Add iswitness parameter to decode- and fundrawtransaction RPCs (MeshCollider)
+- #11667 `711d16c` Add scripts to dumpwallet RPC (MeshCollider)
+- #11475 `9bad8d6` mempoolinfo should take ::minRelayTxFee into account (mess110)
+- #12001 `a9a49e6` Adding ::minRelayTxFee amount to getmempoolinfo and updating help (jeffrade)
+- #12198 `adce1de` Add deprecation error for `getinfo` (laanwj)
+- #11415 `69ec021` Disallow using addresses in createmultisig (achow101)
+- #12278 `288deac` Add special error for genesis coinbase to getrawtransaction (MeshCollider)
+- #11362 `c6223b3` Remove nBlockMaxSize from miner opt struct as it is no longer used (gmaxwell)
+- #10825 `28485c7` Set regtest JSON-RPC port to 18443 to avoid conflict with testnet 18332 (fametrano)
+- #11303 `e542728` Fix estimatesmartfee rounding display issue (TheBlueMatt)
+- #7061 `8c2de82` Add RPC call "rescanblockchain <startheight> <stopheight>" (jonasschnelli)
+- #11055 `95e14dc` RPC getreceivedbyaddress should return error if called with address not owned by the wallet (jnewbery)
+- #12366 `93de37a` http: Join worker threads before deleting work queue (laanwj)
+- #12315 `758a41e` Bech32 addresses in dumpwallet (fivepiece)
+- #12427 `3762ac1` Make signrawtransaction accept P2SH-P2WSH redeemscripts (sipa)
+
+### GUI
+- #10964 `64e66bb` Pass SendCoinsRecipient (208 bytes) by reference (practicalswift)
+- #11169 `5b8af7b` Make tabs toolbar no longer have a context menu (achow101)
+- #10911 `9c8f365` Fix typo and access key in optionsdialog.ui (keystrike)
+- #10770 `ea729d5` Drop upgrade-cancel callback registration for a generic "cancelable" (TheBlueMatt)
+- #11156 `a3624dd` Fix memory leaks in qt/guiutil.cpp (danra)
+- #11268 `31e72b2` [macOS] remove Growl support, remove unused code (jonasschnelli)
+- #11193 `c5c77bd` Terminate string *pszExePath after readlink and without using memset (practicalswift)
+- #11508 `ffa5159` Fix crash via division by zero assertion (jonasschnelli)
+- #11499 `6157e8c` Add upload and download info to the peerlist (debug menu) (aarongolliver)
+- #11480 `ffc0b11` Add toggle for unblinding password fields (tjps)
+- #11316 `22cdf93` Add use available balance in send coins dialog (CryptAxe, promag)
+- #3716 `13e352d` Receive: Remove option to reuse a previous address (luke-jr)
+- #11690 `f0c1f8a` Fix the StartupWMClass for bitoin-qt, so gnome-shell can recognize it (eklitzke)
+- #10920 `f6f8d54` Fix potential memory leak in newPossibleKey(ChangeCWallet *wallet) (practicalswift)
+- #11698 `7293d06` RPC-Console nested commands documentation (lmlsna)
+- #11395 `38d31f9` Enable searching by transaction id (luke-jr)
+- #11556 `91eeaa0` Improved copy for RBF checkbox and tooltip (Sjors)
+- #11809 `80f9dad` Fix proxy setting options dialog crash (laanwj)
+- #11616 `8585bb8` Update ban-state in case of dirty-state during periodic sweep (jonasschnelli)
+- #11605 `f19ca12` Enable RBF by default in QT (Sjors)
+- #12074 `a1136f0` Optimizes boolean expression model && model->haveWatchOnly() (251Labs)
+- #12035 `eeb6d52` Change µBTC to bits (jb55)
+- #12092 `fd4ca17` Replaces numbered place marker %2 with %1 (251Labs)
+- #12173 `bbc91b7` Use flexible font size for QRCode image address (jonasschnelli)
+- #12211 `10d10d7` Avoid potential null dereference in ReceiveCoinsDialog constructor (ryanofsky)
+- #12261 `f359afc` Bump BLOCK_CHAIN_SIZE to 200GB (laanwj)
+- #11991 `062c8b6` Receive: checkbox for bech32 address (Sjors)
+- #11644 `045a809` Fix qt build broken by 5a5e4e9 (TheBlueMatt)
+- #11448 `d473e6d` reset addrProxy/addrSeparateProxyTor if colon char missing (mess110)
+- #12377 `604f289` qt: Poll ShutdownTimer after init is done (MarcoFalke)
+- #12374 `daaae36` qt: Make sure splash screen is freed on AppInitMain fail (laanwj)
+- #12349 `ad10b90` shutdown: fix crash on shutdown with reindex-chainstate (theuni)
+
+### Build system
+- #10923 `2c9f5ec` travis: Build with --enable-werror under OS X (practicalswift)
+- #11176 `df8c722` build: Rename --enable-experimental-asm to --enable-asm and enable by default (laanwj)
+- #11286 `11dacc6` [depends] Don't build libevent sample code (fanquake)
+- #7142 `801dd40` Travis: Test build against system libs (& Qt4) (luke-jr)
+- #11380 `390771b` Remove outdated share/certs/ directory (MeshCollider)
+- #11391 `7632310` Remove lxcbr0 lines from gitian-build.sh (MeshCollider)
+- #11435 `167cef8` build: Make "make clean" remove all files created when running "make check" (practicalswift)
+- #11460 `e022463` [depends] mac_alias 2.0.6, ds_store 1.1.2 (fanquake)
+- #11541 `bb9ab0f` Build: Fix Automake warnings when running autogen.sh (fanquake)
+- #11611 `0e70791` [build] Don't fail when passed --disable-lcov and lcov isn't available (fanquake)
+- #11651 `3c098a8` refactor: Make all #includes relative to project root (laanwj, MeshCollider, ryanofsky)
+- #11621 `1f7695b` [build] Add temp_bitcoin_locale_qrc to CLEAN_QT to fix make distcheck (fanquake)
+- #11755 `84fa645` [Docs] Bump minimum required version of GCC to 4.8 (fanquake)
+- #9254 `6d3dc52` [depends] ZeroMQ 4.2.2 (fanquake)
+- #11842 `3c8f0a3` [build] Add missing stuff to clean-local (kallewoof)
+- #11936 `483bb67` [build] Warn that only libconsensus can be built without Boost (fanquake)
+- #11945 `7a11ba7` Improve BSD compatibility of contrib/install_db4.sh (laanwj)
+- #11981 `180a255` Fix gitian build after libzmq bump (theuni)
+- #11903 `8f68fd2` [trivial] Add required package dependencies for depends cross compilation (jonasschnelli)
+- #12168 `45cf8a0` #include sys/fcntl.h to just fcntl.h (without sys/) (jsarenik)
+- #12095 `3fa1ab4` Use BDB_LIBS/CFLAGS and pass --disable-replication (fanquake)
+- #11711 `6378e5c` bitcoin_qt.m4: Minor fixes and clean-ups (fanquake)
+- #11989 `90d4104` .gitignore: add QT Creator artifacts (Sjors)
+- #11577 `c0ae864` Fix warnings (-Wsign-compare) when building with DEBUG_ADDRMAN (practicalswift)
+
+### Tests and QA
+- #11024 `3e55f13` Remove OldSetKeyFromPassphrase/OldEncrypt/OldDecrypt (practicalswift)
+- #10679 `31b2612` Document the non-DER-conformance of one test in tx_valid.json (schildbach)
+- #11160 `ede386c` Improve versionbits_computeblockversion test code consistency (danra)
+- #10303 `f088a1b` Include ms/blk stats in Connect* benchmarks (kallewoof)
+- #10777 `d81dccf` Avoid redundant assignments. Remove unused variables (practicalswift)
+- #11260 `52f8877` travis: Assert default datadir isn't created, Run scripted diff only once (MarcoFalke)
+- #11271 `638e6c5` travis: filter out pyenv (theuni)
+- #11285 `3255d63` Add -usehd to excluded args in check-doc.py (MeshCollider)
+- #11297 `16e4184` Make sure ~/.bitcoin doesn't exist before build (MeshCollider)
+- #11311 `cce94c5` travis: Revert default datadir check (MarcoFalke)
+- #11300 `f4ed44a` Add a lint check for trailing whitespace (MeshCollider)
+- #11323 `4ce2f3d` mininode: add an optimistic write and disable nagle (theuni)
+- #11370 `2d85899` Add getblockchaininfo functional test (promag)
+- #11365 `f199b8a` Add Qt GUI tests to Overview and ReceiveCoin Page (anditto)
+- #11293 `dbc4ae0` Deduplicate CMerkleBlock construction code, add test coverage (jamesob)
+- #10440 `9e8ef9d` Add libFuzzer support (practicalswift)
+- #10941 `364da2c` Add blocknotify and walletnotify functional tests (promag)
+- #11420 `8928093` Bump univalue subtree and fix json formatting in tests (MarcoFalke)
+- #10099 `424be03` Slightly Improve Unit Tests for Checkqueue (JeremyRubin)
+- #11513 `14b860b` A few Python3 tidy ups (jnewbery)
+- #11486 `2ca518d` Add uacomment tests (mess110)
+- #11452 `02ac8c8` Improve ZMQ functional test (promag)
+- #10409 `b5545d8` Add fuzz testing for BlockTransactions and BlockTransactionsRequest (practicalswift)
+- #11389 `dd56166` Support having segwit always active in regtest (sipa, ajtowns, jnewbery)
+- #11562 `5776582` bench: use std::chrono rather than gettimeofday (theuni)
+- #11182 `f7388e9` Add P2P interface to TestNode (jnewbery)
+- #11552 `b5f9f02` Improve wallet-accounts test (ryanofsky)
+- #11638 `5e3f5e4` Dead mininode code (jnewbery)
+- #11646 `fe503e1` Require a steady clock for bench with at least micro precision (TheBlueMatt)
+- #11468 `76b3349` Make comp test framework more debuggable (jnewbery)
+- #11623 `ee92243` Add missing locks to tests (practicalswift)
+- #11035 `927e528` [contrib] Add Valgrind suppressions file (practicalswift)
+- #11641 `7adeea3` Only allow disconnecting all NodeConns (MarcoFalke)
+- #11677 `3bdf242` Remove unused NodeConn members (MarcoFalke)
+- #11699 `66d46c7` [travis-ci] Only run linters on Pull Requests (jnewbery)
+- #11654 `084f52f` Initialize recently introduced non-static class member lastCycles to zero in constructor (practicalswift)
+- #11648 `ccc70a2` Add messages.py (jnewbery)
+- #11713 `49667a7` Fix for mismatched extern definition in wallet tests (sipsorcery)
+- #11707 `0d89fa0` Fix sendheaders (jnewbery)
+- #11718 `9cdd2bc` Move pwalletMain to wallet test fixture (laanwj)
+- #11714 `901ba3e` Test that mempool rejects coinbase transactions (jamesob)
+- #11743 `3d6ad40` Add multiwallet prefix test (MarcoFalke)
+- #11683 `a892218` Remove unused mininode functions {ser,deser}_int_vector(...). Remove unused imports (practicalswift)
+- #11712 `9f2c2db` Split NodeConn from NodeConnCB (jnewbery)
+- #11791 `13e31dd` Rename NodeConn and NodeConnCB (jnewbery)
+- #11835 `f60b4ad` Add Travis check for unused Python imports (practicalswift)
+- #11849 `ad1820c` Assert that only one NetworkThread exists (jnewbery)
+- #11877 `d4991c0` Improve createrawtransaction functional tests (promag)
+- #11220 `2971fd0` Check specific validation error in miner tests (Sjors)
+- #11947 `797441e` Fix rawtransactions test (laanwj)
+- #11946 `8049241` Remove unused variable (firstAddrnServices) (practicalswift)
+- #11867 `18a1bba` Improve node network test (jnewbery)
+- #11883 `cfd99dd` Add configuration file/argument testing (MeshCollider)
+- #11879 `d4e404a` Remove redundant univalue_tests.cpp (jnewbery)
+- #11748 `20166f8` Adding unit tests for GetDifficulty in blockchain.cpp (merehap)
+- #11517 `5180a86` Improve benchmark precision (martinus)
+- #11291 `a332a7d` Fix string concatenation to os.path.join and add exception case (dongsam)
+- #11965 `d38d1a3` Note on test order in test_runner (MarcoFalke)
+- #11997 `ddff344` util_tests.cpp: actually check ignored args (ajtowns)
+- #12079 `45173fa` Improve prioritisetransaction test coverage (promag)
+- #12150 `92a810d` Fix ListCoins test failure due to unset g_address_type, g_change_type (ryanofsky)
+- #12133 `1d2eaba` Fix rare failure in p2p-segwit.py (sdaftuar)
+- #12082 `0910cbe` Adding test case for SINGLE|ANYONECANPAY hash type in tx_valid.json (Christewart)
+- #11796 `4db16ec` Functional test naming convention (ajtowns)
+- #12227 `b987ca4` test_runner: Readable output if create_cache.py fails (ryanofsky)
+- #12089 `126000b` Make TestNodeCLI command optional in send_cli (MarcoFalke)
+- #11774 `6970b30` Rename functional tests (ajtowns)
+- #12264 `598a9c4` Fix versionbits warning test (jnewbery)
+- #12217 `1213be6` Add missing syncwithvalidationinterfacequeue to tests (MarcoFalke)
+- #12292 `eebe458` Fix names of excluded extended tests for travis (ajtowns)
+- #11789 `60d739e` [travis-ci] Combine logs on failure (jnewbery)
+- #11838 `3e50024` Add getrawtransaction in_active_chain=False test (MarcoFalke)
+- #12206 `898f560` Sync with validationinterface queue in sync_mempools (MarcoFalke)
+- #12424 `ff44101` Fix rescan test failure due to unset g_address_type, g_change_type (ryanofsky)
+- #12388 `e2431d1` travis: Full clone for git subtree check (MarcoFalke)
+
+### Documentation
+- #10680 `6366941` Fix inconsistencies and grammar in various files (MeshCollider)
+- #11011 `7db65c3` Add a comment on the use of prevector in script (gmaxwell)
+- #10878 `c58128f` Fix Markdown formatting issues in init.md (dongcarl)
+- #11066 `9e00a62` Document the preference of nullptr over NULL or (void*)0 (practicalswift)
+- #11094 `271e40a` Hash in ZMQ hash is raw bytes, not hex (runn1ng)
+- #11026 `ea3ac59` Bugfix: Use testnet RequireStandard for -acceptnonstdtxn default (luke-jr)
+- #11058 `4b65fa5` Comments: More comments on functions/globals in standard.h (jimpo)
+- #11112 `3f726c9` [developer-notes] By default, declare single-argument constructors "explicit" (practicalswift)
+- #11155 `a084767` Trivial: Documentation fixes for CVectorWriter ctors (danra)
+- #11136 `108222b` Docs: Add python3 to list of dependencies on some platforms (danra)
+- #11216 `81f8c03` Update hmac_sha256.h (utsavgupta)
+- #11236 `ba05971` Add note on translations to CONTRIBUTING.md (MeshCollider)
+- #11173 `4eb1f39` RPC: Fix currency unit string in the help text (AkioNak)
+- #11135 `21e2f2f` Update developer notes with RPC response guidelines (promag)
+- #11219 `bcc8a62` explain how to recompile a modified unit test (Sjors)
+- #10779 `f656147` Create dependencies.md (flack)
+- #10682 `2a56baf` Move the AreInputsStandard documentation next to its implementation (esneider)
+- #11276 `ee50c9e` Update CONTRIBUTING.md to reduce unnecessary review workload (jonasschnelli)
+- #11264 `b148803` Fix broken Markdown table in dependencies.md (practicalswift)
+- #10691 `ce82985` Properly comment about shutdown process in init.cpp file (wraith7)
+- #11330 `ae233c4` Fix comments for DEFAULT_WHITELIST[FORCE]RELAY (danra)
+- #11340 `d6d2c85` Fix validation comments (danra)
+- #11305 `2847480` Update release notes and manpages for 0.16 (MarcoFalke)
+- #11132 `551d7bf` Document assumptions that are being made to avoid NULL pointer dereferences (practicalswift)
+- #11390 `12ed800` Document scripted-diff (jnewbery)
+- #11392 `a3b4c59` Fix stale link in gitian-building.md (shooterman)
+- #11401 `4202273` Move gitian building to external repo (MarcoFalke)
+- #11414 `bbc901d` Remove partial gitian build instructions from descriptors dir (fanquake)
+- #11571 `c95832d` Fixed a couple small grammatical errors (BitsInMyBlood)
+- #11624 `f9b74ef` Change formatting for sequence of steps (vivganes)
+- #11597 `6f01dcf` Fix error messages in CFeeBumper (kallewoof)
+- #11438 `7fbf3c6` Updated Windows build doc for WSL/Xenial workaround (sipsorcery)
+- #11663 `41aa9c4` Add getreceivedbyaddress release notes (MarcoFalke)
+- #11533 `cbb54e7` Update WSL installation notes for Fall Creators update (Thoragh)
+- #11680 `4db82b7` Add instructions for lcov report generation (jamesob)
+- #11686 `54aedc0` Make ISSUE_TEMPLATE a bit shorter, mention hardware tests (TheBlueMatt)
+- #11704 `ea68190` Windows build doc update (sipsorcery)
+- #11706 `5197100` Make default issue text all comments to make issues more readable (TheBlueMatt)
+- #11140 `1429132` Improve #endif comments (danra)
+- #11729 `7a43fbb` links to code style guides (Sjors)
+- #11793 `8879d50` Bump OS X version to 10.13 (Varunram)
+- #11783 `16fff80` Fix shutdown in case of errors during initialization (laanwj)
+- #11804 `00d25e9` Fixed outdated link with archive.is (TimothyShimmin)
+- #11960 `4307062` Fix link to installation script (laudaa)
+- #12027 `63a4dc1` Remove boost --c++ flag from osx build instructions (fernandezpablo85)
+- #12062 `5961b23` Increment MIT Licence copyright header year on files modified in 2017 (akx20000a)
+- #12063 `36a5a44` Update license year range to 2018 (akx20000a)
+- #12093 `5691028` Fix incorrect Markdown link (practicalswift)
+- #12143 `b0d626d` Fix link for BIP159 pull request (azuchi)
+- #12112 `3c62868` Remove the ending slashes from RPC URI format (jackycjh)
+- #12166 `e839d65` Clarify -walletdir usage (jnewbery)
+- #12241 `b030133` Fix incorrect link in /test/ README.md (fanquake)
+- #12187 `b5e4b9b` Updating benchmarkmarking.md with an updated sample output (jeffrade)
+- #12294 `7cf1aea` Create NetBSD build instructions and fix compilation (fanquake)
+- #12251 `cc5870a` initwallet: Do not translate highly technical addresstype help (MarcoFalke)
+- #11984 `efae366` Update OpenBSD build instructions for 6.2 (cont'd) (laanwj)
+- #12293 `9d9c418` Mention that HD is enabled if hdmasterkeyid is present in getwalletinfo RPC help (fanquake)
+- #12077 `c04cb48` Correct `sendmany` curl example (251Labs)
+- #10677 `b3ecb7b` Document that addmultisigaddress is intended for non-watchonly addresses (instagibbs)
+- #12177 `cad504b` Fix address_type help text of getnewaddress and getrawchangeaddress (mruddy)
+
+### Refactoring
+- #9964 `b6a4891` Add const to methods that do not modify the object for which it is called (practicalswift)
+- #10965 `655970d` Replace deprecated throw() with noexcept specifier (C++11) (practicalswift)
+- #10645 `c484ec6` Use nullptr (C++11) instead of zero (0) as the null pointer constant (practicalswift)
+- #10901 `22e301a` Fix constness of ArgsManager methods (promag)
+- #10969 `4afb5aa` Declare single-argument (non-converting) constructors "explicit" (practicalswift)
+- #11071 `dbf6bd6` Use static_assert(…, …) (C++11) instead of assert(…) where appropriate (practicalswift)
+- #10809 `c559884` optim: mark a few classes final (theuni)
+- #10843 `2ab7c63` Add attribute [[noreturn]] (C++11) to functions that will not return (practicalswift)
+- #11151 `7fd49d0` Fix header guards using reserved identifiers (danra)
+- #11138 `2982511` Compat: Simplify bswap_16 implementation (danra)
+- #11161 `745bbdc` Remove redundant explicitly defined copy ctors (danra)
+- #11144 `cee4fe1` Move local include to before system includes (danra)
+- #10781 `60dd9cc` Python cleanups (practicalswift)
+- #10701 `50fae68` Remove the virtual specifier for functions with the override specifier (practicalswift)
+- #11164 `38a54a5` Fix boost headers included as user instead of system headers (danra)
+- #11143 `3aa60b7` Fix include path for bitcoin-config.h (danra)
+- #8330 `59e1789` Structure Packing Optimizations in C{,Mutable}Transaction (JeremyRubin)
+- #10845 `39ae413` Remove unreachable code (practicalswift)
+- #11238 `6acdb1f` Add assertions before potential null deferences (MeshCollider)
+- #11259 `089b742` Remove duplicate destination decoding (promag)
+- #11232 `2f0d3e6` Ensure that data types are consistent (jjz)
+- #10793 `efb4383` Changing &var[0] to var.data() (MeshCollider)
+- #11196 `e278f86` Switch memory_cleanse implementation to BoringSSL's to ensure memory clearing even with -lto (maaku)
+- #10888 `9821274` range-based loops and const qualifications in net.cpp (benma)
+- #11351 `6c4fecf` Refactor: Modernize disallowed copy constructors/assignment (danra)
+- #11385 `94c9015` Remove some unused functions and methods (sipa)
+- #11301 `8776787` add m_added_nodes to connman options (benma)
+- #11432 `058c0f9` Remove unused fTry from push_lock (promag)
+- #11107 `e93fff1` Fix races in AppInitMain and others with lock and atomic bools (MeshCollider)
+- #9572 `17f2ace` Skip witness sighash cache for non-segwit transactions (jl2012)
+- #10961 `da0478e` Improve readability of DecodeBase58Check(...) (practicalswift)
+- #11133 `a865b38` Document assumptions that are being made to avoid division by zero (practicalswift)
+- #11073 `3bb77eb` Remove dead store in ecdsa_signature_parse_der_lax (BitonicEelis)
+- #10898 `470c730` Fix invalid checks (NULL checks after dereference, redundant checks, etc.) (practicalswift)
+- #11495 `50d72b3` [trivial] Make namespace explicit for is_regular_file (jnewbery)
+- #11511 `db2f83e` [Init] Remove redundant exit(EXIT_FAILURE) instances and replace with return false (donaloconnor)
+- #10866 `ef8a634` Fix -Wthread-safety-analysis warnings. Compile with -Wthread-safety-analysis if available (practicalswift)
+- #11221 `0dec4cc` Refactor: simpler read (gnuser)
+- #10696 `ef3758d` Remove redundant nullptr checks before deallocation (practicalswift)
+- #11043 `5e9be16` Use std::unique_ptr (C++11) where possible (practicalswift)
+- #11353 `05a7619` Small refactor of CCoinsViewCache::BatchWrite() (danra)
+- #10749 `2adbddb` Use compile-time constants instead of unnamed enumerations (remove "enum hack") (practicalswift)
+- #11603 `a933cb1` Move RPC registration out of AppInitParameterInteraction (ryanofsky)
+- #11722 `26efc22` Switched sync.{cpp,h} to std threading primitives (tjps)
+- #10493 `fbce66a` Use range-based for loops (C++11) when looping over map elements (practicalswift)
+- #11337 `0d7e0a3` Fix code constness in CBlockIndex::GetAncestor() overloads (danra)
+- #11516 `0e722e8` crypto: Add test cases covering the relevant HMAC-SHA{256,512} key length boundaries (practicalswift)
+- #10574 `5d132e8` Remove includes in .cpp files for things the corresponding .h file already included (practicalswift)
+- #11884 `66479c0` Remove unused include in hash.cpp (kallewoof)
+- #10839 `c66adb2` Don't use pass by reference to const for cheaply-copied types (bool, char, etc.) (practicalswift)
+- #10657 `79399c8` Utils: Improvements to ECDSA key-handling code (str4d)
+- #12250 `e37ca2b` Make CKey::Load references const (ryanofsky)
+- #12108 `9220426` Remove unused fQuit var from checkqueue.h (donaloconnor)
+- #12159 `f3c7062` Use the character based overload for std::string::find (kekimusmaximus)
+- #12266 `3448907` Move scheduler/threadGroup into common-init instead of per-app (TheBlueMatt)
+
+### Miscellaneous
+- #11246 `777519b` github-merge: Coalesce git fetches (laanwj)
+- #10871 `c9a4aa8` Handle getinfo in bitcoin-cli w/ -getinfo (revival of #8843) (achow101)
+- #11419 `093074b` Utils: Fix launchctl not being able to stop bitcoind (OmeGak)
+- #11394 `6e4e98e` Perform a weaker subtree check in Travis (sipa)
+- #11702 `4122112` [build] Add a script for installing db4 (jamesob)
+- #11794 `dd49862` Prefix leveldb debug logging (laanwj)
+- #11781 `24df9af` Add `-debuglogfile` option (laanwj)
+- #10773 `c17f11f` Shell script cleanups (practicalswift)
+- #11829 `7630a1f` Test datadir specified in conf file exists (MeshCollider)
+- #11836 `d44535d` Rename rpcuser.py to rpcauth.py (hkjn)
+- #11831 `d48ab83` Always return true if AppInitMain got to the end (TheBlueMatt)
+- #11943 `1808660` contrib: fix typo in install_db4.sh help message (laanwj)
+- #12075 `c991b30` [scripts] Add missing univalue file to copyright_header.py (fanquake)
+- #12197 `000ac4f` Log debug build status and warn when running benchmarks (laanwj)
+- #10672 `6ab0e4c` Avoid division by zero in the case of a corrupt estimates file (practicalswift)
+- #11273 `cdd6bbf` Ignore old format estimation file (Xekyo)
+- #11951 `1fb34e0` Remove dead feeest-file read code for old versions (TheBlueMatt)
+- #11421 `9ccafb1` Merge current secp256k1 subtree (MarcoFalke)
+- #11573 `2631d55` [Util] Update tinyformat.h (fanquake)
+- #10529 `331352f` Improve bitcoind systemd service file (Flowdalic)
+- #11620 `70fec9e` [build] .gitignore: add background.tiff (Sjors)
+- #11558 `68e021e` Minimal code changes to allow msvc compilation (sipsorcery)
+- #11284 `10bee0d` Fix invalid memory access in CScript::operator+= (guidovranken, ajtowns)
+- #10939 `a1f7f18` [init] Check non-emptiness of -blocknotify command prior to executing (practicalswift)
+- #11467 `937613d` Fix typos. Use nullptr instead of NULL (practicalswift)
+- #11834 `5bea05b` [verify-commits] Fix gpg.sh's echoing for commits with '\n' (TheBlueMatt)
+- #11830 `a13e443` rpcuser.py: Use 'python' not 'python2' (hkjn)
+- #12194 `7abb0f0` Add change type option to fundrawtransaction (promag)
+- #12269 `2ae7cf8` Update defaultAssumeValid to block 506067 (gmaxwell)
+- #11952 `9ab9963` univalue: Bump subtree (MarcoFalke)
+- #12367 `09fc859` Fix two fast-shutdown bugs (TheBlueMatt)
+- #12422 `4d54e7a` util: Make LockDirectory thread-safe, consistent, and fix OpenBSD 6.2 build (laanwj)
+
+Credits
+=======
+
+Thanks to everyone who directly contributed to this release:
+
+- 251
+- Aaron Clauson
+- Aaron Golliver
+- aaron-hanson
+- Adam Langley
+- Akio Nakamura
+- Akira Takizawa
+- Alejandro Avilés
+- Alex Morcos
+- Alin Rus
+- Anditto Heristyo
+- Andras Elso
+- Andreas Schildbach
+- Andrew Chow
+- Anthony Towns
+- azuchi
+- Carl Dong
+- Chris Moore
+- Chris Stewart
+- Christian Gentry
+- Cory Fields
+- Cristian Mircea Messel
+- CryptAxe
+- Dan Raviv
+- Daniel Edgecumbe
+- danra
+- david60
+- Donal O'Connor
+- dongsamb
+- Dusty Williams
+- Eelis
+- esneider
+- Evan Klitzke
+- fanquake
+- Ferdinando M. Ametrano
+- fivepiece
+- flack
+- Florian Schmaus
+- gnuser
+- Gregory Maxwell
+- Gregory Sanders
+- Henrik Jonsson
+- Jack Grigg
+- Jacky C
+- James Evans
+- James O'Beirne
+- Jan Sarenik
+- Jeff Rade
+- Jeremiah Buddenhagen
+- Jeremy Rubin
+- Jim Posen
+- jjz
+- Joe Harvell
+- Johannes Kanig
+- John Newbery
+- Johnson Lau
+- Jonas Nick
+- Jonas Schnelli
+- João Barbosa
+- Jorge Timón
+- Karel Bílek
+- Karl-Johan Alm
+- klemens
+- Kyuntae Ethan Kim
+- laudaa
+- Lawrence Nahum
+- Lucas Betschart
+- Luke Dashjr
+- Luke Mlsna
+- MarcoFalke
+- Mark Friedenbach
+- Marko Bencun
+- Martin Ankerl
+- Matt Corallo
+- mruddy
+- Murch
+- NicolasDorier
+- Pablo Fernandez
+- Paul Berg
+- Pedro Branco
+- Pierre Rochard
+- Pieter Wuille
+- practicalswift
+- Randolf Richardson
+- Russell Yanofsky
+- Samuel Dobson
+- Sean Erle Johnson
+- Shooter
+- Sjors Provoost
+- Suhas Daftuar
+- Thomas Snider
+- Thoragh
+- Tim Shimmin
+- Tomas van der Wansem
+- Utsav Gupta
+- Varunram Ganesh
+- Vivek Ganesan
+- Werner Lemberg
+- William Casarin
+- Willy Ko
+- Wladimir J. van der Laan
+
+As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
diff --git a/doc/translation_process.md b/doc/translation_process.md
index 1702637d53..5a9c59914e 100644
--- a/doc/translation_process.md
+++ b/doc/translation_process.md
@@ -52,7 +52,7 @@ The client it used to fetch updated translations. If you are having problems, or
`pip install transifex-client`
-Setup your transifex client config as follows. Please *ignore the token field*.
+Setup your Transifex client config as follows. Please *ignore the token field*.
```ini
nano ~/.transifexrc
diff --git a/doc/zmq.md b/doc/zmq.md
index 38c58fb7fd..5d67df9d22 100644
--- a/doc/zmq.md
+++ b/doc/zmq.md
@@ -101,6 +101,6 @@ and just the tip will be notified. It is up to the subscriber to
retrieve the chain from the last known block to the new tip.
There are several possibilities that ZMQ notification can get lost
-during transmission depending on the communication type your are
+during transmission depending on the communication type you are
using. Bitcoind appends an up-counting sequence number to each
notification which allows listeners to detect lost notifications.
diff --git a/src/Makefile.am b/src/Makefile.am
index 4fbd605d9e..ac822d6c5e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -132,13 +132,14 @@ BITCOIN_CORE_H = \
rpc/protocol.h \
rpc/safemode.h \
rpc/server.h \
+ rpc/rawtransaction.h \
rpc/register.h \
rpc/util.h \
scheduler.h \
+ script/ismine.h \
script/sigcache.h \
script/sign.h \
script/standard.h \
- script/ismine.h \
streams.h \
support/allocators/secure.h \
support/allocators/zeroafterfree.h \
@@ -216,7 +217,6 @@ libbitcoin_server_a_SOURCES = \
rpc/safemode.cpp \
rpc/server.cpp \
script/sigcache.cpp \
- script/ismine.cpp \
timedata.cpp \
torcontrol.cpp \
txdb.cpp \
@@ -333,6 +333,7 @@ libbitcoin_common_a_SOURCES = \
policy/feerate.cpp \
protocol.cpp \
scheduler.cpp \
+ script/ismine.cpp \
script/sign.cpp \
script/standard.cpp \
warnings.cpp \
@@ -389,10 +390,10 @@ endif
bitcoind_LDADD = \
$(LIBBITCOIN_SERVER) \
+ $(LIBBITCOIN_WALLET) \
$(LIBBITCOIN_COMMON) \
$(LIBUNIVALUE) \
$(LIBBITCOIN_UTIL) \
- $(LIBBITCOIN_WALLET) \
$(LIBBITCOIN_ZMQ) \
$(LIBBITCOIN_CONSENSUS) \
$(LIBBITCOIN_CRYPTO) \
diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include
index 8e2e587d32..748c5b7887 100644
--- a/src/Makefile.bench.include
+++ b/src/Makefile.bench.include
@@ -27,7 +27,7 @@ bench_bench_bitcoin_SOURCES = \
bench/lockedpool.cpp \
bench/perf.cpp \
bench/perf.h \
- bench/prevector_destructor.cpp
+ bench/prevector.cpp
nodist_bench_bench_bitcoin_SOURCES = $(GENERATED_BENCH_FILES)
@@ -35,6 +35,7 @@ bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS
bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
bench_bench_bitcoin_LDADD = \
$(LIBBITCOIN_SERVER) \
+ $(LIBBITCOIN_WALLET) \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CONSENSUS) \
@@ -51,7 +52,6 @@ endif
if ENABLE_WALLET
bench_bench_bitcoin_SOURCES += bench/coin_selection.cpp
-bench_bench_bitcoin_LDADD += $(LIBBITCOIN_WALLET) $(LIBBITCOIN_CRYPTO)
endif
bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp
index 06d2abeac6..6f438b60e9 100644
--- a/src/bench/coin_selection.cpp
+++ b/src/bench/coin_selection.cpp
@@ -37,11 +37,6 @@ static void CoinSelection(benchmark::State& state)
LOCK(wallet.cs_wallet);
while (state.KeepRunning()) {
- // Empty wallet.
- for (COutput output : vCoins)
- delete output.tx;
- vCoins.clear();
-
// Add coins.
for (int i = 0; i < 1000; i++)
addCoin(1000 * COIN, wallet, vCoins);
@@ -53,6 +48,12 @@ static void CoinSelection(benchmark::State& state)
assert(success);
assert(nValueRet == 1003 * COIN);
assert(setCoinsRet.size() == 2);
+
+ // Empty wallet.
+ for (COutput& output : vCoins) {
+ delete output.tx;
+ }
+ vCoins.clear();
}
}
diff --git a/src/bench/prevector.cpp b/src/bench/prevector.cpp
new file mode 100644
index 0000000000..d0f28d1a3e
--- /dev/null
+++ b/src/bench/prevector.cpp
@@ -0,0 +1,77 @@
+// Copyright (c) 2015-2017 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <compat.h>
+#include <prevector.h>
+
+#include <bench/bench.h>
+
+struct nontrivial_t {
+ int x;
+ nontrivial_t() :x(-1) {}
+};
+static_assert(!IS_TRIVIALLY_CONSTRUCTIBLE<nontrivial_t>::value,
+ "expected nontrivial_t to not be trivially constructible");
+
+typedef unsigned char trivial_t;
+static_assert(IS_TRIVIALLY_CONSTRUCTIBLE<trivial_t>::value,
+ "expected trivial_t to be trivially constructible");
+
+template <typename T>
+static void PrevectorDestructor(benchmark::State& state)
+{
+ while (state.KeepRunning()) {
+ for (auto x = 0; x < 1000; ++x) {
+ prevector<28, T> t0;
+ prevector<28, T> t1;
+ t0.resize(28);
+ t1.resize(29);
+ }
+ }
+}
+
+template <typename T>
+static void PrevectorClear(benchmark::State& state)
+{
+
+ while (state.KeepRunning()) {
+ for (auto x = 0; x < 1000; ++x) {
+ prevector<28, T> t0;
+ prevector<28, T> t1;
+ t0.resize(28);
+ t0.clear();
+ t1.resize(29);
+ t0.clear();
+ }
+ }
+}
+
+template <typename T>
+void PrevectorResize(benchmark::State& state)
+{
+ while (state.KeepRunning()) {
+ prevector<28, T> t0;
+ prevector<28, T> t1;
+ for (auto x = 0; x < 1000; ++x) {
+ t0.resize(28);
+ t0.resize(0);
+ t1.resize(29);
+ t1.resize(0);
+ }
+ }
+}
+
+#define PREVECTOR_TEST(name, nontrivops, trivops) \
+ static void Prevector ## name ## Nontrivial(benchmark::State& state) { \
+ PrevectorResize<nontrivial_t>(state); \
+ } \
+ BENCHMARK(Prevector ## name ## Nontrivial, nontrivops); \
+ static void Prevector ## name ## Trivial(benchmark::State& state) { \
+ PrevectorResize<trivial_t>(state); \
+ } \
+ BENCHMARK(Prevector ## name ## Trivial, trivops);
+
+PREVECTOR_TEST(Clear, 28300, 88600)
+PREVECTOR_TEST(Destructor, 28800, 88900)
+PREVECTOR_TEST(Resize, 28900, 90300)
diff --git a/src/bench/prevector_destructor.cpp b/src/bench/prevector_destructor.cpp
deleted file mode 100644
index 39d0ee5eb1..0000000000
--- a/src/bench/prevector_destructor.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2015-2017 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include <bench/bench.h>
-#include <prevector.h>
-
-static void PrevectorDestructor(benchmark::State& state)
-{
- while (state.KeepRunning()) {
- for (auto x = 0; x < 1000; ++x) {
- prevector<28, unsigned char> t0;
- prevector<28, unsigned char> t1;
- t0.resize(28);
- t1.resize(29);
- }
- }
-}
-
-static void PrevectorClear(benchmark::State& state)
-{
-
- while (state.KeepRunning()) {
- for (auto x = 0; x < 1000; ++x) {
- prevector<28, unsigned char> t0;
- prevector<28, unsigned char> t1;
- t0.resize(28);
- t0.clear();
- t1.resize(29);
- t0.clear();
- }
- }
-}
-
-BENCHMARK(PrevectorDestructor, 5700);
-BENCHMARK(PrevectorClear, 5600);
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 6eb223171f..c2b3480f9d 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -175,6 +175,9 @@ public:
// (the tx=... number in the SetBestChain debug.log lines)
3.5 // * estimated number of transactions per second after that timestamp
};
+
+ /* disable fallback fee on mainnet */
+ m_fallback_fee_enabled = false;
}
};
@@ -266,6 +269,8 @@ public:
0.09
};
+ /* enable fallback fee on testnet */
+ m_fallback_fee_enabled = true;
}
};
@@ -343,6 +348,9 @@ public:
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
bech32_hrp = "bcrt";
+
+ /* enable fallback fee on regtest */
+ m_fallback_fee_enabled = true;
}
};
diff --git a/src/chainparams.h b/src/chainparams.h
index d478da9891..6b1f813afb 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -65,6 +65,8 @@ public:
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
/** Return the BIP70 network string (main, test or regtest) */
std::string NetworkIDString() const { return strNetworkID; }
+ /** Return true if the fallback fee is by default enabled for this network */
+ bool IsFallbackFeeEnabled() const { return m_fallback_fee_enabled; }
/** Return the list of hostnames to look up for DNS seeds */
const std::vector<std::string>& DNSSeeds() const { return vSeeds; }
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
@@ -91,6 +93,7 @@ protected:
bool fMineBlocksOnDemand;
CCheckpointData checkpointData;
ChainTxData chainTxData;
+ bool m_fallback_fee_enabled;
};
/**
diff --git a/src/compat.h b/src/compat.h
index aae84b1181..8a0f901304 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -10,6 +10,16 @@
#include <config/bitcoin-config.h>
#endif
+#include <type_traits>
+
+// GCC 4.8 is missing some C++11 type_traits,
+// https://www.gnu.org/software/gcc/gcc-5/changes.html
+#if defined(__GNUC__) && __GNUC__ < 5
+#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivial
+#else
+#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_constructible
+#endif
+
#ifdef WIN32
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
diff --git a/src/init.cpp b/src/init.cpp
index 895a5358f4..47bcdf2294 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -448,6 +448,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-limitdescendantcount=<n>", strprintf("Do not accept transactions if any ancestor would have <n> or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT));
strUsage += HelpMessageOpt("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT));
strUsage += HelpMessageOpt("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)");
+ strUsage += HelpMessageOpt("-addrmantest", "Allows to test address relay on localhost");
}
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
_("If <category> is not supplied or if <category> = 1, output all debugging information.") + " " + _("<category> can be:") + " " + ListLogCategories() + ".");
@@ -490,7 +491,8 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY));
strUsage += HelpMessageGroup(_("Block creation options:"));
- strUsage += HelpMessageOpt("-blockmaxsize=<n>", _("Set maximum BIP141 block weight to this * 4. Deprecated, use blockmaxweight"));
+ if (showDebug)
+ strUsage += HelpMessageOpt("-blockmaxsize=<n>", "Set maximum BIP141 block weight to this * 4. Deprecated, use blockmaxweight");
strUsage += HelpMessageOpt("-blockmaxweight=<n>", strprintf(_("Set maximum BIP141 block weight (default: %d)"), DEFAULT_BLOCK_MAX_WEIGHT));
strUsage += HelpMessageOpt("-blockmintxfee=<amt>", strprintf(_("Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)));
if (showDebug)
@@ -1526,7 +1528,7 @@ bool AppInitMain()
if (!is_coinsview_empty) {
uiInterface.InitMessage(_("Verifying blocks..."));
if (fHavePruned && gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) {
- LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks",
+ LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks\n",
MIN_BLOCKS_TO_KEEP);
}
diff --git a/src/leveldb/db/db_impl.cc b/src/leveldb/db/db_impl.cc
index f43ad76794..3bb58e560a 100644
--- a/src/leveldb/db/db_impl.cc
+++ b/src/leveldb/db/db_impl.cc
@@ -414,7 +414,7 @@ Status DBImpl::RecoverLogFile(uint64_t log_number, bool last_log,
status.ok()) {
if (record.size() < 12) {
reporter.Corruption(
- record.size(), Status::Corruption("log record too small"));
+ record.size(), Status::Corruption("log record too small", fname));
continue;
}
WriteBatchInternal::SetContents(&batch, record);
diff --git a/src/leveldb/db/leveldbutil.cc b/src/leveldb/db/leveldbutil.cc
index 9f4b7dd70c..d06d64d640 100644
--- a/src/leveldb/db/leveldbutil.cc
+++ b/src/leveldb/db/leveldbutil.cc
@@ -19,6 +19,7 @@ class StdoutPrinter : public WritableFile {
virtual Status Close() { return Status::OK(); }
virtual Status Flush() { return Status::OK(); }
virtual Status Sync() { return Status::OK(); }
+ virtual std::string GetName() const { return "[stdout]"; }
};
bool HandleDumpCommand(Env* env, char** files, int num) {
diff --git a/src/leveldb/db/log_reader.cc b/src/leveldb/db/log_reader.cc
index a6d304545d..8b6ad136d7 100644
--- a/src/leveldb/db/log_reader.cc
+++ b/src/leveldb/db/log_reader.cc
@@ -186,7 +186,7 @@ uint64_t Reader::LastRecordOffset() {
}
void Reader::ReportCorruption(uint64_t bytes, const char* reason) {
- ReportDrop(bytes, Status::Corruption(reason));
+ ReportDrop(bytes, Status::Corruption(reason, file_->GetName()));
}
void Reader::ReportDrop(uint64_t bytes, const Status& reason) {
diff --git a/src/leveldb/db/repair.cc b/src/leveldb/db/repair.cc
index 4cd4bb047f..7281e3d345 100644
--- a/src/leveldb/db/repair.cc
+++ b/src/leveldb/db/repair.cc
@@ -203,7 +203,7 @@ class Repairer {
while (reader.ReadRecord(&record, &scratch)) {
if (record.size() < 12) {
reporter.Corruption(
- record.size(), Status::Corruption("log record too small"));
+ record.size(), Status::Corruption("log record too small", logname));
continue;
}
WriteBatchInternal::SetContents(&batch, record);
diff --git a/src/leveldb/helpers/memenv/memenv.cc b/src/leveldb/helpers/memenv/memenv.cc
index 9a98884daf..68c0614a59 100644
--- a/src/leveldb/helpers/memenv/memenv.cc
+++ b/src/leveldb/helpers/memenv/memenv.cc
@@ -176,6 +176,7 @@ class SequentialFileImpl : public SequentialFile {
return Status::OK();
}
+ virtual std::string GetName() const { return "[memenv]"; }
private:
FileState* file_;
uint64_t pos_;
@@ -196,6 +197,7 @@ class RandomAccessFileImpl : public RandomAccessFile {
return file_->Read(offset, n, result, scratch);
}
+ virtual std::string GetName() const { return "[memenv]"; }
private:
FileState* file_;
};
@@ -218,6 +220,7 @@ class WritableFileImpl : public WritableFile {
virtual Status Flush() { return Status::OK(); }
virtual Status Sync() { return Status::OK(); }
+ virtual std::string GetName() const { return "[memenv]"; }
private:
FileState* file_;
};
diff --git a/src/leveldb/include/leveldb/env.h b/src/leveldb/include/leveldb/env.h
index 99b6c21414..275d441eae 100644
--- a/src/leveldb/include/leveldb/env.h
+++ b/src/leveldb/include/leveldb/env.h
@@ -191,6 +191,9 @@ class SequentialFile {
// REQUIRES: External synchronization
virtual Status Skip(uint64_t n) = 0;
+ // Get a name for the file, only for error reporting
+ virtual std::string GetName() const = 0;
+
private:
// No copying allowed
SequentialFile(const SequentialFile&);
@@ -215,6 +218,9 @@ class RandomAccessFile {
virtual Status Read(uint64_t offset, size_t n, Slice* result,
char* scratch) const = 0;
+ // Get a name for the file, only for error reporting
+ virtual std::string GetName() const = 0;
+
private:
// No copying allowed
RandomAccessFile(const RandomAccessFile&);
@@ -234,6 +240,9 @@ class WritableFile {
virtual Status Flush() = 0;
virtual Status Sync() = 0;
+ // Get a name for the file, only for error reporting
+ virtual std::string GetName() const = 0;
+
private:
// No copying allowed
WritableFile(const WritableFile&);
diff --git a/src/leveldb/table/format.cc b/src/leveldb/table/format.cc
index 24e4e02445..285e1c0de3 100644
--- a/src/leveldb/table/format.cc
+++ b/src/leveldb/table/format.cc
@@ -82,7 +82,7 @@ Status ReadBlock(RandomAccessFile* file,
}
if (contents.size() != n + kBlockTrailerSize) {
delete[] buf;
- return Status::Corruption("truncated block read");
+ return Status::Corruption("truncated block read", file->GetName());
}
// Check the crc of the type and the block contents
@@ -92,7 +92,7 @@ Status ReadBlock(RandomAccessFile* file,
const uint32_t actual = crc32c::Value(data, n + 1);
if (actual != crc) {
delete[] buf;
- s = Status::Corruption("block checksum mismatch");
+ s = Status::Corruption("block checksum mismatch", file->GetName());
return s;
}
}
@@ -119,13 +119,13 @@ Status ReadBlock(RandomAccessFile* file,
size_t ulength = 0;
if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
delete[] buf;
- return Status::Corruption("corrupted compressed block contents");
+ return Status::Corruption("corrupted compressed block contents", file->GetName());
}
char* ubuf = new char[ulength];
if (!port::Snappy_Uncompress(data, n, ubuf)) {
delete[] buf;
delete[] ubuf;
- return Status::Corruption("corrupted compressed block contents");
+ return Status::Corruption("corrupted compressed block contents", file->GetName());
}
delete[] buf;
result->data = Slice(ubuf, ulength);
@@ -135,7 +135,7 @@ Status ReadBlock(RandomAccessFile* file,
}
default:
delete[] buf;
- return Status::Corruption("bad block type");
+ return Status::Corruption("bad block type", file->GetName());
}
return Status::OK();
diff --git a/src/leveldb/util/env_posix.cc b/src/leveldb/util/env_posix.cc
index dd852af354..4676bc2240 100644
--- a/src/leveldb/util/env_posix.cc
+++ b/src/leveldb/util/env_posix.cc
@@ -121,6 +121,8 @@ class PosixSequentialFile: public SequentialFile {
}
return Status::OK();
}
+
+ virtual std::string GetName() const { return filename_; }
};
// pread() based random-access
@@ -172,6 +174,8 @@ class PosixRandomAccessFile: public RandomAccessFile {
}
return s;
}
+
+ virtual std::string GetName() const { return filename_; }
};
// mmap() based random-access
@@ -206,6 +210,8 @@ class PosixMmapReadableFile: public RandomAccessFile {
}
return s;
}
+
+ virtual std::string GetName() const { return filename_; }
};
class PosixWritableFile : public WritableFile {
@@ -287,6 +293,8 @@ class PosixWritableFile : public WritableFile {
}
return s;
}
+
+ virtual std::string GetName() const { return filename_; }
};
static int LockOrUnlock(int fd, bool lock) {
diff --git a/src/leveldb/util/env_win.cc b/src/leveldb/util/env_win.cc
index d32c4e676c..81380216bb 100644
--- a/src/leveldb/util/env_win.cc
+++ b/src/leveldb/util/env_win.cc
@@ -78,6 +78,7 @@ public:
virtual Status Read(size_t n, Slice* result, char* scratch);
virtual Status Skip(uint64_t n);
BOOL isEnable();
+ virtual std::string GetName() const { return _filename; }
private:
BOOL _Init();
void _CleanUp();
@@ -94,6 +95,7 @@ public:
virtual ~Win32RandomAccessFile();
virtual Status Read(uint64_t offset, size_t n, Slice* result,char* scratch) const;
BOOL isEnable();
+ virtual std::string GetName() const { return _filename; }
private:
BOOL _Init(LPCWSTR path);
void _CleanUp();
@@ -114,6 +116,7 @@ public:
virtual Status Flush();
virtual Status Sync();
BOOL isEnable();
+ virtual std::string GetName() const { return filename_; }
private:
std::string filename_;
::HANDLE _hFile;
diff --git a/src/net.cpp b/src/net.cpp
index 201914685c..c7c19f83a1 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -181,6 +181,10 @@ void AdvertiseLocal(CNode *pnode)
if (fListen && pnode->fSuccessfullyConnected)
{
CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
+ if (gArgs.GetBoolArg("-addrmantest", false)) {
+ // use IPv4 loopback during addrmantest
+ addrLocal = CAddress(CService(LookupNumeric("127.0.0.1", GetListenPort())), pnode->GetLocalServices());
+ }
// If discovery is enabled, sometimes give our peer the address it
// tells us that it sees us as in case it has a better idea of our
// address than we do.
@@ -189,7 +193,7 @@ void AdvertiseLocal(CNode *pnode)
{
addrLocal.SetIP(pnode->GetAddrLocal());
}
- if (addrLocal.IsRoutable())
+ if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false))
{
LogPrint(BCLog::NET, "AdvertiseLocal: advertising address %s\n", addrLocal.ToString());
FastRandomContext insecure_rand;
@@ -2718,6 +2722,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
fOneShot = false;
m_manual_connection = false;
fClient = false; // set by version message
+ m_limited_node = false; // set by version message
fFeeler = false;
fSuccessfullyConnected = false;
fDisconnect = false;
diff --git a/src/net.h b/src/net.h
index 8378a303b8..96f04d83e0 100644
--- a/src/net.h
+++ b/src/net.h
@@ -641,6 +641,7 @@ public:
bool fOneShot;
bool m_manual_connection;
bool fClient;
+ bool m_limited_node; //after BIP159
const bool fInbound;
std::atomic_bool fSuccessfullyConnected;
std::atomic_bool fDisconnect;
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index bf9307727a..ddf0dbbbea 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -892,6 +892,7 @@ void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew, const CB
const int nNewHeight = pindexNew->nHeight;
connman->SetBestHeight(nNewHeight);
+ SetServiceFlagsIBDCache(!fInitialDownload);
if (!fInitialDownload) {
// Find the hashes of all blocks that weren't previously in the best chain.
std::vector<uint256> vHashes;
@@ -1642,7 +1643,13 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
pfrom->cleanSubVer = cleanSubVer;
}
pfrom->nStartingHeight = nStartingHeight;
- pfrom->fClient = !(nServices & NODE_NETWORK);
+
+ // set nodes not relaying blocks and tx and not serving (parts) of the historical blockchain as "clients"
+ pfrom->fClient = (!(nServices & NODE_NETWORK) && !(nServices & NODE_NETWORK_LIMITED));
+
+ // set nodes not capable of serving the complete blockchain history as "limited nodes"
+ pfrom->m_limited_node = (!(nServices & NODE_NETWORK) && (nServices & NODE_NETWORK_LIMITED));
+
{
LOCK(pfrom->cs_filter);
pfrom->fRelayTxes = fRelay; // set to true after we get the first filter* message
@@ -1801,7 +1808,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// We only bother storing full nodes, though this may include
// things which we would not make an outbound connection to, in
// part because we may make feeler connections to them.
- if (!MayHaveUsefulAddressDB(addr.nServices))
+ if (!MayHaveUsefulAddressDB(addr.nServices) && !HasAllDesirableServiceFlags(addr.nServices))
continue;
if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
@@ -3611,7 +3618,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto, std::atomic<bool>& interruptM
// Message: getdata (blocks)
//
std::vector<CInv> vGetData;
- if (!pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
+ if (!pto->fClient && ((fFetch && !pto->m_limited_node) || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
std::vector<const CBlockIndex*> vToDownload;
NodeId staller = -1;
FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller, consensusParams);
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 5be3fe34f8..3ea3141d5e 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -139,7 +139,7 @@ bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault,
if (pszName[0] == 0)
return false;
int port = portDefault;
- std::string hostname = "";
+ std::string hostname;
SplitHostPort(std::string(pszName), port, hostname);
std::vector<CNetAddr> vIP;
diff --git a/src/prevector.h b/src/prevector.h
index f8d6a09145..103ead82cc 100644
--- a/src/prevector.h
+++ b/src/prevector.h
@@ -10,9 +10,12 @@
#include <stdint.h>
#include <string.h>
+#include <cstddef>
#include <iterator>
#include <type_traits>
+#include <compat.h>
+
#pragma pack(push, 1)
/** Implements a drop-in replacement for std::vector<T> which stores up to N
* elements directly (without heap allocation). The types Size and Diff are
@@ -194,16 +197,42 @@ private:
T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
+ void fill(T* dst, ptrdiff_t count) {
+ if (IS_TRIVIALLY_CONSTRUCTIBLE<T>::value) {
+ // The most common use of prevector is where T=unsigned char. For
+ // trivially constructible types, we can use memset() to avoid
+ // looping.
+ ::memset(dst, 0, count * sizeof(T));
+ } else {
+ for (auto i = 0; i < count; ++i) {
+ new(static_cast<void*>(dst + i)) T();
+ }
+ }
+ }
+
+ void fill(T* dst, ptrdiff_t count, const T& value) {
+ for (auto i = 0; i < count; ++i) {
+ new(static_cast<void*>(dst + i)) T(value);
+ }
+ }
+
+ template<typename InputIterator>
+ void fill(T* dst, InputIterator first, InputIterator last) {
+ while (first != last) {
+ new(static_cast<void*>(dst)) T(*first);
+ ++dst;
+ ++first;
+ }
+ }
+
public:
void assign(size_type n, const T& val) {
clear();
if (capacity() < n) {
change_capacity(n);
}
- while (size() < n) {
- _size++;
- new(static_cast<void*>(item_ptr(size() - 1))) T(val);
- }
+ _size += n;
+ fill(item_ptr(0), n, val);
}
template<typename InputIterator>
@@ -213,11 +242,8 @@ public:
if (capacity() < n) {
change_capacity(n);
}
- while (first != last) {
- _size++;
- new(static_cast<void*>(item_ptr(size() - 1))) T(*first);
- ++first;
- }
+ _size += n;
+ fill(item_ptr(0), first, last);
}
prevector() : _size(0), _union{{}} {}
@@ -228,31 +254,23 @@ public:
explicit prevector(size_type n, const T& val = T()) : _size(0) {
change_capacity(n);
- while (size() < n) {
- _size++;
- new(static_cast<void*>(item_ptr(size() - 1))) T(val);
- }
+ _size += n;
+ fill(item_ptr(0), n, val);
}
template<typename InputIterator>
prevector(InputIterator first, InputIterator last) : _size(0) {
size_type n = last - first;
change_capacity(n);
- while (first != last) {
- _size++;
- new(static_cast<void*>(item_ptr(size() - 1))) T(*first);
- ++first;
- }
+ _size += n;
+ fill(item_ptr(0), first, last);
}
prevector(const prevector<N, T, Size, Diff>& other) : _size(0) {
- change_capacity(other.size());
- const_iterator it = other.begin();
- while (it != other.end()) {
- _size++;
- new(static_cast<void*>(item_ptr(size() - 1))) T(*it);
- ++it;
- }
+ size_type n = other.size();
+ change_capacity(n);
+ _size += n;
+ fill(item_ptr(0), other.begin(), other.end());
}
prevector(prevector<N, T, Size, Diff>&& other) : _size(0) {
@@ -263,14 +281,7 @@ public:
if (&other == this) {
return *this;
}
- resize(0);
- change_capacity(other.size());
- const_iterator it = other.begin();
- while (it != other.end()) {
- _size++;
- new(static_cast<void*>(item_ptr(size() - 1))) T(*it);
- ++it;
- }
+ assign(other.begin(), other.end());
return *this;
}
@@ -314,16 +325,20 @@ public:
}
void resize(size_type new_size) {
- if (size() > new_size) {
+ size_type cur_size = size();
+ if (cur_size == new_size) {
+ return;
+ }
+ if (cur_size > new_size) {
erase(item_ptr(new_size), end());
+ return;
}
if (new_size > capacity()) {
change_capacity(new_size);
}
- while (size() < new_size) {
- _size++;
- new(static_cast<void*>(item_ptr(size() - 1))) T();
- }
+ ptrdiff_t increase = new_size - cur_size;
+ fill(item_ptr(cur_size), increase);
+ _size += increase;
}
void reserve(size_type new_capacity) {
@@ -346,10 +361,11 @@ public:
if (capacity() < new_size) {
change_capacity(new_size + (new_size >> 1));
}
- memmove(item_ptr(p + 1), item_ptr(p), (size() - p) * sizeof(T));
+ T* ptr = item_ptr(p);
+ memmove(ptr + 1, ptr, (size() - p) * sizeof(T));
_size++;
- new(static_cast<void*>(item_ptr(p))) T(value);
- return iterator(item_ptr(p));
+ new(static_cast<void*>(ptr)) T(value);
+ return iterator(ptr);
}
void insert(iterator pos, size_type count, const T& value) {
@@ -358,11 +374,10 @@ public:
if (capacity() < new_size) {
change_capacity(new_size + (new_size >> 1));
}
- memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T));
+ T* ptr = item_ptr(p);
+ memmove(ptr + count, ptr, (size() - p) * sizeof(T));
_size += count;
- for (size_type i = 0; i < count; i++) {
- new(static_cast<void*>(item_ptr(p + i))) T(value);
- }
+ fill(item_ptr(p), count, value);
}
template<typename InputIterator>
@@ -373,13 +388,10 @@ public:
if (capacity() < new_size) {
change_capacity(new_size + (new_size >> 1));
}
- memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T));
+ T* ptr = item_ptr(p);
+ memmove(ptr + count, ptr, (size() - p) * sizeof(T));
_size += count;
- while (first != last) {
- new(static_cast<void*>(item_ptr(p))) T(*first);
- ++p;
- ++first;
- }
+ fill(ptr, first, last);
}
iterator erase(iterator pos) {
diff --git a/src/protocol.cpp b/src/protocol.cpp
index c412ad9ffe..2ec26fbd3e 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -12,6 +12,8 @@
# include <arpa/inet.h>
#endif
+static std::atomic<bool> g_initial_block_download_completed(false);
+
namespace NetMsgType {
const char *VERSION="version";
const char *VERACK="verack";
@@ -127,6 +129,17 @@ bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
}
+ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
+ if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) {
+ return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
+ }
+ return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
+}
+
+void SetServiceFlagsIBDCache(bool state) {
+ g_initial_block_download_completed = state;
+}
+
CAddress::CAddress() : CService()
{
diff --git a/src/protocol.h b/src/protocol.h
index 42eb57e4f0..e518d11944 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -15,6 +15,7 @@
#include <uint256.h>
#include <version.h>
+#include <atomic>
#include <stdint.h>
#include <string>
@@ -301,9 +302,10 @@ enum ServiceFlags : uint64_t {
* If the NODE_NONE return value is changed, contrib/seeds/makeseeds.py
* should be updated appropriately to filter for the same nodes.
*/
-static ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
- return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
-}
+ServiceFlags GetDesirableServiceFlags(ServiceFlags services);
+
+/** Set the current IBD status in order to figure out the desirable service flags */
+void SetServiceFlagsIBDCache(bool status);
/**
* A shortcut for (services & GetDesirableServiceFlags(services))
@@ -316,10 +318,10 @@ static inline bool HasAllDesirableServiceFlags(ServiceFlags services) {
/**
* Checks if a peer with the given service flags may be capable of having a
- * robust address-storage DB. Currently an alias for checking NODE_NETWORK.
+ * robust address-storage DB.
*/
static inline bool MayHaveUsefulAddressDB(ServiceFlags services) {
- return services & NODE_NETWORK;
+ return (services & NODE_NETWORK) || (services & NODE_NETWORK_LIMITED);
}
/** A CService with information about it as peer */
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 06e1f1a37c..ab381bfb5d 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -29,6 +29,7 @@
#include <init.h>
#include <rpc/server.h>
#include <ui_interface.h>
+#include <uint256.h>
#include <util.h>
#include <warnings.h>
@@ -80,6 +81,7 @@ Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
// Declare meta types used for QMetaObject::invokeMethod
Q_DECLARE_METATYPE(bool*)
Q_DECLARE_METATYPE(CAmount)
+Q_DECLARE_METATYPE(uint256)
static void InitMessage(const std::string &message)
{
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 3642e5d4d4..eaf2896bc3 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -138,9 +138,9 @@ size_t ClientModel::getMempoolDynamicUsage() const
double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const
{
CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn);
+ LOCK(cs_main);
if (!tip)
{
- LOCK(cs_main);
tip = chainActive.Tip();
}
return GuessVerificationProgress(Params().TxData(), tip);
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index edf1c29ea1..a46e0561b9 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -417,7 +417,7 @@ void openDebugLogfile()
bool openBitcoinConf()
{
- boost::filesystem::path pathConfig = GetConfigFile(BITCOIN_CONF_FILENAME);
+ boost::filesystem::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
/* Create the file */
boost::filesystem::ofstream configFile(pathConfig, std::ios_base::app);
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index c4b209a880..1aa4de03ca 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -70,6 +70,7 @@ const QStringList historyFilter = QStringList()
<< "importmulti"
<< "signmessagewithprivkey"
<< "signrawtransaction"
+ << "signrawtransactionwithkey"
<< "walletpassphrase"
<< "walletpassphrasechange"
<< "encryptwallet";
@@ -624,7 +625,7 @@ void RPCConsole::setClientModel(ClientModel *model)
connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged()));
// peer table signal handling - cache selected node ids
connect(model->getPeerTableModel(), SIGNAL(layoutAboutToBeChanged()), this, SLOT(peerLayoutAboutToChange()));
-
+
// set up ban table
ui->banlistWidget->setModel(model->getBanTableModel());
ui->banlistWidget->verticalHeader()->hide();
@@ -772,7 +773,7 @@ void RPCConsole::clear(bool clearHistory)
#else
QString clsKey = "Ctrl-L";
#endif
-
+
message(CMD_REPLY, (tr("Welcome to the %1 RPC console.").arg(tr(PACKAGE_NAME)) + "<br>" +
tr("Use up and down arrows to navigate history, and %1 to clear screen.").arg("<b>"+clsKey+"</b>") + "<br>" +
tr("Type %1 for an overview of available commands.").arg("<b>help</b>") + "<br>" +
@@ -1144,7 +1145,7 @@ void RPCConsole::disconnectSelectedNode()
{
if(!g_connman)
return;
-
+
// Get selected peer addresses
QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->peerWidget, PeerTableModel::NetNodeId);
for(int i = 0; i < nodes.count(); i++)
@@ -1161,7 +1162,7 @@ void RPCConsole::banSelectedNode(int bantime)
{
if (!clientModel || !g_connman)
return;
-
+
// Get selected peer addresses
QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->peerWidget, PeerTableModel::NetNodeId);
for(int i = 0; i < nodes.count(); i++)
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 871822ccb4..ef36aab1a4 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -369,6 +369,7 @@ void SendCoinsDialog::on_sendButton_clicked()
accept();
CoinControlDialog::coinControl()->UnSelectAll();
coinControlUpdateLabels();
+ Q_EMIT coinsSent(currentTransaction.getTransaction()->GetHash());
}
fNewRecipientAllowed = true;
}
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index 7c27785d12..48885bbcad 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -54,6 +54,9 @@ public Q_SLOTS:
void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance);
+Q_SIGNALS:
+ void coinsSent(const uint256& txid);
+
private:
Ui::SendCoinsDialog *ui;
ClientModel *clientModel;
diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp
index aaec15cc13..9d0e0b97d1 100644
--- a/src/qt/test/rpcnestedtests.cpp
+++ b/src/qt/test/rpcnestedtests.cpp
@@ -82,8 +82,8 @@ void RPCNestedTests::rpcNestedTests()
QVERIFY(filtered == "signmessagewithprivkey(…)");
RPCConsole::RPCParseCommandLine(result, "signmessagewithprivkey abc,def", false, &filtered);
QVERIFY(filtered == "signmessagewithprivkey(…)");
- RPCConsole::RPCParseCommandLine(result, "signrawtransaction(abc)", false, &filtered);
- QVERIFY(filtered == "signrawtransaction(…)");
+ RPCConsole::RPCParseCommandLine(result, "signrawtransactionwithkey(abc)", false, &filtered);
+ QVERIFY(filtered == "signrawtransactionwithkey(…)");
RPCConsole::RPCParseCommandLine(result, "walletpassphrase(help())", false, &filtered);
QVERIFY(filtered == "walletpassphrase(…)");
RPCConsole::RPCParseCommandLine(result, "walletpassphrasechange(help(walletpassphrasechange(abc)))", false, &filtered);
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index c1d28be0ab..6f30e56327 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -17,6 +17,7 @@
#include <util.h>
#include <wallet/db.h>
#include <wallet/wallet.h>
+#include <policy/policy.h>
#include <stdint.h>
#include <string>
@@ -241,6 +242,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
strHTML += "<b>" + tr("Transaction ID") + ":</b> " + rec->getTxID() + "<br>";
strHTML += "<b>" + tr("Transaction total size") + ":</b> " + QString::number(wtx.tx->GetTotalSize()) + " bytes<br>";
+ strHTML += "<b>" + tr("Transaction virtual size") + ":</b> " + QString::number(GetVirtualTransactionSize(*wtx.tx)) + " bytes<br>";
strHTML += "<b>" + tr("Output index") + ":</b> " + QString::number(rec->getOutputIndex()) + "<br>";
// Message from normal bitcoin:URI (bitcoin:123...?message=example)
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index 88f8f463bc..006f9fe443 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -263,8 +263,7 @@ void TransactionView::setModel(WalletModel *_model)
void TransactionView::chooseDate(int idx)
{
- if(!transactionProxyModel)
- return;
+ if (!transactionProxyModel) return;
QDate current = QDate::currentDate();
dateRangeWidget->setVisible(false);
switch(dateWidget->itemData(idx).toInt())
@@ -592,6 +591,32 @@ void TransactionView::focusTransaction(const QModelIndex &idx)
transactionView->setFocus();
}
+void TransactionView::focusTransaction(const uint256& txid)
+{
+ if (!transactionProxyModel)
+ return;
+
+ const QModelIndexList results = this->model->getTransactionTableModel()->match(
+ this->model->getTransactionTableModel()->index(0,0),
+ TransactionTableModel::TxHashRole,
+ QString::fromStdString(txid.ToString()), -1);
+
+ transactionView->setFocus();
+ transactionView->selectionModel()->clearSelection();
+ for (const QModelIndex& index : results) {
+ const QModelIndex targetIndex = transactionProxyModel->mapFromSource(index);
+ transactionView->selectionModel()->select(
+ targetIndex,
+ QItemSelectionModel::Rows | QItemSelectionModel::Select);
+ // Called once per destination to ensure all results are in view, unless
+ // transactions are not ordered by (ascending or descending) date.
+ transactionView->scrollTo(targetIndex);
+ // scrollTo() does not scroll far enough the first time when transactions
+ // are ordered by ascending date.
+ if (index == results[0]) transactionView->scrollTo(targetIndex);
+ }
+}
+
// We override the virtual resizeEvent of the QWidget to adjust tables column
// sizes as the tables width is proportional to the dialogs width.
void TransactionView::resizeEvent(QResizeEvent* event)
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index 82e929b53f..66dc5bc86b 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -7,6 +7,8 @@
#include <qt/guiutil.h>
+#include <uint256.h>
+
#include <QWidget>
#include <QKeyEvent>
@@ -116,7 +118,7 @@ public Q_SLOTS:
void changedSearch();
void exportClicked();
void focusTransaction(const QModelIndex&);
-
+ void focusTransaction(const uint256& txid);
};
#endif // BITCOIN_QT_TRANSACTIONVIEW_H
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index 7eced9289d..64497a3431 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -68,6 +68,9 @@ WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent):
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
connect(overviewPage, SIGNAL(outOfSyncWarningClicked()), this, SLOT(requestedSyncWarningInfo()));
+ // Highlight transaction after send
+ connect(sendCoinsPage, SIGNAL(coinsSent(uint256)), transactionView, SLOT(focusTransaction(uint256)));
+
// Double-clicking on a transaction on the transaction history page shows details
connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
@@ -91,6 +94,9 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui)
// Clicking on a transaction on the overview page simply sends you to transaction history page
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), gui, SLOT(gotoHistoryPage()));
+ // Navigate to transaction history page after send
+ connect(sendCoinsPage, SIGNAL(coinsSent(uint256)), gui, SLOT(gotoHistoryPage()));
+
// Receive and report messages
connect(this, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int)));
diff --git a/src/rest.cpp b/src/rest.cpp
index eeeb3f5141..8cba59dbbc 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -90,7 +90,7 @@ static enum RetFormat ParseDataFormat(std::string& param, const std::string& str
static std::string AvailableDataFormatsString()
{
- std::string formats = "";
+ std::string formats;
for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
if (strlen(rf_names[i].name) > 0) {
formats.append(".");
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index f1352a13cf..8007cebc37 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1542,25 +1542,19 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
const CBlockIndex* pindex;
int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
- bool havehash = !request.params[1].isNull();
- uint256 hash;
- if (havehash) {
- hash = uint256S(request.params[1].get_str());
- }
-
- {
+ if (request.params[1].isNull()) {
LOCK(cs_main);
- if (havehash) {
- auto it = mapBlockIndex.find(hash);
- if (it == mapBlockIndex.end()) {
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
- }
- pindex = it->second;
- if (!chainActive.Contains(pindex)) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
- }
- } else {
- pindex = chainActive.Tip();
+ pindex = chainActive.Tip();
+ } else {
+ uint256 hash = uint256S(request.params[1].get_str());
+ LOCK(cs_main);
+ auto it = mapBlockIndex.find(hash);
+ if (it == mapBlockIndex.end()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
+ }
+ pindex = it->second;
+ if (!chainActive.Contains(pindex)) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
}
}
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 99c1242d8a..a95ea0cf92 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -94,6 +94,9 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "decoderawtransaction", 1, "iswitness" },
{ "signrawtransaction", 1, "prevtxs" },
{ "signrawtransaction", 2, "privkeys" },
+ { "signrawtransactionwithkey", 1, "privkeys" },
+ { "signrawtransactionwithkey", 2, "prevtxs" },
+ { "signrawtransactionwithwallet", 1, "prevtxs" },
{ "sendrawtransaction", 1, "allowhighfees" },
{ "combinerawtransaction", 0, "txs" },
{ "fundrawtransaction", 1, "options" },
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 3f89996e61..f573c7dbeb 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -33,175 +33,33 @@
#include <univalue.h>
-#ifdef ENABLE_WALLET
-class DescribeAddressVisitor : public boost::static_visitor<UniValue>
-{
-public:
- CWallet * const pwallet;
-
- explicit DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {}
-
- void ProcessSubScript(const CScript& subscript, UniValue& obj, bool include_addresses = false) const
- {
- // Always present: script type and redeemscript
- txnouttype which_type;
- std::vector<std::vector<unsigned char>> solutions_data;
- Solver(subscript, which_type, solutions_data);
- obj.pushKV("script", GetTxnOutputType(which_type));
- obj.pushKV("hex", HexStr(subscript.begin(), subscript.end()));
-
- CTxDestination embedded;
- UniValue a(UniValue::VARR);
- if (ExtractDestination(subscript, embedded)) {
- // Only when the script corresponds to an address.
- UniValue subobj = boost::apply_visitor(*this, embedded);
- subobj.pushKV("address", EncodeDestination(embedded));
- subobj.pushKV("scriptPubKey", HexStr(subscript.begin(), subscript.end()));
- // Always report the pubkey at the top level, so that `getnewaddress()['pubkey']` always works.
- if (subobj.exists("pubkey")) obj.pushKV("pubkey", subobj["pubkey"]);
- obj.pushKV("embedded", std::move(subobj));
- if (include_addresses) a.push_back(EncodeDestination(embedded));
- } else if (which_type == TX_MULTISIG) {
- // Also report some information on multisig scripts (which do not have a corresponding address).
- // TODO: abstract out the common functionality between this logic and ExtractDestinations.
- obj.pushKV("sigsrequired", solutions_data[0][0]);
- UniValue pubkeys(UniValue::VARR);
- for (size_t i = 1; i < solutions_data.size() - 1; ++i) {
- CPubKey key(solutions_data[i].begin(), solutions_data[i].end());
- if (include_addresses) a.push_back(EncodeDestination(key.GetID()));
- pubkeys.push_back(HexStr(key.begin(), key.end()));
- }
- obj.pushKV("pubkeys", std::move(pubkeys));
- }
-
- // The "addresses" field is confusing because it refers to public keys using their P2PKH address.
- // For that reason, only add the 'addresses' field when needed for backward compatibility. New applications
- // can use the 'embedded'->'address' field for P2SH or P2WSH wrapped addresses, and 'pubkeys' for
- // inspecting multisig participants.
- if (include_addresses) obj.pushKV("addresses", std::move(a));
- }
-
- UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
-
- UniValue operator()(const CKeyID &keyID) const {
- UniValue obj(UniValue::VOBJ);
- CPubKey vchPubKey;
- obj.pushKV("isscript", false);
- obj.pushKV("iswitness", false);
- if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) {
- obj.pushKV("pubkey", HexStr(vchPubKey));
- obj.pushKV("iscompressed", vchPubKey.IsCompressed());
- }
- return obj;
- }
-
- UniValue operator()(const CScriptID &scriptID) const {
- UniValue obj(UniValue::VOBJ);
- CScript subscript;
- obj.pushKV("isscript", true);
- obj.pushKV("iswitness", false);
- if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
- ProcessSubScript(subscript, obj, true);
- }
- return obj;
- }
-
- UniValue operator()(const WitnessV0KeyHash& id) const
- {
- UniValue obj(UniValue::VOBJ);
- CPubKey pubkey;
- obj.pushKV("isscript", false);
- obj.pushKV("iswitness", true);
- obj.pushKV("witness_version", 0);
- obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
- if (pwallet && pwallet->GetPubKey(CKeyID(id), pubkey)) {
- obj.pushKV("pubkey", HexStr(pubkey));
- }
- return obj;
- }
-
- UniValue operator()(const WitnessV0ScriptHash& id) const
- {
- UniValue obj(UniValue::VOBJ);
- CScript subscript;
- obj.pushKV("isscript", true);
- obj.pushKV("iswitness", true);
- obj.pushKV("witness_version", 0);
- obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
- CRIPEMD160 hasher;
- uint160 hash;
- hasher.Write(id.begin(), 32).Finalize(hash.begin());
- if (pwallet && pwallet->GetCScript(CScriptID(hash), subscript)) {
- ProcessSubScript(subscript, obj);
- }
- return obj;
- }
-
- UniValue operator()(const WitnessUnknown& id) const
- {
- UniValue obj(UniValue::VOBJ);
- CScript subscript;
- obj.pushKV("iswitness", true);
- obj.pushKV("witness_version", (int)id.version);
- obj.pushKV("witness_program", HexStr(id.program, id.program + id.length));
- return obj;
- }
-};
-#endif
-
UniValue validateaddress(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() != 1)
throw std::runtime_error(
"validateaddress \"address\"\n"
"\nReturn information about the given bitcoin address.\n"
+ "DEPRECATION WARNING: Parts of this command have been deprecated and moved to getaddressinfo. Clients must\n"
+ "transition to using getaddressinfo to access this information before upgrading to v0.18. The following deprecated\n"
+ "fields have moved to getaddressinfo and will only be shown here with -deprecatedrpc=validateaddress: ismine, iswatchonly,\n"
+ "script, hex, pubkeys, sigsrequired, pubkey, addresses, embedded, iscompressed, account, timestamp, hdkeypath, kdmasterkeyid.\n"
"\nArguments:\n"
- "1. \"address\" (string, required) The bitcoin address to validate\n"
+ "1. \"address\" (string, required) The bitcoin address to validate\n"
"\nResult:\n"
"{\n"
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
" \"address\" : \"address\", (string) The bitcoin address validated\n"
" \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
- " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
- " \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n"
- " \"isscript\" : true|false, (boolean, optional) If the address is P2SH or P2WSH. Not included for unknown witness types.\n"
- " \"iswitness\" : true|false, (boolean) If the address is P2WPKH, P2WSH, or an unknown witness version\n"
- " \"witness_version\" : version (number, optional) For all witness output types, gives the version number.\n"
- " \"witness_program\" : \"hex\" (string, optional) For all witness output types, gives the script or key hash present in the address.\n"
- " \"script\" : \"type\" (string, optional) The output script type. Only if \"isscript\" is true and the redeemscript is known. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash, witness_unknown\n"
- " \"hex\" : \"hex\", (string, optional) The redeemscript for the P2SH or P2WSH address\n"
- " \"addresses\" (string, optional) Array of addresses associated with the known redeemscript (only if \"iswitness\" is false). This field is superseded by the \"pubkeys\" field and the address inside \"embedded\".\n"
- " [\n"
- " \"address\"\n"
- " ,...\n"
- " ]\n"
- " \"pubkeys\" (string, optional) Array of pubkeys associated with the known redeemscript (only if \"script\" is \"multisig\")\n"
- " [\n"
- " \"pubkey\"\n"
- " ,...\n"
- " ]\n"
- " \"sigsrequired\" : xxxxx (numeric, optional) Number of signatures required to spend multisig output (only if \"script\" is \"multisig\")\n"
- " \"pubkey\" : \"publickeyhex\", (string, optional) The hex value of the raw public key, for single-key addresses (possibly embedded in P2SH or P2WSH)\n"
- " \"embedded\" : {...}, (object, optional) information about the address embedded in P2SH or P2WSH, if relevant and known. It includes all validateaddress output fields for the embedded address, excluding \"isvalid\", metadata (\"timestamp\", \"hdkeypath\", \"hdmasterkeyid\") and relation to the wallet (\"ismine\", \"iswatchonly\", \"account\").\n"
- " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
- " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
- " \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n"
- " \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n"
- " \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n"
+ " \"isscript\" : true|false, (boolean) If the key is a script\n"
+ " \"iswitness\" : true|false, (boolean) If the address is a witness address\n"
+ " \"witness_version\" : version (numeric, optional) The version number of the witness program\n"
+ " \"witness_program\" : \"hex\" (string, optional) The hex value of the witness program\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
+ HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
);
-#ifdef ENABLE_WALLET
- CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
-
- LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr);
-#else
- LOCK(cs_main);
-#endif
-
CTxDestination dest = DecodeDestination(request.params[0].get_str());
bool isValid = IsValidDestination(dest);
@@ -209,45 +67,22 @@ UniValue validateaddress(const JSONRPCRequest& request)
ret.pushKV("isvalid", isValid);
if (isValid)
{
- std::string currentAddress = EncodeDestination(dest);
- ret.pushKV("address", currentAddress);
-
- CScript scriptPubKey = GetScriptForDestination(dest);
- ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
#ifdef ENABLE_WALLET
- isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO;
- ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE));
- ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY));
- UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwallet), dest);
- ret.pushKVs(detail);
- if (pwallet && pwallet->mapAddressBook.count(dest)) {
- ret.pushKV("account", pwallet->mapAddressBook[dest].name);
- }
- if (pwallet) {
- const CKeyMetadata* meta = nullptr;
- CKeyID key_id = GetKeyForDestination(*pwallet, dest);
- if (!key_id.IsNull()) {
- auto it = pwallet->mapKeyMetadata.find(key_id);
- if (it != pwallet->mapKeyMetadata.end()) {
- meta = &it->second;
- }
- }
- if (!meta) {
- auto it = pwallet->m_script_metadata.find(CScriptID(scriptPubKey));
- if (it != pwallet->m_script_metadata.end()) {
- meta = &it->second;
- }
- }
- if (meta) {
- ret.pushKV("timestamp", meta->nCreateTime);
- if (!meta->hdKeypath.empty()) {
- ret.pushKV("hdkeypath", meta->hdKeypath);
- ret.pushKV("hdmasterkeyid", meta->hdMasterKeyID.GetHex());
- }
- }
+ if (!::vpwallets.empty() && IsDeprecatedRPCEnabled("validateaddress")) {
+ ret.pushKVs(getaddressinfo(request));
}
#endif
+ if (ret["address"].isNull()) {
+ std::string currentAddress = EncodeDestination(dest);
+ ret.pushKV("address", currentAddress);
+
+ CScript scriptPubKey = GetScriptForDestination(dest);
+ ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));;
+
+ UniValue detail = DescribeAddress(dest);
+ ret.pushKVs(detail);
+ }
}
return ret;
}
@@ -263,7 +98,7 @@ UniValue createmultisig(const JSONRPCRequest& request)
"\nCreates a multi-signature address with n signature of m keys required.\n"
"It returns a json object with the address and redeemScript.\n"
"\nArguments:\n"
- "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
+ "1. nrequired (numeric, required) The number of required signatures out of the n keys.\n"
"2. \"keys\" (string, required) A json array of hex-encoded public keys\n"
" [\n"
" \"key\" (string) The hex-encoded public key\n"
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 7a0225ff0d..fee2b765ba 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -89,7 +89,7 @@ UniValue getpeerinfo(const JSONRPCRequest& request)
" \"pingtime\": n, (numeric) ping time (if available)\n"
" \"minping\": n, (numeric) minimum observed ping time (if any at all)\n"
" \"pingwait\": n, (numeric) ping wait (if non-zero)\n"
- " \"version\": v, (numeric) The peer version, such as 7001\n"
+ " \"version\": v, (numeric) The peer version, such as 70001\n"
" \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n"
" \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
" \"addnode\": true|false, (boolean) Whether connection was due to addnode/-connect or if it was an automatic/inbound connection\n"
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index ef5f04e4ee..813afde4db 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -17,6 +17,7 @@
#include <policy/policy.h>
#include <policy/rbf.h>
#include <primitives/transaction.h>
+#include <rpc/rawtransaction.h>
#include <rpc/safemode.h>
#include <rpc/server.h>
#include <script/script.h>
@@ -28,7 +29,6 @@
#include <utilstrencodings.h>
#ifdef ENABLE_WALLET
#include <wallet/rpcwallet.h>
-#include <wallet/wallet.h>
#endif
#include <future>
@@ -672,88 +672,13 @@ UniValue combinerawtransaction(const JSONRPCRequest& request)
return EncodeHexTx(mergedTx);
}
-UniValue signrawtransaction(const JSONRPCRequest& request)
+UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival, CBasicKeyStore *keystore, bool is_temp_keystore, const UniValue& hashType)
{
-#ifdef ENABLE_WALLET
- CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
-#endif
-
- if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
- throw std::runtime_error(
- "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
- "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
- "The second optional argument (may be null) is an array of previous transaction outputs that\n"
- "this transaction depends on but may not yet be in the block chain.\n"
- "The third optional argument (may be null) is an array of base58-encoded private\n"
- "keys that, if given, will be the only keys used to sign the transaction.\n"
-#ifdef ENABLE_WALLET
- + HelpRequiringPassphrase(pwallet) + "\n"
-#endif
-
- "\nArguments:\n"
- "1. \"hexstring\" (string, required) The transaction hex string\n"
- "2. \"prevtxs\" (string, optional) A json array of previous dependent transaction outputs\n"
- " [ (json array of json objects, or 'null' if none provided)\n"
- " {\n"
- " \"txid\":\"id\", (string, required) The transaction id\n"
- " \"vout\":n, (numeric, required) The output number\n"
- " \"scriptPubKey\": \"hex\", (string, required) script key\n"
- " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n"
- " \"amount\": value (numeric, required) The amount spent\n"
- " }\n"
- " ,...\n"
- " ]\n"
- "3. \"privkeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
- " [ (json array of strings, or 'null' if none provided)\n"
- " \"privatekey\" (string) private key in base58-encoding\n"
- " ,...\n"
- " ]\n"
- "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
- " \"ALL\"\n"
- " \"NONE\"\n"
- " \"SINGLE\"\n"
- " \"ALL|ANYONECANPAY\"\n"
- " \"NONE|ANYONECANPAY\"\n"
- " \"SINGLE|ANYONECANPAY\"\n"
-
- "\nResult:\n"
- "{\n"
- " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
- " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
- " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
- " {\n"
- " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
- " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
- " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
- " \"sequence\" : n, (numeric) Script sequence number\n"
- " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
- " }\n"
- " ,...\n"
- " ]\n"
- "}\n"
-
- "\nExamples:\n"
- + HelpExampleCli("signrawtransaction", "\"myhex\"")
- + HelpExampleRpc("signrawtransaction", "\"myhex\"")
- );
-
- ObserveSafeMode();
-#ifdef ENABLE_WALLET
- LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr);
-#else
- LOCK(cs_main);
-#endif
- RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
-
- CMutableTransaction mtx;
- if (!DecodeHexTx(mtx, request.params[0].get_str(), true))
- throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
-
// Fetch previous transactions (inputs):
CCoinsView viewDummy;
CCoinsViewCache view(&viewDummy);
{
- LOCK(mempool.cs);
+ LOCK2(cs_main, mempool.cs);
CCoinsViewCache &viewChain = *pcoinsTip;
CCoinsViewMemPool viewMempool(&viewChain, mempool);
view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
@@ -765,36 +690,14 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
}
- bool fGivenKeys = false;
- CBasicKeyStore tempKeystore;
- if (!request.params[2].isNull()) {
- fGivenKeys = true;
- UniValue keys = request.params[2].get_array();
- for (unsigned int idx = 0; idx < keys.size(); idx++) {
- UniValue k = keys[idx];
- CBitcoinSecret vchSecret;
- bool fGood = vchSecret.SetString(k.get_str());
- if (!fGood)
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
- CKey key = vchSecret.GetKey();
- if (!key.IsValid())
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
- tempKeystore.AddKey(key);
- }
- }
-#ifdef ENABLE_WALLET
- else if (pwallet) {
- EnsureWalletIsUnlocked(pwallet);
- }
-#endif
-
// Add previous txouts given in the RPC call:
- if (!request.params[1].isNull()) {
- UniValue prevTxs = request.params[1].get_array();
- for (unsigned int idx = 0; idx < prevTxs.size(); idx++) {
+ if (!prevTxsUnival.isNull()) {
+ UniValue prevTxs = prevTxsUnival.get_array();
+ for (unsigned int idx = 0; idx < prevTxs.size(); ++idx) {
const UniValue& p = prevTxs[idx];
- if (!p.isObject())
+ if (!p.isObject()) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
+ }
UniValue prevOut = p.get_obj();
@@ -808,8 +711,9 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
uint256 txid = ParseHashO(prevOut, "txid");
int nOut = find_value(prevOut, "vout").get_int();
- if (nOut < 0)
+ if (nOut < 0) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
+ }
COutPoint out(txid, nOut);
std::vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
@@ -834,8 +738,8 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
}
// if redeemScript given and not using the local wallet (private keys
- // given), add redeemScript to the tempKeystore so it can be signed:
- if (fGivenKeys && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) {
+ // given), add redeemScript to the keystore so it can be signed:
+ if (is_temp_keystore && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) {
RPCTypeCheckObj(prevOut,
{
{"txid", UniValueType(UniValue::VSTR)},
@@ -847,22 +751,16 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
if (!v.isNull()) {
std::vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
CScript redeemScript(rsData.begin(), rsData.end());
- tempKeystore.AddCScript(redeemScript);
+ keystore->AddCScript(redeemScript);
// Automatically also add the P2WSH wrapped version of the script (to deal with P2SH-P2WSH).
- tempKeystore.AddCScript(GetScriptForWitness(redeemScript));
+ keystore->AddCScript(GetScriptForWitness(redeemScript));
}
}
}
}
-#ifdef ENABLE_WALLET
- const CKeyStore& keystore = ((fGivenKeys || !pwallet) ? tempKeystore : *pwallet);
-#else
- const CKeyStore& keystore = tempKeystore;
-#endif
-
int nHashType = SIGHASH_ALL;
- if (!request.params[3].isNull()) {
+ if (!hashType.isNull()) {
static std::map<std::string, int> mapSigHashValues = {
{std::string("ALL"), int(SIGHASH_ALL)},
{std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
@@ -871,11 +769,12 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
{std::string("SINGLE"), int(SIGHASH_SINGLE)},
{std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
};
- std::string strHashType = request.params[3].get_str();
- if (mapSigHashValues.count(strHashType))
+ std::string strHashType = hashType.get_str();
+ if (mapSigHashValues.count(strHashType)) {
nHashType = mapSigHashValues[strHashType];
- else
+ } else {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
+ }
}
bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
@@ -899,8 +798,9 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
SignatureData sigdata;
// Only sign SIGHASH_SINGLE if there's a corresponding output:
- if (!fHashSingle || (i < mtx.vout.size()))
- ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mtx, i, amount, nHashType), prevPubKey, sigdata);
+ if (!fHashSingle || (i < mtx.vout.size())) {
+ ProduceSignature(MutableTransactionSignatureCreator(keystore, &mtx, i, amount, nHashType), prevPubKey, sigdata);
+ }
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(mtx, i));
UpdateTransaction(mtx, i, sigdata);
@@ -927,6 +827,188 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
return result;
}
+UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
+{
+ if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
+ throw std::runtime_error(
+ "signrawtransactionwithkey \"hexstring\" [\"privatekey1\",...] ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] sighashtype )\n"
+ "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
+ "The second argument is an array of base58-encoded private\n"
+ "keys that will be the only keys used to sign the transaction.\n"
+ "The third optional argument (may be null) is an array of previous transaction outputs that\n"
+ "this transaction depends on but may not yet be in the block chain.\n"
+
+ "\nArguments:\n"
+ "1. \"hexstring\" (string, required) The transaction hex string\n"
+ "2. \"privkeys\" (string, required) A json array of base58-encoded private keys for signing\n"
+ " [ (json array of strings)\n"
+ " \"privatekey\" (string) private key in base58-encoding\n"
+ " ,...\n"
+ " ]\n"
+ "3. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
+ " [ (json array of json objects, or 'null' if none provided)\n"
+ " {\n"
+ " \"txid\":\"id\", (string, required) The transaction id\n"
+ " \"vout\":n, (numeric, required) The output number\n"
+ " \"scriptPubKey\": \"hex\", (string, required) script key\n"
+ " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n"
+ " \"amount\": value (numeric, required) The amount spent\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
+ " \"ALL\"\n"
+ " \"NONE\"\n"
+ " \"SINGLE\"\n"
+ " \"ALL|ANYONECANPAY\"\n"
+ " \"NONE|ANYONECANPAY\"\n"
+ " \"SINGLE|ANYONECANPAY\"\n"
+
+ "\nResult:\n"
+ "{\n"
+ " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
+ " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
+ " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
+ " {\n"
+ " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
+ " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
+ " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
+ " \"sequence\" : n, (numeric) Script sequence number\n"
+ " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ "}\n"
+
+ "\nExamples:\n"
+ + HelpExampleCli("signrawtransactionwithkey", "\"myhex\"")
+ + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\"")
+ );
+
+ RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
+
+ CMutableTransaction mtx;
+ if (!DecodeHexTx(mtx, request.params[0].get_str(), true)) {
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
+ }
+
+ CBasicKeyStore keystore;
+ const UniValue& keys = request.params[1].get_array();
+ for (unsigned int idx = 0; idx < keys.size(); ++idx) {
+ UniValue k = keys[idx];
+ CBitcoinSecret vchSecret;
+ if (!vchSecret.SetString(k.get_str())) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
+ }
+ CKey key = vchSecret.GetKey();
+ if (!key.IsValid()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
+ }
+ keystore.AddKey(key);
+ }
+
+ return SignTransaction(mtx, request.params[2], &keystore, true, request.params[3]);
+}
+
+UniValue signrawtransaction(const JSONRPCRequest& request)
+{
+#ifdef ENABLE_WALLET
+ CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
+#endif
+
+ if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
+ throw std::runtime_error(
+ "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
+ "\nDEPRECATED. Sign inputs for raw transaction (serialized, hex-encoded).\n"
+ "The second optional argument (may be null) is an array of previous transaction outputs that\n"
+ "this transaction depends on but may not yet be in the block chain.\n"
+ "The third optional argument (may be null) is an array of base58-encoded private\n"
+ "keys that, if given, will be the only keys used to sign the transaction.\n"
+#ifdef ENABLE_WALLET
+ + HelpRequiringPassphrase(pwallet) + "\n"
+#endif
+ "\nArguments:\n"
+ "1. \"hexstring\" (string, required) The transaction hex string\n"
+ "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
+ " [ (json array of json objects, or 'null' if none provided)\n"
+ " {\n"
+ " \"txid\":\"id\", (string, required) The transaction id\n"
+ " \"vout\":n, (numeric, required) The output number\n"
+ " \"scriptPubKey\": \"hex\", (string, required) script key\n"
+ " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n"
+ " \"amount\": value (numeric, required) The amount spent\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ "3. \"privkeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
+ " [ (json array of strings, or 'null' if none provided)\n"
+ " \"privatekey\" (string) private key in base58-encoding\n"
+ " ,...\n"
+ " ]\n"
+ "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
+ " \"ALL\"\n"
+ " \"NONE\"\n"
+ " \"SINGLE\"\n"
+ " \"ALL|ANYONECANPAY\"\n"
+ " \"NONE|ANYONECANPAY\"\n"
+ " \"SINGLE|ANYONECANPAY\"\n"
+
+ "\nResult:\n"
+ "{\n"
+ " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
+ " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
+ " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
+ " {\n"
+ " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
+ " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
+ " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
+ " \"sequence\" : n, (numeric) Script sequence number\n"
+ " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ "}\n"
+
+ "\nExamples:\n"
+ + HelpExampleCli("signrawtransaction", "\"myhex\"")
+ + HelpExampleRpc("signrawtransaction", "\"myhex\"")
+ );
+
+ if (!IsDeprecatedRPCEnabled("signrawtransaction")) {
+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "signrawtransaction is deprecated and will be fully removed in v0.18. "
+ "To use signrawtransaction in v0.17, restart bitcoind with -deprecatedrpc=signrawtransaction.\n"
+ "Projects should transition to using signrawtransactionwithkey and signrawtransactionwithwallet before upgrading to v0.18");
+ }
+
+ RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
+
+ // Make a JSONRPCRequest to pass on to the right signrawtransaction* command
+ JSONRPCRequest new_request;
+ new_request.id = request.id;
+ new_request.params.setArray();
+
+ // For signing with private keys
+ if (!request.params[2].isNull()) {
+ new_request.params.push_back(request.params[0]);
+ // Note: the prevtxs and privkeys are reversed for signrawtransactionwithkey
+ new_request.params.push_back(request.params[2]);
+ new_request.params.push_back(request.params[1]);
+ new_request.params.push_back(request.params[3]);
+ return signrawtransactionwithkey(new_request);
+ }
+ // Otherwise sign with the wallet which does not take a privkeys parameter
+#ifdef ENABLE_WALLET
+ else {
+ new_request.params.push_back(request.params[0]);
+ new_request.params.push_back(request.params[1]);
+ new_request.params.push_back(request.params[3]);
+ return signrawtransactionwithwallet(new_request);
+ }
+#endif
+ // If we have made it this far, then wallet is disabled and no private keys were given, so fail here.
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "No private keys available.");
+}
+
UniValue sendrawtransaction(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
@@ -1025,18 +1107,19 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
}
static const CRPCCommand commands[] =
-{ // category name actor (function) argNames
- // --------------------- ------------------------ ----------------------- ----------
- { "rawtransactions", "getrawtransaction", &getrawtransaction, {"txid","verbose","blockhash"} },
- { "rawtransactions", "createrawtransaction", &createrawtransaction, {"inputs","outputs","locktime","replaceable"} },
- { "rawtransactions", "decoderawtransaction", &decoderawtransaction, {"hexstring","iswitness"} },
- { "rawtransactions", "decodescript", &decodescript, {"hexstring"} },
- { "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees"} },
- { "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} },
- { "rawtransactions", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */
-
- { "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} },
- { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} },
+{ // category name actor (function) argNames
+ // --------------------- ------------------------ ----------------------- ----------
+ { "rawtransactions", "getrawtransaction", &getrawtransaction, {"txid","verbose","blockhash"} },
+ { "rawtransactions", "createrawtransaction", &createrawtransaction, {"inputs","outputs","locktime","replaceable"} },
+ { "rawtransactions", "decoderawtransaction", &decoderawtransaction, {"hexstring","iswitness"} },
+ { "rawtransactions", "decodescript", &decodescript, {"hexstring"} },
+ { "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees"} },
+ { "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} },
+ { "rawtransactions", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */
+ { "rawtransactions", "signrawtransactionwithkey", &signrawtransactionwithkey, {"hexstring","privkeys","prevtxs","sighashtype"} },
+
+ { "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} },
+ { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} },
};
void RegisterRawTransactionRPCCommands(CRPCTable &t)
diff --git a/src/rpc/rawtransaction.h b/src/rpc/rawtransaction.h
new file mode 100644
index 0000000000..ec9d1f2cf0
--- /dev/null
+++ b/src/rpc/rawtransaction.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2017 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_RPC_RAWTRANSACTION_H
+#define BITCOIN_RPC_RAWTRANSACTION_H
+
+class CBasicKeyStore;
+struct CMutableTransaction;
+class UniValue;
+
+/** Sign a transaction with the given keystore and previous transactions */
+UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxs, CBasicKeyStore *keystore, bool tempKeystore, const UniValue& hashType);
+
+#endif // BITCOIN_RPC_RAWTRANSACTION_H
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index 09ded4e46e..cdcb68d15f 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -66,3 +66,64 @@ CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey
return result;
}
+
+class DescribeAddressVisitor : public boost::static_visitor<UniValue>
+{
+public:
+ explicit DescribeAddressVisitor() {}
+
+ UniValue operator()(const CNoDestination& dest) const
+ {
+ return UniValue(UniValue::VOBJ);
+ }
+
+ UniValue operator()(const CKeyID& keyID) const
+ {
+ UniValue obj(UniValue::VOBJ);
+ obj.pushKV("isscript", false);
+ obj.pushKV("iswitness", false);
+ return obj;
+ }
+
+ UniValue operator()(const CScriptID& scriptID) const
+ {
+ UniValue obj(UniValue::VOBJ);
+ obj.pushKV("isscript", true);
+ obj.pushKV("iswitness", false);
+ return obj;
+ }
+
+ UniValue operator()(const WitnessV0KeyHash& id) const
+ {
+ UniValue obj(UniValue::VOBJ);
+ obj.pushKV("isscript", false);
+ obj.pushKV("iswitness", true);
+ obj.pushKV("witness_version", 0);
+ obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
+ return obj;
+ }
+
+ UniValue operator()(const WitnessV0ScriptHash& id) const
+ {
+ UniValue obj(UniValue::VOBJ);
+ obj.pushKV("isscript", true);
+ obj.pushKV("iswitness", true);
+ obj.pushKV("witness_version", 0);
+ obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
+ return obj;
+ }
+
+ UniValue operator()(const WitnessUnknown& id) const
+ {
+ UniValue obj(UniValue::VOBJ);
+ obj.pushKV("iswitness", true);
+ obj.pushKV("witness_version", (int)id.version);
+ obj.pushKV("witness_program", HexStr(id.program, id.program + id.length));
+ return obj;
+ }
+};
+
+UniValue DescribeAddress(const CTxDestination& dest)
+{
+ return boost::apply_visitor(DescribeAddressVisitor(), dest);
+}
diff --git a/src/rpc/util.h b/src/rpc/util.h
index 568a4260ba..5380d45a83 100644
--- a/src/rpc/util.h
+++ b/src/rpc/util.h
@@ -5,6 +5,13 @@
#ifndef BITCOIN_RPC_UTIL_H
#define BITCOIN_RPC_UTIL_H
+#include <pubkey.h>
+#include <script/standard.h>
+#include <univalue.h>
+#include <utilstrencodings.h>
+
+#include <boost/variant/static_visitor.hpp>
+
#include <string>
#include <vector>
@@ -16,4 +23,6 @@ CPubKey HexToPubKey(const std::string& hex_in);
CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in);
CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey>& pubkeys);
+UniValue DescribeAddress(const CTxDestination& dest);
+
#endif // BITCOIN_RPC_UTIL_H
diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp
index 42f9dd0600..8e0ec5243b 100644
--- a/src/test/checkqueue_tests.cpp
+++ b/src/test/checkqueue_tests.cpp
@@ -406,11 +406,11 @@ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks)
boost::thread_group tg;
std::mutex m;
std::condition_variable cv;
+ bool has_lock{false};
+ bool has_tried{false};
+ bool done{false};
+ bool done_ack{false};
{
- bool has_lock {false};
- bool has_tried {false};
- bool done {false};
- bool done_ack {false};
std::unique_lock<std::mutex> l(m);
tg.create_thread([&]{
CCheckQueueControl<FakeCheck> control(queue.get());
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index ca57f58905..e03234060d 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
ipv4Addr.s_addr = 0xa0b0c001;
CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK);
- std::string pszDest = "";
+ std::string pszDest;
bool fInboundIn = false;
// Test that fFeeler is false by default.
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index ed86413b2f..108c1a063e 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -69,14 +69,6 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams)
BOOST_CHECK_NO_THROW(r = CallRPC(std::string("decoderawtransaction ")+rawtx+" false"));
BOOST_CHECK_THROW(r = CallRPC(std::string("decoderawtransaction ")+rawtx+" false extra"), std::runtime_error);
- BOOST_CHECK_THROW(CallRPC("signrawtransaction"), std::runtime_error);
- BOOST_CHECK_THROW(CallRPC("signrawtransaction null"), std::runtime_error);
- BOOST_CHECK_THROW(CallRPC("signrawtransaction ff00"), std::runtime_error);
- BOOST_CHECK_NO_THROW(CallRPC(std::string("signrawtransaction ")+rawtx));
- BOOST_CHECK_NO_THROW(CallRPC(std::string("signrawtransaction ")+rawtx+" null null NONE|ANYONECANPAY"));
- BOOST_CHECK_NO_THROW(CallRPC(std::string("signrawtransaction ")+rawtx+" [] [] NONE|ANYONECANPAY"));
- BOOST_CHECK_THROW(CallRPC(std::string("signrawtransaction ")+rawtx+" null null badenum"), std::runtime_error);
-
// Only check failure cases for sendrawtransaction, there's no network to send to...
BOOST_CHECK_THROW(CallRPC("sendrawtransaction"), std::runtime_error);
BOOST_CHECK_THROW(CallRPC("sendrawtransaction null"), std::runtime_error);
@@ -119,9 +111,9 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign)
std::string notsigned = r.get_str();
std::string privkey1 = "\"KzsXybp9jX64P5ekX1KUxRQ79Jht9uzW7LorgwE65i5rWACL6LQe\"";
std::string privkey2 = "\"Kyhdf5LuKTRx4ge69ybABsiUAWjVRK4XGxAKk2FQLp2HjGMy87Z4\"";
- r = CallRPC(std::string("signrawtransaction ")+notsigned+" "+prevout+" "+"[]");
+ r = CallRPC(std::string("signrawtransactionwithkey ")+notsigned+" [] "+prevout);
BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == false);
- r = CallRPC(std::string("signrawtransaction ")+notsigned+" "+prevout+" "+"["+privkey1+","+privkey2+"]");
+ r = CallRPC(std::string("signrawtransactionwithkey ")+notsigned+" ["+privkey1+","+privkey2+"] "+prevout);
BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true);
}
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index bdd44489f4..95c4825b84 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -28,6 +28,9 @@ void CConnmanTest::AddNode(CNode& node)
void CConnmanTest::ClearNodes()
{
LOCK(g_connman->cs_vNodes);
+ for (CNode* node : g_connman->vNodes) {
+ delete node;
+ }
g_connman->vNodes.clear();
}
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 463bed5957..58f033cd89 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -82,6 +82,20 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
"04 67 8a fd b0");
BOOST_CHECK_EQUAL(
+ HexStr(ParseHex_expected + sizeof(ParseHex_expected),
+ ParseHex_expected + sizeof(ParseHex_expected)),
+ "");
+
+ BOOST_CHECK_EQUAL(
+ HexStr(ParseHex_expected + sizeof(ParseHex_expected),
+ ParseHex_expected + sizeof(ParseHex_expected), true),
+ "");
+
+ BOOST_CHECK_EQUAL(
+ HexStr(ParseHex_expected, ParseHex_expected),
+ "");
+
+ BOOST_CHECK_EQUAL(
HexStr(ParseHex_expected, ParseHex_expected, true),
"");
@@ -90,6 +104,58 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
BOOST_CHECK_EQUAL(
HexStr(ParseHex_vec, true),
"04 67 8a fd b0");
+
+ BOOST_CHECK_EQUAL(
+ HexStr(ParseHex_vec.rbegin(), ParseHex_vec.rend()),
+ "b0fd8a6704"
+ );
+
+ BOOST_CHECK_EQUAL(
+ HexStr(ParseHex_vec.rbegin(), ParseHex_vec.rend(), true),
+ "b0 fd 8a 67 04"
+ );
+
+ BOOST_CHECK_EQUAL(
+ HexStr(std::reverse_iterator<const uint8_t *>(ParseHex_expected),
+ std::reverse_iterator<const uint8_t *>(ParseHex_expected)),
+ ""
+ );
+
+ BOOST_CHECK_EQUAL(
+ HexStr(std::reverse_iterator<const uint8_t *>(ParseHex_expected),
+ std::reverse_iterator<const uint8_t *>(ParseHex_expected), true),
+ ""
+ );
+
+ BOOST_CHECK_EQUAL(
+ HexStr(std::reverse_iterator<const uint8_t *>(ParseHex_expected + 1),
+ std::reverse_iterator<const uint8_t *>(ParseHex_expected)),
+ "04"
+ );
+
+ BOOST_CHECK_EQUAL(
+ HexStr(std::reverse_iterator<const uint8_t *>(ParseHex_expected + 1),
+ std::reverse_iterator<const uint8_t *>(ParseHex_expected), true),
+ "04"
+ );
+
+ BOOST_CHECK_EQUAL(
+ HexStr(std::reverse_iterator<const uint8_t *>(ParseHex_expected + 5),
+ std::reverse_iterator<const uint8_t *>(ParseHex_expected)),
+ "b0fd8a6704"
+ );
+
+ BOOST_CHECK_EQUAL(
+ HexStr(std::reverse_iterator<const uint8_t *>(ParseHex_expected + 5),
+ std::reverse_iterator<const uint8_t *>(ParseHex_expected), true),
+ "b0 fd 8a 67 04"
+ );
+
+ BOOST_CHECK_EQUAL(
+ HexStr(std::reverse_iterator<const uint8_t *>(ParseHex_expected + 65),
+ std::reverse_iterator<const uint8_t *>(ParseHex_expected)),
+ "5f1df16b2b704c8a578d0bbaf74d385cde12c11ee50455f3c438ef4c3fbcf649b6de611feae06279a60939e028a8d65c10b73071a6f16719274855feb0fd8a6704"
+ );
}
@@ -688,7 +754,7 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory)
thr.join();
BOOST_CHECK_EQUAL(threadresult, true);
#ifndef WIN32
- // Try to aquire lock in child process while we're holding it, this should fail.
+ // Try to acquire lock in child process while we're holding it, this should fail.
char ch;
BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
@@ -699,7 +765,7 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory)
// Probing lock from our side now should succeed, but not hold on to the lock.
BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true);
- // Try to acquire the lock in the child process, this should be succesful.
+ // Try to acquire the lock in the child process, this should be successful.
BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
BOOST_CHECK_EQUAL((bool)ch, true);
diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp
index 52158e9804..ebafe078f4 100644
--- a/src/utilstrencodings.cpp
+++ b/src/utilstrencodings.cpp
@@ -127,7 +127,7 @@ std::string EncodeBase64(const unsigned char* pch, size_t len)
{
static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- std::string strRet = "";
+ std::string strRet;
strRet.reserve((len+2)/3*4);
int mode=0, left=0;
@@ -267,7 +267,7 @@ std::string EncodeBase32(const unsigned char* pch, size_t len)
{
static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
- std::string strRet="";
+ std::string strRet;
strRet.reserve((len+4)/5*8);
int mode=0, left=0;
diff --git a/src/validation.cpp b/src/validation.cpp
index e809f66e25..d2438b0609 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -4658,6 +4658,7 @@ bool DumpMempool(void)
}
//! Guess how far we are in the verification process at the given block index
+//! require cs_main if pindex has not been validated yet (because nChainTx might be unset)
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pindex) {
if (pindex == nullptr)
return 0.0;
diff --git a/src/wallet/fees.cpp b/src/wallet/fees.cpp
index 73985dcf25..385fdc963a 100644
--- a/src/wallet/fees.cpp
+++ b/src/wallet/fees.cpp
@@ -53,6 +53,9 @@ CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, c
// if we don't have enough data for estimateSmartFee, then use fallbackFee
fee_needed = CWallet::fallbackFee.GetFee(nTxBytes);
if (feeCalc) feeCalc->reason = FeeReason::FALLBACK;
+
+ // directly return if fallback fee is disabled (feerate 0 == disabled)
+ if (CWallet::fallbackFee.GetFee(1000) == 0) return fee_needed;
}
// Obey mempool min fee when using smart fee estimation
CAmount min_mempool_fee = pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nTxBytes);
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index 74036f4f0f..9ac48bff77 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -5,6 +5,7 @@
#include <wallet/init.h>
+#include <chainparams.h>
#include <net.h>
#include <util.h>
#include <utilmoneystr.h>
@@ -123,6 +124,8 @@ bool WalletParameterInteraction()
_("This is the minimum transaction fee you pay on every transaction."));
CWallet::minTxFee = CFeeRate(n);
}
+
+ g_wallet_allow_fallback_fee = Params().IsFallbackFeeEnabled();
if (gArgs.IsArgSet("-fallbackfee"))
{
CAmount nFeePerK = 0;
@@ -132,6 +135,7 @@ bool WalletParameterInteraction()
InitWarning(AmountHighWarn("-fallbackfee") + " " +
_("This is the transaction fee you may pay when fee estimates are not available."));
CWallet::fallbackFee = CFeeRate(nFeePerK);
+ g_wallet_allow_fallback_fee = nFeePerK != 0; //disable fallback fee in case value was set to 0, enable if non-null value
}
if (gArgs.IsArgSet("-discardfee"))
{
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 741ea25340..930e8bbbb4 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -279,7 +279,7 @@ UniValue importaddress(const JSONRPCRequest& request)
);
- std::string strLabel = "";
+ std::string strLabel;
if (!request.params[1].isNull())
strLabel = request.params[1].get_str();
@@ -452,7 +452,7 @@ UniValue importpubkey(const JSONRPCRequest& request)
);
- std::string strLabel = "";
+ std::string strLabel;
if (!request.params[1].isNull())
strLabel = request.params[1].get_str();
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 8f378acd1a..8b95c56a5f 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -16,6 +16,7 @@
#include <policy/policy.h>
#include <policy/rbf.h>
#include <rpc/mining.h>
+#include <rpc/rawtransaction.h>
#include <rpc/safemode.h>
#include <rpc/server.h>
#include <rpc/util.h>
@@ -25,6 +26,7 @@
#include <utilmoneystr.h>
#include <wallet/coincontrol.h>
#include <wallet/feebumper.h>
+#include <wallet/rpcwallet.h>
#include <wallet/wallet.h>
#include <wallet/walletdb.h>
#include <wallet/walletutil.h>
@@ -3235,6 +3237,75 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
return result;
}
+UniValue signrawtransactionwithwallet(const JSONRPCRequest& request)
+{
+ CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
+ return NullUniValue;
+ }
+
+ if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
+ throw std::runtime_error(
+ "signrawtransactionwithwallet \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] sighashtype )\n"
+ "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
+ "The second optional argument (may be null) is an array of previous transaction outputs that\n"
+ "this transaction depends on but may not yet be in the block chain.\n"
+ + HelpRequiringPassphrase(pwallet) + "\n"
+
+ "\nArguments:\n"
+ "1. \"hexstring\" (string, required) The transaction hex string\n"
+ "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
+ " [ (json array of json objects, or 'null' if none provided)\n"
+ " {\n"
+ " \"txid\":\"id\", (string, required) The transaction id\n"
+ " \"vout\":n, (numeric, required) The output number\n"
+ " \"scriptPubKey\": \"hex\", (string, required) script key\n"
+ " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n"
+ " \"amount\": value (numeric, required) The amount spent\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ "3. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
+ " \"ALL\"\n"
+ " \"NONE\"\n"
+ " \"SINGLE\"\n"
+ " \"ALL|ANYONECANPAY\"\n"
+ " \"NONE|ANYONECANPAY\"\n"
+ " \"SINGLE|ANYONECANPAY\"\n"
+
+ "\nResult:\n"
+ "{\n"
+ " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
+ " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
+ " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
+ " {\n"
+ " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
+ " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
+ " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
+ " \"sequence\" : n, (numeric) Script sequence number\n"
+ " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ "}\n"
+
+ "\nExamples:\n"
+ + HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"")
+ + HelpExampleRpc("signrawtransactionwithwallet", "\"myhex\"")
+ );
+
+ RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VSTR}, true);
+
+ CMutableTransaction mtx;
+ if (!DecodeHexTx(mtx, request.params[0].get_str(), true)) {
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
+ }
+
+ // Sign the transaction
+ LOCK2(cs_main, pwallet->cs_wallet);
+ return SignTransaction(mtx, request.params[1], pwallet, false, request.params[2]);
+}
+
UniValue bumpfee(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
@@ -3514,6 +3585,209 @@ UniValue rescanblockchain(const JSONRPCRequest& request)
return response;
}
+class DescribeWalletAddressVisitor : public boost::static_visitor<UniValue>
+{
+public:
+ CWallet * const pwallet;
+
+ void ProcessSubScript(const CScript& subscript, UniValue& obj, bool include_addresses = false) const
+ {
+ // Always present: script type and redeemscript
+ txnouttype which_type;
+ std::vector<std::vector<unsigned char>> solutions_data;
+ Solver(subscript, which_type, solutions_data);
+ obj.pushKV("script", GetTxnOutputType(which_type));
+ obj.pushKV("hex", HexStr(subscript.begin(), subscript.end()));
+
+ CTxDestination embedded;
+ UniValue a(UniValue::VARR);
+ if (ExtractDestination(subscript, embedded)) {
+ // Only when the script corresponds to an address.
+ UniValue subobj(UniValue::VOBJ);
+ UniValue detail = DescribeAddress(embedded);
+ subobj.pushKVs(detail);
+ UniValue wallet_detail = boost::apply_visitor(*this, embedded);
+ subobj.pushKVs(wallet_detail);
+ subobj.pushKV("address", EncodeDestination(embedded));
+ subobj.pushKV("scriptPubKey", HexStr(subscript.begin(), subscript.end()));
+ // Always report the pubkey at the top level, so that `getnewaddress()['pubkey']` always works.
+ if (subobj.exists("pubkey")) obj.pushKV("pubkey", subobj["pubkey"]);
+ obj.pushKV("embedded", std::move(subobj));
+ if (include_addresses) a.push_back(EncodeDestination(embedded));
+ } else if (which_type == TX_MULTISIG) {
+ // Also report some information on multisig scripts (which do not have a corresponding address).
+ // TODO: abstract out the common functionality between this logic and ExtractDestinations.
+ obj.pushKV("sigsrequired", solutions_data[0][0]);
+ UniValue pubkeys(UniValue::VARR);
+ for (size_t i = 1; i < solutions_data.size() - 1; ++i) {
+ CPubKey key(solutions_data[i].begin(), solutions_data[i].end());
+ if (include_addresses) a.push_back(EncodeDestination(key.GetID()));
+ pubkeys.push_back(HexStr(key.begin(), key.end()));
+ }
+ obj.pushKV("pubkeys", std::move(pubkeys));
+ }
+
+ // The "addresses" field is confusing because it refers to public keys using their P2PKH address.
+ // For that reason, only add the 'addresses' field when needed for backward compatibility. New applications
+ // can use the 'embedded'->'address' field for P2SH or P2WSH wrapped addresses, and 'pubkeys' for
+ // inspecting multisig participants.
+ if (include_addresses) obj.pushKV("addresses", std::move(a));
+ }
+
+ explicit DescribeWalletAddressVisitor(CWallet* _pwallet) : pwallet(_pwallet) {}
+
+ UniValue operator()(const CNoDestination& dest) const { return UniValue(UniValue::VOBJ); }
+
+ UniValue operator()(const CKeyID& keyID) const
+ {
+ UniValue obj(UniValue::VOBJ);
+ CPubKey vchPubKey;
+ if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) {
+ obj.pushKV("pubkey", HexStr(vchPubKey));
+ obj.pushKV("iscompressed", vchPubKey.IsCompressed());
+ }
+ return obj;
+ }
+
+ UniValue operator()(const CScriptID& scriptID) const
+ {
+ UniValue obj(UniValue::VOBJ);
+ CScript subscript;
+ if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
+ ProcessSubScript(subscript, obj, IsDeprecatedRPCEnabled("validateaddress"));
+ }
+ return obj;
+ }
+
+ UniValue operator()(const WitnessV0KeyHash& id) const
+ {
+ UniValue obj(UniValue::VOBJ);
+ CPubKey pubkey;
+ if (pwallet && pwallet->GetPubKey(CKeyID(id), pubkey)) {
+ obj.pushKV("pubkey", HexStr(pubkey));
+ }
+ return obj;
+ }
+
+ UniValue operator()(const WitnessV0ScriptHash& id) const
+ {
+ UniValue obj(UniValue::VOBJ);
+ CScript subscript;
+ CRIPEMD160 hasher;
+ uint160 hash;
+ hasher.Write(id.begin(), 32).Finalize(hash.begin());
+ if (pwallet && pwallet->GetCScript(CScriptID(hash), subscript)) {
+ ProcessSubScript(subscript, obj);
+ }
+ return obj;
+ }
+
+ UniValue operator()(const WitnessUnknown& id) const { return UniValue(UniValue::VOBJ); }
+};
+
+UniValue DescribeWalletAddress(CWallet* pwallet, const CTxDestination& dest)
+{
+ UniValue ret(UniValue::VOBJ);
+ UniValue detail = DescribeAddress(dest);
+ ret.pushKVs(detail);
+ ret.pushKVs(boost::apply_visitor(DescribeWalletAddressVisitor(pwallet), dest));
+ return ret;
+}
+
+UniValue getaddressinfo(const JSONRPCRequest& request)
+{
+ CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
+ return NullUniValue;
+ }
+
+ if (request.fHelp || request.params.size() != 1) {
+ throw std::runtime_error(
+ "getaddressinfo \"address\"\n"
+ "\nReturn information about the given bitcoin address. Some information requires the address\n"
+ "to be in the wallet.\n"
+ "\nArguments:\n"
+ "1. \"address\" (string, required) The bitcoin address to get the information of.\n"
+ "\nResult:\n"
+ "{\n"
+ " \"address\" : \"address\", (string) The bitcoin address validated\n"
+ " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
+ " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
+ " \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n"
+ " \"isscript\" : true|false, (boolean) If the key is a script\n"
+ " \"iswitness\" : true|false, (boolean) If the address is a witness address\n"
+ " \"witness_version\" : version (numeric, optional) The version number of the witness program\n"
+ " \"witness_program\" : \"hex\" (string, optional) The hex value of the witness program\n"
+ " \"script\" : \"type\" (string, optional) The output script type. Only if \"isscript\" is true and the redeemscript is known. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash, witness_unknown\n"
+ " \"hex\" : \"hex\", (string, optional) The redeemscript for the p2sh address\n"
+ " \"pubkeys\" (string, optional) Array of pubkeys associated with the known redeemscript (only if \"script\" is \"multisig\")\n"
+ " [\n"
+ " \"pubkey\"\n"
+ " ,...\n"
+ " ]\n"
+ " \"sigsrequired\" : xxxxx (numeric, optional) Number of signatures required to spend multisig output (only if \"script\" is \"multisig\")\n"
+ " \"pubkey\" : \"publickeyhex\", (string, optional) The hex value of the raw public key, for single-key addresses (possibly embedded in P2SH or P2WSH)\n"
+ " \"embedded\" : {...}, (object, optional) Information about the address embedded in P2SH or P2WSH, if relevant and known. It includes all getaddressinfo output fields for the embedded address, excluding metadata (\"timestamp\", \"hdkeypath\", \"hdmasterkeyid\") and relation to the wallet (\"ismine\", \"iswatchonly\", \"account\").\n"
+ " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
+ " \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n"
+ " \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n"
+ " \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n"
+ " \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getaddressinfo", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
+ + HelpExampleRpc("getaddressinfo", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
+ );
+ }
+
+ LOCK(pwallet->cs_wallet);
+
+ UniValue ret(UniValue::VOBJ);
+ CTxDestination dest = DecodeDestination(request.params[0].get_str());
+
+ // Make sure the destination is valid
+ if (!IsValidDestination(dest)) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
+ }
+
+ std::string currentAddress = EncodeDestination(dest);
+ ret.pushKV("address", currentAddress);
+
+ CScript scriptPubKey = GetScriptForDestination(dest);
+ ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
+
+ isminetype mine = IsMine(*pwallet, dest);
+ ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE));
+ ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY));
+ UniValue detail = DescribeWalletAddress(pwallet, dest);
+ ret.pushKVs(detail);
+ if (pwallet->mapAddressBook.count(dest)) {
+ ret.pushKV("account", pwallet->mapAddressBook[dest].name);
+ }
+ const CKeyMetadata* meta = nullptr;
+ CKeyID key_id = GetKeyForDestination(*pwallet, dest);
+ if (!key_id.IsNull()) {
+ auto it = pwallet->mapKeyMetadata.find(key_id);
+ if (it != pwallet->mapKeyMetadata.end()) {
+ meta = &it->second;
+ }
+ }
+ if (!meta) {
+ auto it = pwallet->m_script_metadata.find(CScriptID(scriptPubKey));
+ if (it != pwallet->m_script_metadata.end()) {
+ meta = &it->second;
+ }
+ }
+ if (meta) {
+ ret.pushKV("timestamp", meta->nCreateTime);
+ if (!meta->hdKeypath.empty()) {
+ ret.pushKV("hdkeypath", meta->hdKeypath);
+ ret.pushKV("hdmasterkeyid", meta->hdMasterKeyID.GetHex());
+ }
+ }
+ return ret;
+}
+
extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp
extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
extern UniValue importprivkey(const JSONRPCRequest& request);
@@ -3527,61 +3801,63 @@ extern UniValue importmulti(const JSONRPCRequest& request);
extern UniValue rescanblockchain(const JSONRPCRequest& request);
static const CRPCCommand commands[] =
-{ // category name actor (function) argNames
- // --------------------- ------------------------ ----------------------- ----------
- { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options","iswitness"} },
- { "hidden", "resendwallettransactions", &resendwallettransactions, {} },
- { "wallet", "abandontransaction", &abandontransaction, {"txid"} },
- { "wallet", "abortrescan", &abortrescan, {} },
- { "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","account","address_type"} },
- { "hidden", "addwitnessaddress", &addwitnessaddress, {"address","p2sh"} },
- { "wallet", "backupwallet", &backupwallet, {"destination"} },
- { "wallet", "bumpfee", &bumpfee, {"txid", "options"} },
- { "wallet", "dumpprivkey", &dumpprivkey, {"address"} },
- { "wallet", "dumpwallet", &dumpwallet, {"filename"} },
- { "wallet", "encryptwallet", &encryptwallet, {"passphrase"} },
- { "wallet", "getaccountaddress", &getaccountaddress, {"account"} },
- { "wallet", "getaccount", &getaccount, {"address"} },
- { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
- { "wallet", "getbalance", &getbalance, {"account","minconf","include_watchonly"} },
- { "wallet", "getnewaddress", &getnewaddress, {"account","address_type"} },
- { "wallet", "getrawchangeaddress", &getrawchangeaddress, {"address_type"} },
- { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, {"account","minconf"} },
- { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} },
- { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} },
- { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} },
- { "wallet", "getwalletinfo", &getwalletinfo, {} },
- { "wallet", "importmulti", &importmulti, {"requests","options"} },
- { "wallet", "importprivkey", &importprivkey, {"privkey","label","rescan"} },
- { "wallet", "importwallet", &importwallet, {"filename"} },
- { "wallet", "importaddress", &importaddress, {"address","label","rescan","p2sh"} },
- { "wallet", "importprunedfunds", &importprunedfunds, {"rawtransaction","txoutproof"} },
- { "wallet", "importpubkey", &importpubkey, {"pubkey","label","rescan"} },
- { "wallet", "keypoolrefill", &keypoolrefill, {"newsize"} },
- { "wallet", "listaccounts", &listaccounts, {"minconf","include_watchonly"} },
- { "wallet", "listaddressgroupings", &listaddressgroupings, {} },
- { "wallet", "listlockunspent", &listlockunspent, {} },
- { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, {"minconf","include_empty","include_watchonly"} },
- { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, {"minconf","include_empty","include_watchonly"} },
- { "wallet", "listsinceblock", &listsinceblock, {"blockhash","target_confirmations","include_watchonly","include_removed"} },
- { "wallet", "listtransactions", &listtransactions, {"account","count","skip","include_watchonly"} },
- { "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
- { "wallet", "listwallets", &listwallets, {} },
- { "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} },
- { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} },
- { "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
- { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} },
- { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} },
- { "wallet", "setaccount", &setaccount, {"address","account"} },
- { "wallet", "settxfee", &settxfee, {"amount"} },
- { "wallet", "signmessage", &signmessage, {"address","message"} },
- { "wallet", "walletlock", &walletlock, {} },
- { "wallet", "walletpassphrasechange", &walletpassphrasechange, {"oldpassphrase","newpassphrase"} },
- { "wallet", "walletpassphrase", &walletpassphrase, {"passphrase","timeout"} },
- { "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} },
- { "wallet", "rescanblockchain", &rescanblockchain, {"start_height", "stop_height"} },
-
- { "generating", "generate", &generate, {"nblocks","maxtries"} },
+{ // category name actor (function) argNames
+ // --------------------- ------------------------ ----------------------- ----------
+ { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options","iswitness"} },
+ { "hidden", "resendwallettransactions", &resendwallettransactions, {} },
+ { "wallet", "abandontransaction", &abandontransaction, {"txid"} },
+ { "wallet", "abortrescan", &abortrescan, {} },
+ { "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","account","address_type"} },
+ { "hidden", "addwitnessaddress", &addwitnessaddress, {"address","p2sh"} },
+ { "wallet", "backupwallet", &backupwallet, {"destination"} },
+ { "wallet", "bumpfee", &bumpfee, {"txid", "options"} },
+ { "wallet", "dumpprivkey", &dumpprivkey, {"address"} },
+ { "wallet", "dumpwallet", &dumpwallet, {"filename"} },
+ { "wallet", "encryptwallet", &encryptwallet, {"passphrase"} },
+ { "wallet", "getaccountaddress", &getaccountaddress, {"account"} },
+ { "wallet", "getaccount", &getaccount, {"address"} },
+ { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
+ { "wallet", "getaddressinfo", &getaddressinfo, {"address"} },
+ { "wallet", "getbalance", &getbalance, {"account","minconf","include_watchonly"} },
+ { "wallet", "getnewaddress", &getnewaddress, {"account","address_type"} },
+ { "wallet", "getrawchangeaddress", &getrawchangeaddress, {"address_type"} },
+ { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, {"account","minconf"} },
+ { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} },
+ { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} },
+ { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} },
+ { "wallet", "getwalletinfo", &getwalletinfo, {} },
+ { "wallet", "importmulti", &importmulti, {"requests","options"} },
+ { "wallet", "importprivkey", &importprivkey, {"privkey","label","rescan"} },
+ { "wallet", "importwallet", &importwallet, {"filename"} },
+ { "wallet", "importaddress", &importaddress, {"address","label","rescan","p2sh"} },
+ { "wallet", "importprunedfunds", &importprunedfunds, {"rawtransaction","txoutproof"} },
+ { "wallet", "importpubkey", &importpubkey, {"pubkey","label","rescan"} },
+ { "wallet", "keypoolrefill", &keypoolrefill, {"newsize"} },
+ { "wallet", "listaccounts", &listaccounts, {"minconf","include_watchonly"} },
+ { "wallet", "listaddressgroupings", &listaddressgroupings, {} },
+ { "wallet", "listlockunspent", &listlockunspent, {} },
+ { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, {"minconf","include_empty","include_watchonly"} },
+ { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, {"minconf","include_empty","include_watchonly"} },
+ { "wallet", "listsinceblock", &listsinceblock, {"blockhash","target_confirmations","include_watchonly","include_removed"} },
+ { "wallet", "listtransactions", &listtransactions, {"account","count","skip","include_watchonly"} },
+ { "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
+ { "wallet", "listwallets", &listwallets, {} },
+ { "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} },
+ { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} },
+ { "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
+ { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} },
+ { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} },
+ { "wallet", "setaccount", &setaccount, {"address","account"} },
+ { "wallet", "settxfee", &settxfee, {"amount"} },
+ { "wallet", "signmessage", &signmessage, {"address","message"} },
+ { "wallet", "signrawtransactionwithwallet", &signrawtransactionwithwallet, {"hexstring","prevtxs","sighashtype"} },
+ { "wallet", "walletlock", &walletlock, {} },
+ { "wallet", "walletpassphrasechange", &walletpassphrasechange, {"oldpassphrase","newpassphrase"} },
+ { "wallet", "walletpassphrase", &walletpassphrase, {"passphrase","timeout"} },
+ { "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} },
+ { "wallet", "rescanblockchain", &rescanblockchain, {"start_height", "stop_height"} },
+
+ { "generating", "generate", &generate, {"nblocks","maxtries"} },
};
void RegisterWalletRPCCommands(CRPCTable &t)
diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h
index 77f7b42b23..84f161abb5 100644
--- a/src/wallet/rpcwallet.h
+++ b/src/wallet/rpcwallet.h
@@ -10,6 +10,7 @@
class CRPCTable;
class CWallet;
class JSONRPCRequest;
+class UniValue;
void RegisterWalletRPCCommands(CRPCTable &t);
@@ -25,4 +26,6 @@ std::string HelpRequiringPassphrase(CWallet *);
void EnsureWalletIsUnlocked(CWallet *);
bool EnsureWalletIsAvailable(CWallet *, bool avoidException);
+UniValue getaddressinfo(const JSONRPCRequest& request);
+UniValue signrawtransactionwithwallet(const JSONRPCRequest& request);
#endif //BITCOIN_WALLET_RPCWALLET_H
diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp
index 7797f85f07..18abf9a9db 100644
--- a/src/wallet/test/wallet_test_fixture.cpp
+++ b/src/wallet/test/wallet_test_fixture.cpp
@@ -11,7 +11,6 @@ WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
TestingSetup(chainName)
{
bitdb.MakeMock();
-
bool fFirstRun;
g_address_type = OUTPUT_TYPE_DEFAULT;
g_change_type = OUTPUT_TYPE_DEFAULT;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 408a01c50b..bb7be2df33 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -43,6 +43,7 @@ bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE;
bool fWalletRbf = DEFAULT_WALLET_RBF;
OutputType g_address_type = OUTPUT_TYPE_NONE;
OutputType g_change_type = OUTPUT_TYPE_NONE;
+bool g_wallet_allow_fallback_fee = true; //<! will be defined via chainparams
const char * DEFAULT_WALLET_DAT = "wallet.dat";
const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
@@ -1668,20 +1669,15 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
dProgressStart = GuessVerificationProgress(chainParams.TxData(), pindex);
dProgressTip = GuessVerificationProgress(chainParams.TxData(), tip);
}
+ double gvp = dProgressStart;
while (pindex && !fAbortRescan)
{
if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0) {
- double gvp = 0;
- {
- LOCK(cs_main);
- gvp = GuessVerificationProgress(chainParams.TxData(), pindex);
- }
ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((gvp - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
}
if (GetTime() >= nNow + 60) {
nNow = GetTime();
- LOCK(cs_main);
- LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));
+ LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, gvp);
}
CBlock block;
@@ -1705,6 +1701,7 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
{
LOCK(cs_main);
pindex = chainActive.Next(pindex);
+ gvp = GuessVerificationProgress(chainParams.TxData(), pindex);
if (tip != chainActive.Tip()) {
tip = chainActive.Tip();
// in case the tip has changed, update progress max
@@ -1713,7 +1710,7 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
}
}
if (pindex && fAbortRescan) {
- LogPrintf("Rescan aborted at block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));
+ LogPrintf("Rescan aborted at block %d. Progress=%f\n", pindex->nHeight, gvp);
}
ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
}
@@ -2922,6 +2919,11 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
}
nFeeNeeded = GetMinimumFee(nBytes, coin_control, ::mempool, ::feeEstimator, &feeCalc);
+ if (feeCalc.reason == FeeReason::FALLBACK && !g_wallet_allow_fallback_fee) {
+ // eventually allow a fallback fee
+ strFailReason = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.");
+ return false;
+ }
// If we made it here and we aren't even able to meet the relay fee on the next pass, give up
// because we must be at the maximum allowed fee.
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index fefe415bb1..4db45f16ef 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -39,6 +39,7 @@ extern CFeeRate payTxFee;
extern unsigned int nTxConfirmTarget;
extern bool bSpendZeroConfChange;
extern bool fWalletRbf;
+extern bool g_wallet_allow_fallback_fee;
static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
//! -paytxfee default
diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py
index 94b13653b9..e5db9e18c7 100755
--- a/test/functional/feature_bip68_sequence.py
+++ b/test/functional/feature_bip68_sequence.py
@@ -14,7 +14,7 @@ SEQUENCE_LOCKTIME_GRANULARITY = 9 # this is a bit-shift
SEQUENCE_LOCKTIME_MASK = 0x0000ffff
# RPC error for non-BIP68 final transactions
-NOT_FINAL_ERROR = "64: non-BIP68-final"
+NOT_FINAL_ERROR = "non-BIP68-final (code 64)"
class BIP68Test(BitcoinTestFramework):
def set_test_params(self):
@@ -70,7 +70,7 @@ class BIP68Test(BitcoinTestFramework):
tx1.vin = [CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), nSequence=sequence_value)]
tx1.vout = [CTxOut(value, CScript([b'a']))]
- tx1_signed = self.nodes[0].signrawtransaction(ToHex(tx1))["hex"]
+ tx1_signed = self.nodes[0].signrawtransactionwithwallet(ToHex(tx1))["hex"]
tx1_id = self.nodes[0].sendrawtransaction(tx1_signed)
tx1_id = int(tx1_id, 16)
@@ -176,7 +176,7 @@ class BIP68Test(BitcoinTestFramework):
# Overestimate the size of the tx - signatures should be less than 120 bytes, and leave 50 for the output
tx_size = len(ToHex(tx))//2 + 120*num_inputs + 50
tx.vout.append(CTxOut(int(value-self.relayfee*tx_size*COIN/1000), CScript([b'a'])))
- rawtx = self.nodes[0].signrawtransaction(ToHex(tx))["hex"]
+ rawtx = self.nodes[0].signrawtransactionwithwallet(ToHex(tx))["hex"]
if (using_sequence_locks and not should_pass):
# This transaction should be rejected
@@ -205,7 +205,7 @@ class BIP68Test(BitcoinTestFramework):
tx2.nVersion = 2
tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)]
tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))]
- tx2_raw = self.nodes[0].signrawtransaction(ToHex(tx2))["hex"]
+ tx2_raw = self.nodes[0].signrawtransactionwithwallet(ToHex(tx2))["hex"]
tx2 = FromHex(tx2, tx2_raw)
tx2.rehash()
@@ -278,7 +278,7 @@ class BIP68Test(BitcoinTestFramework):
utxos = self.nodes[0].listunspent()
tx5.vin.append(CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["vout"]), nSequence=1))
tx5.vout[0].nValue += int(utxos[0]["amount"]*COIN)
- raw_tx5 = self.nodes[0].signrawtransaction(ToHex(tx5))["hex"]
+ raw_tx5 = self.nodes[0].signrawtransactionwithwallet(ToHex(tx5))["hex"]
assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, raw_tx5)
@@ -338,7 +338,7 @@ class BIP68Test(BitcoinTestFramework):
tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))]
# sign tx2
- tx2_raw = self.nodes[0].signrawtransaction(ToHex(tx2))["hex"]
+ tx2_raw = self.nodes[0].signrawtransactionwithwallet(ToHex(tx2))["hex"]
tx2 = FromHex(tx2, tx2_raw)
tx2.rehash()
@@ -388,7 +388,7 @@ class BIP68Test(BitcoinTestFramework):
rawtxfund = self.nodes[1].fundrawtransaction(rawtx)['hex']
tx = FromHex(CTransaction(), rawtxfund)
tx.nVersion = 2
- tx_signed = self.nodes[1].signrawtransaction(ToHex(tx))["hex"]
+ tx_signed = self.nodes[1].signrawtransactionwithwallet(ToHex(tx))["hex"]
self.nodes[1].sendrawtransaction(tx_signed)
if __name__ == '__main__':
diff --git a/test/functional/feature_bip9_softforks.py b/test/functional/feature_bip9_softforks.py
index ae92e9f07c..71d3d04002 100755
--- a/test/functional/feature_bip9_softforks.py
+++ b/test/functional/feature_bip9_softforks.py
@@ -51,7 +51,7 @@ class BIP9SoftForksTest(ComparisonTestFramework):
return tx
def sign_transaction(self, node, tx):
- signresult = node.signrawtransaction(bytes_to_hex_str(tx.serialize()))
+ signresult = node.signrawtransactionwithwallet(bytes_to_hex_str(tx.serialize()))
tx = CTransaction()
f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f)
diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py
index f62ae31654..e9a8945e76 100755
--- a/test/functional/feature_cltv.py
+++ b/test/functional/feature_cltv.py
@@ -41,7 +41,7 @@ def cltv_validate(node, tx, height):
tx.nLockTime = height
# Need to re-sign, since nSequence and nLockTime changed
- signed_result = node.signrawtransaction(ToHex(tx))
+ signed_result = node.signrawtransactionwithwallet(ToHex(tx))
new_tx = CTransaction()
new_tx.deserialize(BytesIO(hex_str_to_bytes(signed_result['hex'])))
@@ -54,7 +54,7 @@ def create_transaction(node, coinbase, to_address, amount):
inputs = [{ "txid" : from_txid, "vout" : 0}]
outputs = { to_address : amount }
rawtx = node.createrawtransaction(inputs, outputs)
- signresult = node.signrawtransaction(rawtx)
+ signresult = node.signrawtransactionwithwallet(rawtx)
tx = CTransaction()
tx.deserialize(BytesIO(hex_str_to_bytes(signresult['hex'])))
return tx
diff --git a/test/functional/feature_csv_activation.py b/test/functional/feature_csv_activation.py
index 82aa0ff891..8b5e5681e4 100755
--- a/test/functional/feature_csv_activation.py
+++ b/test/functional/feature_csv_activation.py
@@ -118,7 +118,7 @@ class BIP68_112_113Test(ComparisonTestFramework):
def sign_transaction(self, node, unsignedtx):
rawtx = ToHex(unsignedtx)
- signresult = node.signrawtransaction(rawtx)
+ signresult = node.signrawtransactionwithwallet(rawtx)
tx = CTransaction()
f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f)
diff --git a/test/functional/feature_dbcrash.py b/test/functional/feature_dbcrash.py
index 24b9765b4e..cef257cf9b 100755
--- a/test/functional/feature_dbcrash.py
+++ b/test/functional/feature_dbcrash.py
@@ -206,7 +206,7 @@ class ChainstateWriteCrashTest(BitcoinTestFramework):
tx.vout.append(CTxOut(output_amount, hex_str_to_bytes(utxo['scriptPubKey'])))
# Sign and send the transaction to get into the mempool
- tx_signed_hex = node.signrawtransaction(ToHex(tx))['hex']
+ tx_signed_hex = node.signrawtransactionwithwallet(ToHex(tx))['hex']
node.sendrawtransaction(tx_signed_hex)
num_transactions += 1
diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py
index 3414571678..02dcc3e55d 100755
--- a/test/functional/feature_dersig.py
+++ b/test/functional/feature_dersig.py
@@ -42,7 +42,7 @@ def create_transaction(node, coinbase, to_address, amount):
inputs = [{ "txid" : from_txid, "vout" : 0}]
outputs = { to_address : amount }
rawtx = node.createrawtransaction(inputs, outputs)
- signresult = node.signrawtransaction(rawtx)
+ signresult = node.signrawtransactionwithwallet(rawtx)
tx = CTransaction()
tx.deserialize(BytesIO(hex_str_to_bytes(signresult['hex'])))
return tx
diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py
index e1263414bd..8a56d3eefa 100755
--- a/test/functional/feature_fee_estimation.py
+++ b/test/functional/feature_fee_estimation.py
@@ -91,7 +91,7 @@ def split_inputs(from_node, txins, txouts, initial_split=False):
# If this is the initial split we actually need to sign the transaction
# Otherwise we just need to insert the proper ScriptSig
if (initial_split):
- completetx = from_node.signrawtransaction(ToHex(tx))["hex"]
+ completetx = from_node.signrawtransactionwithwallet(ToHex(tx))["hex"]
else:
tx.vin[0].scriptSig = SCRIPT_SIG[prevtxout["vout"]]
completetx = ToHex(tx)
diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py
index 740c498ce6..7db6a03b45 100755
--- a/test/functional/feature_nulldummy.py
+++ b/test/functional/feature_nulldummy.py
@@ -102,7 +102,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
inputs = [{ "txid" : txid, "vout" : 0}]
outputs = { to_address : amount }
rawtx = node.createrawtransaction(inputs, outputs)
- signresult = node.signrawtransaction(rawtx)
+ signresult = node.signrawtransactionwithwallet(rawtx)
tx = CTransaction()
f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f)
diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py
index 6b7ab0f43e..d6ab5ecc37 100755
--- a/test/functional/feature_rbf.py
+++ b/test/functional/feature_rbf.py
@@ -42,7 +42,7 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
tx2.vout = [CTxOut(amount, scriptPubKey)]
tx2.rehash()
- signed_tx = node.signrawtransaction(txToHex(tx2))
+ signed_tx = node.signrawtransactionwithwallet(txToHex(tx2))
txid = node.sendrawtransaction(signed_tx['hex'], True)
diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py
index 7db05077c9..fa1732c4c5 100755
--- a/test/functional/feature_segwit.py
+++ b/test/functional/feature_segwit.py
@@ -96,7 +96,7 @@ class SegWitTest(BitcoinTestFramework):
wit_ids = [] # wit_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE via bare witness
for i in range(3):
newaddress = self.nodes[i].getnewaddress()
- self.pubkey.append(self.nodes[i].validateaddress(newaddress)["pubkey"])
+ self.pubkey.append(self.nodes[i].getaddressinfo(newaddress)["pubkey"])
multiscript = CScript([OP_1, hex_str_to_bytes(self.pubkey[-1]), OP_1, OP_CHECKMULTISIG])
p2sh_addr = self.nodes[i].addwitnessaddress(newaddress)
bip173_addr = self.nodes[i].addwitnessaddress(newaddress, False)
@@ -221,7 +221,7 @@ class SegWitTest(BitcoinTestFramework):
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(int(txid1, 16), 0), b''))
tx.vout.append(CTxOut(int(49.99*COIN), CScript([OP_TRUE])))
- tx2_hex = self.nodes[0].signrawtransaction(ToHex(tx))['hex']
+ tx2_hex = self.nodes[0].signrawtransactionwithwallet(ToHex(tx))['hex']
txid2 = self.nodes[0].sendrawtransaction(tx2_hex)
tx = FromHex(CTransaction(), tx2_hex)
assert(not tx.wit.is_null())
@@ -274,8 +274,8 @@ class SegWitTest(BitcoinTestFramework):
uncompressed_spendable_address = ["mvozP4UwyGD2mGZU4D2eMvMLPB9WkMmMQu"]
self.nodes[0].importprivkey("cNC8eQ5dg3mFAVePDX4ddmPYpPbw41r9bm2jd1nLJT77e6RrzTRR")
compressed_spendable_address = ["mmWQubrDomqpgSYekvsU7HWEVjLFHAakLe"]
- assert ((self.nodes[0].validateaddress(uncompressed_spendable_address[0])['iscompressed'] == False))
- assert ((self.nodes[0].validateaddress(compressed_spendable_address[0])['iscompressed'] == True))
+ assert ((self.nodes[0].getaddressinfo(uncompressed_spendable_address[0])['iscompressed'] == False))
+ assert ((self.nodes[0].getaddressinfo(compressed_spendable_address[0])['iscompressed'] == True))
self.nodes[0].importpubkey(pubkeys[0])
compressed_solvable_address = [key_to_p2pkh(pubkeys[0])]
@@ -308,7 +308,7 @@ class SegWitTest(BitcoinTestFramework):
solvable_after_importaddress.append(CScript([OP_HASH160, hash160(script), OP_EQUAL]))
for i in compressed_spendable_address:
- v = self.nodes[0].validateaddress(i)
+ v = self.nodes[0].getaddressinfo(i)
if (v['isscript']):
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
# bare and p2sh multisig with compressed keys should always be spendable
@@ -325,7 +325,7 @@ class SegWitTest(BitcoinTestFramework):
spendable_anytime.extend([p2wpkh, p2sh_p2wpkh])
for i in uncompressed_spendable_address:
- v = self.nodes[0].validateaddress(i)
+ v = self.nodes[0].getaddressinfo(i)
if (v['isscript']):
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
# bare and p2sh multisig with uncompressed keys should always be spendable
@@ -342,7 +342,7 @@ class SegWitTest(BitcoinTestFramework):
unseen_anytime.extend([p2wpkh, p2sh_p2wpkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh])
for i in compressed_solvable_address:
- v = self.nodes[0].validateaddress(i)
+ v = self.nodes[0].getaddressinfo(i)
if (v['isscript']):
# Multisig without private is not seen after addmultisigaddress, but seen after importaddress
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
@@ -355,7 +355,7 @@ class SegWitTest(BitcoinTestFramework):
solvable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh])
for i in uncompressed_solvable_address:
- v = self.nodes[0].validateaddress(i)
+ v = self.nodes[0].getaddressinfo(i)
if (v['isscript']):
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
# Base uncompressed multisig without private is not seen after addmultisigaddress, but seen after importaddress
@@ -395,7 +395,7 @@ class SegWitTest(BitcoinTestFramework):
importlist = []
for i in compressed_spendable_address + uncompressed_spendable_address + compressed_solvable_address + uncompressed_solvable_address:
- v = self.nodes[0].validateaddress(i)
+ v = self.nodes[0].getaddressinfo(i)
if (v['isscript']):
bare = hex_str_to_bytes(v['hex'])
importlist.append(bytes_to_hex_str(bare))
@@ -473,7 +473,7 @@ class SegWitTest(BitcoinTestFramework):
premature_witaddress = []
for i in compressed_spendable_address:
- v = self.nodes[0].validateaddress(i)
+ v = self.nodes[0].getaddressinfo(i)
if (v['isscript']):
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
# P2WSH and P2SH(P2WSH) multisig with compressed keys are spendable after addwitnessaddress
@@ -485,7 +485,7 @@ class SegWitTest(BitcoinTestFramework):
spendable_anytime.extend([p2wpkh, p2sh_p2wpkh])
for i in uncompressed_spendable_address + uncompressed_solvable_address:
- v = self.nodes[0].validateaddress(i)
+ v = self.nodes[0].getaddressinfo(i)
if (v['isscript']):
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
# P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen
@@ -496,7 +496,7 @@ class SegWitTest(BitcoinTestFramework):
unseen_anytime.extend([p2wpkh, p2sh_p2wpkh])
for i in compressed_solvable_address:
- v = self.nodes[0].validateaddress(i)
+ v = self.nodes[0].getaddressinfo(i)
if (v['isscript']):
# P2WSH multisig without private key are seen after addwitnessaddress
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
@@ -519,7 +519,7 @@ class SegWitTest(BitcoinTestFramework):
assert_raises_rpc_error(-4, "Public key or redeemscript not known to wallet, or the key is uncompressed", self.nodes[0].addwitnessaddress, i)
# after importaddress it should pass addwitnessaddress
- v = self.nodes[0].validateaddress(compressed_solvable_address[1])
+ v = self.nodes[0].getaddressinfo(compressed_solvable_address[1])
self.nodes[0].importaddress(v['hex'],"",False,True)
for i in compressed_spendable_address + compressed_solvable_address + premature_witaddress:
witaddress = self.nodes[0].addwitnessaddress(i)
@@ -559,7 +559,7 @@ class SegWitTest(BitcoinTestFramework):
self.nodes[1].importaddress(scriptPubKey, "", False)
rawtxfund = self.nodes[1].fundrawtransaction(transaction)['hex']
- rawtxfund = self.nodes[1].signrawtransaction(rawtxfund)["hex"]
+ rawtxfund = self.nodes[1].signrawtransactionwithwallet(rawtxfund)["hex"]
txid = self.nodes[1].sendrawtransaction(rawtxfund)
assert_equal(self.nodes[1].gettransaction(txid, True)["txid"], txid)
@@ -578,7 +578,7 @@ class SegWitTest(BitcoinTestFramework):
for i in script_list:
tx.vout.append(CTxOut(10000000, i))
tx.rehash()
- signresults = self.nodes[0].signrawtransaction(bytes_to_hex_str(tx.serialize_without_witness()))['hex']
+ signresults = self.nodes[0].signrawtransactionwithwallet(bytes_to_hex_str(tx.serialize_without_witness()))['hex']
txid = self.nodes[0].sendrawtransaction(signresults, True)
self.nodes[0].generate(1)
sync_blocks(self.nodes)
@@ -630,7 +630,7 @@ class SegWitTest(BitcoinTestFramework):
tx.vin.append(CTxIn(COutPoint(int('0x'+i,0), j)))
tx.vout.append(CTxOut(0, CScript()))
tx.rehash()
- signresults = self.nodes[0].signrawtransaction(bytes_to_hex_str(tx.serialize_without_witness()))['hex']
+ signresults = self.nodes[0].signrawtransactionwithwallet(bytes_to_hex_str(tx.serialize_without_witness()))['hex']
self.nodes[0].sendrawtransaction(signresults, True)
self.nodes[0].generate(1)
sync_blocks(self.nodes)
diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py
index 9006e27cbe..3e87f6d33f 100755
--- a/test/functional/interface_rest.py
+++ b/test/functional/interface_rest.py
@@ -46,6 +46,7 @@ class RESTTest (BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 3
+ self.extra_args = [["-rest"]] * self.num_nodes
def setup_network(self, split=False):
super().setup_network()
diff --git a/test/functional/mempool_limit.py b/test/functional/mempool_limit.py
index 7e01663c96..47f7efd3e7 100755
--- a/test/functional/mempool_limit.py
+++ b/test/functional/mempool_limit.py
@@ -32,7 +32,7 @@ class MempoolLimitTest(BitcoinTestFramework):
self.nodes[0].settxfee(relayfee) # specifically fund this tx with low fee
txF = self.nodes[0].fundrawtransaction(tx)
self.nodes[0].settxfee(0) # return to automatic fee selection
- txFS = self.nodes[0].signrawtransaction(txF['hex'])
+ txFS = self.nodes[0].signrawtransactionwithwallet(txF['hex'])
txid = self.nodes[0].sendrawtransaction(txFS['hex'])
relayfee = self.nodes[0].getnetworkinfo()['relayfee']
@@ -57,7 +57,7 @@ class MempoolLimitTest(BitcoinTestFramework):
tx = self.nodes[0].createrawtransaction(inputs, outputs)
# specifically fund this tx with a fee < mempoolminfee, >= than minrelaytxfee
txF = self.nodes[0].fundrawtransaction(tx, {'feeRate': relayfee})
- txFS = self.nodes[0].signrawtransaction(txF['hex'])
+ txFS = self.nodes[0].signrawtransactionwithwallet(txF['hex'])
assert_raises_rpc_error(-26, "mempool min fee not met, 166 < 411 (code 66)", self.nodes[0].sendrawtransaction, txFS['hex'])
if __name__ == '__main__':
diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py
index a3e872a8c6..23797d83db 100755
--- a/test/functional/mempool_packages.py
+++ b/test/functional/mempool_packages.py
@@ -25,7 +25,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
for i in range(num_outputs):
outputs[node.getnewaddress()] = send_value
rawtx = node.createrawtransaction(inputs, outputs)
- signedtx = node.signrawtransaction(rawtx)
+ signedtx = node.signrawtransactionwithwallet(rawtx)
txid = node.sendrawtransaction(signedtx['hex'])
fulltx = node.getrawtransaction(txid, 1)
assert(len(fulltx['vout']) == num_outputs) # make sure we didn't generate a change output
@@ -205,7 +205,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
for i in range(2):
outputs[self.nodes[0].getnewaddress()] = send_value
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- signedtx = self.nodes[0].signrawtransaction(rawtx)
+ signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx)
txid = self.nodes[0].sendrawtransaction(signedtx['hex'])
tx0_id = txid
value = send_value
@@ -229,7 +229,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
inputs = [ {'txid' : tx1_id, 'vout': 0}, {'txid' : txid, 'vout': 0} ]
outputs = { self.nodes[0].getnewaddress() : send_value + value - 4*fee }
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- signedtx = self.nodes[0].signrawtransaction(rawtx)
+ signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx)
txid = self.nodes[0].sendrawtransaction(signedtx['hex'])
sync_mempools(self.nodes)
diff --git a/test/functional/mempool_reorg.py b/test/functional/mempool_reorg.py
index d6bb292a58..eabed5d633 100755
--- a/test/functional/mempool_reorg.py
+++ b/test/functional/mempool_reorg.py
@@ -48,7 +48,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
# Set the time lock
timelock_tx = timelock_tx.replace("ffffffff", "11111191", 1)
timelock_tx = timelock_tx[:-8] + hex(self.nodes[0].getblockcount() + 2)[2:] + "000000"
- timelock_tx = self.nodes[0].signrawtransaction(timelock_tx)["hex"]
+ timelock_tx = self.nodes[0].signrawtransactionwithwallet(timelock_tx)["hex"]
# This will raise an exception because the timelock transaction is too immature to spend
assert_raises_rpc_error(-26, "non-final", self.nodes[0].sendrawtransaction, timelock_tx)
diff --git a/test/functional/mining_prioritisetransaction.py b/test/functional/mining_prioritisetransaction.py
index 8cea9c2783..32e2b47fc9 100755
--- a/test/functional/mining_prioritisetransaction.py
+++ b/test/functional/mining_prioritisetransaction.py
@@ -116,7 +116,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
inputs.append({"txid" : utxo["txid"], "vout" : utxo["vout"]})
outputs[self.nodes[0].getnewaddress()] = utxo["amount"]
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
- tx_hex = self.nodes[0].signrawtransaction(raw_tx)["hex"]
+ tx_hex = self.nodes[0].signrawtransactionwithwallet(raw_tx)["hex"]
tx_id = self.nodes[0].decoderawtransaction(tx_hex)["txid"]
# This will raise an exception due to min relay fee not being met
diff --git a/test/functional/p2p_node_network_limited.py b/test/functional/p2p_node_network_limited.py
index 70415e0168..81a41d6a97 100755
--- a/test/functional/p2p_node_network_limited.py
+++ b/test/functional/p2p_node_network_limited.py
@@ -8,16 +8,21 @@ Tests that a node configured with -prune=550 signals NODE_NETWORK_LIMITED correc
and that it responds to getdata requests for blocks correctly:
- send a block within 288 + 2 of the tip
- disconnect peers who request blocks older than that."""
-from test_framework.messages import CInv, msg_getdata
-from test_framework.mininode import NODE_BLOOM, NODE_NETWORK_LIMITED, NODE_WITNESS, NetworkThread, P2PInterface
+from test_framework.messages import CInv, msg_getdata, msg_verack
+from test_framework.mininode import NODE_BLOOM, NODE_NETWORK_LIMITED, NODE_WITNESS, P2PInterface, wait_until, mininode_lock, network_thread_start, network_thread_join
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_equal
+from test_framework.util import assert_equal, disconnect_nodes, connect_nodes_bi, sync_blocks
class P2PIgnoreInv(P2PInterface):
+ firstAddrnServices = 0
def on_inv(self, message):
# The node will send us invs for other blocks. Ignore them.
pass
-
+ def on_addr(self, message):
+ self.firstAddrnServices = message.addrs[0].nServices
+ def wait_for_addr(self, timeout=5):
+ test_function = lambda: self.last_message.get("addr")
+ wait_until(test_function, timeout=timeout, lock=mininode_lock)
def send_getdata_for_block(self, blockhash):
getdata_request = msg_getdata()
getdata_request.inv.append(CInv(2, int(blockhash, 16)))
@@ -26,12 +31,24 @@ class P2PIgnoreInv(P2PInterface):
class NodeNetworkLimitedTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
- self.num_nodes = 1
- self.extra_args = [['-prune=550']]
+ self.num_nodes = 3
+ self.extra_args = [['-prune=550', '-addrmantest'], [], []]
+
+ def disconnect_all(self):
+ disconnect_nodes(self.nodes[0], 1)
+ disconnect_nodes(self.nodes[1], 0)
+ disconnect_nodes(self.nodes[2], 1)
+ disconnect_nodes(self.nodes[2], 0)
+ disconnect_nodes(self.nodes[0], 2)
+ disconnect_nodes(self.nodes[1], 2)
+
+ def setup_network(self):
+ super(NodeNetworkLimitedTest, self).setup_network()
+ self.disconnect_all()
def run_test(self):
node = self.nodes[0].add_p2p_connection(P2PIgnoreInv())
- NetworkThread().start()
+ network_thread_start()
node.wait_for_verack()
expected_services = NODE_BLOOM | NODE_WITNESS | NODE_NETWORK_LIMITED
@@ -43,7 +60,9 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
assert_equal(int(self.nodes[0].getnetworkinfo()['localservices'], 16), expected_services)
self.log.info("Mine enough blocks to reach the NODE_NETWORK_LIMITED range.")
- blocks = self.nodes[0].generate(292)
+ connect_nodes_bi(self.nodes, 0, 1)
+ blocks = self.nodes[1].generate(292)
+ sync_blocks([self.nodes[0], self.nodes[1]])
self.log.info("Make sure we can max retrive block at tip-288.")
node.send_getdata_for_block(blocks[1]) # last block in valid range
@@ -53,5 +72,48 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
node.send_getdata_for_block(blocks[0]) # first block outside of the 288+2 limit
node.wait_for_disconnect(5)
+ self.log.info("Check local address relay, do a fresh connection.")
+ self.nodes[0].disconnect_p2ps()
+ network_thread_join()
+ node1 = self.nodes[0].add_p2p_connection(P2PIgnoreInv())
+ network_thread_start()
+ node1.wait_for_verack()
+ node1.send_message(msg_verack())
+
+ node1.wait_for_addr()
+ #must relay address with NODE_NETWORK_LIMITED
+ assert_equal(node1.firstAddrnServices, 1036)
+
+ self.nodes[0].disconnect_p2ps()
+ node1.wait_for_disconnect()
+
+ # connect unsynced node 2 with pruned NODE_NETWORK_LIMITED peer
+ # because node 2 is in IBD and node 0 is a NODE_NETWORK_LIMITED peer, sync must not be possible
+ connect_nodes_bi(self.nodes, 0, 2)
+ try:
+ sync_blocks([self.nodes[0], self.nodes[2]], timeout=5)
+ except:
+ pass
+ # node2 must remain at heigh 0
+ assert_equal(self.nodes[2].getblockheader(self.nodes[2].getbestblockhash())['height'], 0)
+
+ # now connect also to node 1 (non pruned)
+ connect_nodes_bi(self.nodes, 1, 2)
+
+ # sync must be possible
+ sync_blocks(self.nodes)
+
+ # disconnect all peers
+ self.disconnect_all()
+
+ # mine 10 blocks on node 0 (pruned node)
+ self.nodes[0].generate(10)
+
+ # connect node1 (non pruned) with node0 (pruned) and check if the can sync
+ connect_nodes_bi(self.nodes, 0, 1)
+
+ # sync must be possible, node 1 is no longer in IBD and should therefore connect to node 0 (NODE_NETWORK_LIMITED)
+ sync_blocks([self.nodes[0], self.nodes[1]])
+
if __name__ == '__main__':
NodeNetworkLimitedTest().main()
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index 7cf2abe6f0..a9e14d3e3c 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -102,6 +102,22 @@ class BlockchainTest(BitcoinTestFramework):
def _test_getchaintxstats(self):
self.log.info("Test getchaintxstats")
+ # Test `getchaintxstats` invalid extra parameters
+ assert_raises_rpc_error(-1, 'getchaintxstats', self.nodes[0].getchaintxstats, 0, '', 0)
+
+ # Test `getchaintxstats` invalid `nblocks`
+ assert_raises_rpc_error(-1, "JSON value is not an integer as expected", self.nodes[0].getchaintxstats, '')
+ assert_raises_rpc_error(-8, "Invalid block count: should be between 0 and the block's height - 1", self.nodes[0].getchaintxstats, -1)
+ assert_raises_rpc_error(-8, "Invalid block count: should be between 0 and the block's height - 1", self.nodes[0].getchaintxstats, self.nodes[0].getblockcount())
+
+ # Test `getchaintxstats` invalid `blockhash`
+ assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].getchaintxstats, blockhash=0)
+ assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getchaintxstats, blockhash='0')
+ blockhash = self.nodes[0].getblockhash(200)
+ self.nodes[0].invalidateblock(blockhash)
+ assert_raises_rpc_error(-8, "Block is not in main chain", self.nodes[0].getchaintxstats, blockhash=blockhash)
+ self.nodes[0].reconsiderblock(blockhash)
+
chaintxstats = self.nodes[0].getchaintxstats(1)
# 200 txs plus genesis tx
assert_equal(chaintxstats['txcount'], 201)
@@ -133,8 +149,6 @@ class BlockchainTest(BitcoinTestFramework):
assert('window_interval' not in chaintxstats)
assert('txrate' not in chaintxstats)
- assert_raises_rpc_error(-8, "Invalid block count: should be between 0 and the block's height - 1", self.nodes[0].getchaintxstats, 201)
-
def _test_gettxoutsetinfo(self):
node = self.nodes[0]
res = node.gettxoutsetinfo()
diff --git a/test/functional/rpc_deprecated.py b/test/functional/rpc_deprecated.py
index 90183474bb..b94b9d8fae 100755
--- a/test/functional/rpc_deprecated.py
+++ b/test/functional/rpc_deprecated.py
@@ -9,7 +9,7 @@ class DeprecatedRpcTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
- self.extra_args = [[], []]
+ self.extra_args = [[], ["-deprecatedrpc=validateaddress"]]
def run_test(self):
# This test should be used to verify correct behaviour of deprecated
@@ -18,10 +18,13 @@ class DeprecatedRpcTest(BitcoinTestFramework):
# self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses")
# assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()])
# self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()])
- #
- # There are currently no deprecated RPC methods in master, so this
- # test is currently empty.
- pass
+
+ self.log.info("Test validateaddress deprecation")
+ SOME_ADDRESS = "mnvGjUy3NMj67yJ6gkK5o9e5RS33Z2Vqcu" # This is just some random address to pass as a parameter to validateaddress
+ dep_validate_address = self.nodes[0].validateaddress(SOME_ADDRESS)
+ assert "ismine" not in dep_validate_address
+ not_dep_val = self.nodes[1].validateaddress(SOME_ADDRESS)
+ assert "ismine" in not_dep_val
if __name__ == '__main__':
DeprecatedRpcTest().main()
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index 4d3be18516..5fb9a361d9 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -53,7 +53,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(rawmatch["changepos"], -1)
watchonly_address = self.nodes[0].getnewaddress()
- watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"]
+ watchonly_pubkey = self.nodes[0].getaddressinfo(watchonly_address)["pubkey"]
watchonly_amount = Decimal(200)
self.nodes[3].importpubkey(watchonly_pubkey, "", True)
watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount)
@@ -371,8 +371,8 @@ class RawTransactionsTest(BitcoinTestFramework):
addr1 = self.nodes[1].getnewaddress()
addr2 = self.nodes[1].getnewaddress()
- addr1Obj = self.nodes[1].validateaddress(addr1)
- addr2Obj = self.nodes[1].validateaddress(addr2)
+ addr1Obj = self.nodes[1].getaddressinfo(addr1)
+ addr2Obj = self.nodes[1].getaddressinfo(addr2)
mSigObj = self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
@@ -401,11 +401,11 @@ class RawTransactionsTest(BitcoinTestFramework):
addr4 = self.nodes[1].getnewaddress()
addr5 = self.nodes[1].getnewaddress()
- addr1Obj = self.nodes[1].validateaddress(addr1)
- addr2Obj = self.nodes[1].validateaddress(addr2)
- addr3Obj = self.nodes[1].validateaddress(addr3)
- addr4Obj = self.nodes[1].validateaddress(addr4)
- addr5Obj = self.nodes[1].validateaddress(addr5)
+ addr1Obj = self.nodes[1].getaddressinfo(addr1)
+ addr2Obj = self.nodes[1].getaddressinfo(addr2)
+ addr3Obj = self.nodes[1].getaddressinfo(addr3)
+ addr4Obj = self.nodes[1].getaddressinfo(addr4)
+ addr5Obj = self.nodes[1].getaddressinfo(addr5)
mSigObj = self.nodes[1].addmultisigaddress(4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']])['address']
@@ -431,8 +431,8 @@ class RawTransactionsTest(BitcoinTestFramework):
addr1 = self.nodes[2].getnewaddress()
addr2 = self.nodes[2].getnewaddress()
- addr1Obj = self.nodes[2].validateaddress(addr1)
- addr2Obj = self.nodes[2].validateaddress(addr2)
+ addr1Obj = self.nodes[2].getaddressinfo(addr1)
+ addr2Obj = self.nodes[2].getaddressinfo(addr2)
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
@@ -449,7 +449,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
fundedTx = self.nodes[2].fundrawtransaction(rawtx)
- signedTx = self.nodes[2].signrawtransaction(fundedTx['hex'])
+ signedTx = self.nodes[2].signrawtransactionwithwallet(fundedTx['hex'])
txId = self.nodes[2].sendrawtransaction(signedTx['hex'])
self.sync_all()
self.nodes[1].generate(1)
@@ -503,7 +503,7 @@ class RawTransactionsTest(BitcoinTestFramework):
#now we need to unlock
self.nodes[1].walletpassphrase("test", 600)
- signedTx = self.nodes[1].signrawtransaction(fundedTx['hex'])
+ signedTx = self.nodes[1].signrawtransactionwithwallet(fundedTx['hex'])
txId = self.nodes[1].sendrawtransaction(signedTx['hex'])
self.nodes[1].generate(1)
self.sync_all()
@@ -564,7 +564,7 @@ class RawTransactionsTest(BitcoinTestFramework):
outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
fundedTx = self.nodes[1].fundrawtransaction(rawtx)
- fundedAndSignedTx = self.nodes[1].signrawtransaction(fundedTx['hex'])
+ fundedAndSignedTx = self.nodes[1].signrawtransactionwithwallet(fundedTx['hex'])
txId = self.nodes[1].sendrawtransaction(fundedAndSignedTx['hex'])
self.sync_all()
self.nodes[0].generate(1)
@@ -622,9 +622,9 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_greater_than(result["changepos"], -1)
assert_equal(result["fee"] + res_dec["vout"][result["changepos"]]["value"], watchonly_amount / 10)
- signedtx = self.nodes[3].signrawtransaction(result["hex"])
+ signedtx = self.nodes[3].signrawtransactionwithwallet(result["hex"])
assert(not signedtx["complete"])
- signedtx = self.nodes[0].signrawtransaction(signedtx["hex"])
+ signedtx = self.nodes[0].signrawtransactionwithwallet(signedtx["hex"])
assert(signedtx["complete"])
self.nodes[0].sendrawtransaction(signedtx["hex"])
self.nodes[0].generate(1)
diff --git a/test/functional/rpc_listtransactions.py b/test/functional/rpc_listtransactions.py
index ba71ac0967..0dd7372e6b 100755
--- a/test/functional/rpc_listtransactions.py
+++ b/test/functional/rpc_listtransactions.py
@@ -81,7 +81,7 @@ class ListTransactionsTest(BitcoinTestFramework):
{"category":"receive","amount":Decimal("0.44")},
{"txid":txid, "account" : "toself"} )
- pubkey = self.nodes[1].validateaddress(self.nodes[1].getnewaddress())['pubkey']
+ pubkey = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress())['pubkey']
multisig = self.nodes[1].createmultisig(1, [pubkey])
self.nodes[0].importaddress(multisig["redeemScript"], "watchonly", False, True)
txid = self.nodes[1].sendtoaddress(multisig["address"], 0.1)
@@ -131,7 +131,7 @@ class ListTransactionsTest(BitcoinTestFramework):
inputs = [{"txid":utxo_to_use["txid"], "vout":utxo_to_use["vout"]}]
outputs = {self.nodes[0].getnewaddress(): 0.999}
tx2 = self.nodes[1].createrawtransaction(inputs, outputs)
- tx2_signed = self.nodes[1].signrawtransaction(tx2)["hex"]
+ tx2_signed = self.nodes[1].signrawtransactionwithwallet(tx2)["hex"]
txid_2 = self.nodes[1].sendrawtransaction(tx2_signed)
# ...and check the result
@@ -148,7 +148,7 @@ class ListTransactionsTest(BitcoinTestFramework):
tx3_modified = txFromHex(tx3)
tx3_modified.vin[0].nSequence = 0
tx3 = bytes_to_hex_str(tx3_modified.serialize())
- tx3_signed = self.nodes[0].signrawtransaction(tx3)['hex']
+ tx3_signed = self.nodes[0].signrawtransactionwithwallet(tx3)['hex']
txid_3 = self.nodes[0].sendrawtransaction(tx3_signed)
assert(is_opt_in(self.nodes[0], txid_3))
@@ -162,7 +162,7 @@ class ListTransactionsTest(BitcoinTestFramework):
inputs = [{"txid": txid_3, "vout":utxo_to_use["vout"]}]
outputs = {self.nodes[0].getnewaddress(): 0.997}
tx4 = self.nodes[1].createrawtransaction(inputs, outputs)
- tx4_signed = self.nodes[1].signrawtransaction(tx4)["hex"]
+ tx4_signed = self.nodes[1].signrawtransactionwithwallet(tx4)["hex"]
txid_4 = self.nodes[1].sendrawtransaction(tx4_signed)
assert(not is_opt_in(self.nodes[1], txid_4))
@@ -174,7 +174,7 @@ class ListTransactionsTest(BitcoinTestFramework):
tx3_b = tx3_modified
tx3_b.vout[0].nValue -= int(Decimal("0.004") * COIN) # bump the fee
tx3_b = bytes_to_hex_str(tx3_b.serialize())
- tx3_b_signed = self.nodes[0].signrawtransaction(tx3_b)['hex']
+ tx3_b_signed = self.nodes[0].signrawtransactionwithwallet(tx3_b)['hex']
txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True)
assert(is_opt_in(self.nodes[0], txid_3b))
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index 92126ef4b7..e074f5bd74 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -6,7 +6,7 @@
Test the following RPCs:
- createrawtransaction
- - signrawtransaction
+ - signrawtransactionwithwallet
- sendrawtransaction
- decoderawtransaction
- getrawtransaction
@@ -104,7 +104,7 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1}] #won't exists
outputs = { self.nodes[0].getnewaddress() : 4.998 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
- rawtx = self.nodes[2].signrawtransaction(rawtx)
+ rawtx = self.nodes[2].signrawtransactionwithwallet(rawtx)
# This will raise an exception since there are missing inputs
assert_raises_rpc_error(-25, "Missing inputs", self.nodes[2].sendrawtransaction, rawtx['hex'])
@@ -146,8 +146,8 @@ class RawTransactionsTest(BitcoinTestFramework):
addr1 = self.nodes[2].getnewaddress()
addr2 = self.nodes[2].getnewaddress()
- addr1Obj = self.nodes[2].validateaddress(addr1)
- addr2Obj = self.nodes[2].validateaddress(addr2)
+ addr1Obj = self.nodes[2].getaddressinfo(addr1)
+ addr2Obj = self.nodes[2].getaddressinfo(addr2)
# Tests for createmultisig and addmultisigaddress
assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, ["01020304"])
@@ -173,9 +173,9 @@ class RawTransactionsTest(BitcoinTestFramework):
addr2 = self.nodes[2].getnewaddress()
addr3 = self.nodes[2].getnewaddress()
- addr1Obj = self.nodes[1].validateaddress(addr1)
- addr2Obj = self.nodes[2].validateaddress(addr2)
- addr3Obj = self.nodes[2].validateaddress(addr3)
+ addr1Obj = self.nodes[1].getaddressinfo(addr1)
+ addr2Obj = self.nodes[2].getaddressinfo(addr2)
+ addr3Obj = self.nodes[2].getaddressinfo(addr3)
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])['address']
@@ -202,10 +202,10 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "amount" : vout['value']}]
outputs = { self.nodes[0].getnewaddress() : 2.19 }
rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
- rawTxPartialSigned = self.nodes[1].signrawtransaction(rawTx, inputs)
+ rawTxPartialSigned = self.nodes[1].signrawtransactionwithwallet(rawTx, inputs)
assert_equal(rawTxPartialSigned['complete'], False) #node1 only has one key, can't comp. sign the tx
- rawTxSigned = self.nodes[2].signrawtransaction(rawTx, inputs)
+ rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx, inputs)
assert_equal(rawTxSigned['complete'], True) #node2 can sign the tx compl., own two of three keys
self.nodes[2].sendrawtransaction(rawTxSigned['hex'])
rawTx = self.nodes[0].decoderawtransaction(rawTxSigned['hex'])
@@ -219,12 +219,12 @@ class RawTransactionsTest(BitcoinTestFramework):
addr1 = self.nodes[1].getnewaddress()
addr2 = self.nodes[2].getnewaddress()
- addr1Obj = self.nodes[1].validateaddress(addr1)
- addr2Obj = self.nodes[2].validateaddress(addr2)
+ addr1Obj = self.nodes[1].getaddressinfo(addr1)
+ addr2Obj = self.nodes[2].getaddressinfo(addr2)
self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
- mSigObjValid = self.nodes[2].validateaddress(mSigObj)
+ mSigObjValid = self.nodes[2].getaddressinfo(mSigObj)
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
decTx = self.nodes[0].gettransaction(txId)
@@ -247,11 +247,11 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "redeemScript" : mSigObjValid['hex'], "amount" : vout['value']}]
outputs = { self.nodes[0].getnewaddress() : 2.19 }
rawTx2 = self.nodes[2].createrawtransaction(inputs, outputs)
- rawTxPartialSigned1 = self.nodes[1].signrawtransaction(rawTx2, inputs)
+ rawTxPartialSigned1 = self.nodes[1].signrawtransactionwithwallet(rawTx2, inputs)
self.log.info(rawTxPartialSigned1)
assert_equal(rawTxPartialSigned['complete'], False) #node1 only has one key, can't comp. sign the tx
- rawTxPartialSigned2 = self.nodes[2].signrawtransaction(rawTx2, inputs)
+ rawTxPartialSigned2 = self.nodes[2].signrawtransactionwithwallet(rawTx2, inputs)
self.log.info(rawTxPartialSigned2)
assert_equal(rawTxPartialSigned2['complete'], False) #node2 only has one key, can't comp. sign the tx
rawTxComb = self.nodes[2].combinerawtransaction([rawTxPartialSigned1['hex'], rawTxPartialSigned2['hex']])
diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/rpc_signrawtransaction.py
index dd0fa6c02c..18829ef4b8 100755
--- a/test/functional/rpc_signrawtransaction.py
+++ b/test/functional/rpc_signrawtransaction.py
@@ -2,7 +2,7 @@
# Copyright (c) 2015-2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-"""Test transaction signing using the signrawtransaction RPC."""
+"""Test transaction signing using the signrawtransaction* RPCs."""
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
@@ -12,6 +12,7 @@ class SignRawTransactionsTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
+ self.extra_args = [["-deprecatedrpc=signrawtransaction"]]
def successful_signing_test(self):
"""Create and sign a valid raw transaction with one input.
@@ -33,15 +34,18 @@ class SignRawTransactionsTest(BitcoinTestFramework):
outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1}
rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
- rawTxSigned = self.nodes[0].signrawtransaction(rawTx, inputs, privKeys)
+ rawTxSigned = self.nodes[0].signrawtransactionwithkey(rawTx, privKeys, inputs)
# 1) The transaction has a complete set of signatures
- assert 'complete' in rawTxSigned
- assert_equal(rawTxSigned['complete'], True)
+ assert rawTxSigned['complete']
# 2) No script verification error occurred
assert 'errors' not in rawTxSigned
+ # Perform the same test on signrawtransaction
+ rawTxSigned2 = self.nodes[0].signrawtransaction(rawTx, inputs, privKeys)
+ assert_equal(rawTxSigned, rawTxSigned2)
+
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.
@@ -84,11 +88,10 @@ class SignRawTransactionsTest(BitcoinTestFramework):
# Make sure decoderawtransaction throws if there is extra data
assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].decoderawtransaction, rawTx + "00")
- rawTxSigned = self.nodes[0].signrawtransaction(rawTx, scripts, privKeys)
+ rawTxSigned = self.nodes[0].signrawtransactionwithkey(rawTx, privKeys, scripts)
# 3) The transaction has no complete set of signatures
- assert 'complete' in rawTxSigned
- assert_equal(rawTxSigned['complete'], False)
+ assert not rawTxSigned['complete']
# 4) Two script verification errors occurred
assert 'errors' in rawTxSigned
@@ -109,14 +112,17 @@ class SignRawTransactionsTest(BitcoinTestFramework):
assert_equal(rawTxSigned['errors'][1]['vout'], inputs[2]['vout'])
assert not rawTxSigned['errors'][0]['witness']
+ # Perform same test with signrawtransaction
+ rawTxSigned2 = self.nodes[0].signrawtransaction(rawTx, scripts, privKeys)
+ assert_equal(rawTxSigned, rawTxSigned2)
+
# Now test signing failure for transaction with input witnesses
p2wpkh_raw_tx = "01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000"
- rawTxSigned = self.nodes[0].signrawtransaction(p2wpkh_raw_tx)
+ rawTxSigned = self.nodes[0].signrawtransactionwithwallet(p2wpkh_raw_tx)
# 7) The transaction has no complete set of signatures
- assert 'complete' in rawTxSigned
- assert_equal(rawTxSigned['complete'], False)
+ assert not rawTxSigned['complete']
# 8) Two script verification errors occurred
assert 'errors' in rawTxSigned
@@ -134,6 +140,10 @@ class SignRawTransactionsTest(BitcoinTestFramework):
assert_equal(rawTxSigned['errors'][1]['witness'], ["304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee01", "025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357"])
assert not rawTxSigned['errors'][0]['witness']
+ # Perform same test with signrawtransaction
+ rawTxSigned2 = self.nodes[0].signrawtransaction(p2wpkh_raw_tx)
+ assert_equal(rawTxSigned, rawTxSigned2)
+
def run_test(self):
self.successful_signing_test()
self.script_verification_error_test()
diff --git a/test/functional/rpc_txoutproof.py b/test/functional/rpc_txoutproof.py
index 50e0371fdf..c52a7397dc 100755
--- a/test/functional/rpc_txoutproof.py
+++ b/test/functional/rpc_txoutproof.py
@@ -34,9 +34,9 @@ class MerkleBlockTest(BitcoinTestFramework):
node0utxos = self.nodes[0].listunspent(1)
tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99})
- txid1 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx1)["hex"])
+ txid1 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransactionwithwallet(tx1)["hex"])
tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99})
- txid2 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx2)["hex"])
+ txid2 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransactionwithwallet(tx2)["hex"])
# This will raise an exception because the transaction is not yet in a block
assert_raises_rpc_error(-5, "Transaction not yet in block", self.nodes[0].gettxoutproof, [txid1])
@@ -55,7 +55,7 @@ class MerkleBlockTest(BitcoinTestFramework):
txin_spent = self.nodes[1].listunspent(1).pop()
tx3 = self.nodes[1].createrawtransaction([txin_spent], {self.nodes[0].getnewaddress(): 49.98})
- txid3 = self.nodes[0].sendrawtransaction(self.nodes[1].signrawtransaction(tx3)["hex"])
+ txid3 = self.nodes[0].sendrawtransaction(self.nodes[1].signrawtransactionwithwallet(tx3)["hex"])
self.nodes[0].generate(1)
self.sync_all()
diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py
index 642ef98a27..43982cd09a 100644
--- a/test/functional/test_framework/blocktools.py
+++ b/test/functional/test_framework/blocktools.py
@@ -149,7 +149,7 @@ def create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount):
else:
addr = key_to_p2sh_p2wpkh(pubkey) if encode_p2sh else key_to_p2wpkh(pubkey)
if not encode_p2sh:
- assert_equal(node.validateaddress(addr)['scriptPubKey'], witness_script(use_p2wsh, pubkey))
+ assert_equal(node.getaddressinfo(addr)['scriptPubKey'], witness_script(use_p2wsh, pubkey))
return node.createrawtransaction([utxo], {addr: amount})
# Create a transaction spending a given utxo to a segwit output corresponding
@@ -160,7 +160,7 @@ def create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount):
def send_to_witness(use_p2wsh, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""):
tx_to_witness = create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount)
if (sign):
- signed = node.signrawtransaction(tx_to_witness)
+ signed = node.signrawtransactionwithwallet(tx_to_witness)
assert("errors" not in signed or len(["errors"]) == 0)
return node.sendrawtransaction(signed["hex"])
else:
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 46ef7521e0..e032be1337 100644..100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -186,19 +186,24 @@ def ToHex(obj):
class CAddress():
def __init__(self):
+ self.time = 0
self.nServices = 1
self.pchReserved = b"\x00" * 10 + b"\xff" * 2
self.ip = "0.0.0.0"
self.port = 0
- def deserialize(self, f):
+ def deserialize(self, f, with_time=True):
+ if with_time:
+ self.time = struct.unpack("<i", f.read(4))[0]
self.nServices = struct.unpack("<Q", f.read(8))[0]
self.pchReserved = f.read(12)
self.ip = socket.inet_ntoa(f.read(4))
self.port = struct.unpack(">H", f.read(2))[0]
- def serialize(self):
+ def serialize(self, with_time=True):
r = b""
+ if with_time:
+ r += struct.pack("<i", self.time)
r += struct.pack("<Q", self.nServices)
r += self.pchReserved
r += socket.inet_aton(self.ip)
@@ -856,11 +861,11 @@ class msg_version():
self.nServices = struct.unpack("<Q", f.read(8))[0]
self.nTime = struct.unpack("<q", f.read(8))[0]
self.addrTo = CAddress()
- self.addrTo.deserialize(f)
+ self.addrTo.deserialize(f, False)
if self.nVersion >= 106:
self.addrFrom = CAddress()
- self.addrFrom.deserialize(f)
+ self.addrFrom.deserialize(f, False)
self.nNonce = struct.unpack("<Q", f.read(8))[0]
self.strSubVer = deser_string(f)
else:
@@ -888,8 +893,8 @@ class msg_version():
r += struct.pack("<i", self.nVersion)
r += struct.pack("<Q", self.nServices)
r += struct.pack("<q", self.nTime)
- r += self.addrTo.serialize()
- r += self.addrFrom.serialize()
+ r += self.addrTo.serialize(False)
+ r += self.addrFrom.serialize(False)
r += struct.pack("<Q", self.nNonce)
r += ser_string(self.strSubVer)
r += struct.pack("<i", self.nStartingHeight)
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index a5e66bd959..ecb91b315e 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -392,7 +392,7 @@ class BitcoinTestFramework():
# Create cache directories, run bitcoinds:
for i in range(MAX_NODES):
datadir = initialize_datadir(self.options.cachedir, i)
- args = [os.getenv("BITCOIND", "bitcoind"), "-server", "-keypool=1", "-datadir=" + datadir, "-discover=0"]
+ args = [os.getenv("BITCOIND", "bitcoind"), "-datadir=" + datadir]
if i > 0:
args.append("-connect=127.0.0.1:" + str(p2p_port(0)))
self.nodes.append(TestNode(i, self.options.cachedir, extra_args=[], rpchost=None, timewait=None, binary=None, stderr=None, mocktime=self.mocktime, coverage_dir=None))
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 1054e6d028..93a052f785 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -57,9 +57,11 @@ class TestNode():
self.binary = binary
self.stderr = stderr
self.coverage_dir = coverage_dir
- # Most callers will just need to add extra args to the standard list below. For those callers that need more flexibity, they can just set the args property directly.
+ # Most callers will just need to add extra args to the standard list below.
+ # For those callers that need more flexibity, they can just set the args property directly.
+ # Note that common args are set in the config file (see initialize_datadir)
self.extra_args = extra_args
- self.args = [self.binary, "-datadir=" + self.datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-logtimemicros", "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", "-mocktime=" + str(mocktime), "-uacomment=testnode%d" % i]
+ self.args = [self.binary, "-datadir=" + self.datadir, "-logtimemicros", "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", "-mocktime=" + str(mocktime), "-uacomment=testnode%d" % i]
self.cli = TestNodeCLI(os.getenv("BITCOINCLI", "bitcoin-cli"), self.datadir)
self.use_cli = use_cli
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index 7fdc171332..e9e7bbd8e4 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -26,7 +26,7 @@ logger = logging.getLogger("TestFramework.utils")
def assert_fee_amount(fee, tx_size, fee_per_kB):
"""Assert the fee was in range"""
- target_fee = tx_size * fee_per_kB / 1000
+ target_fee = round(tx_size * fee_per_kB / 1000, 8)
if fee < target_fee:
raise AssertionError("Fee of %s BTC too low! (Should be %s BTC)" % (str(fee), str(target_fee)))
# allow the wallet's estimation to be at most 2 bytes off
@@ -291,6 +291,9 @@ def initialize_datadir(dirname, n):
f.write("regtest=1\n")
f.write("port=" + str(p2p_port(n)) + "\n")
f.write("rpcport=" + str(rpc_port(n)) + "\n")
+ f.write("server=1\n")
+ f.write("keypool=1\n")
+ f.write("discover=0\n")
f.write("listenonion=0\n")
return datadir
@@ -472,7 +475,7 @@ def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants):
outputs[to_node.getnewaddress()] = float(amount)
rawtx = from_node.createrawtransaction(inputs, outputs)
- signresult = from_node.signrawtransaction(rawtx)
+ signresult = from_node.signrawtransactionwithwallet(rawtx)
txid = from_node.sendrawtransaction(signresult["hex"], True)
return (txid, signresult["hex"], fee)
@@ -499,7 +502,7 @@ def create_confirmed_utxos(fee, node, count):
outputs[addr1] = satoshi_round(send_value / 2)
outputs[addr2] = satoshi_round(send_value / 2)
raw_tx = node.createrawtransaction(inputs, outputs)
- signed_tx = node.signrawtransaction(raw_tx)["hex"]
+ signed_tx = node.signrawtransactionwithwallet(raw_tx)["hex"]
node.sendrawtransaction(signed_tx)
while (node.getmempoolinfo()['size'] > 0):
@@ -533,7 +536,7 @@ def create_tx(node, coinbase, to_address, amount):
inputs = [{"txid": coinbase, "vout": 0}]
outputs = {to_address: amount}
rawtx = node.createrawtransaction(inputs, outputs)
- signresult = node.signrawtransaction(rawtx)
+ signresult = node.signrawtransactionwithwallet(rawtx)
assert_equal(signresult["complete"], True)
return signresult["hex"]
@@ -552,7 +555,7 @@ def create_lots_of_big_transactions(node, txouts, utxos, num, fee):
newtx = rawtx[0:92]
newtx = newtx + txouts
newtx = newtx + rawtx[94:]
- signresult = node.signrawtransaction(newtx, None, None, "NONE")
+ signresult = node.signrawtransactionwithwallet(newtx, None, "NONE")
txid = node.sendrawtransaction(signresult["hex"], True)
txids.append(txid)
return txids
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 945f645eac..082191098e 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -126,6 +126,7 @@ BASE_SCRIPTS= [
'feature_cltv.py',
'rpc_uptime.py',
'wallet_resendwallettransactions.py',
+ 'wallet_fallbackfee.py',
'feature_minchainwork.py',
'p2p_fingerprint.py',
'feature_uacomment.py',
diff --git a/test/functional/wallet_abandonconflict.py b/test/functional/wallet_abandonconflict.py
index 8fb860cd7e..7e0635d80f 100755
--- a/test/functional/wallet_abandonconflict.py
+++ b/test/functional/wallet_abandonconflict.py
@@ -55,7 +55,7 @@ class AbandonConflictTest(BitcoinTestFramework):
outputs[self.nodes[0].getnewaddress()] = Decimal("14.99998")
outputs[self.nodes[1].getnewaddress()] = Decimal("5")
- signed = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs))
+ signed = self.nodes[0].signrawtransactionwithwallet(self.nodes[0].createrawtransaction(inputs, outputs))
txAB1 = self.nodes[0].sendrawtransaction(signed["hex"])
# Identify the 14.99998btc output
@@ -67,7 +67,7 @@ class AbandonConflictTest(BitcoinTestFramework):
inputs.append({"txid":txC, "vout":nC})
outputs = {}
outputs[self.nodes[0].getnewaddress()] = Decimal("24.9996")
- signed2 = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs))
+ signed2 = self.nodes[0].signrawtransactionwithwallet(self.nodes[0].createrawtransaction(inputs, outputs))
txABC2 = self.nodes[0].sendrawtransaction(signed2["hex"])
# In mempool txs from self should increase balance from change
@@ -138,7 +138,7 @@ class AbandonConflictTest(BitcoinTestFramework):
outputs = {}
outputs[self.nodes[1].getnewaddress()] = Decimal("9.9999")
tx = self.nodes[0].createrawtransaction(inputs, outputs)
- signed = self.nodes[0].signrawtransaction(tx)
+ signed = self.nodes[0].signrawtransactionwithwallet(tx)
self.nodes[1].sendrawtransaction(signed["hex"])
self.nodes[1].generate(1)
diff --git a/test/functional/wallet_address_types.py b/test/functional/wallet_address_types.py
index 38a3425214..5d2428e6ef 100755
--- a/test/functional/wallet_address_types.py
+++ b/test/functional/wallet_address_types.py
@@ -93,8 +93,8 @@ class AddressTypeTest(BitcoinTestFramework):
def test_address(self, node, address, multisig, typ):
"""Run sanity checks on an address."""
- info = self.nodes[node].validateaddress(address)
- assert(info['isvalid'])
+ info = self.nodes[node].getaddressinfo(address)
+ assert(self.nodes[node].validateaddress(address)['isvalid'])
if not multisig and typ == 'legacy':
# P2PKH
assert(not info['isscript'])
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index a90dbc8adf..f686cb6ea5 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -66,7 +66,7 @@ class WalletTest(BitcoinTestFramework):
assert_equal(txout['value'], 50)
txout = self.nodes[0].gettxout(txid=confirmed_txid, n=confirmed_index, include_mempool=True)
assert_equal(txout['value'], 50)
-
+
# Send 21 BTC from 0 to 2 using sendtoaddress call.
# Locked memory should use at least 32 bytes to sign each transaction
self.log.info("test getmemoryinfo")
@@ -140,7 +140,7 @@ class WalletTest(BitcoinTestFramework):
inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]})
outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"] - 3
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
- txns_to_send.append(self.nodes[0].signrawtransaction(raw_tx))
+ txns_to_send.append(self.nodes[0].signrawtransactionwithwallet(raw_tx))
# Have node 1 (miner) send the transactions
self.nodes[1].sendrawtransaction(txns_to_send[0]["hex"], True)
@@ -225,7 +225,7 @@ class WalletTest(BitcoinTestFramework):
rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") #replace 11.11 with 0.0 (int32)
decRawTx = self.nodes[1].decoderawtransaction(rawTx)
- signedRawTx = self.nodes[1].signrawtransaction(rawTx)
+ signedRawTx = self.nodes[1].signrawtransactionwithwallet(rawTx)
decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex'])
zeroValueTxid= decRawTx['txid']
self.nodes[1].sendrawtransaction(signedRawTx['hex'])
@@ -317,7 +317,7 @@ class WalletTest(BitcoinTestFramework):
self.nodes[1].importaddress(address_to_import)
# 3. Validate that the imported address is watch-only on node1
- assert(self.nodes[1].validateaddress(address_to_import)["iswatchonly"])
+ assert(self.nodes[1].getaddressinfo(address_to_import)["iswatchonly"])
# 4. Check that the unspents after import are not spendable
assert_array_result(self.nodes[1].listunspent(),
@@ -400,7 +400,7 @@ class WalletTest(BitcoinTestFramework):
node0_balance = self.nodes[0].getbalance()
# Split into two chains
rawtx = self.nodes[0].createrawtransaction([{"txid":singletxid, "vout":0}], {chain_addrs[0]:node0_balance/2-Decimal('0.01'), chain_addrs[1]:node0_balance/2-Decimal('0.01')})
- signedtx = self.nodes[0].signrawtransaction(rawtx)
+ signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx)
singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"])
self.nodes[0].generate(1)
@@ -442,5 +442,14 @@ class WalletTest(BitcoinTestFramework):
# Verify nothing new in wallet
assert_equal(total_txs, len(self.nodes[0].listtransactions("*",99999)))
+ # Test getaddressinfo. Note that these addresses are taken from disablewallet.py
+ assert_raises_rpc_error(-5, "Invalid address", self.nodes[0].getaddressinfo, "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy")
+ address_info = self.nodes[0].getaddressinfo("mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ")
+ assert_equal(address_info['address'], "mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ")
+ assert_equal(address_info["scriptPubKey"], "76a9144e3854046c7bd1594ac904e4793b6a45b36dea0988ac")
+ assert not address_info["ismine"]
+ assert not address_info["iswatchonly"]
+ assert not address_info["isscript"]
+
if __name__ == '__main__':
WalletTest().main()
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index f621d41b4e..3e496248fd 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -104,7 +104,7 @@ def test_segwit_bumpfee_succeeds(rbf_node, dest_address):
# which spends it, and make sure bumpfee can be called on it.
segwit_in = next(u for u in rbf_node.listunspent() if u["amount"] == Decimal("0.001"))
- segwit_out = rbf_node.validateaddress(rbf_node.getnewaddress())
+ segwit_out = rbf_node.getaddressinfo(rbf_node.getnewaddress())
rbf_node.addwitnessaddress(segwit_out["address"])
segwitid = send_to_witness(
use_p2wsh=False,
@@ -121,7 +121,7 @@ def test_segwit_bumpfee_succeeds(rbf_node, dest_address):
"sequence": BIP125_SEQUENCE_NUMBER
}], {dest_address: Decimal("0.0005"),
rbf_node.getrawchangeaddress(): Decimal("0.0003")})
- rbfsigned = rbf_node.signrawtransaction(rbfraw)
+ rbfsigned = rbf_node.signrawtransactionwithwallet(rbfraw)
rbfid = rbf_node.sendrawtransaction(rbfsigned["hex"])
assert rbfid in rbf_node.getrawmempool()
@@ -150,8 +150,8 @@ def test_notmine_bumpfee_fails(rbf_node, peer_node, dest_address):
} for utxo in utxos]
output_val = sum(utxo["amount"] for utxo in utxos) - Decimal("0.001")
rawtx = rbf_node.createrawtransaction(inputs, {dest_address: output_val})
- signedtx = rbf_node.signrawtransaction(rawtx)
- signedtx = peer_node.signrawtransaction(signedtx["hex"])
+ signedtx = rbf_node.signrawtransactionwithwallet(rawtx)
+ signedtx = peer_node.signrawtransactionwithwallet(signedtx["hex"])
rbfid = rbf_node.sendrawtransaction(signedtx["hex"])
assert_raises_rpc_error(-4, "Transaction contains inputs that don't belong to this wallet",
rbf_node.bumpfee, rbfid)
@@ -162,7 +162,7 @@ def test_bumpfee_with_descendant_fails(rbf_node, rbf_node_address, dest_address)
# parent is send-to-self, so we don't have to check which output is change when creating the child tx
parent_id = spend_one_input(rbf_node, rbf_node_address)
tx = rbf_node.createrawtransaction([{"txid": parent_id, "vout": 0}], {dest_address: 0.00020000})
- tx = rbf_node.signrawtransaction(tx)
+ tx = rbf_node.signrawtransactionwithwallet(tx)
rbf_node.sendrawtransaction(tx["hex"])
assert_raises_rpc_error(-8, "Transaction has descendants in the wallet", rbf_node.bumpfee, parent_id)
@@ -277,7 +277,7 @@ def spend_one_input(node, dest_address):
rawtx = node.createrawtransaction(
[tx_input], {dest_address: Decimal("0.00050000"),
node.getrawchangeaddress(): Decimal("0.00049000")})
- signedtx = node.signrawtransaction(rawtx)
+ signedtx = node.signrawtransactionwithwallet(rawtx)
txid = node.sendrawtransaction(signedtx["hex"])
return txid
diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py
index 5e943d048d..59eae78cbd 100755
--- a/test/functional/wallet_dump.py
+++ b/test/functional/wallet_dump.py
@@ -49,7 +49,7 @@ def read_dump(file_name, addrs, script_addrs, hd_master_addr_old):
# count key types
for addrObj in addrs:
if addrObj['address'] == addr.split(",")[0] and addrObj['hdkeypath'] == keypath and keytype == "label=":
- # a labled entry in the wallet should contain both a native address
+ # 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(",")
@@ -97,7 +97,7 @@ class WalletDumpTest(BitcoinTestFramework):
addrs = []
for i in range(0,test_addr_count):
addr = self.nodes[0].getnewaddress()
- vaddr= self.nodes[0].validateaddress(addr) #required to get hd keypath
+ vaddr= self.nodes[0].getaddressinfo(addr) #required to get hd keypath
addrs.append(vaddr)
# Should be a no-op:
self.nodes[0].keypoolrefill()
@@ -143,13 +143,13 @@ class WalletDumpTest(BitcoinTestFramework):
self.start_node(0, ['-wallet=w2'])
# Make sure the address is not IsMine before import
- result = self.nodes[0].validateaddress(multisig_addr)
+ result = self.nodes[0].getaddressinfo(multisig_addr)
assert(result['ismine'] == False)
self.nodes[0].importwallet(os.path.abspath(tmpdir + "/node0/wallet.unencrypted.dump"))
# Now check IsMine is true
- result = self.nodes[0].validateaddress(multisig_addr)
+ result = self.nodes[0].getaddressinfo(multisig_addr)
assert(result['ismine'] == True)
if __name__ == '__main__':
diff --git a/test/functional/wallet_fallbackfee.py b/test/functional/wallet_fallbackfee.py
new file mode 100755
index 0000000000..e9cd052344
--- /dev/null
+++ b/test/functional/wallet_fallbackfee.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+# Copyright (c) 2017 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test wallet replace-by-fee capabilities in conjunction with the fallbackfee."""
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+class WalletRBFTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+ self.setup_clean_chain = True
+
+ def run_test(self):
+ self.nodes[0].generate(101)
+
+ # sending a transaction without fee estimations must be possible by default on regtest
+ self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
+
+ # test sending a tx with disabled fallback fee (must fail)
+ self.restart_node(0, extra_args=["-fallbackfee=0"])
+ assert_raises_rpc_error(-4, "Fee estimation failed", lambda: self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1))
+ assert_raises_rpc_error(-4, "Fee estimation failed", lambda: self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1})))
+ assert_raises_rpc_error(-4, "Fee estimation failed", lambda: self.nodes[0].sendfrom("", self.nodes[0].getnewaddress(), 1))
+ assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1}))
+
+if __name__ == '__main__':
+ WalletRBFTest().main()
diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py
index 9f0e9acb47..91f77dd5ba 100755
--- a/test/functional/wallet_hd.py
+++ b/test/functional/wallet_hd.py
@@ -33,7 +33,7 @@ class WalletHDTest(BitcoinTestFramework):
# create an internal key
change_addr = self.nodes[1].getrawchangeaddress()
- change_addrV= self.nodes[1].validateaddress(change_addr)
+ change_addrV= self.nodes[1].getaddressinfo(change_addr)
assert_equal(change_addrV["hdkeypath"], "m/0'/1'/0'") #first internal child key
# Import a non-HD private key in the HD wallet
@@ -51,7 +51,7 @@ class WalletHDTest(BitcoinTestFramework):
num_hd_adds = 300
for i in range(num_hd_adds):
hd_add = self.nodes[1].getnewaddress()
- hd_info = self.nodes[1].validateaddress(hd_add)
+ hd_info = self.nodes[1].getaddressinfo(hd_add)
assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(i)+"'")
assert_equal(hd_info["hdmasterkeyid"], masterkeyid)
self.nodes[0].sendtoaddress(hd_add, 1)
@@ -61,7 +61,7 @@ class WalletHDTest(BitcoinTestFramework):
# create an internal key (again)
change_addr = self.nodes[1].getrawchangeaddress()
- change_addrV= self.nodes[1].validateaddress(change_addr)
+ change_addrV= self.nodes[1].getaddressinfo(change_addr)
assert_equal(change_addrV["hdkeypath"], "m/0'/1'/1'") #second internal child key
self.sync_all()
@@ -80,7 +80,7 @@ class WalletHDTest(BitcoinTestFramework):
hd_add_2 = None
for _ in range(num_hd_adds):
hd_add_2 = self.nodes[1].getnewaddress()
- hd_info_2 = self.nodes[1].validateaddress(hd_add_2)
+ hd_info_2 = self.nodes[1].getaddressinfo(hd_add_2)
assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/"+str(_)+"'")
assert_equal(hd_info_2["hdmasterkeyid"], masterkeyid)
assert_equal(hd_add, hd_add_2)
@@ -114,7 +114,7 @@ class WalletHDTest(BitcoinTestFramework):
keypath = ""
for out in outs:
if out['value'] != 1:
- keypath = self.nodes[1].validateaddress(out['scriptPubKey']['addresses'][0])['hdkeypath']
+ keypath = self.nodes[1].getaddressinfo(out['scriptPubKey']['addresses'][0])['hdkeypath']
assert_equal(keypath[0:7], "m/0'/1'")
diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py
index d193a99d5b..3288ce4b60 100755
--- a/test/functional/wallet_import_rescan.py
+++ b/test/functional/wallet_import_rescan.py
@@ -134,7 +134,7 @@ class ImportRescanTest(BitcoinTestFramework):
# each possible type of wallet import RPC.
for i, variant in enumerate(IMPORT_VARIANTS):
variant.label = "label {} {}".format(i, variant)
- variant.address = self.nodes[1].validateaddress(self.nodes[1].getnewaddress(variant.label))
+ 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 be9be83839..56ebc2622a 100755
--- a/test/functional/wallet_importmulti.py
+++ b/test/functional/wallet_importmulti.py
@@ -21,7 +21,7 @@ class ImportMultiTest (BitcoinTestFramework):
self.nodes[1].generate(1)
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
- node0_address1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ node0_address1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
#Check only one address
assert_equal(node0_address1['ismine'], True)
@@ -30,7 +30,7 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(self.nodes[1].getblockcount(),1)
#Address Test - before import
- address_info = self.nodes[1].validateaddress(node0_address1['address'])
+ address_info = self.nodes[1].getaddressinfo(node0_address1['address'])
assert_equal(address_info['iswatchonly'], False)
assert_equal(address_info['ismine'], False)
@@ -39,7 +39,7 @@ class ImportMultiTest (BitcoinTestFramework):
# Bitcoin Address
self.log.info("Should import an address")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": {
"address": address['address']
@@ -47,7 +47,7 @@ class ImportMultiTest (BitcoinTestFramework):
"timestamp": "now",
}])
assert_equal(result[0]['success'], True)
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], True)
assert_equal(address_assert['ismine'], False)
assert_equal(address_assert['timestamp'], timestamp)
@@ -67,21 +67,21 @@ class ImportMultiTest (BitcoinTestFramework):
# ScriptPubKey + internal
self.log.info("Should import a scriptPubKey with internal flag")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": address['scriptPubKey'],
"timestamp": "now",
"internal": True
}])
assert_equal(result[0]['success'], True)
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], True)
assert_equal(address_assert['ismine'], False)
assert_equal(address_assert['timestamp'], timestamp)
# ScriptPubKey + !internal
self.log.info("Should not import a scriptPubKey without internal flag")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": address['scriptPubKey'],
"timestamp": "now",
@@ -89,7 +89,7 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(result[0]['success'], False)
assert_equal(result[0]['error']['code'], -8)
assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], False)
assert_equal(address_assert['ismine'], False)
assert_equal('timestamp' in address_assert, False)
@@ -97,7 +97,7 @@ class ImportMultiTest (BitcoinTestFramework):
# Address + Public key + !Internal
self.log.info("Should import an address with public key")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": {
"address": address['address']
@@ -106,7 +106,7 @@ class ImportMultiTest (BitcoinTestFramework):
"pubkeys": [ address['pubkey'] ]
}])
assert_equal(result[0]['success'], True)
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], True)
assert_equal(address_assert['ismine'], False)
assert_equal(address_assert['timestamp'], timestamp)
@@ -114,7 +114,7 @@ class ImportMultiTest (BitcoinTestFramework):
# ScriptPubKey + Public key + internal
self.log.info("Should import a scriptPubKey with internal and with public key")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
request = [{
"scriptPubKey": address['scriptPubKey'],
"timestamp": "now",
@@ -123,14 +123,14 @@ class ImportMultiTest (BitcoinTestFramework):
}]
result = self.nodes[1].importmulti(request)
assert_equal(result[0]['success'], True)
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], True)
assert_equal(address_assert['ismine'], False)
assert_equal(address_assert['timestamp'], timestamp)
# ScriptPubKey + Public key + !internal
self.log.info("Should not import a scriptPubKey without internal and with public key")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
request = [{
"scriptPubKey": address['scriptPubKey'],
"timestamp": "now",
@@ -140,14 +140,14 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(result[0]['success'], False)
assert_equal(result[0]['error']['code'], -8)
assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], False)
assert_equal(address_assert['ismine'], False)
assert_equal('timestamp' in address_assert, False)
# Address + Private key + !watchonly
self.log.info("Should import an address with private key")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": {
"address": address['address']
@@ -156,7 +156,7 @@ class ImportMultiTest (BitcoinTestFramework):
"keys": [ self.nodes[0].dumpprivkey(address['address']) ]
}])
assert_equal(result[0]['success'], True)
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], False)
assert_equal(address_assert['ismine'], True)
assert_equal(address_assert['timestamp'], timestamp)
@@ -175,7 +175,7 @@ class ImportMultiTest (BitcoinTestFramework):
# Address + Private key + watchonly
self.log.info("Should not import an address with private key and with watchonly")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": {
"address": address['address']
@@ -187,14 +187,14 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(result[0]['success'], False)
assert_equal(result[0]['error']['code'], -8)
assert_equal(result[0]['error']['message'], 'Incompatibility found between watchonly and keys')
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], False)
assert_equal(address_assert['ismine'], False)
assert_equal('timestamp' in address_assert, False)
# ScriptPubKey + Private key + internal
self.log.info("Should import a scriptPubKey with internal and with private key")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": address['scriptPubKey'],
"timestamp": "now",
@@ -202,14 +202,14 @@ class ImportMultiTest (BitcoinTestFramework):
"internal": True
}])
assert_equal(result[0]['success'], True)
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], False)
assert_equal(address_assert['ismine'], True)
assert_equal(address_assert['timestamp'], timestamp)
# ScriptPubKey + Private key + !internal
self.log.info("Should not import a scriptPubKey without internal and with private key")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": address['scriptPubKey'],
"timestamp": "now",
@@ -218,16 +218,16 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(result[0]['success'], False)
assert_equal(result[0]['error']['code'], -8)
assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], False)
assert_equal(address_assert['ismine'], False)
assert_equal('timestamp' in address_assert, False)
# P2SH address
- sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
self.nodes[1].generate(100)
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
@@ -242,7 +242,7 @@ class ImportMultiTest (BitcoinTestFramework):
"timestamp": "now",
}])
assert_equal(result[0]['success'], True)
- address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
+ address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
assert_equal(address_assert['isscript'], True)
assert_equal(address_assert['iswatchonly'], True)
assert_equal(address_assert['timestamp'], timestamp)
@@ -252,9 +252,9 @@ class ImportMultiTest (BitcoinTestFramework):
# P2SH + Redeem script
- sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
self.nodes[1].generate(100)
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
@@ -270,7 +270,7 @@ class ImportMultiTest (BitcoinTestFramework):
"redeemscript": multi_sig_script['redeemScript']
}])
assert_equal(result[0]['success'], True)
- address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
+ address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
assert_equal(address_assert['timestamp'], timestamp)
p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
@@ -279,9 +279,9 @@ class ImportMultiTest (BitcoinTestFramework):
# P2SH + Redeem script + Private Keys + !Watchonly
- sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
self.nodes[1].generate(100)
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
@@ -298,7 +298,7 @@ class ImportMultiTest (BitcoinTestFramework):
"keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])]
}])
assert_equal(result[0]['success'], True)
- address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
+ address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
assert_equal(address_assert['timestamp'], timestamp)
p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
@@ -306,9 +306,9 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(p2shunspent['solvable'], True)
# P2SH + Redeem script + Private Keys + Watchonly
- sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
self.nodes[1].generate(100)
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
@@ -332,8 +332,8 @@ class ImportMultiTest (BitcoinTestFramework):
# Address + Public key + !Internal + Wrong pubkey
self.log.info("Should not import an address with a wrong public key")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": {
"address": address['address']
@@ -344,7 +344,7 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(result[0]['success'], False)
assert_equal(result[0]['error']['code'], -5)
assert_equal(result[0]['error']['message'], 'Consistency check failed')
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], False)
assert_equal(address_assert['ismine'], False)
assert_equal('timestamp' in address_assert, False)
@@ -352,8 +352,8 @@ class ImportMultiTest (BitcoinTestFramework):
# ScriptPubKey + Public key + internal + Wrong pubkey
self.log.info("Should not import a scriptPubKey with internal and with a wrong public key")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
request = [{
"scriptPubKey": address['scriptPubKey'],
"timestamp": "now",
@@ -364,7 +364,7 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(result[0]['success'], False)
assert_equal(result[0]['error']['code'], -5)
assert_equal(result[0]['error']['message'], 'Consistency check failed')
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], False)
assert_equal(address_assert['ismine'], False)
assert_equal('timestamp' in address_assert, False)
@@ -372,8 +372,8 @@ class ImportMultiTest (BitcoinTestFramework):
# Address + Private key + !watchonly + Wrong private key
self.log.info("Should not import an address with a wrong private key")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": {
"address": address['address']
@@ -384,7 +384,7 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(result[0]['success'], False)
assert_equal(result[0]['error']['code'], -5)
assert_equal(result[0]['error']['message'], 'Consistency check failed')
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], False)
assert_equal(address_assert['ismine'], False)
assert_equal('timestamp' in address_assert, False)
@@ -392,8 +392,8 @@ class ImportMultiTest (BitcoinTestFramework):
# ScriptPubKey + Private key + internal + Wrong private key
self.log.info("Should not import a scriptPubKey with internal and with a wrong private key")
- address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+ address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
result = self.nodes[1].importmulti([{
"scriptPubKey": address['scriptPubKey'],
"timestamp": "now",
@@ -403,7 +403,7 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(result[0]['success'], False)
assert_equal(result[0]['error']['code'], -5)
assert_equal(result[0]['error']['message'], 'Consistency check failed')
- address_assert = self.nodes[1].validateaddress(address['address'])
+ address_assert = self.nodes[1].getaddressinfo(address['address'])
assert_equal(address_assert['iswatchonly'], False)
assert_equal(address_assert['ismine'], False)
assert_equal('timestamp' in address_assert, False)
@@ -419,7 +419,7 @@ class ImportMultiTest (BitcoinTestFramework):
"timestamp": "now",
}])
assert_equal(result[0]['success'], True)
- address_assert = self.nodes[1].validateaddress(watchonly_address)
+ address_assert = self.nodes[1].getaddressinfo(watchonly_address)
assert_equal(address_assert['iswatchonly'], True)
assert_equal(address_assert['ismine'], False)
assert_equal(address_assert['timestamp'], timestamp)
@@ -429,7 +429,7 @@ class ImportMultiTest (BitcoinTestFramework):
# restart nodes to check for proper serialization/deserialization of watch only address
self.stop_nodes()
self.start_nodes()
- address_assert = self.nodes[1].validateaddress(watchonly_address)
+ address_assert = self.nodes[1].getaddressinfo(watchonly_address)
assert_equal(address_assert['iswatchonly'], True)
assert_equal(address_assert['ismine'], False)
assert_equal(address_assert['timestamp'], watchonly_timestamp)
diff --git a/test/functional/wallet_importprunedfunds.py b/test/functional/wallet_importprunedfunds.py
index 6b2919b5ae..4d349db23f 100755
--- a/test/functional/wallet_importprunedfunds.py
+++ b/test/functional/wallet_importprunedfunds.py
@@ -26,7 +26,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
address3_privkey = self.nodes[0].dumpprivkey(address3) # Using privkey
#Check only one address
- address_info = self.nodes[0].validateaddress(address1)
+ address_info = self.nodes[0].getaddressinfo(address1)
assert_equal(address_info['ismine'], True)
self.sync_all()
@@ -35,15 +35,15 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
assert_equal(self.nodes[1].getblockcount(),101)
#Address Test - before import
- address_info = self.nodes[1].validateaddress(address1)
+ address_info = self.nodes[1].getaddressinfo(address1)
assert_equal(address_info['iswatchonly'], False)
assert_equal(address_info['ismine'], False)
- address_info = self.nodes[1].validateaddress(address2)
+ address_info = self.nodes[1].getaddressinfo(address2)
assert_equal(address_info['iswatchonly'], False)
assert_equal(address_info['ismine'], False)
- address_info = self.nodes[1].validateaddress(address3)
+ address_info = self.nodes[1].getaddressinfo(address3)
assert_equal(address_info['iswatchonly'], False)
assert_equal(address_info['ismine'], False)
@@ -86,13 +86,13 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
assert_equal(balance3, Decimal('0.075'))
#Addresses Test - after import
- address_info = self.nodes[1].validateaddress(address1)
+ address_info = self.nodes[1].getaddressinfo(address1)
assert_equal(address_info['iswatchonly'], False)
assert_equal(address_info['ismine'], False)
- address_info = self.nodes[1].validateaddress(address2)
+ address_info = self.nodes[1].getaddressinfo(address2)
assert_equal(address_info['iswatchonly'], True)
assert_equal(address_info['ismine'], False)
- address_info = self.nodes[1].validateaddress(address3)
+ address_info = self.nodes[1].getaddressinfo(address3)
assert_equal(address_info['iswatchonly'], False)
assert_equal(address_info['ismine'], True)
diff --git a/test/functional/wallet_keypool.py b/test/functional/wallet_keypool.py
index 45a5eed8ec..9825e4d894 100755
--- a/test/functional/wallet_keypool.py
+++ b/test/functional/wallet_keypool.py
@@ -14,7 +14,7 @@ class KeyPoolTest(BitcoinTestFramework):
def run_test(self):
nodes = self.nodes
addr_before_encrypting = nodes[0].getnewaddress()
- addr_before_encrypting_data = nodes[0].validateaddress(addr_before_encrypting)
+ addr_before_encrypting_data = nodes[0].getaddressinfo(addr_before_encrypting)
wallet_info_old = nodes[0].getwalletinfo()
assert(addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['hdmasterkeyid'])
@@ -24,7 +24,7 @@ class KeyPoolTest(BitcoinTestFramework):
self.start_node(0)
# Keep creating keys
addr = nodes[0].getnewaddress()
- addr_data = nodes[0].validateaddress(addr)
+ addr_data = nodes[0].getaddressinfo(addr)
wallet_info = nodes[0].getwalletinfo()
assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['hdmasterkeyid'])
assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid'])
diff --git a/test/functional/wallet_keypool_topup.py b/test/functional/wallet_keypool_topup.py
index e7af3c3987..e7b76dfaf2 100755
--- a/test/functional/wallet_keypool_topup.py
+++ b/test/functional/wallet_keypool_topup.py
@@ -68,7 +68,7 @@ class KeypoolRestoreTest(BitcoinTestFramework):
assert_equal(self.nodes[1].listtransactions()[0]['category'], "receive")
# Check that we have marked all keys up to the used keypool key as used
- assert_equal(self.nodes[1].validateaddress(self.nodes[1].getnewaddress())['hdkeypath'], "m/0'/0'/110'")
+ assert_equal(self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress())['hdkeypath'], "m/0'/0'/110'")
if __name__ == '__main__':
KeypoolRestoreTest().main()
diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py
index 67e7744bf8..25e2716661 100755
--- a/test/functional/wallet_listsinceblock.py
+++ b/test/functional/wallet_listsinceblock.py
@@ -158,7 +158,7 @@ class ListSinceBlockTest (BitcoinTestFramework):
'vout': utxo['vout'],
}]
txid1 = self.nodes[1].sendrawtransaction(
- self.nodes[1].signrawtransaction(
+ self.nodes[1].signrawtransactionwithwallet(
self.nodes[1].createrawtransaction(utxoDicts, recipientDict))['hex'])
# send from nodes[2] using utxo to nodes[3]
@@ -167,7 +167,7 @@ class ListSinceBlockTest (BitcoinTestFramework):
self.nodes[2].getnewaddress(): change,
}
self.nodes[2].sendrawtransaction(
- self.nodes[2].signrawtransaction(
+ self.nodes[2].signrawtransactionwithwallet(
self.nodes[2].createrawtransaction(utxoDicts, recipientDict2))['hex'])
# generate on both sides
@@ -232,7 +232,7 @@ class ListSinceBlockTest (BitcoinTestFramework):
'txid': utxo['txid'],
'vout': utxo['vout'],
}]
- signedtxres = self.nodes[2].signrawtransaction(
+ signedtxres = self.nodes[2].signrawtransactionwithwallet(
self.nodes[2].createrawtransaction(utxoDicts, recipientDict))
assert signedtxres['complete']
diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py
index ce26d6e0ee..d742ec4618 100755
--- a/test/functional/wallet_txn_clone.py
+++ b/test/functional/wallet_txn_clone.py
@@ -78,7 +78,7 @@ class TxnMallTest(BitcoinTestFramework):
# Use a different signature hash type to sign. This creates an equivalent but malleated clone.
# Don't send the clone anywhere yet
- tx1_clone = self.nodes[0].signrawtransaction(clone_raw, None, None, "ALL|ANYONECANPAY")
+ tx1_clone = self.nodes[0].signrawtransactionwithwallet(clone_raw, None, "ALL|ANYONECANPAY")
assert_equal(tx1_clone["complete"], True)
# Have node0 mine a block, if requested:
diff --git a/test/functional/wallet_txn_doublespend.py b/test/functional/wallet_txn_doublespend.py
index 01129f3817..f16756eeaa 100755
--- a/test/functional/wallet_txn_doublespend.py
+++ b/test/functional/wallet_txn_doublespend.py
@@ -58,7 +58,7 @@ class TxnMallTest(BitcoinTestFramework):
outputs[node1_address] = 1240
outputs[change_address] = 1248 - 1240 + doublespend_fee
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- doublespend = self.nodes[0].signrawtransaction(rawtx)
+ doublespend = self.nodes[0].signrawtransactionwithwallet(rawtx)
assert_equal(doublespend["complete"], True)
# Create two spends using 1 50 BTC coin each