diff --git a/.appveyor.yml b/.appveyor.yml index ed2ab4955..dacfba658 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,31 +1,57 @@ version: '{branch}.{build}' skip_tags: true -image: Visual Studio 2017 +image: Visual Studio 2019 configuration: Release platform: x64 clone_depth: 5 environment: APPVEYOR_SAVE_CACHE_ON_ERROR: true CLCACHE_SERVER: 1 - PACKAGES: berkeleydb boost-filesystem boost-signals2 boost-test libevent openssl rapidcheck zeromq double-conversion PATH: 'C:\Python37-x64;C:\Python37-x64\Scripts;%PATH%' PYTHONUTF8: 1 - QT_DOWNLOAD_URL: 'https://github.com/sipsorcery/qt_win_binary/releases/download/v1.0/Qt5.9.7_ssl_x64_static_vs2017.zip' - QT_DOWNLOAD_HASH: 'D4D35B8112302B67E5610A03421BB3E43FE13F14D9A5F637C22AE60DCEC0E0F5' - QT_LOCAL_PATH: 'C:\Qt5.9.7_ssl_x64_static_vs2017' + QT_DOWNLOAD_URL: 'https://github.com/sipsorcery/qt_win_binary/releases/download/v1.6/Qt5.9.8_x64_static_vs2019.zip' + QT_DOWNLOAD_HASH: '9a8c6eb20967873785057fdcd329a657c7f922b0af08c5fde105cc597dd37e21' + QT_LOCAL_PATH: 'C:\Qt5.9.8_x64_static_vs2019' + VCPKG_INSTALL_PATH: 'C:\tools\vcpkg\installed' cache: -- C:\tools\vcpkg\installed +- C:\tools\vcpkg\installed -> build_msvc\vcpkg-packages.txt - C:\Users\appveyor\clcache -> .appveyor.yml, build_msvc\**, **\Makefile.am, **\*.vcxproj.in -- C:\Qt5.9.7_ssl_x64_static_vs2017 +- C:\Qt5.9.8_x64_static_vs2019 install: - cmd: pip install --quiet git+https://github.com/frerich/clcache.git@v4.2.0 # Disable zmq test for now since python zmq library on Windows would cause Access violation sometimes. # - cmd: pip install zmq -- cmd: echo set(VCPKG_BUILD_TYPE release) >> C:\tools\vcpkg\triplets\%PLATFORM%-windows-static.cmake -- cmd: vcpkg remove --outdated --recurse -- cmd: vcpkg install --triplet %PLATFORM%-windows-static %PACKAGES% > NUL +# Powershell block below is to install the c++ dependencies via vcpkg. The pseudo code is: +# 1. Check whether the vcpkg install directory exists (note that updating the vcpkg-packages.txt file +# will cause the appveyor cache rules to invalidate the directory) +# 2. If the directory is missing: +# a. Update the vcpkg source (including port files) and build the vcpkg binary, +# b. Install the missing packages. +- ps: | + $env:PACKAGES = Get-Content -Path build_msvc\vcpkg-packages.txt + Write-Host "vcpkg list: $env:PACKAGES" + if(!(Test-Path -Path ($env:VCPKG_INSTALL_PATH))) { + cd c:\tools\vcpkg + $env:GIT_REDIRECT_STDERR = '2>&1' # git is writing non-errors to STDERR when doing git pull. Send to STDOUT instead. + git pull origin master + .\bootstrap-vcpkg.bat + Add-Content "C:\tools\vcpkg\triplets\$env:PLATFORM-windows-static.cmake" "set(VCPKG_BUILD_TYPE release)" + .\vcpkg install --triplet $env:PLATFORM-windows-static $env:PACKAGES.split() > $null + cd "$env:APPVEYOR_BUILD_FOLDER" + } + else { + Write-Host "required vcpkg packages already installed." + } + c:\tools\vcpkg\vcpkg integrate install before_build: - ps: clcache -M 536870912 +# Powershell block below is to download and extract the Qt static libraries. The pseudo code is: +# 1. If the Qt destination directory exists assume it is correct and do nothing. To +# force a fresh install of the packages delete the job's appveyor cache. +# 2. Otherwise: +# a. Download the zip file with the prebuilt Qt static libraries. +# b. Check that the downloaded file matches the expected hash. +# c. Extract the zip file to the specific destination path expected by the msbuild projects. - ps: | if(!(Test-Path -Path ($env:QT_LOCAL_PATH))) { Write-Host "Downloading Qt binaries."; @@ -44,17 +70,10 @@ before_build: Write-Host "Qt binaries already present."; } - cmd: python build_msvc\msvc-autogen.py -- ps: $files = (Get-ChildItem -Recurse | where {$_.extension -eq ".vcxproj"}).FullName -- ps: for (${i} = 0; ${i} -lt ${files}.length; ${i}++) { - ${content} = (Get-Content ${files}[${i}]); - ${content} = ${content}.Replace("", "None"); - ${content} = ${content}.Replace("true", "false"); - Set-Content ${files}[${i}] ${content}; - } - ps: Start-Process clcache-server - ps: fsutil behavior set disablelastaccess 0 # Enable Access time feature on Windows (for clcache) build_script: -- cmd: msbuild /p:TrackFileAccess=false /p:CLToolExe=clcache.exe build_msvc\bitcoin.sln /m /v:n /nologo +- cmd: msbuild /p:TrackFileAccess=false /p:CLToolExe=clcache.exe build_msvc\bitcoin.sln /m /v:q /nologo after_build: - ps: fsutil behavior set disablelastaccess 1 # Disable Access time feature on Windows (better performance) - ps: clcache -z @@ -64,7 +83,8 @@ test_script: - cmd: src\bench_bitcoin.exe -evals=1 -scaling=0 > NUL - ps: python test\util\bitcoin-util-test.py - cmd: python test\util\rpcauth-test.py -- cmd: python test\functional\test_runner.py --ci --quiet --combinedlogslen=4000 --failfast +# Fee estimation test failing on appveyor with: WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted. +- cmd: python test\functional\test_runner.py --ci --quiet --combinedlogslen=4000 --failfast --exclude feature_fee_estimation artifacts: #- path: bitcoin-%APPVEYOR_BUILD_VERSION%.zip deploy: off diff --git a/build_msvc/README.md b/build_msvc/README.md index 88b1f514b..6c3ab6f6b 100644 --- a/build_msvc/README.md +++ b/build_msvc/README.md @@ -56,11 +56,12 @@ Building --------------------- The instructions below use `vcpkg` to install the dependencies. -- Clone `vcpkg` from the [github repository](https://github.com/Microsoft/vcpkg) and install as per the instructions in the main README.md. -- Install the required packages (replace x64 with x86 as required): +- Install [`vcpkg`](https://github.com/Microsoft/vcpkg). +- Install the required packages (replace x64 with x86 as required). The list of required packages can be found in the `build_msvc\vcpkg-packages.txt` file. The PowerShell command below will work if run from the repository root directory and `vcpkg` is in the path. Alternatively the contents of the packages text file can be pasted in place of the `Get-Content` cmdlet. ``` - PS >.\vcpkg install --triplet x64-windows-static boost-filesystem boost-signals2 boost-test libevent openssl zeromq berkeleydb rapidcheck double-conversion +PS >.\vcpkg install --triplet x64-windows-static $(Get-Content -Path build_msvc\vcpkg-packages.txt).split() + ``` - Use Python to generate *.vcxproj from Makefile @@ -74,13 +75,13 @@ The instructions below use `vcpkg` to install the dependencies. - Build with Visual Studio 2017 or msbuild. ``` -msbuild /m bitcoin.sln /p:Platform=x64 /p:Configuration=Release /t:build +msbuild /m bitcoin.sln /p:Platform=x64 /p:Configuration=Release /p:PlatformToolset=v141 /t:build ``` - Build with Visual Studio 2019 or msbuild. ``` -msbuild /m bitcoin.sln /p:Platform=x64 /p:Configuration=Release /p:PlatformToolset=v142 /t:build +msbuild /m bitcoin.sln /p:Platform=x64 /p:Configuration=Release /t:build ``` AppVeyor diff --git a/build_msvc/bitcoin-qt/bitcoin-qt.vcxproj b/build_msvc/bitcoin-qt/bitcoin-qt.vcxproj index fdeec55ee..dcfc1e1b3 100644 --- a/build_msvc/bitcoin-qt/bitcoin-qt.vcxproj +++ b/build_msvc/bitcoin-qt/bitcoin-qt.vcxproj @@ -56,6 +56,7 @@ $(QtReleaseLibraries);%(AdditionalDependencies) + /ignore:4206 ..\..\src; @@ -69,6 +70,7 @@ $(QtDebugLibraries);%(AdditionalDependencies) + /ignore:4206 ..\..\src; diff --git a/build_msvc/common.init.vcxproj b/build_msvc/common.init.vcxproj index 77f6a5c62..583cd9f88 100644 --- a/build_msvc/common.init.vcxproj +++ b/build_msvc/common.init.vcxproj @@ -39,7 +39,7 @@ true false true - v141 + v142 Unicode $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ $(Platform)\$(Configuration)\$(ProjectName)\ @@ -48,7 +48,7 @@ false true false - v141 + v142 Unicode $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ $(Platform)\$(Configuration)\$(ProjectName)\ @@ -107,7 +107,7 @@ Level3 NotUsing /utf-8 %(AdditionalOptions) - 4018;4221;4244;4267;4334;4715;4805; + 4018;4221;4244;4267;4334;4715;4805;4834 true ZMQ_STATIC;NOMINMAX;WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CONSOLE;_WIN32_WINNT=0x0601;%(PreprocessorDefinitions) ..\..\src;..\..\src\univalue\include;..\..\src\secp256k1\include;..\..\src\leveldb\include;..\..\src\leveldb\helpers\memenv;%(AdditionalIncludeDirectories) diff --git a/build_msvc/common.qt.init.vcxproj b/build_msvc/common.qt.init.vcxproj index e21288e26..42150a231 100644 --- a/build_msvc/common.qt.init.vcxproj +++ b/build_msvc/common.qt.init.vcxproj @@ -2,7 +2,7 @@ - C:\Qt5.9.7_ssl_x64_static_vs2017 + C:\Qt5.9.8_x64_static_vs2019 $(QtBaseDir)\plugins $(QtBaseDir)\lib $(QtBaseDir)\include diff --git a/build_msvc/test_bitcoin/test_bitcoin.vcxproj b/build_msvc/test_bitcoin/test_bitcoin.vcxproj index 47e87b59e..ad3110422 100644 --- a/build_msvc/test_bitcoin/test_bitcoin.vcxproj +++ b/build_msvc/test_bitcoin/test_bitcoin.vcxproj @@ -16,6 +16,7 @@ + diff --git a/build_msvc/vcpkg-packages.txt b/build_msvc/vcpkg-packages.txt new file mode 100644 index 000000000..082a13f1c --- /dev/null +++ b/build_msvc/vcpkg-packages.txt @@ -0,0 +1 @@ +berkeleydb boost-filesystem boost-multi-index boost-signals2 boost-test boost-thread libevent openssl rapidcheck zeromq double-conversion \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 1ef62a656..947edc698 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -686,13 +686,13 @@ clean-local: check-symbols: $(bin_PROGRAMS) if GLIBC_BACK_COMPAT @echo "Checking glibc back compat..." - $(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py < $(bin_PROGRAMS) + $(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS) endif check-security: $(bin_PROGRAMS) if HARDEN @echo "Checking binary security..." - $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS) + $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS) endif if ENABLE_BIP70 diff --git a/src/blockfilter.cpp b/src/blockfilter.cpp index 787390be3..5ad22d46e 100644 --- a/src/blockfilter.cpp +++ b/src/blockfilter.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -221,15 +222,14 @@ bool BlockFilterTypeByName(const std::string& name, BlockFilterType& filter_type return false; } -const std::vector& AllBlockFilterTypes() +const std::set& AllBlockFilterTypes() { - static std::vector types; + static std::set types; static std::once_flag flag; std::call_once(flag, []() { - types.reserve(g_filter_types.size()); for (auto entry : g_filter_types) { - types.push_back(entry.first); + types.insert(entry.first); } }); diff --git a/src/blockfilter.h b/src/blockfilter.h index 914b94fec..828204b87 100644 --- a/src/blockfilter.h +++ b/src/blockfilter.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -97,7 +98,7 @@ const std::string& BlockFilterTypeName(BlockFilterType filter_type); bool BlockFilterTypeByName(const std::string& name, BlockFilterType& filter_type); /** Get a list of known filter types. */ -const std::vector& AllBlockFilterTypes(); +const std::set& AllBlockFilterTypes(); /** Get a comma-separated list of known filter type names. */ const std::string& ListBlockFilterTypes(); diff --git a/src/fs.h b/src/fs.h index c713297d6..8af81f173 100644 --- a/src/fs.h +++ b/src/fs.h @@ -11,7 +11,6 @@ #include #endif -#define BOOST_FILESYSTEM_NO_DEPRECATED #include #include diff --git a/src/init.cpp b/src/init.cpp index 8c0d59943..543194c2e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -57,6 +57,7 @@ #include #include +#include #ifndef WIN32 #include @@ -865,7 +866,7 @@ int nUserMaxConnections; int nFD; ServiceFlags nLocalServices = ServiceFlags(NODE_NETWORK | NODE_NETWORK_LIMITED); int64_t peer_connect_timeout; -std::vector g_enabled_filter_types; +std::set g_enabled_filter_types; } // namespace @@ -953,13 +954,12 @@ bool AppInitParameterInteraction() g_enabled_filter_types = AllBlockFilterTypes(); } else if (blockfilterindex_value != "0") { const std::vector names = gArgs.GetArgs("-blockfilterindex"); - g_enabled_filter_types.reserve(names.size()); for (const auto& name : names) { BlockFilterType filter_type; if (!BlockFilterTypeByName(name, filter_type)) { return InitError(strprintf(_("Unknown -blockfilterindex value %s.").translated, name)); } - g_enabled_filter_types.push_back(filter_type); + g_enabled_filter_types.insert(filter_type); } } diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 34d349e8e..3d0efa041 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -30,6 +30,7 @@ #include #include +#include #if defined(NDEBUG) # error "Bitcoin cannot be compiled without assertions." @@ -3363,35 +3364,10 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic& inter return false; if (!pfrom->vRecvGetData.empty()) fMoreWork = true; - } - catch (const std::ios_base::failure& e) - { - if (m_enable_bip61) { - connman->PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, strCommand, REJECT_MALFORMED, std::string("error parsing message"))); - } - if (strstr(e.what(), "end of data")) { - // Allow exceptions from under-length message on vRecv - LogPrint(BCLog::NET, "%s(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", __func__, SanitizeString(strCommand), nMessageSize, e.what()); - } else if (strstr(e.what(), "size too large")) { - // Allow exceptions from over-long size - LogPrint(BCLog::NET, "%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what()); - } else if (strstr(e.what(), "non-canonical ReadCompactSize()")) { - // Allow exceptions from non-canonical encoding - LogPrint(BCLog::NET, "%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what()); - } else if (strstr(e.what(), "Superfluous witness record")) { - // Allow exceptions from illegal witness encoding - LogPrint(BCLog::NET, "%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what()); - } else if (strstr(e.what(), "Unknown transaction optional data")) { - // Allow exceptions from unknown witness encoding - LogPrint(BCLog::NET, "%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what()); - } else { - PrintExceptionContinue(&e, "ProcessMessages()"); - } - } - catch (const std::exception& e) { - PrintExceptionContinue(&e, "ProcessMessages()"); + } catch (const std::exception& e) { + LogPrint(BCLog::NET, "%s(%s, %u bytes): Exception '%s' (%s) caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what(), typeid(e).name()); } catch (...) { - PrintExceptionContinue(nullptr, "ProcessMessages()"); + LogPrint(BCLog::NET, "%s(%s, %u bytes): Unknown exception caught\n", __func__, SanitizeString(strCommand), nMessageSize); } if (!fRet) { diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 7671fde70..e269c91d1 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -341,6 +341,7 @@ void BitcoinGUI::createActions() m_close_wallet_action->setStatusTip(tr("Close wallet")); m_create_wallet_action = new QAction(tr("Create Wallet..."), this); + m_create_wallet_action->setEnabled(false); m_create_wallet_action->setStatusTip(tr("Create a new wallet")); showHelpMessageAction = new QAction(tr("&Command-line options"), this); @@ -617,6 +618,7 @@ void BitcoinGUI::setWalletController(WalletController* wallet_controller) m_wallet_controller = wallet_controller; + m_create_wallet_action->setEnabled(true); m_open_wallet_action->setEnabled(true); m_open_wallet_action->setMenu(m_open_wallet_menu); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 02717fa80..ad5be71e2 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2049,7 +2049,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) " \"start\" for starting a scan\n" " \"abort\" for aborting the current scan (returns true when abort was successful)\n" " \"status\" for progress report (in %) of the current scan"}, - {"scanobjects", RPCArg::Type::ARR, RPCArg::Optional::NO, "Array of scan objects\n" + {"scanobjects", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Array of scan objects. Required for \"start\" action\n" " Every scan object is either a string descriptor or an object:", { {"descriptor", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"}, @@ -2109,6 +2109,11 @@ UniValue scantxoutset(const JSONRPCRequest& request) if (!reserver.reserve()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan already in progress, use action \"abort\" or \"status\""); } + + if (request.params.size() < 2) { + throw JSONRPCError(RPC_MISC_ERROR, "scanobjects argument is required for the start action"); + } + std::set needles; std::map descriptors; CAmount total_in = 0; diff --git a/src/util/fees.cpp b/src/util/fees.cpp index cf16d5e44..41149888d 100644 --- a/src/util/fees.cpp +++ b/src/util/fees.cpp @@ -3,8 +3,11 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include + #include +#include #include std::string StringForFeeReason(FeeReason reason) { diff --git a/src/util/system.cpp b/src/util/system.cpp index 382000607..bbd7c9940 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -64,6 +64,7 @@ #endif #include +#include // Application startup time (used for uptime calculation) const int64_t nStartupTime = GetTime(); diff --git a/test/functional/rpc_scantxoutset.py b/test/functional/rpc_scantxoutset.py index 9f94d11a9..f31e4f43b 100755 --- a/test/functional/rpc_scantxoutset.py +++ b/test/functional/rpc_scantxoutset.py @@ -116,5 +116,12 @@ class ScantxoutsetTest(BitcoinTestFramework): assert_equal(descriptors(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0)"])), ["pkh([0c5f9a1e/1/1/0]03e1c5b6e650966971d7e71ef2674f80222752740fc1dfd63bbbd220d2da9bd0fb)#cxmct4w8"]) assert_equal(descriptors(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*)", "range": 1500}])), ['pkh([0c5f9a1e/1/1/0]03e1c5b6e650966971d7e71ef2674f80222752740fc1dfd63bbbd220d2da9bd0fb)#cxmct4w8', 'pkh([0c5f9a1e/1/1/1500]03832901c250025da2aebae2bfb38d5c703a57ab66ad477f9c578bfbcd78abca6f)#vchwd07g', 'pkh([0c5f9a1e/1/1/1]030d820fc9e8211c4169be8530efbc632775d8286167afd178caaf1089b77daba7)#z2t3ypsa']) + # Check that status and abort don't need second arg + assert_equal(self.nodes[0].scantxoutset("status"), None) + assert_equal(self.nodes[0].scantxoutset("abort"), False) + + # Check that second arg is needed for start + assert_raises_rpc_error(-1, "scanobjects argument is required for the start action", self.nodes[0].scantxoutset, "start") + if __name__ == '__main__': ScantxoutsetTest().main() diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 9c92091f1..2f8279bc2 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -361,9 +361,10 @@ def main(): def run_tests(*, test_list, src_dir, build_dir, tmpdir, jobs=1, enable_coverage=False, args=None, combined_logs_len=0, failfast=False, runs_ci, use_term_control): args = args or [] - # Warn if bitcoind is already running (unix only) + # Warn if bitcoind is already running + # pidof might fail or return an empty string if bitcoind is not running try: - if subprocess.check_output(["pidof", "bitcoind"]) is not None: + if subprocess.check_output(["pidof", "bitcoind"]) not in [b'']: print("%sWARNING!%s There is already a bitcoind process running on this system. Tests may fail unexpectedly due to resource contention!" % (BOLD[1], BOLD[0])) except (OSError, subprocess.SubprocessError): pass