diff --git a/ci/build_src.sh b/ci/build_src.sh index 6422b0f2f3..b60f14a866 100755 --- a/ci/build_src.sh +++ b/ci/build_src.sh @@ -15,6 +15,8 @@ export CCACHE_SIZE=${CCACHE_SIZE:-400M} if [ "$PULL_REQUEST" != "false" ]; then contrib/devtools/commit-script-check.sh $COMMIT_RANGE; fi #if [ "$CHECK_DOC" = 1 ]; then contrib/devtools/check-doc.py; fi TODO reenable after all Bitcoin PRs have been merged and docs fully fixed +if [ "$CHECK_DOC" = 1 ]; then contrib/devtools/check-rpc-mappings.py .; fi +if [ "$CHECK_DOC" = 1 ]; then contrib/devtools/lint-all.sh; fi ccache --max-size=$CCACHE_SIZE diff --git a/contrib/dashd.bash-completion b/contrib/dashd.bash-completion index 18e25097fa..020e22465f 100644 --- a/contrib/dashd.bash-completion +++ b/contrib/dashd.bash-completion @@ -30,7 +30,7 @@ _dashd() { ;; *) - # only parse -help if senseful + # only parse -help if sensible if [[ -z "$cur" || "$cur" =~ ^- ]]; then local helpopts helpopts=$($dashd -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 8393086973..30ef275873 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -150,11 +150,11 @@ Perform basic ELF security checks on a series of executables. symbol-check.py =============== -A script to check that the (Linux) executables produced by gitian only contain +A script to check that the (Linux) executables produced by Gitian only contain allowed gcc, glibc and libstdc++ version symbols. This makes sure they are still compatible with the minimum supported Linux distribution versions. -Example usage after a gitian build: +Example usage after a Gitian build: find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py diff --git a/contrib/devtools/check-rpc-mappings.py b/contrib/devtools/check-rpc-mappings.py new file mode 100755 index 0000000000..7d164e56a6 --- /dev/null +++ b/contrib/devtools/check-rpc-mappings.py @@ -0,0 +1,163 @@ +#!/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. +"""Check RPC argument consistency.""" + +from collections import defaultdict +import os +import re +import sys + +# Source files (relative to root) to scan for dispatch tables +SOURCES = [ + "src/rpc/server.cpp", + "src/rpc/blockchain.cpp", + "src/rpc/governance.cpp", + "src/rpc/masternode.cpp", + "src/rpc/mining.cpp", + "src/rpc/misc.cpp", + "src/rpc/net.cpp", + "src/rpc/privatesend.cpp", + "src/rpc/rawtransaction.cpp", + "src/rpc/rpcevo.cpp", + "src/rpc/rpcquorums.cpp", + "src/wallet/rpcwallet.cpp", +] +# Source file (relative to root) containing conversion mapping +SOURCE_CLIENT = 'src/rpc/client.cpp' +# Argument names that should be ignored in consistency checks +IGNORE_DUMMY_ARGS = {'dummy', 'arg0', 'arg1', 'arg2', 'arg3', 'arg4', 'arg5', 'arg6', 'arg7', 'arg8', 'arg9'} + +class RPCCommand: + def __init__(self, name, args): + self.name = name + self.args = args + +class RPCArgument: + def __init__(self, names, idx): + self.names = names + self.idx = idx + self.convert = False + +def parse_string(s): + assert s[0] == '"' + assert s[-1] == '"' + return s[1:-1] + +def process_commands(fname): + """Find and parse dispatch table in implementation file `fname`.""" + cmds = [] + in_rpcs = False + with open(fname, "r") as f: + for line in f: + line = line.rstrip() + if not in_rpcs: + if re.match("static const CRPCCommand .*\[\] =", line): + in_rpcs = True + else: + if line.startswith('};'): + in_rpcs = False + elif '{' in line and '"' in line: + m = re.search('{ *("[^"]*"), *("[^"]*"), *&([^,]*), *{([^}]*)} *},', line) + assert m, 'No match to table expression: %s' % line + name = parse_string(m.group(2)) + args_str = m.group(4).strip() + if args_str: + args = [RPCArgument(parse_string(x.strip()).split('|'), idx) for idx, x in enumerate(args_str.split(','))] + else: + args = [] + cmds.append(RPCCommand(name, args)) + assert not in_rpcs, "Something went wrong with parsing the C++ file: update the regexps" + return cmds + +def process_mapping(fname): + """Find and parse conversion table in implementation file `fname`.""" + cmds = [] + in_rpcs = False + with open(fname, "r") as f: + for line in f: + line = line.rstrip() + if not in_rpcs: + if line == 'static const CRPCConvertParam vRPCConvertParams[] =': + in_rpcs = True + else: + if line.startswith('};'): + in_rpcs = False + elif '{' in line and '"' in line: + m = re.search('{ *("[^"]*"), *([0-9]+) *, *("[^"]*") *},', line) + assert m, 'No match to table expression: %s' % line + name = parse_string(m.group(1)) + idx = int(m.group(2)) + argname = parse_string(m.group(3)) + cmds.append((name, idx, argname)) + assert not in_rpcs + return cmds + +def main(): + root = sys.argv[1] + + # Get all commands from dispatch tables + cmds = [] + for fname in SOURCES: + cmds += process_commands(os.path.join(root, fname)) + + cmds_by_name = {} + for cmd in cmds: + cmds_by_name[cmd.name] = cmd + + # Get current convert mapping for client + client = SOURCE_CLIENT + mapping = set(process_mapping(os.path.join(root, client))) + + print('* Checking consistency between dispatch tables and vRPCConvertParams') + + # Check mapping consistency + errors = 0 + for (cmdname, argidx, argname) in mapping: + try: + rargnames = cmds_by_name[cmdname].args[argidx].names + except IndexError: + print('ERROR: %s argument %i (named %s in vRPCConvertParams) is not defined in dispatch table' % (cmdname, argidx, argname)) + errors += 1 + continue + if argname not in rargnames: + print('ERROR: %s argument %i is named %s in vRPCConvertParams but %s in dispatch table' % (cmdname, argidx, argname, rargnames), file=sys.stderr) + errors += 1 + + # Check for conflicts in vRPCConvertParams conversion + # All aliases for an argument must either be present in the + # conversion table, or not. Anything in between means an oversight + # and some aliases won't work. + for cmd in cmds: + for arg in cmd.args: + convert = [((cmd.name, arg.idx, argname) in mapping) for argname in arg.names] + if any(convert) != all(convert): + print('ERROR: %s argument %s has conflicts in vRPCConvertParams conversion specifier %s' % (cmd.name, arg.names, convert)) + errors += 1 + arg.convert = all(convert) + + # Check for conversion difference by argument name. + # It is preferable for API consistency that arguments with the same name + # have the same conversion, so bin by argument name. + all_methods_by_argname = defaultdict(list) + converts_by_argname = defaultdict(list) + for cmd in cmds: + for arg in cmd.args: + for argname in arg.names: + all_methods_by_argname[argname].append(cmd.name) + converts_by_argname[argname].append(arg.convert) + + for argname, convert in converts_by_argname.items(): + if all(convert) != any(convert): + if argname in IGNORE_DUMMY_ARGS: + # these are testing or dummy, don't warn for them + continue + print('WARNING: conversion mismatch for argument named %s (%s)' % + (argname, list(zip(all_methods_by_argname[argname], converts_by_argname[argname])))) + + sys.exit(errors > 0) + + +if __name__ == '__main__': + main() diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py index 4b1bae6100..2941d2cb6d 100755 --- a/contrib/devtools/github-merge.py +++ b/contrib/devtools/github-merge.py @@ -197,9 +197,10 @@ def main(): print("ERROR: Cannot check out branch %s." % (branch), file=stderr) sys.exit(3) try: - subprocess.check_call([GIT,'fetch','-q',host_repo,'+refs/pull/'+pull+'/*:refs/heads/pull/'+pull+'/*']) + subprocess.check_call([GIT,'fetch','-q',host_repo,'+refs/pull/'+pull+'/*:refs/heads/pull/'+pull+'/*', + '+refs/heads/'+branch+':refs/heads/'+base_branch]) except subprocess.CalledProcessError as e: - print("ERROR: Cannot find pull request #%s on %s." % (pull,host_repo), file=stderr) + print("ERROR: Cannot find pull request #%s or branch %s on %s." % (pull,branch,host_repo), file=stderr) sys.exit(3) try: subprocess.check_call([GIT,'log','-q','-1','refs/heads/'+head_branch], stdout=devnull, stderr=stdout) @@ -211,11 +212,6 @@ def main(): except subprocess.CalledProcessError as e: print("ERROR: Cannot find merge of pull request #%s on %s." % (pull,host_repo), file=stderr) sys.exit(3) - try: - subprocess.check_call([GIT,'fetch','-q',host_repo,'+refs/heads/'+branch+':refs/heads/'+base_branch]) - except subprocess.CalledProcessError as e: - print("ERROR: Cannot find branch %s on %s." % (branch,host_repo), file=stderr) - sys.exit(3) subprocess.check_call([GIT,'checkout','-q',base_branch]) subprocess.call([GIT,'branch','-q','-D',local_merge_branch], stderr=devnull) subprocess.check_call([GIT,'checkout','-q','-b',local_merge_branch]) diff --git a/contrib/devtools/lint-all.sh b/contrib/devtools/lint-all.sh new file mode 100755 index 0000000000..b6d86959c6 --- /dev/null +++ b/contrib/devtools/lint-all.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# +# 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. +# +# This script runs all contrib/devtools/lint-*.sh files, and fails if any exit +# with a non-zero status code. + +set -u + +SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}") +LINTALL=$(basename "${BASH_SOURCE[0]}") + +for f in "${SCRIPTDIR}"/lint-*.sh; do + if [ "$(basename "$f")" != "$LINTALL" ]; then + if ! "$f"; then + echo "^---- failure generated from $f" + exit 1 + fi + fi +done diff --git a/contrib/devtools/lint-whitespace.sh b/contrib/devtools/lint-whitespace.sh new file mode 100755 index 0000000000..7b586420d7 --- /dev/null +++ b/contrib/devtools/lint-whitespace.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# +# 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. +# +# Check for new lines in diff that introduce trailing whitespace. + +# We can't run this check unless we know the commit range for the PR. +if [ -z "${COMMIT_RANGE}" ]; then + echo "Cannot run lint-whitespace.sh without commit range. To run locally, use:" + echo "COMMIT_RANGE='' .lint-whitespace.sh" + echo "For example:" + echo "COMMIT_RANGE='47ba2c3...ee50c9e' .lint-whitespace.sh" + exit 1 +fi + +showdiff() { + if ! git diff -U0 "${COMMIT_RANGE}" -- "." ":(exclude)src/leveldb/" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" ":(exclude)doc/release-notes/"; then + echo "Failed to get a diff" + exit 1 + fi +} + +showcodediff() { + if ! git diff -U0 "${COMMIT_RANGE}" -- *.cpp *.h *.md *.py *.sh ":(exclude)src/leveldb/" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" ":(exclude)doc/release-notes/"; then + echo "Failed to get a diff" + exit 1 + fi +} + +RET=0 + +# Check if trailing whitespace was found in the diff. +if showdiff | grep -E -q '^\+.*\s+$'; then + echo "This diff appears to have added new lines with trailing whitespace." + echo "The following changes were suspected:" + FILENAME="" + SEEN=0 + while read -r line; do + if [[ "$line" =~ ^diff ]]; then + FILENAME="$line" + SEEN=0 + elif [[ "$line" =~ ^@@ ]]; then + LINENUMBER="$line" + else + if [ "$SEEN" -eq 0 ]; then + # The first time a file is seen with trailing whitespace, we print the + # filename (preceded by a newline). + echo + echo "$FILENAME" + echo "$LINENUMBER" + SEEN=1 + fi + echo "$line" + fi + done < <(showdiff | grep -E '^(diff --git |@@|\+.*\s+$)') + RET=1 +fi + +# Check if tab characters were found in the diff. +if showcodediff | grep -P -q '^\+.*\t'; then + echo "This diff appears to have added new lines with tab characters instead of spaces." + echo "The following changes were suspected:" + FILENAME="" + SEEN=0 + while read -r line; do + if [[ "$line" =~ ^diff ]]; then + FILENAME="$line" + SEEN=0 + elif [[ "$line" =~ ^@@ ]]; then + LINENUMBER="$line" + else + if [ "$SEEN" -eq 0 ]; then + # The first time a file is seen with a tab character, we print the + # filename (preceded by a newline). + echo + echo "$FILENAME" + echo "$LINENUMBER" + SEEN=1 + fi + echo "$line" + fi + done < <(showcodediff | grep -P '^(diff --git |@@|\+.*\t)') + RET=1 +fi + +exit $RET diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 6808e77da7..fd20ea16b1 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -3,7 +3,7 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' -A script to check that the (Linux) executables produced by gitian only contain +A script to check that the (Linux) executables produced by Gitian only contain allowed gcc, glibc and libstdc++ version symbols. This makes sure they are still compatible with the minimum supported Linux distribution versions. diff --git a/contrib/gitian-descriptors/README.md b/contrib/gitian-descriptors/README.md index 7b4993b669..f0dc1b4efa 100644 --- a/contrib/gitian-descriptors/README.md +++ b/contrib/gitian-descriptors/README.md @@ -1,4 +1,4 @@ -### Gavin's notes on getting gitian builds up and running using KVM +### Gavin's notes on getting Gitian builds up and running using KVM These instructions distilled from [https://help.ubuntu.com/community/KVM/Installation](https://help.ubuntu.com/community/KVM/Installation). @@ -56,10 +56,10 @@ Here's a description of Gavin's setup on OSX 10.6: 4. Inside the running Ubuntu desktop, install: - sudo apt-get install debootstrap lxc ruby apache2 git apt-cacher-ng python-vm-builder + sudo apt-get install debootstrap lxc ruby apache2 git apt-cacher-ng python-vm-builder 5. Still inside Ubuntu, tell gitian-builder to use LXC, then follow the "Once you've got the right hardware and software" instructions above: - export USE_LXC=1 - git clone git://github.com/dashpay/dash.git - ... etc + export USE_LXC=1 + git clone git://github.com/dashpay/dash.git + ... etc diff --git a/contrib/gitian-keys/README.md b/contrib/gitian-keys/README.md index 439910330d..4b0b7a2615 100644 --- a/contrib/gitian-keys/README.md +++ b/contrib/gitian-keys/README.md @@ -3,7 +3,7 @@ PGP keys This folder contains the public keys of developers and active contributors. -The keys are mainly used to sign git commits or the build results of gitian +The keys are mainly used to sign git commits or the build results of Gitian builds. You can import the keys into gpg as follows. Also, make sure to fetch the diff --git a/contrib/init/dashd.conf b/contrib/init/dashd.conf index fbcb7ebf1e..93f7cc1206 100644 --- a/contrib/init/dashd.conf +++ b/contrib/init/dashd.conf @@ -30,12 +30,12 @@ pre-start script echo echo "This password is security critical to securing wallets " echo "and must not be the same as the rpcuser setting." - echo "You can generate a suitable random password using the following" + echo "You can generate a suitable random password using the following " echo "command from the shell:" echo echo "bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo'" echo - echo "It is also recommended that you also set alertnotify so you are " + echo "It is recommended that you also set alertnotify so you are " echo "notified of problems:" echo echo "ie: alertnotify=echo %%s | mail -s \"Dash Core Alert\"" \ diff --git a/contrib/init/dashd.openrc b/contrib/init/dashd.openrc index 53ccdf7156..85baaeec70 100644 --- a/contrib/init/dashd.openrc +++ b/contrib/init/dashd.openrc @@ -76,12 +76,12 @@ checkconfig() eerror "" eerror "This password is security critical to securing wallets " eerror "and must not be the same as the rpcuser setting." - eerror "You can generate a suitable random password using the following" + eerror "You can generate a suitable random password using the following " eerror "command from the shell:" eerror "" eerror "bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo'" eerror "" - eerror "It is also recommended that you also set alertnotify so you are " + eerror "It is recommended that you also set alertnotify so you are " eerror "notified of problems:" eerror "" eerror "ie: alertnotify=echo %%s | mail -s \"Dash Core Alert\"" \ diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index ed143830c5..8464932a78 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -9,7 +9,7 @@ define $(package)_preprocess_cmds endef define $(package)_set_vars - $(package)_config_opts=--disable-shared --disable-openssl --disable-libevent-regress + $(package)_config_opts=--disable-shared --disable-openssl --disable-libevent-regress --disable-samples $(package)_config_opts_release=--disable-debug-mode $(package)_config_opts_linux=--with-pic endef diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 8166f738bb..001b7be5df 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -560,6 +560,26 @@ Git and GitHub tips or `git fetch upstream-pull`. Afterwards, you can use `upstream-pull/NUMBER/head` in arguments to `git show`, `git checkout` and anywhere a commit id would be acceptable to see the changes from pull request NUMBER. +Scripted diffs +-------------- + +For reformatting and refactoring commits where the changes can be easily automated using a bash script, we use +scripted-diff commits. The bash script is included in the commit message and our Travis CI job checks that +the result of the script is identical to the commit. This aids reviewers since they can verify that the script +does exactly what it's supposed to do. It is also helpful for rebasing (since the same script can just be re-run +on the new master commit). + +To create a scripted-diff: + +- start the commit message with `scripted-diff:` (and then a description of the diff on the same line) +- in the commit message include the bash script between lines containing just the following text: + - `-BEGIN VERIFY SCRIPT-` + - `-END VERIFY SCRIPT-` + +The scripted-diff is verified by the tool `contrib/devtools/commit-script-check.sh` + +Commit `bb81e173` is an example of a scripted-diff. + RPC interface guidelines -------------------------- diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 0ebdbc25bf..c32955dfdf 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -361,7 +361,7 @@ Building Dash Core ---------------- To build Dash Core (for Linux, OS X and Windows) just follow the steps under 'perform -Gitian builds' in [doc/release-process.md](release-process.md#perform-gitian-builds) in the Dash Core repository. +Gitian builds' in [doc/release-process.md](release-process.md#setup-and-perform-gitian-builds) in the Dash Core repository. This may take some time as it will build all the dependencies needed for each descriptor. These dependencies will be cached after a successful build to avoid rebuilding them when possible. diff --git a/doc/release-process.md b/doc/release-process.md index 7c0d400676..125ebb5f93 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -243,9 +243,9 @@ dash-${VERSION}-win32.zip dash-${VERSION}-win64-setup.exe dash-${VERSION}-win64.zip ``` -The `*-debug*` files generated by the gitian build contain debug symbols +The `*-debug*` files generated by the Gitian build contain debug symbols for troubleshooting by developers. It is assumed that anyone that is interested -in debugging can run gitian to generate the files for themselves. To avoid +in debugging can run Gitian to generate the files for themselves. To avoid end-user confusion about which file to pick, as well as save storage space *do not upload these to the dash.org server*. diff --git a/share/certs/PrivateKeyNotes.md b/share/certs/PrivateKeyNotes.md index 8d50144c21..fc15607093 100644 --- a/share/certs/PrivateKeyNotes.md +++ b/share/certs/PrivateKeyNotes.md @@ -38,9 +38,9 @@ that the bitcoin-qt.exe file inside the installer had not been tampered with. However, an attacker could modify the installer's code, so when the setup.exe was run it compromised users' systems. A volunteer to write an auditing tool that checks the setup.exe for tampering, and checks the files in it against -the list of gitian signatures, is needed. +the list of Gitian signatures, is needed. The long-term solution is something like the 'gitian downloader' system, which uses signatures from multiple developers to determine whether or not a binary should be trusted. However, that just pushes the problem to "how will -non-technical users securely get the gitian downloader code to start?" +non-technical users securely get the Gitian downloader code to start?" diff --git a/src/Makefile.am b/src/Makefile.am index 39df62f965..c17041f153 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -252,6 +252,8 @@ BITCOIN_CORE_H = \ wallet/coincontrol.h \ wallet/crypter.h \ wallet/db.h \ + wallet/fees.h \ + wallet/init.h \ wallet/rpcwallet.h \ wallet/wallet.h \ wallet/walletdb.h \ @@ -374,6 +376,8 @@ libdash_wallet_a_SOURCES = \ privatesend/privatesend-util.cpp \ wallet/crypter.cpp \ wallet/db.cpp \ + wallet/fees.cpp \ + wallet/init.cpp \ wallet/rpcdump.cpp \ wallet/rpcwallet.cpp \ wallet/wallet.cpp \ diff --git a/src/addrdb.h b/src/addrdb.h index 4a13b29a0f..3fb60fc036 100644 --- a/src/addrdb.h +++ b/src/addrdb.h @@ -37,7 +37,7 @@ public: SetNull(); } - CBanEntry(int64_t nCreateTimeIn) + explicit CBanEntry(int64_t nCreateTimeIn) { SetNull(); nCreateTime = nCreateTimeIn; diff --git a/src/base58.cpp b/src/base58.cpp index db702cfcd3..c5913e4493 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -218,7 +218,7 @@ private: CBitcoinAddress* addr; public: - CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {} + explicit CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {} bool operator()(const CKeyID& id) const { return addr->Set(id); } bool operator()(const CScriptID& id) const { return addr->Set(id); } @@ -276,11 +276,11 @@ bool CBitcoinAddress::GetIndexKey(uint160& hashBytes, int& type) const if (!IsValid()) { return false; } else if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) { - memcpy(&hashBytes, &vchData[0], 20); + memcpy(&hashBytes, vchData.data(), 20); type = 1; return true; } else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS)) { - memcpy(&hashBytes, &vchData[0], 20); + memcpy(&hashBytes, vchData.data(), 20); type = 2; return true; } diff --git a/src/bench/checkqueue.cpp b/src/bench/checkqueue.cpp index 88a2a570f9..b7ae5c2d57 100644 --- a/src/bench/checkqueue.cpp +++ b/src/bench/checkqueue.cpp @@ -67,7 +67,7 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::State& state) prevector p; PrevectorJob(){ } - PrevectorJob(FastRandomContext& insecure_rand){ + explicit PrevectorJob(FastRandomContext& insecure_rand){ p.resize(insecure_rand.randrange(PREVECTOR_SIZE*2)); } bool operator()() diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp index 3ec9437d8c..f518d62349 100644 --- a/src/bench/crypto_hash.cpp +++ b/src/bench/crypto_hash.cpp @@ -48,7 +48,7 @@ static void HASH_SHA256_0032b(benchmark::State& state) std::vector in(32,0); while (state.KeepRunning()) { for (int i = 0; i < 1000000; i++) { - CSHA256().Write(in.data(), in.size()).Finalize(&in[0]); + CSHA256().Write(in.data(), in.size()).Finalize(in.data()); } } } @@ -66,7 +66,7 @@ static void HASH_DSHA256_0032b(benchmark::State& state) std::vector in(32,0); while (state.KeepRunning()) { for (int i = 0; i < 1000000; i++) { - CHash256().Write(in.data(), in.size()).Finalize(&in[0]); + CHash256().Write(in.data(), in.size()).Finalize(in.data()); } } } @@ -123,42 +123,42 @@ static void HASH_DSHA256_0032b_single(benchmark::State& state) { std::vector in(32,0); while (state.KeepRunning()) - CHash256().Write(in.data(), in.size()).Finalize(&in[0]); + CHash256().Write(in.data(), in.size()).Finalize(in.data()); } static void HASH_DSHA256_0080b_single(benchmark::State& state) { std::vector in(80,0); while (state.KeepRunning()) - CHash256().Write(in.data(), in.size()).Finalize(&in[0]); + CHash256().Write(in.data(), in.size()).Finalize(in.data()); } static void HASH_DSHA256_0128b_single(benchmark::State& state) { std::vector in(128,0); while (state.KeepRunning()) - CHash256().Write(in.data(), in.size()).Finalize(&in[0]); + CHash256().Write(in.data(), in.size()).Finalize(in.data()); } static void HASH_DSHA256_0512b_single(benchmark::State& state) { std::vector in(512,0); while (state.KeepRunning()) - CHash256().Write(in.data(), in.size()).Finalize(&in[0]); + CHash256().Write(in.data(), in.size()).Finalize(in.data()); } static void HASH_DSHA256_1024b_single(benchmark::State& state) { std::vector in(1024,0); while (state.KeepRunning()) - CHash256().Write(in.data(), in.size()).Finalize(&in[0]); + CHash256().Write(in.data(), in.size()).Finalize(in.data()); } static void HASH_DSHA256_2048b_single(benchmark::State& state) { std::vector in(2048,0); while (state.KeepRunning()) - CHash256().Write(in.data(), in.size()).Finalize(&in[0]); + CHash256().Write(in.data(), in.size()).Finalize(in.data()); } static void HASH_X11(benchmark::State& state) diff --git a/src/bip39.cpp b/src/bip39.cpp index 7a8f5fb346..458f5688b8 100644 --- a/src/bip39.cpp +++ b/src/bip39.cpp @@ -37,7 +37,7 @@ SecureString CMnemonic::Generate(int strength) return SecureString(); } SecureVector data(32); - GetStrongRandBytes(&data[0], 32); + GetStrongRandBytes(data.data(), 32); SecureString mnemonic = FromData(data, strength / 8); return mnemonic; } @@ -50,11 +50,11 @@ SecureString CMnemonic::FromData(const SecureVector& data, int len) } SecureVector checksum(32); - CSHA256().Write(&data[0], len).Finalize(&checksum[0]); + CSHA256().Write(data.data(), len).Finalize(checksum.data()); // data SecureVector bits(len); - memcpy(&bits[0], &data[0], len); + memcpy(bits.data(), data.data(), len); // checksum bits.push_back(checksum[0]); @@ -132,7 +132,7 @@ bool CMnemonic::Check(SecureString mnemonic) return false; } bits[32] = bits[nWordCount * 4 / 3]; - CSHA256().Write(&bits[0], nWordCount * 4 / 3).Finalize(&bits[0]); + CSHA256().Write(bits.data(), nWordCount * 4 / 3).Finalize(bits.data()); bool fResult = 0; if (nWordCount == 12) { @@ -158,5 +158,5 @@ void CMnemonic::ToSeed(SecureString mnemonic, SecureString passphrase, SecureVec // const unsigned char *salt, int saltlen, int iter, // const EVP_MD *digest, // int keylen, unsigned char *out); - PKCS5_PBKDF2_HMAC(mnemonic.c_str(), mnemonic.size(), &vchSalt[0], vchSalt.size(), 2048, EVP_sha512(), 64, &seedRet[0]); + PKCS5_PBKDF2_HMAC(mnemonic.c_str(), mnemonic.size(), vchSalt.data(), vchSalt.size(), 2048, EVP_sha512(), 64, seedRet.data()); } diff --git a/src/blockencodings.h b/src/blockencodings.h index a768a753f5..a6f8af099f 100644 --- a/src/blockencodings.h +++ b/src/blockencodings.h @@ -16,7 +16,7 @@ struct TransactionCompressor { private: CTransactionRef& tx; public: - TransactionCompressor(CTransactionRef& txIn) : tx(txIn) {} + explicit TransactionCompressor(CTransactionRef& txIn) : tx(txIn) {} ADD_SERIALIZE_METHODS; @@ -75,7 +75,7 @@ public: std::vector txn; BlockTransactions() {} - BlockTransactions(const BlockTransactionsRequest& req) : + explicit BlockTransactions(const BlockTransactionsRequest& req) : blockhash(req.blockhash), txn(req.indexes.size()) {} ADD_SERIALIZE_METHODS; @@ -198,7 +198,7 @@ protected: CTxMemPool* pool; public: CBlockHeader header; - PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {} + explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {} // extra_txn is a list of extra transactions to look at, in form ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector>& extra_txn); diff --git a/src/bls/bls_worker.h b/src/bls/bls_worker.h index e119091037..3170f04972 100644 --- a/src/bls/bls_worker.h +++ b/src/bls/bls_worker.h @@ -158,7 +158,7 @@ private: std::map > publicKeyShareCache; public: - CBLSWorkerCache(CBLSWorker& _worker) : + explicit CBLSWorkerCache(CBLSWorker& _worker) : worker(_worker) {} BLSVerificationVectorPtr BuildQuorumVerificationVector(const uint256& cacheKey, const std::vector& vvecs) diff --git a/src/cachemap.h b/src/cachemap.h index 8b45b67014..c4d973b401 100644 --- a/src/cachemap.h +++ b/src/cachemap.h @@ -70,7 +70,7 @@ private: map_t mapIndex; public: - CacheMap(size_type nMaxSizeIn = 0) + explicit CacheMap(size_type nMaxSizeIn = 0) : nMaxSize(nMaxSizeIn), listItems(), mapIndex() diff --git a/src/chain.cpp b/src/chain.cpp index 351cba846d..cb1e1cc660 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -128,7 +128,7 @@ arith_uint256 GetBlockProof(const CBlockIndex& block) // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 // as it's too large for an arith_uint256. However, as 2**256 is at least as large // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, - // or ~bnTarget / (nTarget+1) + 1. + // or ~bnTarget / (bnTarget+1) + 1. return (~bnTarget / (bnTarget + 1)) + 1; } diff --git a/src/chain.h b/src/chain.h index 421bfb1a54..f29580e7fb 100644 --- a/src/chain.h +++ b/src/chain.h @@ -204,14 +204,14 @@ public: unsigned int nChainTx; //! Verification status of this block. See enum BlockStatus - unsigned int nStatus; + uint32_t nStatus; //! block header - int nVersion; + int32_t nVersion; uint256 hashMerkleRoot; - unsigned int nTime; - unsigned int nBits; - unsigned int nNonce; + uint32_t nTime; + uint32_t nBits; + uint32_t nNonce; //! (memory only) Sequential id assigned to distinguish order in which blocks are received. int32_t nSequenceId; @@ -247,7 +247,7 @@ public: SetNull(); } - CBlockIndex(const CBlockHeader& block) + explicit CBlockIndex(const CBlockHeader& block) { SetNull(); diff --git a/src/checkqueue.h b/src/checkqueue.h index 4bc6be45f8..6377fbe942 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -131,7 +131,7 @@ public: boost::mutex ControlMutex; //! Create a new check queue - CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} + explicit CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} //! Worker thread void Thread() diff --git a/src/compressor.h b/src/compressor.h index 961365d261..c8d804ba38 100644 --- a/src/compressor.h +++ b/src/compressor.h @@ -53,7 +53,7 @@ protected: unsigned int GetSpecialSize(unsigned int nSize) const; bool Decompress(unsigned int nSize, const std::vector &out); public: - CScriptCompressor(CScript &scriptIn) : script(scriptIn) { } + explicit CScriptCompressor(CScript &scriptIn) : script(scriptIn) { } template void Serialize(Stream &s) const { @@ -99,7 +99,7 @@ public: static uint64_t CompressAmount(uint64_t nAmount); static uint64_t DecompressAmount(uint64_t nAmount); - CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } + explicit CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } ADD_SERIALIZE_METHODS; diff --git a/src/crypto/aes.h b/src/crypto/aes.h index 8cae357c12..fb4df9f863 100644 --- a/src/crypto/aes.h +++ b/src/crypto/aes.h @@ -22,7 +22,7 @@ private: AES128_ctx ctx; public: - AES128Encrypt(const unsigned char key[16]); + explicit AES128Encrypt(const unsigned char key[16]); ~AES128Encrypt(); void Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const; }; @@ -34,7 +34,7 @@ private: AES128_ctx ctx; public: - AES128Decrypt(const unsigned char key[16]); + explicit AES128Decrypt(const unsigned char key[16]); ~AES128Decrypt(); void Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const; }; @@ -46,7 +46,7 @@ private: AES256_ctx ctx; public: - AES256Encrypt(const unsigned char key[32]); + explicit AES256Encrypt(const unsigned char key[32]); ~AES256Encrypt(); void Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const; }; @@ -58,7 +58,7 @@ private: AES256_ctx ctx; public: - AES256Decrypt(const unsigned char key[32]); + explicit AES256Decrypt(const unsigned char key[32]); ~AES256Decrypt(); void Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const; }; diff --git a/src/cuckoocache.h b/src/cuckoocache.h index b9de589fd4..947e1a7185 100644 --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -58,7 +58,7 @@ public: * @post All calls to bit_is_set (without subsequent bit_unset) will return * true. */ - bit_packed_atomic_flags(uint32_t size) + explicit bit_packed_atomic_flags(uint32_t size) { // pad out the size if needed size = (size + 7) / 8; diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 670b31289f..29beb473d1 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -24,7 +24,7 @@ static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024; class dbwrapper_error : public std::runtime_error { public: - dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {} + explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {} }; class CDBWrapper; @@ -63,7 +63,7 @@ public: /** * @param[in] parent CDBWrapper that this batch is to be submitted to */ - CDBBatch(const CDBWrapper &_parent) : parent(_parent), ssKey(SER_DISK, CLIENT_VERSION), ssValue(SER_DISK, CLIENT_VERSION), size_estimate(0) { }; + explicit CDBBatch(const CDBWrapper &_parent) : parent(_parent), ssKey(SER_DISK, CLIENT_VERSION), ssValue(SER_DISK, CLIENT_VERSION), size_estimate(0) { }; void Clear() { @@ -415,7 +415,7 @@ private: bool curIsParent{false}; public: - CDBTransactionIterator(CDBTransaction& _transaction) : + explicit CDBTransactionIterator(CDBTransaction& _transaction) : transaction(_transaction), parentKey(SER_DISK, CLIENT_VERSION) { @@ -736,7 +736,7 @@ private: bool didCommitOrRollback{}; public: - CScopedDBTransaction(Transaction &dbTx) : dbTransaction(dbTx) {} + explicit CScopedDBTransaction(Transaction &dbTx) : dbTransaction(dbTx) {} ~CScopedDBTransaction() { if (!didCommitOrRollback) Rollback(); diff --git a/src/dsnotificationinterface.h b/src/dsnotificationinterface.h index a677c3eb1f..c3c63dcd0f 100644 --- a/src/dsnotificationinterface.h +++ b/src/dsnotificationinterface.h @@ -10,7 +10,7 @@ class CDSNotificationInterface : public CValidationInterface { public: - CDSNotificationInterface(CConnman& connmanIn): connman(connmanIn) {} + explicit CDSNotificationInterface(CConnman& connmanIn): connman(connmanIn) {} virtual ~CDSNotificationInterface() = default; // a small helper to initialize current block height in sub-modules on startup diff --git a/src/evo/deterministicmns.h b/src/evo/deterministicmns.h index 18c0289c96..55c67f153b 100644 --- a/src/evo/deterministicmns.h +++ b/src/evo/deterministicmns.h @@ -52,7 +52,7 @@ public: public: CDeterministicMNState() {} - CDeterministicMNState(const CProRegTx& proTx) + explicit CDeterministicMNState(const CProRegTx& proTx) { keyIDOwner = proTx.keyIDOwner; pubKeyOperator.Set(proTx.pubKeyOperator); @@ -632,7 +632,7 @@ private: const CBlockIndex* tipIndex{nullptr}; public: - CDeterministicMNManager(CEvoDB& _evoDb); + explicit CDeterministicMNManager(CEvoDB& _evoDb); bool ProcessBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, bool fJustCheck); bool UndoBlock(const CBlock& block, const CBlockIndex* pindex); diff --git a/src/evo/evodb.h b/src/evo/evodb.h index 35b94186d3..382066923a 100644 --- a/src/evo/evodb.h +++ b/src/evo/evodb.h @@ -28,7 +28,7 @@ private: CurTransaction curDBTransaction; public: - CEvoDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); + explicit CEvoDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); std::unique_ptr BeginTransaction() { diff --git a/src/evo/simplifiedmns.h b/src/evo/simplifiedmns.h index 8800c37453..39ffc0fc3e 100644 --- a/src/evo/simplifiedmns.h +++ b/src/evo/simplifiedmns.h @@ -33,7 +33,7 @@ public: public: CSimplifiedMNListEntry() {} - CSimplifiedMNListEntry(const CDeterministicMN& dmn); + explicit CSimplifiedMNListEntry(const CDeterministicMN& dmn); bool operator==(const CSimplifiedMNListEntry& rhs) const { @@ -78,8 +78,8 @@ public: public: CSimplifiedMNList() {} - CSimplifiedMNList(const std::vector& smlEntries); - CSimplifiedMNList(const CDeterministicMNList& dmnList); + explicit CSimplifiedMNList(const std::vector& smlEntries); + explicit CSimplifiedMNList(const CDeterministicMNList& dmnList); uint256 CalcMerkleRoot(bool* pmutated = nullptr) const; }; diff --git a/src/flat-database.h b/src/flat-database.h index 0f4ec0ad19..8ed7442635 100644 --- a/src/flat-database.h +++ b/src/flat-database.h @@ -97,7 +97,7 @@ private: // read data and checksum from file try { - filein.read((char *)&vchData[0], dataSize); + filein.read((char *)vchData.data(), dataSize); filein >> hashIn; } catch (std::exception &e) { diff --git a/src/governance/governance-classes.h b/src/governance/governance-classes.h index 9ed8e0df1f..780b9dda94 100644 --- a/src/governance/governance-classes.h +++ b/src/governance/governance-classes.h @@ -141,7 +141,7 @@ private: public: CSuperblock(); - CSuperblock(uint256& nHash); + explicit CSuperblock(uint256& nHash); static bool IsValidBlockHeight(int nBlockHeight); static void GetNearestSuperblocksHeights(int nBlockHeight, int& nLastSuperblockRet, int& nNextSuperblockRet); diff --git a/src/hash.h b/src/hash.h index e4e579f3c4..ddb7140e57 100644 --- a/src/hash.h +++ b/src/hash.h @@ -102,20 +102,6 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end, return result; } -/** Compute the 256-bit hash of the concatenation of three objects. */ -template -inline uint256 Hash(const T1 p1begin, const T1 p1end, - const T2 p2begin, const T2 p2end, - const T3 p3begin, const T3 p3end) { - static const unsigned char pblank[1] = {}; - uint256 result; - CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])) - .Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])) - .Write(p3begin == p3end ? pblank : (const unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])) - .Finalize((unsigned char*)&result); - return result; -} - /** Compute the 256-bit hash of the concatenation of three objects. */ template inline uint256 Hash(const T1 p1begin, const T1 p1end, @@ -236,7 +222,7 @@ private: Source* source; public: - CHashVerifier(Source* source_) : CHashWriter(source_->GetType(), source_->GetVersion()), source(source_) {} + explicit CHashVerifier(Source* source_) : CHashWriter(source_->GetType(), source_->GetVersion()), source(source_) {} void read(char* pch, size_t nSize) { diff --git a/src/hdchain.cpp b/src/hdchain.cpp index da6398dab6..04e943d92d 100644 --- a/src/hdchain.cpp +++ b/src/hdchain.cpp @@ -53,7 +53,7 @@ void CHDChain::Debug(const std::string& strName) const std::cout << "seed: " << HexStr(vchSeed).c_str() << std::endl; CExtKey extkey; - extkey.SetMaster(&vchSeed[0], vchSeed.size()); + extkey.SetMaster(vchSeed.data(), vchSeed.size()); CBitcoinExtKey b58extkey; b58extkey.SetKey(extkey); @@ -158,7 +158,7 @@ void CHDChain::DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_ CExtKey changeKey; //key at m/purpose'/coin_type'/account'/change CExtKey childKey; //key at m/purpose'/coin_type'/account'/change/address_index - masterKey.SetMaster(&vchSeed[0], vchSeed.size()); + masterKey.SetMaster(vchSeed.data(), vchSeed.size()); // Use hardened derivation for purpose, coin_type and account // (keys >= 0x80000000 are hardened after bip32) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 3cd136b17f..c386347e1b 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -43,7 +43,7 @@ private: class HTTPRPCTimerInterface : public RPCTimerInterface { public: - HTTPRPCTimerInterface(struct event_base* _base) : base(_base) + explicit HTTPRPCTimerInterface(struct event_base* _base) : base(_base) { } const char* Name() override diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 46345978f6..933921a7d9 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -79,7 +79,7 @@ private: size_t maxDepth; public: - WorkQueue(size_t _maxDepth) : running(true), + explicit WorkQueue(size_t _maxDepth) : running(true), maxDepth(_maxDepth) { } diff --git a/src/httpserver.h b/src/httpserver.h index 7f57d7d790..d597f155a2 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -61,7 +61,7 @@ private: bool replySent; public: - HTTPRequest(struct evhttp_request* req); + explicit HTTPRequest(struct evhttp_request* req); ~HTTPRequest(); enum RequestMethod { diff --git a/src/init.cpp b/src/init.cpp index 5b536baa13..5153ef0eb7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -46,7 +46,7 @@ #include "utilmoneystr.h" #include "validationinterface.h" #ifdef ENABLE_WALLET -#include "wallet/wallet.h" +#include "wallet/init.h" #endif #include "masternode/activemasternode.h" @@ -134,12 +134,11 @@ static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; // created by AppInit() or the Qt main() function. // // A clean exit happens when StartShutdown() or the SIGTERM -// signal handler sets fRequestShutdown, which triggers -// the DetectShutdownThread(), which interrupts the main thread group. -// DetectShutdownThread() then exits, which causes AppInit() to -// continue (it .joins the shutdown thread). -// Shutdown() is then -// called to clean up database connections, and stop other +// signal handler sets fRequestShutdown, which makes main thread's +// WaitForShutdown() interrupts the thread group. +// And then, WaitForShutdown() makes all other on-going threads +// in the thread group join the main thread. +// Shutdown() is then called to clean up database connections, and stop other // threads that should only be stopped after the main network-processing // threads have exited. // @@ -173,7 +172,7 @@ bool ShutdownRequested() class CCoinsViewErrorCatcher final : public CCoinsViewBacked { public: - CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {} + explicit CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {} bool GetCoin(const COutPoint &outpoint, Coin &coin) const override { try { return CCoinsViewBacked::GetCoin(outpoint, coin); @@ -238,9 +237,7 @@ void PrepareShutdown() privateSendClient.fPrivateSendRunning = false; privateSendClient.ResetPool(); } - for (CWalletRef pwallet : vpwallets) { - pwallet->Flush(false); - } + FlushWallets(); #endif MapPort(false); @@ -314,9 +311,7 @@ void PrepareShutdown() evoDb = nullptr; } #ifdef ENABLE_WALLET - for (CWalletRef pwallet : vpwallets) { - pwallet->Flush(true); - } + StopWallets(); #endif #if ENABLE_ZMQ @@ -369,10 +364,7 @@ void Shutdown() // Shutdown part 2: Stop TOR thread and delete wallet instance StopTorControl(); #ifdef ENABLE_WALLET - for (CWalletRef pwallet : vpwallets) { - delete pwallet; - } - vpwallets.clear(); + CloseWallets(); #endif globalVerifyHandle.reset(); ECC_Stop(); @@ -519,7 +511,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-maxuploadtarget=", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET)); #ifdef ENABLE_WALLET - strUsage += CWallet::GetWalletHelpString(showDebug); + strUsage += GetWalletHelpString(showDebug); if (mode == HMM_BITCOIN_QT) strUsage += HelpMessageOpt("-windowtitle=", _("Wallet window title")); #endif @@ -1260,7 +1252,7 @@ bool AppInitParameterInteraction() RegisterAllCoreRPCCommands(tableRPC); #ifdef ENABLE_WALLET - RegisterWalletRPCCommands(tableRPC); + RegisterWalletRPC(tableRPC); #endif nConnectTimeout = gArgs.GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); @@ -1272,7 +1264,7 @@ bool AppInitParameterInteraction() if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) { return InitError(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", ""))); } - // High fee check is done afterward in CWallet::ParameterInteraction() + // High fee check is done afterward in WalletParameterInteraction() ::minRelayTxFee = CFeeRate(n); } else if (incrementalRelayFee > ::minRelayTxFee) { // Allow only setting incrementalRelayFee to control both @@ -1305,7 +1297,7 @@ bool AppInitParameterInteraction() nBytesPerSigOp = gArgs.GetArg("-bytespersigop", nBytesPerSigOp); #ifdef ENABLE_WALLET - if (!CWallet::ParameterInteraction()) + if (!WalletParameterInteraction()) return false; #endif // ENABLE_WALLET @@ -1596,7 +1588,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) if (!CWallet::InitAutoBackup()) return false; - if (!CWallet::Verify()) + if (!VerifyWallets()) return false; // Initialize KeePass Integration @@ -1973,7 +1965,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 8: load wallet #ifdef ENABLE_WALLET - if (!CWallet::InitLoadWallet()) + if (!OpenWallets()) return false; #else LogPrintf("No wallet support compiled in!\n"); @@ -2269,9 +2261,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.InitMessage(_("Done loading")); #ifdef ENABLE_WALLET - for (CWalletRef pwallet : vpwallets) { - pwallet->postInitProcess(scheduler); - } + StartWallets(scheduler); #endif // Final check if the user requested to kill the GUI during one of the last operations. If so, exit. diff --git a/src/keepass.cpp b/src/keepass.cpp index ccc71dc4c8..33031f0a7d 100644 --- a/src/keepass.cpp +++ b/src/keepass.cpp @@ -41,7 +41,7 @@ SecureString DecodeBase64Secure(const SecureString& sInput) BIO *b64, *mem; b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer - mem = BIO_new_mem_buf((void *) &sInput[0], sInput.size()); + mem = BIO_new_mem_buf((void *) sInput.data(), sInput.size()); BIO_push(b64, mem); // Prepare buffer to receive decoded data @@ -53,7 +53,7 @@ SecureString DecodeBase64Secure(const SecureString& sInput) // Decode the string size_t nLen; - nLen = BIO_read(b64, (void *) &output[0], sInput.size()); + nLen = BIO_read(b64, (void *) output.data(), sInput.size()); output.resize(nLen); // Free memory @@ -72,7 +72,7 @@ SecureString EncodeBase64Secure(const SecureString& sInput) BIO_push(b64, mem); // Decode the string - BIO_write(b64, &sInput[0], sInput.size()); + BIO_write(b64, sInput.data(), sInput.size()); (void) BIO_flush(b64); // Create output variable from buffer mem ptr @@ -145,10 +145,10 @@ std::string CKeePassIntegrator::CKeePassRequest::getJson() void CKeePassIntegrator::CKeePassRequest::init() { SecureString sIVSecure = generateRandomKey(KEEPASS_CRYPTO_BLOCK_SIZE); - strIV = std::string(&sIVSecure[0], sIVSecure.size()); + strIV = std::string(sIVSecure.data(), sIVSecure.size()); // Generate Nonce, Verifier and RequestType SecureString sNonceBase64Secure = EncodeBase64Secure(sIVSecure); - addStrParameter("Nonce", std::string(&sNonceBase64Secure[0], sNonceBase64Secure.size())); // Plain + addStrParameter("Nonce", std::string(sNonceBase64Secure.data(), sNonceBase64Secure.size())); // Plain addStrParameter("Verifier", sNonceBase64Secure); // Encoded addStrParameter("RequestType", strType); } @@ -228,7 +228,7 @@ SecureString CKeePassIntegrator::generateRandomKey(size_t nSize) SecureString sKey; sKey.resize(nSize); - GetStrongRandBytes((unsigned char *) &sKey[0], nSize); + GetStrongRandBytes((unsigned char *) sKey.data(), nSize); return sKey; } @@ -463,7 +463,7 @@ void CKeePassIntegrator::rpcAssociate(std::string& strIdRet, SecureString& sKeyB CKeePassRequest request(sKey, "associate"); sKeyBase64Ret = EncodeBase64Secure(sKey); - request.addStrParameter("Key", std::string(&sKeyBase64Ret[0], sKeyBase64Ret.size())); + request.addStrParameter("Key", std::string(sKeyBase64Ret.data(), sKeyBase64Ret.size())); int nStatus; std::string strResponse; diff --git a/src/key.h b/src/key.h index b6c4c2a195..ff9ccddc36 100644 --- a/src/key.h +++ b/src/key.h @@ -56,11 +56,6 @@ public: keydata.resize(32); } - //! Destructor (again necessary because of memlocking). - ~CKey() - { - } - friend bool operator==(const CKey& a, const CKey& b) { return a.fCompressed == b.fCompressed && diff --git a/src/keystore.h b/src/keystore.h index ac0dfd14a5..f2c4f3a9a5 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -31,7 +31,7 @@ public: //! Check whether a key corresponding to a given address is present in the store. virtual bool HaveKey(const CKeyID &address) const =0; virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0; - virtual void GetKeys(std::set &setAddress) const =0; + virtual std::set GetKeys() const =0; virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const =0; //! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki @@ -74,18 +74,14 @@ public: } return result; } - void GetKeys(std::set &setAddress) const override + std::set GetKeys() const override { - setAddress.clear(); - { - LOCK(cs_KeyStore); - KeyMap::const_iterator mi = mapKeys.begin(); - while (mi != mapKeys.end()) - { - setAddress.insert((*mi).first); - mi++; - } + LOCK(cs_KeyStore); + std::set set_address; + for (const auto& mi : mapKeys) { + set_address.insert(mi.first); } + return set_address; } bool GetKey(const CKeyID &address, CKey &keyOut) const override { diff --git a/src/limitedmap.h b/src/limitedmap.h index 23fee18020..1a7df7b145 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -33,7 +33,7 @@ protected: size_type nPruneAfterSize; public: - unordered_limitedmap(size_type nMaxSizeIn, size_type nPruneAfterSizeIn = 0) + explicit unordered_limitedmap(size_type nMaxSizeIn, size_type nPruneAfterSizeIn = 0) { assert(nMaxSizeIn > 0); nMaxSize = nMaxSizeIn; diff --git a/src/llmq/quorums_blockprocessor.h b/src/llmq/quorums_blockprocessor.h index b95207c0d9..089c89c22d 100644 --- a/src/llmq/quorums_blockprocessor.h +++ b/src/llmq/quorums_blockprocessor.h @@ -35,7 +35,7 @@ private: std::unordered_map, bool, StaticSaltedHasher> hasMinedCommitmentCache; public: - CQuorumBlockProcessor(CEvoDB& _evoDb) : evoDb(_evoDb) {} + explicit CQuorumBlockProcessor(CEvoDB& _evoDb) : evoDb(_evoDb) {} void UpgradeDB(); diff --git a/src/llmq/quorums_chainlocks.h b/src/llmq/quorums_chainlocks.h index e1697c34d7..47bf9faf12 100644 --- a/src/llmq/quorums_chainlocks.h +++ b/src/llmq/quorums_chainlocks.h @@ -78,7 +78,7 @@ private: int64_t lastCleanupTime{0}; public: - CChainLocksHandler(CScheduler* _scheduler); + explicit CChainLocksHandler(CScheduler* _scheduler); ~CChainLocksHandler(); void Start(); diff --git a/src/llmq/quorums_dkgsession.h b/src/llmq/quorums_dkgsession.h index 6acc438f10..e0d80b6ce9 100644 --- a/src/llmq/quorums_dkgsession.h +++ b/src/llmq/quorums_dkgsession.h @@ -97,7 +97,7 @@ public: public: CDKGComplaint() {} - CDKGComplaint(const Consensus::LLMQParams& params); + explicit CDKGComplaint(const Consensus::LLMQParams& params); ADD_SERIALIZE_METHODS @@ -170,7 +170,7 @@ public: public: CDKGPrematureCommitment() {} - CDKGPrematureCommitment(const Consensus::LLMQParams& params); + explicit CDKGPrematureCommitment(const Consensus::LLMQParams& params); int CountValidMembers() const { diff --git a/src/llmq/quorums_dkgsessionhandler.h b/src/llmq/quorums_dkgsessionhandler.h index b8e2a9604e..42f8b43515 100644 --- a/src/llmq/quorums_dkgsessionhandler.h +++ b/src/llmq/quorums_dkgsessionhandler.h @@ -46,7 +46,7 @@ private: std::set seenMessages; public: - CDKGPendingMessages(size_t _maxMessagesPerNode); + explicit CDKGPendingMessages(size_t _maxMessagesPerNode); void PushPendingMessage(NodeId from, CDataStream& vRecv); std::list PopPendingMessages(size_t maxCount); diff --git a/src/llmq/quorums_instantsend.h b/src/llmq/quorums_instantsend.h index fe59d9f3a9..0ea315e49f 100644 --- a/src/llmq/quorums_instantsend.h +++ b/src/llmq/quorums_instantsend.h @@ -50,7 +50,7 @@ private: unordered_lru_cache outpointCache; public: - CInstantSendDb(CDBWrapper& _db) : db(_db) {} + explicit CInstantSendDb(CDBWrapper& _db) : db(_db) {} void WriteNewInstantSendLock(const uint256& hash, const CInstantSendLock& islock); void RemoveInstantSendLock(CDBBatch& batch, const uint256& hash, CInstantSendLockPtr islock); @@ -112,7 +112,7 @@ private: std::unordered_set pendingRetryTxs; public: - CInstantSendManager(CDBWrapper& _llmqDb); + explicit CInstantSendManager(CDBWrapper& _llmqDb); ~CInstantSendManager(); void Start(); diff --git a/src/llmq/quorums_signing.h b/src/llmq/quorums_signing.h index 44f7f7910c..eee362d405 100644 --- a/src/llmq/quorums_signing.h +++ b/src/llmq/quorums_signing.h @@ -72,7 +72,7 @@ private: unordered_lru_cache hasSigForHashCache; public: - CRecoveredSigsDb(CDBWrapper& _db); + explicit CRecoveredSigsDb(CDBWrapper& _db); void ConvertInvalidTimeKeys(); void AddVoteTimeKeys(); diff --git a/src/masternode/masternode-meta.h b/src/masternode/masternode-meta.h index 9c005afe3d..75e8990ea1 100644 --- a/src/masternode/masternode-meta.h +++ b/src/masternode/masternode-meta.h @@ -35,7 +35,7 @@ private: public: CMasternodeMetaInfo() {} - CMasternodeMetaInfo(const uint256& _proTxHash) : proTxHash(_proTxHash) {} + explicit CMasternodeMetaInfo(const uint256& _proTxHash) : proTxHash(_proTxHash) {} CMasternodeMetaInfo(const CMasternodeMetaInfo& ref) : proTxHash(ref.proTxHash), nLastDsq(ref.nLastDsq), diff --git a/src/messagesigner.cpp b/src/messagesigner.cpp index 80894dba30..bb1c91d0fd 100644 --- a/src/messagesigner.cpp +++ b/src/messagesigner.cpp @@ -65,7 +65,7 @@ bool CHashSigner::VerifyHash(const uint256& hash, const CKeyID& keyID, const std if(pubkeyFromSig.GetID() != keyID) { strErrorRet = strprintf("Keys don't match: pubkey=%s, pubkeyFromSig=%s, hash=%s, vchSig=%s", keyID.ToString(), pubkeyFromSig.GetID().ToString(), hash.ToString(), - EncodeBase64(&vchSig[0], vchSig.size())); + EncodeBase64(vchSig.data(), vchSig.size())); return false; } diff --git a/src/miner.cpp b/src/miner.cpp index 68aa079b33..96060ccd6c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -136,6 +136,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc LOCK2(cs_main, mempool.cs); CBlockIndex* pindexPrev = chainActive.Tip(); + assert(pindexPrev != nullptr); nHeight = pindexPrev->nHeight + 1; bool fDIP0003Active_context = nHeight >= chainparams.GetConsensus().DIP0003Height; diff --git a/src/miner.h b/src/miner.h index 4494d57126..b3ac851276 100644 --- a/src/miner.h +++ b/src/miner.h @@ -36,7 +36,7 @@ struct CBlockTemplate // Container for tracking updates to ancestor feerate as we include (parent) // transactions in a block struct CTxMemPoolModifiedEntry { - CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) + explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) { iter = entry; nSizeWithAncestors = entry->GetSizeWithAncestors(); @@ -119,7 +119,7 @@ typedef indexed_modified_transaction_set::index::type::iterator struct update_for_parent_inclusion { - update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} + explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} void operator() (CTxMemPoolModifiedEntry &e) { @@ -163,7 +163,7 @@ public: CFeeRate blockMinFeeRate; }; - BlockAssembler(const CChainParams& params); + explicit BlockAssembler(const CChainParams& params); BlockAssembler(const CChainParams& params, const Options& options); /** Construct a new block template with coinbase to scriptPubKeyIn */ diff --git a/src/net_processing.cpp b/src/net_processing.cpp index d5c72ca0a9..da968e0305 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -337,6 +337,7 @@ bool MarkBlockAsReceived(const uint256& hash) { std::map::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash); if (itInFlight != mapBlocksInFlight.end()) { CNodeState *state = State(itInFlight->second.first); + assert(state != nullptr); state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders; if (state->nBlocksInFlightValidHeaders == 0 && itInFlight->second.second->fValidatedHeaders) { // Last validated block on the queue was received. @@ -3470,7 +3471,7 @@ class CompareInvMempoolOrder { CTxMemPool *mp; public: - CompareInvMempoolOrder(CTxMemPool *_mempool) + explicit CompareInvMempoolOrder(CTxMemPool *_mempool) { mp = _mempool; } diff --git a/src/netaddress.h b/src/netaddress.h index 65b64726b9..0e2f6e6b88 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -38,7 +38,7 @@ class CNetAddr public: CNetAddr(); - CNetAddr(const struct in_addr& ipv4Addr); + explicit CNetAddr(const struct in_addr& ipv4Addr); void Init(); void SetIP(const CNetAddr& ip); @@ -84,7 +84,7 @@ class CNetAddr std::vector GetGroup() const; int GetReachabilityFrom(const CNetAddr *paddrPartner = nullptr) const; - CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0); + explicit CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0); bool GetIn6Addr(struct in6_addr* pipv6Addr) const; friend bool operator==(const CNetAddr& a, const CNetAddr& b); @@ -148,7 +148,7 @@ class CService : public CNetAddr CService(); CService(const CNetAddr& ip, unsigned short port); CService(const struct in_addr& ipv4Addr, unsigned short port); - CService(const struct sockaddr_in& addr); + explicit CService(const struct sockaddr_in& addr); void Init(); void SetPort(unsigned short portIn); unsigned short GetPort() const; @@ -163,7 +163,7 @@ class CService : public CNetAddr std::string ToStringIPPort(bool fUseGetnameinfo = true) const; CService(const struct in6_addr& ipv6Addr, unsigned short port); - CService(const struct sockaddr_in6& addr); + explicit CService(const struct sockaddr_in6& addr); ADD_SERIALIZE_METHODS; diff --git a/src/netbase.h b/src/netbase.h index 729fcb4fce..1fd222697a 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -30,7 +30,7 @@ class proxyType { public: proxyType(): randomize_credentials(false) {} - proxyType(const CService &_proxy, bool _randomize_credentials=false): proxy(_proxy), randomize_credentials(_randomize_credentials) {} + explicit proxyType(const CService &_proxy, bool _randomize_credentials=false): proxy(_proxy), randomize_credentials(_randomize_credentials) {} bool IsValid() const { return proxy.IsValid(); } diff --git a/src/netmessagemaker.h b/src/netmessagemaker.h index 7a050681bf..70cc941dd4 100644 --- a/src/netmessagemaker.h +++ b/src/netmessagemaker.h @@ -12,7 +12,7 @@ class CNetMsgMaker { public: - CNetMsgMaker(int nVersionIn) : nVersion(nVersionIn){} + explicit CNetMsgMaker(int nVersionIn) : nVersion(nVersionIn){} template CSerializedNetMsg Make(int nFlags, std::string sCommand, Args&&... args) const diff --git a/src/primitives/block.h b/src/primitives/block.h index 4ec1cf75ca..024b043a1c 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -130,7 +130,7 @@ struct CBlockLocator CBlockLocator() {} - CBlockLocator(const std::vector& vHaveIn) : vHave(vHaveIn) {} + explicit CBlockLocator(const std::vector& vHaveIn) : vHave(vHaveIn) {} ADD_SERIALIZE_METHODS; diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 772408f43e..e0219c665c 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -61,7 +61,7 @@ std::string CTxOut::ToString() const } CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nType(TRANSACTION_NORMAL), nLockTime(0) {} -CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), nType(tx.nType), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), vExtraPayload(tx.vExtraPayload) {} +CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nType(tx.nType), nLockTime(tx.nLockTime), vExtraPayload(tx.vExtraPayload) {} uint256 CMutableTransaction::GetHash() const { @@ -92,9 +92,9 @@ uint256 CTransaction::ComputeHash() const } /* For backward compatibility, the hash is initialized to 0. TODO: remove the need for this default constructor entirely. */ -CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), nType(TRANSACTION_NORMAL), vin(), vout(), nLockTime(0), hash() {} -CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), nType(tx.nType), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), vExtraPayload(tx.vExtraPayload), hash(ComputeHash()) {} -CTransaction::CTransaction(CMutableTransaction &&tx) : nVersion(tx.nVersion), nType(tx.nType), vin(std::move(tx.vin)), vout(std::move(tx.vout)), nLockTime(tx.nLockTime), vExtraPayload(tx.vExtraPayload), hash(ComputeHash()) {} +CTransaction::CTransaction() : vin(), vout(), nVersion(CTransaction::CURRENT_VERSION), nType(TRANSACTION_NORMAL), nLockTime(0), hash() {} +CTransaction::CTransaction(const CMutableTransaction &tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nType(tx.nType), nLockTime(tx.nLockTime), vExtraPayload(tx.vExtraPayload), hash(ComputeHash()) {} +CTransaction::CTransaction(CMutableTransaction &&tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), nVersion(tx.nVersion), nType(tx.nType), nLockTime(tx.nLockTime), vExtraPayload(tx.vExtraPayload), hash(ComputeHash()) {} CAmount CTransaction::GetValueOut() const { diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index e10cbde8a2..ee83a7b514 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -212,10 +212,10 @@ public: // actually immutable; deserialization and assignment are implemented, // and bypass the constness. This is safe, as they update the entire // structure, including the hash. - const int16_t nVersion; - const int16_t nType; const std::vector vin; const std::vector vout; + const int16_t nVersion; + const int16_t nType; const uint32_t nLockTime; const std::vector vExtraPayload; // only available for special transaction types @@ -290,10 +290,10 @@ public: /** A mutable version of CTransaction. */ struct CMutableTransaction { - int16_t nVersion; - int16_t nType; std::vector vin; std::vector vout; + int16_t nVersion; + int16_t nType; uint32_t nLockTime; std::vector vExtraPayload; // only available for special transaction types diff --git a/src/protocol.h b/src/protocol.h index 128f0adb19..4bf0cdf00a 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -39,7 +39,7 @@ public: }; typedef unsigned char MessageStartChars[MESSAGE_START_SIZE]; - CMessageHeader(const MessageStartChars& pchMessageStartIn); + explicit CMessageHeader(const MessageStartChars& pchMessageStartIn); CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn); std::string GetCommand() const; diff --git a/src/pubkey.h b/src/pubkey.h index 9499862210..45f836781f 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -30,7 +30,7 @@ class CKeyID : public uint160 { public: CKeyID() : uint160() {} - CKeyID(const uint160& in) : uint160(in) {} + explicit CKeyID(const uint160& in) : uint160(in) {} }; typedef uint256 ChainCode; @@ -88,7 +88,7 @@ public: } //! Construct a public key from a byte vector. - CPubKey(const std::vector& _vch) + explicit CPubKey(const std::vector& _vch) { Set(_vch.begin(), _vch.end()); } diff --git a/src/qt/callback.h b/src/qt/callback.h index a8b593a652..da6b0c4c2e 100644 --- a/src/qt/callback.h +++ b/src/qt/callback.h @@ -16,7 +16,7 @@ class FunctionCallback : public Callback F f; public: - FunctionCallback(F f_) : f(std::move(f_)) {} + explicit FunctionCallback(F f_) : f(std::move(f_)) {} ~FunctionCallback() override {} void call() override { f(this); } }; diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 1d96a3b229..7e5b257d8d 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -19,6 +19,7 @@ #include "policy/fees.h" #include "policy/policy.h" #include "validation.h" // For mempool +#include "wallet/fees.h" #include "wallet/wallet.h" #include "privatesend/privatesend-client.h" @@ -547,7 +548,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) nBytes -= 34; // Fee - nPayFee = CWallet::GetMinimumFee(nBytes, *coinControl, ::mempool, ::feeEstimator, nullptr /* FeeCalculation */); + nPayFee = GetMinimumFee(nBytes, *coinControl, ::mempool, ::feeEstimator, nullptr /* FeeCalculation */); if (nPayAmount > 0) { diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index c50b16ca2c..fcafdac4f8 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -30,9 +30,9 @@ namespace Ui { class CCoinControlWidgetItem : public QTreeWidgetItem { public: - CCoinControlWidgetItem(QTreeWidget *parent, int type = Type) : QTreeWidgetItem(parent, type) {} - CCoinControlWidgetItem(int type = Type) : QTreeWidgetItem(type) {} - CCoinControlWidgetItem(QTreeWidgetItem *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + explicit CCoinControlWidgetItem(QTreeWidget *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + explicit CCoinControlWidgetItem(int type = Type) : QTreeWidgetItem(type) {} + explicit CCoinControlWidgetItem(QTreeWidgetItem *parent, int type = Type) : QTreeWidgetItem(parent, type) {} bool operator<(const QTreeWidgetItem &other) const; }; diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index d64a14068d..4812e5c5ab 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -44,7 +44,7 @@ class FreespaceChecker : public QObject Q_OBJECT public: - FreespaceChecker(Intro *intro); + explicit FreespaceChecker(Intro *intro); enum Status { ST_OK, diff --git a/src/qt/macnotificationhandler.h b/src/qt/macnotificationhandler.h index d4749b3d5f..3a005c3c46 100644 --- a/src/qt/macnotificationhandler.h +++ b/src/qt/macnotificationhandler.h @@ -7,20 +7,17 @@ #include -/** Macintosh-specific notification handler (supports UserNotificationCenter and Growl). +/** Macintosh-specific notification handler (supports UserNotificationCenter). */ class MacNotificationHandler : public QObject { Q_OBJECT public: - /** shows a 10.8+ UserNotification in the UserNotificationCenter + /** shows a macOS 10.8+ UserNotification in the UserNotificationCenter */ void showNotification(const QString &title, const QString &text); - /** executes AppleScript */ - void sendAppleScript(const QString &script); - /** check if OS can handle UserNotifications */ bool hasUserNotificationCenterSupport(void); static MacNotificationHandler *instance(); diff --git a/src/qt/macnotificationhandler.mm b/src/qt/macnotificationhandler.mm index 4c344038a9..fd15586630 100644 --- a/src/qt/macnotificationhandler.mm +++ b/src/qt/macnotificationhandler.mm @@ -47,20 +47,6 @@ void MacNotificationHandler::showNotification(const QString &title, const QStrin } } -// sendAppleScript just take a QString and executes it as apple script -void MacNotificationHandler::sendAppleScript(const QString &script) -{ - QByteArray utf8 = script.toUtf8(); - char* cString = (char *)utf8.constData(); - NSString *scriptApple = [[NSString alloc] initWithUTF8String:cString]; - - NSAppleScript *as = [[NSAppleScript alloc] initWithSource:scriptApple]; - NSDictionary *err = nil; - [as executeAndReturnError:&err]; - [as release]; - [scriptApple release]; -} - bool MacNotificationHandler::hasUserNotificationCenterSupport(void) { Class possibleClass = NSClassFromString(@"NSUserNotificationCenter"); diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 8277e20c90..6049890fc9 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -60,22 +60,6 @@ Notificator::Notificator(const QString &_programName, QSystemTrayIcon *_trayIcon if( MacNotificationHandler::instance()->hasUserNotificationCenterSupport()) { mode = UserNotificationCenter; } - else { - // Check if Growl is installed (based on Qt's tray icon implementation) - CFURLRef cfurl; - OSStatus status = LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFSTR("growlTicket"), kLSRolesAll, 0, &cfurl); - if (status != kLSApplicationNotFoundErr) { - CFBundleRef bundle = CFBundleCreate(0, cfurl); - if (CFStringCompare(CFBundleGetIdentifier(bundle), CFSTR("com.Growl.GrowlHelperApp"), kCFCompareCaseInsensitive | kCFCompareBackwards) == kCFCompareEqualTo) { - if (CFStringHasSuffix(CFURLGetString(cfurl), CFSTR("/Growl.app/"))) - mode = Growl13; - else - mode = Growl12; - } - CFRelease(cfurl); - CFRelease(bundle); - } - } #endif } @@ -93,7 +77,7 @@ class FreedesktopImage { public: FreedesktopImage() {} - FreedesktopImage(const QImage &img); + explicit FreedesktopImage(const QImage &img); static int metaType(); @@ -241,52 +225,6 @@ void Notificator::notifySystray(Class cls, const QString &title, const QString & // Based on Qt's tray icon implementation #ifdef Q_OS_MAC -void Notificator::notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon) -{ - const QString script( - "tell application \"%5\"\n" - " set the allNotificationsList to {\"Notification\"}\n" // -- Make a list of all the notification types (all) - " set the enabledNotificationsList to {\"Notification\"}\n" // -- Make a list of the notifications (enabled) - " register as application \"%1\" all notifications allNotificationsList default notifications enabledNotificationsList\n" // -- Register our script with Growl - " notify with name \"Notification\" title \"%2\" description \"%3\" application name \"%1\"%4\n" // -- Send a Notification - "end tell" - ); - - QString notificationApp(QApplication::applicationName()); - if (notificationApp.isEmpty()) - notificationApp = "Application"; - - QPixmap notificationIconPixmap; - if (icon.isNull()) { // If no icon specified, set icon based on class - QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion; - switch (cls) - { - case Information: sicon = QStyle::SP_MessageBoxInformation; break; - case Warning: sicon = QStyle::SP_MessageBoxWarning; break; - case Critical: sicon = QStyle::SP_MessageBoxCritical; break; - } - notificationIconPixmap = QApplication::style()->standardPixmap(sicon); - } - else { - QSize size = icon.actualSize(QSize(48, 48)); - notificationIconPixmap = icon.pixmap(size); - } - - QString notificationIcon; - QTemporaryFile notificationIconFile; - if (!notificationIconPixmap.isNull() && notificationIconFile.open()) { - QImageWriter writer(¬ificationIconFile, "PNG"); - if (writer.write(notificationIconPixmap.toImage())) - notificationIcon = QString(" image from location \"file://%1\"").arg(notificationIconFile.fileName()); - } - - QString quotedTitle(title), quotedText(text); - quotedTitle.replace("\\", "\\\\").replace("\"", "\\"); - quotedText.replace("\\", "\\\\").replace("\"", "\\"); - QString growlApp(this->mode == Notificator::Growl13 ? "Growl" : "GrowlHelperApp"); - MacNotificationHandler::instance()->sendAppleScript(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon, growlApp)); -} - void Notificator::notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon) { // icon is not supported by the user notification center yet. OSX will use the app icon. MacNotificationHandler::instance()->showNotification(title, text); @@ -310,10 +248,6 @@ void Notificator::notify(Class cls, const QString &title, const QString &text, c case UserNotificationCenter: notifyMacUserNotificationCenter(cls, title, text, icon); break; - case Growl12: - case Growl13: - notifyGrowl(cls, title, text, icon); - break; #endif default: if(cls == Critical) diff --git a/src/qt/notificator.h b/src/qt/notificator.h index 7794b49f96..830fbc00cf 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -58,8 +58,6 @@ private: None, /**< Ignore informational notifications, and show a modal pop-up dialog for Critical notifications. */ Freedesktop, /**< Use DBus org.freedesktop.Notifications */ QSystemTray, /**< Use QSystemTray::showMessage */ - Growl12, /**< Use the Growl 1.2 notification system (Mac only) */ - Growl13, /**< Use the Growl 1.3 notification system (Mac only) */ UserNotificationCenter /**< Use the 10.8+ User Notification Center (Mac only) */ }; QString programName; @@ -72,7 +70,6 @@ private: #endif void notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout); #ifdef Q_OS_MAC - void notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon); void notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon); #endif }; diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index e3d9a79afa..983aa559fc 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -18,8 +18,6 @@ #include "txdb.h" // for -dbcache defaults #ifdef ENABLE_WALLET -#include "wallet/wallet.h" // for CWallet::GetRequiredFee() - #include "privatesend/privatesend-client.h" #endif // ENABLE_WALLET @@ -82,14 +80,14 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : } /* Display elements init */ - + /* Number of displayed decimal digits selector */ QString digits; for(int index = 2; index <=8; index++){ digits.setNum(index); ui->digits->addItem(digits, digits); } - + /* Theme selector */ ui->theme->addItem(QString("Dark"), QVariant("dark")); ui->theme->addItem(QString("Light"), QVariant("light")); diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 9ca6094268..999ba97308 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -34,7 +34,7 @@ class TxViewDelegate : public QAbstractItemDelegate { Q_OBJECT public: - TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr): + explicit TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr): QAbstractItemDelegate(), unit(BitcoinUnits::DASH), platformStyle(_platformStyle) { diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index ae76e14f5f..165e499150 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -22,7 +22,7 @@ class SSLVerifyError : public std::runtime_error { public: - SSLVerifyError(std::string err) : std::runtime_error(err) { } + explicit SSLVerifyError(std::string err) : std::runtime_error(err) { } }; bool PaymentRequestPlus::parse(const QByteArray& data) diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 22bee46726..f0926d8dca 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -72,7 +72,7 @@ public: static bool ipcSendCommandLine(); // parent should be QApplication object - PaymentServer(QObject* parent, bool startLocalServer = true); + explicit PaymentServer(QObject* parent, bool startLocalServer = true); ~PaymentServer(); // Load root certificate authorities. Pass nullptr (default) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 97562dd149..2de2612f54 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -22,7 +22,7 @@ #include "ui_interface.h" #include "txmempool.h" #include "policy/fees.h" -#include "wallet/wallet.h" +#include "wallet/fees.h" #include "privatesend/privatesend.h" #include "privatesend/privatesend-client.h" @@ -210,7 +210,7 @@ void SendCoinsDialog::setModel(WalletModel *_model) connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(setMinimumFee())); connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateFeeSectionControls())); connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels())); - ui->customFee->setSingleStep(CWallet::GetRequiredFee(1000)); + ui->customFee->setSingleStep(GetRequiredFee(1000)); updateFeeSectionControls(); updateMinFeeLabel(); updateSmartFeeLabel(); @@ -709,7 +709,7 @@ void SendCoinsDialog::on_buttonMinimizeFee_clicked() void SendCoinsDialog::setMinimumFee() { - ui->customFee->setValue(CWallet::GetRequiredFee(1000)); + ui->customFee->setValue(GetRequiredFee(1000)); } void SendCoinsDialog::updateFeeSectionControls() @@ -741,7 +741,7 @@ void SendCoinsDialog::updateMinFeeLabel() { if (model && model->getOptionsModel()) ui->checkBoxMinimumFee->setText(tr("Pay only the required fee of %1").arg( - BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::GetRequiredFee(1000)) + "/kB") + BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), GetRequiredFee(1000)) + "/kB") ); } @@ -765,7 +765,7 @@ void SendCoinsDialog::updateSmartFeeLabel() updateCoinControlState(coin_control); coin_control.m_feerate.reset(); // Explicitly use only fee estimation rate for smart fee labels FeeCalculation feeCalc; - CFeeRate feeRate = CFeeRate(CWallet::GetMinimumFee(1000, coin_control, ::mempool, ::feeEstimator, &feeCalc)); + CFeeRate feeRate = CFeeRate(GetMinimumFee(1000, coin_control, ::mempool, ::feeEstimator, &feeCalc)); ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB"); diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 38a45b0e69..130dc32700 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -175,7 +175,7 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() ui->statusLabel_SM->setStyleSheet(GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_SUCCESS)); ui->statusLabel_SM->setText(QString("") + tr("Message signed.") + QString("")); - ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size()))); + ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(vchSig.data(), vchSig.size()))); } void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked() diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index c7830071ed..273bd10487 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -24,7 +24,7 @@ X509 *parse_b64der_cert(const char* cert_data) { std::vector data = DecodeBase64(cert_data); assert(data.size() > 0); - const unsigned char* dptr = &data[0]; + const unsigned char* dptr = data.data(); X509 *cert = d2i_X509(nullptr, &dptr, data.size()); assert(cert); return cert; @@ -43,7 +43,7 @@ static SendCoinsRecipient handleRequest(PaymentServer* server, std::vector #include #include @@ -69,6 +70,7 @@ bool WalletFrame::setCurrentWallet(const QString& name) WalletView *walletView = mapWalletViews.value(name); walletStack->setCurrentWidget(walletView); + assert(walletView); walletView->updateEncryptionStatus(); return true; } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 0df954a942..9a3cb47a44 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -387,7 +387,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << *newTx->tx; - transaction_array.append(&(ssTx[0]), ssTx.size()); + transaction_array.append(ssTx.data(), ssTx.size()); } // Add addresses / update labels that we've sent to the address book, diff --git a/src/rest.cpp b/src/rest.cpp index 3571eb00b3..0e568162c3 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -48,7 +48,7 @@ struct CCoin { ADD_SERIALIZE_METHODS; CCoin() : nHeight(0) {} - CCoin(Coin&& in) : nHeight(in.nHeight), out(std::move(in.out)) {} + explicit CCoin(Coin&& in) : nHeight(in.nHeight), out(std::move(in.out)) {} template inline void SerializationOp(Stream& s, Operation ser_action) diff --git a/src/reverse_iterator.h b/src/reverse_iterator.h index 46789e5417..ab467f07c9 100644 --- a/src/reverse_iterator.h +++ b/src/reverse_iterator.h @@ -17,7 +17,7 @@ class reverse_range T &m_x; public: - reverse_range(T &x) : m_x(x) {} + explicit reverse_range(T &x) : m_x(x) {} auto begin() const -> decltype(this->m_x.rbegin()) { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b6b8a63168..b3b15bf386 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1080,6 +1080,7 @@ static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) { std::unique_ptr pcursor(view->Cursor()); + assert(pcursor); CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); stats.hashBlock = pcursor->GetBestBlock(); @@ -1643,7 +1644,7 @@ UniValue getmempoolinfo(const JSONRPCRequest& request) " \"bytes\": xxxxx, (numeric) Sum of all tx sizes\n" " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n" " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n" - " \"mempoolminfee\": xxxxx (numeric) Minimum feerate (" + CURRENCY_UNIT + " per KB) for tx to be accepted\n" + " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted\n" " \"instantsendlocks\": xxxxx, (numeric) Number of unconfirmed instant send locks\n" "}\n" "\nExamples:\n" @@ -1816,6 +1817,8 @@ UniValue getchaintxstats(const JSONRPCRequest& request) } } + assert(pindex != nullptr); + if (blockcount < 1 || blockcount >= pindex->nHeight) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 1 and the block's height"); } diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 38d2439943..4bf5603429 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -43,8 +43,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "sendtoaddress", 5, "use_is" }, { "sendtoaddress", 6, "use_ps" }, { "sendtoaddress", 7, "conf_target" }, - { "instantsendtoaddress", 1, "address" }, - { "instantsendtoaddress", 4, "comment_to" }, { "settxfee", 0, "amount" }, { "getreceivedbyaddress", 1, "minconf" }, { "getreceivedbyaddress", 2, "addlocked" }, diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index 2f93511f9a..cd88f47df1 100644 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -1098,7 +1098,7 @@ static const CRPCCommand commands[] = { "dash", "getgovernanceinfo", &getgovernanceinfo, {} }, { "dash", "getsuperblockbudget", &getsuperblockbudget, {"index"} }, { "dash", "gobject", &gobject, {} }, - { "dash", "voteraw", &voteraw, {} }, + { "dash", "voteraw", &voteraw, {"tx_hash","tx_index","gov_hash","signal","outcome","time","sig"} }, }; diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index ac2b6e1dfe..3d40bd20eb 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -721,7 +721,7 @@ public: bool found; CValidationState state; - submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {} + explicit submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {} protected: void BlockChecked(const CBlock& block, const CValidationState& stateIn) override { @@ -850,7 +850,7 @@ UniValue estimatesmartfee(const JSONRPCRequest& request) " \"CONSERVATIVE\"\n" "\nResult:\n" "{\n" - " \"feerate\" : x.x, (numeric, optional) estimate fee-per-kilobyte (in " + CURRENCY_UNIT + ")\n" + " \"feerate\" : x.x, (numeric, optional) estimate fee rate in " + CURRENCY_UNIT + "/kB\n" " \"errors\": [ str... ] (json array of strings, optional) Errors encountered during processing\n" " \"blocks\" : n (numeric) block number where estimate was found\n" "}\n" @@ -908,7 +908,7 @@ UniValue estimaterawfee(const JSONRPCRequest& request) "\nResult:\n" "{\n" " \"short\" : { (json object, optional) estimate for short time horizon\n" - " \"feerate\" : x.x, (numeric, optional) estimate fee-per-kilobyte (in " + CURRENCY_UNIT + ")\n" + " \"feerate\" : x.x, (numeric, optional) estimate fee rate in " + CURRENCY_UNIT + "/kB\n" " \"decay\" : x.x, (numeric) exponential decay (per block) for historical moving average of confirmation data\n" " \"scale\" : x, (numeric) The resolution of confirmation targets at this time horizon\n" " \"pass\" : { (json object, optional) information about the lowest range of feerates to succeed in meeting the threshold\n" @@ -1004,7 +1004,7 @@ static const CRPCCommand commands[] = #endif // ENABLE_MINER { "util", "estimatefee", &estimatefee, {"nblocks"} }, - { "util", "estimatesmartfee", &estimatesmartfee, {"nblocks", "estimate_mode"} }, + { "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} }, { "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} }, }; diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 9abcf70074..5e1dce882b 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -211,7 +211,7 @@ class DescribeAddressVisitor : public boost::static_visitor public: CWallet * const pwallet; - DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {} + explicit DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {} UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); } @@ -623,7 +623,7 @@ UniValue signmessagewithprivkey(const JSONRPCRequest& request) if (!key.SignCompact(ss.GetHash(), vchSig)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); - return EncodeBase64(&vchSig[0], vchSig.size()); + return EncodeBase64(vchSig.data(), vchSig.size()); } UniValue setmocktime(const JSONRPCRequest& request) @@ -1307,7 +1307,7 @@ static const CRPCCommand commands[] = /* Dash features */ { "dash", "mnsync", &mnsync, {} }, - { "dash", "spork", &spork, {"value"} }, + { "dash", "spork", &spork, {"arg0","value"} }, /* Not shown in help */ { "hidden", "setmocktime", &setmocktime, {"timestamp"}}, diff --git a/src/rpc/server.h b/src/rpc/server.h index 8350013705..8803132518 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -28,7 +28,7 @@ namespace RPCServer /** Wrapper for UniValue::VType, which includes typeAny: * Used to denote don't care type. Only used by RPCTypeCheckObj */ struct UniValueType { - UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {} + explicit UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {} UniValueType() : typeAny(true) {} bool typeAny; UniValue::VType type; diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 29f7cee5e1..f091bbab4f 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -174,7 +174,7 @@ void SingleThreadedSchedulerClient::ProcessQueue() { // to ensure both happen safely even if callback() throws. struct RAIICallbacksRunning { SingleThreadedSchedulerClient* instance; - RAIICallbacksRunning(SingleThreadedSchedulerClient* _instance) : instance(_instance) {} + explicit RAIICallbacksRunning(SingleThreadedSchedulerClient* _instance) : instance(_instance) {} ~RAIICallbacksRunning() { { LOCK(instance->m_cs_callbacks_pending); diff --git a/src/scheduler.h b/src/scheduler.h index cc2f01f2ff..db93bcb21e 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -102,7 +102,7 @@ private: void ProcessQueue(); public: - SingleThreadedSchedulerClient(CScheduler *pschedulerIn) : m_pscheduler(pschedulerIn) {} + explicit SingleThreadedSchedulerClient(CScheduler *pschedulerIn) : m_pscheduler(pschedulerIn) {} void AddToProcessQueue(std::function func); // Processes all remaining queue members on the calling thread, blocking until queue is empty diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 7ba43c76a1..454aedffb9 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -98,7 +98,7 @@ struct PrecomputedTransactionData { uint256 hashPrevouts, hashSequence, hashOutputs; - PrecomputedTransactionData(const CTransaction& tx); + explicit PrecomputedTransactionData(const CTransaction& tx); }; enum SigVersion diff --git a/src/script/sign.h b/src/script/sign.h index a371937818..8a52119f84 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -21,7 +21,7 @@ protected: const CKeyStore* keystore; public: - BaseSignatureCreator(const CKeyStore* keystoreIn) : keystore(keystoreIn) {} + explicit BaseSignatureCreator(const CKeyStore* keystoreIn) : keystore(keystoreIn) {} const CKeyStore& KeyStore() const { return *keystore; }; virtual ~BaseSignatureCreator() {} virtual const BaseSignatureChecker& Checker() const =0; @@ -54,7 +54,7 @@ public: /** A signature creator that just produces 72-byte empty signatures. */ class DummySignatureCreator : public BaseSignatureCreator { public: - DummySignatureCreator(const CKeyStore* keystoreIn) : BaseSignatureCreator(keystoreIn) {} + explicit DummySignatureCreator(const CKeyStore* keystoreIn) : BaseSignatureCreator(keystoreIn) {} const BaseSignatureChecker& Checker() const override; bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override; }; diff --git a/src/script/standard.cpp b/src/script/standard.cpp index e34b7c3360..068089284e 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -232,7 +232,7 @@ class CScriptVisitor : public boost::static_visitor private: CScript *script; public: - CScriptVisitor(CScript *scriptin) { script = scriptin; } + explicit CScriptVisitor(CScript *scriptin) { script = scriptin; } bool operator()(const CNoDestination &dest) const { script->clear(); diff --git a/src/serialize.h b/src/serialize.h index d0f8fe4b11..8039ffc1f8 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -578,7 +578,7 @@ class CVarInt protected: I &n; public: - CVarInt(I& nIn) : n(nIn) { } + explicit CVarInt(I& nIn) : n(nIn) { } template void Serialize(Stream &s) const { @@ -596,7 +596,7 @@ class CCompactSize protected: uint64_t &n; public: - CCompactSize(uint64_t& nIn) : n(nIn) { } + explicit CCompactSize(uint64_t& nIn) : n(nIn) { } unsigned int GetSerializeSize() const { return GetSizeOfCompactSize(n); @@ -619,7 +619,7 @@ class LimitedString protected: std::string& string; public: - LimitedString(std::string& _string) : string(_string) {} + explicit LimitedString(std::string& _string) : string(_string) {} template void Unserialize(Stream& s) diff --git a/src/support/lockedpool.h b/src/support/lockedpool.h index 7641d81471..cecbdec1aa 100644 --- a/src/support/lockedpool.h +++ b/src/support/lockedpool.h @@ -150,7 +150,7 @@ public: * If this callback is provided and returns false, the allocation fails (hard fail), if * it returns true the allocation proceeds, but it could warn. */ - LockedPool(std::unique_ptr allocator, LockingFailed_Callback lf_cb_in = nullptr); + explicit LockedPool(std::unique_ptr allocator, LockingFailed_Callback lf_cb_in = nullptr); ~LockedPool(); /** Allocate size bytes from this arena. @@ -217,7 +217,7 @@ public: } private: - LockedPoolManager(std::unique_ptr allocator); + explicit LockedPoolManager(std::unique_ptr allocator); /** Create a new LockedPoolManager specialized to the OS */ static void CreateInstance(); diff --git a/src/sync.h b/src/sync.h index 864d427e1c..104ca660c6 100644 --- a/src/sync.h +++ b/src/sync.h @@ -199,7 +199,7 @@ private: int value; public: - CSemaphore(int init) : value(init) {} + explicit CSemaphore(int init) : value(init) {} void wait() { @@ -270,7 +270,7 @@ public: CSemaphoreGrant() : sem(nullptr), fHaveGrant(false) {} - CSemaphoreGrant(CSemaphore& sema, bool fTry = false) : sem(&sema), fHaveGrant(false) + explicit CSemaphoreGrant(CSemaphore& sema, bool fTry = false) : sem(&sema), fHaveGrant(false) { if (fTry) TryAcquire(); diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index fba69759ce..7cbc7899a0 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -78,7 +78,7 @@ class TestAddrTypeVisitor : public boost::static_visitor private: std::string exp_addrType; public: - TestAddrTypeVisitor(const std::string &_exp_addrType) : exp_addrType(_exp_addrType) { } + explicit TestAddrTypeVisitor(const std::string &_exp_addrType) : exp_addrType(_exp_addrType) { } bool operator()(const CKeyID &id) const { return (exp_addrType == "pubkey"); @@ -99,7 +99,7 @@ class TestPayloadVisitor : public boost::static_visitor private: std::vector exp_payload; public: - TestPayloadVisitor(std::vector &_exp_payload) : exp_payload(_exp_payload) { } + explicit TestPayloadVisitor(std::vector &_exp_payload) : exp_payload(_exp_payload) { } bool operator()(const CKeyID &id) const { uint160 exp_key(exp_payload); diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index ab040c5cc7..e0cc26d770 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -24,7 +24,7 @@ struct TestVector { std::string strHexMaster; std::vector vDerive; - TestVector(std::string strHexMasterIn) : strHexMaster(strHexMasterIn) {} + explicit TestVector(std::string strHexMasterIn) : strHexMaster(strHexMasterIn) {} TestVector& operator()(std::string pub, std::string prv, unsigned int nChild) { vDerive.push_back(TestDerivation()); @@ -91,7 +91,7 @@ void RunTest(const TestVector &test) { std::vector seed = ParseHex(test.strHexMaster); CExtKey key; CExtPubKey pubkey; - key.SetMaster(&seed[0], seed.size()); + key.SetMaster(seed.data(), seed.size()); pubkey = key.Neuter(); for (const TestDerivation &derive : test.vDerive) { unsigned char data[74]; diff --git a/src/test/bip39_tests.cpp b/src/test/bip39_tests.cpp index 186c415d9f..fed0e8a893 100644 --- a/src/test/bip39_tests.cpp +++ b/src/test/bip39_tests.cpp @@ -54,7 +54,7 @@ BOOST_AUTO_TEST_CASE(bip39_vectors) CExtKey key; CExtPubKey pubkey; - key.SetMaster(&seed[0], 64); + key.SetMaster(seed.data(), 64); pubkey = key.Neuter(); CBitcoinExtKey b58key; diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index 4db613a431..c8e1c7783e 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -118,12 +118,12 @@ public: std::vector shorttxids; std::vector prefilledtxn; - TestHeaderAndShortIDs(const CBlockHeaderAndShortTxIDs& orig) { + explicit TestHeaderAndShortIDs(const CBlockHeaderAndShortTxIDs& orig) { CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << orig; stream >> *this; } - TestHeaderAndShortIDs(const CBlock& block) : + explicit TestHeaderAndShortIDs(const CBlock& block) : TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs(block)) {} uint64_t GetShortID(const uint256& txhash) const { diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 8f14db9001..d82b5a6abb 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -154,8 +154,8 @@ BOOST_AUTO_TEST_CASE(bloom_match) COutPoint prevOutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0); { std::vector data(32 + sizeof(unsigned int)); - memcpy(&data[0], prevOutPoint.hash.begin(), 32); - memcpy(&data[32], &prevOutPoint.n, sizeof(unsigned int)); + memcpy(data.data(), prevOutPoint.hash.begin(), 32); + memcpy(data.data()+32, &prevOutPoint.n, sizeof(unsigned int)); filter.insert(data); } BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match manually serialized COutPoint"); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 99c4f7428f..90385dbdda 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -74,7 +74,7 @@ public: class CCoinsViewCacheTest : public CCoinsViewCache { public: - CCoinsViewCacheTest(CCoinsView* _base) : CCoinsViewCache(_base) {} + explicit CCoinsViewCacheTest(CCoinsView* _base) : CCoinsViewCache(_base) {} void SelfTest() const { diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 1e8cc1c2ef..5233972209 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -60,12 +60,12 @@ void TestRIPEMD160(const std::string &in, const std::string &hexout) { TestVecto void TestHMACSHA256(const std::string &hexkey, const std::string &hexin, const std::string &hexout) { std::vector key = ParseHex(hexkey); - TestVector(CHMAC_SHA256(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout)); + TestVector(CHMAC_SHA256(key.data(), key.size()), ParseHex(hexin), ParseHex(hexout)); } void TestHMACSHA512(const std::string &hexkey, const std::string &hexin, const std::string &hexout) { std::vector key = ParseHex(hexkey); - TestVector(CHMAC_SHA512(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout)); + TestVector(CHMAC_SHA512(key.data(), key.size()), ParseHex(hexin), ParseHex(hexout)); } void TestAES128(const std::string &hexkey, const std::string &hexin, const std::string &hexout) @@ -78,13 +78,13 @@ void TestAES128(const std::string &hexkey, const std::string &hexin, const std:: assert(key.size() == 16); assert(in.size() == 16); assert(correctout.size() == 16); - AES128Encrypt enc(&key[0]); + AES128Encrypt enc(key.data()); buf.resize(correctout.size()); buf2.resize(correctout.size()); - enc.Encrypt(&buf[0], &in[0]); + enc.Encrypt(buf.data(), in.data()); BOOST_CHECK_EQUAL(HexStr(buf), HexStr(correctout)); - AES128Decrypt dec(&key[0]); - dec.Decrypt(&buf2[0], &buf[0]); + AES128Decrypt dec(key.data()); + dec.Decrypt(buf2.data(), buf.data()); BOOST_CHECK_EQUAL(HexStr(buf2), HexStr(in)); } @@ -98,12 +98,12 @@ void TestAES256(const std::string &hexkey, const std::string &hexin, const std:: assert(key.size() == 32); assert(in.size() == 16); assert(correctout.size() == 16); - AES256Encrypt enc(&key[0]); + AES256Encrypt enc(key.data()); buf.resize(correctout.size()); - enc.Encrypt(&buf[0], &in[0]); + enc.Encrypt(buf.data(), in.data()); BOOST_CHECK(buf == correctout); - AES256Decrypt dec(&key[0]); - dec.Decrypt(&buf[0], &buf[0]); + AES256Decrypt dec(key.data()); + dec.Decrypt(buf.data(), buf.data()); BOOST_CHECK(buf == in); } @@ -116,16 +116,16 @@ void TestAES128CBC(const std::string &hexkey, const std::string &hexiv, bool pad std::vector realout(in.size() + AES_BLOCKSIZE); // Encrypt the plaintext and verify that it equals the cipher - AES128CBCEncrypt enc(&key[0], &iv[0], pad); - int size = enc.Encrypt(&in[0], in.size(), &realout[0]); + AES128CBCEncrypt enc(key.data(), iv.data(), pad); + int size = enc.Encrypt(in.data(), in.size(), realout.data()); realout.resize(size); BOOST_CHECK(realout.size() == correctout.size()); BOOST_CHECK_MESSAGE(realout == correctout, HexStr(realout) + std::string(" != ") + hexout); // Decrypt the cipher and verify that it equals the plaintext std::vector decrypted(correctout.size()); - AES128CBCDecrypt dec(&key[0], &iv[0], pad); - size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]); + AES128CBCDecrypt dec(key.data(), iv.data(), pad); + size = dec.Decrypt(correctout.data(), correctout.size(), decrypted.data()); decrypted.resize(size); BOOST_CHECK(decrypted.size() == in.size()); BOOST_CHECK_MESSAGE(decrypted == in, HexStr(decrypted) + std::string(" != ") + hexin); @@ -135,12 +135,12 @@ void TestAES128CBC(const std::string &hexkey, const std::string &hexiv, bool pad { std::vector sub(i, in.end()); std::vector subout(sub.size() + AES_BLOCKSIZE); - int _size = enc.Encrypt(&sub[0], sub.size(), &subout[0]); + int _size = enc.Encrypt(sub.data(), sub.size(), subout.data()); if (_size != 0) { subout.resize(_size); std::vector subdecrypted(subout.size()); - _size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]); + _size = dec.Decrypt(subout.data(), subout.size(), subdecrypted.data()); subdecrypted.resize(_size); BOOST_CHECK(decrypted.size() == in.size()); BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub)); @@ -157,16 +157,16 @@ void TestAES256CBC(const std::string &hexkey, const std::string &hexiv, bool pad std::vector realout(in.size() + AES_BLOCKSIZE); // Encrypt the plaintext and verify that it equals the cipher - AES256CBCEncrypt enc(&key[0], &iv[0], pad); - int size = enc.Encrypt(&in[0], in.size(), &realout[0]); + AES256CBCEncrypt enc(key.data(), iv.data(), pad); + int size = enc.Encrypt(in.data(), in.size(), realout.data()); realout.resize(size); BOOST_CHECK(realout.size() == correctout.size()); BOOST_CHECK_MESSAGE(realout == correctout, HexStr(realout) + std::string(" != ") + hexout); // Decrypt the cipher and verify that it equals the plaintext std::vector decrypted(correctout.size()); - AES256CBCDecrypt dec(&key[0], &iv[0], pad); - size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]); + AES256CBCDecrypt dec(key.data(), iv.data(), pad); + size = dec.Decrypt(correctout.data(), correctout.size(), decrypted.data()); decrypted.resize(size); BOOST_CHECK(decrypted.size() == in.size()); BOOST_CHECK_MESSAGE(decrypted == in, HexStr(decrypted) + std::string(" != ") + hexin); @@ -176,12 +176,12 @@ void TestAES256CBC(const std::string &hexkey, const std::string &hexiv, bool pad { std::vector sub(i, in.end()); std::vector subout(sub.size() + AES_BLOCKSIZE); - int _size = enc.Encrypt(&sub[0], sub.size(), &subout[0]); + int _size = enc.Encrypt(sub.data(), sub.size(), subout.data()); if (_size != 0) { subout.resize(_size); std::vector subdecrypted(subout.size()); - _size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]); + _size = dec.Decrypt(subout.data(), subout.size(), subdecrypted.data()); subdecrypted.resize(_size); BOOST_CHECK(decrypted.size() == in.size()); BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub)); diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 14ef2824d6..2114123816 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -243,7 +243,7 @@ struct StringContentsSerializer { // This is a terrible idea std::string str; StringContentsSerializer() {} - StringContentsSerializer(const std::string& inp) : str(inp) {} + explicit StringContentsSerializer(const std::string& inp) : str(inp) {} StringContentsSerializer& operator+=(const std::string& s) { str += s; diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index 44109f2161..5afb9167c0 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -27,7 +27,7 @@ static void ResetArgs(const std::string& strArg) for (std::string& s : vecArg) vecChar.push_back(s.c_str()); - gArgs.ParseParameters(vecChar.size(), &vecChar[0]); + gArgs.ParseParameters(vecChar.size(), vecChar.data()); } BOOST_AUTO_TEST_CASE(boolarg) diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index 173c943d88..186142a6bb 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(skiplist_test) BOOST_CHECK(vIndex[SKIPLIST_LENGTH - 1].GetAncestor(from) == &vIndex[from]); BOOST_CHECK(vIndex[from].GetAncestor(to) == &vIndex[to]); - BOOST_CHECK(vIndex[from].GetAncestor(0) == &vIndex[0]); + BOOST_CHECK(vIndex[from].GetAncestor(0) == vIndex.data()); } } @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(getlocator_test) for (unsigned int i=0; i peerLogic; - TestingSetup(const std::string& chainName = CBaseChainParams::MAIN); + explicit TestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~TestingSetup(); }; diff --git a/src/test/test_dash_fuzzy.cpp b/src/test/test_dash_fuzzy.cpp index 35c97cbd19..dc38d1abf1 100644 --- a/src/test/test_dash_fuzzy.cpp +++ b/src/test/test_dash_fuzzy.cpp @@ -67,7 +67,7 @@ int do_fuzz() if (buffer.size() < sizeof(uint32_t)) return 0; uint32_t test_id = 0xffffffff; - memcpy(&test_id, &buffer[0], sizeof(uint32_t)); + memcpy(&test_id, buffer.data(), sizeof(uint32_t)); buffer.erase(buffer.begin(), buffer.begin() + sizeof(uint32_t)); if (test_id >= TEST_ID_END) return 0; diff --git a/src/tinyformat.h b/src/tinyformat.h index 10d73c2a0b..4e12e4172a 100644 --- a/src/tinyformat.h +++ b/src/tinyformat.h @@ -167,7 +167,7 @@ namespace tinyformat { class format_error: public std::runtime_error { public: - format_error(const std::string &what): std::runtime_error(what) { + explicit format_error(const std::string &what): std::runtime_error(what) { } }; @@ -498,7 +498,7 @@ class FormatArg FormatArg() {} template - FormatArg(const T& value) + explicit FormatArg(const T& value) : m_value(static_cast(&value)), m_formatImpl(&formatImpl), m_toIntImpl(&toIntImpl) @@ -867,7 +867,7 @@ class FormatListN : public FormatList public: #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES template - FormatListN(const Args&... args) + explicit FormatListN(const Args&... args) : FormatList(&m_formatterStore[0], N), m_formatterStore { FormatArg(args)... } { static_assert(sizeof...(args) == N, "Number of args must be N"); } @@ -876,7 +876,7 @@ class FormatListN : public FormatList # define TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR(n) \ \ template \ - FormatListN(TINYFORMAT_VARARGS(n)) \ + explicit FormatListN(TINYFORMAT_VARARGS(n)) \ : FormatList(&m_formatterStore[0], n) \ { assert(n == N); init(0, TINYFORMAT_PASSARGS(n)); } \ \ diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 6a515a3928..2255292dc4 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -76,7 +76,7 @@ public: /** Create a new TorControlConnection. */ - TorControlConnection(struct event_base *base); + explicit TorControlConnection(struct event_base *base); ~TorControlConnection(); /** diff --git a/src/txdb.cpp b/src/txdb.cpp index 596bc74579..2ddacf3e52 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -39,7 +39,7 @@ namespace { struct CoinEntry { COutPoint* outpoint; char key; - CoinEntry(const COutPoint* ptr) : outpoint(const_cast(ptr)), key(DB_COIN) {} + explicit CoinEntry(const COutPoint* ptr) : outpoint(const_cast(ptr)), key(DB_COIN) {} template void Serialize(Stream &s) const { diff --git a/src/txdb.h b/src/txdb.h index 6887f838df..8ea9d26654 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -70,7 +70,7 @@ class CCoinsViewDB final : public CCoinsView protected: CDBWrapper db; public: - CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); + explicit CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); bool GetCoin(const COutPoint &outpoint, Coin &coin) const override; @@ -111,7 +111,7 @@ private: class CBlockTreeDB : public CDBWrapper { public: - CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); + explicit CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); private: CBlockTreeDB(const CBlockTreeDB&); void operator=(const CBlockTreeDB&); diff --git a/src/txmempool.h b/src/txmempool.h index 123a85d1df..d81b3210e9 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -172,7 +172,7 @@ struct update_ancestor_state struct update_fee_delta { - update_fee_delta(int64_t _feeDelta) : feeDelta(_feeDelta) { } + explicit update_fee_delta(int64_t _feeDelta) : feeDelta(_feeDelta) { } void operator() (CTxMemPoolEntry &e) { e.UpdateFeeDelta(feeDelta); } @@ -182,7 +182,7 @@ private: struct update_lock_points { - update_lock_points(const LockPoints& _lp) : lp(_lp) { } + explicit update_lock_points(const LockPoints& _lp) : lp(_lp) { } void operator() (CTxMemPoolEntry &e) { e.UpdateLockPoints(lp); } @@ -522,7 +522,7 @@ public: /** Create a new CTxMemPool. */ - CTxMemPool(CBlockPolicyEstimator* estimator = nullptr); + explicit CTxMemPool(CBlockPolicyEstimator* estimator = nullptr); /** * If sanity-checking is turned on, check makes sure the pool is diff --git a/src/uint256.cpp b/src/uint256.cpp index e368fbe8a6..93a4b2072b 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -14,7 +14,7 @@ template base_blob::base_blob(const std::vector& vch) { assert(vch.size() == sizeof(data)); - memcpy(data, &vch[0], sizeof(data)); + memcpy(data, vch.data(), sizeof(data)); } template diff --git a/src/uint256.h b/src/uint256.h index 5409a20a35..a1ad3db129 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -112,7 +112,6 @@ public: class uint160 : public base_blob<160> { public: uint160() {} - uint160(const base_blob<160>& b) : base_blob<160>(b) {} explicit uint160(const std::vector& vch) : base_blob<160>(vch) {} }; @@ -124,7 +123,6 @@ public: class uint256 : public base_blob<256> { public: uint256() {} - uint256(const base_blob<256>& b) : base_blob<256>(b) {} explicit uint256(const std::vector& vch) : base_blob<256>(vch) {} /** A cheap hash function that just returns 64 bits from the result, it can be diff --git a/src/undo.h b/src/undo.h index a83b701485..f3f32effc5 100644 --- a/src/undo.h +++ b/src/undo.h @@ -33,7 +33,7 @@ public: ::Serialize(s, CTxOutCompressor(REF(txout->out))); } - TxInUndoSerializer(const Coin* coin) : txout(coin) {} + explicit TxInUndoSerializer(const Coin* coin) : txout(coin) {} }; class TxInUndoDeserializer @@ -57,7 +57,7 @@ public: ::Unserialize(s, REF(CTxOutCompressor(REF(txout->out)))); } - TxInUndoDeserializer(Coin* coin) : txout(coin) {} + explicit TxInUndoDeserializer(Coin* coin) : txout(coin) {} }; static const size_t MAX_INPUTS_PER_BLOCK = MaxBlockSize(true) / ::GetSerializeSize(CTxIn(), SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/univalue/lib/univalue_utffilter.h b/src/univalue/lib/univalue_utffilter.h index 6dcde9fa81..ba7db715a9 100644 --- a/src/univalue/lib/univalue_utffilter.h +++ b/src/univalue/lib/univalue_utffilter.h @@ -9,7 +9,7 @@ class JSONUTF8StringFilter { public: - JSONUTF8StringFilter(std::string &s): + explicit JSONUTF8StringFilter(std::string &s): str(s), is_valid(true), codepoint(0), state(0), surpair(0) { } diff --git a/src/unordered_lru_cache.h b/src/unordered_lru_cache.h index 57951b360c..066559cdde 100644 --- a/src/unordered_lru_cache.h +++ b/src/unordered_lru_cache.h @@ -19,7 +19,7 @@ private: int64_t accessCounter{0}; public: - unordered_lru_cache(size_t _maxSize = MaxSize, size_t _truncateThreshold = TruncateThreshold) : + explicit unordered_lru_cache(size_t _maxSize = MaxSize, size_t _truncateThreshold = TruncateThreshold) : maxSize(_maxSize), truncateThreshold(_truncateThreshold == 0 ? _maxSize * 2 : _truncateThreshold) { diff --git a/src/validation.cpp b/src/validation.cpp index c29706e597..338b8c4a82 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -254,7 +254,7 @@ bool CheckFinalTx(const CTransaction &tx, int flags) // IsFinalTx() with one more than chainActive.Height(). const int nBlockHeight = chainActive.Height() + 1; - // BIP113 will require that time-locked transactions have nLockTime set to + // BIP113 requires that time-locked transactions have nLockTime set to // less than the median time of the previous block they're contained in. // When the next block is created its previous block will be the current // chain tip, so we use that to calculate the median time passed to @@ -290,6 +290,8 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool AssertLockHeld(mempool.cs); CBlockIndex* tip = chainActive.Tip(); + assert(tip != nullptr); + CBlockIndex index; index.pprev = tip; // CheckSequenceLocks() uses chainActive.Height()+1 to evaluate @@ -1747,7 +1749,7 @@ private: int bit; public: - WarningBitsConditionChecker(int bitIn) : bit(bitIn) {} + explicit WarningBitsConditionChecker(int bitIn) : bit(bitIn) {} int64_t BeginTime(const Consensus::Params& params) const override { return 0; } int64_t EndTime(const Consensus::Params& params) const override { return std::numeric_limits::max(); } @@ -1910,6 +1912,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd // before the first had been spent. Since those coinbases are sufficiently buried its no longer possible to create further // duplicate transactions descending from the known pairs either. // If we're on the known chain at height greater than where BIP34 activated, we can save the db accesses needed for the BIP30 check. + assert(pindex->pprev); CBlockIndex *pindexBIP34height = pindex->pprev->GetAncestor(chainparams.GetConsensus().BIP34Height); //Only continue to enforce if we're below BIP34 activation height or the block hash at that height doesn't correspond. fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->GetBlockHash() == chainparams.GetConsensus().BIP34Hash)); @@ -2232,6 +2235,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(pindex->nTime, pindex->GetBlockHash()))) return AbortNode(state, "Failed to write timestamp index"); + assert(pindex->phashBlock); // add this block to the view's block chain view.SetBestBlock(pindex->GetBlockHash()); @@ -2533,7 +2537,7 @@ private: CTxMemPool &pool; public: - ConnectTrace(CTxMemPool &_pool) : blocksConnected(1), pool(_pool) { + explicit ConnectTrace(CTxMemPool &_pool) : blocksConnected(1), pool(_pool) { pool.NotifyEntryRemoved.connect(boost::bind(&ConnectTrace::NotifyEntryRemoved, this, _1, _2)); } diff --git a/src/validation.h b/src/validation.h index 9d0f96b378..cd58c14088 100644 --- a/src/validation.h +++ b/src/validation.h @@ -47,9 +47,9 @@ struct ChainTxData; struct LockPoints; -/** Default for DEFAULT_WHITELISTRELAY. */ +/** Default for -whitelistrelay. */ static const bool DEFAULT_WHITELISTRELAY = true; -/** Default for DEFAULT_WHITELISTFORCERELAY. */ +/** Default for -whitelistforcerelay. */ static const bool DEFAULT_WHITELISTFORCERELAY = true; /** Default for -minrelaytxfee, minimum relay fee for transactions */ static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000; @@ -96,8 +96,8 @@ static const int MAX_CMPCTBLOCK_DEPTH = 5; static const int MAX_BLOCKTXN_DEPTH = 10; /** Size of the "block download window": how far ahead of our current height do we fetch? * Larger windows tolerate larger download speed differences between peer, but increase the potential - * degree of disordering of blocks on disk (which make reindexing and in the future perhaps pruning - * harder). We'll probably want to make this a per-peer adaptive value at some point. */ + * degree of disordering of blocks on disk (which make reindexing and pruning harder). We'll probably + * want to make this a per-peer adaptive value at some point. */ static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024; /** Time to wait (in seconds) between writing blocks/block index to disk. */ static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60; diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index b95e7a75b0..45ae80cdc8 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -39,7 +39,7 @@ struct MainSignalsInstance { // our own queue here :( SingleThreadedSchedulerClient m_schedulerClient; - MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {} + explicit MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {} }; static CMainSignals g_signals; diff --git a/src/versionbits.cpp b/src/versionbits.cpp index d3f1452cb4..a9faf104f9 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -203,7 +203,7 @@ protected: } public: - VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {} + explicit VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {} uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; } }; diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index c986e57678..5815793ffe 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -27,8 +27,7 @@ int CCrypter::BytesToKeySHA512AES(const std::vector& chSalt, cons CSHA512 di; di.Write((const unsigned char*)strKeyData.c_str(), strKeyData.size()); - if(chSalt.size()) - di.Write(&chSalt[0], chSalt.size()); + di.Write(chSalt.data(), chSalt.size()); di.Finalize(buf); for(int i = 0; i != count - 1; i++) @@ -82,7 +81,7 @@ bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector& vchCiphertext, CKeyingM vchPlaintext.resize(nLen); AES256CBCDecrypt dec(vchKey.data(), vchIV.data(), true); - nLen = dec.Decrypt(&vchCiphertext[0], vchCiphertext.size(), &vchPlaintext[0]); + nLen = dec.Decrypt(vchCiphertext.data(), vchCiphertext.size(), &vchPlaintext[0]); if(nLen == 0) return false; vchPlaintext.resize(nLen); @@ -113,7 +112,7 @@ static bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMateri { CCrypter cKeyCrypter; std::vector chIV(WALLET_CRYPTO_IV_SIZE); - memcpy(&chIV[0], &nIV, WALLET_CRYPTO_IV_SIZE); + memcpy(chIV.data(), &nIV, WALLET_CRYPTO_IV_SIZE); if(!cKeyCrypter.SetKey(vMasterKey, chIV)) return false; return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext); @@ -146,7 +145,7 @@ static bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector chIV(WALLET_CRYPTO_IV_SIZE); - memcpy(&chIV[0], &nIV, WALLET_CRYPTO_IV_SIZE); + memcpy(chIV.data(), &nIV, WALLET_CRYPTO_IV_SIZE); if(!cKeyCrypter.SetKey(vMasterKey, chIV)) return false; return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)); diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index d8012537db..18ecdd71df 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -16,13 +16,13 @@ const unsigned int WALLET_CRYPTO_IV_SIZE = 16; /** * Private key encryption is done based on a CMasterKey, * which holds a salt and random encryption key. - * + * * CMasterKeys are encrypted using AES-256-CBC using a key * derived using derivation method nDerivationMethod * (0 == EVP_sha512()) and derivation iterations nDeriveIterations. * vchOtherDerivationParameters is provided for alternative algorithms * which may require more parameters (such as scrypt). - * + * * Wallet Private Keys are then encrypted using AES-256-CBC * with the double-sha256 of the public key as the IV, and the * master key's key as the encryption key (see keystore.[ch]). @@ -192,28 +192,26 @@ public: { { LOCK(cs_KeyStore); - if (!IsCrypted()) + if (!IsCrypted()) { return CBasicKeyStore::HaveKey(address); + } return mapCryptedKeys.count(address) > 0; } return false; } bool GetKey(const CKeyID &address, CKey& keyOut) const override; bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const override; - void GetKeys(std::set &setAddress) const override + std::set GetKeys() const override { - if (!IsCrypted()) - { - CBasicKeyStore::GetKeys(setAddress); - return; + LOCK(cs_KeyStore); + if (!IsCrypted()) { + return CBasicKeyStore::GetKeys(); } - setAddress.clear(); - CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); - while (mi != mapCryptedKeys.end()) - { - setAddress.insert((*mi).first); - mi++; + std::set set_address; + for (const auto& mi : mapCryptedKeys) { + set_address.insert(mi.first); } + return set_address; } virtual bool GetHDChain(CHDChain& hdChainRet) const override; diff --git a/src/wallet/fees.cpp b/src/wallet/fees.cpp new file mode 100644 index 0000000000..8b5d1135aa --- /dev/null +++ b/src/wallet/fees.cpp @@ -0,0 +1,87 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-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 "wallet/fees.h" + +#include "policy/policy.h" +#include "txmempool.h" +#include "util.h" +#include "validation.h" +#include "wallet/coincontrol.h" +#include "wallet/wallet.h" + + +CAmount GetRequiredFee(unsigned int nTxBytes) +{ + return std::max(CWallet::minTxFee.GetFee(nTxBytes), ::minRelayTxFee.GetFee(nTxBytes)); +} + +CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc) +{ + /* User control of how to calculate fee uses the following parameter precedence: + 1. coin_control.m_feerate + 2. coin_control.m_confirm_target + 3. payTxFee (user-set global variable) + 4. nTxConfirmTarget (user-set global variable) + The first parameter that is set is used. + */ + CAmount fee_needed; + if (coin_control.m_feerate) { // 1. + fee_needed = coin_control.m_feerate->GetFee(nTxBytes); + if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE; + // Allow to override automatic min/max check over coin control instance + if (coin_control.fOverrideFeeRate) return fee_needed; + } + else if (!coin_control.m_confirm_target && ::payTxFee != CFeeRate(0)) { // 3. TODO: remove magic value of 0 for global payTxFee + fee_needed = ::payTxFee.GetFee(nTxBytes); + if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE; + } + else { // 2. or 4. + // We will use smart fee estimation + unsigned int target = coin_control.m_confirm_target ? *coin_control.m_confirm_target : ::nTxConfirmTarget; + // By default estimates are economical + bool conservative_estimate = true; + // Allow to override the default fee estimate mode over the CoinControl instance + if (coin_control.m_fee_mode == FeeEstimateMode::CONSERVATIVE) conservative_estimate = true; + else if (coin_control.m_fee_mode == FeeEstimateMode::ECONOMICAL) conservative_estimate = false; + + fee_needed = estimator.estimateSmartFee(target, feeCalc, conservative_estimate).GetFee(nTxBytes); + if (fee_needed == 0) { + // if we don't have enough data for estimateSmartFee, then use fallbackFee + fee_needed = CWallet::fallbackFee.GetFee(nTxBytes); + if (feeCalc) feeCalc->reason = FeeReason::FALLBACK; + } + // 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); + if (fee_needed < min_mempool_fee) { + fee_needed = min_mempool_fee; + if (feeCalc) feeCalc->reason = FeeReason::MEMPOOL_MIN; + } + } + + // prevent user from paying a fee below minRelayTxFee or minTxFee + CAmount required_fee = GetRequiredFee(nTxBytes); + if (required_fee > fee_needed) { + fee_needed = required_fee; + if (feeCalc) feeCalc->reason = FeeReason::REQUIRED; + } + // But always obey the maximum + if (fee_needed > maxTxFee) { + fee_needed = maxTxFee; + if (feeCalc) feeCalc->reason = FeeReason::MAXTXFEE; + } + return fee_needed; +} + +CFeeRate GetDiscardRate(const CBlockPolicyEstimator& estimator) +{ + unsigned int highest_target = estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); + CFeeRate discard_rate = estimator.estimateSmartFee(highest_target, nullptr /* FeeCalculation */, false /* conservative */); + // Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate + discard_rate = (discard_rate == CFeeRate(0)) ? CWallet::m_discard_rate : std::min(discard_rate, CWallet::m_discard_rate); + // Discard rate must be at least dustRelayFee + discard_rate = std::max(discard_rate, ::dustRelayFee); + return discard_rate; +} diff --git a/src/wallet/fees.h b/src/wallet/fees.h new file mode 100644 index 0000000000..7b8a7dc868 --- /dev/null +++ b/src/wallet/fees.h @@ -0,0 +1,34 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-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_WALLET_FEES_H +#define BITCOIN_WALLET_FEES_H + +#include "amount.h" + +class CBlockPolicyEstimator; +class CCoinControl; +class CFeeRate; +class CTxMemPool; +struct FeeCalculation; + +/** + * Return the minimum required fee taking into account the + * floating relay fee and user set minimum transaction fee + */ +CAmount GetRequiredFee(unsigned int nTxBytes); + +/** + * Estimate the minimum fee considering user set parameters + * and the required fee + */ +CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc); + +/** + * Return the maximum feerate for discarding change. + */ +CFeeRate GetDiscardRate(const CBlockPolicyEstimator& estimator); + +#endif // BITCOIN_WALLET_FEES_H diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp new file mode 100644 index 0000000000..2e05ccd01f --- /dev/null +++ b/src/wallet/init.cpp @@ -0,0 +1,298 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-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 "wallet/init.h" + +#include "keepass.h" +#include "net.h" +#include "util.h" +#include "utilmoneystr.h" +#include "validation.h" +#include "wallet/wallet.h" +#include "wallet/rpcwallet.h" + +std::string GetWalletHelpString(bool showDebug) +{ + std::string strUsage = HelpMessageGroup(_("Wallet options:")); + strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); + strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), DEFAULT_KEYPOOL_SIZE)); + strUsage += HelpMessageOpt("-fallbackfee=", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); + strUsage += HelpMessageOpt("-discardfee=", strprintf(_("The fee rate (in %s/kB) that indicates your tolerance for discarding change by adding it to the fee (default: %s). " + "Note: An output is discarded if it is dust at this rate, but we will always discard up to the dust relay fee and a discard fee above that is limited by the fee estimate for the longest target"), + CURRENCY_UNIT, FormatMoney(DEFAULT_DISCARD_FEE))); + strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); + strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), + CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); + strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup")); + strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); + strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); + strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP39/BIP44. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); + strUsage += HelpMessageOpt("-mnemonic=", _("User defined mnemonic for HD wallet (bip39). Only has effect during wallet creation/first start (default: randomly generated)")); + strUsage += HelpMessageOpt("-mnemonicpassphrase=", _("User defined mnemonic passphrase for HD wallet (BIP39). Only has effect during wallet creation/first start (default: empty string)")); + strUsage += HelpMessageOpt("-hdseed=", _("User defined seed for HD wallet (should be in hex). Only has effect during wallet creation/first start (default: randomly generated)")); + strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); + strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); + strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); + strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); + strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + + " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); + strUsage += HelpMessageOpt("-createwalletbackups=", strprintf(_("Number of automatic wallet backups (default: %u)"), nWalletBackups)); + strUsage += HelpMessageOpt("-walletbackupsdir=", _("Specify full path to directory for automatic wallet backups (must exist)")); + strUsage += HelpMessageOpt("-keepass", strprintf(_("Use KeePass 2 integration using KeePassHttp plugin (default: %u)"), 0)); + strUsage += HelpMessageOpt("-keepassport=", strprintf(_("Connect to KeePassHttp on port (default: %u)"), DEFAULT_KEEPASS_HTTP_PORT)); + strUsage += HelpMessageOpt("-keepasskey=", _("KeePassHttp key for AES encrypted communication with KeePass")); + strUsage += HelpMessageOpt("-keepassid=", _("KeePassHttp id for the established association")); + strUsage += HelpMessageOpt("-keepassname=", _("Name to construct url for KeePass entry that stores the wallet passphrase")); + + if (showDebug) + { + strUsage += HelpMessageGroup(_("Wallet debugging/testing options:")); + + strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); + strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); + strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); + strUsage += HelpMessageOpt("-walletrejectlongchains", strprintf(_("Wallet will not create transactions that violate mempool chain limits (default: %u)"), DEFAULT_WALLET_REJECT_LONG_CHAINS)); + } + + return strUsage; +} + +bool WalletParameterInteraction() +{ + gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT); + const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1; + + if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) + return true; + + if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && gArgs.SoftSetBoolArg("-walletbroadcast", false)) { + LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__); + } + + if (gArgs.GetBoolArg("-salvagewallet", false)) { + if (is_multiwallet) { + return InitError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet")); + } + // Rewrite just private keys: rescan to find transactions + if (gArgs.SoftSetBoolArg("-rescan", true)) { + LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); + } + } + + int zapwallettxes = gArgs.GetArg("-zapwallettxes", 0); + // -zapwallettxes implies dropping the mempool on startup + if (zapwallettxes != 0 && gArgs.SoftSetBoolArg("-persistmempool", false)) { + LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -persistmempool=0\n", __func__, zapwallettxes); + } + + // -zapwallettxes implies a rescan + if (zapwallettxes != 0) { + if (is_multiwallet) { + return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes")); + } + if (gArgs.SoftSetBoolArg("-rescan", true)) { + LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -rescan=1\n", __func__, zapwallettxes); + } + } + + if (is_multiwallet) { + if (gArgs.GetBoolArg("-upgradewallet", false)) { + return InitError(strprintf("%s is only allowed with a single wallet file", "-upgradewallet")); + } + } + + if (gArgs.GetBoolArg("-sysperms", false)) + return InitError("-sysperms is not allowed in combination with enabled wallet functionality"); + if (gArgs.GetArg("-prune", 0) && gArgs.GetBoolArg("-rescan", false)) + return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.")); + + if (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-minrelaytxfee") + " " + + _("The wallet will avoid paying less than the minimum relay fee.")); + + if (gArgs.IsArgSet("-mintxfee")) + { + CAmount n = 0; + if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) + return InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", ""))); + if (n > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-mintxfee") + " " + + _("This is the minimum transaction fee you pay on every transaction.")); + CWallet::minTxFee = CFeeRate(n); + } + if (gArgs.IsArgSet("-fallbackfee")) + { + CAmount nFeePerK = 0; + if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) + return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), gArgs.GetArg("-fallbackfee", ""))); + if (nFeePerK > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-fallbackfee") + " " + + _("This is the transaction fee you may pay when fee estimates are not available.")); + CWallet::fallbackFee = CFeeRate(nFeePerK); + } + if (gArgs.IsArgSet("-discardfee")) + { + CAmount nFeePerK = 0; + if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) + return InitError(strprintf(_("Invalid amount for -discardfee=: '%s'"), gArgs.GetArg("-discardfee", ""))); + if (nFeePerK > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-discardfee") + " " + + _("This is the transaction fee you may discard if change is smaller than dust at this level")); + CWallet::m_discard_rate = CFeeRate(nFeePerK); + } + if (gArgs.IsArgSet("-paytxfee")) + { + CAmount nFeePerK = 0; + if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) + return InitError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", ""))); + if (nFeePerK > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-paytxfee") + " " + + _("This is the transaction fee you will pay if you send a transaction.")); + + payTxFee = CFeeRate(nFeePerK, 1000); + if (payTxFee < ::minRelayTxFee) + { + return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s' (must be at least %s)"), + gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString())); + } + } + if (gArgs.IsArgSet("-maxtxfee")) + { + CAmount nMaxFee = 0; + if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee)) + return InitError(AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", ""))); + if (nMaxFee > HIGH_MAX_TX_FEE) + InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); + maxTxFee = nMaxFee; + if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) + { + return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), + gArgs.GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString())); + } + } + nTxConfirmTarget = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); + bSpendZeroConfChange = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); + + if (gArgs.IsArgSet("-walletbackupsdir")) { + if (!fs::is_directory(gArgs.GetArg("-walletbackupsdir", ""))) { + LogPrintf("%s: Warning: incorrect parameter -walletbackupsdir, path must exist! Using default path.\n", __func__); + InitWarning("Warning: incorrect parameter -walletbackupsdir, path must exist! Using default path.\n"); + + gArgs.ForceRemoveArg("-walletbackupsdir"); + } + } + + return true; +} + +void RegisterWalletRPC(CRPCTable &t) +{ + if (gArgs.GetBoolArg("-disablewallet", false)) return; + + RegisterWalletRPCCommands(t); +} + +bool VerifyWallets() +{ + if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) + return true; + + uiInterface.InitMessage(_("Verifying wallet(s)...")); + + // Keep track of each wallet absolute path to detect duplicates. + std::set wallet_paths; + + for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { + if (boost::filesystem::path(walletFile).filename() != walletFile) { + return InitError(strprintf(_("Error loading wallet %s. -wallet parameter must only specify a filename (not a path)."), walletFile)); + } + + if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) { + return InitError(strprintf(_("Error loading wallet %s. Invalid characters in -wallet filename."), walletFile)); + } + + fs::path wallet_path = fs::absolute(walletFile, GetDataDir()); + + if (fs::exists(wallet_path) && (!fs::is_regular_file(wallet_path) || fs::is_symlink(wallet_path))) { + return InitError(strprintf(_("Error loading wallet %s. -wallet filename must be a regular file."), walletFile)); + } + + if (!wallet_paths.insert(wallet_path).second) { + return InitError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), walletFile)); + } + + std::string strError; + if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) { + return InitError(strError); + } + + if (gArgs.GetBoolArg("-salvagewallet", false)) { + // Recover readable keypairs: + CWallet dummyWallet; + std::string backup_filename; + if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) { + return false; + } + } + + std::string strWarning; + bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError); + if (!strWarning.empty()) { + InitWarning(strWarning); + } + if (!dbV) { + InitError(strError); + return false; + } + } + + return true; +} + +bool OpenWallets() +{ + if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { + LogPrintf("Wallet disabled!\n"); + return true; + } + + for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { + CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile); + if (!pwallet) { + return false; + } + vpwallets.push_back(pwallet); + } + + return true; +} + +void StartWallets(CScheduler& scheduler) { + for (CWalletRef pwallet : vpwallets) { + pwallet->postInitProcess(scheduler); + } +} + +void FlushWallets() { + for (CWalletRef pwallet : vpwallets) { + pwallet->Flush(false); + } +} + +void StopWallets() { + for (CWalletRef pwallet : vpwallets) { + pwallet->Flush(true); + } +} + +void CloseWallets() { + for (CWalletRef pwallet : vpwallets) { + delete pwallet; + } + vpwallets.clear(); +} diff --git a/src/wallet/init.h b/src/wallet/init.h new file mode 100644 index 0000000000..0b3ee2dda2 --- /dev/null +++ b/src/wallet/init.h @@ -0,0 +1,43 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-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_WALLET_INIT_H +#define BITCOIN_WALLET_INIT_H + +#include + +class CRPCTable; +class CScheduler; + +//! Return the wallets help message. +std::string GetWalletHelpString(bool showDebug); + +//! Wallets parameter interaction +bool WalletParameterInteraction(); + +//! Register wallet RPCs. +void RegisterWalletRPC(CRPCTable &tableRPC); + +//! Responsible for reading and validating the -wallet arguments and verifying the wallet database. +// This function will perform salvage on the wallet if requested, as long as only one wallet is +// being loaded (WalletParameterInteraction forbids -salvagewallet, -zapwallettxes or -upgradewallet with multiwallet). +bool VerifyWallets(); + +//! Load wallet databases. +bool OpenWallets(); + +//! Complete startup of wallets. +void StartWallets(CScheduler& scheduler); + +//! Flush all wallets in preparation for shutdown. +void FlushWallets(); + +//! Stop all wallets. Wallets will be flushed first. +void StopWallets(); + +//! Close all wallets. +void CloseWallets(); + +#endif // BITCOIN_WALLET_INIT_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index cf6f79ccf4..76a1cb5192 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -9,7 +9,6 @@ #include "chain.h" #include "consensus/validation.h" #include "core_io.h" -#include "init.h" #include "httpserver.h" #include "keepass.h" #include "net.h" @@ -27,6 +26,8 @@ #include "wallet/wallet.h" #include "wallet/walletdb.h" +#include // For StartShutdown + #include "llmq/quorums_chainlocks.h" #include "llmq/quorums_instantsend.h" @@ -660,7 +661,7 @@ UniValue signmessage(const JSONRPCRequest& request) if (!key.SignCompact(ss.GetHash(), vchSig)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); - return EncodeBase64(&vchSig[0], vchSig.size()); + return EncodeBase64(vchSig.data(), vchSig.size()); } UniValue getreceivedbyaddress(const JSONRPCRequest& request) @@ -2958,7 +2959,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) " \"changePosition\" (numeric, optional, default random) The index of the change output\n" " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" - " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n" + " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific fee rate in " + CURRENCY_UNIT + "/kB\n" " \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n" " The fee will be equally deducted from the amount of each specified output.\n" " The outputs are specified by their zero-based index, before any change output is added.\n" @@ -3206,8 +3207,8 @@ static const CRPCCommand commands[] = { "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} }, { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} }, { "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","addlocked","comment","comment_to"} }, - { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","addlocked","comment","subtractfeefrom","use_ps","conf_target","estimate_mode"} }, - { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","use_ps","conf_target","estimate_mode"} }, + { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","addlocked","comment","subtractfeefrom","use_is","use_ps","conf_target","estimate_mode"} }, + { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","use_is","use_ps","conf_target","estimate_mode"} }, { "wallet", "setaccount", &setaccount, {"address","account"} }, { "wallet", "settxfee", &settxfee, {"amount"} }, { "wallet", "setprivatesendrounds", &setprivatesendrounds, {"rounds"} }, @@ -3222,16 +3223,13 @@ static const CRPCCommand commands[] = { "generating", "generate", &generate, {"nblocks","maxtries"} }, #endif //ENABLE_MINER { "wallet", "keepass", &keepass, {} }, - { "hidden", "instantsendtoaddress", &instantsendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount"} }, + { "hidden", "instantsendtoaddress", &instantsendtoaddress, {} }, { "wallet", "dumphdinfo", &dumphdinfo, {} }, { "wallet", "importelectrumwallet", &importelectrumwallet, {"filename", "index"} }, }; void RegisterWalletRPCCommands(CRPCTable &t) { - if (gArgs.GetBoolArg("-disablewallet", false)) - return; - for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) t.appendCommand(commands[vcidx].name, &commands[vcidx]); } diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index db0808b93b..14e51610d9 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -5,7 +5,10 @@ #ifndef BITCOIN_WALLET_RPCWALLET_H #define BITCOIN_WALLET_RPCWALLET_H +#include + class CRPCTable; +class CWallet; class JSONRPCRequest; void RegisterWalletRPCCommands(CRPCTable &t); diff --git a/src/wallet/test/crypto_tests.cpp b/src/wallet/test/crypto_tests.cpp index f9008c3767..1542156713 100644 --- a/src/wallet/test/crypto_tests.cpp +++ b/src/wallet/test/crypto_tests.cpp @@ -281,7 +281,7 @@ BOOST_AUTO_TEST_CASE(passphrase) { std::string hash(GetRandHash().ToString()); std::vector vchSalt(8); - GetRandBytes(&vchSalt[0], vchSalt.size()); + GetRandBytes(vchSalt.data(), vchSalt.size()); uint32_t rounds = InsecureRand32(); if (rounds > 30000) rounds = 30000; diff --git a/src/wallet/test/wallet_test_fixture.h b/src/wallet/test/wallet_test_fixture.h index 72398a7040..8f73645ebd 100644 --- a/src/wallet/test/wallet_test_fixture.h +++ b/src/wallet/test/wallet_test_fixture.h @@ -10,7 +10,7 @@ /** Testing setup and teardown for wallet. */ struct WalletTestingSetup: public TestingSetup { - WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); + explicit WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~WalletTestingSetup(); }; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 940451b1bd..7ad988648f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -30,6 +30,7 @@ #include "util.h" #include "ui_interface.h" #include "utilmoneystr.h" +#include "wallet/fees.h" #include "governance/governance.h" #include "keepass.h" @@ -661,63 +662,6 @@ void CWallet::Flush(bool shutdown) dbw->Flush(shutdown); } -bool CWallet::Verify() -{ - if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) - return true; - - uiInterface.InitMessage(_("Verifying wallet(s)...")); - - // Keep track of each wallet absolute path to detect duplicates. - std::set wallet_paths; - - for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { - if (boost::filesystem::path(walletFile).filename() != walletFile) { - return InitError(strprintf(_("Error loading wallet %s. -wallet parameter must only specify a filename (not a path)."), walletFile)); - } - - if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) { - return InitError(strprintf(_("Error loading wallet %s. Invalid characters in -wallet filename."), walletFile)); - } - - fs::path wallet_path = fs::absolute(walletFile, GetDataDir()); - - if (fs::exists(wallet_path) && (!fs::is_regular_file(wallet_path) || fs::is_symlink(wallet_path))) { - return InitError(strprintf(_("Error loading wallet %s. -wallet filename must be a regular file."), walletFile)); - } - - if (!wallet_paths.insert(wallet_path).second) { - return InitError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), walletFile)); - } - - std::string strError; - if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) { - return InitError(strError); - } - - if (gArgs.GetBoolArg("-salvagewallet", false)) { - // Recover readable keypairs: - CWallet dummyWallet; - std::string backup_filename; - if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) { - return false; - } - } - - std::string strWarning; - bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError); - if (!strWarning.empty()) { - InitWarning(strWarning); - } - if (!dbV) { - InitError(strError); - return false; - } - } - - return true; -} - void CWallet::SyncMetaData(std::pair range) { // We want all the wallet transactions in range to have the same metadata as @@ -742,6 +686,7 @@ void CWallet::SyncMetaData(std::pair ran const uint256& hash = it->second; CWalletTx* copyTo = &mapWallet[hash]; if (copyFrom == copyTo) continue; + assert(copyFrom && "Oldest wallet transaction in range assumed to have been found."); if (!copyFrom->IsEquivalentTo(*copyTo)) continue; copyTo->mapValue = copyFrom->mapValue; copyTo->vOrderForm = copyFrom->vOrderForm; @@ -3625,17 +3570,6 @@ bool CWallet::ConvertList(std::vector vecTxIn, std::vector& vecA return true; } -static CFeeRate GetDiscardRate(const CBlockPolicyEstimator& estimator) -{ - unsigned int highest_target = estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); - CFeeRate discard_rate = estimator.estimateSmartFee(highest_target, nullptr /* FeeCalculation */, false /* conservative */); - // Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate - discard_rate = (discard_rate == CFeeRate(0)) ? CWallet::m_discard_rate : std::min(discard_rate, CWallet::m_discard_rate); - // Discard rate must be at least dustRelayFee - discard_rate = std::max(discard_rate, ::dustRelayFee); - return discard_rate; -} - bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign, int nExtraPayloadSize) { @@ -4118,68 +4052,6 @@ bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, CWalletDB *pwa return true; } -CAmount CWallet::GetRequiredFee(unsigned int nTxBytes) -{ - return std::max(minTxFee.GetFee(nTxBytes), ::minRelayTxFee.GetFee(nTxBytes)); -} - -CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc) -{ - /* User control of how to calculate fee uses the following parameter precedence: - 1. coin_control.m_feerate - 2. coin_control.m_confirm_target - 3. payTxFee (user-set global variable) - 4. nTxConfirmTarget (user-set global variable) - The first parameter that is set is used. - */ - CAmount fee_needed; - if (coin_control.m_feerate) { // 1. - fee_needed = coin_control.m_feerate->GetFee(nTxBytes); - if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE; - // Allow to override automatic min/max check over coin control instance - if (coin_control.fOverrideFeeRate) return fee_needed; - } - else if (!coin_control.m_confirm_target && ::payTxFee != CFeeRate(0)) { // 3. TODO: remove magic value of 0 for global payTxFee - fee_needed = ::payTxFee.GetFee(nTxBytes); - if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE; - } - else { // 2. or 4. - // We will use smart fee estimation - unsigned int target = coin_control.m_confirm_target ? *coin_control.m_confirm_target : ::nTxConfirmTarget; - // By default estimates are economical - bool conservative_estimate = true; - // Allow to override the default fee estimate mode over the CoinControl instance - if (coin_control.m_fee_mode == FeeEstimateMode::CONSERVATIVE) conservative_estimate = true; - else if (coin_control.m_fee_mode == FeeEstimateMode::ECONOMICAL) conservative_estimate = false; - - fee_needed = estimator.estimateSmartFee(target, feeCalc, conservative_estimate).GetFee(nTxBytes); - if (fee_needed == 0) { - // if we don't have enough data for estimateSmartFee, then use fallbackFee - fee_needed = fallbackFee.GetFee(nTxBytes); - if (feeCalc) feeCalc->reason = FeeReason::FALLBACK; - } - // 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); - if (fee_needed < min_mempool_fee) { - fee_needed = min_mempool_fee; - if (feeCalc) feeCalc->reason = FeeReason::MEMPOOL_MIN; - } - } - - // prevent user from paying a fee below minRelayTxFee or minTxFee - CAmount required_fee = GetRequiredFee(nTxBytes); - if (required_fee > fee_needed) { - fee_needed = required_fee; - if (feeCalc) feeCalc->reason = FeeReason::REQUIRED; - } - // But always obey the maximum - if (fee_needed > maxTxFee) { - fee_needed = maxTxFee; - if (feeCalc) feeCalc->reason = FeeReason::MAXTXFEE; - } - return fee_needed; -} - DBErrors CWallet::LoadWallet(bool& fFirstRunRet) { LOCK2(cs_main, cs_wallet); @@ -4895,13 +4767,10 @@ void CWallet::GetKeyBirthTimes(std::map &mapKeyBirth) c // map in which we'll infer heights of other keys CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganized; use a 144-block safety margin std::map mapKeyFirstBlock; - std::set setKeys; - GetKeys(setKeys); - for (const CKeyID &keyid : setKeys) { + for (const CKeyID &keyid : GetKeys()) { if (mapKeyBirth.count(keyid) == 0) mapKeyFirstBlock[keyid] = pindexMax; } - setKeys.clear(); // if there are no such keys, we're done if (mapKeyFirstBlock.empty()) @@ -5052,55 +4921,6 @@ std::vector CWallet::GetDestValues(const std::string& prefix) const return values; } -std::string CWallet::GetWalletHelpString(bool showDebug) -{ - std::string strUsage = HelpMessageGroup(_("Wallet options:")); - strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); - strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), DEFAULT_KEYPOOL_SIZE)); - strUsage += HelpMessageOpt("-fallbackfee=", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), - CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); - strUsage += HelpMessageOpt("-discardfee=", strprintf(_("The fee rate (in %s/kB) that indicates your tolerance for discarding change by adding it to the fee (default: %s). " - "Note: An output is discarded if it is dust at this rate, but we will always discard up to the dust relay fee and a discard fee above that is limited by the fee estimate for the longest target"), - CURRENCY_UNIT, FormatMoney(DEFAULT_DISCARD_FEE))); - strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), - CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); - strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), - CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); - strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup")); - strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); - strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP39/BIP44. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); - strUsage += HelpMessageOpt("-mnemonic=", _("User defined mnemonic for HD wallet (bip39). Only has effect during wallet creation/first start (default: randomly generated)")); - strUsage += HelpMessageOpt("-mnemonicpassphrase=", _("User defined mnemonic passphrase for HD wallet (BIP39). Only has effect during wallet creation/first start (default: empty string)")); - strUsage += HelpMessageOpt("-hdseed=", _("User defined seed for HD wallet (should be in hex). Only has effect during wallet creation/first start (default: randomly generated)")); - strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); - strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); - strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); - strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); - strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + - " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); - strUsage += HelpMessageOpt("-createwalletbackups=", strprintf(_("Number of automatic wallet backups (default: %u)"), nWalletBackups)); - strUsage += HelpMessageOpt("-walletbackupsdir=", _("Specify full path to directory for automatic wallet backups (must exist)")); - strUsage += HelpMessageOpt("-keepass", strprintf(_("Use KeePass 2 integration using KeePassHttp plugin (default: %u)"), 0)); - strUsage += HelpMessageOpt("-keepassport=", strprintf(_("Connect to KeePassHttp on port (default: %u)"), DEFAULT_KEEPASS_HTTP_PORT)); - strUsage += HelpMessageOpt("-keepasskey=", _("KeePassHttp key for AES encrypted communication with KeePass")); - strUsage += HelpMessageOpt("-keepassid=", _("KeePassHttp id for the established association")); - strUsage += HelpMessageOpt("-keepassname=", _("Name to construct url for KeePass entry that stores the wallet passphrase")); - - if (showDebug) - { - strUsage += HelpMessageGroup(_("Wallet debugging/testing options:")); - - strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); - strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); - strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); - strUsage += HelpMessageOpt("-walletrejectlongchains", strprintf(_("Wallet will not create transactions that violate mempool chain limits (default: %u)"), DEFAULT_WALLET_REJECT_LONG_CHAINS)); - } - - return strUsage; -} - CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) { // needed to restore wallet transaction meta data after -zapwallettxes @@ -5315,24 +5135,6 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) return walletInstance; } -bool CWallet::InitLoadWallet() -{ - if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { - LogPrintf("Wallet disabled!\n"); - return true; - } - - for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { - CWallet * const pwallet = CreateWalletFromFile(walletFile); - if (!pwallet) { - return false; - } - vpwallets.push_back(pwallet); - } - - return true; -} - std::atomic CWallet::fFlushScheduled(false); void CWallet::postInitProcess(CScheduler& scheduler) @@ -5347,134 +5149,6 @@ void CWallet::postInitProcess(CScheduler& scheduler) } } -bool CWallet::ParameterInteraction() -{ - gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT); - const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1; - - if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) - return true; - - if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && gArgs.SoftSetBoolArg("-walletbroadcast", false)) { - LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__); - } - - if (gArgs.GetBoolArg("-salvagewallet", false)) { - if (is_multiwallet) { - return InitError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet")); - } - // Rewrite just private keys: rescan to find transactions - if (gArgs.SoftSetBoolArg("-rescan", true)) { - LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); - } - } - - int zapwallettxes = gArgs.GetArg("-zapwallettxes", 0); - // -zapwallettxes implies dropping the mempool on startup - if (zapwallettxes != 0 && gArgs.SoftSetBoolArg("-persistmempool", false)) { - LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -persistmempool=0\n", __func__, zapwallettxes); - } - - // -zapwallettxes implies a rescan - if (zapwallettxes != 0) { - if (is_multiwallet) { - return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes")); - } - if (gArgs.SoftSetBoolArg("-rescan", true)) { - LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -rescan=1\n", __func__, zapwallettxes); - } - } - - if (is_multiwallet) { - if (gArgs.GetBoolArg("-upgradewallet", false)) { - return InitError(strprintf("%s is only allowed with a single wallet file", "-upgradewallet")); - } - } - - if (gArgs.GetBoolArg("-sysperms", false)) - return InitError("-sysperms is not allowed in combination with enabled wallet functionality"); - if (gArgs.GetArg("-prune", 0) && gArgs.GetBoolArg("-rescan", false)) - return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.")); - - if (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB) - InitWarning(AmountHighWarn("-minrelaytxfee") + " " + - _("The wallet will avoid paying less than the minimum relay fee.")); - - if (gArgs.IsArgSet("-mintxfee")) - { - CAmount n = 0; - if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) - return InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", ""))); - if (n > HIGH_TX_FEE_PER_KB) - InitWarning(AmountHighWarn("-mintxfee") + " " + - _("This is the minimum transaction fee you pay on every transaction.")); - CWallet::minTxFee = CFeeRate(n); - } - if (gArgs.IsArgSet("-fallbackfee")) - { - CAmount nFeePerK = 0; - if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) - return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), gArgs.GetArg("-fallbackfee", ""))); - if (nFeePerK > HIGH_TX_FEE_PER_KB) - InitWarning(AmountHighWarn("-fallbackfee") + " " + - _("This is the transaction fee you may pay when fee estimates are not available.")); - CWallet::fallbackFee = CFeeRate(nFeePerK); - } - if (gArgs.IsArgSet("-discardfee")) - { - CAmount nFeePerK = 0; - if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) - return InitError(strprintf(_("Invalid amount for -discardfee=: '%s'"), gArgs.GetArg("-discardfee", ""))); - if (nFeePerK > HIGH_TX_FEE_PER_KB) - InitWarning(AmountHighWarn("-discardfee") + " " + - _("This is the transaction fee you may discard if change is smaller than dust at this level")); - CWallet::m_discard_rate = CFeeRate(nFeePerK); - } - if (gArgs.IsArgSet("-paytxfee")) - { - CAmount nFeePerK = 0; - if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) - return InitError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", ""))); - if (nFeePerK > HIGH_TX_FEE_PER_KB) - InitWarning(AmountHighWarn("-paytxfee") + " " + - _("This is the transaction fee you will pay if you send a transaction.")); - - payTxFee = CFeeRate(nFeePerK, 1000); - if (payTxFee < ::minRelayTxFee) - { - return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s' (must be at least %s)"), - gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString())); - } - } - if (gArgs.IsArgSet("-maxtxfee")) - { - CAmount nMaxFee = 0; - if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee)) - return InitError(AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", ""))); - if (nMaxFee > HIGH_MAX_TX_FEE) - InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); - maxTxFee = nMaxFee; - if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) - { - return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), - gArgs.GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString())); - } - } - nTxConfirmTarget = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); - bSpendZeroConfChange = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); - - if (gArgs.IsArgSet("-walletbackupsdir")) { - if (!fs::is_directory(gArgs.GetArg("-walletbackupsdir", ""))) { - LogPrintf("%s: Warning: incorrect parameter -walletbackupsdir, path must exist! Using default path.\n", __func__); - InitWarning("Warning: incorrect parameter -walletbackupsdir, path must exist! Using default path.\n"); - - gArgs.ForceRemoveArg("-walletbackupsdir"); - } - } - - return true; -} - bool CWallet::InitAutoBackup() { if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 499234a276..d522885d02 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -223,7 +223,7 @@ public: Init(); } - CMerkleTx(CTransactionRef arg) + explicit CMerkleTx(CTransactionRef arg) { SetTx(std::move(arg)); Init(); @@ -599,7 +599,7 @@ public: //! todo: add something to note what created it (user, getnewaddress, change) //! maybe should have a map property map - CWalletKey(int64_t nExpires=0); + explicit CWalletKey(int64_t nExpires=0); ADD_SERIALIZE_METHODS; @@ -827,7 +827,7 @@ public: } // Create wallet with passed-in database handle - CWallet(std::unique_ptr dbw_in) : dbw(std::move(dbw_in)) + explicit CWallet(std::unique_ptr dbw_in) : dbw(std::move(dbw_in)) { SetNull(); } @@ -1073,16 +1073,6 @@ public: static CFeeRate minTxFee; static CFeeRate fallbackFee; static CFeeRate m_discard_rate; - /** - * Estimate the minimum fee considering user set parameters - * and the required fee - */ - static CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc); - /** - * Return the minimum required fee taking into account the - * floating relay fee and user set minimum transaction fee - */ - static CAmount GetRequiredFee(unsigned int nTxBytes); bool NewKeyPool(); size_t KeypoolCountExternalKeys(); @@ -1170,11 +1160,6 @@ public: //! Flush wallet (bitdb flush) void Flush(bool shutdown=false); - //! Responsible for reading and validating the -wallet arguments and verifying the wallet database. - // This function will perform salvage on the wallet if requested, as long as only one wallet is - // being loaded (CWallet::ParameterInteraction forbids -salvagewallet, -zapwallettxes or -upgradewallet with multiwallet). - static bool Verify(); - /** * Address book entry changed. * @note called with lock cs_wallet held. @@ -1214,12 +1199,8 @@ public: /* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */ bool AbandonTransaction(const uint256& hashTx); - /* Returns the wallets help message */ - static std::string GetWalletHelpString(bool showDebug); - /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ static CWallet* CreateWalletFromFile(const std::string walletFile); - static bool InitLoadWallet(); /** * Wallet post-init setup @@ -1227,9 +1208,6 @@ public: */ void postInitProcess(CScheduler& scheduler); - /* Wallets parameter interaction */ - static bool ParameterInteraction(); - /* Initialize AutoBackup functionality */ static bool InitAutoBackup(); @@ -1268,7 +1246,7 @@ protected: CPubKey vchPubKey; bool fInternal; public: - CReserveKey(CWallet* pwalletIn) + explicit CReserveKey(CWallet* pwalletIn) { nIndex = -1; pwallet = pwalletIn; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 53131ef601..f37ebe902f 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -43,9 +43,9 @@ bool CWalletDB::WritePurpose(const std::string& strAddress, const std::string& s return WriteIC(std::make_pair(std::string("purpose"), strAddress), strPurpose); } -bool CWalletDB::ErasePurpose(const std::string& strPurpose) +bool CWalletDB::ErasePurpose(const std::string& strAddress) { - return EraseIC(std::make_pair(std::string("purpose"), strPurpose)); + return EraseIC(std::make_pair(std::string("purpose"), strAddress)); } bool CWalletDB::WriteTx(const CWalletTx& wtx) diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 520ee56e6f..e8576ce9ee 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -67,7 +67,7 @@ public: { SetNull(); } - CKeyMetadata(int64_t nCreateTime_) + explicit CKeyMetadata(int64_t nCreateTime_) { SetNull(); nCreateTime = nCreateTime_; @@ -117,7 +117,7 @@ private: } public: - CWalletDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool _fFlushOnClose = true) : + explicit CWalletDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool _fFlushOnClose = true) : batch(dbw, pszMode, _fFlushOnClose), m_dbw(dbw) { diff --git a/test/functional/p2p-leaktests.py b/test/functional/p2p-leaktests.py index 73183c880a..aaf196fd60 100755 --- a/test/functional/p2p-leaktests.py +++ b/test/functional/p2p-leaktests.py @@ -115,6 +115,9 @@ class P2PLeakTest(BitcoinTestFramework): self.nodes[0].disconnect_p2ps() + # Wait until all connections are closed + wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 0) + # Make sure no unexpected messages came in assert(no_version_bannode.unexpected_msg == False) assert(no_version_idlenode.unexpected_msg == False) diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py index 8e3332cfc0..8778102e36 100755 --- a/test/functional/test_framework/mininode.py +++ b/test/functional/test_framework/mininode.py @@ -1896,6 +1896,7 @@ class NetworkThread(threading.Thread): disconnected.append(obj) [ obj.handle_close() for obj in disconnected ] asyncore.loop(0.1, use_poll=True, map=mininode_socket_map, count=1) + logger.debug("Network thread closing") def network_thread_start(): """Start the network thread.""" diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 8d7ed8fad9..4981ee8f26 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -403,7 +403,7 @@ def print_results(test_results, max_len_name, runtime): class TestHandler: """ - Trigger the testscrips passed in via the list. + Trigger the test scripts passed in via the list. """ def __init__(self, *, num_tests_parallel, tests_dir, tmpdir, test_list, flags, timeout_duration):