diff --git a/Makefile.am b/Makefile.am index 9de5e5c37d95..bec6213bb56f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,10 +59,10 @@ OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \ $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh -COVERAGE_INFO = baseline_filtered_combined.info baseline.info \ - leveldb_baseline.info test_dash_filtered.info total_coverage.info \ +COVERAGE_INFO = baseline.info \ + test_dash_filtered.info total_coverage.info \ baseline_filtered.info functional_test.info functional_test_filtered.info \ - leveldb_baseline_filtered.info test_dash_coverage.info test_dash.info + test_dash_coverage.info test_dash.info dist-hook: -$(GIT) archive --format=tar HEAD -- src/clientversion.cpp | $(AMTAR) -C $(top_distdir) -xf - @@ -166,52 +166,45 @@ $(BITCOIN_CLI_BIN): FORCE $(MAKE) -C src $(@F) if USE_LCOV +LCOV_FILTER_PATTERN=-p "/usr/include/" -p "src/leveldb/" -p "src/bench/" -p "src/univalue" -p "src/crypto/ctaes" -p "src/secp256k1" baseline.info: $(LCOV) -c -i -d $(abs_builddir)/src -o $@ baseline_filtered.info: baseline.info - $(LCOV) -r $< "/usr/include/*" -o $@ + $(abs_builddir)/contrib/filter-lcov.py $(LCOV_FILTER_PATTERN) $< $@ + $(LCOV) -a $@ $(LCOV_OPTS) -o $@ -leveldb_baseline.info: baseline_filtered.info - $(LCOV) -c -i -d $(abs_builddir)/src/leveldb -b $(abs_builddir)/src/leveldb -o $@ - -leveldb_baseline_filtered.info: leveldb_baseline.info - $(LCOV) -r $< "/usr/include/*" -o $@ - -baseline_filtered_combined.info: leveldb_baseline_filtered.info baseline_filtered.info - $(LCOV) -a leveldb_baseline_filtered.info -a baseline_filtered.info -o $@ - -test_dash.info: baseline_filtered_combined.info +test_dash.info: baseline_filtered.info $(MAKE) -C src/ check - $(LCOV) -c -d $(abs_builddir)/src -t test_dash -o $@ - $(LCOV) -z -d $(abs_builddir)/src - $(LCOV) -z -d $(abs_builddir)/src/leveldb + $(LCOV) -c $(LCOV_OPTS) -d $(abs_builddir)/src -t test_dash -o $@ + $(LCOV) -z $(LCOV_OPTS) -d $(abs_builddir)/src test_dash_filtered.info: test_dash.info - $(LCOV) -r $< "/usr/include/*" -o $@ + $(abs_builddir)/contrib/filter-lcov.py $(LCOV_FILTER_PATTERN) $< $@ + $(LCOV) -a $@ $(LCOV_OPTS) -o $@ functional_test.info: test_dash_filtered.info - -@TIMEOUT=15 python test/functional/test_runner.py $(EXTENDED_FUNCTIONAL_TESTS) - $(LCOV) -c -d $(abs_builddir)/src --t functional-tests -o $@ - $(LCOV) -z -d $(abs_builddir)/src - $(LCOV) -z -d $(abs_builddir)/src/leveldb + -@TIMEOUT=15 test/functional/test_runner.py $(EXTENDED_FUNCTIONAL_TESTS) + $(LCOV) -c $(LCOV_OPTS) -d $(abs_builddir)/src --t functional-tests -o $@ + $(LCOV) -z $(LCOV_OPTS) -d $(abs_builddir)/src functional_test_filtered.info: functional_test.info - $(LCOV) -r $< "/usr/include/*" -o $@ + $(abs_builddir)/contrib/filter-lcov.py $(LCOV_FILTER_PATTERN) $< $@ + $(LCOV) -a $@ $(LCOV_OPTS) -o $@ -test_dash_coverage.info: baseline_filtered_combined.info test_dash_filtered.info - $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_dash_filtered.info -o $@ +test_dash_coverage.info: baseline_filtered.info test_dash_filtered.info + $(LCOV) -a $(LCOV_OPTS) baseline_filtered.info -a test_dash_filtered.info -o $@ -total_coverage.info: baseline_filtered_combined.info test_dash_filtered.info functional_test_filtered.info - $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_dash_filtered.info -a functional_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt +total_coverage.info: test_dash_filtered.info functional_test_filtered.info + $(LCOV) -a $(LCOV_OPTS) baseline_filtered.info -a test_dash_filtered.info -a functional_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt test_dash.coverage/.dirstamp: test_dash_coverage.info - $(GENHTML) -s $< -o $(@D) + $(GENHTML) -s $(LCOV_OPTS) $< -o $(@D) @touch $@ total.coverage/.dirstamp: total_coverage.info - $(GENHTML) -s $< -o $(@D) + $(GENHTML) -s $(LCOV_OPTS) $< -o $(@D) @touch $@ cov: test_dash.coverage/.dirstamp total.coverage/.dirstamp diff --git a/configure.ac b/configure.ac index 2f7bcbe97734..2f7f8b6fb17d 100644 --- a/configure.ac +++ b/configure.ac @@ -159,6 +159,12 @@ AC_ARG_ENABLE([lcov], [enable lcov testing (default is no)])], [use_lcov=yes], [use_lcov=no]) + +AC_ARG_ENABLE([lcov-branch-coverage], + [AS_HELP_STRING([--enable-lcov-branch-coverage], + [enable lcov testing branch coverage (default is no)])], + [use_lcov_branch=yes], + [use_lcov_branch=no]) AC_ARG_ENABLE([glibc-back-compat], [AS_HELP_STRING([--enable-glibc-back-compat], @@ -486,6 +492,12 @@ if test x$use_lcov = xyes; then [AC_MSG_ERROR("lcov testing requested but --coverage linker flag does not work")]) AX_CHECK_COMPILE_FLAG([--coverage],[CXXFLAGS="$CXXFLAGS --coverage"], [AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")]) + AC_DEFINE(USE_COVERAGE, 1, [Define this symbol if coverage is enabled]) + CXXFLAGS="$CXXFLAGS -Og" +fi + +if test x$use_lcov_branch != xno; then + AC_SUBST(LCOV_OPTS, "$LCOV_OPTS --rc lcov_branch_coverage=1") fi dnl Check for endianness diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py index 4bd65ad947ea..464e2a8a46b6 100755 --- a/contrib/devtools/check-doc.py +++ b/contrib/devtools/check-doc.py @@ -21,7 +21,7 @@ REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"') REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")') # list unsupported, deprecated and duplicate args as they need no documentation -SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-blockminsize', '-sendfreetransactions']) +SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-blockminsize']) def main(): used = check_output(CMD_GREP_ARGS, shell=True, universal_newlines=True) diff --git a/contrib/filter-lcov.py b/contrib/filter-lcov.py new file mode 100755 index 000000000000..299377d69115 --- /dev/null +++ b/contrib/filter-lcov.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +import argparse + +parser = argparse.ArgumentParser(description='Remove the coverage data from a tracefile for all files matching the pattern.') +parser.add_argument('--pattern', '-p', action='append', help='the pattern of files to remove', required=True) +parser.add_argument('tracefile', help='the tracefile to remove the coverage data from') +parser.add_argument('outfile', help='filename for the output to be written to') + +args = parser.parse_args() +tracefile = args.tracefile +pattern = args.pattern +outfile = args.outfile + +in_remove = False +with open(tracefile, 'r') as f: + with open(outfile, 'w') as wf: + for line in f: + for p in pattern: + if line.startswith("SF:") and p in line: + in_remove = True + if not in_remove: + wf.write(line) + if line == 'end_of_record\n': + in_remove = False diff --git a/contrib/verifybinaries/README.md b/contrib/verifybinaries/README.md index ed3e14fb6c11..3ffe0a2f2895 100644 --- a/contrib/verifybinaries/README.md +++ b/contrib/verifybinaries/README.md @@ -26,6 +26,14 @@ The script returns 0 if everything passes the checks. It returns 1 if either the ./verify.sh bitcoin-core-0.13.0-rc3 ``` +If you only want to download the binaries of certain platform, add the corresponding suffix, e.g.: + +```sh +./verify.sh bitcoin-core-0.11.2-osx +./verify.sh 0.12.0-linux +./verify.sh bitcoin-core-0.13.0-rc3-win64 +``` + If you do not want to keep the downloaded binaries, specify anything as the second parameter. ```sh diff --git a/contrib/verifybinaries/verify.sh b/contrib/verifybinaries/verify.sh index e20770c96a96..c2cc2b7013ad 100755 --- a/contrib/verifybinaries/verify.sh +++ b/contrib/verifybinaries/verify.sh @@ -42,13 +42,36 @@ if [ -n "$1" ]; then VERSION="$VERSIONPREFIX$1" fi - #now let's see if the version string contains "rc", and strip it off if it does - # and simultaneously add RCSUBDIR to BASEDIR, where we will look for SIGNATUREFILENAME - if [[ $VERSION == *"$RCVERSIONSTRING"* ]]; then - BASEDIR="$BASEDIR${VERSION/%-$RCVERSIONSTRING*}/" - BASEDIR="$BASEDIR$RCSUBDIR.$RCVERSIONSTRING${VERSION: -1}/" + STRIPPEDLAST="${VERSION%-*}" + + #now let's see if the version string contains "rc" or a platform name (e.g. "osx") + if [[ "$STRIPPEDLAST-" == "$VERSIONPREFIX" ]]; then + BASEDIR="$BASEDIR$VERSION/" else + # let's examine the last part to see if it's rc and/or platform name + STRIPPEDNEXTTOLAST="${STRIPPEDLAST%-*}" + if [[ "$STRIPPEDNEXTTOLAST-" == "$VERSIONPREFIX" ]]; then + + LASTSUFFIX="${VERSION##*-}" + VERSION="$STRIPPEDLAST" + + if [[ $LASTSUFFIX == *"$RCVERSIONSTRING"* ]]; then + RCVERSION="$LASTSUFFIX" + else + PLATFORM="$LASTSUFFIX" + fi + + else + RCVERSION="${STRIPPEDLAST##*-}" + PLATFORM="${VERSION##*-}" + + VERSION="$STRIPPEDNEXTTOLAST" + fi + BASEDIR="$BASEDIR$VERSION/" + if [[ $RCVERSION == *"$RCVERSIONSTRING"* ]]; then + BASEDIR="$BASEDIR$RCSUBDIR.$RCVERSION/" + fi fi SIGNATUREFILE="$BASEDIR$SIGNATUREFILENAME" @@ -92,12 +115,22 @@ if [ $RET -ne 0 ]; then exit "$RET" fi +if [ -n "$PLATFORM" ]; then + grep $PLATFORM $TMPFILE > "$TMPFILE-plat" + TMPFILESIZE=$(stat -c%s "$TMPFILE-plat") + if [ $TMPFILESIZE -eq 0 ]; then + echo "error: no files matched the platform specified" && exit 3 + fi + mv "$TMPFILE-plat" $TMPFILE +fi + #here we extract the filenames from the signature file FILES=$(awk '{print $2}' "$TMPFILE") #and download these one by one for file in $FILES do + echo "Downloading $file" wget --quiet -N "$BASEDIR$file" done diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 81a660e83a55..7f484724a490 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,8 +1,8 @@ package=expat -$(package)_version=2.2.0 +$(package)_version=2.2.1 $(package)_download_path=https://downloads.sourceforge.net/project/expat/expat/$($(package)_version) $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=d9e50ff2d19b3538bd2127902a89987474e1a4db8e43a66a4d1a712ab9a504ff +$(package)_sha256_hash=1868cadae4c82a018e361e2b2091de103cd820aaacb0d6cfa49bd2cd83978885 define $(package)_set_vars $(package)_config_opts=--disable-static diff --git a/doc/developer-notes.md b/doc/developer-notes.md index d0f6e2773ea0..36d6a2d38f75 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -46,7 +46,7 @@ class Class return true; } } -} +} // namespace foo ``` Doxygen comments @@ -267,7 +267,7 @@ General C++ - Assertions should not have side-effects - - *Rationale*: Even though the source code is set to to refuse to compile + - *Rationale*: Even though the source code is set to refuse to compile with assertions disabled, having side-effects in assertions is unexpected and makes the code harder to understand @@ -417,6 +417,21 @@ Source code organization - *Rationale*: Avoids symbol conflicts +- Terminate namespaces with a comment (`// namespace mynamespace`). The comment + should be placed on the same line as the brace closing the namespace, e.g. + +```c++ +namespace mynamespace { + ... +} // namespace mynamespace + +namespace { + ... +} // namespace +``` + + - *Rationale*: Avoids confusion about the namespace context + GUI ----- diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index 4fee9ba7fc1f..7083820958af 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -50,7 +50,8 @@ qt_test_test_dash_qt_SOURCES = \ if ENABLE_WALLET qt_test_test_dash_qt_SOURCES += \ qt/test/paymentservertests.cpp \ - qt/test/wallettests.cpp + qt/test/wallettests.cpp \ + wallet/test/wallet_test_fixture.cpp endif nodist_qt_test_test_dash_qt_SOURCES = $(TEST_QT_MOC_CPP) diff --git a/src/addrdb.cpp b/src/addrdb.cpp index dce52aea6ae6..5239e893844f 100644 --- a/src/addrdb.cpp +++ b/src/addrdb.cpp @@ -15,25 +15,31 @@ #include "tinyformat.h" #include "util.h" +namespace { -CBanDB::CBanDB() +template +bool SerializeDB(Stream& stream, const Data& data) { - pathBanlist = GetDataDir() / "banlist.dat"; + // Write and commit header, data + try { + CHashWriter hasher(SER_DISK, CLIENT_VERSION); + stream << FLATDATA(Params().MessageStart()) << data; + hasher << FLATDATA(Params().MessageStart()) << data; + stream << hasher.GetHash(); + } catch (const std::exception& e) { + return error("%s: Serialize or I/O error - %s", __func__, e.what()); + } + + return true; } -bool CBanDB::Write(const banmap_t& banSet) +template +bool SerializeFileDB(const std::string& prefix, const fs::path& path, const Data& data) { // Generate random temporary filename unsigned short randv = 0; GetRandBytes((unsigned char*)&randv, sizeof(randv)); - std::string tmpfn = strprintf("banlist.dat.%04x", randv); - - // serialize banlist, checksum data up to that point, then append csum - CDataStream ssBanlist(SER_DISK, CLIENT_VERSION); - ssBanlist << FLATDATA(Params().MessageStart()); - ssBanlist << banSet; - uint256 hash = Hash(ssBanlist.begin(), ssBanlist.end()); - ssBanlist << hash; + std::string tmpfn = strprintf("%s.%04x", prefix, randv); // open temp output file, and associate with CAutoFile fs::path pathTmp = GetDataDir() / tmpfn; @@ -42,69 +48,41 @@ bool CBanDB::Write(const banmap_t& banSet) if (fileout.IsNull()) return error("%s: Failed to open file %s", __func__, pathTmp.string()); - // Write and commit header, data - try { - fileout << ssBanlist; - } - catch (const std::exception& e) { - return error("%s: Serialize or I/O error - %s", __func__, e.what()); - } + // Serialize + if (!SerializeDB(fileout, data)) return false; FileCommit(fileout.Get()); fileout.fclose(); - // replace existing banlist.dat, if any, with new banlist.dat.XXXX - if (!RenameOver(pathTmp, pathBanlist)) + // replace existing file, if any, with new file + if (!RenameOver(pathTmp, path)) return error("%s: Rename-into-place failed", __func__); return true; } -bool CBanDB::Read(banmap_t& banSet) +template +bool DeserializeDB(Stream& stream, Data& data, bool fCheckSum = true) { - // open input file, and associate with CAutoFile - FILE *file = fsbridge::fopen(pathBanlist, "rb"); - CAutoFile filein(file, SER_DISK, CLIENT_VERSION); - if (filein.IsNull()) - return error("%s: Failed to open file %s", __func__, pathBanlist.string()); - - // use file size to size memory buffer - uint64_t fileSize = fs::file_size(pathBanlist); - uint64_t dataSize = 0; - // Don't try to resize to a negative number if file is small - if (fileSize >= sizeof(uint256)) - dataSize = fileSize - sizeof(uint256); - std::vector vchData; - vchData.resize(dataSize); - uint256 hashIn; - - // read data and checksum from file - try { - filein.read((char *)&vchData[0], dataSize); - filein >> hashIn; - } - catch (const std::exception& e) { - return error("%s: Deserialize or I/O error - %s", __func__, e.what()); - } - filein.fclose(); - - CDataStream ssBanlist(vchData, SER_DISK, CLIENT_VERSION); - - // verify stored checksum matches input data - uint256 hashTmp = Hash(ssBanlist.begin(), ssBanlist.end()); - if (hashIn != hashTmp) - return error("%s: Checksum mismatch, data corrupted", __func__); - - unsigned char pchMsgTmp[4]; try { + CHashVerifier verifier(&stream); // de-serialize file header (network specific magic number) and .. - ssBanlist >> FLATDATA(pchMsgTmp); - + unsigned char pchMsgTmp[4]; + verifier >> FLATDATA(pchMsgTmp); // ... verify the network matches ours if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) return error("%s: Invalid network magic number", __func__); - // de-serialize ban data - ssBanlist >> banSet; + // de-serialize data + verifier >> data; + + // verify checksum + if (fCheckSum) { + uint256 hashTmp; + stream >> hashTmp; + if (hashTmp != verifier.GetHash()) { + return error("%s: Checksum mismatch, data corrupted", __func__); + } + } } catch (const std::exception& e) { return error("%s: Deserialize or I/O error - %s", __func__, e.what()); @@ -113,106 +91,56 @@ bool CBanDB::Read(banmap_t& banSet) return true; } -CAddrDB::CAddrDB() +template +bool DeserializeFileDB(const fs::path& path, Data& data) { - pathAddr = GetDataDir() / "peers.dat"; + // open input file, and associate with CAutoFile + FILE *file = fsbridge::fopen(path, "rb"); + CAutoFile filein(file, SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) + return error("%s: Failed to open file %s", __func__, path.string()); + + return DeserializeDB(filein, data); } -bool CAddrDB::Write(const CAddrMan& addr) -{ - // Generate random temporary filename - unsigned short randv = 0; - GetRandBytes((unsigned char*)&randv, sizeof(randv)); - std::string tmpfn = strprintf("peers.dat.%04x", randv); +} - // serialize addresses, checksum data up to that point, then append csum - CDataStream ssPeers(SER_DISK, CLIENT_VERSION); - ssPeers << FLATDATA(Params().MessageStart()); - ssPeers << addr; - uint256 hash = Hash(ssPeers.begin(), ssPeers.end()); - ssPeers << hash; +CBanDB::CBanDB() +{ + pathBanlist = GetDataDir() / "banlist.dat"; +} - // open temp output file, and associate with CAutoFile - fs::path pathTmp = GetDataDir() / tmpfn; - FILE *file = fsbridge::fopen(pathTmp, "wb"); - CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); - if (fileout.IsNull()) - return error("%s: Failed to open file %s", __func__, pathTmp.string()); +bool CBanDB::Write(const banmap_t& banSet) +{ + return SerializeFileDB("banlist", pathBanlist, banSet); +} - // Write and commit header, data - try { - fileout << ssPeers; - } - catch (const std::exception& e) { - return error("%s: Serialize or I/O error - %s", __func__, e.what()); - } - FileCommit(fileout.Get()); - fileout.fclose(); +bool CBanDB::Read(banmap_t& banSet) +{ + return DeserializeFileDB(pathBanlist, banSet); +} - // replace existing peers.dat, if any, with new peers.dat.XXXX - if (!RenameOver(pathTmp, pathAddr)) - return error("%s: Rename-into-place failed", __func__); +CAddrDB::CAddrDB() +{ + pathAddr = GetDataDir() / "peers.dat"; +} - return true; +bool CAddrDB::Write(const CAddrMan& addr) +{ + return SerializeFileDB("peers", pathAddr, addr); } bool CAddrDB::Read(CAddrMan& addr) { - // open input file, and associate with CAutoFile - FILE *file = fsbridge::fopen(pathAddr, "rb"); - CAutoFile filein(file, SER_DISK, CLIENT_VERSION); - if (filein.IsNull()) - return error("%s: Failed to open file %s", __func__, pathAddr.string()); - - // use file size to size memory buffer - uint64_t fileSize = fs::file_size(pathAddr); - uint64_t dataSize = 0; - // Don't try to resize to a negative number if file is small - if (fileSize >= sizeof(uint256)) - dataSize = fileSize - sizeof(uint256); - std::vector vchData; - vchData.resize(dataSize); - uint256 hashIn; - - // read data and checksum from file - try { - filein.read((char *)&vchData[0], dataSize); - filein >> hashIn; - } - catch (const std::exception& e) { - return error("%s: Deserialize or I/O error - %s", __func__, e.what()); - } - filein.fclose(); - - CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION); - - // verify stored checksum matches input data - uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); - if (hashIn != hashTmp) - return error("%s: Checksum mismatch, data corrupted", __func__); - - return Read(addr, ssPeers); + return DeserializeFileDB(pathAddr, addr); } bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers) { - unsigned char pchMsgTmp[4]; - try { - // de-serialize file header (network specific magic number) and .. - ssPeers >> FLATDATA(pchMsgTmp); - - // ... verify the network matches ours - if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) - return error("%s: Invalid network magic number", __func__); - - // de-serialize address data into one CAddrMan object - ssPeers >> addr; - } - catch (const std::exception& e) { - // de-serialization has failed, ensure addrman is left in a clean state + bool ret = DeserializeDB(ssPeers, addr, false); + if (!ret) { + // Ensure addrman is left in a clean state addr.Clear(); - return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } - - return true; + return ret; } diff --git a/src/addrdb.h b/src/addrdb.h index afb62c580ad2..4e3b45c3f095 100644 --- a/src/addrdb.h +++ b/src/addrdb.h @@ -85,7 +85,7 @@ class CAddrDB CAddrDB(); bool Write(const CAddrMan& addr); bool Read(CAddrMan& addr); - bool Read(CAddrMan& addr, CDataStream& ssPeers); + static bool Read(CAddrMan& addr, CDataStream& ssPeers); }; /** Access to the banlist database (banlist.dat) */ diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index 64c9dc2bb851..1755b72a8356 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -15,6 +15,8 @@ template base_uint::base_uint(const std::string& str) { + static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); + SetHex(str); } diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 5cc52f6e72af..52a4747c1586 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -31,12 +31,16 @@ class base_uint base_uint() { + static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); + for (int i = 0; i < WIDTH; i++) pn[i] = 0; } base_uint(const base_uint& b) { + static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); + for (int i = 0; i < WIDTH; i++) pn[i] = b.pn[i]; } @@ -50,6 +54,8 @@ class base_uint base_uint(uint64_t b) { + static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); + pn[0] = (unsigned int)b; pn[1] = (unsigned int)(b >> 32); for (int i = 2; i < WIDTH; i++) @@ -174,7 +180,7 @@ class base_uint { // prefix operator int i = 0; - while (++pn[i] == 0 && i < WIDTH-1) + while (i < WIDTH && ++pn[i] == 0) i++; return *this; } @@ -191,7 +197,7 @@ class base_uint { // prefix operator int i = 0; - while (--pn[i] == (uint32_t)-1 && i < WIDTH-1) + while (i < WIDTH && --pn[i] == (uint32_t)-1) i++; return *this; } diff --git a/src/base58.cpp b/src/base58.cpp index b251a688a3b8..0ae0ff2a4a33 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -225,7 +225,7 @@ class CBitcoinAddressVisitor : public boost::static_visitor bool operator()(const CNoDestination& no) const { return false; } }; -} // anon namespace +} // namespace bool CBitcoinAddress::Set(const CKeyID& id) { diff --git a/src/chain.cpp b/src/chain.cpp index 6154e24f2317..e075e36c83cc 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -126,7 +126,7 @@ arith_uint256 GetBlockProof(const CBlockIndex& block) if (fNegative || fOverflow || bnTarget == 0) return 0; // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 - // as it's too large for a arith_uint256. However, as 2**256 is at least as large + // 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. return (~bnTarget / (bnTarget + 1)) + 1; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index de4a2fa3bb7d..4c3d3498c014 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -313,10 +313,9 @@ class CMainParams : public CChainParams { assert(consensus.hashGenesisBlock == uint256S("0x00000ffd590b1485b3caadc19b22e6379c733355108f107a430458cdf3407ab6")); assert(genesis.hashMerkleRoot == uint256S("0xe0028eb9648db56b1ac77cf090b99048a8007e2bb64b68f092c03c7f56a662c7")); - - vSeeds.push_back(CDNSSeedData("dash.org", "dnsseed.dash.org")); - vSeeds.push_back(CDNSSeedData("dashdot.io", "dnsseed.dashdot.io")); - vSeeds.push_back(CDNSSeedData("masternode.io", "dnsseed.masternode.io")); + vSeeds.emplace_back("dnsseed.dash.org", true); + vSeeds.emplace_back("dnsseed.dashdot.io", true); + vSeeds.emplace_back("dnsseed.masternode.io", true); // Dash addresses start with 'X' base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,76); @@ -493,8 +492,8 @@ class CTestNetParams : public CChainParams { vSeeds.clear(); // nodes with support for servicebits filtering should be at the top - vSeeds.push_back(CDNSSeedData("dashdot.io", "testnet-seed.dashdot.io")); - vSeeds.push_back(CDNSSeedData("masternode.io", "test.dnsseed.masternode.io")); + vSeeds.emplace_back("testnet-seed.dashdot.io", true); + vSeeds.emplace_back("test.dnsseed.masternode.io", true); // Testnet Dash addresses start with 'y' base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,140); diff --git a/src/chainparams.h b/src/chainparams.h index e47b9ce5b535..1334ddca1cc4 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -15,9 +15,9 @@ #include struct CDNSSeedData { - std::string name, host; + std::string host; bool supportsServiceBitsFiltering; - CDNSSeedData(const std::string &strName, const std::string &strHost, bool supportsServiceBitsFilteringIn = false) : name(strName), host(strHost), supportsServiceBitsFiltering(supportsServiceBitsFilteringIn) {} + CDNSSeedData(const std::string &strHost, bool supportsServiceBitsFilteringIn) : host(strHost), supportsServiceBitsFiltering(supportsServiceBitsFilteringIn) {} }; struct SeedSpec6 { diff --git a/src/compat/glibc_sanity.cpp b/src/compat/glibc_sanity.cpp index f4931f7d4d90..7df6eb25b2ed 100644 --- a/src/compat/glibc_sanity.cpp +++ b/src/compat/glibc_sanity.cpp @@ -56,7 +56,7 @@ bool sanity_test_fdelt() } #endif -} // anon namespace +} // namespace bool glibc_sanity_test() { diff --git a/src/compat/glibcxx_sanity.cpp b/src/compat/glibcxx_sanity.cpp index cee8a98c7f58..569fb1bbe886 100644 --- a/src/compat/glibcxx_sanity.cpp +++ b/src/compat/glibcxx_sanity.cpp @@ -38,7 +38,7 @@ bool sanity_test_list(unsigned int size) return true; } -} // anon namespace +} // namespace // trigger: string::at(x) on an empty string to trigger __throw_out_of_range_fmt. // test: force std::string to throw an out_of_range exception. Verify that diff --git a/src/cuckoocache.h b/src/cuckoocache.h index 58375494555e..fd24d05ee7b9 100644 --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -176,7 +176,7 @@ class cache */ mutable std::vector epoch_flags; - /** epoch_heuristic_counter is used to determine when a epoch might be aged + /** epoch_heuristic_counter is used to determine when an epoch might be aged * & an expensive scan should be done. epoch_heuristic_counter is * decremented on insert and reset to the new number of inserts which would * cause the epoch to reach epoch_size when it reaches zero. @@ -184,7 +184,7 @@ class cache uint32_t epoch_heuristic_counter; /** epoch_size is set to be the number of elements supposed to be in a - * epoch. When the number of non-erased elements in a epoch + * epoch. When the number of non-erased elements in an epoch * exceeds epoch_size, a new epoch should be started and all * current entries demoted. epoch_size is set to be 45% of size because * we want to keep load around 90%, and we support 3 epochs at once -- @@ -206,6 +206,37 @@ class cache /** compute_hashes is convenience for not having to write out this * expression everywhere we use the hash values of an Element. * + * We need to map the 32-bit input hash onto a hash bucket in a range [0, size) in a + * manner which preserves as much of the hash's uniformity as possible. Ideally + * this would be done by bitmasking but the size is usually not a power of two. + * + * The naive approach would be to use a mod -- which isn't perfectly uniform but so + * long as the hash is much larger than size it is not that bad. Unfortunately, + * mod/division is fairly slow on ordinary microprocessors (e.g. 90-ish cycles on + * haswell, ARM doesn't even have an instruction for it.); when the divisor is a + * constant the compiler will do clever tricks to turn it into a multiply+add+shift, + * but size is a run-time value so the compiler can't do that here. + * + * One option would be to implement the same trick the compiler uses and compute the + * constants for exact division based on the size, as described in "{N}-bit Unsigned + * Division via {N}-bit Multiply-Add" by Arch D. Robison in 2005. But that code is + * somewhat complicated and the result is still slower than other options: + * + * Instead we treat the 32-bit random number as a Q32 fixed-point number in the range + * [0,1) and simply multiply it by the size. Then we just shift the result down by + * 32-bits to get our bucket number. The results has non-uniformity the same as a + * mod, but it is much faster to compute. More about this technique can be found at + * http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ + * + * The resulting non-uniformity is also more equally distributed which would be + * advantageous for something like linear probing, though it shouldn't matter + * one way or the other for a cuckoo table. + * + * The primary disadvantage of this approach is increased intermediate precision is + * required but for a 32-bit random number we only need the high 32 bits of a + * 32*32->64 multiply, which means the operation is reasonably fast even on a + * typical 32-bit processor. + * * @param e the element whose hashes will be returned * @returns std::array of deterministic hashes derived from e */ diff --git a/src/dash-tx.cpp b/src/dash-tx.cpp index 420a39a4aaef..70322e01de47 100644 --- a/src/dash-tx.cpp +++ b/src/dash-tx.cpp @@ -281,7 +281,6 @@ static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& str if (!pubkey.IsFullyValid()) throw std::runtime_error("invalid TX output pubkey"); CScript scriptPubKey = GetScriptForRawPubKey(pubkey); - CBitcoinAddress addr(scriptPubKey); // Extract and validate FLAGS bool bScriptHash = false; diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index eb6d5ecb5fd6..bf836d8bc25c 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -215,4 +215,4 @@ const std::vector& GetObfuscateKey(const CDBWrapper &w) return w.obfuscate_key; } -}; +} // namespace dbwrapper_private diff --git a/src/evo/deterministicmns.h b/src/evo/deterministicmns.h index d8702c518660..a95e313e3395 100644 --- a/src/evo/deterministicmns.h +++ b/src/evo/deterministicmns.h @@ -25,7 +25,7 @@ class CValidationState; namespace llmq { class CFinalCommitment; -} +} // namespace llmq class CDeterministicMNState { diff --git a/src/evo/simplifiedmns.h b/src/evo/simplifiedmns.h index 8a66f428f4cd..ba567c911d4d 100644 --- a/src/evo/simplifiedmns.h +++ b/src/evo/simplifiedmns.h @@ -19,7 +19,7 @@ class CDeterministicMN; namespace llmq { class CFinalCommitment; -} +} // namespace llmq class CSimplifiedMNListEntry { diff --git a/src/httprpc.cpp b/src/httprpc.cpp index e0b943045ebb..36a1fd651e5d 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -92,35 +92,32 @@ static bool multiUserAuthorized(std::string strUserPass) std::string strUser = strUserPass.substr(0, strUserPass.find(":")); std::string strPass = strUserPass.substr(strUserPass.find(":") + 1); - if (gArgs.IsArgSet("-rpcauth")) { + for (const std::string& strRPCAuth : gArgs.GetArgs("-rpcauth")) { //Search for multi-user login/pass "rpcauth" from config - for (std::string strRPCAuth : gArgs.GetArgs("-rpcauth")) - { - std::vector vFields; - boost::split(vFields, strRPCAuth, boost::is_any_of(":$")); - if (vFields.size() != 3) { - //Incorrect formatting in config file - continue; - } - - std::string strName = vFields[0]; - if (!TimingResistantEqual(strName, strUser)) { - continue; - } - - std::string strSalt = vFields[1]; - std::string strHash = vFields[2]; - - static const unsigned int KEY_SIZE = 32; - unsigned char out[KEY_SIZE]; - - CHMAC_SHA256(reinterpret_cast(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast(strPass.c_str()), strPass.size()).Finalize(out); - std::vector hexvec(out, out+KEY_SIZE); - std::string strHashFromPass = HexStr(hexvec); - - if (TimingResistantEqual(strHashFromPass, strHash)) { - return true; - } + std::vector vFields; + boost::split(vFields, strRPCAuth, boost::is_any_of(":$")); + if (vFields.size() != 3) { + //Incorrect formatting in config file + continue; + } + + std::string strName = vFields[0]; + if (!TimingResistantEqual(strName, strUser)) { + continue; + } + + std::string strSalt = vFields[1]; + std::string strHash = vFields[2]; + + static const unsigned int KEY_SIZE = 32; + unsigned char out[KEY_SIZE]; + + CHMAC_SHA256(reinterpret_cast(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast(strPass.c_str()), strPass.size()).Finalize(out); + std::vector hexvec(out, out+KEY_SIZE); + std::string strHashFromPass = HexStr(hexvec); + + if (TimingResistantEqual(strHashFromPass, strHash)) { + return true; } } return false; diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 7b8c21c9a649..4f369b241644 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -21,13 +21,13 @@ #include #include -#include -#include #include #include #include #include +#include "support/events.h" + #ifdef EVENT__HAVE_NETINET_IN_H #include #ifdef _XOPEN_SOURCE_EXTENDED @@ -197,18 +197,16 @@ static bool InitHTTPAllowList() LookupHost("::1", localv6, false); rpc_allow_subnets.push_back(CSubNet(localv4, 8)); // always allow IPv4 local subnet rpc_allow_subnets.push_back(CSubNet(localv6)); // always allow IPv6 localhost - if (gArgs.IsArgSet("-rpcallowip")) { - for (const std::string& strAllow : gArgs.GetArgs("-rpcallowip")) { - CSubNet subnet; - LookupSubNet(strAllow.c_str(), subnet); - if (!subnet.IsValid()) { - uiInterface.ThreadSafeMessageBox( - strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow), - "", CClientUIInterface::MSG_ERROR); - return false; - } - rpc_allow_subnets.push_back(subnet); + for (const std::string& strAllow : gArgs.GetArgs("-rpcallowip")) { + CSubNet subnet; + LookupSubNet(strAllow.c_str(), subnet); + if (!subnet.IsValid()) { + uiInterface.ThreadSafeMessageBox( + strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow), + "", CClientUIInterface::MSG_ERROR); + return false; } + rpc_allow_subnets.push_back(subnet); } std::string strAllowed; for (const CSubNet& subnet : rpc_allow_subnets) @@ -369,9 +367,6 @@ static void libevent_log_cb(int severity, const char *msg) bool InitHTTPServer() { - struct evhttp* http = 0; - struct event_base* base = 0; - if (!InitHTTPAllowList()) return false; @@ -397,17 +392,13 @@ bool InitHTTPServer() evthread_use_pthreads(); #endif - base = event_base_new(); // XXX RAII - if (!base) { - LogPrintf("Couldn't create an event_base: exiting\n"); - return false; - } + raii_event_base base_ctr = obtain_event_base(); /* Create a new evhttp object to handle requests. */ - http = evhttp_new(base); // XXX RAII + raii_evhttp http_ctr = obtain_evhttp(base_ctr.get()); + struct evhttp* http = http_ctr.get(); if (!http) { LogPrintf("couldn't create evhttp. Exiting.\n"); - event_base_free(base); return false; } @@ -418,8 +409,6 @@ bool InitHTTPServer() if (!HTTPBindAddresses(http)) { LogPrintf("Unable to bind any endpoint for RPC server\n"); - evhttp_free(http); - event_base_free(base); return false; } @@ -428,8 +417,9 @@ bool InitHTTPServer() LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth); workQueue = new WorkQueue(workQueueDepth); - eventBase = base; - eventHTTP = http; + // tranfer ownership to eventBase/HTTP via .release() + eventBase = base_ctr.release(); + eventHTTP = http_ctr.release(); return true; } diff --git a/src/httpserver.h b/src/httpserver.h index d9b45f076d64..b7fce073208b 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -86,7 +86,7 @@ class HTTPRequest /** * Get the request header specified by hdr, or an empty string. - * Return an pair (isPresent,string). + * Return a pair (isPresent,string). */ std::pair GetHeader(const std::string& hdr); @@ -125,7 +125,7 @@ class HTTPClosure virtual ~HTTPClosure() {} }; -/** Event class. This can be used either as an cross-thread trigger or as a timer. +/** Event class. This can be used either as a cross-thread trigger or as a timer. */ class HTTPEvent { diff --git a/src/init.cpp b/src/init.cpp index 1d6b1012ffc2..0012281d921e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -120,14 +120,6 @@ static CDSNotificationInterface* pdsNotificationInterface = NULL; #define MIN_CORE_FILEDESCRIPTORS 150 #endif -/** Used to pass flags to the Bind() function */ -enum BindFlags { - BF_NONE = 0, - BF_EXPLICIT = (1U << 0), - BF_REPORT_ERROR = (1U << 1), - BF_WHITELIST = (1U << 2), -}; - static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; ////////////////////////////////////////////////////////////////////////////// @@ -397,17 +389,6 @@ static void registerSignalHandler(int signal, void(*handler)(int)) } #endif -bool static Bind(CConnman& connman, const CService &addr, unsigned int flags) { - if (!(flags & BF_EXPLICIT) && IsLimited(addr)) - return false; - std::string strError; - if (!connman.BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) { - if (flags & BF_REPORT_ERROR) - return InitError(strError); - return false; - } - return true; -} void OnRPCStarted() { uiInterface.NotifyBlockTip.connect(&RPCNotifyBlockChange); @@ -1032,7 +1013,7 @@ int nUserMaxConnections; int nFD; ServiceFlags nLocalServices = NODE_NETWORK; -} +} // namespace [[noreturn]] static void new_handler_terminate() { @@ -1054,8 +1035,6 @@ bool AppInitBasicSetup() // Turn off Microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); -#endif -#if _MSC_VER >= 1400 // Disable confusing "helpful" text message on abort, Ctrl-C _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif @@ -1125,10 +1104,14 @@ bool AppInitParameterInteraction() fAllowPrivateNet = gArgs.GetBoolArg("-allowprivatenet", DEFAULT_ALLOWPRIVATENET); + // -bind and -whitebind can't be set when not listening + size_t nUserBind = gArgs.GetArgs("-bind").size() + gArgs.GetArgs("-whitebind").size(); + if (nUserBind != 0 && !gArgs.GetBoolArg("-listen", DEFAULT_LISTEN)) { + return InitError("Cannot set -bind or -whitebind together with -listen=0"); + } + // Make sure enough file descriptors are available - int nBind = std::max( - (gArgs.IsArgSet("-bind") ? gArgs.GetArgs("-bind").size() : 0) + - (gArgs.IsArgSet("-whitebind") ? gArgs.GetArgs("-whitebind").size() : 0), size_t(1)); + int nBind = std::max(nUserBind, size_t(1)); nUserMaxConnections = gArgs.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); nMaxConnections = std::max(nUserMaxConnections, 0); @@ -1160,14 +1143,12 @@ bool AppInitParameterInteraction() } // Now remove the logging categories which were explicitly excluded - if (gArgs.IsArgSet("-debugexclude")) { - for (const std::string& cat : gArgs.GetArgs("-debugexclude")) { - uint64_t flag; + for (const std::string& cat : gArgs.GetArgs("-debugexclude")) { + uint64_t flag; if (!GetLogCategory(&flag, &cat)) { InitWarning(strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat)); - } - logCategories &= ~flag; } + logCategories &= ~flag; } // Check for -debugnet @@ -1261,14 +1242,7 @@ bool AppInitParameterInteraction() if (nConnectTimeout <= 0) nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; - // Fee-per-kilobyte amount required for mempool acceptance and relay - // If you are mining, be careful setting this: - // if you set it to zero then - // a transaction spammer can cheaply fill blocks using - // 0-fee transactions. It should be set above the real - // cost to you of processing a transaction. - if (gArgs.IsArgSet("-minrelaytxfee")) - { + if (gArgs.IsArgSet("-minrelaytxfee")) { CAmount n = 0; if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) { return InitError(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", ""))); @@ -1591,13 +1565,10 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) uacomments.push_back(strprintf("devnet=%s", GetDevNetName())); } - if (gArgs.IsArgSet("-uacomment")) { - for (std::string cmt : gArgs.GetArgs("-uacomment")) - { - if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) - return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt)); - uacomments.push_back(cmt); - } + for (const std::string& cmt : gArgs.GetArgs("-uacomment")) { + if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) + return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt)); + uacomments.push_back(cmt); } strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments); if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) { @@ -1620,16 +1591,6 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } } - if (gArgs.IsArgSet("-whitelist")) { - for (const std::string& net : gArgs.GetArgs("-whitelist")) { - CSubNet subnet; - LookupSubNet(net.c_str(), subnet); - if (!subnet.IsValid()) - return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net)); - connman.AddWhitelistedRange(subnet); - } - } - // Check for host lookup allowed before parsing any network related parameters fNameLookup = gArgs.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); @@ -1680,44 +1641,12 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fDiscover = gArgs.GetBoolArg("-discover", true); fRelayTxes = !gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); - if (fListen) { - bool fBound = false; - if (gArgs.IsArgSet("-bind")) { - for (const std::string& strBind : gArgs.GetArgs("-bind")) { - CService addrBind; - if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) - return InitError(ResolveErrMsg("bind", strBind)); - fBound |= Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR)); - } - } - if (gArgs.IsArgSet("-whitebind")) { - for (const std::string& strBind : gArgs.GetArgs("-whitebind")) { - CService addrBind; - if (!Lookup(strBind.c_str(), addrBind, 0, false)) - return InitError(ResolveErrMsg("whitebind", strBind)); - if (addrBind.GetPort() == 0) - return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind)); - fBound |= Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST)); - } - } - if (!gArgs.IsArgSet("-bind") && !gArgs.IsArgSet("-whitebind")) { - struct in_addr inaddr_any; - inaddr_any.s_addr = INADDR_ANY; - fBound |= Bind(connman, CService((in6_addr)IN6ADDR_ANY_INIT, GetListenPort()), BF_NONE); - fBound |= Bind(connman, CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE); - } - if (!fBound) - return InitError(_("Failed to listen on any port. Use -listen=0 if you want this.")); - } - - if (gArgs.IsArgSet("-externalip")) { - for (const std::string& strAddr : gArgs.GetArgs("-externalip")) { - CService addrLocal; - if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) - AddLocal(addrLocal, LOCAL_MANUAL); - else - return InitError(ResolveErrMsg("externalip", strAddr)); - } + for (const std::string& strAddr : gArgs.GetArgs("-externalip")) { + CService addrLocal; + if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) + AddLocal(addrLocal, LOCAL_MANUAL); + else + return InitError(ResolveErrMsg("externalip", strAddr)); } #if ENABLE_ZMQ @@ -2095,10 +2024,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); std::vector vImportFiles; - if (gArgs.IsArgSet("-loadblock")) - { - for (const std::string& strFile : gArgs.GetArgs("-loadblock")) - vImportFiles.push_back(strFile); + for (const std::string& strFile : gArgs.GetArgs("-loadblock")) { + vImportFiles.push_back(strFile); } threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); @@ -2125,7 +2052,6 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // Map ports with UPnP MapPort(gArgs.GetBoolArg("-upnp", DEFAULT_UPNP)); - std::string strNodeError; CConnman::Options connOptions; connOptions.nLocalServices = nLocalServices; connOptions.nRelevantServices = nRelevantServices; @@ -2141,12 +2067,39 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) connOptions.nMaxOutboundTimeframe = nMaxOutboundTimeframe; connOptions.nMaxOutboundLimit = nMaxOutboundLimit; + for (const std::string& strBind : gArgs.GetArgs("-bind")) { + CService addrBind; + if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) { + return InitError(ResolveErrMsg("bind", strBind)); + } + connOptions.vBinds.push_back(addrBind); + } + for (const std::string& strBind : gArgs.GetArgs("-whitebind")) { + CService addrBind; + if (!Lookup(strBind.c_str(), addrBind, 0, false)) { + return InitError(ResolveErrMsg("whitebind", strBind)); + } + if (addrBind.GetPort() == 0) { + return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind)); + } + connOptions.vWhiteBinds.push_back(addrBind); + } + + for (const auto& net : gArgs.GetArgs("-whitelist")) { + CSubNet subnet; + LookupSubNet(net.c_str(), subnet); + if (!subnet.IsValid()) + return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net)); + connOptions.vWhitelistedRange.push_back(subnet); + } + if (gArgs.IsArgSet("-seednode")) { connOptions.vSeedNodes = gArgs.GetArgs("-seednode"); } - if (!connman.Start(scheduler, strNodeError, connOptions)) - return InitError(strNodeError); + if (!connman.Start(scheduler, connOptions)) { + return false; + } // ********************************************************* Step 13: finished diff --git a/src/leveldb/db/version_set.h b/src/leveldb/db/version_set.h index c4e7ac360b87..7935a965a7c9 100644 --- a/src/leveldb/db/version_set.h +++ b/src/leveldb/db/version_set.h @@ -376,7 +376,7 @@ class Compaction { // Each compaction reads inputs from "level_" and "level_+1" std::vector inputs_[2]; // The two sets of inputs - // State used to check for number of of overlapping grandparent files + // State used to check for number of overlapping grandparent files // (parent == level_ + 1, grandparent == level_ + 2) std::vector grandparents_; size_t grandparent_index_; // Index in grandparent_starts_ diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index 17ace0cc39ce..67a7a6a945c7 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -419,4 +419,4 @@ CQuorumCPtr CQuorumManager::GetNewestQuorum(Consensus::LLMQType llmqType) return quorums.front(); } -} +} // namespace llmq diff --git a/src/llmq/quorums.h b/src/llmq/quorums.h index 37da0f0d5f11..9f945c088859 100644 --- a/src/llmq/quorums.h +++ b/src/llmq/quorums.h @@ -116,6 +116,6 @@ class CQuorumManager extern CQuorumManager* quorumManager; -} +} // namespace llmq #endif //DASH_QUORUMS_H diff --git a/src/llmq/quorums_blockprocessor.cpp b/src/llmq/quorums_blockprocessor.cpp index fd6b84d2ce5e..bb5a3d88f41d 100644 --- a/src/llmq/quorums_blockprocessor.cpp +++ b/src/llmq/quorums_blockprocessor.cpp @@ -566,4 +566,4 @@ bool CQuorumBlockProcessor::GetMinableCommitmentTx(Consensus::LLMQType llmqType, return true; } -} +} // namespace llmq diff --git a/src/llmq/quorums_blockprocessor.h b/src/llmq/quorums_blockprocessor.h index 937494ea9639..b95207c0d9f8 100644 --- a/src/llmq/quorums_blockprocessor.h +++ b/src/llmq/quorums_blockprocessor.h @@ -66,6 +66,6 @@ class CQuorumBlockProcessor extern CQuorumBlockProcessor* quorumBlockProcessor; -} +} // namespace llmq #endif//DASH_QUORUMS_BLOCKPROCESSOR_H diff --git a/src/llmq/quorums_chainlocks.cpp b/src/llmq/quorums_chainlocks.cpp index bbb106d37a2b..3bd9ecfe817e 100644 --- a/src/llmq/quorums_chainlocks.cpp +++ b/src/llmq/quorums_chainlocks.cpp @@ -724,4 +724,4 @@ void CChainLocksHandler::Cleanup() lastCleanupTime = GetTimeMillis(); } -} +} // namespace llmq diff --git a/src/llmq/quorums_chainlocks.h b/src/llmq/quorums_chainlocks.h index 36308b28e0a0..04c2dd2aee37 100644 --- a/src/llmq/quorums_chainlocks.h +++ b/src/llmq/quorums_chainlocks.h @@ -118,6 +118,6 @@ class CChainLocksHandler : public CRecoveredSigsListener extern CChainLocksHandler* chainLocksHandler; -} +} // namespace llmq #endif //DASH_QUORUMS_CHAINLOCKS_H diff --git a/src/llmq/quorums_commitment.cpp b/src/llmq/quorums_commitment.cpp index fd615c7cf8b7..3e781dcd339d 100644 --- a/src/llmq/quorums_commitment.cpp +++ b/src/llmq/quorums_commitment.cpp @@ -177,4 +177,4 @@ bool CheckLLMQCommitment(const CTransaction& tx, const CBlockIndex* pindexPrev, return true; } -} +} // namespace llmq diff --git a/src/llmq/quorums_commitment.h b/src/llmq/quorums_commitment.h index 15a2a28b0ad1..ca8ce8b1995d 100644 --- a/src/llmq/quorums_commitment.h +++ b/src/llmq/quorums_commitment.h @@ -134,6 +134,6 @@ class CFinalCommitmentTxPayload bool CheckLLMQCommitment(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state); -} +} // namespace llmq #endif //DASH_QUORUMS_COMMITMENT_H diff --git a/src/llmq/quorums_debug.cpp b/src/llmq/quorums_debug.cpp index e9bbcf9249ea..e0710e0931c7 100644 --- a/src/llmq/quorums_debug.cpp +++ b/src/llmq/quorums_debug.cpp @@ -212,4 +212,4 @@ void CDKGDebugManager::UpdateLocalMemberStatus(Consensus::LLMQType llmqType, siz } } -} +} // namespace llmq diff --git a/src/llmq/quorums_debug.h b/src/llmq/quorums_debug.h index e6eaa1ba3689..b26179120a07 100644 --- a/src/llmq/quorums_debug.h +++ b/src/llmq/quorums_debug.h @@ -106,6 +106,6 @@ class CDKGDebugManager extern CDKGDebugManager* quorumDKGDebugManager; -} +} // namespace llmq #endif //DASH_QUORUMS_DEBUG_H diff --git a/src/llmq/quorums_dkgsession.cpp b/src/llmq/quorums_dkgsession.cpp index 03e06b34f8fe..29ba3ff6ee5f 100644 --- a/src/llmq/quorums_dkgsession.cpp +++ b/src/llmq/quorums_dkgsession.cpp @@ -1285,4 +1285,4 @@ void CDKGSession::RelayInvToParticipants(const CInv& inv) const }); } -} +} // namespace llmq diff --git a/src/llmq/quorums_dkgsession.h b/src/llmq/quorums_dkgsession.h index 28b64ff3d29e..045c9e3f1af8 100644 --- a/src/llmq/quorums_dkgsession.h +++ b/src/llmq/quorums_dkgsession.h @@ -342,6 +342,6 @@ class CDKGSession void SetSimulatedDKGErrorRate(const std::string& type, double rate); -} +} // namespace llmq #endif //DASH_QUORUMS_DKGSESSION_H diff --git a/src/llmq/quorums_dkgsessionhandler.cpp b/src/llmq/quorums_dkgsessionhandler.cpp index 932881a06203..c2bf296a2edc 100644 --- a/src/llmq/quorums_dkgsessionhandler.cpp +++ b/src/llmq/quorums_dkgsessionhandler.cpp @@ -560,4 +560,4 @@ void CDKGSessionHandler::PhaseHandlerThread() } } -} +} // namespace llmq diff --git a/src/llmq/quorums_dkgsessionhandler.h b/src/llmq/quorums_dkgsessionhandler.h index 6613d06b324e..7b3be79e9440 100644 --- a/src/llmq/quorums_dkgsessionhandler.h +++ b/src/llmq/quorums_dkgsessionhandler.h @@ -139,6 +139,6 @@ class CDKGSessionHandler void PhaseHandlerThread(); }; -} +} // namespace llmq #endif //DASH_QUORUMS_DKGSESSIONHANDLER_H diff --git a/src/llmq/quorums_dkgsessionmgr.cpp b/src/llmq/quorums_dkgsessionmgr.cpp index 2441e2aaa4f7..d1f5ba69e636 100644 --- a/src/llmq/quorums_dkgsessionmgr.cpp +++ b/src/llmq/quorums_dkgsessionmgr.cpp @@ -274,4 +274,4 @@ void CDKGSessionManager::CleanupCache() } } -} +} // namespace llmq diff --git a/src/llmq/quorums_dkgsessionmgr.h b/src/llmq/quorums_dkgsessionmgr.h index 7c5074dd63a1..17d82e4eef04 100644 --- a/src/llmq/quorums_dkgsessionmgr.h +++ b/src/llmq/quorums_dkgsessionmgr.h @@ -74,6 +74,6 @@ class CDKGSessionManager extern CDKGSessionManager* quorumDKGSessionManager; -} +} // namespace llmq #endif //DASH_QUORUMS_DKGSESSIONMGR_H diff --git a/src/llmq/quorums_init.cpp b/src/llmq/quorums_init.cpp index 394703ad5af9..9bbb71f6cd40 100644 --- a/src/llmq/quorums_init.cpp +++ b/src/llmq/quorums_init.cpp @@ -115,4 +115,4 @@ void InterruptLLMQSystem() } } -} +} // namespace llmq diff --git a/src/llmq/quorums_init.h b/src/llmq/quorums_init.h index 3d094f017f1f..38309b0a13bc 100644 --- a/src/llmq/quorums_init.h +++ b/src/llmq/quorums_init.h @@ -23,6 +23,6 @@ void DestroyLLMQSystem(); void StartLLMQSystem(); void StopLLMQSystem(); void InterruptLLMQSystem(); -} +} // namespace llmq #endif //DASH_QUORUMS_INIT_H diff --git a/src/llmq/quorums_instantsend.cpp b/src/llmq/quorums_instantsend.cpp index 6aee659c11c7..1f12ea257697 100644 --- a/src/llmq/quorums_instantsend.cpp +++ b/src/llmq/quorums_instantsend.cpp @@ -1445,4 +1445,4 @@ bool IsInstantSendEnabled() return sporkManager.IsSporkActive(SPORK_2_INSTANTSEND_ENABLED); } -} +} // namespace llmq diff --git a/src/llmq/quorums_instantsend.h b/src/llmq/quorums_instantsend.h index 0be4e47b6c1e..1a7521c2dd57 100644 --- a/src/llmq/quorums_instantsend.h +++ b/src/llmq/quorums_instantsend.h @@ -172,6 +172,6 @@ extern CInstantSendManager* quorumInstantSendManager; bool IsInstantSendEnabled(); -} +} // namespace llmq #endif//DASH_QUORUMS_INSTANTSEND_H diff --git a/src/llmq/quorums_signing.cpp b/src/llmq/quorums_signing.cpp index 119812030c07..708872f4a67c 100644 --- a/src/llmq/quorums_signing.cpp +++ b/src/llmq/quorums_signing.cpp @@ -861,4 +861,4 @@ bool CSigningManager::VerifyRecoveredSig(Consensus::LLMQType llmqType, int signe return sig.VerifyInsecure(quorum->qc.quorumPublicKey, signHash); } -} +} // namespace llmq diff --git a/src/llmq/quorums_signing.h b/src/llmq/quorums_signing.h index 509a870a6859..0eec5c393490 100644 --- a/src/llmq/quorums_signing.h +++ b/src/llmq/quorums_signing.h @@ -179,6 +179,6 @@ class CSigningManager extern CSigningManager* quorumSigningManager; -} +} // namespace llmq #endif //DASH_QUORUMS_SIGNING_H diff --git a/src/llmq/quorums_signing_shares.cpp b/src/llmq/quorums_signing_shares.cpp index 3d04007e22c7..ff23633a472d 100644 --- a/src/llmq/quorums_signing_shares.cpp +++ b/src/llmq/quorums_signing_shares.cpp @@ -1442,4 +1442,4 @@ void CSigSharesManager::HandleNewRecoveredSig(const llmq::CRecoveredSig& recover RemoveSigSharesForSession(CLLMQUtils::BuildSignHash(recoveredSig)); } -} +} // namespace llmq diff --git a/src/llmq/quorums_signing_shares.h b/src/llmq/quorums_signing_shares.h index 4dc82c7a3374..8f056c679a53 100644 --- a/src/llmq/quorums_signing_shares.h +++ b/src/llmq/quorums_signing_shares.h @@ -424,6 +424,6 @@ class CSigSharesManager : public CRecoveredSigsListener extern CSigSharesManager* quorumSigSharesManager; -} +} // namespace llmq #endif //DASH_QUORUMS_SIGNING_SHARES_H diff --git a/src/llmq/quorums_utils.cpp b/src/llmq/quorums_utils.cpp index 87a85e9e55ae..81908b9049f1 100644 --- a/src/llmq/quorums_utils.cpp +++ b/src/llmq/quorums_utils.cpp @@ -112,4 +112,4 @@ bool CLLMQUtils::IsQuorumActive(Consensus::LLMQType llmqType, const uint256& quo } -} +} // namespace llmq diff --git a/src/llmq/quorums_utils.h b/src/llmq/quorums_utils.h index 7aaf70ad8484..cfbb864b7b10 100644 --- a/src/llmq/quorums_utils.h +++ b/src/llmq/quorums_utils.h @@ -67,6 +67,6 @@ class CLLMQUtils } }; -} +} // namespace llmq #endif//DASH_QUORUMS_UTILS_H diff --git a/src/net.cpp b/src/net.cpp index ee12a26863d8..3b7cbed43063 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -71,6 +71,14 @@ #endif #endif +/** Used to pass flags to the Bind() function */ +enum BindFlags { + BF_NONE = 0, + BF_EXPLICIT = (1U << 0), + BF_REPORT_ERROR = (1U << 1), + BF_WHITELIST = (1U << 2), +}; + const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; constexpr const CConnman::CFullyConnectedOnly CConnman::FullyConnectedOnly; @@ -250,7 +258,7 @@ bool RemoveLocal(const CService& addr) /** Make a particular network entirely off-limits (no automatic connects to it) */ void SetLimited(enum Network net, bool fLimited) { - if (net == NET_UNROUTABLE) + if (net == NET_UNROUTABLE || net == NET_INTERNAL) return; LOCK(cs_mapLocalHost); vfLimited[net] = fLimited; @@ -614,7 +622,6 @@ void CConnman::SetBannedSetDirty(bool dirty) bool CConnman::IsWhitelistedRange(const CNetAddr &addr) { - LOCK(cs_vWhitelistedRange); for (const CSubNet& subnet : vWhitelistedRange) { if (subnet.Match(addr)) return true; @@ -622,12 +629,6 @@ bool CConnman::IsWhitelistedRange(const CNetAddr &addr) { return false; } -void CConnman::AddWhitelistedRange(const CSubNet &subnet) { - LOCK(cs_vWhitelistedRange); - vWhitelistedRange.push_back(subnet); -} - - std::string CNode::GetAddrName() const { LOCK(cs_addrName); return addrName; @@ -1713,7 +1714,12 @@ void CConnman::ThreadDNSAddressSeed() std::vector vIPs; std::vector vAdd; ServiceFlags requiredServiceBits = nRelevantServices; - if (LookupHost(GetDNSHost(seed, &requiredServiceBits).c_str(), vIPs, 0, true)) + std::string host = GetDNSHost(seed, &requiredServiceBits); + CNetAddr resolveSource; + if (!resolveSource.SetInternal(host)) { + continue; + } + if (LookupHost(host.c_str(), vIPs, 0, true)) { for (const CNetAddr& ip : vIPs) { @@ -1723,18 +1729,7 @@ void CConnman::ThreadDNSAddressSeed() vAdd.push_back(addr); found++; } - } - if (interruptNet) { - return; - } - // TODO: The seed name resolve may fail, yielding an IP of [::], which results in - // addrman assigning the same source to results from different seeds. - // This should switch to a hard-coded stable dummy IP for each seed name, so that the - // resolve is not required at all. - if (!vIPs.empty()) { - CService seedSource; - Lookup(seed.name.c_str(), seedSource, 0, true); - addrman.Add(vAdd, seedSource); + addrman.Add(vAdd, resolveSource); } } } @@ -1791,7 +1786,7 @@ void CConnman::ProcessOneShot() void CConnman::ThreadOpenConnections() { // Connect to specific addresses - if (gArgs.IsArgSet("-connect") && gArgs.GetArgs("-connect").size() > 0) + if (gArgs.IsArgSet("-connect")) { for (int64_t nLoop = 0;; nLoop++) { @@ -1833,7 +1828,7 @@ void CConnman::ThreadOpenConnections() if (!done) { LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n"); CNetAddr local; - LookupHost("127.0.0.1", local, false); + local.SetInternal("fixedseeds"); addrman.Add(convertSeed6(Params().FixedSeeds()), local); done = true; } @@ -2027,8 +2022,7 @@ void CConnman::ThreadOpenAddedConnections() { { LOCK(cs_vAddedNodes); - if (gArgs.IsArgSet("-addnode")) - vAddedNodes = gArgs.GetArgs("-addnode"); + vAddedNodes = gArgs.GetArgs("-addnode"); } while (true) @@ -2432,7 +2426,38 @@ NodeId CConnman::GetNewNodeId() return nLastNodeId.fetch_add(1, std::memory_order_relaxed); } -bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options connOptions) + +bool CConnman::Bind(const CService &addr, unsigned int flags) { + if (!(flags & BF_EXPLICIT) && IsLimited(addr)) + return false; + std::string strError; + if (!BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) { + if ((flags & BF_REPORT_ERROR) && clientInterface) { + clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR); + } + return false; + } + return true; +} + +bool CConnman::InitBinds(const std::vector& binds, const std::vector& whiteBinds) { + bool fBound = false; + for (const auto& addrBind : binds) { + fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR)); + } + for (const auto& addrBind : whiteBinds) { + fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST)); + } + if (binds.empty() && whiteBinds.empty()) { + struct in_addr inaddr_any; + inaddr_any.s_addr = INADDR_ANY; + fBound |= Bind(CService((in6_addr)IN6ADDR_ANY_INIT, GetListenPort()), BF_NONE); + fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE); + } + return fBound; +} + +bool CConnman::Start(CScheduler& scheduler, Options connOptions) { nTotalBytesRecv = 0; nTotalBytesSent = 0; @@ -2454,11 +2479,23 @@ bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options c SetBestHeight(connOptions.nBestHeight); + clientInterface = connOptions.uiInterface; + + if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) { + if (clientInterface) { + clientInterface->ThreadSafeMessageBox( + _("Failed to listen on any port. Use -listen=0 if you want this."), + "", CClientUIInterface::MSG_ERROR); + } + return false; + } + + vWhitelistedRange = connOptions.vWhitelistedRange; + for (const auto& strDest : connOptions.vSeedNodes) { AddOneShot(strDest); } - clientInterface = connOptions.uiInterface; if (clientInterface) { clientInterface->InitMessage(_("Loading P2P addresses...")); } diff --git a/src/net.h b/src/net.h index 8d22b6c4a729..9683184c7544 100644 --- a/src/net.h +++ b/src/net.h @@ -168,13 +168,14 @@ class CConnman uint64_t nMaxOutboundTimeframe = 0; uint64_t nMaxOutboundLimit = 0; std::vector vSeedNodes; + std::vector vWhitelistedRange; + std::vector vBinds, vWhiteBinds; }; CConnman(uint64_t seed0, uint64_t seed1); ~CConnman(); - bool Start(CScheduler& scheduler, std::string& strNodeError, Options options); + bool Start(CScheduler& scheduler, Options options); void Stop(); void Interrupt(); - bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); bool GetNetworkActive() const { return fNetworkActive; }; void SetNetworkActive(bool active); bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false, bool fAddnode = false, bool fConnectToMasternode = false); @@ -383,8 +384,6 @@ class CConnman unsigned int GetSendBufferSize() const; - void AddWhitelistedRange(const CSubNet &subnet); - ServiceFlags GetLocalServices() const; //!set the max outbound target in bytes @@ -430,6 +429,9 @@ class CConnman ListenSocket(SOCKET socket_, bool whitelisted_) : socket(socket_), whitelisted(whitelisted_) {} }; + bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); + bool Bind(const CService &addr, unsigned int flags); + bool InitBinds(const std::vector& binds, const std::vector& whiteBinds); void ThreadOpenAddedConnections(); void AddOneShot(const std::string& strDest); void ProcessOneShot(); @@ -488,7 +490,6 @@ class CConnman // Whitelisted ranges. Any node connecting from these is automatically // whitelisted (as well as those connecting to whitelisted binds). std::vector vWhitelistedRange; - CCriticalSection cs_vWhitelistedRange; unsigned int nSendBufferMaxSize; unsigned int nReceiveFloodSize; diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 24c0cd7d4f9d..addf4d2807f9 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -158,7 +158,7 @@ namespace { MapRelay mapRelay; /** Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */ std::deque> vRelayExpiration; -} // anon namespace +} // namespace ////////////////////////////////////////////////////////////////////////////// // @@ -590,7 +590,7 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector6 && strName.substr(strName.size() - 6, 6) == ".onion") { @@ -87,7 +102,7 @@ bool CNetAddr::IsIPv4() const bool CNetAddr::IsIPv6() const { - return (!IsIPv4() && !IsTor()); + return (!IsIPv4() && !IsTor() && !IsInternal()); } bool CNetAddr::IsRFC1918() const @@ -202,6 +217,9 @@ bool CNetAddr::IsValid() const if (IsRFC3849()) return false; + if (IsInternal()) + return false; + if (IsIPv4()) { // INADDR_NONE @@ -224,11 +242,19 @@ bool CNetAddr::IsRoutable() const return false; if (!fAllowPrivateNet && IsRFC1918()) return false; - return !(IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal()); + return !(IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal() || IsInternal()); +} + +bool CNetAddr::IsInternal() const +{ + return memcmp(ip, g_internal_prefix, sizeof(g_internal_prefix)) == 0; } enum Network CNetAddr::GetNetwork() const { + if (IsInternal()) + return NET_INTERNAL; + if (!IsRoutable()) return NET_UNROUTABLE; @@ -245,6 +271,8 @@ std::string CNetAddr::ToStringIP(bool fUseGetnameinfo) const { if (IsTor()) return EncodeBase32(&ip[6], 10) + ".onion"; + if (IsInternal()) + return EncodeBase32(ip + sizeof(g_internal_prefix), sizeof(ip) - sizeof(g_internal_prefix)) + ".internal"; if (fUseGetnameinfo) { CService serv(*this, 0); @@ -315,9 +343,15 @@ std::vector CNetAddr::GetGroup() const nClass = 255; nBits = 0; } - - // all unroutable addresses belong to the same group - if (!IsRoutable()) + // all internal-usage addresses get their own group + if (IsInternal()) + { + nClass = NET_INTERNAL; + nStartByte = sizeof(g_internal_prefix); + nBits = (sizeof(ip) - sizeof(g_internal_prefix)) * 8; + } + // all other unroutable addresses belong to the same group + else if (!IsRoutable()) { nClass = NET_UNROUTABLE; nBits = 0; @@ -403,7 +437,7 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const REACH_PRIVATE }; - if (!IsRoutable()) + if (!IsRoutable() || IsInternal()) return REACH_UNREACHABLE; int ourNet = GetExtNetwork(this); @@ -562,7 +596,7 @@ std::string CService::ToStringPort() const std::string CService::ToStringIPPort(bool fUseGetnameinfo) const { - if (IsIPv4() || IsTor()) { + if (IsIPv4() || IsTor() || IsInternal()) { return ToStringIP(fUseGetnameinfo) + ":" + ToStringPort(); } else { return "[" + ToStringIP(fUseGetnameinfo) + "]:" + ToStringPort(); diff --git a/src/netaddress.h b/src/netaddress.h index 0c6166d7697b..69c1bbf3fbb9 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -24,6 +24,7 @@ enum Network NET_IPV4, NET_IPV6, NET_TOR, + NET_INTERNAL, NET_MAX, }; @@ -47,6 +48,12 @@ class CNetAddr */ void SetRaw(Network network, const uint8_t *data); + /** + * Transform an arbitrary string into a non-routable ipv6 address. + * Useful for mapping resolved addresses back to their source. + */ + bool SetInternal(const std::string& name); + bool SetSpecial(const std::string &strName); // for Tor addresses bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor) @@ -66,6 +73,7 @@ class CNetAddr bool IsTor() const; bool IsLocal() const; bool IsRoutable() const; + bool IsInternal() const; bool IsValid() const; enum Network GetNetwork() const; std::string ToString() const; diff --git a/src/netbase.cpp b/src/netbase.cpp index 175e2b8100ca..a6d2bdc6bf9e 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -108,17 +108,22 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign struct addrinfo *aiTrav = aiRes; while (aiTrav != NULL && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions)) { + CNetAddr resolved; if (aiTrav->ai_family == AF_INET) { assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in)); - vIP.push_back(CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr)); + resolved = CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr); } if (aiTrav->ai_family == AF_INET6) { assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6)); struct sockaddr_in6* s6 = (struct sockaddr_in6*) aiTrav->ai_addr; - vIP.push_back(CNetAddr(s6->sin6_addr, s6->sin6_scope_id)); + resolved = CNetAddr(s6->sin6_addr, s6->sin6_scope_id); + } + /* Never allow resolving to an internal address. Consider any such result invalid */ + if (!resolved.IsInternal()) { + vIP.push_back(resolved); } aiTrav = aiTrav->ai_next; diff --git a/src/protocol.cpp b/src/protocol.cpp index 0e519a4b6a0b..1e19b666bedf 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -72,7 +72,7 @@ const char *QSIGREC="qsigrec"; const char *CLSIG="clsig"; const char *ISLOCK="islock"; const char *MNAUTH="mnauth"; -}; +}; // namespace NetMsgType /** All known message types. Keep this in the same order as the list of * messages above and in protocol.h. diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 91a657593a4a..f8f68af6f831 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -11,7 +11,7 @@ namespace { /* Global secp256k1_context object used for verification. */ secp256k1_context* secp256k1_context_verify = NULL; -} +} // namespace /** This function is taken from the libsecp256k1 distribution and implements * DER parsing for ECDSA signatures, while supporting an arbitrary subset of diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 1836509e13d3..df2a88aaf553 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -32,7 +32,6 @@ class CBlockIndex; -static const int64_t nClientStartupTime = GetTime(); static int64_t nLastHeaderTipUpdateNotification = 0; static int64_t nLastBlockTipUpdateNotification = 0; @@ -275,7 +274,7 @@ bool ClientModel::isReleaseVersion() const QString ClientModel::formatClientStartupTime() const { - return QDateTime::fromTime_t(nClientStartupTime).toString(); + return QDateTime::fromTime_t(GetStartupTime()).toString(); } QString ClientModel::dataDir() const @@ -340,7 +339,7 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB } // if we are in-sync, update the UI regardless of last update time if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) { - //pass a async signal to the UI thread + //pass an async signal to the UI thread QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection, Q_ARG(int, pIndex->nHeight), Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())), diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index b8873d3c6eab..b28275ea050b 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -569,13 +569,10 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) CTxOut txout(nChange, (CScript)std::vector(24, 0)); if (IsDust(txout, ::dustRelayFee)) { - if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust - nChange = GetDustThreshold(txout, ::dustRelayFee); - else - { - nPayFee += nChange; - nChange = 0; - } + nPayFee += nChange; + nChange = 0; + if (CoinControlDialog::fSubtractFeeFromAmount) + nBytes -= 34; // we didn't detect lack of change above } } diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index f0cf50166516..d2b12b9bf44e 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -434,7 +434,7 @@ false - Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type. @@ -457,7 +457,7 @@ false - Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type. @@ -480,7 +480,7 @@ false - Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type. diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index d45320c5b5ab..bb72bdc4ea13 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -129,7 +129,7 @@ void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVeri return; // estimate the number of headers left based on nPowTargetSpacing - // and check if the gui is not aware of the the best header (happens rarely) + // and check if the gui is not aware of the best header (happens rarely) int estimateNumHeadersLeft = bestHeaderDate.secsTo(currentDate) / Params().GetConsensus().nPowTargetSpacing; bool hasBestHeader = bestHeaderHeight >= count; diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index f174c2b04b3e..0a17126766a5 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -702,7 +702,7 @@ void RPCConsole::setFontSize(int newSize) { QSettings settings; - //don't allow a insane font size + //don't allow an insane font size if (newSize < FONT_RANGE.width() || newSize > FONT_RANGE.height()) return; @@ -830,7 +830,7 @@ void RPCConsole::clear(bool clearHistory) tr("Use up and down arrows to navigate history, and %1 to clear screen.").arg(""+clsKey+"") + "
" + tr("Type help for an overview of available commands.")) + "
" + - tr("WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramification of a command.") + + tr("WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command.") + "", true); } diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index ff78b6f04045..723c183bdd5b 100644 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -36,8 +36,6 @@ static const CRPCCommand vRPCCommands[] = void RPCNestedTests::rpcNestedTests() { - UniValue jsonRPCError; - // do some test setup // could be moved to a more generic place when we add more tests on QT level const CChainParams& chainparams = Params(); diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index b3ee9a5d748e..7f2a916cbced 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -65,7 +65,6 @@ QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid) } return {}; } -} //! Simple qt wallet tests. // @@ -80,7 +79,7 @@ QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid) // src/qt/test/test_bitcoin-qt -platform xcb # Linux // src/qt/test/test_bitcoin-qt -platform windows # Windows // src/qt/test/test_bitcoin-qt -platform cocoa # macOS -void WalletTests::walletTests() +void TestSendCoins() { // Set up wallet and chain with 101 blocks (1 mature block for spending). TestChain100Setup test; @@ -117,3 +116,10 @@ void WalletTests::walletTests() bitdb.Flush(true); bitdb.Reset(); } + +} + +void WalletTests::walletTests() +{ + TestSendCoins(); +} diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 4d2ef994ad26..b2ff459a3bc3 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -76,14 +76,7 @@ CAmount WalletModel::getBalance(const CCoinControl *coinControl) const { if (coinControl) { - CAmount nBalance = 0; - std::vector vCoins; - wallet->AvailableCoins(vCoins, true, coinControl); - for (const COutput& out : vCoins) - if(out.fSpendable) - nBalance += out.tx->tx->vout[out.i].nValue; - - return nBalance; + return wallet->GetAvailableBalance(coinControl); } return wallet->GetBalance(); @@ -398,7 +391,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran transaction_array.append(&(ssTx[0]), ssTx.size()); } - // Add addresses / update labels that we've sent to to the address book, + // Add addresses / update labels that we've sent to the address book, // and emit coinsSent signal for each recipient for (const SendCoinsRecipient &rcp : transaction.getRecipients()) { @@ -700,38 +693,11 @@ bool WalletModel::isSpent(const COutPoint& outpoint) const // AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address) void WalletModel::listCoins(std::map >& mapCoins) const { - std::vector vCoins; - wallet->AvailableCoins(vCoins); - - LOCK2(cs_main, wallet->cs_wallet); // ListLockedCoins, mapWallet - std::vector vLockedCoins; - wallet->ListLockedCoins(vLockedCoins); - - // add locked coins - for (const COutPoint& outpoint : vLockedCoins) - { - if (!wallet->mapWallet.count(outpoint.hash)) continue; - int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain(); - if (nDepth < 0) continue; - COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */); - if (outpoint.n < out.tx->tx->vout.size() && wallet->IsMine(out.tx->tx->vout[outpoint.n]) == ISMINE_SPENDABLE) - vCoins.push_back(out); - } - - for (const COutput& out : vCoins) - { - COutput cout = out; - - while (wallet->IsChange(cout.tx->tx->vout[cout.i]) && cout.tx->tx->vin.size() > 0 && wallet->IsMine(cout.tx->tx->vin[0])) - { - if (!wallet->mapWallet.count(cout.tx->tx->vin[0].prevout.hash)) break; - cout = COutput(&wallet->mapWallet[cout.tx->tx->vin[0].prevout.hash], cout.tx->tx->vin[0].prevout.n, 0 /* depth */, true /* spendable */, true /* solvable */, true /* safe */); + for (auto& group : wallet->ListCoins()) { + auto& resultGroup = mapCoins[QString::fromStdString(CBitcoinAddress(group.first).ToString())]; + for (auto& coin : group.second) { + resultGroup.emplace_back(std::move(coin)); } - - CTxDestination address; - if(!out.fSpendable || !ExtractDestination(cout.tx->tx->vout[cout.i].scriptPubKey, address)) - continue; - mapCoins[QString::fromStdString(CBitcoinAddress(address).ToString())].push_back(out); } } @@ -767,11 +733,7 @@ void WalletModel::listProTxCoins(std::vector& vOutpts) void WalletModel::loadReceiveRequests(std::vector& vReceiveRequests) { - LOCK(wallet->cs_wallet); - for (const std::pair& item : wallet->mapAddressBook) - for (const std::pair& item2 : item.second.destdata) - if (item2.first.size() > 2 && item2.first.substr(0,2) == "rr") // receive request - vReceiveRequests.push_back(item2.second); + vReceiveRequests = wallet->GetDestValues("rr"); // receive request } bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest) @@ -791,11 +753,7 @@ bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t bool WalletModel::transactionCanBeAbandoned(uint256 hash) const { - LOCK2(cs_main, wallet->cs_wallet); - const CWalletTx *wtx = wallet->GetWalletTx(hash); - if (!wtx || wtx->isAbandoned() || wtx->GetDepthInMainChain() > 0 || wtx->IsLockedByInstantSend() || wtx->InMempool()) - return false; - return true; + return wallet->TransactionCanBeAbandoned(hash); } bool WalletModel::abandonTransaction(uint256 hash) const diff --git a/src/rest.cpp b/src/rest.cpp index 69220579269d..0c0551cfe691 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -413,7 +413,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) boost::split(uriParts, strUriParams, boost::is_any_of("/")); } - // throw exception in case of a empty request + // throw exception in case of an empty request std::string strRequestMutable = req->ReadBody(); if (strRequestMutable.length() == 0 && uriParts.size() == 0) return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request"); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index f4ef6cebd593..7bdec5bb29e4 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -758,19 +758,16 @@ class submitblock_StateCatcher : public CValidationInterface UniValue submitblock(const JSONRPCRequest& request) { + // We allow 2 arguments for compliance with BIP22. Argument 2 is ignored. if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n" + "submitblock \"hexdata\" ( \"dummy\" )\n" "\nAttempts to submit new block to network.\n" - "The 'jsonparametersobject' parameter is currently ignored.\n" "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n" "\nArguments:\n" "1. \"hexdata\" (string, required) the hex-encoded block data to submit\n" - "2. \"parameters\" (string, optional) object of optional parameters\n" - " {\n" - " \"workid\" : \"id\" (string, optional) if the server provided a workid, it MUST be included with submissions\n" - " }\n" + "2. \"dummy\" (optional) dummy value, for compatibility with BIP22. This value is ignored.\n" "\nResult:\n" "\nExamples:\n" + HelpExampleCli("submitblock", "\"mydata\"") @@ -898,7 +895,7 @@ static const CRPCCommand commands[] = { "mining", "getmininginfo", &getmininginfo, true, {} }, { "mining", "prioritisetransaction", &prioritisetransaction, true, {"txid","fee_delta"} }, { "mining", "getblocktemplate", &getblocktemplate, true, {"template_request"} }, - { "mining", "submitblock", &submitblock, true, {"hexdata","parameters"} }, + { "mining", "submitblock", &submitblock, true, {"hexdata","dummy"} }, #if ENABLE_MINER { "generating", "generate", &generate, true, {"nblocks","maxtries"} }, diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 5396e548c97d..efbcea2c6297 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -76,7 +76,7 @@ UniValue getpeerinfo(const JSONRPCRequest& request) "[\n" " {\n" " \"id\": n, (numeric) Peer index\n" - " \"addr\":\"host:port\", (string) The ip address and port of the peer\n" + " \"addr\":\"host:port\", (string) The IP address and port of the peer\n" " \"addrbind\":\"ip:port\", (string) Bind address of the connection to the peer\n" " \"addrlocal\":\"ip:port\", (string) Local address as reported by the peer\n" " \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n" @@ -200,7 +200,7 @@ UniValue addnode(const JSONRPCRequest& request) (strCommand != "onetry" && strCommand != "add" && strCommand != "remove")) throw std::runtime_error( "addnode \"node\" \"add|remove|onetry\"\n" - "\nAttempts add or remove a node from the addnode list.\n" + "\nAttempts to add or remove a node from the addnode list.\n" "Or try a connection to a node once.\n" "\nArguments:\n" "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n" @@ -291,7 +291,7 @@ UniValue getaddednodeinfo(const JSONRPCRequest& request) "\nResult:\n" "[\n" " {\n" - " \"addednode\" : \"192.168.0.201\", (string) The node ip address or name (as provided to addnode)\n" + " \"addednode\" : \"192.168.0.201\", (string) The node IP address or name (as provided to addnode)\n" " \"connected\" : true|false, (boolean) If connected\n" " \"addresses\" : [ (list of objects) Only when connected = true\n" " {\n" @@ -398,7 +398,7 @@ static UniValue GetNetworksInfo() for(int n=0; n(n); - if(network == NET_UNROUTABLE) + if(network == NET_UNROUTABLE || network == NET_INTERNAL) continue; proxyType proxy; UniValue obj(UniValue::VOBJ); @@ -498,12 +498,12 @@ UniValue setban(const JSONRPCRequest& request) (strCommand != "add" && strCommand != "remove")) throw std::runtime_error( "setban \"subnet\" \"add|remove\" (bantime) (absolute)\n" - "\nAttempts add or remove a IP/Subnet from the banned list.\n" + "\nAttempts to add or remove an IP/Subnet from the banned list.\n" "\nArguments:\n" - "1. \"subnet\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n" - "2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n" - "3. \"bantime\" (numeric, optional) time in seconds how long (or until when if [absolute] is set) the ip is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n" - "4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n" + "1. \"subnet\" (string, required) The IP/Subnet (see getpeerinfo for nodes IP) with an optional netmask (default is /32 = single IP)\n" + "2. \"command\" (string, required) 'add' to add an IP/Subnet to the list, 'remove' to remove an IP/Subnet from the list\n" + "3. \"bantime\" (numeric, optional) time in seconds how long (or until when if [absolute] is set) the IP is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n" + "4. \"absolute\" (boolean, optional) If set, the bantime must be an absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n" "\nExamples:\n" + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400") + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 241c456f344c..b02c4bacb147 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -314,6 +314,22 @@ UniValue stop(const JSONRPCRequest& jsonRequest) return "Dash Core server stopping"; } +UniValue uptime(const JSONRPCRequest& jsonRequest) +{ + if (jsonRequest.fHelp || jsonRequest.params.size() > 1) + throw std::runtime_error( + "uptime\n" + "\nReturns the total uptime of the server.\n" + "\nResult:\n" + "ttt (numeric) The number of seconds that the server has been running\n" + "\nExamples:\n" + + HelpExampleCli("uptime", "") + + HelpExampleRpc("uptime", "") + ); + + return GetTime() - GetStartupTime(); +} + /** * Call Table */ @@ -323,6 +339,7 @@ static const CRPCCommand vRPCCommands[] = /* Overall control/query calls */ { "control", "help", &help, true, {"command"} }, { "control", "stop", &stop, true, {} }, + { "control", "uptime", &uptime, true, {} }, }; CRPCTable::CRPCTable() diff --git a/src/script/dashconsensus.cpp b/src/script/dashconsensus.cpp index 2f274dddad84..d9489201ed11 100644 --- a/src/script/dashconsensus.cpp +++ b/src/script/dashconsensus.cpp @@ -68,7 +68,7 @@ struct ECCryptoClosure }; ECCryptoClosure instance_of_eccryptoclosure; -} +} // namespace /** Check that all specified flags are part of the libconsensus interface. */ static bool verify_flags(unsigned int flags) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index a915776aa908..533915318864 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -31,7 +31,7 @@ inline bool set_error(ScriptError* ret, const ScriptError serror) return false; } -} // anon namespace +} // namespace bool CastToBool(const valtype& vch) { @@ -1141,7 +1141,7 @@ uint256 GetOutputsHash(const CTransaction& txTo) { return ss.GetHash(); } -} // anon namespace +} // namespace PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo) { diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index d61ac2e0a475..bebc9fc192a8 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -66,7 +66,7 @@ class CSignatureCache * signatureCache could be made local to VerifySignature. */ static CSignatureCache signatureCache; -} +} // namespace // To be called once in AppInitMain/BasicTestingSetup to initialize the // signatureCache. diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 9e4424e7c8a9..08b88017cdae 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -288,7 +288,7 @@ class DummySignatureChecker : public BaseSignatureChecker } }; const DummySignatureChecker dummyChecker; -} +} // namespace const BaseSignatureChecker& DummySignatureCreator::Checker() const { diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 470bdb4c6c23..4046f12c3ab9 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -255,7 +255,7 @@ class CScriptVisitor : public boost::static_visitor return true; } }; -} +} // namespace CScript GetScriptForDestination(const CTxDestination& dest) { diff --git a/src/secp256k1/sage/group_prover.sage b/src/secp256k1/sage/group_prover.sage index ab580c5b23bb..5198724bea15 100644 --- a/src/secp256k1/sage/group_prover.sage +++ b/src/secp256k1/sage/group_prover.sage @@ -3,7 +3,7 @@ # to independently set assumptions on input or intermediary variables. # # The general approach is: -# * A constraint is a tuple of two sets of of symbolic expressions: +# * A constraint is a tuple of two sets of symbolic expressions: # the first of which are required to evaluate to zero, the second of which # are required to evaluate to nonzero. # - A constraint is said to be conflicting if any of its nonzero expressions diff --git a/src/secp256k1/src/asm/field_10x26_arm.s b/src/secp256k1/src/asm/field_10x26_arm.s index 5df561f2fc93..bd2b629e1c2e 100644 --- a/src/secp256k1/src/asm/field_10x26_arm.s +++ b/src/secp256k1/src/asm/field_10x26_arm.s @@ -11,7 +11,7 @@ Note: - To avoid unnecessary loads and make use of available registers, two 'passes' have every time been interleaved, with the odd passes accumulating c' and d' - which will be added to c and d respectively in the the even passes + which will be added to c and d respectively in the even passes */ diff --git a/src/support/events.h b/src/support/events.h index 4f2f3cf9ef76..90690876eee0 100644 --- a/src/support/events.h +++ b/src/support/events.h @@ -27,26 +27,26 @@ MAKE_RAII(evhttp); MAKE_RAII(evhttp_request); MAKE_RAII(evhttp_connection); -raii_event_base obtain_event_base() { +inline raii_event_base obtain_event_base() { auto result = raii_event_base(event_base_new()); if (!result.get()) throw std::runtime_error("cannot create event_base"); return result; } -raii_event obtain_event(struct event_base* base, evutil_socket_t s, short events, event_callback_fn cb, void* arg) { +inline raii_event obtain_event(struct event_base* base, evutil_socket_t s, short events, event_callback_fn cb, void* arg) { return raii_event(event_new(base, s, events, cb, arg)); } -raii_evhttp obtain_evhttp(struct event_base* base) { +inline raii_evhttp obtain_evhttp(struct event_base* base) { return raii_evhttp(evhttp_new(base)); } -raii_evhttp_request obtain_evhttp_request(void(*cb)(struct evhttp_request *, void *), void *arg) { +inline raii_evhttp_request obtain_evhttp_request(void(*cb)(struct evhttp_request *, void *), void *arg) { return raii_evhttp_request(evhttp_request_new(cb, arg)); } -raii_evhttp_connection obtain_evhttp_connection_base(struct event_base* base, std::string host, uint16_t port) { +inline raii_evhttp_connection obtain_evhttp_connection_base(struct event_base* base, std::string host, uint16_t port) { auto result = raii_evhttp_connection(evhttp_connection_base_new(base, NULL, host.c_str(), port)); if (!result.get()) throw std::runtime_error("create connection failed"); diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 20cccdc2abc7..4452fb76a316 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -219,7 +219,7 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - // Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each -// element of Aarray and Barray, and then converting the result into a arith_uint256. +// element of Aarray and Barray, and then converting the result into an arith_uint256. #define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 58f77731b4e9..3388405c8b60 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -93,7 +93,7 @@ class CCoinsViewCacheTest : public CCoinsViewCache size_t& usage() { return cachedCoinsUsage; } }; -} +} // namespace BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup) diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index 3631ce3d5d86..ec2afb84c3cc 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -1850,8 +1850,8 @@ "P2SH with CLEANSTACK" ], -["CHECKSEQUENCEVERIFY tests"], -["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"], +["CHECKSEQUENCEVERIFY tests"], +["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on an empty stack"], ["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], ["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], ["0", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index aa0aadeac3d4..06190df3261b 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -174,7 +174,7 @@ [[["5a6b0021a6042a686b6b94abc36b387bef9109847774e8b1e51eb8cc55c53921", 1, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]], "01000000012139c555ccb81ee5b1e87477840991ef7b386bc3ab946b6b682a04a621006b5a01000000fdb40148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f2204148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390175ac4830450220646b72c35beeec51f4d5bc1cbae01863825750d7f490864af354e6ea4f625e9c022100f04b98432df3a9641719dbced53393022e7249fb59db993af1118539830aab870148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a580039017521038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"], -["Finally CHECKMULTISIG removes all signatures prior to hashing the script containing those signatures. In conjunction with the SIGHASH_SINGLE bug this lets us test whether or not FindAndDelete() is actually present in scriptPubKey/redeemScript evaluation by including a signature of the digest 0x01 We can compute in advance for our pubkey, embed it it in the scriptPubKey, and then also using a normal SIGHASH_ALL signature. If FindAndDelete() wasn't run, the 'bugged' signature would still be in the hashed script, and the normal signature would fail."], +["Finally CHECKMULTISIG removes all signatures prior to hashing the script containing those signatures. In conjunction with the SIGHASH_SINGLE bug this lets us test whether or not FindAndDelete() is actually present in scriptPubKey/redeemScript evaluation by including a signature of the digest 0x01 We can compute in advance for our pubkey, embed it in the scriptPubKey, and then also using a normal SIGHASH_ALL signature. If FindAndDelete() wasn't run, the 'bugged' signature would still be in the hashed script, and the normal signature would fail."], ["Here's an example on mainnet within a P2SH redeemScript. Remarkably it's a standard transaction in <0.9"], [[["b5b598de91787439afd5938116654e0b16b7a0d0f82742ba37564219c5afcbf9", 0, "DUP HASH160 0x14 0xf6f365c40f0739b61de827a44751e5e99032ed8f EQUALVERIFY CHECKSIG"], diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index a7ba36819448..d0af22d1ff67 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -26,6 +26,13 @@ static CSubNet ResolveSubNet(const char* subnet) return ret; } +static CNetAddr CreateInternal(const char* host) +{ + CNetAddr addr; + addr.SetInternal(host); + return addr; +} + BOOST_AUTO_TEST_CASE(netbase_networks) { BOOST_CHECK(ResolveIP("127.0.0.1").GetNetwork() == NET_UNROUTABLE); @@ -33,6 +40,7 @@ BOOST_AUTO_TEST_CASE(netbase_networks) BOOST_CHECK(ResolveIP("8.8.8.8").GetNetwork() == NET_IPV4); BOOST_CHECK(ResolveIP("2001::8888").GetNetwork() == NET_IPV6); BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() == NET_TOR); + BOOST_CHECK(CreateInternal("foo.com").GetNetwork() == NET_INTERNAL); } @@ -59,6 +67,8 @@ BOOST_AUTO_TEST_CASE(netbase_properties) BOOST_CHECK(ResolveIP("8.8.8.8").IsRoutable()); BOOST_CHECK(ResolveIP("2001::1").IsRoutable()); BOOST_CHECK(ResolveIP("127.0.0.1").IsValid()); + BOOST_CHECK(CreateInternal("FD6B:88C0:8724:edb1:8e4:3588:e546:35ca").IsInternal()); + BOOST_CHECK(CreateInternal("bar.com").IsInternal()); } @@ -104,6 +114,11 @@ BOOST_AUTO_TEST_CASE(netbase_lookupnumeric) BOOST_CHECK(TestParse("[::]:9999", "[::]:9999")); BOOST_CHECK(TestParse("[127.0.0.1]", "127.0.0.1:65535")); BOOST_CHECK(TestParse(":::", "[::]:0")); + + // verify that an internal address fails to resolve + BOOST_CHECK(TestParse("[fd6b:88c0:8724:1:2:3:4:5]", "[::]:0")); + // and that a one-off resolves correctly + BOOST_CHECK(TestParse("[fd6c:88c0:8724:1:2:3:4:5]", "[fd6c:88c0:8724:1:2:3:4:5]:65535")); } BOOST_AUTO_TEST_CASE(onioncat_test) @@ -282,6 +297,9 @@ BOOST_AUTO_TEST_CASE(netbase_getgroup) BOOST_CHECK(ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == std::vector({(unsigned char)NET_IPV6, 32, 1, 4, 112, 175})); //he.net BOOST_CHECK(ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == std::vector({(unsigned char)NET_IPV6, 32, 1, 32, 1})); //IPv6 + // baz.net sha256 hash: 12929400eb4607c4ac075f087167e75286b179c693eb059a01774b864e8fe505 + std::vector internal_group = {NET_INTERNAL, 0x12, 0x92, 0x94, 0x00, 0xeb, 0x46, 0x07, 0xc4, 0xac, 0x07}; + BOOST_CHECK(CreateInternal("baz.net").GetGroup() == internal_group); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 623dbf0efa20..18282dd6cc13 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -394,7 +394,7 @@ std::string JSONPrettyPrint(const UniValue& univalue) } return ret; } -} +} // namespace BOOST_AUTO_TEST_CASE(script_build) { diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 3f460ae8c71e..0f6e11a2eab3 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -407,7 +407,7 @@ static bool WriteBinaryFile(const fs::path &filename, const std::string &data) /****** Bitcoin specific TorController implementation ********/ /** Controller that connects to Tor control socket, authenticate, then create - * and maintain a ephemeral hidden service. + * and maintain an ephemeral hidden service. */ class TorController { diff --git a/src/txdb.cpp b/src/txdb.cpp index 944cfcaf1cd3..13fe5b9109d6 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -344,7 +344,7 @@ bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) { return true; } -bool CBlockTreeDB::LoadBlockIndexGuts(std::function insertBlockIndex) +bool CBlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function insertBlockIndex) { std::unique_ptr pcursor(NewIterator()); @@ -372,7 +372,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts(std::functionnStatus = diskindex.nStatus; pindexNew->nTx = diskindex.nTx; - if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, Params().GetConsensus())) + if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, consensusParams)) return error("%s: CheckProofOfWork failed: %s", __func__, pindexNew->ToString()); pcursor->Next(); diff --git a/src/txdb.h b/src/txdb.h index de3a00dceb3a..b50b7b2e7073 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -136,7 +136,7 @@ class CBlockTreeDB : public CDBWrapper bool ReadTimestampIndex(const unsigned int &high, const unsigned int &low, std::vector &vect); bool WriteFlag(const std::string &name, bool fValue); bool ReadFlag(const std::string &name, bool &fValue); - bool LoadBlockIndexGuts(std::function insertBlockIndex); + bool LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function insertBlockIndex); }; #endif // BITCOIN_TXDB_H diff --git a/src/txmempool.cpp b/src/txmempool.cpp index e5c8c5664ac3..f166d9c9fd0b 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -123,7 +123,7 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashes // accounted for in the state of their ancestors) std::set setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end()); - // Iterate in reverse, so that whenever we are looking at at a transaction + // Iterate in reverse, so that whenever we are looking at a transaction // we are sure that all in-mempool descendants have already been processed. // This maximizes the benefit of the descendant cache and guarantees that // setMemPoolChildren will be updated, an assumption made in @@ -1162,7 +1162,7 @@ class DepthAndScoreComparator return counta < countb; } }; -} +} // namespace std::vector CTxMemPool::GetSortedDepthAndScore() const { diff --git a/src/util.cpp b/src/util.cpp index 78262772d2a1..5e145301f868 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -92,6 +92,8 @@ #include #include +// Application startup time (used for uptime calculation) +const int64_t nStartupTime = GetTime(); //Dash only features bool fMasternodeMode = false; @@ -514,7 +516,9 @@ void ArgsManager::ParseParameters(int argc, const char* const argv[]) std::vector ArgsManager::GetArgs(const std::string& strArg) { LOCK(cs_args); - return mapMultiArgs.at(strArg); + if (IsArgSet(strArg)) + return mapMultiArgs.at(strArg); + return {}; } bool ArgsManager::IsArgSet(const std::string& strArg) @@ -1099,3 +1103,9 @@ std::string SafeIntVersionToString(uint32_t nVersion) } } + +// Obtain the application startup time (used for uptime calculation) +int64_t GetStartupTime() +{ + return nStartupTime; +} diff --git a/src/util.h b/src/util.h index 034f6205a1c9..0804facb0906 100644 --- a/src/util.h +++ b/src/util.h @@ -6,7 +6,7 @@ /** * Server/client environment: argument handling, config file parsing, - * logging, thread wrappers + * logging, thread wrappers, startup time */ #ifndef BITCOIN_UTIL_H #define BITCOIN_UTIL_H @@ -49,6 +49,9 @@ extern bool fMasternodeMode; extern bool fLiteMode; extern int nWalletBackups; +// Application startup time (used for uptime calculation) +int64_t GetStartupTime(); + static const bool DEFAULT_LOGTIMEMICROS = false; static const bool DEFAULT_LOGIPS = false; static const bool DEFAULT_LOGTIMESTAMPS = true; @@ -175,6 +178,17 @@ std::string SafeStringFormat(const std::string& fmt, const Args&... args) /** Get format string from VA_ARGS for error reporting */ template std::string FormatStringFromLogArgs(const char *fmt, const Args&... args) { return fmt; } +static inline void MarkUsed() {} +template static inline void MarkUsed(const T& t, const Args&... args) +{ + (void)t; + MarkUsed(args...); +} + +#ifdef USE_COVERAGE +#define LogPrintf(...) do { MarkUsed(__VA_ARGS__); } while(0) +#define LogPrint(category, ...) do { MarkUsed(__VA_ARGS__); } while(0) +#else #define LogPrintf(...) do { \ std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \ try { \ @@ -191,6 +205,7 @@ template std::string FormatStringFromLogArgs(const char *fmt, LogPrintf(__VA_ARGS__); \ } \ } while(0) +#endif template bool error(const char* fmt, const Args&... args) diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index bbaecbf5cef9..339f805b794f 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -437,7 +437,7 @@ bool ParseInt32(const std::string& str, int32_t *out) errno = 0; // strtol will not set errno if valid long int n = strtol(str.c_str(), &endp, 10); if(out) *out = (int32_t)n; - // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow + // Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit // platforms the size of these types may be different. return endp && *endp == 0 && !errno && @@ -453,7 +453,7 @@ bool ParseInt64(const std::string& str, int64_t *out) errno = 0; // strtoll will not set errno if valid long long int n = strtoll(str.c_str(), &endp, 10); if(out) *out = (int64_t)n; - // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow + // Note that strtoll returns a *long long int*, so even if strtol doesn't report an over/underflow // we still have to check that the returned value is within the range of an *int64_t*. return endp && *endp == 0 && !errno && n >= std::numeric_limits::min() && @@ -470,7 +470,7 @@ bool ParseUInt32(const std::string& str, uint32_t *out) errno = 0; // strtoul will not set errno if valid unsigned long int n = strtoul(str.c_str(), &endp, 10); if(out) *out = (uint32_t)n; - // Note that strtoul returns a *unsigned long int*, so even if it doesn't report a over/underflow + // Note that strtoul returns a *unsigned long int*, so even if it doesn't report an over/underflow // we still have to check that the returned value is within the range of an *uint32_t*. On 64-bit // platforms the size of these types may be different. return endp && *endp == 0 && !errno && @@ -487,7 +487,7 @@ bool ParseUInt64(const std::string& str, uint64_t *out) errno = 0; // strtoull will not set errno if valid unsigned long long int n = strtoull(str.c_str(), &endp, 10); if(out) *out = (uint64_t)n; - // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report a over/underflow + // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report an over/underflow // we still have to check that the returned value is within the range of an *uint64_t*. return endp && *endp == 0 && !errno && n <= std::numeric_limits::max(); diff --git a/src/validation.cpp b/src/validation.cpp index 6f96fb56894e..b3ccadc4b1a5 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1488,7 +1488,7 @@ static bool CheckInputs(const CTransaction& tx, CValidationState &state, const C return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } // Failures of other flags indicate a transaction that is - // invalid in new blocks, e.g. a invalid P2SH. We DoS ban + // invalid in new blocks, e.g. an invalid P2SH. We DoS ban // such nodes as they are not following the protocol. That // said during an upgrade careful thought should be taken // as to the correct behavior - we may want to continue @@ -1576,7 +1576,7 @@ bool AbortNode(CValidationState& state, const std::string& strMessage, const std return state.Error(strMessage); } -} // anon namespace +} // namespace enum DisconnectResult { @@ -3922,7 +3922,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash) bool static LoadBlockIndexDB(const CChainParams& chainparams) { - if (!pblocktree->LoadBlockIndexGuts(InsertBlockIndex)) + if (!pblocktree->LoadBlockIndexGuts(chainparams.GetConsensus(), InsertBlockIndex)) return false; boost::this_thread::interruption_point(); diff --git a/src/validationinterface.h b/src/validationinterface.h index 8d2df801c1d5..c65f6c9d753e 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -27,7 +27,7 @@ class uint256; namespace llmq { class CChainLockSig; class CInstantSendLock; -} +} // namespace llmq // These functions dispatch to one or all registered wallets diff --git a/src/versionbits.cpp b/src/versionbits.cpp index e1d6ae47d708..d00357a9331d 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -207,7 +207,7 @@ class VersionBitsConditionChecker : public AbstractThresholdConditionChecker { uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; } }; -} +} // namespace ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache) { diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 1f54d7430444..83279e2e2438 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -337,7 +337,6 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co // Check for watch-only pubkeys return CBasicKeyStore::GetPubKey(address, vchPubKeyOut); } - return false; } bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 05af581dc032..fe72bfe93de9 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -149,7 +149,7 @@ UniValue importprivkey(const JSONRPCRequest& request) pwallet->UpdateTimeFirstKey(1); if (fRescan) { - pwallet->ScanForWalletTransactions(chainActive.Genesis(), true); + pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */); } } @@ -279,7 +279,7 @@ UniValue importaddress(const JSONRPCRequest& request) if (fRescan) { - pwallet->ScanForWalletTransactions(chainActive.Genesis(), true); + pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */); pwallet->ReacceptWalletTransactions(); } @@ -437,7 +437,7 @@ UniValue importpubkey(const JSONRPCRequest& request) if (fRescan) { - pwallet->ScanForWalletTransactions(chainActive.Genesis(), true); + pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */); pwallet->ReacceptWalletTransactions(); } @@ -538,10 +538,7 @@ UniValue importwallet(const JSONRPCRequest& request) pwallet->ShowProgress("", 100); // hide progress dialog in GUI pwallet->UpdateTimeFirstKey(nTimeBegin); - CBlockIndex* pindex = chainActive.FindEarliestAtLeast(nTimeBegin - TIMESTAMP_WINDOW); - - LogPrintf("Rescanning last %i blocks\n", pindex ? chainActive.Height() - pindex->nHeight + 1 : 0); - pwallet->ScanForWalletTransactions(pindex); + pwallet->RescanFromTime(nTimeBegin, false /* update */); pwallet->MarkDirty(); if (!fGood) @@ -1255,7 +1252,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) " \"redeemscript\": \"