From 07aae4d261cc031561e74452110b8dcf1429a0ec Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 13 Mar 2023 17:32:05 -0400 Subject: [PATCH 001/391] [RPC] Fix `getinfo` crash with -disablewallet --- src/rpc/misc.cpp | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 1608c5322d..b489948797 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -103,28 +103,32 @@ UniValue getinfo(const UniValue ¶ms, bool fHelp) { obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); #endif obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); - bool nStaking = false; - if (mapHashedBlocks.count(chainActive.Tip()->nHeight)) - nStaking = true; - else if (mapHashedBlocks.count(chainActive.Tip()->nHeight - 1) && nLastCoinStakeSearchInterval) - nStaking = true; - if (pwalletMain->IsLocked()) { - obj.push_back(Pair("staking mode", ("disabled"))); - obj.push_back(Pair("staking status", ("inactive (wallet locked)"))); - } else { - obj.push_back(Pair("staking mode", (pwalletMain->ReadStakingStatus() ? "enabled" : "disabled"))); - if (vNodes.empty()) { - obj.push_back(Pair("staking status", ("inactive (no peer connections)"))); - } else if (!masternodeSync.IsSynced()) { - obj.push_back(Pair("staking status", ("inactive (syncing masternode list)"))); - } else if (!pwalletMain->MintableCoins() && pwalletMain->combineMode == CombineMode::ON) { - obj.push_back(Pair("staking status", ("delayed (waiting for 100 blocks)"))); - } else if (!pwalletMain->MintableCoins()) { - obj.push_back(Pair("staking status", ("inactive (no mintable coins)"))); +#ifdef ENABLE_WALLET + if (pwalletMain) { + bool nStaking = false; + if (mapHashedBlocks.count(chainActive.Tip()->nHeight)) + nStaking = true; + else if (mapHashedBlocks.count(chainActive.Tip()->nHeight - 1) && nLastCoinStakeSearchInterval) + nStaking = true; + if (pwalletMain->IsLocked()) { + obj.push_back(Pair("staking mode", ("disabled"))); + obj.push_back(Pair("staking status", ("inactive (wallet locked)"))); } else { - obj.push_back(Pair("staking status", (nStaking ? "active (attempting to mint a block)" : "idle (waiting for next round)"))); + obj.push_back(Pair("staking mode", (pwalletMain->ReadStakingStatus() ? "enabled" : "disabled"))); + if (vNodes.empty()) { + obj.push_back(Pair("staking status", ("inactive (no peer connections)"))); + } else if (!masternodeSync.IsSynced()) { + obj.push_back(Pair("staking status", ("inactive (syncing masternode list)"))); + } else if (!pwalletMain->MintableCoins() && pwalletMain->combineMode == CombineMode::ON) { + obj.push_back(Pair("staking status", ("delayed (waiting for 100 blocks)"))); + } else if (!pwalletMain->MintableCoins()) { + obj.push_back(Pair("staking status", ("inactive (no mintable coins)"))); + } else { + obj.push_back(Pair("staking status", (nStaking ? "active (attempting to mint a block)" : "idle (waiting for next round)"))); + } } } +#endif obj.push_back(Pair("errors", GetWarnings("statusbar"))); return obj; } From 2d42bce32fccaeebedef3e50a360a51d11c26100 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 17 Mar 2023 10:51:15 -0400 Subject: [PATCH 002/391] build: remove protobuf from depends --- depends/config.site.in | 3 --- depends/packages/native_protobuf.mk | 25 --------------------- depends/packages/packages.mk | 5 +---- depends/packages/protobuf.mk | 34 ----------------------------- 4 files changed, 1 insertion(+), 66 deletions(-) delete mode 100644 depends/packages/native_protobuf.mk delete mode 100644 depends/packages/protobuf.mk diff --git a/depends/config.site.in b/depends/config.site.in index 9842a672e6..fb9bf713cc 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -16,9 +16,6 @@ fi if test -z $with_qt_bindir && test -z "@no_qt@"; then with_qt_bindir=$depends_prefix/native/bin fi -if test -z $with_protoc_bindir && test -z "@no_qt@"; then - with_protoc_bindir=$depends_prefix/native/bin -fi if test -z $with_qrencode && test -n "@no_qr@"; then with_qrencode=no diff --git a/depends/packages/native_protobuf.mk b/depends/packages/native_protobuf.mk deleted file mode 100644 index 1de8c37d36..0000000000 --- a/depends/packages/native_protobuf.mk +++ /dev/null @@ -1,25 +0,0 @@ -package=native_protobuf -$(package)_version=2.6.1 -$(package)_download_path=https://github.com/google/protobuf/releases/download/v$($(package)_version) -$(package)_file_name=protobuf-$($(package)_version).tar.bz2 -$(package)_sha256_hash=ee445612d544d885ae240ffbcbf9267faa9f593b7b101f21d58beceb92661910 - -define $(package)_set_vars -$(package)_config_opts=--disable-shared --without-zlib -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C src protoc -endef - -define $(package)_stage_cmds - $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install-strip -endef - -define $(package)_postprocess_cmds - rm -rf lib include -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 5a7e426748..0ecc090e83 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,9 +1,6 @@ packages:=boost openssl libevent -qt_native_packages = native_protobuf -qt_packages = protobuf zlib - -qrencode_packages = qrencode +qt_packages = qrencode zlib qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk deleted file mode 100644 index 4bd9447c67..0000000000 --- a/depends/packages/protobuf.mk +++ /dev/null @@ -1,34 +0,0 @@ -package=protobuf -$(package)_version=$(native_$(package)_version) -$(package)_download_path=$(native_$(package)_download_path) -$(package)_file_name=$(native_$(package)_file_name) -$(package)_sha256_hash=$(native_$(package)_sha256_hash) -$(package)_dependencies=native_$(package) -$(package)_cxxflags=-std=c++17 - -define $(package)_set_vars - $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc - $(package)_config_opts_linux=--with-pic -endef - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . &&\ - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub gtest/build-aux -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C src libprotobuf.la -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) -C src install-libLTLIBRARIES install-nobase_includeHEADERS &&\ - $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA -endef - -define $(package)_postprocess_cmds - rm lib/libprotoc.a -endef From 701fa445410aa71d5e15715075552f3da7dabb95 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 17 Mar 2023 10:53:47 -0400 Subject: [PATCH 003/391] docs: remove protobuf from docs --- doc/build-osx.md | 2 +- doc/build-unix.md | 5 ++--- doc/build-windows.md | 3 +-- doc/dependencies.md | 1 - 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/doc/build-osx.md b/doc/build-osx.md index 20ba4118cb..3cbab97843 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -16,7 +16,7 @@ Then install [Homebrew](https://brew.sh). Dependencies ---------------------- - brew install autoconf automake berkeley-db4 libtool boost miniupnpc openssl pkg-config protobuf python3 qt5 zmq libevent qrencode + brew install autoconf automake berkeley-db4 libtool boost miniupnpc openssl pkg-config python3 qt5 zmq libevent qrencode See [dependencies.md](dependencies.md) for a complete overview. diff --git a/doc/build-unix.md b/doc/build-unix.md index 98ef67c71e..8155cb020c 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -42,7 +42,6 @@ Optional dependencies: miniupnpc | UPnP Support | Firewall-jumping support libdb4.8 | Berkeley DB | Wallet storage (only needed when wallet enabled) qt | GUI | GUI toolkit (only needed when GUI enabled) - protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when GUI enabled) libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) univalue | Utility | JSON parsing and encoding (bundled version will be used unless --with-system-univalue passed to configure) libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.0.0) @@ -114,7 +113,7 @@ To build without GUI pass `--without-gui`. To build with Qt 5 you need the following: - sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler + sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode (optional) can be installed with: @@ -138,7 +137,7 @@ Optional: To build with Qt 5 you need the following: - sudo dnf install qt5-qttools-devel qt5-qtbase-devel protobuf-devel + sudo dnf install qt5-qttools-devel qt5-qtbase-devel libqrencode (optional) can be installed with: diff --git a/doc/build-windows.md b/doc/build-windows.md index 29d2983b0a..8e83f027d5 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -62,8 +62,7 @@ First, install the general dependencies: sudo apt install build-essential libtool autotools-dev automake pkg-config bsdmainutils curl git A host toolchain (`build-essential`) is necessary because some dependency -packages (such as `protobuf`) need to build host utilities that are used in the -build process. +packages need to build host utilities that are used in the build process. See [dependencies.md](dependencies.md) for a complete overview. diff --git a/doc/dependencies.md b/doc/dependencies.md index c124bd5324..e557c5cced 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -21,7 +21,6 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | MiniUPnPc | [2.2.2](https://miniupnp.tuxfamily.org/files) | | No | | | | OpenSSL | [1.0.1k](https://www.openssl.org/source) | | Yes | | | | PCRE | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L66) | -| protobuf | [2.6.1](https://github.com/google/protobuf/releases) | | No | | | | Python (tests) | | [3.5](https://www.python.org/downloads) | | | | | qrencode | [3.4.4](https://fukuchi.org/works/qrencode) | | No | | | | Qt | [5.9.9](https://download.qt.io/official_releases/qt/) | [5.5.1](https://github.com/bitcoin/bitcoin/issues/13478) | No | | | From 60796b6f6c565544223cf2c49cb85e7360e68425 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 17 Mar 2023 11:25:19 -0400 Subject: [PATCH 004/391] Remove BIP70 support This removes the support for BIP 70 payment requests. Protobuf is no longer required by any binary target. --- .../workflows/prcy-build-factory-debug.yml | 4 +- .../workflows/prcy-build-factory-ubuntu20.yml | 4 +- .github/workflows/prcy-build-factory.yml | 4 +- .travis.yml | 6 +- configure.ac | 7 - contrib/prcycoin-qt.pro | 2 - contrib/prcycoind.bash-completion | 2 +- src/Makefile.am | 4 - src/Makefile.qt.include | 24 +- src/Makefile.qttest.include | 16 +- src/qt/optionsmodel.cpp | 19 +- src/qt/optionsmodel.h | 5 - src/qt/paymentrequest.proto | 46 -- src/qt/paymentrequestplus.cpp | 207 -------- src/qt/paymentrequestplus.h | 50 -- src/qt/paymentserver.cpp | 442 +----------------- src/qt/paymentserver.h | 36 -- src/qt/prcycoin.cpp | 1 - src/qt/sendcoinsentry.cpp | 23 - src/qt/test/paymentrequestdata.h | 311 ------------ src/qt/test/paymentservertests.cpp | 134 ------ src/qt/test/paymentservertests.h | 35 -- src/qt/test/test_main.cpp | 9 - src/qt/transactiondesc.cpp | 13 - src/qt/utilitydialog.cpp | 1 - src/qt/walletmodel.cpp | 17 +- src/qt/walletmodel.h | 15 +- src/qt/walletmodeltransaction.h | 3 + 28 files changed, 46 insertions(+), 1394 deletions(-) delete mode 100644 src/qt/paymentrequest.proto delete mode 100644 src/qt/paymentrequestplus.cpp delete mode 100644 src/qt/paymentrequestplus.h delete mode 100644 src/qt/test/paymentrequestdata.h delete mode 100644 src/qt/test/paymentservertests.cpp delete mode 100644 src/qt/test/paymentservertests.h diff --git a/.github/workflows/prcy-build-factory-debug.yml b/.github/workflows/prcy-build-factory-debug.yml index ad6add0f4c..66374f90f3 100644 --- a/.github/workflows/prcy-build-factory-debug.yml +++ b/.github/workflows/prcy-build-factory-debug.yml @@ -28,13 +28,13 @@ jobs: echo "VERSION=${VERSION}" echo "TAG=${TAG}" printenv - # May need qt and protobuf to configure qt and include prcycoin-qt.1 in distribution + # May need qt to configure qt and include prcycoin-qt.1 in distribution - name: Install Required Packages run: | sudo apt-get update sudo apt-get install -y build-essential libtool bsdmainutils autotools-dev autoconf pkg-config automake python3 sudo apt-get install -y libssl1.0-dev libzmq5 libgmp-dev libevent-dev libboost-all-dev libsodium-dev cargo - sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode-dev + sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode-dev sudo apt-get install -y software-properties-common g++-multilib binutils-gold patch sudo add-apt-repository ppa:pivx/pivx sudo apt-get update diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml index 9e173eaa8c..b4ec4d66c5 100644 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ b/.github/workflows/prcy-build-factory-ubuntu20.yml @@ -78,12 +78,12 @@ jobs: run: | export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} echo "VERSION=${VERSION}" >> $GITHUB_ENV - # May need qt and protobuf to configure qt and include prcycoin-qt.1 in distribution + # May need qt to configure qt and include prcycoin-qt.1 in distribution - name: Install Required Packages run: | sudo apt-get update sudo apt-get install -y libssl1.0-dev libevent-dev libboost-all-dev - sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode-dev + sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode-dev sudo add-apt-repository ppa:pivx/pivx sudo apt-get update sudo apt-get install -y libdb4.8-dev libdb4.8++-dev diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 40d5bf5765..86ed3c626c 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -77,12 +77,12 @@ jobs: run: | export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} echo "VERSION=${VERSION}" >> $GITHUB_ENV - # May need qt and protobuf to configure qt and include prcycoin-qt.1 in distribution + # May need qt to configure qt and include prcycoin-qt.1 in distribution - name: Install Required Packages run: | sudo apt-get update sudo apt-get install -y libssl1.0-dev libevent-dev libboost-all-dev - sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode-dev + sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode-dev sudo add-apt-repository ppa:pivx/pivx sudo apt-get update sudo apt-get install -y libdb4.8-dev libdb4.8++-dev diff --git a/.travis.yml b/.travis.yml index c133a5bd94..5912f40515 100644 --- a/.travis.yml +++ b/.travis.yml @@ -98,7 +98,7 @@ jobs: - stage: test env: >- HOST=x86_64-unknown-linux-gnu - PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools protobuf-compiler libdbus-1-dev libharfbuzz-dev libprotobuf-dev" + PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libharfbuzz-dev" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1" GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" @@ -106,7 +106,7 @@ jobs: - stage: test env: >- HOST=x86_64-unknown-linux-gnu - PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" + PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev" NO_DEPENDS=1 GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --enable-glibc-back-compat --enable-reduce-exports --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER" @@ -114,7 +114,7 @@ jobs: # - stage: test # env: >- # HOST=x86_64-unknown-linux-gnu -# PACKAGES="clang python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" +# PACKAGES="clang python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev" # NO_DEPENDS=1 # RUN_BENCH=true # RUN_FUNCTIONAL_TESTS=false # Disabled for now, can be combined with the other x86_64 linux NO_DEPENDS job when functional tests pass the sanitizers diff --git a/configure.ac b/configure.ac index c073b22348..f863f9b44f 100644 --- a/configure.ac +++ b/configure.ac @@ -208,8 +208,6 @@ AC_ARG_ENABLE([zmq], [use_zmq=$enableval], [use_zmq=yes]) -AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) - AC_ARG_ENABLE(man, [AS_HELP_STRING([--disable-man], [do not install man pages (default is to install)])],, @@ -1005,7 +1003,6 @@ if test x$use_pkgconfig = xyes; then [ PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)]) PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)]) - BITCOIN_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITCOIN_QT_FAIL(libprotobuf not found)])]) if test x$use_qr != xno; then BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) fi @@ -1065,7 +1062,6 @@ else esac fi - BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITCOIN_QT_FAIL(libprotobuf not found))) if test x$use_qr != xno; then BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) @@ -1135,8 +1131,6 @@ AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes]) AC_SUBST(UNIVALUE_CFLAGS) AC_SUBST(UNIVALUE_LIBS) -BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path) - AC_MSG_CHECKING([whether to build prcycoind]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) AC_MSG_RESULT($build_bitcoind) @@ -1343,7 +1337,6 @@ AC_SUBST(SSL_LIBS) AC_SUBST(EVENT_LIBS) AC_SUBST(EVENT_PTHREADS_LIBS) AC_SUBST(ZMQ_LIBS) -AC_SUBST(PROTOBUF_LIBS) AC_SUBST(QR_LIBS) AC_SUBST(USE_NUM_OPENSSL) AC_SUBST(HAVE_FDATASYNC) diff --git a/contrib/prcycoin-qt.pro b/contrib/prcycoin-qt.pro index 0f55b4307b..090a61e9c2 100644 --- a/contrib/prcycoin-qt.pro +++ b/contrib/prcycoin-qt.pro @@ -215,7 +215,6 @@ HEADERS += src/activemasternode.h \ src/qt/optionsmodel.h \ src/qt/optionspage.h \ src/qt/overviewpage.h \ - src/qt/paymentrequestplus.h \ src/qt/paymentserver.h \ src/qt/peertablemodel.h \ src/qt/qgoogleauth.h \ @@ -543,7 +542,6 @@ SOURCES += src/activemasternode.cpp \ src/qt/optionsmodel.cpp \ src/qt/optionspage.cpp \ src/qt/overviewpage.cpp \ - src/qt/paymentrequestplus.cpp \ src/qt/paymentserver.cpp \ src/qt/peertablemodel.cpp \ src/qt/qgoogleauth.cpp \ diff --git a/contrib/prcycoind.bash-completion b/contrib/prcycoind.bash-completion index bac417eafd..315b54649a 100644 --- a/contrib/prcycoind.bash-completion +++ b/contrib/prcycoind.bash-completion @@ -15,7 +15,7 @@ _prcycoind() { _get_comp_words_by_ref -n = cur prev words cword case "$cur" in - -conf=*|-pid=*|-loadblock=*|-rootcertificates=*|-rpccookiefile=*|-wallet=*) + -conf=*|-pid=*|-loadblock=*|-rpccookiefile=*|-wallet=*) cur="${cur#*=}" _filedir return 0 diff --git a/src/Makefile.am b/src/Makefile.am index 5b7c4335f3..7c54ddfc46 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -583,10 +583,6 @@ if HARDEN $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS) endif -%.pb.cc %.pb.h: %.proto - @test -f $(PROTOC) - $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$( forms/ui_foo.h QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h)))) @@ -413,14 +406,9 @@ QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI: $(QT_MOC): $(QT_FORMS_H) $(qt_libbitcoinqt_a_OBJECTS) $(qt_prcycoin_qt_OBJECTS) : | $(QT_MOC) -#Generating these with a half-written protobuf header leads to wacky results. -#This makes sure it's done. -$(QT_MOC): $(PROTOBUF_H) -$(QT_MOC_CPP): $(PROTOBUF_H) - # prcycoin-qt binary # qt_prcycoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ - $(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) + $(QT_INCLUDES) $(QR_CFLAGS) qt_prcycoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) qt_prcycoin_qt_SOURCES = qt/prcycoin.cpp @@ -439,7 +427,7 @@ qt_prcycoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif qt_prcycoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \ - $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ + $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) -lqrencode qt_prcycoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_prcycoin_qt_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX @@ -464,7 +452,7 @@ $(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM) $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ @rm $(@D)/temp_$( $@ diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index cf3b86c202..da1890ef62 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -6,26 +6,16 @@ TESTS += qt/test/test_prcycoin-qt TEST_QT_MOC_CPP = qt/test/moc_uritests.cpp -if ENABLE_WALLET -TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp -endif - TEST_QT_H = \ - qt/test/uritests.h \ - qt/test/paymentrequestdata.h \ - qt/test/paymentservertests.h + qt/test/uritests.h qt_test_test_prcycoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ - $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS) + $(QT_INCLUDES) $(QT_TEST_INCLUDES) qt_test_test_prcycoin_qt_SOURCES = \ qt/test/test_main.cpp \ qt/test/uritests.cpp \ $(TEST_QT_H) -if ENABLE_WALLET -qt_test_test_prcycoin_qt_SOURCES += \ - qt/test/paymentservertests.cpp -endif nodist_qt_test_test_prcycoin_qt_SOURCES = $(TEST_QT_MOC_CPP) @@ -38,7 +28,7 @@ qt_test_test_prcycoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif qt_test_test_prcycoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \ $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ - $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ + $(QR_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_test_test_prcycoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_test_test_prcycoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 4a21e7e5f3..4f16057bba 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -27,7 +27,7 @@ #include "wallet/walletdb.h" #endif -#include +#include #include #include @@ -364,23 +364,6 @@ void OptionsModel::setDisplayUnit(const QVariant& value) } } -bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const -{ - // Directly query current base proxy, because - // GUI settings can be overridden with -proxy. - proxyType curProxy; - if (GetProxy(NET_IPV4, curProxy)) { - proxy.setType(QNetworkProxy::Socks5Proxy); - proxy.setHostName(QString::fromStdString(curProxy.proxy.ToStringIP())); - proxy.setPort(curProxy.proxy.GetPort()); - - return true; - } else - proxy.setType(QNetworkProxy::NoProxy); - - return false; -} - void OptionsModel::setRestartRequired(bool fRequired) { QSettings settings; diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index b4c360646c..a911056c5c 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -9,10 +9,6 @@ #include -QT_BEGIN_NAMESPACE -class QNetworkProxy; -QT_END_NAMESPACE - /** Interface from Qt to configuration data structure for Bitcoin client. To Qt, the options are presented as a list with the different options laid out vertically. @@ -63,7 +59,6 @@ class OptionsModel : public QAbstractListModel bool getMinimizeOnClose() { return fMinimizeOnClose; } int getDisplayUnit() { return nDisplayUnit; } QString getThirdPartyTxUrls() { return strThirdPartyTxUrls; } - bool getProxySettings(QNetworkProxy& proxy) const; bool getCoinControlFeatures() { return fCoinControlFeatures; } const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; } diff --git a/src/qt/paymentrequest.proto b/src/qt/paymentrequest.proto deleted file mode 100644 index b2281c4c7b..0000000000 --- a/src/qt/paymentrequest.proto +++ /dev/null @@ -1,46 +0,0 @@ -// -// Simple Bitcoin Payment Protocol messages -// -// Use fields 100+ for extensions; -// to avoid conflicts, register extensions at: -// https://en.bitcoin.it/wiki/Payment_Request -// - -package payments; -option java_package = "org.bitcoin.protocols.payments"; -option java_outer_classname = "Protos"; - -// Generalized form of "send payment to this/these bitcoin addresses" -message Output { - optional uint64 amount = 1 [default = 0]; // amount is integer-number-of-satoshis - required bytes script = 2; // usually one of the standard Script forms -} -message PaymentDetails { - optional string network = 1 [default = "main"]; // "main" or "test" - repeated Output outputs = 2; // Where payment should be sent - required uint64 time = 3; // Timestamp; when payment request created - optional uint64 expires = 4; // Timestamp; when this request should be considered invalid - optional string memo = 5; // Human-readable description of request for the customer - optional string payment_url = 6; // URL to send Payment and get PaymentACK - optional bytes merchant_data = 7; // Arbitrary data to include in the Payment message -} -message PaymentRequest { - optional uint32 payment_details_version = 1 [default = 1]; - optional string pki_type = 2 [default = "none"]; // none / x509+sha256 / x509+sha1 - optional bytes pki_data = 3; // depends on pki_type - required bytes serialized_payment_details = 4; // PaymentDetails - optional bytes signature = 5; // pki-dependent signature -} -message X509Certificates { - repeated bytes certificate = 1; // DER-encoded X.509 certificate chain -} -message Payment { - optional bytes merchant_data = 1; // From PaymentDetails.merchant_data - repeated bytes transactions = 2; // Signed transactions that satisfy PaymentDetails.outputs - repeated Output refund_to = 3; // Where to send refunds, if a refund is necessary - optional string memo = 4; // Human-readable message for the merchant -} -message PaymentACK { - required Payment payment = 1; // Payment message that triggered this ACK - optional string memo = 2; // human-readable message for customer -} diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp deleted file mode 100644 index 8b195f1da4..0000000000 --- a/src/qt/paymentrequestplus.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -// -// Wraps dumb protocol buffer paymentRequest -// with some extra methods -// - -#include "paymentrequestplus.h" - -#include - -#include - -#include -#include -#include - - -class SSLVerifyError : public std::runtime_error -{ -public: - SSLVerifyError(std::string err) : std::runtime_error(err) {} -}; - -bool PaymentRequestPlus::parse(const QByteArray& data) -{ - bool parseOK = paymentRequest.ParseFromArray(data.data(), data.size()); - if (!parseOK) { - qWarning() << "PaymentRequestPlus::parse : Error parsing payment request"; - return false; - } - if (paymentRequest.payment_details_version() > 1) { - qWarning() << "PaymentRequestPlus::parse : Received up-version payment details, version=" << paymentRequest.payment_details_version(); - return false; - } - - parseOK = details.ParseFromString(paymentRequest.serialized_payment_details()); - if (!parseOK) { - qWarning() << "PaymentRequestPlus::parse : Error parsing payment details"; - paymentRequest.Clear(); - return false; - } - return true; -} - -bool PaymentRequestPlus::SerializeToString(std::string* output) const -{ - return paymentRequest.SerializeToString(output); -} - -bool PaymentRequestPlus::IsInitialized() const -{ - return paymentRequest.IsInitialized(); -} - -QString PaymentRequestPlus::getPKIType() const -{ - if (!IsInitialized()) return QString("none"); - return QString::fromStdString(paymentRequest.pki_type()); -} - -bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) const -{ - merchant.clear(); - - if (!IsInitialized()) - return false; - - // One day we'll support more PKI types, but just - // x509 for now: - const EVP_MD* digestAlgorithm = NULL; - if (paymentRequest.pki_type() == "x509+sha256") { - digestAlgorithm = EVP_sha256(); - } else if (paymentRequest.pki_type() == "x509+sha1") { - digestAlgorithm = EVP_sha1(); - } else if (paymentRequest.pki_type() == "none") { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: pki_type == none"; - return false; - } else { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type()); - return false; - } - - payments::X509Certificates certChain; - if (!certChain.ParseFromString(paymentRequest.pki_data())) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: error parsing pki_data"; - return false; - } - - std::vector certs; - const QDateTime currentTime = QDateTime::currentDateTime(); - for (int i = 0; i < certChain.certificate_size(); i++) { - QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size()); - QSslCertificate qCert(certData, QSsl::Der); - if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: certificate expired or not yet active: " << qCert; - return false; - } -#if QT_VERSION >= 0x050000 - if (qCert.isBlacklisted()) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: certificate blacklisted: " << qCert; - return false; - } -#endif - const unsigned char* data = (const unsigned char*)certChain.certificate(i).data(); - X509* cert = d2i_X509(NULL, &data, certChain.certificate(i).size()); - if (cert) - certs.push_back(cert); - } - if (certs.empty()) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: empty certificate chain"; - return false; - } - - // The first cert is the signing cert, the rest are untrusted certs that chain - // to a valid root authority. OpenSSL needs them separately. - STACK_OF(X509)* chain = sk_X509_new_null(); - for (int i = certs.size() - 1; i > 0; i--) { - sk_X509_push(chain, certs[i]); - } - X509* signing_cert = certs[0]; - - // Now create a "store context", which is a single use object for checking, - // load the signing cert into it and verify. - X509_STORE_CTX* store_ctx = X509_STORE_CTX_new(); - if (!store_ctx) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: error creating X509_STORE_CTX"; - return false; - } - - char* website = NULL; - bool fResult = true; - try { - if (!X509_STORE_CTX_init(store_ctx, certStore, signing_cert, chain)) { - int error = X509_STORE_CTX_get_error(store_ctx); - throw SSLVerifyError(X509_verify_cert_error_string(error)); - } - - // Now do the verification! - int result = X509_verify_cert(store_ctx); - if (result != 1) { - int error = X509_STORE_CTX_get_error(store_ctx); - throw SSLVerifyError(X509_verify_cert_error_string(error)); - } - X509_NAME* certname = X509_get_subject_name(signing_cert); - - // Valid cert; check signature: - payments::PaymentRequest rcopy(paymentRequest); // Copy - rcopy.set_signature(std::string("")); - std::string data_to_verify; // Everything but the signature - rcopy.SerializeToString(&data_to_verify); - -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); - if (!ctx) throw SSLVerifyError("Error allocating OpenSSL context."); -#else - EVP_MD_CTX _ctx; - EVP_MD_CTX *ctx; - ctx = &_ctx; -#endif - EVP_PKEY* pubkey = X509_get_pubkey(signing_cert); - EVP_MD_CTX_init(ctx); - if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, NULL) || - !EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) || - !EVP_VerifyFinal(ctx, (const unsigned char*)paymentRequest.signature().data(), paymentRequest.signature().size(), pubkey)) { - throw SSLVerifyError("Bad signature, invalid PaymentRequest."); - } -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - EVP_MD_CTX_free(ctx); -#endif - - // OpenSSL API for getting human printable strings from certs is baroque. - int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0); - website = new char[textlen + 1]; - if (X509_NAME_get_text_by_NID(certname, NID_commonName, website, textlen + 1) == textlen && textlen > 0) { - merchant = website; - } else { - throw SSLVerifyError("Bad certificate, missing common name."); - } - // TODO: detect EV certificates and set merchant = business name instead of unfriendly NID_commonName ? - } catch (const SSLVerifyError& err) { - fResult = false; - qWarning() << "PaymentRequestPlus::getMerchant : SSL error: " << err.what(); - } - - if (website) - delete[] website; - X509_STORE_CTX_free(store_ctx); - for (unsigned int i = 0; i < certs.size(); i++) - X509_free(certs[i]); - - return fResult; -} - -QList > PaymentRequestPlus::getPayTo() const -{ - QList > result; - for (int i = 0; i < details.outputs_size(); i++) { - const unsigned char* scriptStr = (const unsigned char*)details.outputs(i).script().data(); - CScript s(scriptStr, scriptStr + details.outputs(i).script().size()); - - result.append(std::make_pair(s, details.outputs(i).amount())); - } - return result; -} diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h deleted file mode 100644 index 79e7fd8993..0000000000 --- a/src/qt/paymentrequestplus.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_QT_PAYMENTREQUESTPLUS_H -#define BITCOIN_QT_PAYMENTREQUESTPLUS_H - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#include "paymentrequest.pb.h" -#pragma GCC diagnostic pop - -#include "base58.h" - -#include - -#include -#include -#include - -// -// Wraps dumb protocol buffer paymentRequest -// with extra methods -// - -class PaymentRequestPlus -{ -public: - PaymentRequestPlus() {} - - bool parse(const QByteArray& data); - bool SerializeToString(std::string* output) const; - - bool IsInitialized() const; - QString getPKIType() const; - // Returns true if merchant's identity is authenticated, and - // returns human-readable merchant identity in merchant - bool getMerchant(X509_STORE* certStore, QString& merchant) const; - - // Returns list of outputs, amount - QList > getPayTo() const; - - const payments::PaymentDetails& getDetails() const { return details; } - -private: - payments::PaymentRequest paymentRequest; - payments::PaymentDetails details; -}; - -#endif // BITCOIN_QT_PAYMENTREQUESTPLUS_H diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index ba812512d4..f8f9712adb 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -32,45 +32,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include #include const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds const QString BITCOIN_IPC_PREFIX("prcycoin:"); -// BIP70 payment protocol messages -const char* BIP70_MESSAGE_PAYMENTACK = "PaymentACK"; -const char* BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest"; -// BIP71 payment protocol media types -const char* BIP71_MIMETYPE_PAYMENT = "application/prcycoin-payment"; -const char* BIP71_MIMETYPE_PAYMENTACK = "application/prcycoin-paymentack"; -const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/prcycoin-paymentrequest"; -// BIP70 max payment request size in bytes (DoS protection) -const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; - -struct X509StoreDeleter { - void operator()(X509_STORE* b) { - X509_STORE_free(b); - } -}; - -struct X509Deleter { - void operator()(X509* b) { X509_free(b); } -}; - -namespace // Anon namespace -{ - - std::unique_ptr certStore; -} // // Create a name that is unique for: @@ -97,79 +64,6 @@ static QString ipcServerName() static QList savedPaymentRequests; -static void ReportInvalidCertificate(const QSslCertificate& cert) -{ - qDebug() << QString("%1: Payment server found an invalid certificate: ").arg(__func__) << cert.serialNumber() << cert.subjectInfo(QSslCertificate::CommonName) << cert.subjectInfo(QSslCertificate::DistinguishedNameQualifier) << cert.subjectInfo(QSslCertificate::OrganizationalUnitName); -} - -// -// Load OpenSSL's list of root certificate authorities -// -void PaymentServer::LoadRootCAs(X509_STORE* _store) -{ - // Unit tests mostly use this, to pass in fake root CAs: - if (_store) { - certStore.reset(_store); - return; - } - - // Normal execution, use either -rootcertificates or system certs: - certStore.reset(X509_STORE_new()); - - // Note: use "-system-" default here so that users can pass -rootcertificates="" - // and get 'I don't like X.509 certificates, don't trust anybody' behavior: - QString certFile = QString::fromStdString(GetArg("-rootcertificates", "-system-")); - - if (certFile.isEmpty()) - return; // Empty store - - QList certList; - - if (certFile != "-system-") { - certList = QSslCertificate::fromPath(certFile); - // Use those certificates when fetching payment requests, too: - QSslConfiguration::defaultConfiguration().setCaCertificates(certList); - } else - certList = QSslConfiguration::systemCaCertificates(); - - int nRootCerts = 0; - const QDateTime currentTime = QDateTime::currentDateTime(); - Q_FOREACH (const QSslCertificate& cert, certList) { - if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate()) { - ReportInvalidCertificate(cert); - continue; - } - - // Blacklisted certificate - if (cert.isBlacklisted()) { - ReportInvalidCertificate(cert); - continue; - } - QByteArray certData = cert.toDer(); - const unsigned char* data = (const unsigned char*)certData.data(); - - std::unique_ptr x509(d2i_X509(0, &data, certData.size())); - if (x509 && X509_STORE_add_cert(certStore.get(), x509.get())) { - // Note: X509_STORE increases the reference count to the X509 object, - // we still have to release our reference to it. - ++nRootCerts; - } else { - ReportInvalidCertificate(cert); - continue; - } - } - qWarning() << "PaymentServer::LoadRootCAs : Loaded " << nRootCerts << " root certificates"; - - // Project for another day: - // Fetch certificate revocation lists, and add them to certStore. - // Issues to consider: - // performance (start a thread to fetch in background?) - // privacy (fetch through tor/proxy so IP address isn't revealed) - // would it be easier to just use a compiled-in blacklist? - // or use Qt's blacklist? - // "certificate stapling" with server-side caching is more efficient -} - // // Sending to the server is done synchronously, at startup. // If the server isn't already running, startup continues, @@ -204,22 +98,6 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) SelectParams(CBaseChainParams::TESTNET); } } - } else if (QFile::exists(arg)) // Filename - { - savedPaymentRequests.append(arg); - - PaymentRequestPlus request; - if (readPaymentRequestFromFile(arg, request)) { - if (request.getDetails().network() == "main") { - SelectParams(CBaseChainParams::MAIN); - } else if (request.getDetails().network() == "test") { - SelectParams(CBaseChainParams::TESTNET); - } - } - } else { - // Printing to debug.log is about the best we can do here, the - // GUI hasn't started yet so we can't pop up a message box. - qWarning() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg; } } } @@ -264,13 +142,8 @@ bool PaymentServer::ipcSendCommandLine() PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : QObject(parent), saveURIs(true), uriServer(0), - netManager(0), optionsModel(0) { - // Verify that the version of the library that we linked against is - // compatible with the version of the headers we compiled against. - GOOGLE_PROTOBUF_VERIFY_VERSION; - // Install global event filter to catch QFileOpenEvents // on Mac: sent when you click prcycoin: links // other OSes: helpful when dealing with payment request files (in the future) @@ -291,14 +164,12 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : QObject(p tr("Cannot start prcycoin: click-to-pay handler")); } else { connect(uriServer, SIGNAL(newConnection()), this, SLOT(handleURIConnection())); - connect(this, SIGNAL(receivedPaymentACK(QString)), this, SLOT(handlePaymentACK(QString))); } } } PaymentServer::~PaymentServer() { - google::protobuf::ShutdownProtobufLibrary(); } // @@ -321,36 +192,8 @@ bool PaymentServer::eventFilter(QObject* object, QEvent* event) return QObject::eventFilter(object, event); } -void PaymentServer::initNetManager() -{ - if (!optionsModel) - return; - if (netManager != NULL) - delete netManager; - - // netManager is used to fetch paymentrequests given in prcycoin: URIs - netManager = new QNetworkAccessManager(this); - - QNetworkProxy proxy; - - // Query active SOCKS5 proxy - if (optionsModel->getProxySettings(proxy)) { - netManager->setProxy(proxy); - - qDebug() << "PaymentServer::initNetManager : Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port(); - } else - qDebug() << "PaymentServer::initNetManager : No active proxy server found."; - - connect(netManager, SIGNAL(finished(QNetworkReply*)), - this, SLOT(netRequestFinished(QNetworkReply*))); - connect(netManager, SIGNAL(sslErrors(QNetworkReply*, const QList&)), - this, SLOT(reportSslErrors(QNetworkReply*, const QList&))); -} - void PaymentServer::uiReady() { - initNetManager(); - saveURIs = false; Q_FOREACH (const QString& s, savedPaymentRequests) { handleURIOrFile(s); @@ -368,34 +211,23 @@ void PaymentServer::handleURIOrFile(const QString& s) if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // prcycoin: URI { QUrlQuery uri((QUrl(s))); - SendCoinsRecipient recipient; - if (GUIUtil::parseBitcoinURI(s, &recipient)) { - CBitcoinAddress address(recipient.address.toStdString()); - if (!address.IsValid()) { - Q_EMIT message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), - CClientUIInterface::MSG_ERROR); + // normal URI + { + SendCoinsRecipient recipient; + if (GUIUtil::parseBitcoinURI(s, &recipient)) { + CBitcoinAddress address(recipient.address.toStdString()); + if (!address.IsValid()) { + Q_EMIT message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), + CClientUIInterface::MSG_ERROR); + } else + Q_EMIT receivedPaymentRequest(recipient); } else - Q_EMIT receivedPaymentRequest(recipient); - } else - Q_EMIT message(tr("URI handling"), - tr("URI cannot be parsed! This can be caused by an invalid PRCY address or malformed URI parameters."), - CClientUIInterface::ICON_WARNING); - - return; - } + Q_EMIT message(tr("URI handling"), + tr("URI cannot be parsed! This can be caused by an invalid PRCY address or malformed URI parameters."), + CClientUIInterface::ICON_WARNING); - if (QFile::exists(s)) // payment request file - { - PaymentRequestPlus request; - SendCoinsRecipient recipient; - if (!readPaymentRequestFromFile(s, request)) { - Q_EMIT message(tr("Payment request file handling"), - tr("Payment request file cannot be read! This can be caused by an invalid payment request file."), - CClientUIInterface::ICON_WARNING); - } else if (processPaymentRequest(request, recipient)) - Q_EMIT receivedPaymentRequest(recipient); - - return; + return; + } } } @@ -420,251 +252,7 @@ void PaymentServer::handleURIConnection() handleURIOrFile(msg); } -// -// Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine() -// so don't use "Q_EMIT message()", but "QMessageBox::"! -// -bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request) -{ - QFile f(filename); - if (!f.open(QIODevice::ReadOnly)) { - qWarning() << QString("PaymentServer::%1: Failed to open %2").arg(__func__).arg(filename); - return false; - } - - // BIP70 DoS protection - if (f.size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - qWarning() << QString("PaymentServer::%1: Payment request %2 is too large (%3 bytes, allowed %4 bytes).") - .arg(__func__) - .arg(filename) - .arg(f.size()) - .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); - return false; - } - - QByteArray data = f.readAll(); - - return request.parse(data); -} - -bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient) -{ - if (!optionsModel) - return false; - - if (request.IsInitialized()) { - const payments::PaymentDetails& details = request.getDetails(); - - // Payment request network matches client network? - if (details.network() != Params().NetworkIDString()) { - Q_EMIT message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), - CClientUIInterface::MSG_ERROR); - - return false; - } - - // Expired payment request? - if (details.has_expires() && (int64_t)details.expires() < GetTime()) { - Q_EMIT message(tr("Payment request rejected"), tr("Payment request has expired."), - CClientUIInterface::MSG_ERROR); - - return false; - } - } else { - Q_EMIT message(tr("Payment request error"), tr("Payment request is not initialized."), - CClientUIInterface::MSG_ERROR); - - return false; - } - - recipient.paymentRequest = request; - recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo()); - - request.getMerchant(certStore.get(), recipient.authenticatedMerchant); - - QList > sendingTos = request.getPayTo(); - QStringList addresses; - - Q_FOREACH (const PAIRTYPE(CScript, CAmount) & sendingTo, sendingTos) { - // Extract and check destination addresses - CTxDestination dest; - if (ExtractDestination(sendingTo.first, dest)) { - // Append destination address - addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString())); - } else if (!recipient.authenticatedMerchant.isEmpty()) { - // Insecure payments to custom prcycoin addresses are not supported - // (there is no good way to tell the user where they are paying in a way - // they'd have a chance of understanding). - Q_EMIT message(tr("Payment request rejected"), - tr("Unverified payment requests to custom payment scripts are unsupported."), - CClientUIInterface::MSG_ERROR); - return false; - } - - // Extract and check amounts - CTxOut txOut(sendingTo.second, sendingTo.first); - if (txOut.IsDust(::minRelayTxFee)) { - Q_EMIT message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).").arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)), - CClientUIInterface::MSG_ERROR); - - return false; - } - - recipient.amount += sendingTo.second; - } - // Store addresses and format them to fit nicely into the GUI - recipient.address = addresses.join("
"); - - if (!recipient.authenticatedMerchant.isEmpty()) { - qDebug() << "PaymentServer::processPaymentRequest : Secure payment request from " << recipient.authenticatedMerchant; - } else { - qDebug() << "PaymentServer::processPaymentRequest : Insecure payment request to " << addresses.join(", "); - } - - return true; -} - -void PaymentServer::fetchRequest(const QUrl& url) -{ - QNetworkRequest netRequest; - netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTREQUEST); - netRequest.setUrl(url); - netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str()); - netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTREQUEST); - netManager->get(netRequest); -} - -void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction) -{ - const payments::PaymentDetails& details = recipient.paymentRequest.getDetails(); - if (!details.has_payment_url()) - return; - - QNetworkRequest netRequest; - netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTACK); - netRequest.setUrl(QString::fromStdString(details.payment_url())); - netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BIP71_MIMETYPE_PAYMENT); - netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str()); - netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTACK); - - payments::Payment payment; - payment.set_merchant_data(details.merchant_data()); - payment.add_transactions(transaction.data(), transaction.size()); - - // Create a new refund address, or re-use: - QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant); - std::string strAccount = account.toStdString(); - std::set refundAddresses = wallet->GetAccountAddresses(strAccount); - if (!refundAddresses.empty()) { - CScript s = GetScriptForDestination(*refundAddresses.begin()); - payments::Output* refund_to = payment.add_refund_to(); - refund_to->set_script(&s[0], s.size()); - } else { - CPubKey newKey; - if (wallet->GetKeyFromPool(newKey)) { - CKeyID keyID = newKey.GetID(); - wallet->SetAddressBook(keyID, strAccount, "refund"); - - CScript s = GetScriptForDestination(keyID); - payments::Output* refund_to = payment.add_refund_to(); - refund_to->set_script(&s[0], s.size()); - } else { - // This should never happen, because sending coins should have - // just unlocked the wallet and refilled the keypool. - qWarning() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set"; - } - } - - int length = payment.ByteSize(); - netRequest.setHeader(QNetworkRequest::ContentLengthHeader, length); - QByteArray serData(length, '\0'); - if (payment.SerializeToArray(serData.data(), length)) { - netManager->post(netRequest, serData); - } else { - // This should never happen, either. - qWarning() << "PaymentServer::fetchPaymentACK : Error serializing payment message"; - } -} - -void PaymentServer::netRequestFinished(QNetworkReply* reply) -{ - reply->deleteLater(); - - // BIP70 DoS protection - if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - QString msg = tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).") - .arg(reply->request().url().toString()) - .arg(reply->size()) - .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); - - qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg; - Q_EMIT message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR); - return; - } - - if (reply->error() != QNetworkReply::NoError) { - QString msg = tr("Error communicating with %1: %2") - .arg(reply->request().url().toString()) - .arg(reply->errorString()); - - qWarning() << "PaymentServer::netRequestFinished: " << msg; - Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); - return; - } - - QByteArray data = reply->readAll(); - - QString requestType = reply->request().attribute(QNetworkRequest::User).toString(); - if (requestType == BIP70_MESSAGE_PAYMENTREQUEST) { - PaymentRequestPlus request; - SendCoinsRecipient recipient; - if (!request.parse(data)) { - qWarning() << "PaymentServer::netRequestFinished : Error parsing payment request"; - Q_EMIT message(tr("Payment request error"), - tr("Payment request cannot be parsed!"), - CClientUIInterface::MSG_ERROR); - } else if (processPaymentRequest(request, recipient)) - Q_EMIT receivedPaymentRequest(recipient); - - return; - } else if (requestType == BIP70_MESSAGE_PAYMENTACK) { - payments::PaymentACK paymentACK; - if (!paymentACK.ParseFromArray(data.data(), data.size())) { - QString msg = tr("Bad response from server %1") - .arg(reply->request().url().toString()); - - qWarning() << "PaymentServer::netRequestFinished : " << msg; - Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); - } else { - Q_EMIT receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo())); - } - } -} - -void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList& errs) -{ - Q_UNUSED(reply); - - QString errString; - Q_FOREACH (const QSslError& err, errs) { - qWarning() << "PaymentServer::reportSslErrors : " << err; - errString += err.errorString() + "\n"; - } - Q_EMIT message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR); -} - void PaymentServer::setOptionsModel(OptionsModel* optionsModel) { this->optionsModel = optionsModel; } - -void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) -{ - // currently we don't futher process or store the paymentACK message - Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); -} - -X509_STORE* PaymentServer::getCertStore() -{ - return certStore.get(); -} diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 74c7b88ae2..29a317a852 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -32,7 +32,6 @@ // sends them to the server. // -#include "paymentrequestplus.h" #include "walletmodel.h" #include @@ -46,15 +45,9 @@ QT_BEGIN_NAMESPACE class QApplication; class QByteArray; class QLocalServer; -class QNetworkAccessManager; -class QNetworkReply; -class QSslError; class QUrl; QT_END_NAMESPACE -// BIP70 max payment request size in bytes (DoS protection) -extern const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE; - class PaymentServer : public QObject { Q_OBJECT @@ -75,29 +68,13 @@ class PaymentServer : public QObject PaymentServer(QObject* parent, bool startLocalServer = true); ~PaymentServer(); - // Load root certificate authorities. Pass NULL (default) - // to read from the file specified in the -rootcertificates setting, - // or, if that's not set, to use the system default root certificates. - // If you pass in a store, you should not X509_STORE_free it: it will be - // freed either at exit or when another set of CAs are loaded. - static void LoadRootCAs(X509_STORE* store = NULL); - - // Return certificate store - static X509_STORE* getCertStore(); - // OptionsModel is used for getting proxy settings and display unit void setOptionsModel(OptionsModel* optionsModel); - // This is now public, because we use it in paymentservertests.cpp - static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request); - Q_SIGNALS: // Fired when a valid payment request is received void receivedPaymentRequest(SendCoinsRecipient); - // Fired when a valid PaymentACK is received - void receivedPaymentACK(const QString& paymentACKMsg); - // Fired when a message should be reported to the user void message(const QString& title, const QString& message, unsigned int style); @@ -106,17 +83,11 @@ public Q_SLOTS: // to display payment requests to the user void uiReady(); - // Submit Payment message to a merchant, get back PaymentACK: - void fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction); - // Handle an incoming URI, URI with local file scheme or file void handleURIOrFile(const QString& s); private Q_SLOTS: void handleURIConnection(); - void netRequestFinished(QNetworkReply*); - void reportSslErrors(QNetworkReply*, const QList&); - void handlePaymentACK(const QString& paymentACKMsg); protected: // Constructor registers this on the parent QApplication to @@ -124,15 +95,8 @@ private Q_SLOTS: bool eventFilter(QObject* object, QEvent* event); private: - bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient); - void fetchRequest(const QUrl& url); - - // Setup networking - void initNetManager(); - bool saveURIs; // true during startup QLocalServer* uriServer; - QNetworkAccessManager* netManager; // Used to fetch payment requests OptionsModel* optionsModel; }; diff --git a/src/qt/prcycoin.cpp b/src/qt/prcycoin.cpp index a10d5dd7f5..22705ded39 100644 --- a/src/qt/prcycoin.cpp +++ b/src/qt/prcycoin.cpp @@ -460,7 +460,6 @@ void BitcoinApplication::initializeResult(int retval) returnValue = retval ? 0 : 1; if (retval) { #ifdef ENABLE_WALLET - PaymentServer::LoadRootCAs(); paymentServer->setOptionsModel(optionsModel); #endif clientModel = new ClientModel(optionsModel); diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 2edbbd2c5e..32a31762e8 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -145,11 +145,6 @@ CAmount SendCoinsEntry::getValidatedAmount() { SendCoinsRecipient SendCoinsEntry::getValue() { - // Payment request - if (recipient.paymentRequest.IsInitialized()) - return recipient; - - // Normal payment recipient.address = ui->payTo->text(); recipient.label = ui->addAsLabel->text(); recipient.amount = getValidatedAmount(); @@ -169,24 +164,6 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient& value) { recipient = value; - if (recipient.paymentRequest.IsInitialized()) // payment request - { - if (recipient.authenticatedMerchant.isEmpty()) // insecure - { - ui->payTo_is->setText(recipient.address); - ui->memoTextLabel_is->setText(recipient.message); - ui->payAmount_is->setValue(recipient.amount); - ui->payAmount_is->setReadOnly(true); - setCurrentWidget(ui->SendCoins_InsecurePaymentRequest); - } else // secure - { - ui->payTo_s->setText(recipient.authenticatedMerchant); - ui->memoTextLabel_s->setText(recipient.message); - ui->payAmount_s->setValue(recipient.amount); - ui->payAmount_s->setReadOnly(true); - setCurrentWidget(ui->SendCoins_SecurePaymentRequest); - } - } else // normal payment { ui->addAsLabel->clear(); ui->payTo->setText(recipient.address); // this may set a label from addressbook diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h deleted file mode 100644 index aeaa7d89a0..0000000000 --- a/src/qt/test/paymentrequestdata.h +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -// -// Data for paymentservertests.cpp -// - -// Base64/DER-encoded fake certificate authority certificate. -// Convert pem to base64/der with: -// cat file.pem | openssl x509 -inform PEM -outform DER | openssl enc -base64 -// -// Serial Number: 10302349811211485352 (0x8ef94c91b112c0a8) -// Issuer: CN=PaymentRequest Test CA -// Subject: CN=PaymentRequest Test CA -// Not Valid After : Dec 8 16:37:24 2022 GMT -// -const char* caCert_BASE64 = -"\ -MIIB0DCCATmgAwIBAgIJAI75TJGxEsCoMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\ -BAMTFlBheW1lbnRSZXF1ZXN0IFRlc3QgQ0EwHhcNMTIxMjEwMTYzNzI0WhcNMjIx\ -MjA4MTYzNzI0WjAhMR8wHQYDVQQDExZQYXltZW50UmVxdWVzdCBUZXN0IENBMIGf\ -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvua59nX9radoqDYyplcns5qdVDTN1\ -7tmcGixmMYOYU3UYMU55VSsJs0dWKnMm3COQDY+N63c0XSbRqarBcsLTkaNASuPX\ -FCv1VWuEKSyy5xe4zeoDU7CVSzlxtQD9wbZW/s3ISjgaXBpwn6eVmntb0JwYxxPc\ -M1u/hrMD8BDbSQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA\ -A4GBADSaRgK5xe47XxycXBhHhr0Wgl4pAsFsufqA9aB9r8KNEHJ0yUvvbD/jaJJM\ -RtQcf0AJ9olzUMY4syehxbzUJP6aeXhZEYiMvdvcv9D55clq6+WLLlNT3jBgAaVn\ -p3waRjPD4bUX3nv+ojz5s4puw7Qq5QUZlhGsMzPvwDGCmZkL\ -"; - -// -// This payment request validates directly against the -// above certificate authority. -// -const char* paymentrequest1_BASE64 = -"\ -Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\ -BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMjEyMTAx\ -NjM3MjRaFw0yMjEyMDgxNjM3MjRaMEMxGTAXBgNVBAMMEHRlc3RtZXJjaGFudC5v\ -cmcxJjAkBgNVBAoMHVBheW1lbnQgUmVxdWVzdCBUZXN0IE1lcmNoYW50MIGfMA0G\ -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHkMy8W1u6HsWlSqdWTmMKf54gICxNfxbY\ -+rcMtAftr62hCYx2d2QiSRd1pCUzmo12IiSX3WxSHwaTnT3MFD6jRx6+zM6XdGar\ -I2zpYle11ANzu4gAthN17uRQHV2O5QxVtzNaMdKeJLXT2L9tfEdyL++9ZUqoQmdA\ -YG9ix330hQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GB\ -AIkyO99KC68bi9PFRyQQ7nvn5GlQEb3Ca1bRG5+AKN9N5vc8rZ9G2hejtM8wEXni\ -eGBP+chVMsbTPEHKLrwREn7IvcyCcbAStaklPC3w0B/2idQSHskb6P3X13OR2bTH\ -a2+6wuhsOZRUrVNr24rM95DKx/eCC6JN1VW+qRPU6fqzIjQSHwiw2wYSGXapFJVg\ -igPI+6XpExtNLO/i1WFV8ZmoiKwYsuHFiwUqC1VuaXRUZXN0T25lKoABS0j59iMU\ -Uc9MdIfwsO1BskIET0eJSGNZ7eXb9N62u+qf831PMpEHkmlGpk8rHy92nPcgua/U\ -Yt8oZMn3QaTZ5A6HjJbc3A73eLylp1a0SwCl+KDMEvDQhqMn1jAVu2v92AH3uB7n\ -SiWVbw0tX/68iSQEGGfh9n6ee/8Myb3ICdw=\ -"; - -// -// Signed, but expired, merchant cert in the request -// -const char* paymentrequest2_BASE64 = -"\ -Egt4NTA5K3NoYTI1NhrsAwrpAzCCAeUwggFOoAMCAQICAQMwDQYJKoZIhvcNAQEL\ -BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzAyMjMy\ -MTI2NDNaFw0xMzAyMjQyMTI2NDNaMD4xHDAaBgNVBAMME2V4cGlyZWRtZXJjaGFu\ -dC5vcmcxHjAcBgNVBAoMFUV4cGlyZWQgVGVzdCBNZXJjaGFudDCBnzANBgkqhkiG\ -9w0BAQEFAAOBjQAwgYkCgYEAx5DMvFtbuh7FpUqnVk5jCn+eICAsTX8W2Pq3DLQH\ -7a+toQmMdndkIkkXdaQlM5qNdiIkl91sUh8Gk509zBQ+o0cevszOl3RmqyNs6WJX\ -tdQDc7uIALYTde7kUB1djuUMVbczWjHSniS109i/bXxHci/vvWVKqEJnQGBvYsd9\ -9IUCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAaU137\ -j53rvSjlmYZpZ4RWTP7EdD6fl5ZxBeXHytN6DQL33H0eD7OFHt+ofc7E6D7keubl\ -UfCu+jOvt/MvvPUmtCI9yXZ0dNC4sjyETv+wQpxO0UNZwOM4uegdCzlo6Bi3pD4/\ -KKLdMkWuUfuPBmoammny74lZaOVr5deKXztTuCI0Eh8IsNsGEhl2qRSVYIoDyPul\ -6RMbTSzv4tVhVfGZqIisGLLhxYsFKgtVbml0VGVzdFR3byqAAXHuo4nZEPniLpkd\ -y30TkwBxVgprWJ18a9z/7Py35Qss/JMbOXbnBhJtmJCdIowHRI0aa+zqt3KKKAXi\ -mm+V4seMgxTcxMS+eDDkiTcB/RtWWSyRcS2ANjFeY0T4SLMwiCL9qWPi03hr8j96\ -tejrSPOBNSJ3Mi/q5u2Yl4gJZY2b\ -"; - -// -// 10-long chain, all intermediates valid -// -const char* paymentrequest3_BASE64 = -"\ -Egt4NTA5K3NoYTI1Nhq8JAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\ -BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\ -dWVzdCBJbnRlcm1lZGlhdGUgODAeFw0xMzAyMjMyMjQyMzFaFw0yMzAyMjEyMjQy\ -MzFaMDYxGjAYBgNVBAMMEXRlc3RtZXJjaGFudDgub3JnMRgwFgYDVQQKDA9UZXN0\ -IE1lcmNoYW50IDgwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMMCHA3hiHbS\ -TKZ5K9jHRwE8NxkGp3IOx56PDB2diNkldG8XweTcRq7bBm7pdiBt4IVggtfs+6hE\ -hDYIOecyoAnVzPFTdvQ7KQdQ/fD9YLe6lk+o0edOqutPMyrxLFjSluXxEQyk7fdt\ -URloMMYfp3p1/hFCboA1rAsQ2RW38hR5AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w\ -DQYJKoZIhvcNAQELBQADgYEAPsdFatnc2RJSpvZsw+nCiPVsllycw5ELglq9vfJz\ -nJJucRxgzmqI2iuas1ugwbXn0BEIRLK7vMF/qBzQR6M/nTxttah+KEu+okjps9vJ\ -cIyhfTyGPC5xkHaHZ7sG+UHOFhPw0/kXn0x+pbVgBZ5315axqcp1R+DTSj/whMAr\ -n0AKiAQwggIEMIIBbaADAgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMM\ -C3Rlc3RjYTcub3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRp\ -YXRlIDcwHhcNMTMwMjIzMjI0MjMxWhcNMjMwMjIxMjI0MjMxWjA/MRQwEgYDVQQD\ -DAt0ZXN0Y2E4Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVk\ -aWF0ZSA4MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDexUFfxb1sThvabp7u\ -dZz59ciThGmmAW0nP4tjrgEACgvWIInr2dZpTHbiQNF34ycsk0le1JD93D7Qb8rd\ -25OrpaO8XS2Li2zjR9cleixXjSLwV/zv8zJ8yPl/27XL++PDTKBXVpJ8/Syp+9Ty\ -plV1BqDhqtIHb/QSHEkTQXjeYQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqG\ -SIb3DQEBCwUAA4GBACMooQVbkbIZ2DaPwHDc4ULwguG3VI2Kzj50UdExmHtzm2S4\ -MQei+n+HEPjtJAx5OY520+10nfuP+12H2DRLQmWmdvDpeQ/Cv0yavlw4ZRejRFo7\ -KS83C0wo5rd+qTvvOmAN4UTArWkzYcEUulPdiXnRamb0WQHTeVdIbHVkMormCogE\ -MIICBDCCAW2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0ZXN0\ -Y2E2Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSA2\ -MB4XDTEzMDIyMzIyNDIzMVoXDTIzMDIyMTIyNDIzMVowPzEUMBIGA1UEAwwLdGVz\ -dGNhNy5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUg\ -NzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtjBRazrkebXAhXsbjimrMIRm\ -W/f9SwAHwXfc042keNtl0t2z6XE6UPcR2v/KrssXuCZgodeYxz6IM6lWosCM1xot\ -C3ChKKFBfVO30reuKBRUxXfKAFqxaG0YOAEzdZkkY9AGhqWloeSmgxpIfhInU0EF\ -JjCwrJ6IkijBatGoAAECAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B\ -AQsFAAOBgQDBRTi1MolmOA0niHYX0A2lN5QWHkCfX0A7GwyoMA3dvM45m/NYd4WB\ -X+HwfnfYcI6X9jOgNo5OWmc4GGsld0HlxwMYEKISBS9PbSHPBrb3TBOlw5ztQpXZ\ -91+bOhLux52Fr03sK7v9qExmBM12M8UR2ltpzAMiUgLLMHyPfiWkvQqIBDCCAgQw\ -ggFtoAMCAQICAQIwDQYJKoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNhNS5v\ -cmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgNTAeFw0x\ -MzAyMjMyMjQyMzBaFw0yMzAyMjEyMjQyMzBaMD8xFDASBgNVBAMMC3Rlc3RjYTYu\ -b3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDYwgZ8w\ -DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANJSH3xivX1t9olIdHsznI1aE9SD7t9i\ -SZJsIB0otoETHZRVv9M9LvyzBNK98ZV+kTOlST7PJgC0d9BQM9sgYApSRq5oqKDM\ -9FXbOm/yaReAbU3mkFNFw5roTlJ5ThEy0yOGT/DS0YBRaGIvRPRj2DiqDVdCZZ+w\ -4jo1IYHkZt4FAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQAD\ -gYEATm6+J1OmbrothO60xALKonWMBKr6hudb4amkFBqKbA9wMeM3jl+I/yKfz/Uf\ -xWuJ071IhiNv6Gxx5YwNvhUe1xMhUqHv0gpyK1Z47bD+kYS2se5sWNPNo3Y9qZDG\ -IXiGQxwHmrzaFk79Uy1xsmvsEz42w6hr25Yaw7HkIgrFveoKiAQwggIEMIIBbaAD\ -AgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMMC3Rlc3RjYTQub3JnMScw\ -JQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDQwHhcNMTMwMjIz\ -MjI0MjMwWhcNMjMwMjIxMjI0MjMwWjA/MRQwEgYDVQQDDAt0ZXN0Y2E1Lm9yZzEn\ -MCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSA1MIGfMA0GCSqG\ -SIb3DQEBAQUAA4GNADCBiQKBgQC7vVUFpxHzz2Tr/xij3k58s8d/BPA0R6D5RXTV\ -vmhAzc1Zuin4zUKRFs/aCj/0yED8Wu/COfNGF4tVlRNMdl9EcFsxa8XGEL4eAZa+\ -H/rOHH+7/1EINrrVWhZlUecyhilN8jmCZmqEM3ecuD0NAViqyMrgmaiFmsLoQZpE\ -GepDUQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAEdJ\ -Ss8jWiooja3WZzHXeF95QkBJNjIlpDLGcpl4opOYLSuEl9Uxp//LaQQiXuzpj4/I\ -pkWGQmMy5HOyH1lqDyiMgXpcG8PE0jEQAoEUGZ0QEqB1mZ6BCrYvmUuf/5aSVd8Y\ -6lKMR3WzFDYU9Zy0nzuHB/3nvp6MeDRQeRMtYvz4CogEMIICBDCCAW2gAwIBAgIB\ -AjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0ZXN0Y2EzLm9yZzEnMCUGA1UE\ -CgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSAzMB4XDTEzMDIyMzIyNDIy\ -OVoXDTIzMDIyMTIyNDIyOVowPzEUMBIGA1UEAwwLdGVzdGNhNC5vcmcxJzAlBgNV\ -BAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgNDCBnzANBgkqhkiG9w0B\ -AQEFAAOBjQAwgYkCgYEAxYYo3w2UXiYg6O8b4QgwN/vgreTkiW122Ep/z2TiDrhV\ -MhfOOiKdwYESPflfnXnVaQQzCGexYTQqsvqvzHSyna5hL0zPTRJxSKmTVrXRsWtp\ -dCRhjxCGipS3tlQBDi7vb+7SNRIBK4dBjjGzALNk7gMCpy+yM8f6I043jTlmGb0C\ -AwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQDU+IQxt3Oh\ -KqaUYWC23+cB2gekvWqwMBnrCNrX/Dp+kjoJKUoR2Fs3qw53raHES4SIhpGT9l9l\ -rppNQgFe/JMHeYqOZMZO+6kuU0olJanBJ14tPIc7zlMTQ9OfmZ6v07IpyFbsQDtR\ -hpe80DpuvSFPfJ4fh0WrQf6kn3KDVpGDnAqIBDCCAgQwggFtoAMCAQICAQIwDQYJ\ -KoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNhMi5vcmcxJzAlBgNVBAoMHlBh\ -eW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgMjAeFw0xMzAyMjMyMjQyMjlaFw0y\ -MzAyMjEyMjQyMjlaMD8xFDASBgNVBAMMC3Rlc3RjYTMub3JnMScwJQYDVQQKDB5Q\ -YXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDMwgZ8wDQYJKoZIhvcNAQEBBQAD\ -gY0AMIGJAoGBANzgVP99Qg98e6NsKEz1v5KqRB7NTBRRsYnBvb/TSWipvMQaCYuE\ -yk1xG57x++QuASKeR3QHRQJOoAhQaj9JLUhSSv9GQ5PrFLLsOFv7L1tpzXHh2dOB\ -IW92X2yFRW2s39q+Q21yvN+N8uoKdqXhzRA+dDoXh3cavaVeHX1G+IrlAgMBAAGj\ -EDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEASTwg84cX+1UhOG9s\ -ejFV3m34QuI1hPZ+qhqVJlRYUtego8Wng1BburDSwqVAv4ch2wi3c2s4e8J7AXyL\ -tzSbSQG4RN0oZi0mR8EtTTN+Mix/hBIk79dMZg85+I29uFA6Zj2d9oAhQv2qkHhc\ -6tcaheNvkQRlCyH68k3iF1Fqf+4KiAQwggIEMIIBbaADAgECAgECMA0GCSqGSIb3\ -DQEBCwUAMD8xFDASBgNVBAMMC3Rlc3RjYTEub3JnMScwJQYDVQQKDB5QYXltZW50\ -IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDEwHhcNMTMwMjIzMjI0MjI5WhcNMjMwMjIx\ -MjI0MjI5WjA/MRQwEgYDVQQDDAt0ZXN0Y2EyLm9yZzEnMCUGA1UECgweUGF5bWVu\ -dCBSZXF1ZXN0IEludGVybWVkaWF0ZSAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\ -iQKBgQDaV8zhfyQuSf/f+fauMfgs3g/RnWy9yxxUkvQneQQPH3uZzCyk3A6q72ip\ -TtwNqiibG9455L9A7SaUjGtnpUz0NKT/VWUdqbfCl1PqXjEZbDobbAQ5hxLGOTyL\ -RQhLIcgeq2/BnmeCqHsC4md04nUp+nBo1HwKyygvK+9sMbCp/wIDAQABoxAwDjAM\ -BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBACvYyE+PPmWFkbjyRu9LAt8D\ -crtyYYLRClKSg6tVvutwukLG2l//kDOohYkJtgTqr6LnCIIIwYdXN+4wxugmw4cn\ -PIZmP6kovxjhhVM95okilor1zniTAo3RN7JDIfTGNgxLdGu1btt7DOFL4zTbeSJM\ -b8M1JpPftehH+x/VLyuUCuoDMIIB5jCCAU+gAwIBAgIBBTANBgkqhkiG9w0BAQsF\ -ADAhMR8wHQYDVQQDExZQYXltZW50UmVxdWVzdCBUZXN0IENBMB4XDTEzMDIyMzIy\ -NDIyOFoXDTIzMDIyMTIyNDIyOFowPzEUMBIGA1UEAwwLdGVzdGNhMS5vcmcxJzAl\ -BgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgMTCBnzANBgkqhkiG\ -9w0BAQEFAAOBjQAwgYkCgYEAo5Vy9H3nA/OOkF5Ap89yfVNSiTay/LYCaB0eALpc\ -U690U75O9Q3w2M+2AN8wpbbHsJHZMIjEeBRoQfjlYXW1ucQTxWKyT+liu0D25mGX\ -X27CBXBd4iXTxVII/iX+u3lcjORjoHOBy7QgeIDIIS9y0vYu8eArpjh7m4thrVgI\ -RtMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQB9LKcV\ -JK9sjASNzpQlpUp7nCiw5FSjVY+XMRIKK/kavzlKjZ+InsmmyRVGjDoZi9GrqG9P\ -VHgLBxi2VtVjmokZoNPqao3OfhqORAubC+JR/JLepM7aDaxDdTHVhSUk4lgNAvi2\ -6dGY7nZMsnHlPQ2tPp/HvRRiMq1oDjlylc8VTCI2Eh8IsNsGEhl2qRSVYIoDyPul\ -6RMbTSzv4tVhVfGZqIisGLLhxYsFKg1Vbml0VGVzdFRocmVlKoABn2HTsUQtMNI4\ -yNvkfkFNka3pRvTUTydJrvyfmEeLzImfM1BWddZjnywku9RToNFZZNgow5QnljmF\ -chhR/aHOuEMTxmc12K4rNlgYtHCsxLP9zd+6u0cva3TucZ6EzS8PKEib/+r12/52\ -664NuWA9WtsK7QCFrK2K95PnVCRmWl0=\ -"; - -// -// Long chain, with an invalid (expired) cert in the middle -// -const char* paymentrequest4_BASE64 = -"\ -Egt4NTA5K3NoYTI1NhqeJAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\ -BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\ -dWVzdCBJbnRlcm1lZGlhdGUgODAeFw0xMzAyMjMyMjQyMzFaFw0yMzAyMjEyMjQy\ -MzFaMDYxGjAYBgNVBAMMEXRlc3RtZXJjaGFudDgub3JnMRgwFgYDVQQKDA9UZXN0\ -IE1lcmNoYW50IDgwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMMCHA3hiHbS\ -TKZ5K9jHRwE8NxkGp3IOx56PDB2diNkldG8XweTcRq7bBm7pdiBt4IVggtfs+6hE\ -hDYIOecyoAnVzPFTdvQ7KQdQ/fD9YLe6lk+o0edOqutPMyrxLFjSluXxEQyk7fdt\ -URloMMYfp3p1/hFCboA1rAsQ2RW38hR5AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w\ -DQYJKoZIhvcNAQELBQADgYEAPsdFatnc2RJSpvZsw+nCiPVsllycw5ELglq9vfJz\ -nJJucRxgzmqI2iuas1ugwbXn0BEIRLK7vMF/qBzQR6M/nTxttah+KEu+okjps9vJ\ -cIyhfTyGPC5xkHaHZ7sG+UHOFhPw0/kXn0x+pbVgBZ5315axqcp1R+DTSj/whMAr\ -n0AKiAQwggIEMIIBbaADAgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMM\ -C3Rlc3RjYTcub3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRp\ -YXRlIDcwHhcNMTMwMjIzMjI0MjMxWhcNMjMwMjIxMjI0MjMxWjA/MRQwEgYDVQQD\ -DAt0ZXN0Y2E4Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVk\ -aWF0ZSA4MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDexUFfxb1sThvabp7u\ -dZz59ciThGmmAW0nP4tjrgEACgvWIInr2dZpTHbiQNF34ycsk0le1JD93D7Qb8rd\ -25OrpaO8XS2Li2zjR9cleixXjSLwV/zv8zJ8yPl/27XL++PDTKBXVpJ8/Syp+9Ty\ -plV1BqDhqtIHb/QSHEkTQXjeYQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqG\ -SIb3DQEBCwUAA4GBACMooQVbkbIZ2DaPwHDc4ULwguG3VI2Kzj50UdExmHtzm2S4\ -MQei+n+HEPjtJAx5OY520+10nfuP+12H2DRLQmWmdvDpeQ/Cv0yavlw4ZRejRFo7\ -KS83C0wo5rd+qTvvOmAN4UTArWkzYcEUulPdiXnRamb0WQHTeVdIbHVkMormCogE\ -MIICBDCCAW2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0ZXN0\ -Y2E2Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSA2\ -MB4XDTEzMDIyMzIyNDIzMVoXDTIzMDIyMTIyNDIzMVowPzEUMBIGA1UEAwwLdGVz\ -dGNhNy5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUg\ -NzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtjBRazrkebXAhXsbjimrMIRm\ -W/f9SwAHwXfc042keNtl0t2z6XE6UPcR2v/KrssXuCZgodeYxz6IM6lWosCM1xot\ -C3ChKKFBfVO30reuKBRUxXfKAFqxaG0YOAEzdZkkY9AGhqWloeSmgxpIfhInU0EF\ -JjCwrJ6IkijBatGoAAECAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B\ -AQsFAAOBgQDBRTi1MolmOA0niHYX0A2lN5QWHkCfX0A7GwyoMA3dvM45m/NYd4WB\ -X+HwfnfYcI6X9jOgNo5OWmc4GGsld0HlxwMYEKISBS9PbSHPBrb3TBOlw5ztQpXZ\ -91+bOhLux52Fr03sK7v9qExmBM12M8UR2ltpzAMiUgLLMHyPfiWkvQqIBDCCAgQw\ -ggFtoAMCAQICAQIwDQYJKoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNhNS5v\ -cmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgNTAeFw0x\ -MzAyMjMyMjQyMzBaFw0yMzAyMjEyMjQyMzBaMD8xFDASBgNVBAMMC3Rlc3RjYTYu\ -b3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDYwgZ8w\ -DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANJSH3xivX1t9olIdHsznI1aE9SD7t9i\ -SZJsIB0otoETHZRVv9M9LvyzBNK98ZV+kTOlST7PJgC0d9BQM9sgYApSRq5oqKDM\ -9FXbOm/yaReAbU3mkFNFw5roTlJ5ThEy0yOGT/DS0YBRaGIvRPRj2DiqDVdCZZ+w\ -4jo1IYHkZt4FAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQAD\ -gYEATm6+J1OmbrothO60xALKonWMBKr6hudb4amkFBqKbA9wMeM3jl+I/yKfz/Uf\ -xWuJ071IhiNv6Gxx5YwNvhUe1xMhUqHv0gpyK1Z47bD+kYS2se5sWNPNo3Y9qZDG\ -IXiGQxwHmrzaFk79Uy1xsmvsEz42w6hr25Yaw7HkIgrFveoK6gMwggHmMIIBT6AD\ -AgECAgEGMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNVBAMTFlBheW1lbnRSZXF1ZXN0\ -IFRlc3QgQ0EwHhcNMTMwMjIzMjI1OTUxWhcNMTMwMjI0MjI1OTUxWjA/MRQwEgYD\ -VQQDDAt0ZXN0Y2E1Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVy\ -bWVkaWF0ZSA1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vVUFpxHzz2Tr\ -/xij3k58s8d/BPA0R6D5RXTVvmhAzc1Zuin4zUKRFs/aCj/0yED8Wu/COfNGF4tV\ -lRNMdl9EcFsxa8XGEL4eAZa+H/rOHH+7/1EINrrVWhZlUecyhilN8jmCZmqEM3ec\ -uD0NAViqyMrgmaiFmsLoQZpEGepDUQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0G\ -CSqGSIb3DQEBCwUAA4GBAEmcUEnhua/oiXy1fwScLgMqt+jk9mHRpE6SVsIop23Q\ -CY2JfpG6RxhMMzzzhGklEGN6cxG0HCi6B3HJx6PYrFEfTB0rW4K6m0Tvx3WpS9mN\ -uoEuJHLy18ausI/sYAPDHCL+SfBVcqorpaIG2sSpZouRBjRHAyqFAYlwlW87uq5n\ -CogEMIICBDCCAW2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0\ -ZXN0Y2EzLm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0\ -ZSAzMB4XDTEzMDIyMzIyNDIyOVoXDTIzMDIyMTIyNDIyOVowPzEUMBIGA1UEAwwL\ -dGVzdGNhNC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlh\ -dGUgNDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxYYo3w2UXiYg6O8b4Qgw\ -N/vgreTkiW122Ep/z2TiDrhVMhfOOiKdwYESPflfnXnVaQQzCGexYTQqsvqvzHSy\ -na5hL0zPTRJxSKmTVrXRsWtpdCRhjxCGipS3tlQBDi7vb+7SNRIBK4dBjjGzALNk\ -7gMCpy+yM8f6I043jTlmGb0CAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG\ -9w0BAQsFAAOBgQDU+IQxt3OhKqaUYWC23+cB2gekvWqwMBnrCNrX/Dp+kjoJKUoR\ -2Fs3qw53raHES4SIhpGT9l9lrppNQgFe/JMHeYqOZMZO+6kuU0olJanBJ14tPIc7\ -zlMTQ9OfmZ6v07IpyFbsQDtRhpe80DpuvSFPfJ4fh0WrQf6kn3KDVpGDnAqIBDCC\ -AgQwggFtoAMCAQICAQIwDQYJKoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNh\ -Mi5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgMjAe\ -Fw0xMzAyMjMyMjQyMjlaFw0yMzAyMjEyMjQyMjlaMD8xFDASBgNVBAMMC3Rlc3Rj\ -YTMub3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDMw\ -gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANzgVP99Qg98e6NsKEz1v5KqRB7N\ -TBRRsYnBvb/TSWipvMQaCYuEyk1xG57x++QuASKeR3QHRQJOoAhQaj9JLUhSSv9G\ -Q5PrFLLsOFv7L1tpzXHh2dOBIW92X2yFRW2s39q+Q21yvN+N8uoKdqXhzRA+dDoX\ -h3cavaVeHX1G+IrlAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL\ -BQADgYEASTwg84cX+1UhOG9sejFV3m34QuI1hPZ+qhqVJlRYUtego8Wng1BburDS\ -wqVAv4ch2wi3c2s4e8J7AXyLtzSbSQG4RN0oZi0mR8EtTTN+Mix/hBIk79dMZg85\ -+I29uFA6Zj2d9oAhQv2qkHhc6tcaheNvkQRlCyH68k3iF1Fqf+4KiAQwggIEMIIB\ -baADAgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMMC3Rlc3RjYTEub3Jn\ -MScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDEwHhcNMTMw\ -MjIzMjI0MjI5WhcNMjMwMjIxMjI0MjI5WjA/MRQwEgYDVQQDDAt0ZXN0Y2EyLm9y\ -ZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSAyMIGfMA0G\ -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDaV8zhfyQuSf/f+fauMfgs3g/RnWy9yxxU\ -kvQneQQPH3uZzCyk3A6q72ipTtwNqiibG9455L9A7SaUjGtnpUz0NKT/VWUdqbfC\ -l1PqXjEZbDobbAQ5hxLGOTyLRQhLIcgeq2/BnmeCqHsC4md04nUp+nBo1HwKyygv\ -K+9sMbCp/wIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GB\ -ACvYyE+PPmWFkbjyRu9LAt8DcrtyYYLRClKSg6tVvutwukLG2l//kDOohYkJtgTq\ -r6LnCIIIwYdXN+4wxugmw4cnPIZmP6kovxjhhVM95okilor1zniTAo3RN7JDIfTG\ -NgxLdGu1btt7DOFL4zTbeSJMb8M1JpPftehH+x/VLyuUCuoDMIIB5jCCAU+gAwIB\ -AgIBBTANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDExZQYXltZW50UmVxdWVzdCBU\ -ZXN0IENBMB4XDTEzMDIyMzIyNDIyOFoXDTIzMDIyMTIyNDIyOFowPzEUMBIGA1UE\ -AwwLdGVzdGNhMS5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1l\ -ZGlhdGUgMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo5Vy9H3nA/OOkF5A\ -p89yfVNSiTay/LYCaB0eALpcU690U75O9Q3w2M+2AN8wpbbHsJHZMIjEeBRoQfjl\ -YXW1ucQTxWKyT+liu0D25mGXX27CBXBd4iXTxVII/iX+u3lcjORjoHOBy7QgeIDI\ -IS9y0vYu8eArpjh7m4thrVgIRtMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkq\ -hkiG9w0BAQsFAAOBgQB9LKcVJK9sjASNzpQlpUp7nCiw5FSjVY+XMRIKK/kavzlK\ -jZ+InsmmyRVGjDoZi9GrqG9PVHgLBxi2VtVjmokZoNPqao3OfhqORAubC+JR/JLe\ -pM7aDaxDdTHVhSUk4lgNAvi26dGY7nZMsnHlPQ2tPp/HvRRiMq1oDjlylc8VTCI1\ -Eh8IsNsGEhl2qRSVYIoDyPul6RMbTSzv4tVhVfGZqIisGLLhxYsFKgxVbml0VGVz\ -dEZvdXIqgAEBE1PP93Tkpif35F+dYmXn9kLA/1djcPjCs2o2rwRMM4Uk356O5dgu\ -HXQjsfdR58qZQS9CS5DAtRUf0R8+43/wijO/hb49VNaNXmY+/cPHMkahP2aV3tZi\ -FAyZblLik9A7ZvF+UsjeFQiHB5wzWQvbqk5wQ4yabHIXoYv/E0q+eQ==\ -"; - -const char* paymentrequest5_BASE64 = -"\ -Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\ -BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzA0MTkx\ -NzIwMDZaFw0yMzA0MTcxNzIwMDZaMEMxGTAXBgNVBAMMEHRlc3RtZXJjaGFudC5v\ -cmcxJjAkBgNVBAoMHVBheW1lbnQgUmVxdWVzdCBUZXN0IE1lcmNoYW50MIGfMA0G\ -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhV6Yn47aEEmbl50YLvXoqGEJA51I/40wr\ -Z6VQGdXYaRqYktagrWDlgYY9h0JQ1bQhm8HgW7ju0R4NaDTXUqxg4HjprF0z3Mfm\ -/6mmebkLOOptfkVD7ceAteNI7cyuqWGIAZA7D9mV97mXoCAtTlBUycvkmoiClCCS\ -h0EpF/UTaQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GB\ -AGIRwW7I0QvLga+RnJoJSZNZQbtu4rQW3xmoz8WfZMBYXX3QBYg5ftycbdK+/IbP\ -qozfjGW2AS6DNArvpveSPDTK9+GJBNo1paiNtVqwXkC3Ddscv5AIms1eZGiIOQNC\ -mUvdLkpoXo48WAer3EGsZ3B15GyNEELc0q9W5yUebba1IjUSHwiw2wYSGXapFJVg\ -igPI+6XpExtNLO/i1WFV8ZmoiKwYuPvFiwUqDFVuaXRUZXN0Rml2ZSqAAXdsMgdG\ -ssymvca1S/1KeM3n8Ydi2fi1JUzAAr59xPvNJRUeqCLP9upHn5z7br3P12Oz9A20\ -5/4wL4ClPRPVnOHgij0bEg+y0tGESqmF1rfOfXDszlo2U92wCxS07kq79YAZJ1Zo\ -XYh860/Q4wvc7lfiTe+dXBzPKAKhMy91yETY\ -"; diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp deleted file mode 100644 index 7cd5a857e9..0000000000 --- a/src/qt/test/paymentservertests.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "paymentservertests.h" - -#include "optionsmodel.h" -#include "paymentrequestdata.h" - -#include "random.h" -#include "util.h" -#include "utilstrencodings.h" - -#include -#include - -#include -#include - -X509 *parse_b64der_cert(const char* cert_data) -{ - std::vector data = DecodeBase64(cert_data); - assert(data.size() > 0); - const unsigned char* dptr = &data[0]; - X509 *cert = d2i_X509(NULL, &dptr, data.size()); - assert(cert); - return cert; -} - -// -// Test payment request handling -// - -static SendCoinsRecipient handleRequest(PaymentServer* server, std::vector& data) -{ - RecipientCatcher sigCatcher; - QObject::connect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), - &sigCatcher, SLOT(getRecipient(SendCoinsRecipient))); - - // Write data to a temp file: - QTemporaryFile f; - f.open(); - f.write((const char*)&data[0], data.size()); - f.close(); - - // Create a QObject, install event filter from PaymentServer - // and send a file open event to the object - QObject object; - object.installEventFilter(server); - QFileOpenEvent event(f.fileName()); - // If sending the event fails, this will cause sigCatcher to be empty, - // which will lead to a test failure anyway. - QCoreApplication::sendEvent(&object, &event); - - QObject::disconnect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), - &sigCatcher, SLOT(getRecipient(SendCoinsRecipient))); - - // Return results from sigCatcher - return sigCatcher.recipient; -} - -void PaymentServerTests::paymentServerTests() -{ - SelectParams(CBaseChainParams::MAIN); - OptionsModel optionsModel; - PaymentServer* server = new PaymentServer(NULL, false); - X509_STORE* caStore = X509_STORE_new(); - X509_STORE_add_cert(caStore, parse_b64der_cert(caCert_BASE64)); - PaymentServer::LoadRootCAs(caStore); - server->setOptionsModel(&optionsModel); - server->uiReady(); - - // Now feed PaymentRequests to server, and observe signals it produces: - std::vector data = DecodeBase64(paymentrequest1_BASE64); - SendCoinsRecipient r = handleRequest(server, data); - QString merchant; - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("testmerchant.org")); - - // Version of the above, with an expired certificate: - data = DecodeBase64(paymentrequest2_BASE64); - r = handleRequest(server, data); - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("")); - - // Long certificate chain: - data = DecodeBase64(paymentrequest3_BASE64); - r = handleRequest(server, data); - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("testmerchant8.org")); - - // Long certificate chain, with an expired certificate in the middle: - data = DecodeBase64(paymentrequest4_BASE64); - r = handleRequest(server, data); - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("")); - - // Validly signed, but by a CA not in our root CA list: - data = DecodeBase64(paymentrequest5_BASE64); - r = handleRequest(server, data); - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("")); - - // Try again with no root CA's, verifiedMerchant should be empty: - caStore = X509_STORE_new(); - PaymentServer::LoadRootCAs(caStore); - data = DecodeBase64(paymentrequest1_BASE64); - r = handleRequest(server, data); - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("")); - - unsigned long lDoSProtectionTrigger = (unsigned long) BIP70_MAX_PAYMENTREQUEST_SIZE + 1; - std::string randData(lDoSProtectionTrigger, '\0'); - unsigned char* buff = reinterpret_cast(&randData[0]); - - // Just get some random data big enough to trigger BIP70 DoS protection - // unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1]; - // GetRandBytes(randData, sizeof(randData)); - GetRandBytes(buff, sizeof(buff)); - // Write data to a temp file: - QTemporaryFile tempFile; - tempFile.open(); - tempFile.write((const char*)buff, sizeof(buff)); - tempFile.close(); - // Trigger BIP70 DoS protection - QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false); - - delete server; -} - -void RecipientCatcher::getRecipient(SendCoinsRecipient r) -{ - recipient = r; -} diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h deleted file mode 100644 index b56ad66fbe..0000000000 --- a/src/qt/test/paymentservertests.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H -#define BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H - -#include "../paymentserver.h" - -#include -#include - -class PaymentServerTests : public QObject -{ - Q_OBJECT - -private Q_SLOTS: - void paymentServerTests(); -}; - -// Dummy class to receive paymentserver signals. -// If SendCoinsRecipient was a proper QObject, then -// we could use QSignalSpy... but it's not. -class RecipientCatcher : public QObject -{ - Q_OBJECT - -public Q_SLOTS: - void getRecipient(SendCoinsRecipient r); - -public: - SendCoinsRecipient recipient; -}; - -#endif // BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index bc4f4ad87e..fc2cbc2712 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -12,10 +12,6 @@ #include "util.h" #include "uritests.h" -#ifdef ENABLE_WALLET -#include "paymentservertests.h" -#endif - #include #include #include @@ -54,11 +50,6 @@ int main(int argc, char *argv[]) URITests test1; if (QTest::qExec(&test1) != 0) fInvalid = true; -#ifdef ENABLE_WALLET - PaymentServerTests test2; - if (QTest::qExec(&test2) != 0) - fInvalid = true; -#endif return fInvalid; } diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 2b752a73f1..aa0dad2a82 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -261,19 +261,6 @@ QString TransactionDesc::toHTML(CWallet* wallet, CWalletTx& wtx, TransactionReco if (r.first == "Message") strHTML += "
" + tr("Message") + ":
" + GUIUtil::HtmlEscape(r.second, true) + "
"; - // - // PaymentRequest info: - // - Q_FOREACH (const PAIRTYPE(std::string, std::string) & r, wtx.vOrderForm) { - if (r.first == "PaymentRequest") { - PaymentRequestPlus req; - req.parse(QByteArray::fromRawData(r.second.data(), r.second.size())); - QString merchant; - if (req.getMerchant(PaymentServer::getCertStore(), merchant)) - strHTML += "" + tr("Merchant") + ": " + GUIUtil::HtmlEscape(merchant) + "
"; - } - } - if (wtx.IsCoinBase()) { quint32 numBlocksToMaturity = Params().COINBASE_MATURITY() + 1; strHTML += "
" + tr("Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.").arg(QString::number(numBlocksToMaturity)) + "
"; diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 67d604b00a..78ee02f1d1 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -80,7 +80,6 @@ HelpMessageDialog::HelpMessageDialog(QWidget* parent, bool about) : QDialog(pare strUsage += HelpMessageOpt("-choosedatadir", strprintf(tr("Choose data directory on startup (default: %u)").toStdString(), DEFAULT_CHOOSE_DATADIR)); strUsage += HelpMessageOpt("-lang=", tr("Set language, for example \"de_DE\" (default: system locale)").toStdString()); strUsage += HelpMessageOpt("-min", tr("Start minimized").toStdString()); - strUsage += HelpMessageOpt("-rootcertificates=", tr("Set SSL root certificates for payment request (default: -system-)").toStdString()); strUsage += HelpMessageOpt("-splash", strprintf(tr("Show splash screen on startup (default: %u)").toStdString(), DEFAULT_SPLASHSCREEN)); QString coreOptions = QString::fromStdString(strUsage); text = version + "\n" + header + "\n" + coreOptions; diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index c11fb20fb5..4cce4a0278 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -285,22 +285,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact // Pre-check input data for validity Q_FOREACH (const SendCoinsRecipient& rcp, recipients) { - if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... - CAmount subtotal = 0; - const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); - for (int i = 0; i < details.outputs_size(); i++) { - const payments::Output& out = details.outputs(i); - if (out.amount() <= 0) continue; - subtotal += out.amount(); - const unsigned char* scriptStr = (const unsigned char*)out.script().data(); - CScript scriptPubKey(scriptStr, scriptStr + out.script().size()); - vecSend.push_back(std::pair(scriptPubKey, out.amount())); - } - if (subtotal <= 0) { - return InvalidAmount; - } - total += subtotal; - } else { // User-entered prcycoin address / amount: + { // User-entered prcycoin address / amount: if (!validateAddress(rcp.address)) { return InvalidAddress; } diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 204acd8d59..e9449f0871 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -5,12 +5,16 @@ #ifndef BITCOIN_QT_WALLETMODEL_H #define BITCOIN_QT_WALLETMODEL_H +#if defined(HAVE_CONFIG_H) +#include "config/prcycoin-config.h" +#endif + #include "askpassphrasedialog.h" -#include "paymentrequestplus.h" #include "walletmodeltransaction.h" #include "allocators.h" /* for SecureString */ #include "guiutil.h" +#include "key.h" #include "swifttx.h" #include "wallet/wallet.h" #include "init.h" @@ -58,8 +62,8 @@ class SendCoinsRecipient // If from a payment request, this is used for storing the memo QString message; - // If from a payment request, paymentRequest.IsInitialized() will be true - PaymentRequestPlus paymentRequest; + // serialized string to ensure load/store is lossless + std::string sPaymentRequest{}; // Empty if no authentication or invalid signature/cert/etc. QString authenticatedMerchant; @@ -74,9 +78,6 @@ class SendCoinsRecipient std::string sAddress = address.toStdString(); std::string sLabel = label.toStdString(); std::string sMessage = message.toStdString(); - std::string sPaymentRequest; - if (!ser_action.ForRead() && paymentRequest.IsInitialized()) - paymentRequest.SerializeToString(&sPaymentRequest); std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString(); READWRITE(this->nVersion); @@ -92,8 +93,6 @@ class SendCoinsRecipient address = QString::fromStdString(sAddress); label = QString::fromStdString(sLabel); message = QString::fromStdString(sMessage); - if (!sPaymentRequest.empty()) - paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size())); authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant); } } diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index 83eb6cbfbf..dc699e822f 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -7,6 +7,9 @@ #include "walletmodel.h" +#include "amount.h" +#include "primitives/transaction.h" + #include class SendCoinsRecipient; From 4c23f1341d616c67971ecd39149d6e65f35d7500 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 17 Mar 2023 11:43:09 -0400 Subject: [PATCH 005/391] GUI: remove payment request file handling from OpenURI dialog --- src/qt/forms/openuridialog.ui | 15 +-------------- src/qt/openuridialog.cpp | 9 --------- src/qt/openuridialog.h | 3 --- src/qt/paymentserver.cpp | 3 +-- 4 files changed, 2 insertions(+), 28 deletions(-) diff --git a/src/qt/forms/openuridialog.ui b/src/qt/forms/openuridialog.ui index 114a363943..b202df6f6b 100644 --- a/src/qt/forms/openuridialog.ui +++ b/src/qt/forms/openuridialog.ui @@ -17,7 +17,7 @@ - Open payment request from URI or file + Open PRCYcoin URI @@ -33,19 +33,6 @@ - - - - Select payment request file - - - ... - - - false - - - diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index 815a585125..2bc91a3d9a 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -40,12 +40,3 @@ void OpenURIDialog::accept() ui->uriEdit->setValid(false); } } - -void OpenURIDialog::on_selectFileButton_clicked() -{ - QString filename = GUIUtil::getOpenFileName(this, tr("Select payment request file to open"), "", "", NULL); - if (filename.isEmpty()) - return; - QUrl fileUri = QUrl::fromLocalFile(filename); - ui->uriEdit->setText("prcycoin:?r=" + QUrl::toPercentEncoding(fileUri.toString())); -} diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index c3fc32a95b..6e5e172c8d 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -25,9 +25,6 @@ class OpenURIDialog : public QDialog protected Q_SLOTS: void accept(); -private Q_SLOTS: - void on_selectFileButton_clicked(); - private: Ui::OpenURIDialog* ui; }; diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index f8f9712adb..8150008eb2 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -173,8 +173,7 @@ PaymentServer::~PaymentServer() } // -// OSX-specific way of handling prcycoin: URIs and -// PaymentRequest mime types +// OSX-specific way of handling prcycoin: URIs // bool PaymentServer::eventFilter(QObject* object, QEvent* event) { From 20a76ebf1b7522b9b557a334adb77e9cbd7df5f5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 17 Mar 2023 11:45:39 -0400 Subject: [PATCH 006/391] build: remove BIP70 entries from macOS Info.plist --- share/qt/Info.plist.in | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 22e6ed6095..4de8eb420e 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -54,43 +54,6 @@ - UTExportedTypeDeclarations - - - UTTypeIdentifier - io.prcycoin.paymentrequest - UTTypeDescription - Prcycoin payment request - UTTypeConformsTo - - public.data - - UTTypeTagSpecification - - public.mime-type - application/x-prcycoin-payment-request - public.filename-extension - - prcycoinpaymentrequest - - - - - - CFBundleDocumentTypes - - - CFBundleTypeRole - Editor - LSItemContentTypes - - io.prcycoin.paymentrequest - - LSHandlerRank - Owner - - - NSPrincipalClass NSApplication From bc5893fb96f59296aafeaaca9008712028716373 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 17 Mar 2023 11:47:16 -0400 Subject: [PATCH 007/391] compat: remove bswap_* check on macOS This was originally added in https://github.com/bitcoin/bitcoin/pull/9366 to fix the gui build, as Protobuf would also define these macros. Now that we're no-longer using Protobuf, remove the additional check. --- src/compat/byteswap.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/compat/byteswap.h b/src/compat/byteswap.h index 92a4f91ed1..c09778a99f 100644 --- a/src/compat/byteswap.h +++ b/src/compat/byteswap.h @@ -17,20 +17,13 @@ #if defined(MAC_OSX) -#if !defined(bswap_16) - -// Mac OS X / Darwin features; we include a check for bswap_16 because if it is already defined, protobuf has -// defined these macros for us already; if it isn't, we do it ourselves. In either case, we get the exact same -// result regardless which path was taken #include #define bswap_16(x) OSSwapInt16(x) #define bswap_32(x) OSSwapInt32(x) #define bswap_64(x) OSSwapInt64(x) -#endif // !defined(bswap_16) - #else -// Non-Mac OS X / non-Darwin +// Non-MacOS / non-Darwin #if HAVE_DECL_BSWAP_16 == 0 inline uint16_t bswap_16(uint16_t x) From f49a8e16cf53deb9c3e4ddb7b54e30f435e0184c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 17 Mar 2023 11:49:58 -0400 Subject: [PATCH 008/391] Remove remaining references to BIP70 --- doc/REST-interface.md | 2 +- src/chainparams.h | 2 +- src/qt/networkstyle.h | 2 +- src/rpc/blockchain.cpp | 2 +- src/rpc/mining.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/REST-interface.md b/doc/REST-interface.md index ddb3cbe37b..418fcf9f5e 100644 --- a/doc/REST-interface.md +++ b/doc/REST-interface.md @@ -33,7 +33,7 @@ Given a block hash: returns amount of blockheaders in upward direction. Returns various state info regarding block chain processing. Only supports JSON as output format. -* chain : (string) current network name as defined in BIP70 (main, test, regtest) +* chain : (string) current network name (main, test, regtest) * blocks : (numeric) the current number of blocks processed in the server * headers : (numeric) the current number of headers we have validated * bestblockhash : (string) the hash of the currently best block diff --git a/src/chainparams.h b/src/chainparams.h index f983ed9dd1..4451258962 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -91,7 +91,7 @@ class CChainParams bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** In the future use NetworkIDString() for RPC fields */ bool TestnetToBeDeprecatedFieldRPC() const { return fTestnetToBeDeprecatedFieldRPC; } - /** Return the BIP70 network string (main, test or regtest) */ + /** Return the network string */ std::string NetworkIDString() const { return strNetworkID; } const std::vector& DNSSeeds() const { return vSeeds; } const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } diff --git a/src/qt/networkstyle.h b/src/qt/networkstyle.h index 2533755f9b..f346cdcf27 100644 --- a/src/qt/networkstyle.h +++ b/src/qt/networkstyle.h @@ -13,7 +13,7 @@ class NetworkStyle { public: - /** Get style associated with provided BIP70 network id, or 0 if not known */ + /** Get style associated with provided network id, or 0 if not known */ static const NetworkStyle* instantiate(const QString& networkId); const QString& getAppName() const { return appName; } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index cfe508aeee..a0e4aec12e 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -772,7 +772,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) "Returns an object containing various state info regarding block chain processing.\n" "\nResult:\n" "{\n" - " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" + " \"chain\": \"xxxx\", (string) current network name (main, test, regtest)\n" " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n" " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n" diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 1f2b705359..f22293d9b0 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -327,7 +327,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) " \"hashespersec\": n (numeric) The hashes per second of the generation, or 0 if no generation.\n" " \"pooledtx\": n (numeric) The size of the mem pool\n" " \"testnet\": true|false (boolean) If using testnet or not\n" - " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" + " \"chain\": \"xxxx\", (string) current network name (main, test, regtest)\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmininginfo", "") + HelpExampleRpc("getmininginfo", "")); From a7b45d5307c2bd51e16539bd4754241068471bd7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 15 Mar 2023 15:42:33 -0400 Subject: [PATCH 009/391] Add Height check in AcceptBlock for multiple stake inputs --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 6c702f2b18..4f3363a198 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4716,7 +4716,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, CTransaction &stakeTxIn = block.vtx[1]; // Only one input is allowed - if (stakeTxIn.vin.size() > 1) + if (stakeTxIn.vin.size() > 1 && nHeight > Params().FixChecks()) return state.DoS(100, error("%s : multiple stake inputs not allowed", __func__), REJECT_INVALID, "bad-txns-stake"); // Inputs From edc50da9f1dfc9c02d7f050a53eaf8839cdaec90 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 13:44:54 -0400 Subject: [PATCH 010/391] windows: Set _WIN32_WINNT to 0x0601 (Windows 7) Also remove all defines in many places and define it in configure stage to keep consistency. --- configure.ac | 2 +- src/allocators.cpp | 4 ---- src/compat.h | 4 ---- src/qt/guiutil.cpp | 4 ---- src/util.cpp | 5 ----- 5 files changed, 1 insertion(+), 18 deletions(-) diff --git a/configure.ac b/configure.ac index f863f9b44f..21b5b91789 100644 --- a/configure.ac +++ b/configure.ac @@ -485,7 +485,7 @@ case $host in AC_MSG_ERROR("windres not found") fi - CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB" + CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601" LEVELDB_TARGET_FLAGS="-DOS_WINDOWS" if test "x$CXXFLAGS_overridden" = "xno"; then CXXFLAGS="$CXXFLAGS -w" diff --git a/src/allocators.cpp b/src/allocators.cpp index df498f7eae..754317c748 100644 --- a/src/allocators.cpp +++ b/src/allocators.cpp @@ -5,10 +5,6 @@ #include "allocators.h" #ifdef WIN32 -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0501 #define WIN32_LEAN_AND_MEAN 1 #ifndef NOMINMAX #define NOMINMAX diff --git a/src/compat.h b/src/compat.h index 6fbefd772b..822a61340c 100644 --- a/src/compat.h +++ b/src/compat.h @@ -11,10 +11,6 @@ #endif #ifdef WIN32 -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0501 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index ba5aaf1463..efdbad85fd 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -21,10 +21,6 @@ #include "util.h" #ifdef WIN32 -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0501 #ifdef _WIN32_IE #undef _WIN32_IE #endif diff --git a/src/util.cpp b/src/util.cpp index f4b67e23ff..caac3df622 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -56,11 +56,6 @@ #pragma warning(disable : 4717) #endif -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0501 - #ifdef _WIN32_IE #undef _WIN32_IE #endif From 40ad3747714cc0d5ff8acd66647b8da3092e0c36 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 13:46:03 -0400 Subject: [PATCH 011/391] windows: Call SetProcessDEPPolicy directly --- src/init.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 408adad708..6d8fc55df2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -774,16 +774,7 @@ bool AppInitBasicSetup() #endif #ifdef WIN32 // Enable Data Execution Prevention (DEP) -// Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008 -// A failure is non-critical and needs no further attention! -#ifndef PROCESS_DEP_ENABLE -// We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7), -// which is not correct. Can be removed, when GCCs winbase.h is fixed! -#define PROCESS_DEP_ENABLE 0x00000001 -#endif - typedef BOOL(WINAPI * PSETPROCDEPPOL)(DWORD); - PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); - if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); + SetProcessDEPPolicy(PROCESS_DEP_ENABLE); #endif if (!SetupNetworking()) From c72b74c7d474fcb501e8d6d12bd476442f651a93 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 13:47:43 -0400 Subject: [PATCH 012/391] Drop defunct Windows compat fixes "The AI_ADDRCONFIG flag is defined on the Windows SDK for Windows Vista and later. The AI_ADDRCONFIG flag is supported on Windows Vista and later." https://docs.microsoft.com/en-us/windows/desktop/api/ws2tcpip/nf-ws2tcpip-getaddrinfo However, the version of MinGW we use on Travis is not current and does not carry the relevant definition, as such I defined it in compat. https://github.com/wine-mirror/wine/blob/master/include/ws2tcpip.h Testing confirms that the PROTECTION_LEVEL_UNRESTRICTED, IPV6_PROTECTION_LEVEL, PROCESS_DEP_ENABLE, AI_ADDRCONFIG, are now supported by the version of Windows that we test against, so can be removed. --- src/net.cpp | 12 ------------ src/netbase.cpp | 4 ---- 2 files changed, 16 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 23b4f72a6a..135c7ef774 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -50,18 +50,6 @@ #define MSG_NOSIGNAL 0 #endif -// Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h. -// Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version. -#ifdef WIN32 -#ifndef PROTECTION_LEVEL_UNRESTRICTED -#define PROTECTION_LEVEL_UNRESTRICTED 10 -#endif -#ifndef IPV6_PROTECTION_LEVEL -#define IPV6_PROTECTION_LEVEL 23 -#endif -#endif - - namespace { const int MAX_OUTBOUND_CONNECTIONS = 16; const int MAX_FEELER_CONNECTIONS = 1; diff --git a/src/netbase.cpp b/src/netbase.cpp index 24319659ae..53f5df6965 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -130,11 +130,7 @@ bool static LookupIntern(const char* pszName, std::vector& vIP, unsign aiHint.ai_socktype = SOCK_STREAM; aiHint.ai_protocol = IPPROTO_TCP; aiHint.ai_family = AF_UNSPEC; -#ifdef WIN32 - aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST; -#else aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; -#endif struct addrinfo* aiRes = NULL; #ifdef HAVE_GETADDRINFO_A From b218592a988e15d2efe334814537dc82d80990ab Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 14:08:28 -0400 Subject: [PATCH 013/391] depends: Build secondary deps statically. --- depends/packages/expat.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index a0c1e2d766..531965b28d 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -5,7 +5,8 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=17b43c2716d521369f82fc2dc70f359860e90fa440bea65b3b85f0b246ea81f2 define $(package)_set_vars - $(package)_config_opts=--disable-static --without-docbook + $(package)_config_opts=--disable-shared --without-docbook + $(package)_config_opts_linux=--with-pic endef define $(package)_config_cmds From 52f8d61cfceb0777d13612305665bec5479b034f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 14:12:08 -0400 Subject: [PATCH 014/391] depends: Purge libtool archives We use pkg-config where we can, which generally replaces libtool at a higher level and does not have the same downsides as libtool. These archives sit in our depends tree with no purpose and pollute the final bitcoin build with massive overlinking. --- depends/packages.md | 12 ++++++++++++ depends/packages/expat.mk | 4 ++++ depends/packages/fontconfig.mk | 4 ++++ depends/packages/freetype.mk | 4 ++++ depends/packages/libXau.mk | 4 ++++ depends/packages/libevent.mk | 1 + depends/packages/libxcb.mk | 2 +- depends/packages/qrencode.mk | 4 ++++ depends/packages/zeromq.mk | 2 +- 9 files changed, 35 insertions(+), 2 deletions(-) diff --git a/depends/packages.md b/depends/packages.md index 51ce968355..955a6be7a0 100644 --- a/depends/packages.md +++ b/depends/packages.md @@ -151,6 +151,18 @@ Most autotools projects can be properly staged using: $(MAKE) DESTDIR=$($(package)_staging_dir) install +## Build outputs: + +In general, the output of a depends package should not contain any libtool +archives. Instead, the package should output `.pc` (`pkg-config`) files where +possible. + +From the [Gentoo Wiki entry](https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Handling_Libtool_Archives): + +> Libtool pulls in all direct and indirect dependencies into the .la files it +> creates. This leads to massive overlinking, which is toxic to the Gentoo +> ecosystem, as it leads to a massive number of unnecessary rebuilds. + ## Secondary dependencies: Secondary dependency packages relative to the bitcoin binaries/libraries (i.e. diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 531965b28d..b811f84a38 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -20,3 +20,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk index 416e5c0a75..efa253f9a9 100644 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -26,3 +26,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk index a98e82ed16..f24fc69d81 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -20,3 +20,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index ce42140689..0e4a60ad25 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -25,3 +25,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index ae1a0b4478..1cd5a1749a 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -35,4 +35,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds + rm lib/*.la endef diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 961cb86c95..90bc15f9f4 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -44,5 +44,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf share/man share/doc + rm -rf share/man share/doc lib/*.la endef diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index f81fb100be..7cc8d924d2 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -25,3 +25,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 9eae1a816e..e54868005f 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -30,5 +30,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf bin share + rm -rf bin share lib/*.la endef From 57935e70513d9060ac38b9813487bf2fb52d025a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 14:42:16 -0400 Subject: [PATCH 015/391] depends: libXext: Bump to 1.3.3 to fix _XEatDataWords --- depends/packages/libXau.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index 0e4a60ad25..058416f793 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -5,8 +5,10 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=fdd477320aeb5cdd67272838722d6b7d544887dfe7de46e1e7cc0c27c2bea4f2 $(package)_dependencies=xproto +# When updating this package, check the default value of +# --disable-xthreads. It is currently enabled. define $(package)_set_vars - $(package)_config_opts=--disable-shared + $(package)_config_opts=--disable-shared --disable-lint-library --without-lint $(package)_config_opts_linux=--with-pic endef From 22136601a5d777a90d6cd23716a6390579650649 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 14:42:56 -0400 Subject: [PATCH 016/391] depends: libxcb: configure flags cleanup --- depends/packages/libxcb.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 90bc15f9f4..5805f8b5c3 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c $(package)_dependencies=xcb_proto libXau define $(package)_set_vars -$(package)_config_opts=--disable-static +$(package)_config_opts= --disable-build-docs --without-doxygen --without-launchd # Because we pass -qt-xcb to Qt, it will compile in a set of xcb helper libraries and extensions, # so we skip building all of the extensions here. # More info is available from: https://doc.qt.io/qt-5.9/linux-requirements.html From 02e90b2819dbcfa6aab50ae5d9607312debbfe08 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 14:43:20 -0400 Subject: [PATCH 017/391] depends: fontconfig: configure flags cleanup --- depends/packages/fontconfig.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk index efa253f9a9..c4f11d8dd0 100644 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -7,7 +7,7 @@ $(package)_dependencies=freetype expat $(package)_patches=remove_char_width_usage.patch gperf_header_regen.patch define $(package)_set_vars - $(package)_config_opts=--disable-docs --disable-static + $(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv endef define $(package)_preprocess_cmds From fa6ac32145288f3e5ec5ea897b1f55e332e5f7aa Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 14:44:07 -0400 Subject: [PATCH 018/391] depends: qrencode: configure flags cleanup This also fixes passing --without-tools --- depends/packages/qrencode.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index 7cc8d924d2..eed2bcd980 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -5,7 +5,8 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=efe5188b1ddbcbf98763b819b146be6a90481aac30cfc8d858ab78a19cde1fa5 define $(package)_set_vars -$(package)_config_opts=--disable-shared -without-tools --disable-sdltest +$(package)_config_opts=--disable-shared --without-tools --without-tests --disable-sdltest +$(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap $(package)_config_opts_linux=--with-pic $(package)_config_opts_android=--with-pic endef From e0c917ac8fb11cfcd901cad2fdcde57ee67e0a16 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 14:44:41 -0400 Subject: [PATCH 019/391] depends: xproto: configure flags cleanup --- depends/packages/xproto.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk index 23ad5ffa10..2462f3c647 100644 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -5,7 +5,7 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=636162c1759805a5a0114a369dffdeccb8af8c859ef6e1445f26a4e6e046514f define $(package)_set_vars -$(package)_config_opts=--disable-shared +$(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs endef define $(package)_preprocess_cmds From 29c7226e76de62e270de342db86f36564814a6fd Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 14:46:11 -0400 Subject: [PATCH 020/391] depends: zeromq: disable draft classes and methods --- depends/packages/zeromq.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index e54868005f..a424a30a3c 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -6,7 +6,9 @@ $(package)_sha256_hash=bcbabe1e2c7d0eec4ed612e10b94b112dd5f06fcefa994a0c79a45d83 $(package)_patches=remove_libstd_link.patch define $(package)_set_vars - $(package)_config_opts=--without-docs --disable-shared --without-libsodium --disable-curve --disable-curve-keygen --disable-perf --disable-Werror + $(package)_config_opts=--without-docs --disable-shared --disable-curve --disable-curve-keygen --disable-perf --disable-Werror --disable-drafts + $(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci + $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov $(package)_config_opts_linux=--with-pic $(package)_config_opts_android=--with-pic $(package)_cxxflags=-std=c++17 From 831d73091c5d66b2005fd37ca4e729ceb2d25367 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 15:03:17 -0400 Subject: [PATCH 021/391] Move Win32 defines to configure.ac to ensure they are globally defined --- configure.ac | 2 +- src/allocators.cpp | 1 - src/compat.h | 3 --- src/qt/guiutil.cpp | 5 ----- src/util.cpp | 6 ------ 5 files changed, 1 insertion(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index 21b5b91789..9f7217c6c0 100644 --- a/configure.ac +++ b/configure.ac @@ -485,7 +485,7 @@ case $host in AC_MSG_ERROR("windres not found") fi - CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601" + CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN" LEVELDB_TARGET_FLAGS="-DOS_WINDOWS" if test "x$CXXFLAGS_overridden" = "xno"; then CXXFLAGS="$CXXFLAGS -w" diff --git a/src/allocators.cpp b/src/allocators.cpp index 754317c748..15b72f1447 100644 --- a/src/allocators.cpp +++ b/src/allocators.cpp @@ -5,7 +5,6 @@ #include "allocators.h" #ifdef WIN32 -#define WIN32_LEAN_AND_MEAN 1 #ifndef NOMINMAX #define NOMINMAX #endif diff --git a/src/compat.h b/src/compat.h index 822a61340c..54c4f980a8 100644 --- a/src/compat.h +++ b/src/compat.h @@ -11,9 +11,6 @@ #endif #ifdef WIN32 -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 -#endif #ifndef NOMINMAX #define NOMINMAX #endif diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index efdbad85fd..d926259017 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -21,11 +21,6 @@ #include "util.h" #ifdef WIN32 -#ifdef _WIN32_IE -#undef _WIN32_IE -#endif -#define _WIN32_IE 0x0501 -#define WIN32_LEAN_AND_MEAN 1 #ifndef NOMINMAX #define NOMINMAX #endif diff --git a/src/util.cpp b/src/util.cpp index caac3df622..0587df1d04 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -56,12 +56,6 @@ #pragma warning(disable : 4717) #endif -#ifdef _WIN32_IE -#undef _WIN32_IE -#endif -#define _WIN32_IE 0x0501 - -#define WIN32_LEAN_AND_MEAN 1 #ifndef NOMINMAX #define NOMINMAX #endif From 19a3b864068f6512170096e7e8099e0a2c1946c8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 15:20:59 -0400 Subject: [PATCH 022/391] build: Set minimum Automake version to 1.13 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 21b5b91789..62c5ac015c 100644 --- a/configure.ac +++ b/configure.ac @@ -34,14 +34,14 @@ dnl faketime breaks configure and is only needed for make. Disable it here. unset FAKETIME dnl Automake init set-up and checks -AM_INIT_AUTOMAKE([no-define subdir-objects foreign]) +AM_INIT_AUTOMAKE([1.13 no-define subdir-objects foreign]) dnl faketime messes with timestamps and causes configure to be re-run. dnl --disable-maintainer-mode can be used to bypass this. AM_MAINTAINER_MODE([enable]) dnl make the compilation flags quiet unless V=1 is used -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +AM_SILENT_RULES([yes]) dnl Compiler checks (here before libtool). if test "x${CXXFLAGS+set}" = "xset"; then From b3a55747c55ad0438137f7591eff03f5ece1701f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 15:32:06 -0400 Subject: [PATCH 023/391] build: Set libevent minimum version to 2.0.21 --- configure.ac | 4 ++-- doc/dependencies.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 21b5b91789..c7637298aa 100644 --- a/configure.ac +++ b/configure.ac @@ -1007,9 +1007,9 @@ if test x$use_pkgconfig = xyes; then BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) fi if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then - PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)]) + PKG_CHECK_MODULES([EVENT], [libevent >= 2.0.21], [use_libevent=yes], [AC_MSG_ERROR(libevent version 2.0.21 or greater not found.)]) if test x$TARGET_OS != xwindows; then - PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads],, [AC_MSG_ERROR(libevent_pthreads not found.)]) + PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads >= 2.0.21],, [AC_MSG_ERROR(libevent_pthreads version 2.0.21 or greater not found.)]) fi fi diff --git a/doc/dependencies.md b/doc/dependencies.md index e557c5cced..9d3e3e4327 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -14,7 +14,7 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | FreeType | [2.7.1](https://download.savannah.gnu.org/releases/freetype) | | No | | | | GCC | | [4.8+](https://gcc.gnu.org/) (C++11 support) | | | | | HarfBuzz-NG | | | | | | -| libevent | [2.1.11-stable](https://github.com/libevent/libevent/releases) | 2.0.22 | No | | | +| libevent | [2.1.11-stable](https://github.com/libevent/libevent/releases) | [2.0.21](https://github.com/PRCYCoin/PRCYCoin/pull/385) | No | | | | libjpeg | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L65) | | libpng | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L64) | | librsvg | | | | | | From ddc9627a340761e2b9f6cf40e0c184819a208db1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 15:58:05 -0400 Subject: [PATCH 024/391] build: Use pkg-config in BITCOIN_QT_CONFIGURE for all hosts This change adds to the BITCOIN_QT_CONFIGURE script ability to use pkg-config for MinGW. All of the non-pkg-config paths are removed as needless. If depends is built with DEBUG=1 the configure script fails to pickup Qt: - for macOS host (similar, but not the same as issue 16391) - for Windows host (regression) --- build-aux/m4/bitcoin_qt.m4 | 187 +------------------------------------ depends/config.site.in | 9 -- 2 files changed, 5 insertions(+), 191 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index b1ebde2846..bc96b1d9e7 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -79,25 +79,10 @@ AC_DEFUN([BITCOIN_QT_INIT],[ AC_SUBST(QT_TRANSLATION_DIR,$qt_translation_path) ]) -dnl Find the appropriate version of Qt libraries and includes. -dnl Inputs: $1: Whether or not pkg-config should be used. yes|no. Default: yes. -dnl Inputs: $2: If $1 is "yes" and --with-gui=auto, which qt version should be -dnl tried first. -dnl Outputs: See _BITCOIN_QT_FIND_LIBS_* -dnl Outputs: Sets variables for all qt-related tools. -dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_dbus, bitcoin_enable_qt_test +dnl Find Qt libraries and includes. +dnl Outputs: See _BITCOIN_QT_FIND_LIBS AC_DEFUN([BITCOIN_QT_CONFIGURE],[ - use_pkgconfig=$1 - - if test "x$use_pkgconfig" = x; then - use_pkgconfig=yes - fi - - if test "x$use_pkgconfig" = xyes; then - BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG]) - else - BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG]) - fi + BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS]) dnl This is ugly and complicated. Yuck. Works as follows: dnl For Qt5, we can check a header to find out whether Qt is build @@ -157,7 +142,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ CXXFLAGS=$TEMP_CXXFLAGS ]) - if test "x$use_pkgconfig$qt_bin_path" = xyes; then + if test "x$qt_bin_path" = x; then qt_bin_path="`$PKG_CONFIG --variable=host_bins Qt5Core 2>/dev/null`" fi @@ -269,47 +254,6 @@ dnl All macros below are internal and should _not_ be used from the main dnl configure.ac. dnl ---- -dnl Internal. Check if the included version of Qt is Qt5. -dnl Requires: INCLUDES must be populated as necessary. -dnl Output: bitcoin_cv_qt5=yes|no -AC_DEFUN([_BITCOIN_QT_CHECK_QT5],[ - AC_CACHE_CHECK(for Qt 5, bitcoin_cv_qt5,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION < 0x050000 || QT_VERSION_MAJOR < 5 - choke - #endif - ]])], - [bitcoin_cv_qt5=yes], - [bitcoin_cv_qt5=no]) -])]) - -dnl Internal. Check if the included version of Qt is greater than Qt58. -dnl Requires: INCLUDES must be populated as necessary. -dnl Output: bitcoin_cv_qt5=yes|no -AC_DEFUN([_BITCOIN_QT_CHECK_QT58],[ - AC_CACHE_CHECK(for > Qt 5.7, bitcoin_cv_qt58,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION_MINOR < 8 - choke - #endif - ]])], - [bitcoin_cv_qt58=yes], - [bitcoin_cv_qt58=no]) -])]) - - dnl Internal. Check if the linked version of Qt was built as static libs. dnl Requires: Qt5. dnl Requires: INCLUDES and LIBS must be populated as necessary. @@ -367,8 +311,6 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ if test -d "$qt_plugin_path/platforms/android"; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" fi - if test "x$use_pkgconfig" = xyes; then - : dnl m4_ifdef([PKG_CHECK_MODULES],[ if test x$bitcoin_cv_qt58 = xno; then PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) @@ -390,49 +332,13 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport], [QT_LIBS="-lQt5CglSupport $QT_LIBS"]) fi ]) - else - if test "x$TARGET_OS" = xwindows; then - AC_CACHE_CHECK(for Qt >= 5.6, bitcoin_cv_need_platformsupport,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION < 0x050600 || QT_VERSION_MINOR < 6 - choke - #endif - ]])], - [bitcoin_cv_need_platformsupport=yes], - [bitcoin_cv_need_platformsupport=no]) - ]) - if test "x$bitcoin_cv_need_platformsupport" = xyes; then - if test x$bitcoin_cv_qt58 = xno; then - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}PlatformSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXPlatformSupport not found))) - else - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}FontDatabaseSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXFontDatabaseSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}EventDispatcherSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXEventDispatcherSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}ThemeSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXThemeSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}FbSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXFbSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}DeviceDiscoverySupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXDeviceDiscoverySupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}AccessibilitySupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXAccessibilitySupport not found))) - QT_LIBS="$QT_LIBS -lversion -ldwmapi -luxtheme" - fi - fi - fi - fi fi ]) dnl Internal. Find Qt libraries using pkg-config. -dnl Inputs: bitcoin_qt_want_version (from --with-gui=). The version to check -dnl first. -dnl Inputs: $1: If bitcoin_qt_want_version is "auto", check for this version -dnl first. dnl Outputs: All necessary QT_* variables are set. dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. -AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[ +AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[ m4_ifdef([PKG_CHECK_MODULES],[ QT_LIB_PREFIX=Qt5 qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets Qt5Concurrent" @@ -453,86 +359,3 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[ ]) true; dnl ]) - -dnl Internal. Find Qt libraries without using pkg-config. Version is deduced -dnl from the discovered headers. -dnl Inputs: bitcoin_qt_want_version (from --with-gui=). The version to use. -dnl If "auto", the version will be discovered by _BITCOIN_QT_CHECK_QT5. -dnl Outputs: All necessary QT_* variables are set. -dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. -AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[ - TEMP_CPPFLAGS="$CPPFLAGS" - TEMP_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$PIC_FLAGS $CXXFLAGS" - TEMP_LIBS="$LIBS" - BITCOIN_QT_CHECK([ - if test "x$qt_include_path" != x; then - QT_INCLUDES="-I$qt_include_path -I$qt_include_path/QtCore -I$qt_include_path/QtGui -I$qt_include_path/QtWidgets -I$qt_include_path/QtNetwork -I$qt_include_path/QtTest -I$qt_include_path/QtDBus -I$qt_include_path/QtConcurrent" - CPPFLAGS="$QT_INCLUDES $CPPFLAGS" - fi - ]) - - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QtPlugin],,BITCOIN_QT_FAIL(QtCore headers missing))]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QApplication],, BITCOIN_QT_FAIL(QtGui headers missing))]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QLocalSocket],, BITCOIN_QT_FAIL(QtNetwork headers missing))]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QtConcurrent],, BITCOIN_QT_FAIL(QtConcurrent headers missing))]) - - BITCOIN_QT_CHECK([ - if test "x$bitcoin_qt_want_version" = xauto; then - _BITCOIN_QT_CHECK_QT5 - _BITCOIN_QT_CHECK_QT58 - fi - QT_LIB_PREFIX=Qt5 - ]) - - BITCOIN_QT_CHECK([ - LIBS= - if test "x$qt_lib_path" != x; then - LIBS="$LIBS -L$qt_lib_path" - fi - - if test "x$TARGET_OS" = xwindows; then - AC_CHECK_LIB([imm32], [main],, BITCOIN_QT_FAIL(libimm32 not found)) - fi - ]) - - BITCOIN_QT_CHECK(AC_CHECK_LIB([z] ,[main],,AC_MSG_WARN([zlib not found. Assuming qt has it built-in]))) - if test x$bitcoin_cv_qt58 = xno; then - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([png_error] ,[qtpng png],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in]))) - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([pcre16_exec], [qtpcre pcre16],,AC_MSG_WARN([libpcre16 not found. Assuming qt has it built-in]))) - else - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([png_error] ,[qtlibpng png],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in]))) - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([pcre2_match_16], [qtpcre2 libqtpcre2],,AC_MSG_WARN([libqtpcre2 not found. Assuming qt has it built-in]))) - fi - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([hb_ot_tags_from_script] ,[qtharfbuzzng qtharfbuzz harfbuzz],,AC_MSG_WARN([libharfbuzz not found. Assuming qt has it built-in or support is disabled]))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Core] ,[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Core not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Gui] ,[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Gui not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Network],[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Network not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Widgets],[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Widgets not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Concurrent],[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Concurrent not found))) - QT_LIBS="$LIBS" - LIBS="$TEMP_LIBS" - - BITCOIN_QT_CHECK([ - LIBS= - if test "x$qt_lib_path" != x; then - LIBS="-L$qt_lib_path" - fi - AC_CHECK_LIB([${QT_LIB_PREFIX}Test], [main],, have_qt_test=no) - AC_CHECK_HEADER([QTest],, have_qt_test=no) - QT_TEST_LIBS="$LIBS" - if test "x$use_dbus" != xno; then - LIBS= - if test "x$qt_lib_path" != x; then - LIBS="-L$qt_lib_path" - fi - AC_CHECK_LIB([${QT_LIB_PREFIX}DBus], [main],, have_qt_dbus=no) - AC_CHECK_HEADER([QtDBus],, have_qt_dbus=no) - QT_DBUS_LIBS="$LIBS" - fi - ]) - CPPFLAGS="$TEMP_CPPFLAGS" - CXXFLAGS="$TEMP_CXXFLAGS" - LIBS="$TEMP_LIBS" -]) - diff --git a/depends/config.site.in b/depends/config.site.in index fb9bf713cc..bb10f72734 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -42,15 +42,6 @@ if test x@host_os@ = xdarwin; then PORT=no fi -if test x@host_os@ = xmingw32; then - if test -z $with_qt_incdir; then - with_qt_incdir=$depends_prefix/include - fi - if test -z $with_qt_libdir; then - with_qt_libdir=$depends_prefix/lib - fi -fi - PATH=$depends_prefix/native/bin:$PATH PKG_CONFIG="`which pkg-config` --static" From 539f75a40f8fcda2778e8806e44942ec3e48829b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:00:10 -0400 Subject: [PATCH 025/391] build: Fix indentation in bitcoin_qt.m4 --- build-aux/m4/bitcoin_qt.m4 | 46 ++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index bc96b1d9e7..8a51502d5e 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -120,8 +120,8 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets]) fi if test "x$TARGET_OS" != xandroid; then - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin)],[-lqminimal]) - AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) + _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin)],[-lqminimal]) + AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) fi if test "x$TARGET_OS" = xwindows; then _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows]) @@ -311,28 +311,26 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ if test -d "$qt_plugin_path/platforms/android"; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" fi - m4_ifdef([PKG_CHECK_MODULES],[ - if test x$bitcoin_cv_qt58 = xno; then - PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) - else - PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport], [QT_LIBS="-lQt5FontDatabaseSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport], [QT_LIBS="-lQt5EventDispatcherSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport], [QT_LIBS="-lQt5ThemeSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport], [QT_LIBS="-lQt5DeviceDiscoverySupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport], [QT_LIBS="-lQt5AccessibilitySupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTFB], [Qt5FbSupport], [QT_LIBS="-lQt5FbSupport $QT_LIBS"]) - fi - if test "x$TARGET_OS" = xlinux; then - if ${PKG_CONFIG} --exists "Qt5Core >= 5.5" 2>/dev/null; then - PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) - fi - elif test "x$TARGET_OS" = xdarwin; then - PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport], [QT_LIBS="-lQt5ClipboardSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport], [QT_LIBS="-lQt5GraphicsSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport], [QT_LIBS="-lQt5CglSupport $QT_LIBS"]) - fi - ]) - fi + m4_ifdef([PKG_CHECK_MODULES],[ + if test x$bitcoin_cv_qt58 = xno; then + PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) + else + PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport], [QT_LIBS="-lQt5FontDatabaseSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport], [QT_LIBS="-lQt5EventDispatcherSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport], [QT_LIBS="-lQt5ThemeSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport], [QT_LIBS="-lQt5DeviceDiscoverySupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport], [QT_LIBS="-lQt5AccessibilitySupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTFB], [Qt5FbSupport], [QT_LIBS="-lQt5FbSupport $QT_LIBS"]) + fi + if test "x$TARGET_OS" = xlinux; then + PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xdarwin; then + PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport], [QT_LIBS="-lQt5ClipboardSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport], [QT_LIBS="-lQt5GraphicsSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport], [QT_LIBS="-lQt5CglSupport $QT_LIBS"]) + fi + ]) + fi ]) dnl Internal. Find Qt libraries using pkg-config. From 394380c5fb03d90ea7648ea70f1a5bbc3971d198 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:00:54 -0400 Subject: [PATCH 026/391] build: Remove duplicated QT_STATICPLUGIN define QT_STATICPLUGIN is defined in BITCOIN_QT_CONFIGURE macro. --- build-aux/m4/bitcoin_qt.m4 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 8a51502d5e..7258f033ae 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -258,7 +258,6 @@ dnl Internal. Check if the linked version of Qt was built as static libs. dnl Requires: Qt5. dnl Requires: INCLUDES and LIBS must be populated as necessary. dnl Output: bitcoin_cv_static_qt=yes|no -dnl Output: Defines QT_STATICPLUGIN if plugins are static. AC_DEFUN([_BITCOIN_QT_IS_STATIC],[ AC_CACHE_CHECK(for static Qt, bitcoin_cv_static_qt,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @@ -275,9 +274,6 @@ AC_DEFUN([_BITCOIN_QT_IS_STATIC],[ [bitcoin_cv_static_qt=yes], [bitcoin_cv_static_qt=no]) ]) - if test "x$bitcoin_cv_static_qt" = xyes; then - AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol for static Qt plugins]) - fi ]) dnl Internal. Check if the link-requirements for static plugins are met. From 1860c0f2dd490d7b2974c9751e1e8b934d942079 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:01:24 -0400 Subject: [PATCH 027/391] build: Remove extra tokens warning --- build-aux/m4/bitcoin_qt.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 7258f033ae..0194305edd 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -262,7 +262,7 @@ AC_DEFUN([_BITCOIN_QT_IS_STATIC],[ AC_CACHE_CHECK(for static Qt, bitcoin_cv_static_qt,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - #ifndef QT_VERSION OR QT_VERSION_STR + #ifndef QT_VERSION # include #endif ]], From b3df65e89ac1d8a094b83c28491996c72885d36a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:01:56 -0400 Subject: [PATCH 028/391] build: Fix m4 escaping --- build-aux/m4/bitcoin_qt.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 0194305edd..1f2b8f4f12 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -216,7 +216,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ dnl enable qt support - AC_MSG_CHECKING(whether to build ]AC_PACKAGE_NAME[ GUI) + AC_MSG_CHECKING([whether to build ]AC_PACKAGE_NAME[ GUI]) BITCOIN_QT_CHECK([ bitcoin_enable_qt=yes bitcoin_enable_qt_test=yes From 94a665ac2562075218644ac6b60e5e798bb03f9d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:25:16 -0400 Subject: [PATCH 029/391] build: Always define ZMQ_STATIC for MinGW --- configure.ac | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index c7637298aa..7b0a4fd83e 100644 --- a/configure.ac +++ b/configure.ac @@ -1053,15 +1053,6 @@ else AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) fi - if test "x$use_zmq" = "xyes"; then - dnl Assume libzmq was built for static linking - case $host in - *mingw*) - ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC" - ;; - esac - fi - if test x$use_qr != xno; then BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) @@ -1083,6 +1074,15 @@ AC_CHECK_LIB([crypto],[RAND_egd],[],[ ) ]) +if test "x$use_zmq" = xyes; then + dnl Assume libzmq was built for static linking + case $host in + *mingw*) + ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC" + ;; + esac +fi + dnl univalue check need_bundled_univalue=yes From bd55088486c8c71ae345f0810dcdc2c55fc9e2a8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:27:32 -0400 Subject: [PATCH 030/391] build: Always use pkg-config --- configure.ac | 4 ---- 1 file changed, 4 deletions(-) diff --git a/configure.ac b/configure.ac index 7b0a4fd83e..542270f780 100644 --- a/configure.ac +++ b/configure.ac @@ -446,10 +446,6 @@ AC_ARG_WITH([daemon], use_pkgconfig=yes case $host in *mingw*) - - #pkgconfig does more harm than good with MinGW - use_pkgconfig=no - TARGET_OS=windows AC_CHECK_LIB([mingwthrd], [main],, AC_MSG_ERROR(libmingwthrd missing)) AC_CHECK_LIB([kernel32], [main],, AC_MSG_ERROR(libkernel32 missing)) From ea76494da36d625841147393f6184dc25a98d3e9 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:30:34 -0400 Subject: [PATCH 031/391] build: Drop dead non-pkg-config code for UNIVALUE check --- configure.ac | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/configure.ac b/configure.ac index 542270f780..cb2dad1181 100644 --- a/configure.ac +++ b/configure.ac @@ -1088,24 +1088,7 @@ if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_ben else if test x$system_univalue != xno ; then - found_univalue=no - if test x$use_pkgconfig = xyes; then - : #NOP - m4_ifdef( - [PKG_CHECK_MODULES], - [ - PKG_CHECK_MODULES([UNIVALUE],[libunivalue >= 1.0.4],[found_univalue=yes],[true]) - ] - ) - else - AC_CHECK_HEADER([univalue.h],[ - AC_CHECK_LIB([univalue], [main],[ - UNIVALUE_LIBS=-lunivalue - found_univalue=yes - ],[true]) - ],[true]) - fi - + PKG_CHECK_MODULES([UNIVALUE], [libunivalue >= 1.0.4], [found_univalue=yes], [found_univalue=no]) if test x$found_univalue = xyes ; then system_univalue=yes need_bundled_univalue=no From 5c10a22cfcda408090008644bb5c8188bd7689ed Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:34:47 -0400 Subject: [PATCH 032/391] build: Fix indentation in UNIVALUE check --- configure.ac | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index cb2dad1181..a5be884e92 100644 --- a/configure.ac +++ b/configure.ac @@ -1087,23 +1087,22 @@ if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_ben need_bundled_univalue=no else -if test x$system_univalue != xno ; then - PKG_CHECK_MODULES([UNIVALUE], [libunivalue >= 1.0.4], [found_univalue=yes], [found_univalue=no]) - if test x$found_univalue = xyes ; then - system_univalue=yes - need_bundled_univalue=no - elif test x$system_univalue = xyes ; then - AC_MSG_ERROR([univalue not found]) - else - system_univalue=no + if test x$system_univalue != xno; then + PKG_CHECK_MODULES([UNIVALUE], [libunivalue >= 1.0.4], [found_univalue=yes], [found_univalue=no]) + if test x$found_univalue = xyes; then + system_univalue=yes + need_bundled_univalue=no + elif test x$system_univalue = xyes; then + AC_MSG_ERROR([univalue not found]) + else + system_univalue=no + fi fi -fi - -if test x$need_bundled_univalue = xyes ; then - UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' - UNIVALUE_LIBS='univalue/libunivalue.la' -fi + if test x$need_bundled_univalue = xyes; then + UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' + UNIVALUE_LIBS='univalue/libunivalue.la' + fi fi AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes]) From 281540ff3a1db5101c5b9c811d2af0d1c557e109 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:37:53 -0400 Subject: [PATCH 033/391] build: Drop dead non-pkg-config code for ZMQ check --- configure.ac | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index a5be884e92..5be6534a9a 100644 --- a/configure.ac +++ b/configure.ac @@ -1008,16 +1008,6 @@ if test x$use_pkgconfig = xyes; then PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads >= 2.0.21],, [AC_MSG_ERROR(libevent_pthreads version 2.0.21 or greater not found.)]) fi fi - - if test "x$use_zmq" = "xyes"; then - PKG_CHECK_MODULES([ZMQ],[libzmq >= 4], - [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], - [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) - AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) - use_zmq=no]) - else - AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) - fi ] ) else @@ -1035,20 +1025,6 @@ else fi fi - if test "x$use_zmq" = "xyes"; then - AC_CHECK_HEADER([zmq.h], - [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], - [AC_MSG_WARN([zmq.h not found, disabling zmq support]) - use_zmq=no - AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) - AC_CHECK_LIB([zmq],[zmq_ctx_shutdown],ZMQ_LIBS=-lzmq, - [AC_MSG_WARN([libzmq >= 4.0 not found, disabling zmq support]) - use_zmq=no - AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) - else - AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) - fi - if test x$use_qr != xno; then BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) @@ -1070,6 +1046,18 @@ AC_CHECK_LIB([crypto],[RAND_egd],[],[ ) ]) +dnl ZMQ check + +if test "x$use_zmq" = xyes; then + PKG_CHECK_MODULES([ZMQ], [libzmq >= 4], + AC_DEFINE([ENABLE_ZMQ], [1], [Define to 1 to enable ZMQ functions]), + [AC_DEFINE([ENABLE_ZMQ], [0], [Define to 1 to enable ZMQ functions]) + AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) + use_zmq=no]) +else + AC_DEFINE_UNQUOTED([ENABLE_ZMQ], [0], [Define to 1 to enable ZMQ functions]) +fi + if test "x$use_zmq" = xyes; then dnl Assume libzmq was built for static linking case $host in From 6baef382d034b162b104d0c7468e226a07fcf4a7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:40:16 -0400 Subject: [PATCH 034/391] build: Drop dead non-pkg-config code for qrencode check --- configure.ac | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 5be6534a9a..a3a278e315 100644 --- a/configure.ac +++ b/configure.ac @@ -999,9 +999,6 @@ if test x$use_pkgconfig = xyes; then [ PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)]) PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)]) - if test x$use_qr != xno; then - BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) - fi if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then PKG_CHECK_MODULES([EVENT], [libevent >= 2.0.21], [use_libevent=yes], [AC_MSG_ERROR(libevent version 2.0.21 or greater not found.)]) if test x$TARGET_OS != xwindows; then @@ -1024,11 +1021,12 @@ else AC_CHECK_LIB([event_pthreads],[main],EVENT_PTHREADS_LIBS=-levent_pthreads,AC_MSG_ERROR(libevent_pthreads missing)) fi fi +fi - if test x$use_qr != xno; then - BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) - fi +dnl QR Code encoding library check + +if test "x$use_qr" != xno; then + BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) fi save_CXXFLAGS="${CXXFLAGS}" From c77171056f4ce5c5672742acb15d0c3773a09497 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:47:42 -0400 Subject: [PATCH 035/391] build: Drop dead non-pkg-config code for libevent check --- configure.ac | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index a3a278e315..4de90cfa70 100644 --- a/configure.ac +++ b/configure.ac @@ -992,34 +992,17 @@ if test x$use_boost = xyes; then BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" fi -if test x$use_pkgconfig = xyes; then - : dnl - m4_ifdef( - [PKG_CHECK_MODULES], - [ - PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)]) - PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)]) - if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then - PKG_CHECK_MODULES([EVENT], [libevent >= 2.0.21], [use_libevent=yes], [AC_MSG_ERROR(libevent version 2.0.21 or greater not found.)]) - if test x$TARGET_OS != xwindows; then - PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads >= 2.0.21],, [AC_MSG_ERROR(libevent_pthreads version 2.0.21 or greater not found.)]) - fi - fi - ] - ) -else +dnl libevent check AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) - if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then - AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),) - AC_CHECK_LIB([event],[main],EVENT_LIBS=-levent,AC_MSG_ERROR(libevent missing)) - if test x$TARGET_OS != xwindows; then - AC_CHECK_LIB([event_pthreads],[main],EVENT_PTHREADS_LIBS=-levent_pthreads,AC_MSG_ERROR(libevent_pthreads missing)) - fi +if test x$build_bitcoin_cli$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench != xnonononono; then + PKG_CHECK_MODULES([EVENT], [libevent >= 2.0.21], [use_libevent=yes], [AC_MSG_ERROR([libevent version 2.0.21 or greater not found.])]) + if test x$TARGET_OS != xwindows; then + PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads >= 2.0.21],, [AC_MSG_ERROR([libevent_pthreads version 2.0.21 or greater not found.])]) fi fi From 4147dd8f2052e5629797b49d0025c9bd8eebfb86 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:49:12 -0400 Subject: [PATCH 036/391] build: Drop unused use_pkgconfig variable --- configure.ac | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 4de90cfa70..d92c982688 100644 --- a/configure.ac +++ b/configure.ac @@ -443,7 +443,6 @@ AC_ARG_WITH([daemon], [build_bitcoind=$withval], [build_bitcoind=yes]) -use_pkgconfig=yes case $host in *mingw*) TARGET_OS=windows @@ -561,14 +560,10 @@ case $host in ;; esac -if test x$use_pkgconfig = xyes; then - m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) - m4_ifdef([PKG_PROG_PKG_CONFIG], [ - PKG_PROG_PKG_CONFIG - if test x"$PKG_CONFIG" = "x"; then - AC_MSG_ERROR(pkg-config not found.) - fi - ]) +m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR([PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh])]) +PKG_PROG_PKG_CONFIG +if test "x$PKG_CONFIG" = x; then + AC_MSG_ERROR([pkg-config not found]) fi if test x$use_extended_functional_tests != xno; then From 07ec74fa0d76e51c616c935ae467ddb819998aec Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 16:50:06 -0400 Subject: [PATCH 037/391] build: Detect missed pkg-config early --- configure.ac | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index d92c982688..f4621a09e6 100644 --- a/configure.ac +++ b/configure.ac @@ -13,6 +13,12 @@ AC_CONFIG_HEADERS([src/config/prcycoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) +m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR([PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh])]) +PKG_PROG_PKG_CONFIG +if test "x$PKG_CONFIG" = x; then + AC_MSG_ERROR([pkg-config not found]) +fi + BITCOIN_DAEMON_NAME=prcycoind BITCOIN_GUI_NAME=prcycoin-qt BITCOIN_CLI_NAME=prcycoin-cli @@ -560,12 +566,6 @@ case $host in ;; esac -m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR([PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh])]) -PKG_PROG_PKG_CONFIG -if test "x$PKG_CONFIG" = x; then - AC_MSG_ERROR([pkg-config not found]) -fi - if test x$use_extended_functional_tests != xno; then AC_SUBST(EXTENDED_FUNCTIONAL_TESTS, --extended) fi From d82bee93b167a858305b40fe5f04e58f398a90c0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 17:08:47 -0400 Subject: [PATCH 038/391] build: remove configure checks for win libraries we don't link against While cross compiling, HOST=x86_64-w64-mingw32, none of these libs actually seem to be passed to the linker. --- configure.ac | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index c001fb66fe..077af5e1fd 100644 --- a/configure.ac +++ b/configure.ac @@ -451,25 +451,20 @@ case $host in use_pkgconfig=no TARGET_OS=windows - AC_CHECK_LIB([mingwthrd], [main],, AC_MSG_ERROR(libmingwthrd missing)) - AC_CHECK_LIB([kernel32], [main],, AC_MSG_ERROR(libkernel32 missing)) - AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(libuser32 missing)) - AC_CHECK_LIB([gdi32], [main],, AC_MSG_ERROR(libgdi32 missing)) - AC_CHECK_LIB([comdlg32], [main],, AC_MSG_ERROR(libcomdlg32 missing)) - AC_CHECK_LIB([winspool], [main],, AC_MSG_ERROR(libwinspool missing)) - AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(libwinmm missing)) - AC_CHECK_LIB([shell32], [main],, AC_MSG_ERROR(libshell32 missing)) - AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(libcomctl32 missing)) - AC_CHECK_LIB([ole32], [main],, AC_MSG_ERROR(libole32 missing)) - AC_CHECK_LIB([oleaut32], [main],, AC_MSG_ERROR(liboleaut32 missing)) - AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(libuuid missing)) - AC_CHECK_LIB([rpcrt4], [main],, AC_MSG_ERROR(librpcrt4 missing)) - AC_CHECK_LIB([advapi32], [main],, AC_MSG_ERROR(libadvapi32 missing)) - AC_CHECK_LIB([ws2_32], [main],, AC_MSG_ERROR(libws2_32 missing)) - AC_CHECK_LIB([mswsock], [main],, AC_MSG_ERROR(libmswsock missing)) - AC_CHECK_LIB([shlwapi], [main],, AC_MSG_ERROR(libshlwapi missing)) - AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(libiphlpapi missing)) - AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(libcrypt32 missing)) + AC_CHECK_LIB([kernel32], [GetModuleFileNameA],, AC_MSG_ERROR(libkernel32 missing)) + AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(libuser32 missing)) + AC_CHECK_LIB([gdi32], [main],, AC_MSG_ERROR(libgdi32 missing)) + AC_CHECK_LIB([comdlg32], [main],, AC_MSG_ERROR(libcomdlg32 missing)) + AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(libwinmm missing)) + AC_CHECK_LIB([shell32], [SHGetSpecialFolderPathW],, AC_MSG_ERROR(libshell32 missing)) + AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(libcomctl32 missing)) + AC_CHECK_LIB([ole32], [CoCreateInstance],, AC_MSG_ERROR(libole32 missing)) + AC_CHECK_LIB([oleaut32], [main],, AC_MSG_ERROR(liboleaut32 missing)) + AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(libuuid missing)) + AC_CHECK_LIB([advapi32], [CryptAcquireContextW],, AC_MSG_ERROR(libadvapi32 missing)) + AC_CHECK_LIB([ws2_32], [WSAStartup],, AC_MSG_ERROR(libws2_32 missing)) + AC_CHECK_LIB([shlwapi], [PathRemoveFileSpecW],, AC_MSG_ERROR(libshlwapi missing)) + AC_CHECK_LIB([iphlpapi], [GetAdaptersAddresses],, AC_MSG_ERROR(libiphlpapi missing)) # -static is interpreted by libtool, where it has a different meaning. # In libtool-speak, it's -all-static. From 288390eb5e8b0d1c9163aaf69d831e75f9302317 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 17:48:02 -0400 Subject: [PATCH 039/391] depends: Do not force Precompiled Headers (PCH) for building Qt on Linux On CentOS 8 the forced '-pch' option breaks Qt build. Removing '-pch' option does not affect build time for other Linux systems. --- depends/packages/qt.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index dab7172721..f0ca94ed21 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -64,7 +64,6 @@ $(package)_config_opts += -nomake tests $(package)_config_opts += -opensource $(package)_config_opts += -openssl-linked $(package)_config_opts += -optimized-qmake -$(package)_config_opts += -pch $(package)_config_opts += -pkg-config $(package)_config_opts += -prefix $(host_prefix) $(package)_config_opts += -qt-libpng @@ -91,6 +90,7 @@ $(package)_config_opts += -no-feature-wizard $(package)_config_opts += -no-feature-xml $(package)_config_opts_darwin = -no-dbus +$(package)_config_opts_darwin += -pch ifneq ($(build_os),darwin) $(package)_config_opts_darwin += -xplatform macx-clang-linux @@ -130,6 +130,7 @@ $(package)_config_opts_mingw32 = -no-opengl $(package)_config_opts_mingw32 += -no-dbus $(package)_config_opts_mingw32 += -xplatform win32-g++ $(package)_config_opts_mingw32 += -device-option CROSS_COMPILE="$(host)-" +$(package)_config_opts_mingw32 += -pch $(package)_config_opts_android = -xplatform android-clang $(package)_config_opts_android += -android-sdk $(ANDROID_SDK) @@ -145,6 +146,7 @@ $(package)_config_opts_android += -qt-freetype $(package)_config_opts_android += -no-fontconfig $(package)_config_opts_android += -L $(host_prefix)/lib $(package)_config_opts_android += -I $(host_prefix)/include +$(package)_config_opts_android += -pch $(package)_config_opts_aarch64_android += -android-arch arm64-v8a $(package)_config_opts_armv7a_android += -android-arch armeabi-v7a From 58ffc26aaf6830ad45446af4441fa7962bfc6177 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 18:07:30 -0400 Subject: [PATCH 040/391] build: Drop non-existent share/pkgconfig directory --- depends/packages/qt.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index dab7172721..ee1dd0232d 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -235,7 +235,6 @@ endef define $(package)_config_cmds export PKG_CONFIG_SYSROOT_DIR=/ && \ export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \ - export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \ ./configure $($(package)_config_opts) && \ echo "host_build: QT_CONFIG ~= s/system-zlib/zlib" >> mkspecs/qconfig.pri && \ echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \ From 65ecb813a89888644b3cea246647e99db2e230df Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 18:07:53 -0400 Subject: [PATCH 041/391] build: Remove unneeded share/doc directory from expat package --- depends/packages/expat.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index b811f84a38..7479f31e2c 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -22,5 +22,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm lib/*.la + rm -rf share lib/*.la endef From 1faa9fe7b2535329e8ddba9a99163a8597dfab0f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 18:08:17 -0400 Subject: [PATCH 042/391] build: Remove empty var/cache/fontconfig directory from fontconfig --- depends/packages/fontconfig.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk index c4f11d8dd0..3a2a8f4a7c 100644 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -28,5 +28,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm lib/*.la + rm -rf var lib/*.la endef From 42fcd38c04e99d1b942eb129794d0c567abd36e9 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 18:09:01 -0400 Subject: [PATCH 043/391] build: Remove unneeded share/man directory from freetype package --- depends/packages/freetype.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk index f24fc69d81..298786bde6 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -22,5 +22,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm lib/*.la + rm -rf share/man lib/*.la endef From 4cf0a00e1a4d29cadc4ce115c9e9faea9f4d7e62 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 18:09:21 -0400 Subject: [PATCH 044/391] build: Remove unneeded share/man directory from libXau package --- depends/packages/libXau.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index 058416f793..acc03b419a 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -29,5 +29,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm lib/*.la + rm -rf share lib/*.la endef From 7a80f1b61cde489a8979075a13c8b971d000a276 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 18:14:18 -0400 Subject: [PATCH 045/391] build: fix cflags passing for mingw miniupnpc Cherry-pick of a patch upstreamed to miniupnpc, see here: https://github.com/miniupnp/miniupnp/pull/619. --- depends/packages/miniupnpc.mk | 5 ++-- .../miniupnpc/respect_mingw_cflags.patch | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 depends/patches/miniupnpc/respect_mingw_cflags.patch diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index 99f5b0a8db..dc9ffaac74 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -3,7 +3,7 @@ $(package)_version=2.2.2 $(package)_download_path=https://miniupnp.tuxfamily.org/files/ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=888fb0976ba61518276fe1eda988589c700a3f2a69d71089260d75562afd3687 -$(package)_patches=dont_leak_info.patch +$(package)_patches=dont_leak_info.patch respect_mingw_cflags.patch define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" @@ -13,7 +13,8 @@ $(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$ endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/dont_leak_info.patch + patch -p1 < $($(package)_patch_dir)/dont_leak_info.patch && \ + patch -p1 < $($(package)_patch_dir)/respect_mingw_cflags.patch endef define $(package)_build_cmds diff --git a/depends/patches/miniupnpc/respect_mingw_cflags.patch b/depends/patches/miniupnpc/respect_mingw_cflags.patch new file mode 100644 index 0000000000..a44580ddab --- /dev/null +++ b/depends/patches/miniupnpc/respect_mingw_cflags.patch @@ -0,0 +1,23 @@ +commit fec515a7ac9991a0ee91068fda046b54b191155e +Author: fanquake +Date: Wed Jul 27 15:52:37 2022 +0100 + + build: respect CFLAGS in makefile.mingw + + Similar to the other Makefile. + + Cherry-pick of https://github.com/miniupnp/miniupnp/pull/619. + +diff --git a/Makefile.mingw b/Makefile.mingw +index 2bff7bd..88430d2 100644 +--- a/Makefile.mingw ++++ b/Makefile.mingw +@@ -19,7 +19,7 @@ else + RM = rm -f + endif + #CFLAGS = -Wall -g -DDEBUG -D_WIN32_WINNT=0X501 +-CFLAGS = -Wall -W -Wstrict-prototypes -Os -DNDEBUG -D_WIN32_WINNT=0X501 ++CFLAGS ?= -Wall -W -Wstrict-prototypes -Os -DNDEBUG -D_WIN32_WINNT=0X501 + LDLIBS = -lws2_32 -liphlpapi + # -lwsock32 + # -liphlpapi is needed for GetBestRoute() and GetIpAddrTable() From d6d6bd8c25392e63bc6bf7031abe95c585043126 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 18:15:25 -0400 Subject: [PATCH 046/391] build: set D_WIN32_WINNT=0x0601 for mingw miniupnpc This matches configure, and what we set for libevent etc. --- depends/packages/miniupnpc.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index dc9ffaac74..7ad2529e47 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -5,10 +5,12 @@ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=888fb0976ba61518276fe1eda988589c700a3f2a69d71089260d75562afd3687 $(package)_patches=dont_leak_info.patch respect_mingw_cflags.patch +# Next time this package is updated, ensure that _WIN32_WINNT is still properly set. +# See discussion in https://github.com/bitcoin/bitcoin/pull/25964. define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" $(package)_build_opts_darwin=LIBTOOL="$($(package)_libtool)" -$(package)_build_opts_mingw32=-f Makefile.mingw +$(package)_build_opts_mingw32=-f Makefile.mingw CFLAGS="$($(package)_cflags) -D_WIN32_WINNT=0x0601" $(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)" endef From 58bd02442a771b4c606868aba8984bd80e6492cb Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 18:33:29 -0400 Subject: [PATCH 047/391] build: Improve error message when pkg-config is not installed --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b175fd4f54..a42f38c06e 100644 --- a/configure.ac +++ b/configure.ac @@ -13,7 +13,7 @@ AC_CONFIG_HEADERS([src/config/prcycoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) -m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR([PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh])]) +m4_ifndef([PKG_PROG_PKG_CONFIG], [m4_fatal([PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh])]) PKG_PROG_PKG_CONFIG if test "x$PKG_CONFIG" = x; then AC_MSG_ERROR([pkg-config not found]) From b12bc85f2c977192d49823411b4d67569360565a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 18:40:11 -0400 Subject: [PATCH 048/391] build: add FreeBSD support to depends --- depends/Makefile | 2 ++ depends/builders/freebsd.mk | 5 +++++ depends/hosts/freebsd.mk | 31 +++++++++++++++++++++++++++++++ depends/packages/bdb.mk | 1 + depends/packages/boost.mk | 1 + depends/packages/libevent.mk | 1 + depends/packages/zeromq.mk | 1 + 7 files changed, 42 insertions(+) create mode 100644 depends/builders/freebsd.mk create mode 100644 depends/hosts/freebsd.mk diff --git a/depends/Makefile b/depends/Makefile index ce76527e8a..cd13fa5683 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -71,6 +71,7 @@ build_vendor=$(word 2,$(subst -, ,$(build))) full_build_os:=$(subst $(build_arch)-$(build_vendor)-,,$(build)) build_os:=$(findstring linux,$(full_build_os)) build_os+=$(findstring darwin,$(full_build_os)) +build_os+=$(findstring freebsd,$(full_build_os)) build_os:=$(strip $(build_os)) ifeq ($(build_os),) build_os=$(full_build_os) @@ -81,6 +82,7 @@ host_vendor=$(word 2,$(subst -, ,$(canonical_host))) full_host_os:=$(subst $(host_arch)-$(host_vendor)-,,$(canonical_host)) host_os:=$(findstring linux,$(full_host_os)) host_os+=$(findstring darwin,$(full_host_os)) +host_os+=$(findstring freebsd,$(full_host_os)) host_os+=$(findstring mingw32,$(full_host_os)) ifeq (android,$(findstring android,$(full_host_os))) diff --git a/depends/builders/freebsd.mk b/depends/builders/freebsd.mk new file mode 100644 index 0000000000..465f58e04d --- /dev/null +++ b/depends/builders/freebsd.mk @@ -0,0 +1,5 @@ +build_freebsd_CC=clang +build_freebsd_CXX=clang++ + +build_freebsd_SHA256SUM = shasum -a 256 +build_freebsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o diff --git a/depends/hosts/freebsd.mk b/depends/hosts/freebsd.mk new file mode 100644 index 0000000000..307f844331 --- /dev/null +++ b/depends/hosts/freebsd.mk @@ -0,0 +1,31 @@ +freebsd_CFLAGS=-pipe +freebsd_CFLAGS_CXXFLAGS=$(freebsd_CFLAGS) + +freebsd_CFLAGS_release_CFLAGS=-O2 +freebsd_CFLAGS_release_CXXFLAGS=$(freebsd_release_CFLAGS) + +freebsd_CFLAGS_debug_CFLAGS=-O1 +freebsd_CFLAGS_debug_CXXFLAGS=$(freebsd_debug_CFLAGS) + +ifeq (86,$(findstring 86,$(build_arch))) +i686_freebsd_CC=clang -m32 +i686_freebsd_CXX=clang++ -m32 +i686_freebsd_AR=ar +i686_freebsd_RANLIB=ranlib +i686_freebsd_NM=nm +i686_freebsd_STRIP=strip + +x86_64_freebsd_CC=clang -m64 +x86_64_freebsd_CXX=clang++ -m64 +x86_64_freebsd_AR=ar +x86_64_freebsd_RANLIB=ranlib +x86_64_freebsd_NM=nm +x86_64_freebsd_STRIP=strip +else +i686_freebsd_CC=$(default_host_CC) -m32 +i686_freebsd_CXX=$(default_host_CXX) -m32 +x86_64_freebsd_CC=$(default_host_CC) -m64 +x86_64_freebsd_CXX=$(default_host_CXX) -m64 +endif + +freebsd_cmake_system=FreeBSD diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index abd67d106c..f0c7501299 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -10,6 +10,7 @@ define $(package)_set_vars $(package)_config_opts=--disable-shared --enable-cxx --disable-replication $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic +$(package)_config_opts_freebsd=--with-pic $(package)_cxxflags=-std=c++17 $(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 33074f39bd..c4512704ae 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -33,6 +33,7 @@ endif $(package)_config_libraries=chrono,filesystem,program_options,system,thread,test $(package)_cxxflags=-std=c++17 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC +$(package)_cxxflags_freebsd=-fPIC $(package)_cxxflags_android=-fPIC endef diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index 1cd5a1749a..c0ee9d21d6 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -18,6 +18,7 @@ define $(package)_set_vars $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_release=--disable-debug-mode $(package)_config_opts_linux=--with-pic + $(package)_config_opts_freebsd=--with-pic $(package)_config_opts_android=--with-pic $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 endef diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index a424a30a3c..85dd159e81 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -10,6 +10,7 @@ define $(package)_set_vars $(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov $(package)_config_opts_linux=--with-pic + $(package)_config_opts_freebsd=--with-pic $(package)_config_opts_android=--with-pic $(package)_cxxflags=-std=c++17 endef From 2006af51123077e73613730cc528df96f1943f67 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 19:35:03 -0400 Subject: [PATCH 049/391] build: add NetBSD support to depends --- depends/Makefile | 4 +++- depends/builders/netbsd.mk | 2 ++ depends/hosts/netbsd.mk | 31 +++++++++++++++++++++++++++++++ depends/packages/bdb.mk | 1 + depends/packages/libevent.mk | 1 + depends/packages/zeromq.mk | 1 + 6 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 depends/builders/netbsd.mk create mode 100644 depends/hosts/netbsd.mk diff --git a/depends/Makefile b/depends/Makefile index cd13fa5683..adf4c2b412 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -72,6 +72,7 @@ full_build_os:=$(subst $(build_arch)-$(build_vendor)-,,$(build)) build_os:=$(findstring linux,$(full_build_os)) build_os+=$(findstring darwin,$(full_build_os)) build_os+=$(findstring freebsd,$(full_build_os)) +build_os+=$(findstring netbsd,$(full_build_os)) build_os:=$(strip $(build_os)) ifeq ($(build_os),) build_os=$(full_build_os) @@ -83,6 +84,7 @@ full_host_os:=$(subst $(host_arch)-$(host_vendor)-,,$(canonical_host)) host_os:=$(findstring linux,$(full_host_os)) host_os+=$(findstring darwin,$(full_host_os)) host_os+=$(findstring freebsd,$(full_host_os)) +host_os+=$(findstring netbsd,$(full_host_os)) host_os+=$(findstring mingw32,$(full_host_os)) ifeq (android,$(findstring android,$(full_host_os))) @@ -172,7 +174,7 @@ $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) $(AT)mkdir -p $(@D) $(AT)echo copying packages: $^ $(AT)echo to: $(@D) - $(AT)cd $(@D); $(foreach package,$^, tar xf $($(package)_cached); ) + $(AT)cd $(@D); $(foreach package,$^, $(build_TAR) xf $($(package)_cached); ) $(AT)touch $@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_build_id) diff --git a/depends/builders/netbsd.mk b/depends/builders/netbsd.mk new file mode 100644 index 0000000000..b7cf1f7514 --- /dev/null +++ b/depends/builders/netbsd.mk @@ -0,0 +1,2 @@ +build_netbsd_SHA256SUM = shasum -a 256 +build_netbsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o diff --git a/depends/hosts/netbsd.mk b/depends/hosts/netbsd.mk new file mode 100644 index 0000000000..b3e4545a64 --- /dev/null +++ b/depends/hosts/netbsd.mk @@ -0,0 +1,31 @@ +netbsd_CFLAGS=-pipe +netbsd_CXXFLAGS=$(netbsd_CFLAGS) + +netbsd_release_CFLAGS=-O2 +netbsd_release_CXXFLAGS=$(netbsd_release_CFLAGS) + +netbsd_debug_CFLAGS=-O1 +netbsd_debug_CXXFLAGS=$(netbsd_debug_CFLAGS) + +ifeq (86,$(findstring 86,$(build_arch))) +i686_netbsd_CC=gcc -m32 +i686_netbsd_CXX=g++ -m32 +i686_netbsd_AR=ar +i686_netbsd_RANLIB=ranlib +i686_netbsd_NM=nm +i686_netbsd_STRIP=strip + +x86_64_netbsd_CC=gcc -m64 +x86_64_netbsd_CXX=g++ -m64 +x86_64_netbsd_AR=ar +x86_64_netbsd_RANLIB=ranlib +x86_64_netbsd_NM=nm +x86_64_netbsd_STRIP=strip +else +i686_netbsd_CC=$(default_host_CC) -m32 +i686_netbsd_CXX=$(default_host_CXX) -m32 +x86_64_netbsd_CC=$(default_host_CC) -m64 +x86_64_netbsd_CXX=$(default_host_CXX) -m64 +endif + +netbsd_cmake_system=NetBSD diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index f0c7501299..44d68422ce 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -11,6 +11,7 @@ $(package)_config_opts=--disable-shared --enable-cxx --disable-replication $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic +$(package)_config_opts_netbsd=--with-pic $(package)_cxxflags=-std=c++17 $(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index c0ee9d21d6..e776a1f64b 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -19,6 +19,7 @@ define $(package)_set_vars $(package)_config_opts_release=--disable-debug-mode $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic + $(package)_config_opts_netbsd=--with-pic $(package)_config_opts_android=--with-pic $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 endef diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 85dd159e81..f34e50d7d6 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -11,6 +11,7 @@ define $(package)_set_vars $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic + $(package)_config_opts_netbsd=--with-pic $(package)_config_opts_android=--with-pic $(package)_cxxflags=-std=c++17 endef From 75681608db596b4ac29b1f441b08d7889a2016f1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 19:35:43 -0400 Subject: [PATCH 050/391] build: correct depends FreeBSD C{XX}FLAGS --- depends/hosts/freebsd.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/depends/hosts/freebsd.mk b/depends/hosts/freebsd.mk index 307f844331..0a62347b57 100644 --- a/depends/hosts/freebsd.mk +++ b/depends/hosts/freebsd.mk @@ -1,11 +1,11 @@ freebsd_CFLAGS=-pipe -freebsd_CFLAGS_CXXFLAGS=$(freebsd_CFLAGS) +freebsd_CXXFLAGS=$(freebsd_CFLAGS) -freebsd_CFLAGS_release_CFLAGS=-O2 -freebsd_CFLAGS_release_CXXFLAGS=$(freebsd_release_CFLAGS) +freebsd_release_CFLAGS=-O2 +freebsd_release_CXXFLAGS=$(freebsd_release_CFLAGS) -freebsd_CFLAGS_debug_CFLAGS=-O1 -freebsd_CFLAGS_debug_CXXFLAGS=$(freebsd_debug_CFLAGS) +freebsd_debug_CFLAGS=-O1 +freebsd_debug_CXXFLAGS=$(freebsd_debug_CFLAGS) ifeq (86,$(findstring 86,$(build_arch))) i686_freebsd_CC=clang -m32 From 1c68c47aa9e930534acdf0ece7241e7501e3946e Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 19:09:25 -0400 Subject: [PATCH 051/391] build: add a default build tar in depends This is so we can override it later for BSDs. --- depends/builders/default.mk | 3 ++- depends/funcs.mk | 7 +++---- depends/packages/qt.mk | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/depends/builders/default.mk b/depends/builders/default.mk index f097db65d6..0370fb9acb 100644 --- a/depends/builders/default.mk +++ b/depends/builders/default.mk @@ -1,6 +1,7 @@ default_build_CC = gcc default_build_CXX = g++ default_build_AR = ar +default_build_TAR = tar default_build_RANLIB = ranlib default_build_STRIP = strip default_build_NM = nm @@ -12,7 +13,7 @@ build_$(build_os)_$1 ?= $$(default_build_$1) build_$(build_arch)_$(build_os)_$1 ?= $$(build_$(build_os)_$1) build_$1=$$(build_$(build_arch)_$(build_os)_$1) endef -$(foreach var,CC CXX AR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL,$(eval $(call add_build_tool_func,$(var)))) +$(foreach var,CC CXX AR TAR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL,$(eval $(call add_build_tool_func,$(var)))) define add_build_flags_func build_$(build_arch)_$(build_os)_$1 += $(build_$(build_os)_$1) build_$1=$$(build_$(build_arch)_$(build_os)_$1) diff --git a/depends/funcs.mk b/depends/funcs.mk index 11dfe743d7..7b8338f247 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -78,8 +78,7 @@ $(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path)) #default commands # The default behavior for tar will try to set ownership when running as uid 0 and may not succeed, --no-same-owner disables this behavior $(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)),$$($(1)_download_file),$($(1)_file_name),$($(1)_sha256_hash)) -$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --no-same-owner --strip-components=1 -xf $$($(1)_source) -$(1)_preprocess_cmds ?= +$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_TAR) --no-same-owner --strip-components=1 -xf $$($(1)_source) $(1)_build_cmds ?= $(1)_config_cmds ?= $(1)_stage_cmds ?= @@ -179,7 +178,7 @@ $($(1)_preprocessed): | $($(1)_extracted) $(AT)touch $$@ $($(1)_configured): | $($(1)_dependencies) $($(1)_preprocessed) $(AT)echo Configuring $(1)... - $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar --no-same-owner -xf $($(package)_cached); ) + $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), $(build_TAR) --no-same-owner -xf $($(package)_cached); ) $(AT)mkdir -p $$(@D) $(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1)) $(AT)touch $$@ @@ -200,7 +199,7 @@ $($(1)_postprocessed): | $($(1)_staged) $(AT)touch $$@ $($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed) $(AT)echo Caching $(1)... - $(AT)cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | tar --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - + $(AT)cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | $(build_TAR) --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - $(AT)mkdir -p $$(@D) $(AT)rm -rf $$(@D) && mkdir -p $$(@D) $(AT)mv $$($(1)_staging_dir)/$$(@F) $$(@) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 9f6808b3a5..99d923e00e 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -170,11 +170,11 @@ define $(package)_extract_cmds echo "$($(package)_qttools_sha256_hash) $($(package)_source_dir)/$($(package)_qttools_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ mkdir qtbase && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ + $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ mkdir qttranslations && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ + $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ mkdir qttools && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools + $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools endef # Preprocessing steps work as follows: From 61b4db3df09bb976a816a68edbeb7557713c5745 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 19:44:44 -0400 Subject: [PATCH 052/391] build: add support for OpenBSD to depends --- depends/Makefile | 2 + depends/README.md | 4 ++ depends/builders/openbsd.mk | 7 ++++ depends/hosts/openbsd.mk | 31 +++++++++++++++ depends/packages/bdb.mk | 1 + depends/packages/boost.mk | 3 ++ depends/packages/libevent.mk | 1 + depends/packages/zeromq.mk | 1 + .../patches/boost/fix_openbsd_test_lib.patch | 38 +++++++++++++++++++ 9 files changed, 88 insertions(+) create mode 100644 depends/builders/openbsd.mk create mode 100644 depends/hosts/openbsd.mk create mode 100644 depends/patches/boost/fix_openbsd_test_lib.patch diff --git a/depends/Makefile b/depends/Makefile index adf4c2b412..f411a89753 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -73,6 +73,7 @@ build_os:=$(findstring linux,$(full_build_os)) build_os+=$(findstring darwin,$(full_build_os)) build_os+=$(findstring freebsd,$(full_build_os)) build_os+=$(findstring netbsd,$(full_build_os)) +build_os+=$(findstring openbsd,$(full_build_os)) build_os:=$(strip $(build_os)) ifeq ($(build_os),) build_os=$(full_build_os) @@ -85,6 +86,7 @@ host_os:=$(findstring linux,$(full_host_os)) host_os+=$(findstring darwin,$(full_host_os)) host_os+=$(findstring freebsd,$(full_host_os)) host_os+=$(findstring netbsd,$(full_host_os)) +host_os+=$(findstring openbsd,$(full_host_os)) host_os+=$(findstring mingw32,$(full_host_os)) ifeq (android,$(findstring android,$(full_host_os))) diff --git a/depends/README.md b/depends/README.md index bfbe7b9833..1348a6c85f 100644 --- a/depends/README.md +++ b/depends/README.md @@ -69,6 +69,10 @@ For linux RISC-V 64-bit cross compilation (there are no packages for 32-bit): RISC-V known issue: gcc-7.3.0 and gcc-7.3.1 result in a broken `test_prcy` executable (see https://github.com/bitcoin/bitcoin/pull/13543), this is apparently fixed in gcc-8.1.0. +### Install the required dependencies: OpenBSD + + pkg_add bash gtar + ### Dependency Options The following can be set when running make: `make FOO=bar` diff --git a/depends/builders/openbsd.mk b/depends/builders/openbsd.mk new file mode 100644 index 0000000000..44825d106a --- /dev/null +++ b/depends/builders/openbsd.mk @@ -0,0 +1,7 @@ +build_openbsd_CC = clang +build_openbsd_CXX = clang++ + +build_openbsd_SHA256SUM = sha256 +build_openbsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o + +build_openbsd_TAR = gtar diff --git a/depends/hosts/openbsd.mk b/depends/hosts/openbsd.mk new file mode 100644 index 0000000000..dc8393e04c --- /dev/null +++ b/depends/hosts/openbsd.mk @@ -0,0 +1,31 @@ +openbsd_CFLAGS=-pipe +openbsd_CFLAGS_CXXFLAGS=$(openbsd_CFLAGS) + +openbsd_CFLAGS_release_CFLAGS=-O2 +openbsd_CFLAGS_release_CXXFLAGS=$(openbsd_release_CFLAGS) + +openbsd_CFLAGS_debug_CFLAGS=-O1 +openbsd_CFLAGS_debug_CXXFLAGS=$(openbsd_debug_CFLAGS) + +ifeq (86,$(findstring 86,$(build_arch))) +i686_openbsd_CC=clang -m32 +i686_openbsd_CXX=clang++ -m32 +i686_openbsd_AR=ar +i686_openbsd_RANLIB=ranlib +i686_openbsd_NM=nm +i686_openbsd_STRIP=strip + +x86_64_openbsd_CC=clang -m64 +x86_64_openbsd_CXX=clang++ -m64 +x86_64_openbsd_AR=ar +x86_64_openbsd_RANLIB=ranlib +x86_64_openbsd_NM=nm +x86_64_openbsd_STRIP=strip +else +i686_openbsd_CC=$(default_host_CC) -m32 +i686_openbsd_CXX=$(default_host_CXX) -m32 +x86_64_openbsd_CC=$(default_host_CC) -m64 +x86_64_openbsd_CXX=$(default_host_CXX) -m64 +endif + +openbsd_cmake_system=OpenBSD diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 44d68422ce..29287e1fdf 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -12,6 +12,7 @@ $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic $(package)_config_opts_netbsd=--with-pic +$(package)_config_opts_openbsd=--with-pic $(package)_cxxflags=-std=c++17 $(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index c4512704ae..576fab1a27 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -4,6 +4,7 @@ $(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(su $(package)_file_name=boost_$($(package)_version).tar.bz2 $(package)_sha256_hash=d73a8da01e8bf8c7eda40b4c84915071a8c8a0df4a6734537ddde4a8580524ee $(package)_dependencies=native_b2 +$(package)_patches=fix_openbsd_test_lib.patch define $(package)_set_vars $(package)_config_opts_release=variant=release @@ -34,10 +35,12 @@ $(package)_config_libraries=chrono,filesystem,program_options,system,thread,test $(package)_cxxflags=-std=c++17 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC $(package)_cxxflags_freebsd=-fPIC +$(package)_cxxflags_openbsd=-fPIC $(package)_cxxflags_android=-fPIC endef define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/fix_openbsd_test_lib.patch && \ echo "using $($(package)_toolset_$(host_os)) : : $($(package)_cxx) : \"$($(package)_cflags)\" \"$($(package)_cxxflags)\" \"$($(package)_cppflags)\" \"$($(package)_ldflags)\" \"$($(package)_ar)\" \"$(host_STRIP)\" \"$(host_RANLIB)\" \"$(host_WINDRES)\" : ;" > user-config.jam endef diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index e776a1f64b..699304af76 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -20,6 +20,7 @@ define $(package)_set_vars $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic $(package)_config_opts_netbsd=--with-pic + $(package)_config_opts_openbsd=--with-pic $(package)_config_opts_android=--with-pic $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 endef diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index f34e50d7d6..6f8afcb26e 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -12,6 +12,7 @@ define $(package)_set_vars $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic $(package)_config_opts_netbsd=--with-pic + $(package)_config_opts_openbsd=--with-pic $(package)_config_opts_android=--with-pic $(package)_cxxflags=-std=c++17 endef diff --git a/depends/patches/boost/fix_openbsd_test_lib.patch b/depends/patches/boost/fix_openbsd_test_lib.patch new file mode 100644 index 0000000000..84351065a3 --- /dev/null +++ b/depends/patches/boost/fix_openbsd_test_lib.patch @@ -0,0 +1,38 @@ +commit 684f067dde3b798877655cdda4eab8d7c26b2510 +Author: George Koehler +Date: Thu Oct 3 20:06:38 2019 -0400 + + OpenBSD is missing SI_ASYNCIO and SI_MESGQ + + Check if SI_ASYNCIO and SI_MESGQ are defined as macros. This allows + to run tests on OpenBSD 6.5, where the macros are missing. + + This is identical to patch-boost_test_impl_execution_monitor_ipp in + OpenBSD Ports, except that I added a comment. + + Can be removed when we use Boost 1.72.x or later. + +diff --git a/boost/test/impl/execution_monitor.ipp b/boost/test/impl/execution_monitor.ipp +index ccc44972..77a01e21 100644 +--- a/boost/test/impl/execution_monitor.ipp ++++ b/boost/test/impl/execution_monitor.ipp +@@ -391,14 +391,19 @@ system_signal_exception::report() const + report_error( execution_exception::system_error, + "signal: the expiration of a timer set by timer_settimer()" ); + break; ++// OpenBSD was missing SI_ASYNCIO and SI_MESGQ ++#ifdef SI_ASYNCIO + case SI_ASYNCIO: + report_error( execution_exception::system_error, + "signal: generated by the completion of an asynchronous I/O request" ); + break; ++#endif ++#ifdef SI_MESGQ + case SI_MESGQ: + report_error( execution_exception::system_error, + "signal: generated by the the arrival of a message on an empty message queue" ); + break; ++#endif + default: + break; + } From b5f0d61c484fc88ed15a883e309ee51d1d4bc3d0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 19:47:59 -0400 Subject: [PATCH 053/391] zeromq 4.3.4 --- depends/packages/zeromq.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index f34e50d7d6..c080a6f59f 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,8 +1,8 @@ package=zeromq -$(package)_version=4.3.1 +$(package)_version=4.3.4 $(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=bcbabe1e2c7d0eec4ed612e10b94b112dd5f06fcefa994a0c79a45d835cd21eb +$(package)_sha256_hash=c593001a89f5a85dd2ddf564805deb860e02471171b3f204944857336295c3e5 $(package)_patches=remove_libstd_link.patch define $(package)_set_vars From 92ea0f5f1c4bb7c644be2982f5ce7a8651c88d1b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 19:49:15 -0400 Subject: [PATCH 054/391] build: patch depends zeromq to fix building on NetBSD Current --- depends/packages/zeromq.mk | 4 +- .../patches/zeromq/netbsd_kevent_void.patch | 57 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 depends/patches/zeromq/netbsd_kevent_void.patch diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index c080a6f59f..aeda50b37c 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -3,7 +3,7 @@ $(package)_version=4.3.4 $(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=c593001a89f5a85dd2ddf564805deb860e02471171b3f204944857336295c3e5 -$(package)_patches=remove_libstd_link.patch +$(package)_patches=remove_libstd_link.patch netbsd_kevent_void.patch define $(package)_set_vars $(package)_config_opts=--without-docs --disable-shared --disable-curve --disable-curve-keygen --disable-perf --disable-Werror --disable-drafts @@ -18,10 +18,12 @@ endef define $(package)_preprocess_cmds patch -p1 < $($(package)_patch_dir)/remove_libstd_link.patch && \ + patch -p1 < $($(package)_patch_dir)/netbsd_kevent_void.patch && \ cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub config endef define $(package)_config_cmds + ./autogen.sh && \ $($(package)_autoconf) endef diff --git a/depends/patches/zeromq/netbsd_kevent_void.patch b/depends/patches/zeromq/netbsd_kevent_void.patch new file mode 100644 index 0000000000..4e36a363fb --- /dev/null +++ b/depends/patches/zeromq/netbsd_kevent_void.patch @@ -0,0 +1,57 @@ +commit 129137d5182967dbfcfec66bad843df2a992a78f +Author: fanquake +Date: Mon Jan 3 20:13:33 2022 +0800 + + problem: kevent udata is now void* on NetBSD Current (10) + + solution: check for the intptr_t variant in configure. + +diff --git a/configure.ac b/configure.ac +index 1a571291..402f8b86 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -308,6 +308,27 @@ case "${host_os}" in + if test "x$libzmq_netbsd_has_atomic" = "xno"; then + AC_DEFINE(ZMQ_FORCE_MUTEXES, 1, [Force to use mutexes]) + fi ++ # NetBSD Current (to become 10) has changed the type of udata in it's ++ # kevent struct from intptr_t to void * to align with darwin and other ++ # BSDs, see upstream commit: ++ # https://github.com/NetBSD/src/commit/e5ead823eb916b56589d2c6c560dbcfe4a2d0afc ++ AC_MSG_CHECKING([whether kevent udata type is intptr_t]) ++ AC_LANG_PUSH([C++]) ++ AC_LINK_IFELSE([AC_LANG_PROGRAM( ++ [[#include ++ #include ++ #include ]], ++ [[struct kevent ev; ++ intptr_t udata; ++ EV_SET(&ev, 0, 0, EV_ADD, 0, 0, udata); ++ return 0;]])], ++ [libzmq_netbsd_kevent_udata_intptr_t=yes], ++ [libzmq_netbsd_kevent_udata_intptr_t=no]) ++ AC_LANG_POP([C++]) ++ AC_MSG_RESULT([$libzmq_netbsd_kevent_udata_intptr_t]) ++ if test "x$libzmq_netbsd_kevent_udata_intptr_t" = "xyes"; then ++ AC_DEFINE(ZMQ_NETBSD_KEVENT_UDATA_INTPTR_T, 1, [kevent udata type is intptr_t]) ++ fi + ;; + *openbsd*|*bitrig*) + # Define on OpenBSD to enable all library features +diff --git a/src/kqueue.cpp b/src/kqueue.cpp +index 53d82ac4..a6a7a7f2 100644 +--- a/src/kqueue.cpp ++++ b/src/kqueue.cpp +@@ -46,9 +46,9 @@ + #include "i_poll_events.hpp" + #include "likely.hpp" + +-// NetBSD defines (struct kevent).udata as intptr_t, everyone else +-// as void *. +-#if defined ZMQ_HAVE_NETBSD ++// NetBSD up to version 9 defines (struct kevent).udata as intptr_t, ++// everyone else as void *. ++#if defined ZMQ_HAVE_NETBSD && defined(ZMQ_NETBSD_KEVENT_UDATA_INTPTR_T) + #define kevent_udata_t intptr_t + #else + #define kevent_udata_t void * From b9ba487f856036591476cee9c56cb5c54beee4c8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 21:59:03 -0400 Subject: [PATCH 055/391] build: set minimum supported macOS to 10.14 --- .github/workflows/prcy-build-factory-debug.yml | 4 ++-- .github/workflows/prcy-build-factory-ubuntu20.yml | 4 ++-- .github/workflows/prcy-build-factory.yml | 4 ++-- .travis.yml | 2 +- contrib/gitian-descriptors/gitian-osx.yml | 2 +- depends/README.md | 2 +- depends/hosts/darwin.mk | 2 +- doc/build-osx.md | 2 +- doc/release-notes.md | 2 +- share/qt/Info.plist.in | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/prcy-build-factory-debug.yml b/.github/workflows/prcy-build-factory-debug.yml index 66374f90f3..eb46f64266 100644 --- a/.github/workflows/prcy-build-factory-debug.yml +++ b/.github/workflows/prcy-build-factory-debug.yml @@ -196,12 +196,12 @@ jobs: fi working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build Dependencies - run: make -C depends HOST=x86_64-apple-darwin16 -j$(nproc) + run: make -C depends HOST=x86_64-apple-darwin18 -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin16) --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin18) --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml index b4ec4d66c5..d617a3f312 100644 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ b/.github/workflows/prcy-build-factory-ubuntu20.yml @@ -262,12 +262,12 @@ jobs: fi working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build Dependencies - run: make -C depends HOST=x86_64-apple-darwin16 -j$(nproc) + run: make -C depends HOST=x86_64-apple-darwin18 -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin16) --enable-upnp-default + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin18) --enable-upnp-default make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 86ed3c626c..128fd48586 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -261,12 +261,12 @@ jobs: fi working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build Dependencies - run: make -C depends HOST=x86_64-apple-darwin16 -j$(nproc) + run: make -C depends HOST=x86_64-apple-darwin18 -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin16) --enable-upnp-default --enable-reduce-exports + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin18) --enable-upnp-default --enable-reduce-exports make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} diff --git a/.travis.yml b/.travis.yml index 5912f40515..05686243f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -131,7 +131,7 @@ jobs: # Cross-Mac - stage: test env: >- - HOST=x86_64-apple-darwin16 + HOST=x86_64-apple-darwin18 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git" OSX_SDK=10.14 RUN_UNIT_TESTS=false diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 5297bacd7d..d1dee57368 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -37,7 +37,7 @@ script: | set -e -o pipefail WRAP_DIR=$HOME/wrapped - HOSTS="x86_64-apple-darwin16" + HOSTS="x86_64-apple-darwin18" CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" diff --git a/depends/README.md b/depends/README.md index 1348a6c85f..88c87c6ca9 100644 --- a/depends/README.md +++ b/depends/README.md @@ -21,7 +21,7 @@ created. To use it for Bitcoin: Common `host-platform-triplets` for cross compilation are: - `x86_64-w64-mingw32` for Win64 -- `x86_64-apple-darwin16` for macOS +- `x86_64-apple-darwin18` for macOS - `arm-linux-gnueabihf` for Linux ARM 32 bit - `aarch64-linux-gnu` for Linux ARM 64 bit - `riscv32-linux-gnu` for Linux RISC-V 32 bit diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 3e16780cca..3a11d1493e 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,4 +1,4 @@ -OSX_MIN_VERSION=10.12 +OSX_MIN_VERSION=10.14 OSX_SDK_VERSION=10.15.1 XCODE_VERSION=11.3.1 XCODE_BUILD_ID=11C505 diff --git a/doc/build-osx.md b/doc/build-osx.md index 3cbab97843..eabdbcd1d6 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -110,7 +110,7 @@ Other commands: Notes ----- -* Tested on OS X 10.12 Sierra through macOS 10.15 Catalina on 64-bit Intel processors only. +* Tested on OS X 10.14 Mojave through macOS 11 Big Sur on 64-bit Intel * Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714) diff --git a/doc/release-notes.md b/doc/release-notes.md index dfd904d06e..5972ff3257 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -20,7 +20,7 @@ Compatibility ============== PRCY is extensively tested on multiple operating systems using -the Linux kernel, macOS 10.8+, and Windows Vista and later. +the Linux kernel, macOS 10.14+, and Windows Vista and later. Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support), No attempt is made to prevent installing or running the software on Windows XP, you diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 4de8eb420e..ed45e41514 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -3,7 +3,7 @@ LSMinimumSystemVersion - 10.12.0 + 10.14.0 LSArchitecturePriority From c396fc2bc06566f3d895c1547411a9f7f9d1b409 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 22:17:10 -0400 Subject: [PATCH 056/391] depends: Allow relative CONFIG_SITE path env var Previously, if ./configure was invoked with: ``` $ env CONFIG_SITE=depends/x86_64-pc-linux-gnu/share/config.site ./configure ``` Where $CONFIG_SITE was a relative path, ./configure would fail with the following misleading output: ``` checking for boostlib >= 1.58.0 (105800)... yes checking whether the Boost::System library is available... yes configure: error: Could not find a version of the Boost::System library! ``` Fully resolving depends_prefix in config.site.in fixes this. To make sure that there are no other side effects I ran a diff on the config.status generated by: 1. The scripts prior to this change with CONFIG_SITE set to a full path: env CONFIG_SITE=$PWD/depends/x86_64-pc-linux-gnu/share/config.site ./configure 2. The scripts after this change with CONFIG_SITE set to a relative path: env CONFIG_SITE=depends/x86_64-pc-linux-gnu/share/config.site ./configure And it looks good! Diff: https://paste.sr.ht/~dongcarl/95b469fbc555c128046e85723d87a9082a754f6b --- depends/config.site.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/config.site.in b/depends/config.site.in index bb10f72734..a63bba8672 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -1,4 +1,4 @@ -depends_prefix="`dirname ${ac_site_file}`/.." +depends_prefix="$(cd "$(dirname ${ac_site_file})/.." && pwd)" cross_compiling=maybe host_alias=@HOST@ From 0e33d4becc6082012190f42aa86062ad74db2af6 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 22:19:23 -0400 Subject: [PATCH 057/391] lint: Also lint files with shellcheck directive Files like config.site.in are not referenced by any other script in our tree, so we need to mark it manually with a "shellcheck shell=" directive and make sure that shellcheck is run on them. --- depends/config.site.in | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/depends/config.site.in b/depends/config.site.in index a63bba8672..ab1894145b 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -1,3 +1,13 @@ +# shellcheck shell=sh disable=SC2034 # Many variables set will be used in + # ./configure but shellcheck doesn't know + # that, hence: disable=SC2034 + +true # Dummy command because shellcheck treats all directives before first + # command as file-wide, and we only want to disable for one line. + # + # See: https://github.com/koalaman/shellcheck/wiki/Directive + +# shellcheck disable=SC2154 depends_prefix="$(cd "$(dirname ${ac_site_file})/.." && pwd)" cross_compiling=maybe @@ -43,7 +53,7 @@ if test x@host_os@ = xdarwin; then fi PATH=$depends_prefix/native/bin:$PATH -PKG_CONFIG="`which pkg-config` --static" +PKG_CONFIG="$(which pkg-config) --static" # These two need to remain exported because pkg-config does not see them # otherwise. That means they must be unexported at the end of configure.ac to From 45654ee3f5330e2c5486765d5025d9ecf8cdabf5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 22:20:00 -0400 Subject: [PATCH 058/391] depends: Fix PYTHONPATH setting in config.site.in Previously, when running ./configure: 1. With CONFIG_SITE pointed to our depends config.site.in, and 2. PYTHONPATH was not set either in the environment or by the user The configure would output something like: PYTHONPATH='depends/x86_64-pc-linux-gnu/share/../native/lib/python3/dist-packages:' When we really mean: PYTHONPATH='depends/x86_64-pc-linux-gnu/share/../native/lib/python3/dist-packages' ...without the colon This change makes sure that: 1. There's no trailing colon, and 2. We use the $PATH_SEPARATOR variable instead of a colon --- depends/config.site.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/config.site.in b/depends/config.site.in index ab1894145b..5d0c76c712 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -72,7 +72,7 @@ fi if test -n "@CXX@" -a -z "${CXX}"; then CXX="@CXX@" fi -PYTHONPATH=$depends_prefix/native/lib/python3/dist-packages:$PYTHONPATH +PYTHONPATH="${depends_prefix}/native/lib/python3/dist-packages${PYTHONPATH:+${PATH_SEPARATOR}}${PYTHONPATH}" if test -n "@AR@"; then AR=@AR@ From 138f84309c4d36c6902a1604223be14961a78413 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 22:35:07 -0400 Subject: [PATCH 059/391] depends: Delay expansion of per-package vars Prior to this commit, when int_vars was called for packages, it would immediately expand the "single-dollar variables", which may be defined in terms of variables which are not yet determined (e.g. variables defined in package/*.mk, which are included after int_vars is called). This is required for the next commit as after that commit, for darwin cross-builds: 0. int_vars is defined in terms of $(1)_cc 1. $(1)_cc is defined in terms of darwin_CC 2. ... which is defined in terms of clang_resource_dir 3. ... which is defined in terms of native_cctools_clang_version 4. which is undetermined at the time when int_vars is being expanded and evaluated --- depends/funcs.mk | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index 7b8338f247..2695aecb85 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -1,17 +1,23 @@ define int_vars #Set defaults for vars which may be overridden per-package -$(1)_cc=$($($(1)_type)_CC) -$(1)_cxx=$($($(1)_type)_CXX) -$(1)_objc=$($($(1)_type)_OBJC) -$(1)_objcxx=$($($(1)_type)_OBJCXX) -$(1)_ar=$($($(1)_type)_AR) -$(1)_ranlib=$($($(1)_type)_RANLIB) -$(1)_libtool=$($($(1)_type)_LIBTOOL) -$(1)_nm=$($($(1)_type)_NM) -$(1)_cflags=$($($(1)_type)_CFLAGS) $($($(1)_type)_$(release_type)_CFLAGS) -$(1)_cxxflags=$($($(1)_type)_CXXFLAGS) $($($(1)_type)_$(release_type)_CXXFLAGS) -$(1)_ldflags=$($($(1)_type)_LDFLAGS) $($($(1)_type)_$(release_type)_LDFLAGS) -L$($($(1)_type)_prefix)/lib -$(1)_cppflags=$($($(1)_type)_CPPFLAGS) $($($(1)_type)_$(release_type)_CPPFLAGS) -I$($($(1)_type)_prefix)/include +$(1)_cc=$$($$($(1)_type)_CC) +$(1)_cxx=$$($$($(1)_type)_CXX) +$(1)_objc=$$($$($(1)_type)_OBJC) +$(1)_objcxx=$$($$($(1)_type)_OBJCXX) +$(1)_ar=$$($$($(1)_type)_AR) +$(1)_ranlib=$$($$($(1)_type)_RANLIB) +$(1)_libtool=$$($$($(1)_type)_LIBTOOL) +$(1)_nm=$$($$($(1)_type)_NM) +$(1)_cflags=$$($$($(1)_type)_CFLAGS) \ + $$($$($(1)_type)_$$(release_type)_CFLAGS) +$(1)_cxxflags=$$($$($(1)_type)_CXXFLAGS) \ + $$($$($(1)_type)_$$(release_type)_CXXFLAGS) +$(1)_ldflags=$$($$($(1)_type)_LDFLAGS) \ + $$($$($(1)_type)_$$(release_type)_LDFLAGS) \ + -L$$($($(1)_type)_prefix)/lib +$(1)_cppflags=$$($$($(1)_type)_CPPFLAGS) \ + $$($$($(1)_type)_$$(release_type)_CPPFLAGS) \ + -I$$($$($(1)_type)_prefix)/include $(1)_recipe_hash:= endef From 03e7360b62fdd848522137ff12150b6e8dcc3f26 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 22:36:06 -0400 Subject: [PATCH 060/391] depends: Pin clang search paths for darwin host --- depends/hosts/darwin.mk | 55 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 3a11d1493e..ca34b60543 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -6,6 +6,12 @@ LD64_VERSION=530 OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +clang_resource_dir=$(build_prefix)/lib/clang/$(native_cctools_clang_version) +else +clang_resource_dir=$(shell clang -print-resource-dir) +endif + # Flag explanations: # # -mlinker-version @@ -18,7 +24,7 @@ OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with- # Explicitly point to our binaries (e.g. cctools) so that they are # ensured to be found and preferred over other possibilities. # -# -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1 +# -stdlib=libc++ -nostdinc++ -Xclang -cxx-isystem$(OSX_SDK)/usr/include/c++/v1 # # Forces clang to use the libc++ headers from our SDK and completely # forget about the libc++ headers from the standard directories @@ -28,8 +34,51 @@ OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with- # https://reviews.llvm.org/D64089, we should use that instead. Read the # differential summary there for more details. # -darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -B$(build_prefix)/bin -darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -stdlib=libc++ -mlinker-version=$(LD64_VERSION) -B$(build_prefix)/bin -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1 +# -Xclang -*system \ +# -Xclang -*system \ +# -Xclang -*system ... +# +# Adds path_a, path_b, and path_c to the bottom of clang's list of +# include search paths. This is used to explicitly specify the list of +# system include search paths and its ordering, rather than rely on +# clang's autodetection routine. This routine has been shown to: +# 1. Fail to pickup libc++ headers in $SYSROOT/usr/include/c++/v1 +# when clang was built manually (see: https://github.com/bitcoin/bitcoin/pull/17919#issuecomment-656785034) +# 2. Fail to pickup C headers in $SYSROOT/usr/include when +# C_INCLUDE_DIRS was specified at configure time (see: https://gist.github.com/dongcarl/5cdc6990b7599e8a5bf6d2a9c70e82f9) +# +# Talking directly to cc1 with -Xclang here grants us access to specify +# more granular categories for these system include search paths, and we +# can use the correct categories that these search paths would have been +# placed in if the autodetection routine had worked correctly. (see: +# https://gist.github.com/dongcarl/5cdc6990b7599e8a5bf6d2a9c70e82f9#the-treatment) +# +# Furthermore, it places these search paths after any "non-Xclang" +# specified search paths. This prevents any additional clang options or +# environment variables from coming after or in between these system +# include search paths, as that would be wrong in general but would also +# break #include_next's. +# +darwin_CC=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ + -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \ + -u LIBRARY_PATH \ + clang --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ + -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ + -fuse-ld=$(build_prefix)/bin/x86_64-apple-darwin16-ld \ + --sysroot=$(OSX_SDK) \ + -Xclang -internal-externc-isystem$(clang_resource_dir)/include \ + -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include +darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ + -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \ + -u LIBRARY_PATH \ + clang++ --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ + -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ + -fuse-ld=$(build_prefix)/bin/x86_64-apple-darwin16-ld \ + --sysroot=$(OSX_SDK) \ + -stdlib=libc++ -nostdinc++ \ + -Xclang -cxx-isystem$(OSX_SDK)/usr/include/c++/v1 \ + -Xclang -internal-externc-isystem$(clang_resource_dir)/include \ + -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include darwin_CFLAGS=-pipe darwin_CXXFLAGS=$(darwin_CFLAGS) From ca63933bc0379f72cdaa9ad9d7d79e3b15b9b960 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 22:37:04 -0400 Subject: [PATCH 061/391] depends: Remove -fuse-ld line clang warns when a command line option is unused, and some of our tests use Werror, so unfortunately we cannot use this flag to pin our linker for now. Leaving this commit in for future reference, as it would be great if there's more granularity to Werror and we can be explicit about what linker we want to use. --- depends/hosts/darwin.mk | 2 -- 1 file changed, 2 deletions(-) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index ca34b60543..2a0613d779 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -64,7 +64,6 @@ darwin_CC=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ -u LIBRARY_PATH \ clang --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ - -fuse-ld=$(build_prefix)/bin/x86_64-apple-darwin16-ld \ --sysroot=$(OSX_SDK) \ -Xclang -internal-externc-isystem$(clang_resource_dir)/include \ -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include @@ -73,7 +72,6 @@ darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ -u LIBRARY_PATH \ clang++ --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ - -fuse-ld=$(build_prefix)/bin/x86_64-apple-darwin16-ld \ --sysroot=$(OSX_SDK) \ -stdlib=libc++ -nostdinc++ \ -Xclang -cxx-isystem$(OSX_SDK)/usr/include/c++/v1 \ From d51a603415f3c43ed83b9b868f1f0bc02b6b80cb Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 22:39:15 -0400 Subject: [PATCH 062/391] depends: Quote to prevent word splitting in config.site SC2086 is disabled in our linter script so this wasn't caught. --- depends/config.site.in | 75 ++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/depends/config.site.in b/depends/config.site.in index 5d0c76c712..391767357a 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -8,63 +8,74 @@ true # Dummy command because shellcheck treats all directives before first # See: https://github.com/koalaman/shellcheck/wiki/Directive # shellcheck disable=SC2154 -depends_prefix="$(cd "$(dirname ${ac_site_file})/.." && pwd)" +depends_prefix="$(cd "$(dirname "$ac_site_file")/.." && pwd)" cross_compiling=maybe -host_alias=@HOST@ -ac_tool_prefix=${host_alias}- +host_alias="@HOST@" +ac_tool_prefix="${host_alias}-" -if test -z $with_boost; then - with_boost=$depends_prefix +if test -z "$with_boost"; then + with_boost="$depends_prefix" fi -if test -z $with_qt_plugindir; then - with_qt_plugindir=$depends_prefix/plugins +if test -z "$with_qt_plugindir"; then + with_qt_plugindir="${depends_prefix}/plugins" fi -if test -z $with_qt_translationdir; then - with_qt_translationdir=$depends_prefix/translations +if test -z "$with_qt_translationdir"; then + with_qt_translationdir="${depends_prefix}/translations" fi -if test -z $with_qt_bindir && test -z "@no_qt@"; then - with_qt_bindir=$depends_prefix/native/bin +if test -z "$with_qt_bindir" && test -z "@no_qt@"; then + with_qt_bindir="${depends_prefix}/native/bin" +fi +if test -z "$with_mpgen" && test -n "@multiprocess@"; then + with_mpgen="${depends_prefix}/native" fi -if test -z $with_qrencode && test -n "@no_qr@"; then +if test -z "$with_qrencode" && test -n "@no_qr@"; then with_qrencode=no fi -if test -z $enable_wallet && test -n "@no_wallet@"; then +if test -z "$enable_wallet" && test -n "@no_wallet@"; then enable_wallet=no fi -if test -z $with_miniupnpc && test -n "@no_upnp@"; then +if test -z "$enable_multiprocess" && test -n "@multiprocess@"; then + enable_multiprocess=yes +fi + +if test -z "$with_miniupnpc" && test -n "@no_upnp@"; then with_miniupnpc=no fi -if test -z $with_gui && test -n "@no_qt@"; then +if test -z "$with_natpmp" && test -n "@no_natpmp@"; then + with_natpmp=no +fi + +if test -z "$with_gui" && test -n "@no_qt@"; then with_gui=no fi -if test -z $enable_zmq && test -n "@no_zmq@"; then +if test -z "$enable_zmq" && test -n "@no_zmq@"; then enable_zmq=no fi -if test x@host_os@ = xdarwin; then +if test "x@host_os@" = xdarwin; then BREW=no PORT=no fi -PATH=$depends_prefix/native/bin:$PATH +PATH="${depends_prefix}/native/bin:${PATH}" PKG_CONFIG="$(which pkg-config) --static" # These two need to remain exported because pkg-config does not see them # otherwise. That means they must be unexported at the end of configure.ac to # avoid ruining the cache. Sigh. -export PKG_CONFIG_PATH=$depends_prefix/share/pkgconfig:$depends_prefix/lib/pkgconfig +export PKG_CONFIG_PATH="${depends_prefix}/share/pkgconfig:${depends_prefix}/lib/pkgconfig" if test -z "@allow_host_packages@"; then - export PKG_CONFIG_LIBDIR=$depends_prefix/lib/pkgconfig + export PKG_CONFIG_LIBDIR="${depends_prefix}/lib/pkgconfig" fi -CPPFLAGS="-I$depends_prefix/include/ $CPPFLAGS" -LDFLAGS="-L$depends_prefix/lib $LDFLAGS" +CPPFLAGS="-I${depends_prefix}/include/ ${CPPFLAGS}" +LDFLAGS="-L${depends_prefix}/lib ${LDFLAGS}" if test -n "@CC@" -a -z "${CC}"; then CC="@CC@" @@ -75,18 +86,18 @@ fi PYTHONPATH="${depends_prefix}/native/lib/python3/dist-packages${PYTHONPATH:+${PATH_SEPARATOR}}${PYTHONPATH}" if test -n "@AR@"; then - AR=@AR@ - ac_cv_path_ac_pt_AR=${AR} + AR="@AR@" + ac_cv_path_ac_pt_AR="${AR}" fi if test -n "@RANLIB@"; then - RANLIB=@RANLIB@ - ac_cv_path_ac_pt_RANLIB=${RANLIB} + RANLIB="@RANLIB@" + ac_cv_path_ac_pt_RANLIB="${RANLIB}" fi if test -n "@NM@"; then - NM=@NM@ - ac_cv_path_ac_pt_NM=${NM} + NM="@NM@" + ac_cv_path_ac_pt_NM="${NM}" fi if test -n "@debug@"; then @@ -94,14 +105,14 @@ if test -n "@debug@"; then fi if test -n "@CFLAGS@"; then - CFLAGS="@CFLAGS@ $CFLAGS" + CFLAGS="@CFLAGS@ ${CFLAGS}" fi if test -n "@CXXFLAGS@"; then - CXXFLAGS="@CXXFLAGS@ $CXXFLAGS" + CXXFLAGS="@CXXFLAGS@ ${CXXFLAGS}" fi if test -n "@CPPFLAGS@"; then - CPPFLAGS="@CPPFLAGS@ $CPPFLAGS" + CPPFLAGS="@CPPFLAGS@ ${CPPFLAGS}" fi if test -n "@LDFLAGS@"; then - LDFLAGS="@LDFLAGS@ $LDFLAGS" + LDFLAGS="@LDFLAGS@ ${LDFLAGS}" fi From c108b75910d4c33057011d1c2d054725c22c19ec Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 22:44:05 -0400 Subject: [PATCH 063/391] depends: Fully determine path for darwin_{CC,CXX} Instead of doing the awkward /bin path prepending at config.site creation time, set darwin_{CC,CXX} in a way that fully determines the program's path (clang/clang++) similar to how AC_PATH_{TOOL,PROG} would do. Also see the added comment block in depends/Makefile for more context on determining $PATH for our config.site. --- depends/Makefile | 34 +++++++++++++++++++++++++++------- depends/hosts/darwin.mk | 34 +++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index f411a89753..ce6847d837 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -164,11 +164,7 @@ $(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain) include funcs.mk binutils_path=$($($(host_arch)_$(host_os)_native_binutils)_prefixbin) -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -toolchain_path=$($($(host_arch)_$(host_os)_native_toolchain)_prefixbin) -else -toolchain_path= -endif + final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in) final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)) $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) @@ -179,11 +175,35 @@ $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) $(AT)cd $(@D); $(foreach package,$^, $(build_TAR) xf $($(package)_cached); ) $(AT)touch $@ +# $PATH is not preserved between ./configure and make by convention. Its +# modification and overriding at ./configure time is (as I understand it) +# supposed to be captured by the AC_{PROG_{,OBJ}CXX,PATH_{PROG,TOOL}} macros, +# which will expand the program names to their full absolute paths. The notable +# exception is command line overriding: ./configure CC=clang, which skips the +# program name expansion step, and works because the user implicitly indicates +# with CC=clang that clang will be available in $PATH at all times, and is most +# likely part of the user's system. +# +# Therefore, when we "seed the autoconf cache"/"override well-known program +# vars" by setting AR= in our config.site, either one of two things needs +# to be true for the build system to work correctly: +# +# 1. If we refer to the program by name (e.g. AR=riscv64-gnu-linux-ar), the +# tool needs to be available in $PATH at all times. +# +# 2. If the tool is _**not**_ expected to be available in $PATH at all times +# (such as is the case for our native_cctools binutils tools), it needs to +# be referred to by its absolute path, such as would be output by the +# AC_PATH_{PROG,TOOL} macros. +# +# Minor note: it is also okay to refer to tools by their absolute path even if +# we expect them to be available in $PATH at all times, more specificity does +# not hurt. $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_build_id) $(AT)@mkdir -p $(@D) $(AT)sed -e 's|@HOST@|$(host)|' \ - -e 's|@CC@|$(toolchain_path)$(host_CC)|' \ - -e 's|@CXX@|$(toolchain_path)$(host_CXX)|' \ + -e 's|@CC@|$(host_CC)|' \ + -e 's|@CXX@|$(host_CXX)|' \ -e 's|@AR@|$(binutils_path)$(host_AR)|' \ -e 's|@RANLIB@|$(binutils_path)$(host_RANLIB)|' \ -e 's|@NM@|$(binutils_path)$(host_NM)|' \ diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 2a0613d779..d5a4c44d12 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -7,8 +7,33 @@ LD64_VERSION=530 OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +# FORCE_USE_SYSTEM_CLANG is empty, so we use our depends-managed, pinned clang +# from llvm.org + +# The native_cctools package is what provides clang when FORCE_USE_SYSTEM_CLANG +# is empty +darwin_native_toolchain=native_cctools + +clang_prog=$(build_prefix)/bin/clang +clangxx_prog=$(clang_prog)++ + clang_resource_dir=$(build_prefix)/lib/clang/$(native_cctools_clang_version) else +# FORCE_USE_SYSTEM_CLANG is non-empty, so we use the clang from the user's +# system + +darwin_native_toolchain= + +# We can't just use $(shell command -v clang) because GNU Make handles builtins +# in a special way and doesn't know that `command` is a POSIX-standard builtin +# prior to 1af314465e5dfe3e8baa839a32a72e83c04f26ef, first released in v4.2.90. +# At the time of writing, GNU Make v4.2.1 is still being used in supported +# distro releases. +# +# Source: https://lists.gnu.org/archive/html/bug-make/2017-11/msg00017.html +clang_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang") +clangxx_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang++") + clang_resource_dir=$(shell clang -print-resource-dir) endif @@ -62,7 +87,7 @@ endif darwin_CC=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \ -u LIBRARY_PATH \ - clang --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ + $(clang_prog) --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ --sysroot=$(OSX_SDK) \ -Xclang -internal-externc-isystem$(clang_resource_dir)/include \ @@ -70,7 +95,7 @@ darwin_CC=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \ -u LIBRARY_PATH \ - clang++ --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ + $(clangxx_prog) --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ --sysroot=$(OSX_SDK) \ -stdlib=libc++ -nostdinc++ \ @@ -88,8 +113,3 @@ darwin_debug_CFLAGS=-O1 darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS) darwin_native_binutils=native_cctools -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -darwin_native_toolchain=native_cctools -else -darwin_native_toolchain= -endif From a385658a16a7f912d1c97bde383858cef954693d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 22:47:09 -0400 Subject: [PATCH 064/391] depends: Fully determine path for darwin cctools See previous commit for description. --- depends/Makefile | 10 ++++------ depends/hosts/darwin.mk | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index ce6847d837..4e187c36ec 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -163,8 +163,6 @@ $(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain) include funcs.mk -binutils_path=$($($(host_arch)_$(host_os)_native_binutils)_prefixbin) - final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in) final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)) $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) @@ -204,10 +202,10 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ $(AT)sed -e 's|@HOST@|$(host)|' \ -e 's|@CC@|$(host_CC)|' \ -e 's|@CXX@|$(host_CXX)|' \ - -e 's|@AR@|$(binutils_path)$(host_AR)|' \ - -e 's|@RANLIB@|$(binutils_path)$(host_RANLIB)|' \ - -e 's|@NM@|$(binutils_path)$(host_NM)|' \ - -e 's|@STRIP@|$(binutils_path)$(host_STRIP)|' \ + -e 's|@AR@|$(host_AR)|' \ + -e 's|@RANLIB@|$(host_RANLIB)|' \ + -e 's|@NM@|$(host_NM)|' \ + -e 's|@STRIP@|$(host_STRIP)|' \ -e 's|@build_os@|$(build_os)|' \ -e 's|@host_os@|$(host_os)|' \ -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \ diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index d5a4c44d12..ee4a45154b 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -6,6 +6,8 @@ LD64_VERSION=530 OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers +darwin_native_binutils=native_cctools + ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) # FORCE_USE_SYSTEM_CLANG is empty, so we use our depends-managed, pinned clang # from llvm.org @@ -37,6 +39,16 @@ clangxx_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang++") clang_resource_dir=$(shell clang -print-resource-dir) endif +cctools_TOOLS=AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL + +# Make-only lowercase function +lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1)))))))))))))))))))))))))) + +# For well-known tools provided by cctools, make sure that their well-known +# variable is set to the full path of the tool, just like how AC_PATH_{TOO,PROG} +# would. +$(foreach TOOL,$(cctools_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/$$(host)-$(call lc,$(TOOL)))) + # Flag explanations: # # -mlinker-version @@ -111,5 +123,3 @@ darwin_release_CXXFLAGS=$(darwin_release_CFLAGS) darwin_debug_CFLAGS=-O1 darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS) - -darwin_native_binutils=native_cctools From a9d56c5b038667207725a8c6c799aad58b1ba74c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 22:48:11 -0400 Subject: [PATCH 065/391] depends: Add comment about cache invalidation --- depends/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/depends/Makefile b/depends/Makefile index 4e187c36ec..9541e1bf01 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -131,6 +131,8 @@ $(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null) $(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null) ifneq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +# Make sure that cache is invalidated when switching between system and +# depends-managed, pinned clang build_id_string+=system_clang $(host_arch)_$(host_os)_id_string+=system_clang endif From b546344ade5a585257ff0021f3ebd4933fc799a3 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 19:52:16 -0400 Subject: [PATCH 066/391] build: Update netbsd_kevent_void.patch This change fixes "Hunk #1 succeeded at 307 (offset -1 lines)." --- depends/patches/zeromq/netbsd_kevent_void.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/patches/zeromq/netbsd_kevent_void.patch b/depends/patches/zeromq/netbsd_kevent_void.patch index 4e36a363fb..845c6bdda6 100644 --- a/depends/patches/zeromq/netbsd_kevent_void.patch +++ b/depends/patches/zeromq/netbsd_kevent_void.patch @@ -10,7 +10,7 @@ diff --git a/configure.ac b/configure.ac index 1a571291..402f8b86 100644 --- a/configure.ac +++ b/configure.ac -@@ -308,6 +308,27 @@ case "${host_os}" in +@@ -307,6 +307,27 @@ case "${host_os}" in if test "x$libzmq_netbsd_has_atomic" = "xno"; then AC_DEFINE(ZMQ_FORCE_MUTEXES, 1, [Force to use mutexes]) fi From a1cbe88eebafc645c9cd3fc0a7342aae90d74e10 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 19:54:04 -0400 Subject: [PATCH 067/391] build: Disable libbsd when building zeromq package in depends Since v4.3.3 (068385c951c0608edec6264d55ba9c4c923acccc) libbsd is used by default. As we have no libbsd package in our depends, disable it explicitly. Zeromq will fallback to its internal strlcpy implementation. --- depends/packages/zeromq.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 6144596516..b3b1195e30 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -6,7 +6,8 @@ $(package)_sha256_hash=c593001a89f5a85dd2ddf564805deb860e02471171b3f204944857336 $(package)_patches=remove_libstd_link.patch netbsd_kevent_void.patch define $(package)_set_vars - $(package)_config_opts=--without-docs --disable-shared --disable-curve --disable-curve-keygen --disable-perf --disable-Werror --disable-drafts + $(package)_config_opts = --without-docs --disable-shared + $(package)_config_opts += --disable-perf --disable-curve-keygen --disable-curve --disable-libbsd --disable-Werror --disable-drafts $(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov $(package)_config_opts_linux=--with-pic From 79c057458fa4cbb389b820795c0fa4f155171a2a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 21 Mar 2023 19:54:24 -0400 Subject: [PATCH 068/391] build: Disable valgrind when building zeromq package in depends We are not running unit tests, therefore it is not required. --- depends/packages/zeromq.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index b3b1195e30..82e0dc7875 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=c593001a89f5a85dd2ddf564805deb860e02471171b3f204944857336 $(package)_patches=remove_libstd_link.patch netbsd_kevent_void.patch define $(package)_set_vars - $(package)_config_opts = --without-docs --disable-shared + $(package)_config_opts = --without-docs --disable-shared --disable-valgrind $(package)_config_opts += --disable-perf --disable-curve-keygen --disable-curve --disable-libbsd --disable-Werror --disable-drafts $(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov From d1f8bd9d47eae05ebfb31ce9b3fbb6227d95ad59 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 11:01:00 -0400 Subject: [PATCH 069/391] build: Run libdmg-hfsplus's DMG tool in make deploy Previously, the compression of the .iso file to a .dmg file was done outside of `make deploy' in order to use the faketime-wrapped version of libdmg-hfsplus's DMG tool. Specifying the faketime-wrapped version of the DMG tool to ./configure fixes this and simplifies build scripts. --- .gitignore | 1 + Makefile.am | 7 ++++++- configure.ac | 1 + contrib/gitian-descriptors/gitian-osx.yml | 8 +++----- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 81fcffeb57..98ef6e9435 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,7 @@ src/qt/test/moc*.cpp *.log *.trs *.dmg +*.iso *.raw.h diff --git a/Makefile.am b/Makefile.am index 980792cc52..0346549586 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,6 +32,7 @@ space := $(empty) $(empty) OSX_APP=PRCYcoin-Qt.app OSX_VOLNAME = $(subst $(space),-,$(PACKAGE_NAME)) OSX_DMG = $(OSX_VOLNAME).dmg +OSX_TEMP_ISO = $(OSX_DMG:.dmg=).temp.iso OSX_BACKGROUND_SVG=background.svg OSX_BACKGROUND_IMAGE=background.tiff OSX_BACKGROUND_IMAGE_DPIS=36 72 @@ -141,9 +142,13 @@ $(APP_DIST_DIR)/Applications: $(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt -$(OSX_DMG): $(APP_DIST_EXTRAS) +.INTERMEDIATE: $(OSX_TEMP_ISO) +$(OSX_TEMP_ISO): $(APP_DIST_EXTRAS) $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -apple -o $@ dist +$(OSX_DMG): $(OSX_TEMP_ISO) + $(DMG) dmg "$<" "$@" + dpi%.$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_SVG) sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d $* -p $* | $(IMAGEMAGICK_CONVERT) - $@ OSX_BACKGROUND_IMAGE_DPIFILES := $(foreach dpi,$(OSX_BACKGROUND_IMAGE_DPIS),dpi$(dpi).$(OSX_BACKGROUND_IMAGE)) diff --git a/configure.ac b/configure.ac index a42f38c06e..e2a8c97fbf 100644 --- a/configure.ac +++ b/configure.ac @@ -535,6 +535,7 @@ case $host in AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage) + AC_PATH_PROGS([DMG], [dmg], dmg) AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_PATH_PROGS([IMAGEMAGICK_CONVERT], [convert],convert) AC_PATH_PROGS([TIFFCP], [tiffcp],tiffcp) diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index d1dee57368..ab812d7846 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -6,7 +6,7 @@ suites: - "bionic" architectures: - "amd64" -packages: +packages: - "ca-certificates" - "curl" - "g++" @@ -38,7 +38,7 @@ script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin18" - CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage" + CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage DMG=$WRAP_DIR/dmg" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" @@ -140,7 +140,6 @@ script: | make osx_volname make deploydir - OSX_VOLNAME="$(cat osx_volname)" mkdir -p unsigned-app-${i} cp osx_volname unsigned-app-${i}/ cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i} @@ -153,8 +152,7 @@ script: | find . | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz popd - make deploy - ${WRAP_DIR}/dmg dmg "${OSX_VOLNAME}.dmg" ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg + make deploy OSX_DMG="${OUTDIR}/${DISTNAME}-osx-unsigned.dmg" cd installed find . -name "lib*.la" -delete From 3be00897f29c9b2668187e8d21db026db181208c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 11:22:53 -0400 Subject: [PATCH 070/391] build: Replace genisoimage with xorriso xorriso and its mkisofs/genisoimage emulation alter-ego xorrisofs are more maintained, and has the right toggles for us to achieve output determinism without using blunt tools like faketime. In this commit, we use xorrisofs from the build environment rather than building it ourselves using depends. This is not necessary and can be changed in the future. From https://wiki.debian.org/genisoimage?action=recall&rev=11 : > The classical command line interface for production of ISO 9660 > filesystem images is the option set established by program mkisofs. > For reasons of licensing and other problems with its author, Debian > ships a fork of mkisofs, called genisoimage, which was split off in > 2006 and then developed independently. > > Meanwhile, genisoimage gets no new features and not even bug fixes. It > is first choice only if its options -udf or -hfs are needed. > > Replacement in most uses cases, especially for bootable ISO 9660 > filesystems, archiving, and backup, is xorrisofs which starts the -as > mkisofs emulation mode of program xorriso. --- Makefile.am | 2 +- configure.ac | 2 +- contrib/gitian-descriptors/gitian-osx-signer.yml | 5 +++-- contrib/gitian-descriptors/gitian-osx.yml | 5 +++-- contrib/macdeploy/README.md | 14 +++++--------- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Makefile.am b/Makefile.am index 0346549586..7735a11a0f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -144,7 +144,7 @@ $(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt .INTERMEDIATE: $(OSX_TEMP_ISO) $(OSX_TEMP_ISO): $(APP_DIST_EXTRAS) - $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -apple -o $@ dist + $(XORRISOFS) -D -l -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -o $@ dist $(OSX_DMG): $(OSX_TEMP_ISO) $(DMG) dmg "$<" "$@" diff --git a/configure.ac b/configure.ac index e2a8c97fbf..b1524550fc 100644 --- a/configure.ac +++ b/configure.ac @@ -534,7 +534,7 @@ case $host in *) AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) - AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage) + AC_PATH_PROGS([XORRISOFS], [xorrisofs], xorrisofs) AC_PATH_PROGS([DMG], [dmg], dmg) AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_PATH_PROGS([IMAGEMAGICK_CONVERT], [convert],convert) diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index 936954a8c3..ba7fff5260 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -7,6 +7,7 @@ architectures: - "amd64" packages: - "faketime" +- "xorriso" remotes: - "url": "https://github.com/prcycoin/prcycoin-detached-sigs.git" "dir": "signature" @@ -18,7 +19,7 @@ script: | WRAP_DIR=$HOME/wrapped mkdir -p ${WRAP_DIR} export PATH=`pwd`:$PATH - FAKETIME_PROGS="dmg genisoimage" + FAKETIME_PROGS="dmg xorrisofs" # Create global faketime wrappers for prog in ${FAKETIME_PROGS}; do @@ -36,5 +37,5 @@ script: | tar -xf ${UNSIGNED} OSX_VOLNAME="$(cat osx_volname)" ./detached-sig-apply.sh ${UNSIGNED} signature/osx - ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "${OSX_VOLNAME}" -no-pad -r -dir-mode 0755 -apple -o uncompressed.dmg signed-app + ${WRAP_DIR}/xorrisofs -D -l -V "${OSX_VOLNAME}" -no-pad -r -dir-mode 0755 -o uncompressed.dmg signed-app ${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED} diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index ab812d7846..dba694c3c7 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -28,6 +28,7 @@ packages: - "python3-dev" - "python3-setuptools" - "fonts-tuffy" +- "xorriso" remotes: - "url": "https://github.com/prcycoin/prcycoin.git" "dir": "prcycoin" @@ -38,7 +39,7 @@ script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin18" - CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage DMG=$WRAP_DIR/dmg" + CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests XORRISOFS=${WRAP_DIR}/xorrisofs DMG=${WRAP_DIR}/dmg" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" @@ -144,7 +145,7 @@ script: | cp osx_volname unsigned-app-${i}/ cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i} cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i} - cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i} + cp ${BASEPREFIX}/${i}/native/bin/dmg unsigned-app-${i} cp ${BASEPREFIX}/${i}/native/bin/${i}-codesign_allocate unsigned-app-${i}/codesign_allocate cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff mv dist unsigned-app-${i} diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md index d21fce7d71..b6ea176197 100644 --- a/contrib/macdeploy/README.md +++ b/contrib/macdeploy/README.md @@ -92,19 +92,15 @@ created using these tools. The build process has been designed to avoid includin SDK's files in Gitian's outputs. All interim tarballs are fully deterministic and may be freely redistributed. -`genisoimage` is used to create the initial DMG. It is not deterministic as-is, so it has been -patched. A system `genisoimage` will work fine, but it will not be deterministic because -the file-order will change between invocations. The patch can be seen here: [cdrkit-deterministic.patch](https://github.com/prcycoin/prcycoin/blob/master/depends/patches/native_cdrkit/cdrkit-deterministic.patch). -No effort was made to fix this cleanly, so it likely leaks memory badly, however it's only used for -a single invocation, so that's no real concern. +[`xorrisofs`](https://www.gnu.org/software/xorriso/) is used to create the DMG. -`genisoimage` cannot compress DMGs, so afterwards, the DMG tool from the -`libdmg-hfsplus` project is used to compress it. There are several bugs in this tool and its -maintainer has seemingly abandoned the project. +`xorrisofs` cannot compress DMGs, so afterwards, the DMG tool from the +`libdmg-hfsplus` project is used to compress it. There are several bugs in this +tool and its maintainer has seemingly abandoned the project. The DMG tool has the ability to create DMGs from scratch as well, but this functionality is broken. Only the compression feature is currently used. Ideally, the creation could be fixed -and `genisoimage` would no longer be necessary. +and `xorrisofs` would no longer be necessary. Background images and other features can be added to DMG files by inserting a `.DS_Store` during creation. From 87fa2caeafd96a5b42c6301c51c4151818cbeb8c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 11:23:21 -0400 Subject: [PATCH 071/391] build: remove cdrkit package from depends --- depends/packages/native_cdrkit.mk | 26 ------ depends/packages/packages.mk | 2 +- .../native_cdrkit/cdrkit-deterministic.patch | 86 ------------------- 3 files changed, 1 insertion(+), 113 deletions(-) delete mode 100644 depends/packages/native_cdrkit.mk delete mode 100644 depends/patches/native_cdrkit/cdrkit-deterministic.patch diff --git a/depends/packages/native_cdrkit.mk b/depends/packages/native_cdrkit.mk deleted file mode 100644 index 8243458ec8..0000000000 --- a/depends/packages/native_cdrkit.mk +++ /dev/null @@ -1,26 +0,0 @@ -package=native_cdrkit -$(package)_version=1.1.11 -$(package)_download_path=https://distro.ibiblio.org/fatdog/source/600/c -$(package)_file_name=cdrkit-$($(package)_version).tar.bz2 -$(package)_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564 -$(package)_patches=cdrkit-deterministic.patch - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/cdrkit-deterministic.patch -endef - -define $(package)_config_cmds - cmake -DCMAKE_INSTALL_PREFIX=$(build_prefix) -endef - -define $(package)_build_cmds - $(MAKE) genisoimage -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) -C genisoimage install -endef - -define $(package)_postprocess_cmds - rm bin/isovfy bin/isoinfo bin/isodump bin/isodebug bin/devdump -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 0ecc090e83..972e919be8 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -19,5 +19,5 @@ darwin_native_packages = native_ds_store native_mac_alias $(host_arch)_$(host_os)_native_packages += native_b2 ifneq ($(build_os),darwin) -darwin_native_packages += native_cctools native_cdrkit native_libdmg-hfsplus +darwin_native_packages += native_cctools native_libdmg-hfsplus endif diff --git a/depends/patches/native_cdrkit/cdrkit-deterministic.patch b/depends/patches/native_cdrkit/cdrkit-deterministic.patch deleted file mode 100644 index 8ab0993dc4..0000000000 --- a/depends/patches/native_cdrkit/cdrkit-deterministic.patch +++ /dev/null @@ -1,86 +0,0 @@ ---- cdrkit-1.1.11.old/genisoimage/tree.c 2008-10-21 19:57:47.000000000 -0400 -+++ cdrkit-1.1.11/genisoimage/tree.c 2013-12-06 00:23:18.489622668 -0500 -@@ -1139,8 +1139,9 @@ - scan_directory_tree(struct directory *this_dir, char *path, - struct directory_entry *de) - { -- DIR *current_dir; -+ int current_file; - char whole_path[PATH_MAX]; -+ struct dirent **d_list; - struct dirent *d_entry; - struct directory *parent; - int dflag; -@@ -1164,7 +1165,8 @@ - this_dir->dir_flags |= DIR_WAS_SCANNED; - - errno = 0; /* Paranoia */ -- current_dir = opendir(path); -+ //current_dir = opendir(path); -+ current_file = scandir(path, &d_list, NULL, alphasort); - d_entry = NULL; - - /* -@@ -1173,12 +1175,12 @@ - */ - old_path = path; - -- if (current_dir) { -+ if (current_file >= 0) { - errno = 0; -- d_entry = readdir(current_dir); -+ d_entry = d_list[0]; - } - -- if (!current_dir || !d_entry) { -+ if (current_file < 0 || !d_entry) { - int ret = 1; - - #ifdef USE_LIBSCHILY -@@ -1191,8 +1193,8 @@ - de->isorec.flags[0] &= ~ISO_DIRECTORY; - ret = 0; - } -- if (current_dir) -- closedir(current_dir); -+ if(d_list) -+ free(d_list); - return (ret); - } - #ifdef ABORT_DEEP_ISO_ONLY -@@ -1208,7 +1210,7 @@ - errmsgno(EX_BAD, "use Rock Ridge extensions via -R or -r,\n"); - errmsgno(EX_BAD, "or allow deep ISO9660 directory nesting via -D.\n"); - } -- closedir(current_dir); -+ free(d_list); - return (1); - } - #endif -@@ -1250,13 +1252,13 @@ - * The first time through, skip this, since we already asked - * for the first entry when we opened the directory. - */ -- if (dflag) -- d_entry = readdir(current_dir); -+ if (dflag && current_file >= 0) -+ d_entry = d_list[current_file]; - dflag++; - -- if (!d_entry) -+ if (current_file < 0) - break; -- -+ current_file--; - /* OK, got a valid entry */ - - /* If we do not want all files, then pitch the backups. */ -@@ -1348,7 +1350,7 @@ - insert_file_entry(this_dir, whole_path, d_entry->d_name); - #endif /* APPLE_HYB */ - } -- closedir(current_dir); -+ free(d_list); - - #ifdef APPLE_HYB - /* From e0ea1b35cbfe4363c5811a3a364e8f28d122f5b8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 12:35:14 -0400 Subject: [PATCH 072/391] build: split native_cctools --- depends/hosts/darwin.mk | 5 +- depends/packages/native_cctools.mk | 96 +++--------------------------- depends/packages/native_clang.mk | 26 ++++++++ depends/packages/native_libtapi.mk | 20 +++++++ depends/packages/packages.mk | 7 ++- 5 files changed, 63 insertions(+), 91 deletions(-) create mode 100644 depends/packages/native_clang.mk create mode 100644 depends/packages/native_libtapi.mk diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index ee4a45154b..6c750c24a4 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -12,14 +12,13 @@ ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) # FORCE_USE_SYSTEM_CLANG is empty, so we use our depends-managed, pinned clang # from llvm.org -# The native_cctools package is what provides clang when FORCE_USE_SYSTEM_CLANG -# is empty +# Clang is a dependency of native_cctools when FORCE_USE_SYSTEM_CLANG is empty darwin_native_toolchain=native_cctools clang_prog=$(build_prefix)/bin/clang clangxx_prog=$(clang_prog)++ -clang_resource_dir=$(build_prefix)/lib/clang/$(native_cctools_clang_version) +clang_resource_dir=$(build_prefix)/lib/clang/$(native_clang_version) else # FORCE_USE_SYSTEM_CLANG is non-empty, so we use the clang from the user's # system diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index d56b636695..c789dab74c 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -5,81 +5,19 @@ $(package)_file_name=$($(package)_version).tar.gz $(package)_sha256_hash=e51995a843533a3dac155dd0c71362dd471597a2d23f13dff194c6285362f875 $(package)_build_subdir=cctools $(package)_patches=ld64_disable_threading.patch - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -$(package)_clang_version=8.0.0 -$(package)_clang_download_path=https://releases.llvm.org/$($(package)_clang_version) -$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz -$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz -$(package)_clang_sha256_hash=9ef854b71949f825362a119bf2597f744836cb571131ae6b721cd102ffea8cd0 -endif - -$(package)_libtapi_version=3efb201881e7a76a21e0554906cf306432539cef -$(package)_libtapi_download_path=https://github.com/tpoechtrager/apple-libtapi/archive -$(package)_libtapi_download_file=$($(package)_libtapi_version).tar.gz -$(package)_libtapi_file_name=$($(package)_libtapi_version).tar.gz -$(package)_libtapi_sha256_hash=380c1ca37cfa04a8699d0887a8d3ee1ad27f3d08baba78887c73b09485c0fbd3 - -$(package)_extra_sources=$($(package)_libtapi_file_name) -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -$(package)_extra_sources += $($(package)_clang_file_name) -endif - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -define $(package)_fetch_cmds -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash)) -endef -else -define $(package)_fetch_cmds -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash)) -endef -endif - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -define $(package)_extract_cmds - mkdir -p $($(package)_extract_dir) && \ - echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_clang_sha256_hash) $($(package)_source_dir)/$($(package)_clang_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir -p toolchain/bin toolchain/lib/clang/$($(package)_clang_version)/include && \ - mkdir -p libtapi && \ - tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \ - tar --no-same-owner --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ - rm -f toolchain/lib/libc++abi.so* && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source) -endef -else -define $(package)_extract_cmds - mkdir -p $($(package)_extract_dir) && \ - echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir -p libtapi && \ - tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source) -endef -endif +$(package)_dependencies=native_libtapi define $(package)_set_vars - $(package)_config_opts=--target=$(host) --with-libtapi=$($(package)_extract_dir) + $(package)_config_opts=--target=$(host) $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) - $(package)_config_opts+=--enable-lto-support --with-llvm-config=$($(package)_extract_dir)/toolchain/bin/llvm-config - $(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang - $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ - else - $(package)_cc=clang - $(package)_cxx=clang++ + $(package)_config_opts+=--enable-lto-support --with-llvm-config=$(build_prefix)/bin/llvm-config endif + $(package)_cc=$(clang_prog) + $(package)_cxx=$(clangxx_prog) endef define $(package)_preprocess_cmds - CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/build.sh && \ - CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/install.sh && \ patch -p1 < $($(package)_patch_dir)/ld64_disable_threading.patch endef @@ -91,26 +29,10 @@ define $(package)_build_cmds $(MAKE) endef -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ - mkdir -p $($(package)_staging_prefix_dir)/lib/ && \ - cd $($(package)_extract_dir) && \ - cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ && \ - cd $($(package)_extract_dir)/toolchain && \ - mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \ - mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \ - cp bin/clang $($(package)_staging_prefix_dir)/bin/ &&\ - cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ - cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ - cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \ - cp bin/dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil + $(MAKE) DESTDIR=$($(package)_staging_dir) install endef -else -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ - mkdir -p $($(package)_staging_prefix_dir)/lib/ && \ - cd $($(package)_extract_dir) && \ - cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ + +define $(package)_postprocess_cmds + rm -rf share endef -endif diff --git a/depends/packages/native_clang.mk b/depends/packages/native_clang.mk new file mode 100644 index 0000000000..741ddacf09 --- /dev/null +++ b/depends/packages/native_clang.mk @@ -0,0 +1,26 @@ +package=native_clang +$(package)_version=8.0.0 +$(package)_download_path=https://releases.llvm.org/$($(package)_version) +$(package)_download_file=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz +$(package)_file_name=clang-llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz +$(package)_sha256_hash=9ef854b71949f825362a119bf2597f744836cb571131ae6b721cd102ffea8cd0 + +define $(package)_preprocess_cmds + rm -f $($(package)_extract_dir)/lib/libc++abi.so* +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_version)/include && \ + mkdir -p $($(package)_staging_prefix_dir)/bin && \ + mkdir -p $($(package)_staging_prefix_dir)/include && \ + cp bin/clang $($(package)_staging_prefix_dir)/bin/ && \ + cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ && \ + cp bin/dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ + cp bin/llvm-config $($(package)_staging_prefix_dir)/bin/ && \ + cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ + cp -rf lib/clang/$($(package)_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_version)/include/ +endef + +define $(package)_postprocess_cmds + rmdir include +endef diff --git a/depends/packages/native_libtapi.mk b/depends/packages/native_libtapi.mk new file mode 100644 index 0000000000..d7ac4156a7 --- /dev/null +++ b/depends/packages/native_libtapi.mk @@ -0,0 +1,20 @@ +package=native_libtapi +$(package)_version=3efb201881e7a76a21e0554906cf306432539cef +$(package)_download_path=https://github.com/tpoechtrager/apple-libtapi/archive +$(package)_download_file=$($(package)_version).tar.gz +$(package)_file_name=$($(package)_version).tar.gz +$(package)_sha256_hash=380c1ca37cfa04a8699d0887a8d3ee1ad27f3d08baba78887c73b09485c0fbd3 + +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +$(package)_dependencies=native_clang +endif + +define $(package)_build_cmds + CC=$(clang_prog) CXX=$(clangxx_prog) INSTALLPREFIX=$($(package)_staging_prefix_dir) ./build.sh +endef + +define $(package)_stage_cmds + ./install.sh && \ + mkdir -p $($(package)_staging_prefix_dir)/include/llvm-c && \ + cp src/llvm/include/llvm-c/lto.h $($(package)_staging_prefix_dir)/include/llvm-c +endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 972e919be8..3bd2cfec90 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -19,5 +19,10 @@ darwin_native_packages = native_ds_store native_mac_alias $(host_arch)_$(host_os)_native_packages += native_b2 ifneq ($(build_os),darwin) -darwin_native_packages += native_cctools native_libdmg-hfsplus +darwin_native_packages += native_cctools native_libtapi native_libdmg-hfsplus + +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +darwin_native_packages+= native_clang +endif + endif From 817425438f281329643b1f2bf080ec6bf60ca036 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 12:44:55 -0400 Subject: [PATCH 073/391] build: libtapi 1100.0.11 --- depends/packages/native_libtapi.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/native_libtapi.mk b/depends/packages/native_libtapi.mk index d7ac4156a7..60b898da5f 100644 --- a/depends/packages/native_libtapi.mk +++ b/depends/packages/native_libtapi.mk @@ -1,9 +1,9 @@ package=native_libtapi -$(package)_version=3efb201881e7a76a21e0554906cf306432539cef +$(package)_version=664b8414f89612f2dfd35a9b679c345aa5389026 $(package)_download_path=https://github.com/tpoechtrager/apple-libtapi/archive $(package)_download_file=$($(package)_version).tar.gz $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=380c1ca37cfa04a8699d0887a8d3ee1ad27f3d08baba78887c73b09485c0fbd3 +$(package)_sha256_hash=62e419c12d1c9fad67cc1cd523132bc00db050998337c734c15bc8d73cc02b61 ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) $(package)_dependencies=native_clang From 8a40a85a22c3dbbc198b56dc97ea07950c13d526 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 12:50:23 -0400 Subject: [PATCH 074/391] build: Clang 10.0.1 LLVM 8 has inherent nondeterminism in the compiler, fixed in LLVM 9+. --- depends/packages/native_clang.mk | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/depends/packages/native_clang.mk b/depends/packages/native_clang.mk index 741ddacf09..1131593ac7 100644 --- a/depends/packages/native_clang.mk +++ b/depends/packages/native_clang.mk @@ -1,9 +1,8 @@ -package=native_clang -$(package)_version=8.0.0 -$(package)_download_path=https://releases.llvm.org/$($(package)_version) -$(package)_download_file=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz -$(package)_file_name=clang-llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz -$(package)_sha256_hash=9ef854b71949f825362a119bf2597f744836cb571131ae6b721cd102ffea8cd0 +$(package)_version=10.0.1 +$(package)_download_path=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) +$(package)_download_file=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-16.04.tar.xz +$(package)_file_name=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-16.04.tar.xz +$(package)_sha256_hash=48b83ef827ac2c213d5b64f5ad7ed082c8bcb712b46644e0dc5045c6f462c231 define $(package)_preprocess_cmds rm -f $($(package)_extract_dir)/lib/libc++abi.so* From 7c0618a8b8cc13c8f37251c0f3a8e9a0e8c8935c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 12:56:13 -0400 Subject: [PATCH 075/391] build: native cctools 973.0.1, ld64 609 --- depends/hosts/darwin.mk | 2 +- depends/packages/native_cctools.mk | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 6c750c24a4..23b0e47b11 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -2,7 +2,7 @@ OSX_MIN_VERSION=10.14 OSX_SDK_VERSION=10.15.1 XCODE_VERSION=11.3.1 XCODE_BUILD_ID=11C505 -LD64_VERSION=530 +LD64_VERSION=609 OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index c789dab74c..7e51f8a23d 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,8 +1,8 @@ package=native_cctools -$(package)_version=55562e4073dea0fbfd0b20e0bf69ffe6390c7f97 +$(package)_version=2ef2e931cf641547eb8a68cfebde61003587c9fd $(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=e51995a843533a3dac155dd0c71362dd471597a2d23f13dff194c6285362f875 +$(package)_sha256_hash=6b73269efdf5c58a070e7357b66ee760501388549d6a12b423723f45888b074b $(package)_build_subdir=cctools $(package)_patches=ld64_disable_threading.patch $(package)_dependencies=native_libtapi From 83b90dde05812c18f607cf73bb4f5012ffa1b1ad Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 13:03:29 -0400 Subject: [PATCH 076/391] build: Xcode 12.1, macOS SDK 10.15.6 --- .../workflows/prcy-build-factory-ubuntu20.yml | 4 ++-- .github/workflows/prcy-build-factory.yml | 4 ++-- contrib/gitian-descriptors/gitian-osx.yml | 4 ++-- contrib/macdeploy/README.md | 16 ++++++++-------- depends/hosts/darwin.mk | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml index d617a3f312..d77947397b 100644 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ b/.github/workflows/prcy-build-factory-ubuntu20.yml @@ -232,8 +232,8 @@ jobs: shell: bash run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - export XCODE_VERSION=11.3.1 - export XCODE_BUILD_ID=11C505 + export XCODE_VERSION=12.1 + export XCODE_BUILD_ID=12A7403 echo "VERSION=${VERSION}" >> $GITHUB_ENV echo "XCODE_VERSION=${XCODE_VERSION}" >> $GITHUB_ENV echo "XCODE_BUILD_ID=${XCODE_BUILD_ID}" >> $GITHUB_ENV diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 128fd48586..d9bf7ad8ed 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -231,8 +231,8 @@ jobs: shell: bash run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - export XCODE_VERSION=11.3.1 - export XCODE_BUILD_ID=11C505 + export XCODE_VERSION=12.1 + export XCODE_BUILD_ID=12A7403 echo "VERSION=${VERSION}" >> $GITHUB_ENV echo "XCODE_VERSION=${XCODE_VERSION}" >> $GITHUB_ENV echo "XCODE_BUILD_ID=${XCODE_BUILD_ID}" >> $GITHUB_ENV diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index dba694c3c7..fdc84fce9e 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -33,7 +33,7 @@ remotes: - "url": "https://github.com/prcycoin/prcycoin.git" "dir": "prcycoin" files: -- "Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz" +- "Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz" script: | set -e -o pipefail @@ -90,7 +90,7 @@ script: | BASEPREFIX=`pwd`/depends mkdir -p ${BASEPREFIX}/SDKs - tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz + tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz # Build dependencies for each host for i in $HOSTS; do diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md index b6ea176197..5552e53d7f 100644 --- a/contrib/macdeploy/README.md +++ b/contrib/macdeploy/README.md @@ -13,9 +13,9 @@ When complete, it will have produced `PRCYcoin-Core.dmg`. ### Step 1: Obtaining `Xcode.app` Our current macOS SDK -(`Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz`) can be +(`Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz`) can be extracted from -[Xcode_11.3.1.xip](https://download.developer.apple.com/Developer_Tools/Xcode_11.3.1/Xcode_11.3.1.xip). +[Xcode_12.1.xip](https://download.developer.apple.com/Developer_Tools/Xcode_12.1/Xcode_12.1.xip). An Apple ID is needed to download this. After Xcode version 7.x, Apple started shipping the `Xcode.app` in a `.xip` @@ -27,25 +27,25 @@ approach (tested on Debian Buster) is outlined below: apt install cpio git clone https://github.com/bitcoin-core/apple-sdk-tools.git -# Unpack Xcode_11.3.1.xip and place the resulting Xcode.app in your current +# Unpack Xcode_12.1.xip and place the resulting Xcode.app in your current # working directory -python3 apple-sdk-tools/extract_xcode.py -f Xcode_11.3.1.xip | cpio -d -i +python3 apple-sdk-tools/extract_xcode.py -f Xcode_12.1.xip | cpio -d -i ``` On macOS the process is more straightforward: ```bash -xip -x Xcode_11.3.1.xip +xip -x Xcode_12.1.xip ``` -### Step 2: Generating `Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz` from `Xcode.app` +### Step 2: Generating `Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz` from `Xcode.app` -To generate `Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz`, run +To generate `Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz`, run the script [`gen-sdk`](./gen-sdk) with the path to `Xcode.app` (extracted in the previous stage) as the first argument. ```bash -# Generate a Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz from +# Generate a Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz from # the supplied Xcode.app ./contrib/macdeploy/gen-sdk '/path/to/Xcode.app' ``` diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 23b0e47b11..48b29c1a17 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,7 +1,7 @@ OSX_MIN_VERSION=10.14 -OSX_SDK_VERSION=10.15.1 -XCODE_VERSION=11.3.1 -XCODE_BUILD_ID=11C505 +OSX_SDK_VERSION=10.15.6 +XCODE_VERSION=12.1 +XCODE_BUILD_ID=12A7403 LD64_VERSION=609 OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers From c83809727015ca23a81f2965793d74cb3c917194 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 13:13:03 -0400 Subject: [PATCH 077/391] build: no longer patch threading out of ld64 Changes introduced in ld64-450.3 have likely removed the need for us to patch out pthreads. See: https://opensource.apple.com/source/ld64/ld64-450.3/src/ld/InputFiles.cpp.auto.html. --- depends/packages/native_cctools.mk | 5 ---- .../ld64_disable_threading.patch | 26 ------------------- 2 files changed, 31 deletions(-) delete mode 100755 depends/patches/native_cctools/ld64_disable_threading.patch diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index 7e51f8a23d..885207fce9 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -4,7 +4,6 @@ $(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz $(package)_sha256_hash=6b73269efdf5c58a070e7357b66ee760501388549d6a12b423723f45888b074b $(package)_build_subdir=cctools -$(package)_patches=ld64_disable_threading.patch $(package)_dependencies=native_libtapi define $(package)_set_vars @@ -17,10 +16,6 @@ define $(package)_set_vars $(package)_cxx=$(clangxx_prog) endef -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/ld64_disable_threading.patch -endef - define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/patches/native_cctools/ld64_disable_threading.patch b/depends/patches/native_cctools/ld64_disable_threading.patch deleted file mode 100755 index d6c58c102f..0000000000 --- a/depends/patches/native_cctools/ld64_disable_threading.patch +++ /dev/null @@ -1,26 +0,0 @@ -commit 584668415039adeed073decee7e04de28248afd3 -Author: fanquake -Date: Tue Aug 18 01:20:24 2020 +0000 - - Disable threading to fix non-determinism - - A bug in the file parser can cause dependencies to be calculated - differently based on which files have already been parsed. This is more - likely to occur on systems with more CPUs. - - Just disable threading for now. There is no noticable slowdown. - - See #9891. - -diff --git a/cctools/ld64/src/ld/InputFiles.h b/cctools/ld64/src/ld/InputFiles.h -index ef9c756..90a70b6 100644 ---- a/cctools/ld64/src/ld/InputFiles.h -+++ b/cctools/ld64/src/ld/InputFiles.h -@@ -25,7 +25,6 @@ - #ifndef __INPUT_FILES_H__ - #define __INPUT_FILES_H__ - --#define HAVE_PTHREADS 1 - - #include - #include From 72083ebc9dcaf99be895b60e37f2d29b2ce97597 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 13:20:34 -0400 Subject: [PATCH 078/391] build: use -stdlib++-isystem with Clang 10 --- depends/hosts/darwin.mk | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 48b29c1a17..c2f6a60b62 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -60,16 +60,11 @@ $(foreach TOOL,$(cctools_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/$$( # Explicitly point to our binaries (e.g. cctools) so that they are # ensured to be found and preferred over other possibilities. # -# -stdlib=libc++ -nostdinc++ -Xclang -cxx-isystem$(OSX_SDK)/usr/include/c++/v1 +# -stdlib=libc++ -stdlib++-isystem$(OSX_SDK)/usr/include/c++/v1 # # Forces clang to use the libc++ headers from our SDK and completely # forget about the libc++ headers from the standard directories # -# TODO: Once we start requiring a clang version that has the -# -stdlib++-isystem flag first introduced here: -# https://reviews.llvm.org/D64089, we should use that instead. Read the -# differential summary there for more details. -# # -Xclang -*system \ # -Xclang -*system \ # -Xclang -*system ... @@ -109,8 +104,8 @@ darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ $(clangxx_prog) --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ --sysroot=$(OSX_SDK) \ - -stdlib=libc++ -nostdinc++ \ - -Xclang -cxx-isystem$(OSX_SDK)/usr/include/c++/v1 \ + -stdlib=libc++ \ + -stdlib++-isystem$(OSX_SDK)/usr/include/c++/v1 \ -Xclang -internal-externc-isystem$(clang_resource_dir)/include \ -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include From 3c5ea24afd733c68c97ed7f203d222f355a0bdca Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 15:13:09 -0400 Subject: [PATCH 079/391] depends: expat 2.2.7 --- depends/packages/expat.mk | 8 ++++---- doc/dependencies.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 7479f31e2c..59ce5b21f3 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,11 +1,11 @@ package=expat -$(package)_version=2.2.6 -$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_2_6/ +$(package)_version=2.2.7 +$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_2_7/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=17b43c2716d521369f82fc2dc70f359860e90fa440bea65b3b85f0b246ea81f2 +$(package)_sha256_hash=cbc9102f4a31a8dafd42d642e9a3aa31e79a0aedaa1f6efd2795ebc83174ec18 define $(package)_set_vars - $(package)_config_opts=--disable-shared --without-docbook + $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples $(package)_config_opts_linux=--with-pic endef diff --git a/doc/dependencies.md b/doc/dependencies.md index 9d3e3e4327..406a28edf8 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -9,7 +9,7 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | Boost | [1.71.0](https://www.boost.org/users/download/) | [1.57.0](https://github.com/PRCYCoin/PRCYCoin/pull/286) | No | | | | Clang | | [3.3+](https://llvm.org/releases/download.html) (C++11 support) | | | | | D-Bus | [1.10.18](https://cgit.freedesktop.org/dbus/dbus/tree/NEWS?h=dbus-1.10) | | No | Yes | | -| Expat | [2.2.6](https://libexpat.github.io/) | | No | Yes | | +| Expat | [2.2.7](https://libexpat.github.io/) | | No | Yes | | | fontconfig | [2.12.1](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | | FreeType | [2.7.1](https://download.savannah.gnu.org/releases/freetype) | | No | | | | GCC | | [4.8+](https://gcc.gnu.org/) (C++11 support) | | | | From feff4bd5a9e5ca7b70341b8afe2e31ac74127f42 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 15:35:46 -0400 Subject: [PATCH 080/391] build: only pass --disable-dependency-tracking to packages that understand it By blanket passing --disable-dependency-tracking to all depends packages we end up with some warnings like: configure: WARNING: unrecognized options: --disable-dependency-tracking So instead, only pass it to packages that understand it. --- depends/funcs.mk | 2 +- depends/packages/expat.mk | 2 +- depends/packages/fontconfig.mk | 2 +- depends/packages/libXau.mk | 2 +- depends/packages/libxcb.mk | 2 +- depends/packages/qrencode.mk | 2 +- depends/packages/xproto.mk | 2 +- depends/packages/zeromq.mk | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index 2695aecb85..4b07c116a9 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -138,7 +138,7 @@ $(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig $(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH) $(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH) $(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH) -$(1)_autoconf=./configure --host=$($($(1)_type)_host) --disable-dependency-tracking --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" +$(1)_autoconf=./configure --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" ifneq ($($(1)_nm),) $(1)_autoconf += NM="$$($(1)_nm)" diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 59ce5b21f3..2ae434d068 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -5,7 +5,7 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=cbc9102f4a31a8dafd42d642e9a3aa31e79a0aedaa1f6efd2795ebc83174ec18 define $(package)_set_vars - $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples + $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples --disable-dependency-tracking $(package)_config_opts_linux=--with-pic endef diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk index 3a2a8f4a7c..b5a49f01c3 100644 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -7,7 +7,7 @@ $(package)_dependencies=freetype expat $(package)_patches=remove_char_width_usage.patch gperf_header_regen.patch define $(package)_set_vars - $(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv + $(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv --disable-dependency-tracking endef define $(package)_preprocess_cmds diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index acc03b419a..edde06896e 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -8,7 +8,7 @@ $(package)_dependencies=xproto # When updating this package, check the default value of # --disable-xthreads. It is currently enabled. define $(package)_set_vars - $(package)_config_opts=--disable-shared --disable-lint-library --without-lint + $(package)_config_opts=--disable-shared --disable-lint-library --without-lint --disable-dependency-tracking $(package)_config_opts_linux=--with-pic endef diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 5805f8b5c3..6311e2a8b2 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c $(package)_dependencies=xcb_proto libXau define $(package)_set_vars -$(package)_config_opts= --disable-build-docs --without-doxygen --without-launchd +$(package)_config_opts= --disable-build-docs --without-doxygen --without-launchd --disable-dependency-tracking # Because we pass -qt-xcb to Qt, it will compile in a set of xcb helper libraries and extensions, # so we skip building all of the extensions here. # More info is available from: https://doc.qt.io/qt-5.9/linux-requirements.html diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index eed2bcd980..0c7e92fe73 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=efe5188b1ddbcbf98763b819b146be6a90481aac30cfc8d858ab78a19 define $(package)_set_vars $(package)_config_opts=--disable-shared --without-tools --without-tests --disable-sdltest -$(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap +$(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap --disable-dependency-tracking $(package)_config_opts_linux=--with-pic $(package)_config_opts_android=--with-pic endef diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk index 2462f3c647..d3d81a4b97 100644 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -5,7 +5,7 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=636162c1759805a5a0114a369dffdeccb8af8c859ef6e1445f26a4e6e046514f define $(package)_set_vars -$(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs +$(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs --disable-dependency-tracking endef define $(package)_preprocess_cmds diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 82e0dc7875..2227a73efd 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -9,7 +9,7 @@ define $(package)_set_vars $(package)_config_opts = --without-docs --disable-shared --disable-valgrind $(package)_config_opts += --disable-perf --disable-curve-keygen --disable-curve --disable-libbsd --disable-Werror --disable-drafts $(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci - $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov + $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov --disable-dependency-tracking $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic $(package)_config_opts_netbsd=--with-pic From 2b539481f9e43fc55361a20ad30da048088f45a0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 15:59:29 -0400 Subject: [PATCH 081/391] build: pass --enable-option-checking to applicable packages --- depends/packages/bdb.mk | 2 +- depends/packages/expat.mk | 3 ++- depends/packages/fontconfig.mk | 3 ++- depends/packages/freetype.mk | 1 + depends/packages/libXau.mk | 3 ++- depends/packages/libxcb.mk | 3 ++- depends/packages/qrencode.mk | 3 ++- depends/packages/xproto.mk | 3 ++- depends/packages/zeromq.mk | 3 ++- 9 files changed, 16 insertions(+), 8 deletions(-) diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 29287e1fdf..7f5011ff08 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -7,7 +7,7 @@ $(package)_build_subdir=build_unix $(package)_patches=clang_cxx_11.patch define $(package)_set_vars -$(package)_config_opts=--disable-shared --enable-cxx --disable-replication +$(package)_config_opts=--disable-shared --enable-cxx --disable-replication --enable-option-checking $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 2ae434d068..41c1114be0 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -5,7 +5,8 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=cbc9102f4a31a8dafd42d642e9a3aa31e79a0aedaa1f6efd2795ebc83174ec18 define $(package)_set_vars - $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples --disable-dependency-tracking + $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic endef diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk index b5a49f01c3..22b5022f06 100644 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -7,7 +7,8 @@ $(package)_dependencies=freetype expat $(package)_patches=remove_char_width_usage.patch gperf_header_regen.patch define $(package)_set_vars - $(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv --disable-dependency-tracking + $(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking endef define $(package)_preprocess_cmds diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk index 298786bde6..aebc8a5f3b 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -6,6 +6,7 @@ $(package)_sha256_hash=3a3bb2c4e15ffb433f2032f50a5b5a92558206822e22bfe8cbe339af4 define $(package)_set_vars $(package)_config_opts=--without-zlib --without-png --without-harfbuzz --without-bzip2 --disable-static + $(package)_config_opts += --enable-option-checking $(package)_config_opts_linux=--with-pic endef diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index edde06896e..24e0e9d325 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -8,7 +8,8 @@ $(package)_dependencies=xproto # When updating this package, check the default value of # --disable-xthreads. It is currently enabled. define $(package)_set_vars - $(package)_config_opts=--disable-shared --disable-lint-library --without-lint --disable-dependency-tracking + $(package)_config_opts=--disable-shared --disable-lint-library --without-lint + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic endef diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 6311e2a8b2..2204b38195 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -6,7 +6,8 @@ $(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c $(package)_dependencies=xcb_proto libXau define $(package)_set_vars -$(package)_config_opts= --disable-build-docs --without-doxygen --without-launchd --disable-dependency-tracking +$(package)_config_opts=--disable-static --disable-build-docs --without-doxygen --without-launchd +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking # Because we pass -qt-xcb to Qt, it will compile in a set of xcb helper libraries and extensions, # so we skip building all of the extensions here. # More info is available from: https://doc.qt.io/qt-5.9/linux-requirements.html diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index 0c7e92fe73..d1687883bc 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -6,7 +6,8 @@ $(package)_sha256_hash=efe5188b1ddbcbf98763b819b146be6a90481aac30cfc8d858ab78a19 define $(package)_set_vars $(package)_config_opts=--disable-shared --without-tools --without-tests --disable-sdltest -$(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap --disable-dependency-tracking +$(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic $(package)_config_opts_android=--with-pic endef diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk index d3d81a4b97..6bd867d02b 100644 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -5,7 +5,8 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=636162c1759805a5a0114a369dffdeccb8af8c859ef6e1445f26a4e6e046514f define $(package)_set_vars -$(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs --disable-dependency-tracking +$(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking endef define $(package)_preprocess_cmds diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 2227a73efd..b5cca1dae8 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -7,9 +7,10 @@ $(package)_patches=remove_libstd_link.patch netbsd_kevent_void.patch define $(package)_set_vars $(package)_config_opts = --without-docs --disable-shared --disable-valgrind - $(package)_config_opts += --disable-perf --disable-curve-keygen --disable-curve --disable-libbsd --disable-Werror --disable-drafts + $(package)_config_opts += --disable-perf --disable-curve-keygen --disable-curve --disable-libbsd $(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov --disable-dependency-tracking + $(package)_config_opts += --disable-Werror --disable-drafts --enable-option-checking $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic $(package)_config_opts_netbsd=--with-pic From 7b06ad33d5dc881a5fa5f4dfb0a980b2023360f3 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 16:23:15 -0400 Subject: [PATCH 082/391] build: Clean remnants of QTBUG-34748 fix A fix for QTBUG-34748 was introduced in https://github.com/bitcoin/bitcoin/pull/5915 (v0.11.0, Qt 5.2.1). QTBUG-34748 was fixed in version 5.3.0. The separated patch file, provided by https://github.com/bitcoin/bitcoin/pull/5915, was dropped in https://github.com/bitcoin/bitcoin/pull/12971 while bumping Qt to 5.9.4 (5.9.6). But libxcb.mk remained unchanged. This change reverts https://github.com/bitcoin/bitcoin/pull/5915 for libxcb.mk. --- depends/packages/libxcb.mk | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 5805f8b5c3..f01d2cc791 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -26,13 +26,8 @@ define $(package)_preprocess_cmds sed "s/pthread-stubs//" -i configure endef -# Don't install xcb headers to the default path in order to work around a qt -# build issue: https://bugreports.qt.io/browse/QTBUG-34748 -# When using qt's internal libxcb, it may end up finding the real headers in -# depends staging. Use a non-default path to avoid that. - define $(package)_config_cmds - $($(package)_autoconf) --includedir=$(host_prefix)/include/xcb-shared + $($(package)_autoconf) endef define $(package)_build_cmds From 706f0b15d7eb3e12fc142243f1d388ce6f02948b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 16:24:02 -0400 Subject: [PATCH 083/391] build: Small libxcb.mk improvements --- depends/packages/libxcb.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index f01d2cc791..270659cbc3 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -22,7 +22,7 @@ $(package)_config_opts += --disable-xv --disable-xvmc endef define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux &&\ + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux && \ sed "s/pthread-stubs//" -i configure endef @@ -39,5 +39,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf share/man share/doc lib/*.la + rm -rf share lib/*.la endef From b86331b16e6648707d262cbf1899bdeb10165bf7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 16:35:18 -0400 Subject: [PATCH 084/391] build: expat 2.4.1 --- depends/packages/expat.mk | 11 ++++++----- doc/dependencies.md | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 41c1114be0..c2089d1ccb 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,12 +1,13 @@ package=expat -$(package)_version=2.2.7 -$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_2_7/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=cbc9102f4a31a8dafd42d642e9a3aa31e79a0aedaa1f6efd2795ebc83174ec18 +$(package)_version=2.4.1 +$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_4_1/ +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=cf032d0dba9b928636548e32b327a2d66b1aab63c4f4a13dd132c2d1d2f2fb6a define $(package)_set_vars $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples $(package)_config_opts += --disable-dependency-tracking --enable-option-checking + $(package)_config_opts += --without-xmlwf $(package)_config_opts_linux=--with-pic endef @@ -23,5 +24,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf share lib/*.la + rm -rf share lib/cmake lib/*.la endef diff --git a/doc/dependencies.md b/doc/dependencies.md index 406a28edf8..417e152800 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -9,7 +9,6 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | Boost | [1.71.0](https://www.boost.org/users/download/) | [1.57.0](https://github.com/PRCYCoin/PRCYCoin/pull/286) | No | | | | Clang | | [3.3+](https://llvm.org/releases/download.html) (C++11 support) | | | | | D-Bus | [1.10.18](https://cgit.freedesktop.org/dbus/dbus/tree/NEWS?h=dbus-1.10) | | No | Yes | | -| Expat | [2.2.7](https://libexpat.github.io/) | | No | Yes | | | fontconfig | [2.12.1](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | | FreeType | [2.7.1](https://download.savannah.gnu.org/releases/freetype) | | No | | | | GCC | | [4.8+](https://gcc.gnu.org/) (C++11 support) | | | | From f7d294522363bff62446468e7f6b71581a0365f1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 16:39:16 -0400 Subject: [PATCH 085/391] build: Bump Fonconfig version up to 2.12.6 --- depends/packages/fontconfig.mk | 7 +-- .../fontconfig/gperf_header_regen.patch | 10 +-- .../fontconfig/remove_char_width_usage.patch | 62 ------------------- doc/dependencies.md | 2 +- 4 files changed, 9 insertions(+), 72 deletions(-) delete mode 100755 depends/patches/fontconfig/remove_char_width_usage.patch diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk index 22b5022f06..c8b2fc33d5 100644 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -1,10 +1,10 @@ package=fontconfig -$(package)_version=2.12.1 +$(package)_version=2.12.6 $(package)_download_path=https://www.freedesktop.org/software/fontconfig/release/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=b449a3e10c47e1d1c7a6ec6e2016cca73d3bd68fbbd4f0ae5cc6b573f7d6c7f3 +$(package)_sha256_hash=cf0c30807d08f6a28ab46c61b8dbd55c97d2f292cf88f3a07d3384687f31f017 $(package)_dependencies=freetype expat -$(package)_patches=remove_char_width_usage.patch gperf_header_regen.patch +$(package)_patches=gperf_header_regen.patch define $(package)_set_vars $(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv @@ -12,7 +12,6 @@ define $(package)_set_vars endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/remove_char_width_usage.patch && \ patch -p1 < $($(package)_patch_dir)/gperf_header_regen.patch endef diff --git a/depends/patches/fontconfig/gperf_header_regen.patch b/depends/patches/fontconfig/gperf_header_regen.patch index 7401b83d84..b1a70d5fb1 100755 --- a/depends/patches/fontconfig/gperf_header_regen.patch +++ b/depends/patches/fontconfig/gperf_header_regen.patch @@ -2,7 +2,7 @@ commit 7b6eb33ecd88768b28c67ce5d2d68a7eed5936b6 Author: fanquake Date: Tue Aug 25 14:34:53 2020 +0800 - Remove rule that causes inadvertant header regeneration + Remove rule that causes inadvertent header regeneration Otherwise the makefile will needlessly attempt to re-generate the headers with gperf. This can be dropped once the upstream build is fixed. @@ -13,12 +13,12 @@ diff --git a/src/Makefile.in b/src/Makefile.in index f4626ad..4ae1b00 100644 --- a/src/Makefile.in +++ b/src/Makefile.in -@@ -903,7 +903,7 @@ fcobjshash.gperf: fcobjshash.gperf.h fcobjs.h +@@ -912,7 +912,7 @@ ' - > $@.tmp && \ - mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) + mv -f $@.tmp fcobjshash.gperf && touch $@ || ( $(RM) $@.tmp && false ) --fcobjshash.h: fcobjshash.gperf +-fcobjshash.h: Makefile fcobjshash.gperf +fcobjshash.h: - $(AM_V_GEN) $(GPERF) -m 100 $< > $@.tmp && \ + $(AM_V_GEN) $(GPERF) --pic -m 100 fcobjshash.gperf > $@.tmp && \ mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) diff --git a/depends/patches/fontconfig/remove_char_width_usage.patch b/depends/patches/fontconfig/remove_char_width_usage.patch deleted file mode 100755 index 9f69081890..0000000000 --- a/depends/patches/fontconfig/remove_char_width_usage.patch +++ /dev/null @@ -1,62 +0,0 @@ -commit 28165a9b078583dc8e9e5c344510e37582284cef -Author: fanquake -Date: Mon Aug 17 20:35:42 2020 +0800 - - Remove usage of CHAR_WIDTH - - CHAR_WIDTH which is reserved and clashes with glibc 2.25+ - - See #10851. - -diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h -index 5c72b22..843c532 100644 ---- a/fontconfig/fontconfig.h -+++ b/fontconfig/fontconfig.h -@@ -128,7 +128,7 @@ typedef int FcBool; - #define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION - - /* Adjust outline rasterizer */ --#define FC_CHAR_WIDTH "charwidth" /* Int */ -+#define FC_CHARWIDTH "charwidth" /* Int */ - #define FC_CHAR_HEIGHT "charheight"/* Int */ - #define FC_MATRIX "matrix" /* FcMatrix */ - -diff --git a/src/fcobjs.h b/src/fcobjs.h -index 1fc4f65..d27864b 100644 ---- a/src/fcobjs.h -+++ b/src/fcobjs.h -@@ -51,7 +51,7 @@ FC_OBJECT (DPI, FcTypeDouble, NULL) - FC_OBJECT (RGBA, FcTypeInteger, NULL) - FC_OBJECT (SCALE, FcTypeDouble, NULL) - FC_OBJECT (MINSPACE, FcTypeBool, NULL) --FC_OBJECT (CHAR_WIDTH, FcTypeInteger, NULL) -+FC_OBJECT (CHARWIDTH, FcTypeInteger, NULL) - FC_OBJECT (CHAR_HEIGHT, FcTypeInteger, NULL) - FC_OBJECT (MATRIX, FcTypeMatrix, NULL) - FC_OBJECT (CHARSET, FcTypeCharSet, FcCompareCharSet) -diff --git a/src/fcobjshash.gperf b/src/fcobjshash.gperf -index 80a0237..eb4ad84 100644 ---- a/src/fcobjshash.gperf -+++ b/src/fcobjshash.gperf -@@ -44,7 +44,7 @@ int id; - "rgba",FC_RGBA_OBJECT - "scale",FC_SCALE_OBJECT - "minspace",FC_MINSPACE_OBJECT --"charwidth",FC_CHAR_WIDTH_OBJECT -+"charwidth",FC_CHARWIDTH_OBJECT - "charheight",FC_CHAR_HEIGHT_OBJECT - "matrix",FC_MATRIX_OBJECT - "charset",FC_CHARSET_OBJECT -diff --git a/src/fcobjshash.h b/src/fcobjshash.h -index 5a4d1ea..4e66bb0 100644 ---- a/src/fcobjshash.h -+++ b/src/fcobjshash.h -@@ -284,7 +284,7 @@ FcObjectTypeLookup (register const char *str, register unsigned int len) - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str43,FC_CHARSET_OBJECT}, - {-1}, - #line 47 "fcobjshash.gperf" -- {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHAR_WIDTH_OBJECT}, -+ {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHARWIDTH_OBJECT}, - #line 48 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str46,FC_CHAR_HEIGHT_OBJECT}, - #line 55 "fcobjshash.gperf" diff --git a/doc/dependencies.md b/doc/dependencies.md index 417e152800..9b31633f73 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -9,7 +9,7 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | Boost | [1.71.0](https://www.boost.org/users/download/) | [1.57.0](https://github.com/PRCYCoin/PRCYCoin/pull/286) | No | | | | Clang | | [3.3+](https://llvm.org/releases/download.html) (C++11 support) | | | | | D-Bus | [1.10.18](https://cgit.freedesktop.org/dbus/dbus/tree/NEWS?h=dbus-1.10) | | No | Yes | | -| fontconfig | [2.12.1](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | +| Fontconfig | [2.12.6](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | | FreeType | [2.7.1](https://download.savannah.gnu.org/releases/freetype) | | No | | | | GCC | | [4.8+](https://gcc.gnu.org/) (C++11 support) | | | | | HarfBuzz-NG | | | | | | From afc9642f8d6d31378e7c399690105ccf1985a387 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 16:39:42 -0400 Subject: [PATCH 086/391] build: freetype 2.11.0 --- depends/packages/freetype.mk | 8 ++++---- doc/dependencies.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk index aebc8a5f3b..6f5dbe0f01 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -1,12 +1,12 @@ package=freetype -$(package)_version=2.7.1 +$(package)_version=2.11.0 $(package)_download_path=https://download.savannah.gnu.org/releases/$(package) -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=3a3bb2c4e15ffb433f2032f50a5b5a92558206822e22bfe8cbe339af4aa82f88 +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=8bee39bd3968c4804b70614a0a3ad597299ad0e824bc8aad5ce8aaf48067bde7 define $(package)_set_vars $(package)_config_opts=--without-zlib --without-png --without-harfbuzz --without-bzip2 --disable-static - $(package)_config_opts += --enable-option-checking + $(package)_config_opts += --enable-option-checking --without-brotli $(package)_config_opts_linux=--with-pic endef diff --git a/doc/dependencies.md b/doc/dependencies.md index 9b31633f73..d96b3eb6d7 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -10,7 +10,7 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | Clang | | [3.3+](https://llvm.org/releases/download.html) (C++11 support) | | | | | D-Bus | [1.10.18](https://cgit.freedesktop.org/dbus/dbus/tree/NEWS?h=dbus-1.10) | | No | Yes | | | Fontconfig | [2.12.6](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | -| FreeType | [2.7.1](https://download.savannah.gnu.org/releases/freetype) | | No | | | +| FreeType | [2.11.0](https://download.savannah.gnu.org/releases/freetype) | | No | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) (Android only) | | GCC | | [4.8+](https://gcc.gnu.org/) (C++11 support) | | | | | HarfBuzz-NG | | | | | | | libevent | [2.1.11-stable](https://github.com/libevent/libevent/releases) | [2.0.21](https://github.com/PRCYCoin/PRCYCoin/pull/385) | No | | | From f717136937eb159bffb3191295309add6ae06c8c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 16:40:15 -0400 Subject: [PATCH 087/391] build: libXau 1.0.9 --- depends/packages/libXau.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index 24e0e9d325..b7e032c0b2 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -1,8 +1,8 @@ package=libXau -$(package)_version=1.0.8 +$(package)_version=1.0.9 $(package)_download_path=https://xorg.freedesktop.org/releases/individual/lib/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=fdd477320aeb5cdd67272838722d6b7d544887dfe7de46e1e7cc0c27c2bea4f2 +$(package)_sha256_hash=ccf8cbf0dbf676faa2ea0a6d64bcc3b6746064722b606c8c52917ed00dcb73ec $(package)_dependencies=xproto # When updating this package, check the default value of From 2ba88ddbc930533d0e5b484246b22f073176cf8d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 16:41:30 -0400 Subject: [PATCH 088/391] build: libxcb 1.14 Minimum required libxcb to build qt 5.15.x is 1.11. https://codereview.qt.nokia.com/c/qt/qtbase/+/253905 Some plugins have been re-enabled as they are required by Qt. --- depends/packages/libxcb.mk | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 14abde9b0a..99a7ee2fbd 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -1,25 +1,21 @@ package=libxcb -$(package)_version=1.10 +$(package)_version=1.14 $(package)_download_path=https://xcb.freedesktop.org/dist -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c3f2d5b5 +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=a55ed6db98d43469801262d81dc2572ed124edc3db31059d4e9916eb9f844c34 $(package)_dependencies=xcb_proto libXau define $(package)_set_vars -$(package)_config_opts=--disable-static --disable-build-docs --without-doxygen --without-launchd +$(package)_config_opts=--disable-static --disable-devel-docs --without-doxygen --without-launchd $(package)_config_opts += --disable-dependency-tracking --enable-option-checking -# Because we pass -qt-xcb to Qt, it will compile in a set of xcb helper libraries and extensions, -# so we skip building all of the extensions here. -# More info is available from: https://doc.qt.io/qt-5.9/linux-requirements.html +# Disable uneeded extensions. +# More info is available from: https://doc.qt.io/qt-5.15/linux-requirements.html $(package)_config_opts += --disable-composite --disable-damage --disable-dpms $(package)_config_opts += --disable-dri2 --disable-dri3 --disable-glx -$(package)_config_opts += --disable-present --disable-randr --disable-record -$(package)_config_opts += --disable-render --disable-resource --disable-screensaver -$(package)_config_opts += --disable-shape --disable-shm --disable-sync -$(package)_config_opts += --disable-xevie --disable-xfixes --disable-xfree86-dri -$(package)_config_opts += --disable-xinerama --disable-xinput --disable-xkb -$(package)_config_opts += --disable-xprint --disable-selinux --disable-xtest -$(package)_config_opts += --disable-xv --disable-xvmc +$(package)_config_opts += --disable-present --disable-record --disable-resource +$(package)_config_opts += --disable-screensaver --disable-xevie --disable-xfree86-dri +$(package)_config_opts += --disable-xinput --disable-xprint --disable-selinux +$(package)_config_opts += --disable-xtest --disable-xv --disable-xvmc endef define $(package)_preprocess_cmds From 22b569a3bf41d7224ee2a83a0ab6a74d8b47dec5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 16:42:22 -0400 Subject: [PATCH 089/391] build: xcb_proto 1.14.1 --- depends/packages/xcb_proto.mk | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk index 01203a0718..9be822506d 100644 --- a/depends/packages/xcb_proto.mk +++ b/depends/packages/xcb_proto.mk @@ -1,8 +1,8 @@ package=xcb_proto -$(package)_version=1.10 -$(package)_download_path=https://xcb.freedesktop.org/dist -$(package)_file_name=xcb-proto-$($(package)_version).tar.bz2 -$(package)_sha256_hash=7ef40ddd855b750bc597d2a435da21e55e502a0fefa85b274f2c922800baaf05 +$(package)_version=1.14.1 +$(package)_download_path=https://xorg.freedesktop.org/archive/individual/proto +$(package)_file_name=xcb-proto-$($(package)_version).tar.xz +$(package)_sha256_hash=f04add9a972ac334ea11d9d7eb4fc7f8883835da3e4859c9afa971efdf57fcc3 define $(package)_config_cmds $($(package)_autoconf) @@ -17,6 +17,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - find -name "*.pyc" -delete && \ - find -name "*.pyo" -delete + rm -rf lib/python*/site-packages/xcbgen/__pycache__ endef From b459a644c8946723852c2e8a9614fdb5f126c887 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 16:43:00 -0400 Subject: [PATCH 090/391] build: xproto 7.0.31 --- depends/packages/xproto.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk index 6bd867d02b..7a43c52faf 100644 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -1,8 +1,8 @@ package=xproto -$(package)_version=7.0.26 +$(package)_version=7.0.31 $(package)_download_path=https://xorg.freedesktop.org/releases/individual/proto $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=636162c1759805a5a0114a369dffdeccb8af8c859ef6e1445f26a4e6e046514f +$(package)_sha256_hash=c6f9747da0bd3a95f86b17fb8dd5e717c8f3ab7f0ece3ba1b247899ec1ef7747 define $(package)_set_vars $(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs From 59159d1616496d3056d415da98ffa8907ca5daf4 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 18:10:00 -0400 Subject: [PATCH 091/391] build: add `--enable-lto` configuration option --- configure.ac | 17 +++++++++++++++-- src/Makefile.am | 4 ++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index b1524550fc..a39ca9cbd1 100644 --- a/configure.ac +++ b/configure.ac @@ -247,6 +247,11 @@ AC_ARG_ENABLE([werror], [enable_werror=$enableval], [enable_werror=no]) +AC_ARG_ENABLE([lto], + [AS_HELP_STRING([--enable-lto],[build using LTO (default is no)])], + [enable_lto=$enableval], + [enable_lto=no]) + AC_LANG_PUSH([C++]) AX_CHECK_COMPILE_FLAG([-Werror],[CXXFLAG_WERROR="-Werror"],[CXXFLAG_WERROR=""]) @@ -274,6 +279,11 @@ if test "x$enable_debug" = xyes; then AX_CHECK_COMPILE_FLAG([-ftrapv],[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -ftrapv"],,[[$CXXFLAG_WERROR]]) fi +if test "x$enable_lto" = "xyes"; then + AX_CHECK_COMPILE_FLAG([-flto], [LTO_CXXFLAGS="$LTO_CXXFLAGS -flto"], [AC_MSG_ERROR([compile failed with -flto])], [$CXXFLAG_WERROR]) + AX_CHECK_LINK_FLAG([-flto], [LTO_LDFLAGS="$LTO_LDFLAGS -flto"], [AC_MSG_ERROR([link failed with -flto])], [$CXXFLAG_WERROR]) +fi + if test x$use_sanitizers != x; then # First check if the compiler accepts flags. If an incompatible pair like # -fsanitize=address,thread is used here, this check will fail. This will also @@ -1254,6 +1264,8 @@ AC_SUBST(GPROF_LDFLAGS) AC_SUBST(HARDENED_CXXFLAGS) AC_SUBST(HARDENED_CPPFLAGS) AC_SUBST(HARDENED_LDFLAGS) +AC_SUBST(LTO_CXXFLAGS) +AC_SUBST(LTO_LDFLAGS) AC_SUBST(PIC_FLAGS) AC_SUBST(PIE_FLAGS) AC_SUBST(SANITIZER_CXXFLAGS) @@ -1361,6 +1373,7 @@ echo " sanitizers = $use_sanitizers" echo " debug enabled = $enable_debug" echo " gprof enabled = $enable_gprof" echo " werror = $enable_werror" +echo " LTO = $enable_lto" echo echo " target os = $TARGET_OS" echo " build os = $BUILD_OS" @@ -1369,8 +1382,8 @@ echo " CC = $CC" echo " CFLAGS = $CFLAGS" echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CPPFLAGS" echo " CXX = $CXX" -echo " CXXFLAGS = $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" -echo " LDFLAGS = $PTHREAD_CFLAGS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" +echo " CXXFLAGS = $LTO_CXXFLAGS $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" +echo " LDFLAGS = $LTO_LDFLAGS $PTHREAD_CFLAGS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" echo " ARFLAGS = $ARFLAGS" echo " PIC_FLAGS = $PIC_FLAGS" echo " QT_PIE_FLAGS = $QT_PIE_FLAGS" diff --git a/src/Makefile.am b/src/Makefile.am index 7c54ddfc46..c458d8dccb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,8 +3,8 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. DIST_SUBDIRS = secp256k1 secp256k1-mw univalue -AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS) -AM_CXXFLAGS = $(DEBUG_CXXFLAGS) $(HARDENED_CXXFLAGS) $(WARN_CXXFLAGS) $(NOWARN_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS) +AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS) $(LTO_LDFLAGS) +AM_CXXFLAGS = $(DEBUG_CXXFLAGS) $(HARDENED_CXXFLAGS) $(WARN_CXXFLAGS) $(NOWARN_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS) $(LTO_CXXFLAGS) AM_CPPFLAGS = $(DEBUG_CPPFLAGS) $(HARDENED_CPPFLAGS) AM_LIBTOOLFLAGS = --preserve-dup-deps EXTRA_LIBRARIES = From 98e9ad3d699e405f934bd1e5687c77952e9b0ba5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 18:28:40 -0400 Subject: [PATCH 092/391] build: make macOS HOST in download-osx generic This was missed in https://github.com/bitcoin/bitcoin/pull/20419, and the update before that, so just make this un-versioned so that we don't have to worry about it. This is fine, because it's just for downloading sources. --- depends/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/Makefile b/depends/Makefile index 9541e1bf01..9a02f5f00f 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -260,7 +260,7 @@ install: check-packages $(host_prefix)/share/config.site download-one: check-sources $(all_sources) download-osx: - @$(MAKE) -s HOST=x86_64-apple-darwin14 download-one + @$(MAKE) -s HOST=x86_64-apple-darwin download-one download-linux: @$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one download-win: From 513ea50daec1b664d914028c37f79f828d0ffa33 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 22:17:47 -0400 Subject: [PATCH 093/391] build: update boost macros to latest upstream Fixes: https://github.com/bitcoin/bitcoin/issues/16803 --- build-aux/m4/ax_boost_base.m4 | 19 +- build-aux/m4/ax_boost_chrono.m4 | 4 +- build-aux/m4/ax_boost_filesystem.m4 | 7 +- build-aux/m4/ax_boost_program_options.m4 | 10 +- build-aux/m4/ax_boost_system.m4 | 4 +- build-aux/m4/ax_boost_thread.m4 | 179 +++++++++++-------- build-aux/m4/ax_boost_unit_test_framework.m4 | 4 +- 7 files changed, 129 insertions(+), 98 deletions(-) diff --git a/build-aux/m4/ax_boost_base.m4 b/build-aux/m4/ax_boost_base.m4 index 6635bd711c..b1fed7a50a 100644 --- a/build-aux/m4/ax_boost_base.m4 +++ b/build-aux/m4/ax_boost_base.m4 @@ -10,10 +10,10 @@ # # Test for the Boost C++ libraries of a particular version (or newer) # -# If no path to the installed boost library is given the macro search -# under /usr, /usr/local, /opt, /opt/local, and /opt/homebrew and evaluates the -# $BOOST_ROOT environment variable. Further documentation is available at -# . +# If no path to the installed boost library is given the macro searchs +# under /usr, /usr/local, /opt, /opt/local and /opt/homebrew and evaluates +# the $BOOST_ROOT environment variable. Further documentation is available +# at . # # This macro calls: # @@ -33,7 +33,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 49 +#serial 52 # example boost program (need to pass version) m4_define([_AX_BOOST_BASE_PROGRAM], @@ -114,7 +114,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ AS_CASE([${host_cpu}], [x86_64],[libsubdirs="lib64 libx32 lib lib64"], [mips*64*],[libsubdirs="lib64 lib32 lib lib64"], - [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64],[libsubdirs="lib64 lib lib64"], + [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64|e2k|loongarch64],[libsubdirs="lib64 lib lib64"], [libsubdirs="lib"] ) @@ -123,15 +123,10 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ dnl are almost assuredly the ones desired. AS_CASE([${host_cpu}], [i?86],[multiarch_libsubdir="lib/i386-${host_os}"], + [armv7l],[multiarch_libsubdir="lib/arm-${host_os}"], [multiarch_libsubdir="lib/${host_cpu}-${host_os}"] ) - dnl some arches may advertise a cpu type that doesn't line up with their - dnl prefix's cpu type. For example, uname may report armv7l while libs are - dnl installed to /usr/lib/arm-linux-gnueabihf. Try getting the compiler's - dnl value for an extra chance of finding the correct path. - libsubdirs="lib/`$CXX -dumpmachine 2>/dev/null` $libsubdirs" - dnl first we check the system location for boost libraries dnl this location is chosen if boost libraries are installed with the --layout=system option dnl or if you install boost with RPM diff --git a/build-aux/m4/ax_boost_chrono.m4 b/build-aux/m4/ax_boost_chrono.m4 index 6ea77b9b3e..4cd3b86041 100644 --- a/build-aux/m4/ax_boost_chrono.m4 +++ b/build-aux/m4/ax_boost_chrono.m4 @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 4 +#serial 5 AC_DEFUN([AX_BOOST_CHRONO], [ @@ -105,7 +105,7 @@ AC_DEFUN([AX_BOOST_CHRONO], fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the library!) + AC_MSG_ERROR(Could not find a version of the Boost::Chrono library!) fi if test "x$link_chrono" = "xno"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_boost_filesystem.m4 b/build-aux/m4/ax_boost_filesystem.m4 index f5c9d56470..12f7bc5e2e 100644 --- a/build-aux/m4/ax_boost_filesystem.m4 +++ b/build-aux/m4/ax_boost_filesystem.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html # =========================================================================== # # SYNOPSIS @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 26 +#serial 28 AC_DEFUN([AX_BOOST_FILESYSTEM], [ @@ -80,7 +80,6 @@ AC_DEFUN([AX_BOOST_FILESYSTEM], if test "x$ax_cv_boost_filesystem" = "xyes"; then AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available]) BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - ax_lib= if test "x$ax_boost_user_filesystem_lib" = "x"; then for libextension in `ls -r $BOOSTLIBDIR/libboost_filesystem* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do ax_lib=${libextension} @@ -105,7 +104,7 @@ AC_DEFUN([AX_BOOST_FILESYSTEM], fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_filesystem library!) + AC_MSG_ERROR(Could not find a version of the Boost::Filesystem library!) fi if test "x$link_filesystem" != "xyes"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_boost_program_options.m4 b/build-aux/m4/ax_boost_program_options.m4 index 2bdb593716..7d23da4648 100644 --- a/build-aux/m4/ax_boost_program_options.m4 +++ b/build-aux/m4/ax_boost_program_options.m4 @@ -1,6 +1,6 @@ -# ============================================================================ -# http://www.gnu.org/software/autoconf-archive/ax_boost_program_options.html -# ============================================================================ +# ============================================================================= +# https://www.gnu.org/software/autoconf-archive/ax_boost_program_options.html +# ============================================================================= # # SYNOPSIS # @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 24 +#serial 26 AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], [ @@ -96,7 +96,7 @@ AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], done fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_program_options library!) + AC_MSG_ERROR(Could not find a version of the Boost::Program_Options library!) fi if test "x$link_program_options" != "xyes"; then AC_MSG_ERROR([Could not link against [$ax_lib] !]) diff --git a/build-aux/m4/ax_boost_system.m4 b/build-aux/m4/ax_boost_system.m4 index 207d7be8de..323e2a676a 100644 --- a/build-aux/m4/ax_boost_system.m4 +++ b/build-aux/m4/ax_boost_system.m4 @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 19 +#serial 20 AC_DEFUN([AX_BOOST_SYSTEM], [ @@ -108,7 +108,7 @@ AC_DEFUN([AX_BOOST_SYSTEM], fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the library!) + AC_MSG_ERROR(Could not find a version of the Boost::System library!) fi if test "x$link_system" = "xno"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_boost_thread.m4 b/build-aux/m4/ax_boost_thread.m4 index 9f0bd0b23c..75e80e6e75 100644 --- a/build-aux/m4/ax_boost_thread.m4 +++ b/build-aux/m4/ax_boost_thread.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_thread.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_thread.html # =========================================================================== # # SYNOPSIS @@ -30,73 +30,96 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 27 +#serial 33 AC_DEFUN([AX_BOOST_THREAD], [ - AC_ARG_WITH([boost-thread], - AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], - [use the Thread library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-thread=boost_thread-gcc-mt ]), + AC_ARG_WITH([boost-thread], + AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], + [use the Thread library from boost - + it is possible to specify a certain library for the linker + e.g. --with-boost-thread=boost_thread-gcc-mt ]), [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then + if test "$withval" = "yes"; then want_boost="yes" ax_boost_user_thread_lib="" else - want_boost="yes" - ax_boost_user_thread_lib="$withval" - fi + want_boost="yes" + ax_boost_user_thread_lib="$withval" + fi ], [want_boost="yes"] - ) + ) - if test "x$want_boost" = "xyes"; then + if test "x$want_boost" = "xyes"; then AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_BUILD]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS AC_CACHE_CHECK(whether the Boost::Thread library is available, - ax_cv_boost_thread, + ax_cv_boost_thread, [AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS + CXXFLAGS_SAVE=$CXXFLAGS + + case "x$host_os" in + xsolaris ) + CXXFLAGS="-pthreads $CXXFLAGS" + break; + ;; + xmingw32 ) + CXXFLAGS="-mthreads $CXXFLAGS" + break; + ;; + *android* ) + break; + ;; + * ) + CXXFLAGS="-pthread $CXXFLAGS" + break; + ;; + esac - if test "x$host_os" = "xsolaris" ; then - CXXFLAGS="-pthreads $CXXFLAGS" - elif test "x$host_os" = "xmingw32" ; then - CXXFLAGS="-mthreads $CXXFLAGS" - else - CXXFLAGS="-pthread $CXXFLAGS" - fi - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::thread_group thrds; - return 0;]])], - ax_cv_boost_thread=yes, ax_cv_boost_thread=no) - CXXFLAGS=$CXXFLAGS_SAVE + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [[@%:@include ]], + [[boost::thread_group thrds; + return 0;]])], + ax_cv_boost_thread=yes, ax_cv_boost_thread=no) + CXXFLAGS=$CXXFLAGS_SAVE AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_thread" = "xyes"; then - if test "x$host_os" = "xsolaris" ; then - BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" - elif test "x$host_os" = "xmingw32" ; then - BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" - else - BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" - fi + ]) + if test "x$ax_cv_boost_thread" = "xyes"; then + case "x$host_os" in + xsolaris ) + BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" + break; + ;; + xmingw32 ) + BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" + break; + ;; + *android* ) + break; + ;; + * ) + BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" + break; + ;; + esac - AC_SUBST(BOOST_CPPFLAGS) + AC_SUBST(BOOST_CPPFLAGS) - AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available]) + AC_DEFINE(HAVE_BOOST_THREAD,, + [define if the Boost::Thread library is available]) BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - LDFLAGS_SAVE=$LDFLAGS + LDFLAGS_SAVE=$LDFLAGS case "x$host_os" in *bsd* ) LDFLAGS="-pthread $LDFLAGS" @@ -104,47 +127,61 @@ AC_DEFUN([AX_BOOST_THREAD], ;; esac if test "x$ax_boost_user_thread_lib" = "x"; then - ax_lib= for libextension in `ls -r $BOOSTLIBDIR/libboost_thread* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'`; do ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], [link_thread="no"]) - done + done if test "x$link_thread" != "xyes"; then for libextension in `ls -r $BOOSTLIBDIR/boost_thread* 2>/dev/null | sed 's,.*/,,' | sed 's,\..*,,'`; do ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], [link_thread="no"]) - done + done fi else for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], [link_thread="no"]) done fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_thread library!) + AC_MSG_ERROR(Could not find a version of the Boost::Thread library!) fi - if test "x$link_thread" = "xno"; then - AC_MSG_ERROR(Could not link against $ax_lib !) - else - case "x$host_os" in - *bsd* ) - BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" - break; - ;; - esac - - fi - fi + if test "x$link_thread" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + else + BOOST_THREAD_LIB="-l$ax_lib" + case "x$host_os" in + *bsd* ) + BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" + break; + ;; + xsolaris ) + BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread" + break; + ;; + xmingw32 ) + break; + ;; + *android* ) + break; + ;; + * ) + BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread" + break; + ;; + esac + AC_SUBST(BOOST_THREAD_LIB) + fi + fi - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi ]) diff --git a/build-aux/m4/ax_boost_unit_test_framework.m4 b/build-aux/m4/ax_boost_unit_test_framework.m4 index 3d8e93e964..4cca32fcfd 100644 --- a/build-aux/m4/ax_boost_unit_test_framework.m4 +++ b/build-aux/m4/ax_boost_unit_test_framework.m4 @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 21 +#serial 22 AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], [ @@ -124,7 +124,7 @@ AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], done fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the library!) + AC_MSG_ERROR(Could not find a version of the Boost::Unit_Test_Framework library!) fi if test "x$link_unit_test_framework" != "xyes"; then AC_MSG_ERROR(Could not link against $ax_lib !) From 028173798c7b452492f417d9e1104fd487a21f7b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 22:24:49 -0400 Subject: [PATCH 094/391] build: pass -dead_strip_dylibs to ld on macOS This strips some unused dylibs from bitcoin-qt. From man ld: Remove dylibs that are unreachable by the entry point or exported symbols. That is, suppresses the generation of load command commands for dylibs which supplied no symbols during the link. This option should not be used when linking against a dylib which is required at runtime for some indirect reason such as the dylib has an important initializer. --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index a39ca9cbd1..74f70af22c 100644 --- a/configure.ac +++ b/configure.ac @@ -691,6 +691,7 @@ fi dnl this flag screws up non-darwin gcc even when the check fails. special-case it. if test x$TARGET_OS = xdarwin; then AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"]) + AX_CHECK_LINK_FLAG([[-Wl,-dead_strip_dylibs]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip_dylibs"]) fi AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) From 54cc0ed20ca824e5629cdeb468cb60399c31fd2e Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 22:47:03 -0400 Subject: [PATCH 095/391] depends: don't use OpenGL in Qt on macOS --- depends/packages/qt.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 99d923e00e..c557d3b303 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -90,6 +90,7 @@ $(package)_config_opts += -no-feature-wizard $(package)_config_opts += -no-feature-xml $(package)_config_opts_darwin = -no-dbus +$(package)_config_opts_darwin += -no-opengl $(package)_config_opts_darwin += -pch ifneq ($(build_os),darwin) From b395e4db217581e97401e8f8ab39f578dc28bc60 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 23:00:00 -0400 Subject: [PATCH 096/391] build: Installed Qt version only appears if being built --- build-aux/m4/bitcoin_qt.m4 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 1f2b8f4f12..1a7bf386a4 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -236,7 +236,11 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ ],[ bitcoin_enable_qt=no ]) - AC_MSG_RESULT([$bitcoin_enable_qt (Qt5)]) + if test x$bitcoin_enable_qt = xyes; then + AC_MSG_RESULT([$bitcoin_enable_qt ($QT_LIB_PREFIX)]) + else + AC_MSG_RESULT([$bitcoin_enable_qt]) + fi AC_SUBST(QT_PIE_FLAGS) AC_SUBST(QT_INCLUDES) From c61b71c4d96c50a90d0e3a391527233cfde1adea Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 23:28:46 -0400 Subject: [PATCH 097/391] Bump the minimum Qt version to 5.2 --- src/qt/guiutil.cpp | 5 ++--- src/qt/prcycoin.cpp | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index d926259017..e2834ce8ce 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -79,9 +80,7 @@ QString dateTimeStr(qint64 nTime) QFont bitcoinAddressFont() { - QFont font("Monospace"); - font.setStyleHint(QFont::Monospace); - return font; + return QFontDatabase::systemFont(QFontDatabase::FixedFont); } void setupAddressWidget(QValidatedLineEdit* widget, QWidget* parent) diff --git a/src/qt/prcycoin.cpp b/src/qt/prcycoin.cpp index 22705ded39..c16dae6ecf 100644 --- a/src/qt/prcycoin.cpp +++ b/src/qt/prcycoin.cpp @@ -588,10 +588,8 @@ int main(int argc, char* argv[]) Q_INIT_RESOURCE(prcycoin); BitcoinApplication app(argc, argv); -#if QT_VERSION > 0x050100 // Generate high-dpi pixmaps QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); -#endif #if QT_VERSION >= 0x050600 QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif From 0fd08c239b75e5782af926f13c82d1db1ccaf584 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 23:32:20 -0400 Subject: [PATCH 098/391] Bump minimum Qt version to 5.5.1 --- build-aux/m4/bitcoin_qt.m4 | 18 ------------------ src/qt/prcycoin.cpp | 3 --- 2 files changed, 21 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 1f2b8f4f12..c5459e4c1e 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -101,24 +101,6 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ if test "x$bitcoin_cv_static_qt" = xyes; then _BITCOIN_QT_FIND_STATIC_PLUGINS AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) - AC_CACHE_CHECK(for Qt < 5.4, bitcoin_cv_need_acc_widget,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION >= 0x050400 - choke - #endif - ]])], - [bitcoin_cv_need_acc_widget=yes], - [bitcoin_cv_need_acc_widget=no]) - ]) - if test "x$bitcoin_cv_need_acc_widget" = xyes; then - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets]) - fi if test "x$TARGET_OS" != xandroid; then _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin)],[-lqminimal]) AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) diff --git a/src/qt/prcycoin.cpp b/src/qt/prcycoin.cpp index c16dae6ecf..04e393d524 100644 --- a/src/qt/prcycoin.cpp +++ b/src/qt/prcycoin.cpp @@ -67,9 +67,6 @@ #if defined(QT_STATICPLUGIN) #include -#if QT_VERSION < 0x050400 -Q_IMPORT_PLUGIN(AccessibleFactory) -#endif #if defined(QT_QPA_PLATFORM_XCB) Q_IMPORT_PLUGIN(QXcbIntegrationPlugin); #elif defined(QT_QPA_PLATFORM_WINDOWS) From c2b20f7b9188ca787c6f7a768bfb6bb9d3de779c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 10:37:30 -0400 Subject: [PATCH 099/391] build: disable D-Bus on Android by default Android uses a different notification system and doesn't support D-Bus --- build-aux/m4/bitcoin_qt.m4 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 1f2b8f4f12..b01cb3e84d 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -72,10 +72,19 @@ AC_DEFUN([BITCOIN_QT_INIT],[ AC_ARG_WITH([qtdbus], [AS_HELP_STRING([--with-qtdbus], - [enable DBus support (default is yes if qt is enabled and QtDBus is found)])], + [enable DBus support (default is yes if qt is enabled and QtDBus is found, except on Android)])], [use_dbus=$withval], [use_dbus=auto]) + dnl Android doesn't support D-Bus and certainly doesn't use it for notifications + case $host in + *android*) + if test "x$use_dbus" != xyes; then + use_dbus=no + fi + ;; + esac + AC_SUBST(QT_TRANSLATION_DIR,$qt_translation_path) ]) From 275276e7efd448e534de7773f89e26b90e7dd152 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 23:45:04 -0400 Subject: [PATCH 100/391] build: Drop unused bitcoin_cv_qt58 --- build-aux/m4/bitcoin_qt.m4 | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 1a7bf386a4..d605920165 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -311,25 +311,19 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ if test -d "$qt_plugin_path/platforms/android"; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" fi - m4_ifdef([PKG_CHECK_MODULES],[ - if test x$bitcoin_cv_qt58 = xno; then - PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) - else - PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport], [QT_LIBS="-lQt5FontDatabaseSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport], [QT_LIBS="-lQt5EventDispatcherSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport], [QT_LIBS="-lQt5ThemeSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport], [QT_LIBS="-lQt5DeviceDiscoverySupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport], [QT_LIBS="-lQt5AccessibilitySupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTFB], [Qt5FbSupport], [QT_LIBS="-lQt5FbSupport $QT_LIBS"]) - fi - if test "x$TARGET_OS" = xlinux; then - PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) - elif test "x$TARGET_OS" = xdarwin; then - PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport], [QT_LIBS="-lQt5ClipboardSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport], [QT_LIBS="-lQt5GraphicsSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport], [QT_LIBS="-lQt5CglSupport $QT_LIBS"]) - fi - ]) + PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport], [QT_LIBS="-lQt5FontDatabaseSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport], [QT_LIBS="-lQt5EventDispatcherSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport], [QT_LIBS="-lQt5ThemeSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport], [QT_LIBS="-lQt5DeviceDiscoverySupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport], [QT_LIBS="-lQt5AccessibilitySupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTFB], [Qt5FbSupport], [QT_LIBS="-lQt5FbSupport $QT_LIBS"]) + if test "x$TARGET_OS" = xlinux; then + PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xdarwin; then + PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport], [QT_LIBS="-lQt5ClipboardSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport], [QT_LIBS="-lQt5GraphicsSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport], [QT_LIBS="-lQt5CglSupport $QT_LIBS"]) + fi fi ]) From 52b87d28bdd4dbbd116ad8628fa81ea6476a5592 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 22 Mar 2023 23:48:29 -0400 Subject: [PATCH 101/391] build, qt: Add Qt version checking --- build-aux/m4/bitcoin_qt.m4 | 53 +++++++++++++++++++++++++------------- configure.ac | 2 +- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index d605920165..877567b39a 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -80,8 +80,15 @@ AC_DEFUN([BITCOIN_QT_INIT],[ ]) dnl Find Qt libraries and includes. +dnl +dnl BITCOIN_QT_CONFIGURE([MINIMUM-VERSION]) +dnl dnl Outputs: See _BITCOIN_QT_FIND_LIBS +dnl Outputs: Sets variables for all qt-related tools. +dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_dbus, bitcoin_enable_qt_test AC_DEFUN([BITCOIN_QT_CONFIGURE],[ + qt_version=">= $1" + qt_lib_prefix="Qt5" BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS]) dnl This is ugly and complicated. Yuck. Works as follows: @@ -237,7 +244,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ bitcoin_enable_qt=no ]) if test x$bitcoin_enable_qt = xyes; then - AC_MSG_RESULT([$bitcoin_enable_qt ($QT_LIB_PREFIX)]) + AC_MSG_RESULT([$bitcoin_enable_qt ($qt_lib_prefix)]) else AC_MSG_RESULT([$bitcoin_enable_qt]) fi @@ -331,23 +338,33 @@ dnl Internal. Find Qt libraries using pkg-config. dnl Outputs: All necessary QT_* variables are set. dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[ - m4_ifdef([PKG_CHECK_MODULES],[ - QT_LIB_PREFIX=Qt5 - qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets Qt5Concurrent" - BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT5], [$qt5_modules], [QT_INCLUDES="$QT5_CFLAGS"; QT_LIBS="$QT5_LIBS" have_qt=yes],[have_qt=no]) + BITCOIN_QT_CHECK([ + PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core $qt_version], [], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Core $qt_version not found])]) + ]) + BITCOIN_QT_CHECK([ + PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui $qt_version], [], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Gui $qt_version not found])]) + ]) + BITCOIN_QT_CHECK([ + PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets $qt_version], [], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets $qt_version not found])]) + ]) + BITCOIN_QT_CHECK([ + PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network $qt_version], [], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Network $qt_version not found])]) + ]) + BITCOIN_QT_CHECK([ + PKG_CHECK_MODULES([QT_CONCURRENT], [${qt_lib_prefix}Concurrent $qt_version], [], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Concurrent $qt_version not found])]) + ]) + QT_INCLUDES="$QT_CORE_CFLAGS $QT_GUI_CFLAGS $QT_WIDGETS_CFLAGS $QT_NETWORK_CFLAGS $QT_CONCURRENT_CFLAGS" + QT_LIBS="$QT_CORE_LIBS $QT_GUI_LIBS $QT_WIDGETS_LIBS $QT_NETWORK_LIBS $QT_CONCURRENT_LIBS" - if test "x$have_qt" != xyes; then - have_qt=no - BITCOIN_QT_FAIL([Qt dependencies not found]) - fi - ]) - BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_TEST], [${QT_LIB_PREFIX}Test], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) - if test "x$use_dbus" != xno; then - PKG_CHECK_MODULES([QT_DBUS], [${QT_LIB_PREFIX}DBus], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no]) - fi - ]) + BITCOIN_QT_CHECK([ + PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) + if test "x$use_dbus" != xno; then + PKG_CHECK_MODULES([QT_DBUS], [${qt_lib_prefix}DBus $qt_version], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no]) + fi ]) - true; dnl ]) diff --git a/configure.ac b/configure.ac index a39ca9cbd1..d0f721b1f8 100644 --- a/configure.ac +++ b/configure.ac @@ -922,7 +922,7 @@ fi BITCOIN_QT_INIT dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus -BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt5]) +BITCOIN_QT_CONFIGURE([5.5.1]) if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then use_boost=no From 1e51d16766f993fa93a2107c475a7d99e4cbfd32 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 10:49:48 -0400 Subject: [PATCH 102/391] build: Drop unneeded ApplicationServices framework dependency --- build-aux/m4/bitcoin_qt.m4 | 2 +- src/qt/notificator.cpp | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 471672a3f4..2ae58fa08d 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -195,7 +195,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ *darwin*) BITCOIN_QT_CHECK([ MOC_DEFS="${MOC_DEFS} -DQ_OS_MAC" - base_frameworks="-framework Foundation -framework ApplicationServices -framework AppKit" + base_frameworks="-framework Foundation -framework AppKit" AX_CHECK_LINK_FLAG([[$base_frameworks]],[QT_LIBS="$QT_LIBS $base_frameworks"],[AC_MSG_ERROR(could not find base frameworks)]) ]) ;; diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 7e88baf3eb..ace267ff4e 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -18,13 +18,8 @@ #include #include #endif -// Include ApplicationServices.h after QtDbus to avoid redefinition of check(). -// This affects at least OSX 10.6. See /usr/include/AssertMacros.h for details. -// Note: This could also be worked around using: - #ifdef Q_OS_MAC #include "macnotificationhandler.h" -#include #endif From 170e765d9dc1815c10e0e841ab511149a3b0d51b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 10:50:15 -0400 Subject: [PATCH 103/391] build: Drop unneeded IOKit framework dependency --- build-aux/m4/bitcoin_qt.m4 | 1 - 1 file changed, 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 2ae58fa08d..a3e1a3d32f 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -121,7 +121,6 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)],[-lqxcb -lxcb-static]) AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb]) elif test "x$TARGET_OS" = xdarwin; then - AX_CHECK_LINK_FLAG([[-framework IOKit]],[QT_LIBS="$QT_LIBS -framework IOKit"],[AC_MSG_ERROR(could not iokit framework)]) _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)],[-lqcocoa]) AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa]) elif test "x$TARGET_OS" = xandroid; then From 8da4ffe4006f0948ff160c19b56f593b90cb83c9 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 13:16:45 -0400 Subject: [PATCH 104/391] Bump minimum python version to 3.6 Also add .python-version for pyenv which will cause tests with too modern syntax to fail on developer machine rather than on Travis. --- .python-version | 1 + configure.ac | 4 ++-- doc/dependencies.md | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 .python-version diff --git a/.python-version b/.python-version new file mode 100644 index 0000000000..8b7b0b52e5 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.6.12 diff --git a/configure.ac b/configure.ac index 38a88b20e6..3ff78824d8 100644 --- a/configure.ac +++ b/configure.ac @@ -87,8 +87,8 @@ AC_PATH_TOOL(RANLIB, ranlib) AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) AC_PATH_PROG(LCOV, lcov) -dnl Python 3.x is supported from 3.4 on (see https://github.com/bitcoin/bitcoin/issues/7893) -AC_PATH_PROGS([PYTHON], [python3.7 python3.6 python3.5 python3.4 python3 python]) +dnl Python 3.6 is specified in .python-version and should be used if available, see doc/dependencies.md +AC_PATH_PROGS([PYTHON], [python3.6 python3.7 python3.8 python3.9 python3 python]) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) diff --git a/doc/dependencies.md b/doc/dependencies.md index d96b3eb6d7..4c4c4866a6 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -20,7 +20,7 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | MiniUPnPc | [2.2.2](https://miniupnp.tuxfamily.org/files) | | No | | | | OpenSSL | [1.0.1k](https://www.openssl.org/source) | | Yes | | | | PCRE | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L66) | -| Python (tests) | | [3.5](https://www.python.org/downloads) | | | | +| Python (tests) | | [3.6](https://www.python.org/downloads) | | | | | qrencode | [3.4.4](https://fukuchi.org/works/qrencode) | | No | | | | Qt | [5.9.9](https://download.qt.io/official_releases/qt/) | [5.5.1](https://github.com/bitcoin/bitcoin/issues/13478) | No | | | | XCB | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L87) (Linux only) | From a97aebf16694e1829b8091e797c0225a2cca8f65 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 13:12:18 -0400 Subject: [PATCH 105/391] build: Fix Qt processing of configure script for depends with DEBUG=1 --- build-aux/m4/bitcoin_qt.m4 | 51 ++++++++++++++++++++++---------------- depends/config.site.in | 4 +++ 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index ac7c6688f4..c6ff4965b6 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -64,6 +64,13 @@ AC_DEFUN([BITCOIN_QT_INIT],[ ], [bitcoin_qt_want_version=auto]) + AS_IF([test "x$with_gui" = xqt5_debug], + [AS_CASE([$host], + [*darwin*], [qt_lib_suffix=_debug], + [*mingw*], [qt_lib_suffix=d], + [qt_lib_suffix= ]); bitcoin_qt_want_version=qt5], + [qt_lib_suffix= ]) + AC_ARG_WITH([qt-incdir],[AS_HELP_STRING([--with-qt-incdir=INC_DIR],[specify qt include path (overridden by pkgconfig)])], [qt_include_path=$withval], []) AC_ARG_WITH([qt-libdir],[AS_HELP_STRING([--with-qt-libdir=LIB_DIR],[specify qt lib path (overridden by pkgconfig)])], [qt_lib_path=$withval], []) AC_ARG_WITH([qt-plugindir],[AS_HELP_STRING([--with-qt-plugindir=PLUGIN_DIR],[specify qt plugin path (overridden by pkgconfig)])], [qt_plugin_path=$withval], []) @@ -285,13 +292,13 @@ dnl Output: QT_LIBS is prepended or configure exits. AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[ AC_MSG_CHECKING(for static Qt plugins: $2) CHECK_STATIC_PLUGINS_TEMP_LIBS="$LIBS" - LIBS="$2 $QT_LIBS $LIBS" + LIBS="$2${qt_lib_suffix} $QT_LIBS $LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #define QT_STATICPLUGIN #include $1]], [[return 0;]])], - [AC_MSG_RESULT(yes); QT_LIBS="$2 $QT_LIBS"], + [AC_MSG_RESULT(yes); QT_LIBS="$2${qt_lib_suffix} $QT_LIBS"], [AC_MSG_RESULT(no); BITCOIN_QT_FAIL(Could not resolve: $2)]) LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS" ]) @@ -308,18 +315,18 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ if test -d "$qt_plugin_path/platforms/android"; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" fi - PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport], [QT_LIBS="-lQt5FontDatabaseSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport], [QT_LIBS="-lQt5EventDispatcherSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport], [QT_LIBS="-lQt5ThemeSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport], [QT_LIBS="-lQt5DeviceDiscoverySupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport], [QT_LIBS="-lQt5AccessibilitySupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTFB], [Qt5FbSupport], [QT_LIBS="-lQt5FbSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="-lQt5AccessibilitySupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTFB], [Qt5FbSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FbSupport${qt_lib_suffix} $QT_LIBS"]) if test "x$TARGET_OS" = xlinux; then PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) elif test "x$TARGET_OS" = xdarwin; then - PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport], [QT_LIBS="-lQt5ClipboardSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport], [QT_LIBS="-lQt5GraphicsSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport], [QT_LIBS="-lQt5CglSupport $QT_LIBS"]) + PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ClipboardSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport${qt_lib_suffix}], [QT_LIBS="-lQt5GraphicsSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport${qt_lib_suffix}], [QT_LIBS="-lQt5CglSupport${qt_lib_suffix} $QT_LIBS"]) fi fi ]) @@ -329,30 +336,30 @@ dnl Outputs: All necessary QT_* variables are set. dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[ BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core $qt_version], [], - [BITCOIN_QT_FAIL([${qt_lib_prefix}Core $qt_version not found])]) + PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Core${qt_lib_suffix} $qt_version not found])]) ]) BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui $qt_version], [], - [BITCOIN_QT_FAIL([${qt_lib_prefix}Gui $qt_version not found])]) + PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version], [], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version not found])]) ]) BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets $qt_version], [], - [BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets $qt_version not found])]) + PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version], [], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version not found])]) ]) BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network $qt_version], [], - [BITCOIN_QT_FAIL([${qt_lib_prefix}Network $qt_version not found])]) + PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network${qt_lib_suffix} $qt_version], [], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Network${qt_lib_suffix} $qt_version not found])]) ]) BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_CONCURRENT], [${qt_lib_prefix}Concurrent $qt_version], [], - [BITCOIN_QT_FAIL([${qt_lib_prefix}Concurrent $qt_version not found])]) + PKG_CHECK_MODULES([QT_CONCURRENT], [${qt_lib_prefix}Concurrent${qt_lib_suffix} $qt_version], [], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Concurrent${qt_lib_suffix} $qt_version not found])]) ]) QT_INCLUDES="$QT_CORE_CFLAGS $QT_GUI_CFLAGS $QT_WIDGETS_CFLAGS $QT_NETWORK_CFLAGS $QT_CONCURRENT_CFLAGS" QT_LIBS="$QT_CORE_LIBS $QT_GUI_LIBS $QT_WIDGETS_LIBS $QT_NETWORK_LIBS $QT_CONCURRENT_LIBS" BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) + PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test${qt_lib_suffix} $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) if test "x$use_dbus" != xno; then PKG_CHECK_MODULES([QT_DBUS], [${qt_lib_prefix}DBus $qt_version], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no]) fi diff --git a/depends/config.site.in b/depends/config.site.in index 391767357a..f1a59a5861 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -54,6 +54,10 @@ if test -z "$with_gui" && test -n "@no_qt@"; then with_gui=no fi +if test -n "@debug@" && test -z "@no_qt@" && test "x$with_gui" != xno; then + with_gui=qt5_debug +fi + if test -z "$enable_zmq" && test -n "@no_zmq@"; then enable_zmq=no fi From d1db02c9741ebb49c358e6d669128aa5e106c99a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 13:48:02 -0400 Subject: [PATCH 106/391] Update ax_cxx_compile_stdcxx.m4 --- build-aux/m4/ax_cxx_compile_stdcxx.m4 | 455 ++++++++++++++++++++++++-- 1 file changed, 419 insertions(+), 36 deletions(-) diff --git a/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/build-aux/m4/ax_cxx_compile_stdcxx.m4 index f147cee3b1..43087b2e68 100644 --- a/build-aux/m4/ax_cxx_compile_stdcxx.m4 +++ b/build-aux/m4/ax_cxx_compile_stdcxx.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== # # SYNOPSIS @@ -33,21 +33,23 @@ # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 4 +#serial 11 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl - m4_if([$1], [11], [], - [$1], [14], [], - [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], @@ -57,26 +59,13 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) - m4_if([$4], [], [ax_cxx_compile_cxx$1_try_default=true], - [$4], [default], [ax_cxx_compile_cxx$1_try_default=true], - [$4], [nodefault], [ax_cxx_compile_cxx$1_try_default=false], - [m4_fatal([invalid fourth argument `$4' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no - m4_if([$4], [nodefault], [], [dnl - AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, - ax_cv_cxx_compile_cxx$1, - [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [ax_cv_cxx_compile_cxx$1=yes], - [ax_cv_cxx_compile_cxx$1=no])]) - if test x$ax_cv_cxx_compile_cxx$1 = xyes; then - ac_success=yes - fi]) - m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then - for switch in -std=gnu++$1 -std=gnu++0x; do + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, @@ -102,22 +91,27 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" - for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, - $cachevar, - [ac_save_CXX="$CXX" - CXX="$CXX $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXX="$ac_save_CXX"]) - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break fi - ac_success=yes + done + if test x$ac_success = xyes; then break fi done @@ -154,6 +148,11 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) dnl Tests for new features in C++11 @@ -191,11 +190,13 @@ namespace cxx11 struct Base { + virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { + virtual ~Derived() override {} virtual void f() override {} }; @@ -524,7 +525,7 @@ namespace cxx14 } - namespace test_digit_seperators + namespace test_digit_separators { constexpr auto ten_million = 100'000'000; @@ -566,3 +567,385 @@ namespace cxx14 #endif // __cplusplus >= 201402L ]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + +]]) From a1c6b491de110055d1e07d7cd05e33cf69d6b868 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 14:29:41 -0400 Subject: [PATCH 107/391] build: Drop redundant AC_SUBST macros Variables that are declared with AC_ARG_VAR macro are substituted via AC_SUBST macro. PKG_CHECK_MODULES macro already has AC_ARG_VAR(${PACKAGE}_CFLAGS) and AC_ARG_VAR(${PACKAGE}_LIBS). --- build-aux/m4/bitcoin_find_bdb48.m4 | 1 - build-aux/m4/bitcoin_qt.m4 | 2 -- configure.ac | 4 ---- 3 files changed, 7 deletions(-) diff --git a/build-aux/m4/bitcoin_find_bdb48.m4 b/build-aux/m4/bitcoin_find_bdb48.m4 index ea9c795daa..2dbf0ea099 100644 --- a/build-aux/m4/bitcoin_find_bdb48.m4 +++ b/build-aux/m4/bitcoin_find_bdb48.m4 @@ -74,5 +74,4 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[ AC_MSG_ERROR([libdb_cxx missing, ]AC_PACKAGE_NAME[ requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) fi fi - AC_SUBST(BDB_LIBS) ]) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index c6ff4965b6..a1284761f0 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -251,9 +251,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ AC_SUBST(QT_LIBS) AC_SUBST(QT_LDFLAGS) AC_SUBST(QT_DBUS_INCLUDES) - AC_SUBST(QT_DBUS_LIBS) AC_SUBST(QT_TEST_INCLUDES) - AC_SUBST(QT_TEST_LIBS) AC_SUBST(QT_SELECT, qt5) AC_SUBST(MOC_DEFS) ]) diff --git a/configure.ac b/configure.ac index 3ff78824d8..758c66d7f2 100644 --- a/configure.ac +++ b/configure.ac @@ -1285,10 +1285,6 @@ AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) AC_SUBST(CRYPTO_LIBS) AC_SUBST(SSL_LIBS) -AC_SUBST(EVENT_LIBS) -AC_SUBST(EVENT_PTHREADS_LIBS) -AC_SUBST(ZMQ_LIBS) -AC_SUBST(QR_LIBS) AC_SUBST(USE_NUM_OPENSSL) AC_SUBST(HAVE_FDATASYNC) AC_SUBST(HAVE_FULLFSYNC) From e09fb2ade18517e8ab628bd0541a2cb26685b4cd Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 14:50:22 -0400 Subject: [PATCH 108/391] macdeploy: remove unused plistlib import Unused since https://github.com/bitcoin/bitcoin/pull/20422, see: https://github.com/bitcoin/bitcoin/pull/20422#discussion_r534207899 --- contrib/macdeploy/macdeployqtplus | 1 - 1 file changed, 1 deletion(-) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 0ea8982623..6ff5bcd1e0 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -16,7 +16,6 @@ # along with this program. If not, see . # -import plistlib import sys, re, os, shutil, stat, os.path from argparse import ArgumentParser from ds_store import DSStore From a21ecdb4a6a72a65ba2a2125a2ed32f58329c00c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 14:50:52 -0400 Subject: [PATCH 109/391] macdeploy: fix framework printing when passing -verbose --- contrib/macdeploy/macdeployqtplus | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 6ff5bcd1e0..6708da58da 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -52,7 +52,7 @@ class FrameworkInfo(object): return False def __str__(self): - return f""" Framework name: {frameworkName} + return f""" Framework name: {self.frameworkName} Framework directory: {self.frameworkDirectory} Framework path: {self.frameworkPath} Binary name: {self.binaryName} From 1601e30a64d4286d7d7cbb7a0a7364b0b6fcd2d3 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 14:52:18 -0400 Subject: [PATCH 110/391] macdeploy: select the plugins we need, rather than excluding those we don't --- contrib/macdeploy/macdeployqtplus | 100 ++---------------------------- 1 file changed, 4 insertions(+), 96 deletions(-) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 6708da58da..415b38c332 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -350,112 +350,20 @@ def deployFrameworksForAppBundle(applicationBundle: ApplicationBundleInfo, strip return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose) def deployPlugins(appBundleInfo: ApplicationBundleInfo, deploymentInfo: DeploymentInfo, strip: bool, verbose: int): - # Lookup available plugins, exclude unneeded plugins = [] if deploymentInfo.pluginPath is None: return for dirpath, dirnames, filenames in os.walk(deploymentInfo.pluginPath): pluginDirectory = os.path.relpath(dirpath, deploymentInfo.pluginPath) - if pluginDirectory == "designer": - # Skip designer plugins - continue - elif pluginDirectory == "printsupport": - # Skip printsupport plugins + + if pluginDirectory not in ['styles', 'platforms']: continue - elif pluginDirectory == "sqldrivers": - # Deploy the sql plugins only if QtSql is in use - if not deploymentInfo.usesFramework("QtSql"): - continue - elif pluginDirectory == "script": - # Deploy the script plugins only if QtScript is in use - if not deploymentInfo.usesFramework("QtScript"): - continue - elif pluginDirectory == "qmltooling" or pluginDirectory == "qml1tooling": - # Deploy the qml plugins only if QtDeclarative is in use - if not deploymentInfo.usesFramework("QtDeclarative"): - continue - elif pluginDirectory == "bearer": - # Deploy the bearer plugins only if QtNetwork is in use - if not deploymentInfo.usesFramework("QtNetwork"): - continue - elif pluginDirectory == "position": - # Deploy the position plugins only if QtPositioning is in use - if not deploymentInfo.usesFramework("QtPositioning"): - continue - elif pluginDirectory == "sensors" or pluginDirectory == "sensorgestures": - # Deploy the sensor plugins only if QtSensors is in use - if not deploymentInfo.usesFramework("QtSensors"): - continue - elif pluginDirectory == "audio" or pluginDirectory == "playlistformats": - # Deploy the audio plugins only if QtMultimedia is in use - if not deploymentInfo.usesFramework("QtMultimedia"): - continue - elif pluginDirectory == "mediaservice": - # Deploy the mediaservice plugins only if QtMultimediaWidgets is in use - if not deploymentInfo.usesFramework("QtMultimediaWidgets"): - continue - elif pluginDirectory == "canbus": - # Deploy the canbus plugins only if QtSerialBus is in use - if not deploymentInfo.usesFramework("QtSerialBus"): - continue - elif pluginDirectory == "webview": - # Deploy the webview plugins only if QtWebView is in use - if not deploymentInfo.usesFramework("QtWebView"): - continue - elif pluginDirectory == "gamepads": - # Deploy the webview plugins only if QtGamepad is in use - if not deploymentInfo.usesFramework("QtGamepad"): - continue - elif pluginDirectory == "geoservices": - # Deploy the webview plugins only if QtLocation is in use - if not deploymentInfo.usesFramework("QtLocation"): - continue - elif pluginDirectory == "texttospeech": - # Deploy the texttospeech plugins only if QtTextToSpeech is in use - if not deploymentInfo.usesFramework("QtTextToSpeech"): - continue - elif pluginDirectory == "virtualkeyboard": - # Deploy the virtualkeyboard plugins only if QtVirtualKeyboard is in use - if not deploymentInfo.usesFramework("QtVirtualKeyboard"): - continue - elif pluginDirectory == "sceneparsers": - # Deploy the virtualkeyboard plugins only if Qt3DCore is in use - if not deploymentInfo.usesFramework("Qt3DCore"): - continue - elif pluginDirectory == "renderplugins": - # Deploy the renderplugins plugins only if Qt3DCore is in use - if not deploymentInfo.usesFramework("Qt3DCore"): - continue - elif pluginDirectory == "geometryloaders": - # Deploy the geometryloaders plugins only if Qt3DCore is in use - if not deploymentInfo.usesFramework("Qt3DCore"): - continue for pluginName in filenames: pluginPath = os.path.join(pluginDirectory, pluginName) - if pluginName.endswith("_debug.dylib"): - # Skip debug plugins + + if pluginName.split('.')[0] not in ['libqminimal', 'libqcocoa', 'libqmacstyle']: continue - elif pluginPath == "imageformats/libqsvg.dylib" or pluginPath == "iconengines/libqsvgicon.dylib": - # Deploy the svg plugins only if QtSvg is in use - if not deploymentInfo.usesFramework("QtSvg"): - continue - elif pluginPath == "accessible/libqtaccessiblecompatwidgets.dylib": - # Deploy accessibility for Qt3Support only if the Qt3Support is in use - if not deploymentInfo.usesFramework("Qt3Support"): - continue - elif pluginPath == "graphicssystems/libqglgraphicssystem.dylib": - # Deploy the opengl graphicssystem plugin only if QtOpenGL is in use - if not deploymentInfo.usesFramework("QtOpenGL"): - continue - elif pluginPath == "accessible/libqtaccessiblequick.dylib": - # Deploy the accessible qtquick plugin only if QtQuick is in use - if not deploymentInfo.usesFramework("QtQuick"): - continue - elif pluginPath == "platforminputcontexts/libqtvirtualkeyboardplugin.dylib": - # Deploy the virtualkeyboardplugin plugin only if QtVirtualKeyboard is in use - if not deploymentInfo.usesFramework("QtVirtualKeyboard"): - continue plugins.append((pluginDirectory, pluginName)) From e018687bc08cd940e44f6b200db3bca623e8f5d1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 14:54:21 -0400 Subject: [PATCH 111/391] macdeploy: remove qt4 related code --- contrib/macdeploy/macdeployqtplus | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 415b38c332..a0b714d2ec 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -84,8 +84,8 @@ class FrameworkInfo(object): if line == "": return None - # Don't deploy system libraries (exception for libQtuitools and libQtlucene). - if line.startswith("/System/Library/") or line.startswith("@executable_path") or (line.startswith("/usr/lib/") and "libQt" not in line): + # Don't deploy system libraries + if line.startswith("/System/Library/") or line.startswith("@executable_path") or line.startswith("/usr/lib/"): return None m = cls.reOLine.match(line) @@ -286,14 +286,6 @@ def copyFramework(framework: FrameworkInfo, path: str, verbose: int) -> Optional if verbose: print("Copied Contents:", fromContentsDir) print(" to:", toContentsDir) - elif framework.frameworkName.startswith("libQtGui"): # Copy qt_menu.nib (applies to non-framework layout) - qtMenuNibSourcePath = os.path.join(framework.frameworkDirectory, "Resources", "qt_menu.nib") - qtMenuNibDestinationPath = os.path.join(path, "Contents", "Resources", "qt_menu.nib") - if os.path.exists(qtMenuNibSourcePath) and not os.path.exists(qtMenuNibDestinationPath): - shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath, symlinks=True) - if verbose: - print("Copied for libQtGui:", qtMenuNibSourcePath) - print(" to:", qtMenuNibDestinationPath) return toPath From 502e8eaab3943e60f908f1e58dedf30fa9566738 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 14:54:46 -0400 Subject: [PATCH 112/391] macdeploy: cleanup .temp.dmg if present --- contrib/macdeploy/macdeployqtplus | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index a0b714d2ec..8e207a3f99 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -423,6 +423,9 @@ if os.path.exists(appname + ".dmg"): print("+ Removing existing DMG +") os.unlink(appname + ".dmg") +if os.path.exists(appname + ".temp.dmg"): + os.unlink(appname + ".temp.dmg") + # ------------------------------------------------ target = os.path.join("dist", "PRCYcoin-Qt.app") From 1efd3a760c5fd8bbe86eb7819ca52a838b6c2655 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 15:36:20 -0400 Subject: [PATCH 113/391] [qt] [trivial] share/qt/make_spinner.py => src/qt/res/movies/makespinner.sh * Merge make_spinner.py into makespinner.sh * Also delete now unused imgs * Actually use all 36 frames for the spinner animation --- share/qt/img/reload.png | Bin 10085 -> 0 bytes share/qt/img/reload.xcf | Bin 25292 -> 0 bytes share/qt/make_spinner.py | 38 ------------------------------ src/qt/guiconstants.h | 2 +- src/qt/res/movies/makespinner.sh | 6 +++++ src/qt/res/movies/spinner-000.png | Bin 962 -> 1835 bytes src/qt/res/movies/spinner-001.png | Bin 890 -> 2376 bytes src/qt/res/movies/spinner-002.png | Bin 896 -> 2376 bytes src/qt/res/movies/spinner-003.png | Bin 914 -> 2355 bytes src/qt/res/movies/spinner-004.png | Bin 898 -> 2349 bytes src/qt/res/movies/spinner-005.png | Bin 896 -> 2305 bytes src/qt/res/movies/spinner-006.png | Bin 918 -> 2304 bytes src/qt/res/movies/spinner-007.png | Bin 970 -> 2283 bytes src/qt/res/movies/spinner-008.png | Bin 946 -> 2312 bytes src/qt/res/movies/spinner-009.png | Bin 964 -> 1810 bytes src/qt/res/movies/spinner-010.png | Bin 913 -> 2305 bytes src/qt/res/movies/spinner-011.png | Bin 934 -> 2338 bytes src/qt/res/movies/spinner-012.png | Bin 918 -> 2352 bytes src/qt/res/movies/spinner-013.png | Bin 927 -> 2377 bytes src/qt/res/movies/spinner-014.png | Bin 901 -> 2358 bytes src/qt/res/movies/spinner-015.png | Bin 881 -> 2405 bytes src/qt/res/movies/spinner-016.png | Bin 904 -> 2429 bytes src/qt/res/movies/spinner-017.png | Bin 926 -> 2408 bytes src/qt/res/movies/spinner-018.png | Bin 892 -> 1831 bytes src/qt/res/movies/spinner-019.png | Bin 911 -> 2380 bytes src/qt/res/movies/spinner-020.png | Bin 925 -> 2366 bytes src/qt/res/movies/spinner-021.png | Bin 913 -> 2368 bytes src/qt/res/movies/spinner-022.png | Bin 915 -> 2356 bytes src/qt/res/movies/spinner-023.png | Bin 894 -> 2311 bytes src/qt/res/movies/spinner-024.png | Bin 953 -> 2315 bytes src/qt/res/movies/spinner-025.png | Bin 939 -> 2298 bytes src/qt/res/movies/spinner-026.png | Bin 951 -> 2291 bytes src/qt/res/movies/spinner-027.png | Bin 944 -> 1816 bytes src/qt/res/movies/spinner-028.png | Bin 967 -> 2308 bytes src/qt/res/movies/spinner-029.png | Bin 959 -> 2356 bytes src/qt/res/movies/spinner-030.png | Bin 910 -> 2346 bytes src/qt/res/movies/spinner-031.png | Bin 897 -> 2380 bytes src/qt/res/movies/spinner-032.png | Bin 899 -> 2345 bytes src/qt/res/movies/spinner-033.png | Bin 940 -> 2401 bytes src/qt/res/movies/spinner-034.png | Bin 945 -> 2422 bytes src/qt/res/movies/spinner-035.png | Bin 0 -> 2406 bytes 41 files changed, 7 insertions(+), 39 deletions(-) delete mode 100644 share/qt/img/reload.png delete mode 100644 share/qt/img/reload.xcf delete mode 100644 share/qt/make_spinner.py create mode 100644 src/qt/res/movies/makespinner.sh create mode 100644 src/qt/res/movies/spinner-035.png diff --git a/share/qt/img/reload.png b/share/qt/img/reload.png deleted file mode 100644 index 735d9f165b1647331c2583945e802d0e862e2964..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10085 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 ng#2Hh+57GPZ#n~QJtK3Qdl~Z_4*UUH
qv=ysgTZH`&=@-$8 diff --git a/share/qt/img/reload.xcf b/share/qt/img/reload.xcf deleted file mode 100644 index dc8be62831673c2e99f05f5e5b42581e6e4e1db1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25292 zcmb_^2Y8gl_WtZ{I!Q?Hy(}b<0!T>!i3mz>b^$>V5F6Z!w4YZ&(W@v5C?M7#R#ZTZ zV!0wJ5F1J8AtaO(0x6KXNl140`@ipe--Zo_h|lwfXS3hVoO7m~Ip@4*W_RwqM;1ga zoi!(F&b)_b3;bK5z4+{nmrjR2zIeF|U+eG|UwHPz%K@(lyaKdm()ojaINrVHLTu8! zNA8_FJ8AB}=iQGYfqI?jx$v=N56_NTIRD{!_b0gZoHKXU{D8=`MUo2pO%(3DD}GQ(gqA1 z(4TeMKixJVM&Dukg!dKNi?i)B{N7m)&HeZMMUUPeHEaHYWwCuwD4g)(+9-IrXwRf} z)t>Pt-0Ysa**&}4J$u+acgHhj+5S1>fo<@gy)LLFLO)e|Sb=xGK&xMfk&MMN|E*A8 z`ZYoXe<6f%oe=#nQX!Tb28yPHiE}or-JbQ?2cnOt55NEQ{fGDO`*G)vkKcVmB#WBJ zr8#F$<>&qO^Y@^5=e4z>x41Cj+nV#mCrI|q=UcbDx&Ed9ibPR0<3vL>NDut}%m2RG z_F?9xbuT>qxacV=GEO$vR+JPT$;saR%@?1%_ZG;PFa4J=igQsr+8QsEpFV!@k3BY) zmH%1v=v)ym$`@Q{sjF1Ez9rX&m!Dg)?B5UFKV8I%GW})7AHLrH(dO4*dGVPi7SEqM z^R6i(MwF(W0&i*2(cE8u`tHk5-+z0fjraD6qeQeQnNe-JckT+`n&XvIrNarrJ;B8=92+rrtXKreTBn^+`$U zEyBdfA?mc+R$$fBk3aUvoEdjc9&_Um%1P>#AVNh^_=(~|`z65~KR9dJZS9g0d-fpN zcO6y;(`^$qKo!-~7$-tR;gfQ`S89x*KK>QrIkRN&Q# z+|?E%glhIfL)k9QxYN~NXO@gS3lPV+2ecCw^MYSh2DLe#%E*JL}y6D;~ z3zI~Rmn`$UOqe3-LcwZRk}B#wf&=Ud`U;(2(`Al+!sLAUQ-9IyVH?;0(PGdh&nTAb zeiRmii|8k;29YML14X*9`ikY^SJCv;o1f+8oUN`rPcO9e!#^%G*4NftsH!+$4vTIb z1Akhx?2B_P&8CLB+KV7Ncea$SXhVM6rIx04+OpDOx}wY~bL%A=X~ns-WhG}$!6ZYB zv#3~IWl?$RAiwf_Ie1Q=ETTVJmSd{1%#&@!?fc|K!$abmI6i z`Xf&;wxL1vqXT39u_N?HE2}ML8!x(EZsW~AdiWsyQKqS#8zVkfj_#gDv&WAeIdmY8 z{wP!OW9T&;I{DAAZSo(;%@KhdnWH$9iGek9GA?RjFfdij!MvQDTsoypbc7Ql1z`@Q zpaKXw1VOoZ2kDgF(WI!;UsggX80eA1Qp$lthv}4FROQ�ux+RXp@tZcks}WV=yh& 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 Z<39yuc2k_qwzvQQ002ovPDHLkV1l+mT^RrX literal 962 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4nAih+LR^7dCPoHEAjQDU$OxpF z7#J9VBFxOpK$3xhT}?qO$W=Qw)YZkwj-7*xiHQlQN>N&HL%sC1b9?>#{D3OK8W|)- z`46;9%*a<<*Qga37|6uLz{tq5uU+bJpRlopC<7A*3mZqWpX%8;4i691-#WQkQ%zA? zN}QFA4QQgCif~1w3Z?me&ata9v z+3E}bT*~xj5&w~XO?PW$ZccUEpez>;u?J~jt+c|Ep^mu)`|KG=( zw-@N0nd@+UbN-+8V(*p<{@=v#XM^mgE3^N9zV&|_@2i7FPftwvzm?D-&xwtH-Ul)HUA!#JB>U>u-{0n}>;Xm@|Ni}G5Mp8Kk71TiYxwoM!0gaB z0Y=8Tf6lKw;K$6!!ZzbuGLvoprnQx7Oe&0*WPpyj@9E+gA|c6oP}fIK}6QXOhbhKkZkMWf|)Lb$pJp)KAJ3A_MLAHHcyIuE3PZ;9q)2 zx4Q6#6X8=ghx-{-{`z%UE}(|fJ%44^`EC5EyKb#4lQ~ne>fYZ2GCr2S%=Z7Ec(<$7 zysvStPUiWjWku({IVZAu{0cjLw`jWI^ysh4j(z{$bI4zMcCUxmelF>RwV~cBnzc7P d9reGaO>&oTvNW99?3@n@cTZP8mvv4FO#mlQQTPA= diff --git a/src/qt/res/movies/spinner-001.png b/src/qt/res/movies/spinner-001.png index d464820687163933eb0a451b7607a1d5c754ac0e..d167f20541f8a33511136d109a9ff016f6ea338b 100644 GIT binary patch literal 2376 zcmV-O3Agr%P)z*I?sO<09VFoYR2sgSUkT3muKI*>3!a2(125exzlt0&AsP* z-?_iv@B7sz*ItyqL8%3a(SwM)BfO`0y z2vp+`InFXQ_i$VR_3!j_lBBv=Orr?2jzT=nA`Gu9&h!+coJ0#F7)F%>YB@ceB&T7_ zYQ>JO&jyN|rF|3li{ebrGR0X??`FRO>V5`wbVK861ziI@-q8im?cZ4$y zBb=@ju%X$ETvY;6&ut{w9cEufu$rSjerNmU4=lB_L`E}}?KcImB~Kb-N9`Mmhx^#d zd6QsjXzU@`Zju^GD!=C|6G1l3BBJc&PCv;fri0YbILBoB7@D4xa3vrxo8n2CcKCe5 zNafvtfo#&gg@guQGViCt@Rl2|o%==3E1Yj%ivJQB!PdP|{G87XZTAxIv4v6=@*tyl zf`zQ2(g2O9WCAh4{%||7h!X}*WFNE1Agy`BZbI_Gioq_E!4Mh`I;uaA*;aT^Obr>mFWXA~ZL&^`|<`9ZnW zavm0#jGF`l>gOD5=|Q++T`vR3qBjxNzzkt7rf|TV#@iP zV{GO@ynzSWjjxqkeNp*)XY+wyke4YT%MZ+~R)*{}GXgEc(JWMMb`@Qe%TM>KX%92U zZ!JSVpP#9U2Lc_UtQ5C;m7RhqxjqW`UTI3Ub1$KO)K3Uggy-JmM}Z{p%M{!FkfDC{ z^iYL&bBg7dt&?`&k!y6o49HjDS-m|iueIG zFj=>%B!mfVY-lY-+-XpyJg;DznMAZfS`b2-f>nRb zK=ZY4G?Nr=ah~CK#FNh=R#HG$zv`#$=*&umZg|stpgnj+!Gw%gleqBWy`e_6i+CaUq%s8tk zHZC3&J>U!c#7xgMmXF2XGtokaDuylM9u}IZkTOLHskYQTcJr7Bw1Q~!7I{i!sp~BE zgfql!zzMR=mz}@I4x-2tvH-cD@yW7Mo>Y(%2;c-5ms=$zn+61G8Q~M11|mAOP*gX3?*W zHRtu&928z(Xc;SNNgB2aJ9&pxb6($13_L#lUPVoVkRRoJkE&G zWRqHi64@=h{?j19Oyo;JExu|NH*6TfDQ_d$0w;bp=0cah+ zF;4}&BzmLME!VrtL~SwMyafux{MjbDSPXQh7zocc??n4?QB3&ux3t*FD-yt3ZZmI* zE+Qkj$`T7B4517W_wcTni$qbN@a~f>0~*O-`X(P*#XVwL=85d7UGiN27)!dK&_pqKMNUG1IhMAKevg%U?0x zFl(MiO{-`BK`-4i@v?+EF-pH8P?D0%Nnycy3JpCyNN9Vmr%>liUCiVQMP@cVaFNyZ zV)l8qPI$^iEK?Mfy;a2P7`AGK$UGjnDh3$HVPVO^eorNmG}bD+V2=CYs&3-gqj;`@ z_(1Y9H}icuKljktuY~2Y*H69mXFQ}NechG0?t10~)}FbEqqr5hK1imYzrTa!Ivq{h zNK=SOA66@Wph~mzqLRGDvz(J?d`A_pk)xDPHzU}lTLU;vj6H=gh^+1w$AK%vZ3Pmhqkvg`|ySpYo{&o(@W2PH`TuingzH9&9a%!gt_dvKUGJ-&{kI zJt}%{Wr}WJQzMm3^QoG5;~|r`{Pwq1@MC+l=B4qn7zt=ywz`Q-A4U|-ofHZI&6e|| zQb$`jTtqO2_jT3JQRcPj;dbL@7|YnJ^JEPR0!b2#j$SO)t(tFO2U&Qa8K{ROQpl%_ zW4gUfrcD4Xj(UmZm2Kc*!-T7z?C4k7ia>d0fPA% z^XQ3fMmU)qG9BbaUL@TP=A^Z;pV1E0qCdZ32lwH%Lo1%I-?_mwnB~l}^X-p!w4)7L zrFc&98oBhh<4LxpfTM5d+K|TPkjh&;O9~Mk;W8L6zw+Bn*wCDeztAkt=c(Xh_OgbF z{FKfe=W3r2dh)hXz5J342JMf^HnPH5mqFj6^kZttbJne^X+oJy)BK1Odz+5-8k&4%ANU$NJLxLYTa?Y~mn^Tv z59kObm47Kcl7UWw8cDubi>aaUXDj;dt&BXpAePo?)Yu_tY37Jme!frH>n^dIr-Ye` zdmENJ>2BmEr8HB>k=OA&jvH}8qg6Gdod-0O^frAnS6OXV1Bcx_nupkRE%9`QRrGc4 uKR-!f2J3m56^t`{F+qnNUgCpiRQ?OtN?XCuhW~W{0000rbd2=}E1%cfp+ zXis2LH*|D$1q1>B00Meh8T+LG*qI(nLNG!x5!#z0(4$P+yMA6;QUn75000JvV;udc z0c}+$lW7;+n;oo|Z2|%W0RaJWRT|`^4TNAD009L90ssmK1t%X4r*|0nst#&ZECT}r z1_S{E0s$lhX)1(0RR950|5X41d3!C+?W=G zU>aITBzk2$)U|pY92)`w0RaF2009SoTo|E(Mimkd0RaIc8x3bn5QJV6c2yEMEEE6$ z0{^fN|Fj?Nt~2AhYy7be&Y3dfyKevU)b{Jt-laF=o*2)WG4s`%^5ez-|M&m71Ms5{ z+^I(FrWgI{#s9Vj{;?eYvIPIB0r8;;+^S3Gr6>Qe3;(zR|E&Sp$ffkD3jenN|GftP zx)$=VG5`PnzFe`00001cbW%=J00IL&Z-!YMBE#~80RkcN)V0l)1Oo@Kt~Uh%XZZR> z0})UI0lxmbA^`#gs^fM65#0Cw_NAMW0|Th~`h05o{rY|a3cCEP#Qo_F0iX7?4FMWS z(*3p-1O!zLVfyJi9+9sJ0tE-U`nHg>`Y-|k53SoX0z!?cnqdpk>CF`Y007QOL_t&- z83n<=E5rc+2hh)Bp)M1Xg;*$MLIxQqKXZ&y46H}uUof5FSS^%nbP^d1CNW7?VzJq7 zVDa^yBvB+un*NeVqDV9RCW%DRVjEQy4NuYigS7*=w#QTEP;=?~$`CJDroP zj6QIjtl{p%ItD$%!0Tb{OHd1NtU8b)62B QVE_OC07*qoM6N<$f*)x~4gdfE diff --git a/src/qt/res/movies/spinner-002.png b/src/qt/res/movies/spinner-002.png index aca0c7f307f635ae1fc9cbf04287212f934c3816..4a1f1f8e5660abc5ed3675da7bc26233888a0e75 100644 GIT binary patch literal 2376 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 diff --git a/src/qt/res/movies/spinner-004.png b/src/qt/res/movies/spinner-004.png index ec616718b2f582d3a7cf23befb7e4eca134ce348..4df2132344fb240bf6b4a97e4ea48b3e167d519c 100644 GIT binary patch literal 2349 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 Yf5y=?epJ4-+5i9m07*qoM6N<$f(Eip(f|Me diff --git a/src/qt/res/movies/spinner-005.png b/src/qt/res/movies/spinner-005.png index 74790b142ca7e21fb32880a3693e0eb16a83f45b..5d6f41e0dc04e99328c248c45e16ec8f391128bb 100644 GIT binary patch literal 2305 zcmV+c3I6tpP)&7IK}$;lu@bcyv}p?{O9^Sg>Hhf&~i}ELgB$!GZ)EG4S1-afT8s24%8HEs0^S#kC4a{JWVobJj)Y2O(Ii?BAg&p&Chc%kALE6 z)%GzGTUSzaU}HG3q_LhooTLg5wbao-9UeS1;NdF&;sEcEK_ao(3F`EzVSLnvrUwtN zb`?^GE>gl{3=#J6lHmK5%nIyGPUUTCsWnKmsnxQb z8H9GQ``3jtI#$>ItqUV~mcvpg{=d~x&0;3C>BUK|;G0Kr2a4z%ws1iz&8AkvCp=16 zOFzB&tKeHDxC29TIfwbq1e%`aW9T=GZ0^a;e!(}2=xsj9@9{UPO(WUVuCtyo01Tl_ z@cH}Z%fKIS#E$_tQb#q7)N+|>zg|xjc?<)_2o2;fW?Sfel+dVYn3vei4xS{5cxLek z_cMzmo@X6}9N~^I`c?__AFDdxwF)99mw^K+I_-pMnoga(mf){Lse@vhHB z+sG?CPKckIL@*Dqoa>s*p|xyGHp@nX`LoZi&oGS$ozHeMn|y(A_chB2W)WTKQ>T7F z9}Vu7@4YBKJrs%{TgFAwd=rS*z9b>32+fK_bC{!Q|A(NDcNWBClw`NTft8z#D3Hc z4cJI;3Ju2~Qsv48C-b=?=;)-OQ%oVnAkk`O%bn3+-WMJMuNbrtH}4uETFF$oGul_U z$Zj&zu;t%LJ~g_De$72{Ep&`9T2sLHC4{~0{EU~#Wj~*DgmNmVrdFfUEiU_Zv&mh^11?~A(VYWPjDbT3}KWAh;Hp3)dO;gzAYfS%*=RdSK+x1o6#xrqHkRZ zwS$Aajvfhx2=Y1IoZY(0iY~NICr%>e2T)q;-AOECH4AwVrAwBrg33ZRu$LUti8XTp zEAr1SzveOrPs?uccjos@^XWxSyXe9(;(FqC7~3JvdxO=oMSXX`3c*=k*z<@wggLyg z7}nE>Mo}Oj`Z>3Eb3egv4C90_rmV_cHY1qAD5B{{1VMleHK61b?&Z9I=<9MzZz3t- zJjW=bi1*maMqVJD1tf4EW4VigMB>DO4Ny#}`mvEB2=G6djFU@roUrgkTf4@m?P@gjV6HIs`x$-YTF65NLd+gK{Ff+$BY07m;L5`xS9~RC z%02rkTU=}C7>MDx&_te+?K3P8zE6MJb_4I;#v(2W6I_Gj61Dp%(a_pTxlMQfF)6!}Uf8fTdpBXYP<2cEXDIWU3^wW7T?`jB z+TyotBS^v^BG}~P!){#vqN2t?OQPfBQgUzMs zWT&uXe=rIPt2AA>x|J>Q=&*MW9uDZfVB*Kp6)D{lErlAt<4aTT8rD(4hCoDALxmCY z;+8v`PEz^UG@4Zuk`$;^z;U5J;%qhN{mIdEqru;Hl-JDOfNo(Z-w1}VtxdevhKt7p zKLuf|?Pi{YqDsw7wC;-~63~a`9Tx9aP4C>rZMd06IxmvLmz<)4E7VfS zWvVzsB}dp#HYrSJ0AbM8C3lm_ZKG%QGDq`}6jUIDFx-qLo+;eV-Hhi!Vj0f_RD!!x zMd7`yq>>xdaD_K?hq`W&w?TKUBXlvD*(5O`P(Rnvl~AB-fAq?N1q&7|Sg>Hhf&~i} bdOrRKsU};HTu#dm00000NkvXXu0mjf;C)wq literal 896 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 ahWHQBDqH0#@AX#z0000iB_=yD z9<6{R)RYvOZxuT(6$}dt*Vots0|Oiu4TfMBaaSe)00aU80Rsa7byE@iuK>@OE$Gpu z;^E*42?;bQ72%u}VNo&y0s#X800002g<%}qnHb{4iq_J~1Ox^F0RRUD0aHI37*WcUM#$tS$l9?0|EgG2?qxU z3lR_w$(ld;-l}(WacWHz;+`4~4-g3o3=9eh0|EebRv6Ee6n$SM)}=@L=fG)bXHh&7 z<(v`~6Al0X1+sk=*Q{DBEG`xj3i6`}{jmsEK^X@I0|Eg7009Wfj1&E>0qdOwl8b%- z0047S6wZ|>D<>cV1Pa-d5B;hD;hPlQqAy`jECT`o0s#O30S1a=7=d+PAs`+A0R_N^ z7Y+^&000CwEE$P!JCEf2N&mS7@v0)-vR(hR4CkRgz9s!~6#Qpw+di^y7+5JQ@{{4;!0u$^0`MU+8^;#P8`}g~r z0|E@Usxl7d9|LB;^XP#sbc%;z3JMYr1O&*d#NYq`0K-W{K~xwS1;H^ZgaH5s;P+X4 z$`3FyiQ6RIphRqnOzP4NCdo~7QdV^gCI*voNtv$1Mpw#k$#^M~ksqKww|E{27$if3 zp)!#qNrw4NiZVt3@ROpH(I#4GI_2Bg*Esmhgx!meDHXOa!TSt)Qmwb^uDvF6Hg8^J z9y~1rkFv6Q51n;zCmT!8Zj+h?-NkNO>bTkh)t(2H{?6>1^EANOo}xiTACu@GOHm#H s;80SONsDHZB$5<=Yn^1ec5q@p|1GaF(ivs)0ssI207*qoM6N<$f@TCx*#H0l diff --git a/src/qt/res/movies/spinner-007.png b/src/qt/res/movies/spinner-007.png index 94bca7d10ded4766ccc8114310c02771c57abb8d..1e794b26262243c76c05f068c47a3c4d10bff53c 100644 GIT binary patch literal 2283 zcmVw*p)M@NTE}A{fWg(i9 zsmsS&skmhQSdpTYU}#Rq)UYxsf1#$Lrr=0X;qDI@0{46F{a()Da@q5JpZ~b`p6_{o zKj(aYAHakO6DCZUFk!-k2@@tvm@v`fp#k8J285tt#RqHa-~TTV$WTV`W2Q5QN6F)L z7EwqExy&Y=MB=d#jI}3I^kp=&$ftWOs6@K^Rw zMGZ}Dh>6El4pGEZq6om&Gbl!p!yfF|X*5K!?YP82mNJo8{Jr}$Ci4{KoN2c`-5(eE zm`MbCr=qekkQ_E~T8iSeafMZ+;*Z7q&g5oA6t9irtR&HUC|U^N*LGe-_z@LuEck1xX<$FwIl|}E(a06U zzx{xFxvsm2#_+ZQ%UDZ2Uy;w9j3t#wV!4T6Zr~@3Cy)7*a>9^Q4=~Aq4z{V5ypM$VC}b1lb{OYN00VhzoWrl?aH+$$HV`9EbO6P|Wt`y;^p`YQ zeaPUL@Cj#G)Is6gqT{YKkSy;$P7!X~4UEE1$>F$i_-Q69jv_;Nlm7^0`b3Kf@!<*Gpzs@R zmU-zKBLyblB)?Fe8PG`N6~SvQXEXqV1^cT^PE+`hCvXl5+%zXfsm5_cHyKmMOMo9! zb=OnR47rG>KSu42CQp8z9G#klRW9BsCSi_l?tyDsaB46mX zmV$+7G`I)~|2Gb+iCdZx&M+pCNrb}WMkEbN@=LF%_0H6%l?PI$faVF(yf5Y5v7C{i zfavSqPP6&+uXCEUa6Qg4zGoDc2QY)Z5@)qo*3en7Dhj7vKPj3g`B$gN*71<+#top5 z=ScBTiPlOSk5Z=VY&shs(OcfeoyN`~UgZwH>&cRprymR2xY4V* zn@|sJ<6tJS)=(bb&JNkEpM~#pszZ{Zm`tKQq=|bmhE-I%?10FX&CXj`q+5?JC7XdB zQRW&p#oe9e#Tm{V}jvMZnew+-7gfZhXC0V&3=6A3F2bivc=sbgc@OJEc zNFp}Iv7AE=pM61+5|=R5;l($yO+Jei$6j4ZM|I=DbF2U~EZocz_O-sEOKc@o$wBJF z8#>S3N3yKGeN5m0JS(uQwZvj+ama4r5#C`NYk8irN{an9vURI22jqxqLl_y{Y{OS>qk;=^>^;=P^aPWn6z zpdTOVPWy37@jhD+&onZ*3)+T#N#&@Z#rYl?eQsr(?s>S%Yyw&$nlgb#t|UvbRIN_> zyBEt&UZ6{3e;dbZx}X8aPBr%uq>yYs3I!L1b}?LT>R^`XPW;<8%OA{Qp-nx;lS(`x z@L?EhgwgIFWh31Hp3${f2_4?_eqm;?mRIR39}IIN>x8BJJt{hJr#bY=HnP~kyUBE# zODf^#^zO8Iu@KHo9WU!z=r>VC@qVbo=B;3e!=i(@-$g<8EmAuv)o`A6;%Q%EiJG*k z#t=$cH%%SIj1p|}RW8bU$5=ozy|EfL0~(_#bm3)}lc=tEKZp$8WIZo4mt^5KNo1wV z!q3;d!Q;fy3-MiUOUq7rhf`}lLcycMHieoP4`jp$dE8#MTrCcx=px1Ml?QG^*mN1`r6!Q+NTbi7W1cm2# zr2DQ!TjPY0Jk!Y?QUiJo47z7XIRUv^eAWqlExf%QjMLtsY$tD;j=WPXI$m zB90Wkhc7Wi0{$)8C=(`3m@r|&gb5QSOqeiX!bDHTe*w?vTXVa0F6saP002ovPDHLk FV1n&5V_EAA?|lE?URF0RV7-U?>VbNpaDM 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 Ad;kCd literal 964 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47{3Pigt!8^jEq16D9*^l$N*$A zF*13Y3z=#PGBGiMrGT;w%uGOn<;G;*mTYTrQ4yd@W<~}{agoQfxxOsoxO?rWnT55i zI1d8@8xs>lf}7a$g9`M6Ht`W($~ zFE9Sz%=mq!!2hk%@3#5;+bsHIrR3!WwjVA`c)Tg}?NY(x(`{efJNjm+)c3A}`Ui`alme^pynp0TTiUuoOiD{m;b2^=-EyGn2=czh8r0c$xbD{r&f&H0Oyo z6LaIAzyDr}9tl(b{paJq5JrP{_SNpVm&t} z@;WOcYhip@HU9&5ufJb^8!_8{y~X|D-=E)o%uHt2y3>CEjh@8B#NulH_}`BJMunBX z1(F$E>AHFy-rW`#J{rd6i@|W@g5-D;#iY;-i zvF+|IZi2PK%}oN*;`Os9R7`g%^2&;NJm)n(K?^s)2|6Yg7#l_tVr*516t?&AFKZBCe*;OhlzwcfDKlwqiK--ds69bPO zQ&-!+Y~S*kj8kv!{MkDH=+dWCLwf_+u0`Cxap%|FdpA@08A2Gp@&DuN@6lpVkY8O; cRK@mzUxdXnXuk5!H=wxiboFyt=akR{08)2jr2qf` diff --git a/src/qt/res/movies/spinner-010.png b/src/qt/res/movies/spinner-010.png index 437bf7c9dbd3c42888de8012a5ff8c03d0c8c4ee..a79c845fe828742ad38f8418179b6e2987a968ba 100644 GIT binary patch literal 2305 zcmV+c3I6tpP)+iLIS1q_p>cD;Yc^nrGbU^bqOxrlF`b$foDrMGWz9}U?(0U2OvZXNZ;iWB+G?2Vtm}md+fah?Y_dV}9@B6}G=lwo^9(aGx z_qqJ;5124v!h{JECQO(xVZww76DGPeBtRmFUc}R#L1ZzK6k?G6pGbxf#UKiJjS|+g zpGGcmf-3g0mwmj?dY&bn$gaJM0c23XRxZ=bPuShYEpB4R&K1636LT0tU&6W;O)K%t zU?;}}^u*&Q>iLZITgP>3SivxVJ;oL+ z3}qw#)kw2-)Ubr!Sp84=M6-ym`B^8Lx5xJ^AjrSWPz}t5zH}e*^y!h+SdDuU8b%=_|9_A=tv4s~YWHbAz=0DVMfg7r*{=oBe z?|h;Y6z=CunkZuyqv;8R5l%P9f5nnUJ{vftifR)}3F&O2nH&{P?grHqF_@?}a$>_2 z&m=Z+&I8qR{1#j15)I}bf{7hx1&K&1Y@tLq1~7|CniZ)Y*naxRuuv#86 zcu~8vTEQkK8%0&(9yYmH%boN$*fERZ6&bPe?JG>SJwsp?%6_hJIr1;zbXR z*&FmUJkhp*CZX)z+^diJNnxi4m(0#prW>B_2&Fo#bJgU?0;Gr z$z`GJwVE6gf=OnL$GyBW-X_-YJ^iCl@@e9^3ngzN*q57`&d0(kiRZD4dkm)fI2Q$Sk21_V$H7K4bNF6Ewyu~^ zgZK21Q0^n%c|WO?YD_*ilH=Z|Hd4jI^kr0C**T8Sr<0%nm# zWSg3^kS1^(Zc?sZW|A&6?cCx`9ZI?ZOkpoAT&JEY77^PsXuD$aYPhDm8AH9>Hy1l@p+vbL zzki$u)O|dLHx%;YD~TmdsHR$E{%142G56v)J$^-Lj@rv<-!!(^v0J)UKpby|eK67ReU_p+8#j=EMIe`6>(twf<9 zk#e5L31T5vgwv{Jl#fK?_*7=`DjCQULAZ9dEuj;@DBfwOuCB4%`E*%`WCAZy%(IMj zJKIHqT3HJtfGEm@b<+~=s`h?J73 z6)S8E8*Nirt9(1^;j z3;ObjYI|DAc&%-(-GnVucFvP-@SX-TUX`D8krMi9FLz1g$Ow4P@I4Kp(4(L9rGDkh z!7@em2BsNIRH8q-6ivzB8LnTI*2Y|!#ODdd8C(puFiy4y^b`w-()ap=%VvoV8D0#w zu}qMCZe|x*SoLoMdQhhFY-a}p4Q??Fq1?@sEO*M|>s)z$MK;mBmOci%go9nO83&AP z{;`qD5m~CM)JJ|kVv3_idWjMejWuh5EL3=mb$|@bN6G52+g72Lc#URim_~^4?EYVAZ~%h$Nq!h(Lz3il(;INEI1w zR4v##@(s)ona2XH@k0eqdHHxlB97njxm!J8G@S|yqdmT9I86~L1gkJQ7Q%Ug3SmB> z)Zoqt6)NLNzVqm2f50+EDo!FB{?m2c8oXygoMIL`%+v4gEtah2<``{w#wti!) z!Cl^7;1{gZ`FX5!x%pB21{M-{PKRW(sQqnrXY1VdiYbg4)cDv%DAy+PE|2)rOW-^1 zejM|4yRQ{YqX&MB7@lIc@I{3;57?h0Nn2-iM;zinQdvo@k1cj5d6%L7qh~$iZXTnE z?HuQ_!ectuCYo|yAQOu}-b-Z{u?K^hNHHHd+=3f43&Ohw&QZ-0eo36+Y10na-z;YF zG8=iDGPdy{2dJWy`Aj9BEW&hqrRYa@xF-WiCK9j_($$Ws2@@tvm@r|&gb5QSOqeiX bLI(c>Q@2~ekoFfu00000NkvXXu0mjfx5Z>p literal 913 zcmV;C18)3@P)NlQ;mIu{fY3;wto}=0R{pB07*6v=${cI z9~OpnRDE@3000050|AX=6D%VWV@DGHya$(U8wCUb000040|07G75=&yT16dFJre)8 z8E;o9000FC1ps99&5xvWGMs9UK7x0RjR62nY$lvzm#7d;kCdg<%`}r2zJ%2HLb~f_`@c z0|Nm80SgQcY;A5WDIfW!0+f=D0s{mB0s;gC2a;+X)|Vd6nm3%2f<;9|0|NpB1PFs= zEwGVP0000000eGdL}pt?1qB5Ex&r3AY5lMY`>PN4r3craG5`Pn|F#9WdGohBLVyacD*x#VKUKJ00000NkvXXu0mjf>^oa` diff --git a/src/qt/res/movies/spinner-011.png b/src/qt/res/movies/spinner-011.png index 3f5dda7d37139fd30d55500329f5cf75ac40cda0..57baf66895fd37dc05524402200845b504d9646d 100644 GIT binary patch literal 2338 zcmV+-3ElRIP)yEdbvZgUh&Q~4c}YaYfKWK|fg|BL?>=YmefH+k+W+^PTlTa6 z`+45yeQx`J2@@tvm@r|&gb5QSOqeiX;zxiEfR*laV<_=-B9>?@bf)u54Eu_xj)sDv8!}kc`%)8I7Nt>Ao%dz*neb7ay^h1#Dq6YbnKngWHPet|7WL!a6@< znMWB@+_ah`@VXUz#vI1en-~J|!v+KqfkZE6Q%nh8^Su|MSIBAE_imP*zO^ET}QCaGLzU$jjX(4exkoFBYBa1 zRC~!chU)Aj?8NaGS*kVU=x4rGtUSnUN);XN`35+C8!yNvdPnJ}&#Uz#k!31^xiTIx zVAFJGwTJD}$ycKZWH3v(tTIenh}{4u=+6oni@HRbcAZ)X;3+n6K||nOMuH)3KZZ>* zwWiH<)ppAOlG(~ljTy#m=DNkb`s~#Hd?h1urj}P5#)4*no0hek`wTkA(`EecZX(pb zw`|4LI{B4tP`NUcbwYX98HH8dtsbUWhXnZxgUTL$q{#Se#)&oP0#YNo3*-Vt1refTX{45iiTcQh%bOAw;`zLLlv9{hG+B z91;k4pHMc)v=JUQglGuw38bB*k6r@Caa|A`tVSZ0D?+NTs}0Ru;7?EPXNXIr<;NO< ztO~tes~=Aa$vh2&vQ>C(FEKty?9DR%$7K$(k!-@7@=l3o1-_z|EWHxMTtOARfxbvs z$Pj4TK@~|Fh5Iq!E{|}DxlJK~h4I`HNSmNn;Q3oYaqKK30SMw#p*hXa>~KDCyVvNZ ztCIwN_Xf}FwMU;7P`S$E&bR!GAX%?wfX0&Ca6wf4Y13Z)h43_=r5DlHgtw1z8fUay zidWAO%@wOmVM;N@d3~}lxp>S+*Vp6%UKhkbCmGt5v`^&5UDu8?U9+s^Lg!XQC;-n0 z3ZNB?*DG(BB@lhhX}XOV%Rih>sg|?+iV)32#qOqYpIS%}))~_EGTj`3*S*c;W_~q* z;ml(pZ<9xYPlog}Vf5qR9qz%#eBreuz4C@Z!Xsq4Tb2?+5cs%XY%CL2a;r$j#%{rt zavsu)Xk4>?X!BOP-mRrZ4C0(nZ>xEL5@DT$1Sq)Cx>`akIY-XEf_5rHZ3`#BAhuXa26`9)n zRD=30QMwE`Kc{{!^a+`c)*fOE8CpUlL314YCdpi?_bRZVJ_vWPhBzQ1%kuLvsujpdG>2IzF8!d`qe`nPz(`nBX|AvV%wDm%@c({T!UfjH-1G`9)xCxCF$Ddd!kd-6

^US$A789@*3C5Z$wd5L%UN>KiAP(`W>84F{0 zneGOqgbMcRuT_QJ=Q&L^M>t5Guq58Rav`}GxK&5@rip4Y+jalC(80FW{<=_vNZu08 zbosKj`!pJ05F`SbA*`WmUAOpumeBS#%_U zSrkz&o632w^8A;1?d8`~dN7l{8a{Ep#1>`}*Oq^KL4;wf;~3>sDxh1%J{B-o^FTnW z!%i~uS<5HRom=C~JQ}-T4o+~2t>lwNWZV5=3FQc)A5ZZlxx7IxOW4YCR`3$Z3?rCu z13vX?Ral(yu?6TtM=)eg+k^=dCQO(xVZww76DCZUFwr{rKhru}d&<;+bN~PV07*qo IM6N<$g1&Ka82|tP literal 934 zcmV;X16lluP)EF$8a&!Oy0Iz%*k!BVH0suNJ5Y&_x4Gj%9 zFe8C@Wgj3R1_S~D0Re7K5f>B>O*s<&w-|U_Ce@rWgPJ`Tw^A z|EmJinJWMP`~R^5`_h5`vj+XL59_Zy|GF6Lsx1G(1KOiF|FsFkmOk69RQTGT;jc~X z&6EG{&hxAz)SNHwxKRK9|669R+yDRogmh9)Qvd-30a({90tzO@+86-?1$o>1`>_HI zy#D_BQVs)|_WS;^Gr<=DCHvVxr~8Zt*S!K?^f6qcGXnyXICTEB1q1`}wIb@caG#$`%3vhWh#1feQfx2ffuL z6vkx%1mW<7eEAc?D2O z)k8H-9jp0;+Oqw}fDV0`ZG0qO1Q9~gWY8XkFldmlv)f-*KfF*)_| z`87Q=s{%5|{P)7o;?nX8s{p8L>l?qDTMDLw%J$AKd;0?X0d$EqEeB~`-~a#s07*qo IM6N<$f`hJMLjV8( diff --git a/src/qt/res/movies/spinner-012.png b/src/qt/res/movies/spinner-012.png index c15aefdf9f368db400ffffa55d2331d73b03621f..9deae7853a77be114675325338015003f0df20d4 100644 GIT binary patch literal 2352 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 diff --git a/src/qt/res/movies/spinner-013.png b/src/qt/res/movies/spinner-013.png index 810712dde0fab66446b77db4d1670f1c7ec17eb8..0659d48decf354c0e224c2903526b64bf1757eec 100644 GIT binary patch literal 2377 zcmV-P3AXl$P)=bRi$Z95iK3v>K?$i4EaHPf zrBi7wBBP^ykoZCwL?Be5rBM_NF}x8I5=bD)Cfh$;x7pp_-Q3NdiE z2O0Hz$!koZ9Z{DCB`aXZi32NkqPdc;Br}*%jAa%}DP(>C(P*{@CHehu;iibiTz7HF z+OPpmVzA>NnocCsiwv^K<$j)I4S(Pr_EAa&=cx03u?@ueN%|SbbP@e-R8vVlw-9qN zNXF2KevBuN+2r#In<%D~uQ@^ujWp04p}T)2Z$ zlE*%}`ADnHJ6&b3L>S@!TNqi9Ajjq)&Px;ac* zzzW&fMp-UuSYy=g+z=K`Hy0QdAax|QVMzQiz`Q9yUp^0$XaiXRQtf20iwc^l_e@43 zE-vVnSVVW#M7yy!Y@)v)B0#Q{7&6J>m*g>-$xLAa53!1Wa6pGeIKu|6S4*@D?}bU! z%{(GCq+4+U79u=#+hp%Mk{i?`Ze~%NBx_<`X{2>>`SMz zBj_~GP`gv(No5jua}QYzpf|~MBnl@fyrF~Wd$bEfcO0wPulY^4GgN)(6^Yd+3lPOz zT}$_4I)|x!E{AB+ke(mbH0nYcjk<__N=n$eW@@^P%}h6zW;{D|8l$6Jr$FCCO`;!= zVPwc%z&ARH)-XtcMhBTxYiRf_4x@;U;-e5k=g~@Z#xkAL8vgVhM!EX)G)SEj_H83M ziq5-U8poN7M~wNVS5cv1cGlq%{(Y9hGyRmPxt#v$XtC%2Lx2%oH`$ zFkXH7JCb#x_4_wBFn|-Hx2w)oOVzLrTj{Er=x`cDRkN^=%pu{)dLdA2yS=}i8gcQa zsm<=k^0XMw6cGhH``z8W#|3piDtpK)vxL*WHDfKKcZp1w^dg+%Sl5%Y-K zlxpENap9cdCXb;i7M^~>)k-(d2+>(N%n+6N`my4|UF8kM{vy7D(h!+wUKF%6GD+pq zT_vcfQ+@s31&lcj%dL}CLW%V8~*`B(M@03r_ ztO|tae2oxFK}}4%=p90KMvLjP`?0E7Fk=Mq_00YOx`MKW^SYjURZV%8U;>)B*T5uP z1aUY5Uf;qPA=B$(k}9INi&l4`Ata+nWdX0ViB)9#bwb#=Loh~-%v7a(j1V_8^MV0O zH=dD{doxgFJVUC_^M{2AuVa!bJKvMf1O+>|Liv)t*3Zd1&7u~?DjWHtTR&XY3nYkL zUtjtyEEOkqV7Pa@MW!#7t-^ckRTmCM@T{2s8>;w#=_8~|&NJDYERiRC7wy$$0Ox3w z@6{qj%p9-u+Jcc{iFmcjtdU%WR^9z`z1ZEf-s28Lvq-f5kE%2hH;AuLC3F*ogI;3s zccZ5k>J)eA8M0Jb|2T1X)H7S@E^SAN*g$zD08_=xa+Q+uq!%%)5qIf-T4Wi*heK@p zDJ2nzr%?Ua)GK;R(D4O*v68}3vHCJwwa=2sJK{IpqVP1eiP^-% z3;^C0wU;S(TCkHV_U)ZyMw=UL0*O8$XgJRx=7?6mi3f}b6>k(PEN=GGQyEdIeYuuG zjh4L%#u*b=EYYZV7n7*y7|Rnf2+e$^(Xdx!R79Mm(M?dn6eY{o$~e&_kek#`@)M(o zI(bgxn|?)xg1n7|;Z*8u25Dru;v$yM9!lo}4aHTYE6{MWc!;>gAaOK?;$cnIRbiV3 z3n?7bd8J^9(dnrO4Ijyki~URtQ+fxTz2Dmcatc<}L@f-{Y?Eu`6CMo9K*a01*mag< z+T$dej`ZLf(ip)ohLE7_MEBsaATM#8SLqOjxhv8^bPEM6=Os4tAv-Cjk}7Jcqlkyp z-h8t1e2~{@qKvdQrmO7yQRhWHc^qLS$tsEdi06Y|!D?a|cM}z|gJ$FRVfON$Vw~Di z$zWb?<$^&OACpOcY#zlH9fl*4Wtz>%ddIt}9sQxaDWsGAD_uKyixo^|3@K!g!9a#_ zGuLV?Fe`aM7N)*Ys{V%JAhzr3$9Cc7G$%Ml1>f=wCpk+Auh1pHo3b)N@ODERpVCGB zsoGoYZqR>KFEv2oPs6;1;^v>~(x1L3-&Tz-K|N!qU+2Arp<)ANC}X^Fb=!Onwvp^9 zhWQ*s7J7;el={aC<6M1!95(BYJAB9Een-&N8sUBL(M&V-lv2PIMptcb}XM-|8T zihr?4-E(b0RRXI3o|JbN;niNA`mYn5|3pP0|Ed6000001#M3h+L#d1mLm)d z4FUlG000D)X%y_D67r%6(U~vey>>}NIROCy0|NpC0{~P$6r6D#RzxCwVJqLBAkLyr z-^G%MhlT_M1ONdByo4BIOCJCL1$kvYxVgMMJ3AN_5)BOur-MHL00jdA0X#M=YGqqX zOidpkAPWZok8CFZ0RjO501yuiXk0}F1Opou4ICB=0s{lp!=p+@J_7>-1q1>D0RTQP z5&yRhHYpJU0|S$hjY2{~5D*YLE)-x%7*9MF0|NvG1OS$66)z+@qa**e1p257 z|Nry#t{D5(jP~Zp@a^W%nlszBZ|9&G|F{VMtqK3V1pl`S>Z~-^r%U0nR_3~7@X3DQ zq%zQ*I^@ip_~yg*=E>l?asU7SoJ?XW0001hbW%=J009F?BLX8?aZO#f0s#w{_53OV z3BUaQ`u%PK1OtD~h{F5&`=ta7<(~(*%3nb%;Rpm^hGa7y)CmDBl?FFD5c_BX2LWaN zS_8aTFJp~&3j@AbGFZO-<#PV^A_HCg`up0Dzy7BK13&%!{{GJ#0s#u+`Kc0uZ#`&R zDG@{hG%>{l0002uNkl!{+e0r$eS;7qo=^g+2@KZ{g{HM zIEU!GH3+}?P_0QS^_5Z+-lupSiL6>rlC_&!@*nLgJU)Iwo$&ww002ovPDHLkV1o0Q BTXO&a diff --git a/src/qt/res/movies/spinner-014.png b/src/qt/res/movies/spinner-014.png index 0adba834055bc8fe3747f22ae0dd1e628c94d353..bc1ef51bdedb23b098fd79db1b5f47bd2b3ff97b 100644 GIT binary patch literal 2358 zcmV-63CZ?}P)kcSBJN}wPQDQZDUh)iv1ks>4&Ct*y*v7u;4CB-Q+il96k z3Xaw~gTxUbq+uMiv?PI6sER?GmhcExvAjuzkOcDTAIV^{`@6}#yJv4SbAR{GyL*1; zd(Q9t-sgf%HrZs8O*YwNlT9|+WRp$bQF7qu>Ja1U!4xJkl)>~Sif~*&I2uku0MNPu z%!%Z3nA22ono}I7hyu3r5>JvvDpMHGD05LprG*P&4eH&ngvw}uln0ikG)znbQ3I0tfxBHB$ z;p9o)pp?DrWDTh#Gm`GOI}h|kE|`Yd_BqQW9}$kDq}B2@Qb#rA6tk0gjM9~WAdtUr z{q*#bl4XYfnTy*h+wI|%0D2J2=P*PIAuRzC7)7$~2anUaq%E zwn~IUh(N=Ii&*+HfZO>Mdpn$9Ba3{*P9u`FoHPZrkwWh43`asEf*eEQJYQ#o6qd1- zGQQ%HA*i(!@q^9)nrmo!*GSPZ{2ERo>B|U`_$8|-;(7-QS4}CmSq*fhL6JLWXcru4 z+{|=dpn}SF1^5Wxvks(--|}CBK+lk1O6?6KgMYO<;$N(bXEONIuo9`@R@2MapTc&W z#42*FaSD6!H&YH^Uq86?VJ^pX$2`nTEA}(blv#L>Zhr9zWiV%T72Fmf##L-fAEZK8 z{Y!C9f#0FDMj~HuT}Q<|;pYMxq-fsP4aQc9`f_tXVRSO3I#3TYxg{+Z6tP{a1M@3Z zFi+IPzY8$Tn#~~{o^J%p(GOu9AL}rEi%62WBD~2CnD0_9>Kv7s!P2+C*MXT&C=TXO zC%j7!I3c3(Cmo<0f^kkYZehR3@E?rEfrBi;fve`n3QkhIj(bwZEy2huE!5f17l~-e z8~CP0FEdpE=TN5Vq+D01hZ)9Zk=0(JS_FHYnA01pgnJw>h}`!vN_~F!oS3ssYY|N+ zZwl{^GfWZxheW6FGWV;^0*8}9t?1xIw`*ZPq`#sWL~u~t)7@&bgf~$lFsUQ^hAj){ z9dRL4>BSI!B)Sd<8LCp_dMFnKH?dWKl`q=YC}p!q6cabKOi-tJolF(oyF$9RTJiZl zzU~!%uC!>hUd%dVsubQu;`zvEIm{4}g|?A89#h5OF2Vh4WQjGUyfy|VNf6xz($vgE;|{T5V`V4wkv$+Rc^#Q* zMAyM+{wDxkYI&=Sle@&3JfUjI?-4zcY|HmkBS~!SdKkBw;U|cxjJ2HrG*tlFz+^`Er{tj(1wTFBiF@;2u_&82g4E(y69BswAZ{R@||TEfLZTod(N45UC!hOQ#^)V5((G zkA5hmYnoUCz-<(YxuT1~X>N6srPH4HnNN?kdC{FN24Fcji6BjE8fc=F0l|qLhH+YC zc$G~78<$@QXRw|HxR|Be?(<-LTqDZH;wJNx6%5LUzRAgMw8D<3lbc1LmD|C7nYFHfXu>WRW)aj^g zDXz_|g*P*!%lIqvViQqj`SNvvMle+po?VPKy|3Z? z-7w6n{90Kk(IIVUw;lWp3r)7gcqlUnvy%17I$aFWzIJbwUg9{o;pUT6!!A~m&YcXQH(_FCuh}meqvMKrKZh7%c{Z5=yek$6e2v6e zPEf?_EN6n~glkMSG}56~%^{Z3Sn^C=r)#2uJX}7atdVA5oJy83iIEJ#LoBYA>a0Z- zy@|YL`j%Oq&*U6r8oCp8jWe91oD%*_J}>hukCQ~SH3jJjJZ~E60w2FL~NKVz`R3uq`?0=#uxpuU||KcdVu zeDNpGs})icQ=Mj>dS(Rg&V(n+a literal 901 zcmV;01A6?4P)5dt6c-c>000PTP7+Qz5ds1L0s#O300nGL6XBf700s;U40n)*rR!~L-0{{mG0|WyAk!>dt4F&)J0I8>=9UdSA1Oo*H z1O^2J9vKiF7776Y0WvZ&C?XbLNECWm7lmLKby*lKBM$-s0SE;Fe_9k15)K0a0I+-* zPCFGYB^C9m3)GSk0|W>H0tmZ?9`>gV?4JwvqyXKQ6GAp0D=3J0spfH-#|1lz+C(4#`)yE_u;kw|NqgkHxK{-0D*K;PE!B@11f8Tbv6x^a{>Vf zmiXc30tB!9{P!XP1ZJ^RWb6C+`~Eot0s+K>LMa0a@!A0bE|aRJj!#qw4f=Ql2LjY3 z0@N!51_eGj0Z~terLdq%1P7@!0or|7{PGqL<@@;h`G!=F_mTqx)cgF@5CH?T*b*%(AlnJhlaf{|n} z5}Uia*f<-m$V66y$cRN@GF>sqVpC!kll;9W34ckFB#A_k7Qj#GTa-{mqt^KSBCS-> zsM+PCUB`Q8#U8+Gw;q;`U(&k>htGY|51(y-2N?$UNs>{wGR{qsOkn!*+T_&~z{Ski z-8r*ob0fGt%{)#h761%2kCrJ`D0>`4lLJ}Zuaut*@W{^Om8@;Ad+UO&Y}6x3k|fDy bQBVE>gO@YqRt<~n00000NkvXXu0mjfE2~DR diff --git a/src/qt/res/movies/spinner-015.png b/src/qt/res/movies/spinner-015.png index b7e25b395adf4913f4189f3eff6f3dcecdf02ed6..24b57b62c2cd8ca0a3c4b0f261daef7c6d4f6de2 100644 GIT binary patch literal 2405 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 Hu0mjfk5^ZT diff --git a/src/qt/res/movies/spinner-016.png b/src/qt/res/movies/spinner-016.png index d2fdb2deb522600950280fcc53f2c2656b518ff9..d622872651aa8276442fd6edf5460ed5d0c7ea56 100644 GIT binary patch literal 2429 zcmV-@34->CP)@B6^>J}(dBe*WZe&ig&* zKKHrr?|q*GJ<=mR(j(nQ!ifT$-5H|BP^R+$t60uB;s`_Qo<=`CO-i6G z-!cBg1R@BrH_&*V@B&mv=LBV3Pc%+D+vEAv`v6tvH2g?jTq}vnh5SFpe0MxTovy|@HZU=;`&A=@rwy;Aj?NYay7e}hFO=;Ym`zOJoQp)(aIyn1 znQdH6wJ@EUjXAMtP1q$zsMW~*0is3gZam?0E-gn5$3$smu<#J}FB zwi z#ev2+j*2ao`@r*F#4M^j_*q}_ODi0N2bA+&#gubq#=&Z_MJ+$@@ife2xkB}IbZQvw zUt&CnEDkCL|Cj=Lom=(G6s^|K+kk8NGma~vzAhe7rbz_L6$2mU$E}BklNAc;WSqfi zokEooYLP!#;%gLhe3E;KY~96|E27f1t!;d#Q%6�Qxdn{&V>@DY=5^*7XeI4$+X* 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 AzyJUM diff --git a/src/qt/res/movies/spinner-018.png b/src/qt/res/movies/spinner-018.png index db306aa4e8db2b58d633dced83c654c4be1e12c6..a2c8f38b1d82090ac38a2a06066b6e1301c74aba 100644 GIT binary patch literal 1831 zcmV+?2iW+DP)3$g6o9{(>Bdf5Hq!(*KsG~yxRfnH5DA0`N}`yUDy>pt!Vl393|2r4E;L3``lFR4 zPy~Vr224d`i7bIYRE%hC1(9Ic7p0U!w;6v7NSAZpZ1>%ndCYl#=e_g3`_8@hYs82Axx&=|s>G|9?$Kqq>;i z0n?GFZi+=v$Dz6?P=NZV^zUoMRv;3-~5~vB( z1Zo1+G-{P4>Z9@PG~AA3vdHFRZd#yL#Ve|Z`^cw=a;m7ui>BDdLHej=E=jS7If&hw3^t}Q$67je4#7<31Rk^SV+2luTzGWa|U zOb_GO&ROa?%v*Ff4?2;HmS6Hu^61p+_u*o`)2gJ=!X5^i#T-ht1?Io3}*1r}>y zDmx><^lvh6D17P$p0fiqi|dLCXHU!f26M30HgSeIAT%nS+3=2zlH^E2pd%tt^Z!FtHRR`%D)ZPAGKzG>s$51Eg->Exz>&j)(NtkZP zzfPh=1iebSUPVufj>2J*jfD~qa87hoX6jW_B#!61217#^OU1!nqt|ebiyMpC((MRw z?XA(dn+_A>h!X}4*FW5Uh{mhYLz*rcZn5zM&MNUe^7XB}bH$OIZX9&7I7^r4Q?OJV z$$`c}GsG#R(XvX!FWS{Os7vgC_(Gq8uf(l78VThZ;Z64Hd;E`LRXQ4SM2v>DiIi9P zJ}RK!3U6}B&Y9t5dsINb6xQ7v`X-T-&ZvkA=zif%PU(C6QQ`4NqXK$Dc#}i=9$z6m z{#+C=U1C(KaT0A2V^NQB&~(u=(&#X(64My{jDrppK^N;&uvl~fXBh{bErRCin;E$x z=z8OzW#W5G(YL(}7en6DhEIcb5|b&-+^;j_trAs?H46Hq7`q(NyC{Al8qMkm5}2Wj zTw8lzuab%4Xx17$htx^5suo7;R&zld&m9rY)8H*4&;Hbyf92hzDD*rV!Qc&N68(cp zv1KUwVAkq4of(R5+@IRD+5`*vI%o0Xqlp6n&CkU`aq4&@7-prUim{+SmC+-_XJxXb zP0Po{06hs=oE9}-BEyd5V638W*i2EIF0o)RTRI#VP&Z1YP$+stUY6UF&PisS;+x)N zQP9ckOtJOROOE2DUA&~|Iy@EDqzOs}DNjJukrM%?4*WnK)(&tmf>bDOs>B?DSjd@il=MEJUVYgR=8790=H?N8t%?0Hb%?!|F zp5N|H7vn8Xnl?~is`oyHd6646&C!jT~hwo)0e@g|0)}q$?ZRxrFCFi?&xEK8}UisT83BPo|zP`Mu?fpc#0Gr zZEN3lGEow%Mk#B|I`T;dx|7X^9JgpkzjG+zHKQ4ghoeVEj`BQd#Jq%$+CmK_Ofl)Sn@06=iq%XCDVrEKsEu6YFq>JfbFu&c literal 892 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 literal 925 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47~co@gt!8^%*;&8Obm>SK*R{- zD#{2t8w*?M2=MXpfcOjyOpJ{FUd{(sls}or(-bGn!pZ>@XJuiEi;F*gVDsdbjI3z8 z!YJMS9kOdG#h6(*n7~Hy^Yd$JYOu3&cBLu&S;d|gD8a%6w3Rg@Kc7ZsXZYV&O=$Aok#pc`4385Cs2Jgk+L)*8H7 zDk~|*Usn)zafA@}b!+=annJlq_7e7xb_CKncYzE~*v zYboRWA}LW(@rTzB-#^fNd9LZ3`5b5a#egQCIk@KRWTna&Nk3~5pkG;8mQyswzqY<$Zm9?`(*gS)#+q$t5H# z>hB-G#KHm8#l!^kEyLu#)@?0H1wj&lHX;dbLX&bN^FmdazyVa89esLf+{}ClA$|^^ zHDV${4yJMu&eB14!V;qVkQjNi!SBx|mH%6~{%>UYzn$^_Hm0|$G(Ig8{&*na$7=5H z7h3)wVEDg{;mOXl|Np<-U*mIsp6r>qj{pDv`uG0g_gf3@EHQt*QtSUNvH$xx{%;ce z|NlRqYP&qpSzRSTe!&btS2A+BXUAzVF*4`B|FuGrk)`?h_F1c6UlnC!(u+{q|93vK z(3~Ilm6=&tx!?c&p~z%-@$VrfCabC^|LnK^`u97$tLS-2MtderYV|y_V9HU2Ns}fe zB~6$zX-3Z}hm_483-2w^Ih8U&vU@&bVV_FpewCFUW_wIJHDBw8*V%NH*6&fL*L({5 zuI2jG+csju$<=MoO{%;u9eHyuxqA!KyW5R^kJ*#kr+7=)?z&`LbmqfJ*I#XZ2N}N1 zpPwr5OD`qly{b%4`TdgJW{p9W^_yZAy}mZ@<=vTm*4rkZ*=V|c#-g*#H-5y$O+GbW wbk@fc$EsD1x`!od9(7mp{P=Ua%4@O7f0(rA1Ne+$k?p00i_>zopr05Miv@c;k- diff --git a/src/qt/res/movies/spinner-021.png b/src/qt/res/movies/spinner-021.png index 7dcc2f672ae7a1b63e81a6c3036239d7074f87b4..9cea8f25433a8284bd1e90110ef18a4f952b40cc 100644 GIT binary patch literal 2368 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 literal 894 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47#{@qgt!8^K)?t@Ai%)P1VmsK z0|PTF2M-SqGb=YYpGa$K>#6;#_AV}L%QUbxkYHe7)lgMf)D^X{-Qx5l9PRSH!WaeOE0-DL7swDS%k;sN>AyYl&tJ9TQ<3u1<(bFeb9va)t{b^m&P==3bB z-AzDmvI9dSA=L5CEE!t^@y4ds|G!_JTORvn0q?if%yxRb;GklujMwi-5>u20hA>l5 zP;i=;C@}DRtfdcj2sfvyOG%0w8yQ)d8>%XZ^73#qFmUkj@=6GE3GuN3oyQCUK$`L4 zI-lQbC9bZHxjkR&|2BsIyO@5hWP7?f_~*;hzcz6H+s1Hjt>29;`Tw^teY(5##&XZk zS7tn2DD!o-$p1AAFE+URS}*f|1K0om|DT?ma&w;UtCc+8R|(voCo`)ke-ki*n@fWH zf`Rb?w1|a~U0hvCVcoko`*K(vFTDN!saGlS*ghdfM!Ub4(|>GYVp{d@=f7L*%&h%? zog`lV{d-gQ&%ge_zh6&ES(yD*qA$i zWzYHh{98kqb#63WIdgN~{eK==Q_D`3zPc~Xpnq14Z~oGw zKLnqiU&70O$*?Bv#UH!559uFFIkgM$J>jaPMpt?KOX&$zN=@3bU(R RJsFgZJYD@<);T3K0RW87O_2Zq diff --git a/src/qt/res/movies/spinner-024.png b/src/qt/res/movies/spinner-024.png index d29feb4c561d5f9387764068328161b53f33e4d9..c5dcf1eae90f61ddac48d4f9dd432e820aecc0be 100644 GIT binary patch literal 2315 zcmV+m3H0`fP)CSi4ZumBb-nrM0e< z<-AOsS_cwS+peUVl-OD;#ZrS9V^LBZA_58qCmi7QgM{(i`|jhOM+>?C{q4Q`&N=&@ zbN2q9z4v)w!GZ+~7A#n>V8Ma~3l=PVHJ|`$dsQp|JNI%QeHcn#MlzT&45kkq2*TAK zl(f-vBz&hKAWg=<(jM0R)j$s?iDcszapynN^Vh0mF481$a9N-FW z+?4V@5BXZja5ivBnu_&ujb+3TsM+siK5z8=JH+}<$p9v?mvSGdd1n!yWdfar{&@hO zG}DeC`d5kLs^FO%;eIy7Vqc?5cUU#tW<62# ztW{4NPVQ$Mt2pJ+IjyNv)y{n3N?0b`%_f-aN)PPjIO~bPVVJL|1k#rzvUS@nV^!_* zE_MjMze2nhjLHBeaawaQw5U(W!j1Ex4!LLnUf0=6>!lcj2xjTL%H8zhHQ_fY^5}wt1d25V zaFXvxqt*T_Y{q-)C7mOJPcQL=yxF{4(|4X@E?p$9n?MpM)#&TG@Y4c%%bU-s8XoT! zDW*?^N|V5uld*>U>z9)0(UEx(JIE7uQOa!7QGvlsU_Pl#A(nfv)hfKa$@xUjZ_mI_ zmZEWdA?#!?Jx#S6#5i_y9yirgQ$h~w_&yI4NC?03Kuqd=>^Eeo>12hli!+SEX{zNR z0-|t})BKes{G5D4issWzmZJSRDeNM{BpV50r_O?`s*NDHJ<>yIVe#jL)~=9flZpQ9vQ-$OvGcu=b1fpBLPQJSdj;_lOq}@{&6efERVE0n-vPo* zx7~^3rWH-2gRB`{ENH%(MN-;M*5Eoul6|XF?dt^Q_~jOJzD=8SHB)lGr? zSgxIp3}PVP!sbQb%N(8PLL}o!<3lbs**ag!c6rCMrZe06Q0T@(Oe2FsTyC_3YnUeQ zc=rDT7d?55Ic%bU>(t<;oEX|Mf`}lVSJ=(p=}NnYjjnWTtMx4ZLnzp>)rPLxHC)Uj zow0PoiM>6m+nImirh=pVmIcJp34807yR_EA9ZgA{*Sbv!Ijm(SQ3POXPYOGkCt#da zoFEGLg-I!YNwxF9ich1caR+(hHaArR@$ z4}`7H!(W!7)466c;+iGFJ_eB~%n~e;W%Lw{{F!$$-1ImG3N3#Hqhy_20@!a_&8y5X z{kmrfqelB=MduYp7|u8A$w-sgwotN!?WW3dFLshN!conO8nxx0+;8%5{R|fb?VgpE zB|u?=p&2{EHvY^hjhB#OYCaVP^RckycjYbI;3ix|OHPnV0MSfkBRP#qW(r9o%#>wx zus|cKn<9(aE5uV~ILY%QDtV>%Oq8r0>SBRmb5lbR z!F3(0*a^iYfpkYSNrKdK>SgkHuFBh9+159SmV8=yLRbjr#?5I)$}>d0g?Z@H{97k^ zH%t~K!%jF`GV7SbS9kYk7*!s0Ie+ z!k=OMo=V{rk9zq;_BA_&H#F`ODRt+X$0+fbc)!km(ut!BE>!$b8w5rbz(D{Vc$Vop z)qwS-K6`jjc0$Q6bkwDdXta$4_8Ic9B^+ZHYe^!GM+xUqhVUehkjN6&ah_sBg{mby zCqJ{@OSmu()1%3ABlyV6vuQD(bBSWEbAf6vq8ItZ_#%X=3h#YwXy!Ov^kR?6sxQw{ z$#&x9-cYKK(aaUxL5LUbkYQ57E!sP?fDFFwyBx=`X7`D9YTjsZutbN)n7jU*PmYq%A8WWMUC}?vtnt%EG_SIoqrAm@qC7qwNSpyDVYHt5B8N$A zt%RWpgb+xu;b2G*bJ*iWu13qkzQgl!Zw<=d+bW$I&pJMCVV!0!OG%V{+0}O|!AW-} zkV%1uD!ztyvyXF-X*}Has)qas;sGY{D!bUnDaz_Xr`5H8OmPD@mFy#n*^DL{wJlc+ zsRZHVF773c$t+?8zhohcNM;^W_#uP%S}T=Lw%YCm2X>sOIIv->H8$Hhf`zXb{tJS0Tjf$VziR*h002ovPDHLkV1k1fWy$~m literal 953 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>2_mLR^7dMj!xEAR0(AF)%PQ zF)}bQF#-`YGb1w-0}C@qh?$w0g&8OY5&@}WVze>SnOqalkgQV{sbHfgA}k`>-rl}` z>BOuUCmBgmW@e@UcT<0BVJRu;mYUq$Kp6%GRwgEpHJsf12d26_oGbZ$0mr|MOd)n6 zn(9hNrrHz+i2-%BG}S$u&Gma3laabGP%#HPi*&5Q666Y zgYzO^E>{n+m*QY!;^pIiaP#!-?S;?h@_${ye{qsH7bjo+WF z-_T}$Z6<$bqA1Xj{JiWeEKCecY>dpDK#ibS03sHampdXJEYkSBM&$oC-WSJOt}n9w zzm5O>na+P}xxTMpfA{Fj^F`ACH#7WvaqQnNhSReh-kfava47TqG>!jTSiY`P{lAs# z=Ni8M|Npmb%DvdQ4|b+J`?&FVdQ&MBb@0HcsqlK=n! diff --git a/src/qt/res/movies/spinner-025.png b/src/qt/res/movies/spinner-025.png index b399a262104c5b9c8fd5b565c15916c0f34e73ff..7f3577a4de2c60562ff6d70faef45382588038cc 100644 GIT binary patch literal 2298 zcmV4bbO8d>TzcF9GvSFRz`URmc^8zB5YGPKKyuFSch2ve=izYJ>-Ty7Jm);W-{<*0 z&-eZu(4j+z4jnpl=+L1JSE|Ryh zfpau)nKp+cyN=WBW+t~1*c<2$;@529q6_qF$5Bd{PL%gj^d*6Z*~k&D3eapHO>E{4 zf-rj@O%r1&qE?vVcjGLDq^Oe&ry@n)}dHhLX0WYzcH^`JH zdm~AdJK3&9jMKcfMojc0g~gn5IBPv?2~?b6EG0B_x*J;=CP%J)S?<99spV+~xM`}= zc$4!E$=*+}-R>Gjh0V8CT6dBV{F&n5OdVqm1Kie-Ci?M9wmKmCFaT%>P-#W!i zaiXytQ1wwaa-*;VVq_q%P_KISs~FVf7l|BF_};TBn_M$|__N*mb&U0l#7Bx22<1r! z=XDuFuUnYkD}HAsA!4sEihYU`U!%xorN!hL%)OjYAzH(%>m1N3MP*nh`U=Zb9$vvu zBxipNWK*f4)5{38W~1gQ8l@&CioA`HdsGr5CrRrD*E@h|D#zpsIRM^ zeHWtLg)+4NESt@Hl|^>Gr+fN*rOJ!fQA{R}YtAj!k}QMh0J1xy1Pd14BvMM`AIiH9 zUjA!7(-@#z_?s+iZXknoyvtF_nIg@04&^^m@=K>lmYw+v#U#~5sFXtV@1pv)`>{Yn zI>p(zK!!JF_q!s74}^(s@qT#%+{9*~eE(JPRJXw+IaMEGc$lrK(XO-cZ)-#&Kr@!f zR)?(n5zREVbunSu#uc(f4U3r~PEyPy!aXF}LHvUCoOOxl#|#z|g@N0xk^Xr~_znF$ zLe@+$6IsI<%|vI5Dk5KAxNf=z%E=}cUyp3$zWkU%KG#5Vzj%#2(XLw7$R6?->5;Y> z6J|#96x9w@R4acJ-Df8LLW^Q5>{Awy;33JHNnjr3swInR62*ub7{Ni+b!?%UrA&}r z)=_>f1xa>^bF)56aQ)-s+x9x^^LWKqHe8%O?!qC{iaqe@tA7586p0!cN?8|IbQ3?4v3d!b+ZbDU zi%3#g&X)=ufh{bN;yQ%$j@``v6ql)qd>7gnFOrRc0Frr{{WhQNW0aJQ`=Ej&dX4_# z^87@R(jL{ybB7*G;15)A9t%x;!77raRKagh>^iDvvZzZnhi?^&_c=VTBGm^v8(qvq zkU=In+$XIDK1Wes)R8VWZGZMElG#Nxkt)9Lejc>R;>ojh$tpFO8Y0Bb=WLb0YzBV7 zi;7g+sF9`cZ4gYMioVDfI~Ea?DNei7+Nm{8wWsrClB82L^D7n8RmB*Qry01}CP~qu z;hwOrpD#}+o?r`Cctf-xVCS7pQ%zwn6g?cjQ>1a2#Lo3gc2M*B7dJ|is)6yU71N!f zjmJi&DNg*%bv3F0?oyFyd%w|rlEUe+Y*7vWri;5;DGI*pVQ#Tm>!l7N)l*~=E@(d^ z_!H+;pHLzrppUg%$E(b@I}h=y9VG3J{#quvZDM?gW08Z3OB0jDn%};QTe`-f?(^&0xZ-XgZAGD`v6%X^vw zx)xe#;B#u&O%=_YaB}zCzQ4N%FS{EU!8VsK;kiCaN$aM@XBQC1t16MIoNBhHI?7pyF2<@LcQr98j@He^@ex**ui-3OL_Z~##+UCw0l?Cx0A~d@9gX|5W-YG z(%e~VQMo8|j&hzN#kzbm-8bLx&C>I&|pJp+kob9lag@1ATs5 Ua{-yDwg3PC07*qoM6N<$f;Yfb9RL6T literal 939 zcmV;c162HpP)=pQ9Ty}0s#U70ssI3uBxKmqcQ%c0R6H6nQa&V00IaG11KaN=cOj= zp$-!f3@t4$-nC}5hcVoi4l*be1q1^H1Ofm61Fd@;V@MHTURm|qsVpWLHYpK(TpR!Z z1D9(T{=NW{XAWUpQ1Qrlu7WHA0|f&D05L5jFDfAb00qU2AChMhJU1-7ha&_92Ll2C z1Oov90RajN4bi=rzL!gSU@u}w6$%Oqx{NXPtruGv9YrD;=RsR#eH4BpYQ>#HyK-?8@U(Eqp!|GWd$qeK3<0Ohbu@unC5v;q0%!s?|U@T3j@ zwGjBL74fbO_VxAa*RkTLIRCx?|NsBsbl0;0004`0QchC<0|5gB0s=pOQ5XXRk?)H& zo@^Td1Y`U8P*(AE0s=4O{r&#;CpYnf0|5rj{{H;M0R~+C{V+xS_V!-~1qa@Yfc|A) ztpmmWwSE5W69H9I5$w5L?id6F0T=f8#*QQO{%#3({QNR??Jot%{`~rj0+IJT6#n=8 zs{=fr#!R@v0t5;@gu0Ib0|dV3bVUFF0N_bPK~xyiHNib7gaH76;rBJ57>`9LgF2Ey zJ_E}|DFXwN3# zX;Qln(h{@tNKI#V^LtGUtYTXkV#QGiL+3VocNn-PewkaTKZ-R~I}AmteUegF(UJFf(J?+O3_ N002ovPDHLkV1mrpV5I;6 diff --git a/src/qt/res/movies/spinner-026.png b/src/qt/res/movies/spinner-026.png index e692a637b2d2ebea19a9132e84b16eb2596b8885..1663ddf44c07535034a7280d005318bd39bf254c 100644 GIT binary patch literal 2291 zcmVI&|pJp+kob9XfRAxJw`q%}_=$f;g=7r8gk}7!mFUdQnVbDJ4{} zmtE|pnxi!H8P#m!6@JAc#*su%Lc6B!qWA`xtfZ2Y+`xv78{EX^Caqk>Mk8A(AQclv z3|)!nPztD|o(r^zkQ0~dG*Ck>Da3XKO`3gF@wC0a18V$gRNYXrFxa3z#dQ=VX!{6n*Gn=<)#6}wj$Z}ayU8M6jQJvP2>O}KlF1r=n zveY=yQ+ z3>)WI!$1u)he&pdZ1z0GjK;uJ(W>!rhLbCiNwu+7nbR|oZx6-V*vAabGKVQ{VaV+m z`Y?|XOQ~qpp~&H|J4+4ym0UR^Q#j@D@dlRDO_L)$MkZf5M=^zbEn3Tv`ox3E^cl@Q zH~+Ph6a>}DMsrCf;lAOaLggAaEmwBQOuWQ(kuN&N0(z)U^-rQY^Q9_WPETb{C7Vwr z+k3?%tL%2Ztx}un-;7pfZAbF1>=S;E992z|l}Gu&Z<<&5p^~#E5J9oWi)*7~G(m$%LqOUqguDr=0Pb=06yz3uV{f5%9yOGX&S;>uUk-etj5dA>KsO%@nPVijwe+ej*1|Q_Z02m zkg|yu0}ndILP`$KtHi6QSAkKKc>TyfW3sX@@9!21DUl;QqGFa~B$8aOI_m8_t?bx_ z@S=h-C~=ol$Us%ow~6fVxayn4Dlvx!W=Y0E-ph4fRk?%_$8ywL!aXX7Nt1d;ci2vBvSxq-(A6~%~38F7zb~`S&bUGIU79OTr)X0WnzlOQ?GS4AT5f~aqO!@fu&>s)U4d6sBCJl>CdzN5?z2rQKtd^t@9 zM&JR_pzsuv?A|w=*&MK2>}!0)&y9fG}h=2OT9 z3YiwHZ$5;RFVVT^*OB?Jka!eh9qvd7-8FD2s8?|`GhH;DcFZu-C4B5A2577X6Jwdh zVn(V#*y>h)Ya`Do;j*$JF8s$lR$Qd?{cm2 zepfSH{>Y{6w1xiu>okq+G;x-C%9$l{*J3D=C}7kvOp}|L!AZB4(=XNd;&2kkB!l6i zT}6QrlJmLyiB-9nZ6t+*A}iGg!k!Ckkxa@rkf7>ajb*#U)NTX;zyz6$We4L`b1p{K zOQzTZ0zov4LcWxw`aW5zXf=xUk|WBm2kPCmdwEGF2W{jhnEXo5Lii?cO4@=;EDBuA zHGsEdXQcngIKqA0PAKCkmu&9dWQ(#oyuYDzqK9_HMP6Wx4^+F6BRi@8c3|do9g*R& z|6I%SBxCd{ycZBiVx^ncbe4CyFYqtrh4Eufdn|gM=Fj9Xf?l#@Eu@f770n)+yE8i{ z;|XJ)#1x6Ee9Bfv6o zVN%#XZA3?-s-D{9G6W_I48 zbw)3i(Vz**HmaBrOux_&Mk*x=-Xryv<{rid+YeEMU}XkXGI6j{InFYr(#lPxsz4x3p>|E~61 zI7WJtPA&&&=97-_?xw>O?iG8tr-dWD!hFWjCs-Vb@;t|cm1w3im&bU5O}xV)cJezm zQp|5z&0^BIhr0>}ESLZbal{3yJ=LK@hYlS&bm-8bLx&C>I&}De{{s_OTUsX8J^=s# N002ovPDHLkV1h#WL9+k= literal 951 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 diff --git a/src/qt/res/movies/spinner-029.png b/src/qt/res/movies/spinner-029.png index 27f1d5218c5dff696d82e949ea89bd6b7a3fe056..c8ca15c1e1c24156c70573cdc1dc83d37746234d 100644 GIT binary patch literal 2356 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 WJ+$;|@9~HLMS!QPpUXO@geCx@$z;L+ diff --git a/src/qt/res/movies/spinner-030.png b/src/qt/res/movies/spinner-030.png index cc8af110305dff12ed0f33dde367060e8680d2c6..c847c99a93e55b2de39c2f089c0c9edc1f4c6bcf 100644 GIT binary patch literal 2346 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 XQ9?KPRf~WD00000NkvXXu0mjf$FfU- diff --git a/src/qt/res/movies/spinner-032.png b/src/qt/res/movies/spinner-032.png index 63026d656d38cf8a5c635e6e4d90a6c003c6a3e8..f9db080567c3f8101f3b541c7e1b5b0a5599d8e8 100644 GIT binary patch literal 2345 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 Z$v<}+FkBa*P?Z1x002ovPDHLkV1lbBN8$hg diff --git a/src/qt/res/movies/spinner-033.png b/src/qt/res/movies/spinner-033.png index 7550af7b7a02e571079abcc32296eee691b5992a..43f57719e7fc607fc0152da01246c9f95f80905d 100644 GIT binary patch literal 2401 zcmV-n37+#)Jj2$NfaoEjR=GYgg1d8Oh1r@%*;MBcV^C=OjxteH|BEA{pXzh z`tN-%L?tRwiAq$W5|yY#B`SW!LLyeuv17r4cYh}s`)n)us4T2&0L zAlS)fD_7i}spS)j$s-L%B!%~#d6-#jvZ>#u z%D{m?z(`V?5@b9N@mr1?gn5YxUY^p%Cx-s-AzsGTR7cpxeUt`ZaSxH@^{Nh@F#P|Y zqeIgG9ZYpVKD3m0!ERev!%>4LVj;JM8)OXq*uu4dfG$u3f2rhC$|h{t|HTcYscQjY%5$6mih!Jg1o{sDLTr zpqN@8fXb;8{{8pF7-Si9Sjgu-pzdU3IAF#y*GI-#NueUBn-hRFw~@ic6V2Jrp_~$dt|6{|zpVUBd}2|E`ZR({h32Q}2kK;*xY#lJH?ouKM85v1kcrI2 zq7mH7Bl>~f#)l%%Wh68_lfqv```9hyOfs8&;_7pCC*-jV7X!NwxXaCO{7ZB^aT?y> z6*1he)Ey%wvR*-s#JUmDFA2{SYGL3r`BHp?(RzV?h5f=JwLIj((>~>udz8^#Qz{|3 znL1V}vfLmo?no{R%WNabduxgGI3rf3USvbZ3;LkaD59^7XY1tY7FQx@<6E-v7r zlssB$dy5XD`qYrDk2G_#L8PPe1fUjd+)01N(}y-81q$AWcZFaOukeJvC2nPl0CW$n zeB_j7$T%@Bo1=?yuyDJWdTlVs8R#^L65YLCUmlYulGIDXUbyWl^2n9ku1hyYi9z*b zHy;`vc}vWl?$9&2o!P?l7erHJHZAvpXm>m5vbn`#j`__ds1B?UtLWLf!i8T6(;p$D z35q_?h-a&_o;PtYODGqdZh{@P@Uj5((?*G6NMaLpw2Gc#2kKz5SbXZC$6DB!B4iG= zJlF&}S}ZnN4$`%w(}n3zgg|%&D>35HJx&i@3yc002&A`>(> z?5#0f#7f(Hx>5%#-NoLKW#KB{HAr8v#=e+DT?>3w%wCRZO~P)t5ML@(Csgnz=}Rsg zVlZ9B_cepOg*76=5{6`i)i!X(jujnkT_O<^AgIm1Cp=qZ4`lQJ>V&DQz1 z9w=slC0d9~fD~4^RnfP5QPWl)5iP|oH^Mb!$x#rRst45Tsj3-fH4g+eV+MP~CgytqCxiJ|vEDkfbEiLXNzt29PG%4Xcpw*r+5S!f zFhto8c##oiv&vnlP___nWe|>lJe!55g^c7Hb7{*0fej}nj^|p4r__W4499FK5naA=0hGO#o)en6+3g!Q=w207cLGmyiq5Nsq!_} z`s|WEK`9gIMxx&|Zm8&)eUBHs8VXF5d@)LL-`PE^=SO7VP?`-3MFE1WVX8ic$cQA; zmuds|8eCMcP^nR=yb~bMHDrdHW3}*@;VT5Y`Htv#dMmqs<*~}+Zd;hd!97ZM?m3Rq zN-$4jmCfW5AHSsjV+Tzjc6y85f6{nbC@?Gx;2Qj*aNc*3qz_A|G4QH?_Hqdw*lGB3 z(0H0$tT^}{|L}XYa;;ZvdY{2tr5X-J~lSa%iBj;1!xXa zR(38cD=P~NOJ{rY;q42ef?R;An3vvBtzuF!5aIMFeWjz1avwT^~^L>@zgLw+? zmWch|F8qHB>;J6`|93O|TEoFBq}T|I(VmhZKVZ^;0cIvSV-tV7(4zd{kT*oZ+;qRY6ztcH{qn`(|DF43qWE(SEPfYlm zH3E!`GR3R6P4Q%AW_;2prvr4&2~QWt5D7`vgSHwh3=C`+-WLXi>x7x9J=IT3QIZyO zYxOBIlF*r^Z5cVG=a7rq;$6|2$JgfMM0iX(SUqXUkGU#cA4NTH+1-Aq?5QMcXO**v zXZ@w0mqIr!577)=^WOe--K$7zhA`QxEB9YSTki62Ylvn&{LXDd!{k>pdUksn1xmA; z1|JB0sGm8rEc01X*`#cX`Q=`(WqLyA{?#ekqjH*o$0o#U)5Z2*33nTIJvP7D6t}1` t*K?BWhPyE}{Y&carOo2ne^YnA`u_?}Gs{`q-MT;_?CI*~vd$@?2>`FLKkWbj diff --git a/src/qt/res/movies/spinner-034.png b/src/qt/res/movies/spinner-034.png index afcd2c2826a958d90c3e2133b0e7fdfb56155027..c26656ff17a5afb2a3051b075737f8f2bb062dab 100644 GIT binary patch literal 2422 zcmV-+35oWJP)LQmb88O(*2FXk@9=*ddqAuI94vkTO%N z%i40{(sfv&*lB2FPG@GgG%z#EL*^+l28iy2NZ^#R^zDJIoZanZ&QTngnc}7iJC>G@)^hQ*2^7afEfgwGCwy zN733m^=xMb>DW3K*xvlh0p`W$93N6bI`+;2)4~|O5`b!Gv{1_eatOz2exP=4RlvOX zT;MaFBM+XSC^G7nwx3U(jT*IH($9a#zHdD(JT#wy+ zY8*-i5Av=TE35H2Wu%x7s)Z2Jn8FtR=P}eT7;jcf97aEi*ybV7b!N_X5_z1n9(vcY z=5#fojNobNJXYLtdWkxbO*V-{2B%VYBZ~*A@&aZZzjT5U&os8Mm;LNx1-AyHA-ajp zob$@&R?*YxR|?tBh1NHYu!Nz61P{zq7JCU&qn<*i^&BVY!%qG{3gN*3voFgz=_O2! zZKOD@=id~`-YzE4Bd|L*k_l9M4N~Jgvk7hYTS>gBe7}jMWCqR^S-FGVKETxYFGHLh zOAMd7_>V@a7!)WwJCUz_g4xVmVRdX&x%t0$x!!ml%EE2zcSEF{q(S^kE$N~cp5TEd z+-vk+9n4#_xR}yuUSSwtA@Eoa^-pk?>@trkv_lTfLW*T28fgYp8 z-(EGGmCE5?BC~b19ubxM6cat(Um@hOLrKrnGhAWPbaE=WN@MX4Vp>6@EBM|wi1sS& zyN)vDXDt(*lui=OD#fsyxw4Jo{Z@SE4EbJqK^uKotuRf8xyOHMJCSB_&_mqbMkN#2 zA-=VVSf7~VwTh3smOlOg+MoBt0UO9~mu{UD1M~X`^I_BwuH=9??tXsZAF6tSLWx#6 zP$D7Zi*NmhRG%IF4AC+)QsEDv5iAn{9A~Tp3t**4_#jO@)B%SO&m)R}@CW{ghvYQs zc_*^tc0P7`Yd6Uq^4{@^SZs~{@$D2b;I1LV$&x0s!ifl*-r=mHtPPv=?Q_DXeeXiL zvrhb?3q`k`#ZCwNyq3Nlp1}yQji8R3^aVOpw0y_8QDG^EvWO3ym9)cuh$A z&QhYU;?5L zRyx&pIT5SFyRx zT768e*msi65wZ52r+51Q7qM~TScjWolG)(YI5k>uEel1$b*pY zlW%O~iFWE}BUj*bH8iIBBl+JYe$zc2%3}J7N&OlJ&cH%XUKU|~>W^v~6mvoxZaxV< z@6SnM>1Yda4vyt#ibmOT{i0mQuP?VHe#P&748r;-I?!HqATWE2tFF<&WPh<%4|7}` z@&v_#DgGPepI?W!1Eeu%IVm7SfTp)Wb%y5y8zBo?9aZ=_L8gU_jBz1Q!(i2V$!Ga5fAV- zr(MFFX>4gLgzI?4?J=H>bQ4LgS&IGF;O6i^6U*prG*M+Gh4n7G-!(K6MHf}&RvYAJ zJp%)CbSs5LZVplw2>(^&#j*Fc4Asg26hT_OVJtIUtmvJ(HNF3b|T5*Ne;WX#^R;UbCIo$EaoXL znrYDK=vUA{wUNsG>~(6j*~maTokWsIF>ljwNs$k++>9ZEXZARpK8&H1V!Z literal 945 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl482<(Mgt!8^jEoG73=B*_%)rFJ z093%p!~{e@0w};?s;?3q;+7mAVQp;2K zg(68w6rvf zOUi=1#40N(5b7u-F2V`Jr4|MBrjFE1?mdVlNxeT@ItFyGzR{B5=9*X7(_SBTu0tNnhX z<^L^A|93F_-^=)a59_<7{6AO(`+(uwSrX(2Oc7wf%*-SbUEUbX!_1WM@U}No*87M5 zA{@;bnWVpbt&rt)yY=VaX_mU5w#Ju#|M~T29^(>g4)*4MKY|#YTqKxd&fef*WMn)2 zYK}G|qkXk4liTk$Yv((r3XGJNvIJ&?z@PT^vIsBv}vc*H&dX~HG;rOY#et3#?@JpMM>?m?70|8!@mR?X^Vb@N~U z>bl%Br`9-AKDp=r!;D8CtohWQ9)EFiMY8zevgLner_5)t-kft@^9;`p$J}}UcE`V+ zC9YBEfAa9LQ@d2oc2_-&d;G*pE9BaNPtW^ZCanp(G{tR|x930RkB7|rHs?gNgTmX> L)z4*}Q$iB}X6;ve diff --git a/src/qt/res/movies/spinner-035.png b/src/qt/res/movies/spinner-035.png new file mode 100644 index 0000000000000000000000000000000000000000..e471f950a3e75bcaf83e38a85303360d718bbbed GIT binary patch literal 2406 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 Y0dTEbTKa9S)c^nh07*qoM6N<$g0)(dKmY&$ literal 0 HcmV?d00001 From cd9e623832f07e0fb988b73aae4fc9a0821807e9 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 15:39:12 -0400 Subject: [PATCH 114/391] [trivial] Remove obsolete pixmaps --- share/pixmaps/addressbook16.bmp | Bin 1334 -> 0 bytes share/pixmaps/addressbook16mask.bmp | Bin 126 -> 0 bytes share/pixmaps/addressbook20.bmp | Bin 1478 -> 0 bytes share/pixmaps/addressbook20mask.bmp | Bin 142 -> 0 bytes share/pixmaps/check.ico | Bin 766 -> 0 bytes share/pixmaps/favicon.ico | Bin 110225 -> 0 bytes share/pixmaps/prcycoin-bc.ico | Bin 84494 -> 0 bytes share/pixmaps/send16.bmp | Bin 1334 -> 0 bytes share/pixmaps/send16mask.bmp | Bin 126 -> 0 bytes share/pixmaps/send16masknoshadow.bmp | Bin 126 -> 0 bytes share/pixmaps/send20.bmp | Bin 1478 -> 0 bytes share/pixmaps/send20mask.bmp | Bin 142 -> 0 bytes share/ui.rc | 15 --------------- 13 files changed, 15 deletions(-) delete mode 100644 share/pixmaps/addressbook16.bmp delete mode 100644 share/pixmaps/addressbook16mask.bmp delete mode 100644 share/pixmaps/addressbook20.bmp delete mode 100644 share/pixmaps/addressbook20mask.bmp delete mode 100644 share/pixmaps/check.ico delete mode 100644 share/pixmaps/favicon.ico delete mode 100644 share/pixmaps/prcycoin-bc.ico delete mode 100644 share/pixmaps/send16.bmp delete mode 100644 share/pixmaps/send16mask.bmp delete mode 100644 share/pixmaps/send16masknoshadow.bmp delete mode 100644 share/pixmaps/send20.bmp delete mode 100644 share/pixmaps/send20mask.bmp delete mode 100644 share/ui.rc diff --git a/share/pixmaps/addressbook16.bmp b/share/pixmaps/addressbook16.bmp deleted file mode 100644 index c5576910b1b6b95c23ed7c53adec399a944e610a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1334 zcmZ9MKWrOS9LK*+iDcA*T|jP9K#EfVb%3_kxoL?Sz~+CTKo0?umkcM}a-)X~w`8y~ zWwata$wP;F^b*OVM^AaW@iN6rqzqX?CP!j;d|n(O=-qwq_kQ2^d%y4Zy_2r_Y;|6j z*XnE1Jw~M~TvK5-acvg<`*zOBxvAXL<4n`D6HQM%GM!B(AlC_)PJEuJ;Aq!F>#NkLovPNIJ5$BCNMjXNzRgQ_+*rp!g; zA@kIOH0r69ChE4y+o3w`mbys@n%a#*r9QS=N;g8a!={p`qHa`Dn3U9Rt|@8O6xBjv zRneM91uViXss*BIg-Ct1pujo>E&wqwzyhb34*>)GZGZ*v0ek=-zz6UFd;rgan8}zy z9K*-(2F}14I0I)qN3Dgo@D|R(;UVVyV|>JTi1A?2a=ck4gU;+G$Cp8$Dx%MwXb<4< zWDqq77(5xY4U>i@25o~j0eEeA^bPt3eWn2Qp2vg1gW((~M&aj7mEptAkqMyg_a@XPLPt?d zkC;5hhr8_UYhqQ@*XHJ?wzjskv$LbUy*(Wq9B6-kUx$Z>IyySi@$s=vPfvAzey)p) z3;p%C)5{kxw7tE}>9ScKn#}@lhQO)#%Jtps`s3Lw7VG>=O7B&F`?+#Qdc9t(-w6Nw z{nu~qFaPlTdHBKC%zr1p5Vd?$#kAAwEFRk42>mO|ReC~Q-`SIO_!hG=g_r>}+ss?m65uRi?;YjfP( diff --git a/share/pixmaps/addressbook16mask.bmp b/share/pixmaps/addressbook16mask.bmp deleted file mode 100644 index d3a478d1ad1d4800008fda5be5d583f3d0423480..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126 tcmZ?rtz&=yJ0PV2!~#&v$iN7eZ~&8-#Q*>Q!Giz)F))yd?S4Sa0{}e{AL0N2 diff --git a/share/pixmaps/addressbook20.bmp b/share/pixmaps/addressbook20.bmp deleted file mode 100644 index 2b33b228aaec9ef51fb3dd46b3eab98f3d61d7df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1478 zcma)+J!~6g9LAp(Xj4#-1LY%>FBd2^1%kPdf|c^&f`Ee-Fy_la3iQe$IKDk(@RGsG z9usXbe`4esg7wT_5VJWhTCq&7#TB`8C#7sMrJhB7@1L`@i5T{jfVq~s9}w4E! zw_*2z22GFXsne(_Y6L`^Q&Ln9)UH?6LQUklMn%-9Rn@6^>eWhWRy~zaBdDkql+^G% zxmCM%<*{$qXH@q}s-X&AKx|alBhM=mUG_yagLz^>b>!A&$jizrda9N1+@k8GJjy9> z3#t{1s-n7^Q?J+hqv|Z8#9m33I+p%fx*CFV4wui69xl=fgy&0 zHi&!}3=9Sa0|TuQJ`4s11A_s;Fh8c5q0o@z)5B-)!(r0iHpf?1ZLO}ZYHe*z8yg$i z+}zam_O`aRwzRXequt$I?d|Ppe}7*G2M0PlJk-Dc8U1tPhSt~DIbB|sAI&C#J4GgAUy7(iLxq5=0b7wD>|14iTJ13pEig)jYa`|ijuj|Xd{$44U-+JXM>s@~B ze0F~B8Rz8vXU<$GJsqUpEY+uS&Pl@Tw=exP@s8g$^ZbVs@0%yToOqAF{OrTj+PqKh z`{=0l_^GM)#Y3On@@AKo&)K~1UcWZ2U08f)$$4~Pap8&8SARLm(^2hh-qP}ew)Tg& zy<4?!7M$E7wco$@8{Qk2Q|5D5QkK+v>=D;`4}9?ACI0Kqe*VH!_CVjizOwS^rPG<` PK3-Y5_U;`Xahmo&>vaK4 diff --git a/share/pixmaps/addressbook20mask.bmp b/share/pixmaps/addressbook20mask.bmp deleted file mode 100644 index 56ce6125dbb83abfac437bbbcdb611f45ee57cff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142 zcmZ?r?PGudJ0PV2#3E44$iN7e2mq2o+z`wJ7J(4||Nn>c{{KI~KrXi54>yJZ01nMB AR{#J2 diff --git a/share/pixmaps/check.ico b/share/pixmaps/check.ico deleted file mode 100644 index 0c4e6e81473d47761346fd71e171a807bda5ec58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 766 zcmdUtAritc5Ji7?>Oo=IK{2@m+>AIRcZlpMaugJUL?RfLzb&Fm5tZVcTcTu78nlc+X79T)o9yH~Bu18~wK99d`Ux|y2#0TZ_)l%(v!!U*NL^S< zm%;~9QW>8Y{WOqh07L_>g8?ux2p5ho`>mS)zwRwC&*T?i$=ZxVuA02oAv^cyM=z0KqMI@BqPKaL?fG?t>45&CPf3`vQ#NZx_h0jQ?;vVpA7)O0gwRy9dH0zfDtboz~JAtwDkYkEV2MVDzv!tXh>fy!m#MW z(dx~5Z=MJ08+nJ#tq5aeWofnLSrX`#Wi3j_P7db-#iGYQFkierTY>dH1PYqpWDJ^s zJUV_=|Egxs%jh}lTnuw`*Qgs4Y-d{9&oNH>|1<(PV?A2TfPzpXWs3)E#Eeema6mp- zw$;DIY*rBZgzNUdm1hdt*LTYInOV7y_TnVp5q~n$s}d{Eji8l`9LwXx@&w6NJaPDy zc(s__3PM-EJ0fpa>mwehNbo~7nUo6SeZJSLpihS^rj+7VP<`JQZ}bae3Chw0kEbBT8L3o}%cgV)gT9 zszg=3i%ZwgFf1@%bt(LyR;zpP?`Hb=v5qXHUWiq*JFdN|ReO}go23^wAd+_(k1VEm zYiK){=;0fyw8)`uao>t`oSw+#o~$1ZUEWCZQ9kf?@o|)t7`ws?_3fB>n79c+Or{!kpN&p08#oe{|@INakPL|WiA@D>P3phI=%>BUK+Wa@P(aFG%Lv6nN8 z7;x~hA|eT3hn;6z)fzf@iFBHPjlcc@)p~U>Ykpm%d5iZTp?Tlk{4LDXClvM;Y=S`D zi@cu$*OsGO@Q7_=8=MN z64es#`g6Z+R$$^2VD0>hw)-X33>xVO-20en%n$ge5YYEH82rWN5H{?!j}4MKzs|5+ zni-g<_DgwqASP5zX&OK6c#!cMQILWseRwnfiFA^!Ho}V+a+WPXI~rO@K^jWSGZT80 zJECl4;z~Jsz@k4ssh+?q#ow1YhE_*Gv13;@DY<2Z&r<9L7b^{z5;!pKF5`Ay66R{{ ztoZRce}v|uL=OEG?8j< zp5?~DE6-F*EWHdD9-}h)VLZJ@@aPMCa|BkCAa(aImU(BxzbHA0me1PM;S>aVd_O3g zGbFw5-B2evn>r}_3K<+ye7=4r{z3Ed(jGa|X=G&kxB&CNbqF>x1OMlzN1U1DguI2>H-PvOqoh&>5J|rup8{eCqg>@L z?uA1LOj(sjsB^^LGC=I2twzR7-}377LRO^Z2V~==%>E#4nxMOybt_IO;nB5ru*{Q~ z+oLQX-FsBduo|L#F8zWoLzXx~YxxO_;jh!eUWVfBtZwJ?;85+8RpEQDhrZ|nkwE&- zh7uEB4yA)`d79nOA* zFig3|9zj|maZtbK5`wU;#2%=RkUd7vf*ghxCo5SBwzu(?KsE z{xL-aJEqLH+-619HSH0P;uL0K(f;{)kB#@(urVO$gfVF+3#rhWzT$JN-YOKOyS!yocQS`JIxuQ6AO% z6RPrd*pgT}CDdYMN;4NZf94PmJ5lLR4nP&&^7>yXtJJ5o93RyW>aFLuw)duPGLc1yrh1C1H*mPOt&)#dmq?RD5xwf z-4i7A(kSyt4>}yODcmJ*b${0oNT?_}Jh{2#gt-A{&l`uhRL zO_>FIJb@D$HJtVMg5(D6f(V{lrmC6d0SQ-D5NYn_?E*>`^OWeKX~>HrT{K}eO%%Vj zJS(2;Pkx1O>!EyN?xP{g&&H0V;!A+YBn^TmMMZ4-grGRrgFw07_+mSGn~I+TUnlf zzKFgj;$tUs2y*mgRe*i9#WR1of()6|Af-a-!!q7f06raM^9NNc!WuYIa9?A|%A%hkBs%G98d&{4p77Vyb!?#MQ?VKv=w`r=#!I>to z+@9)lc3vGNMga_;O*E59iPI0aI0wd%*!6Em=TFR1H(qGsru+cdGG8aycJOYV+n&`# zJN!m+prbx}xryTa`=Ql#jFjbu3=VoKQncIZKdR@r`qdGIPZ8HXy5!BhpLh$*M8xDy z)PJu%(fyf&w8^43hlj34Sg{Tq_Q{GKGb7wTO)1>4yO0QVyHXn2G-qCF6Im>ufq}>& zm^Tx%G_|xJh5@Bj&>G9L>pfRD6-FU<|yEq^Fap7~y)J`aeM>zOqaw zE|nvfuM^dQIj>f+&p5$xj+TrpaR?}zr6a?pCAEAQ)o$70G7b@o=N;F`j&cJC?-KBWoPoBMuy50i<{pA!3>8ZMy}3>vHpu3WkChPiJ1g|> zW~D5K^HA8FTtHv1AJZE=KagrLOaGSaIWrQp+} z@U}Iz{Pnvj%}{HvU(#rp8aW0=S0$^!KhxH^fKE@L5 z-+BNCm?nsNoq-3);x|?H=*O@i@;}B=ut7a$Z^y-^MM0;p>!Q@%-AOSuCVRikJcSv> zfR_~hEgDVfp}kosuAZoJz7&Bi9{KkjaI->R3PvKTP|e(@`$kP40VKj6gT@~-eyF@V zna}KX_0sAHrfesMdy%t-d4Vh(cJqBM3GL%jR`YxUaU8q!syoTFaq`I z0i}W5A-nxIl2hJ&)K}noQJqW2njpmF^U!8kcvAX zYAJcKE)SvYDMBVyMXVL!^5#k}C}NuH)xhQ-xVSR%O&U`U z!|~N~Q>78N5sSHUB&CG1s9075B#sRM+GXLMitJV#b(62KIz{R5J^xX~Tpw%at8P15 z4gdYPPD6=jL9Gux|C&2+|7r?}SNQp?!}#S*624ZqgoFMRvK6n-8+@xF&}?&Y=Nq9a zT`5_PayJ)=$*_!fW2;n;VYF6GHu~ds)`r0Q3(2oF3fhg&=QV)kBVyH(PAa=^bhhnp zJ+?ism_8FV{X`OI!~Sa1LR8w8s0~f^-N73-&dmp6W!b-T%_66ngux82=(83sE?7U| zYfA&E#^uR+1Q83O?>t26;`dPHb7bpLYKiSjVjTpO*PK1SV|D#TV=X7 z2#iU#F#E&caVH8ReuULMR6XKkIN|}fbX29T2s&4-7{Id=YTmkA)U>nqUx2Jezi&#- z!53QAZoV0t-!^FHg*b@D{Tv8CJNgHm$o!R3kFXaiUf_FqqoQ{m8BxxVjowMYn?^+x zV~-V5H#HTO033p_J{Q8d7ubfj7eBpXPXb$t;~MagLTghoo1y@2vao8mvwG&AiT;v9y$2rf+;r?<+93M?Z6H z_>D}kcRqS>QS2wtHRh%djuV7ixxLc~R=2Aqh)I73#f*eig^5I(IwkS&^|D*v>tVkp z9-p;9&30Wx8o>M*+)<`luommV;^OZ=#q>E{O(M?d#c@Ww+$2y&#t1k2+N1|1;Kyb9L`U2gO~7_hq6ZuwCJTzZJ*nsAs4OZ1}H+Wcr@*2k#6WEvIv)KT=CL7 zxLjK`j9FHs;xHb#-B7%%{i4uOGE0hw!UVdW(C&3OY3x_}sqm-4lAw~*V=K6RH{2xo z4*V14(mh(L*c5!$Dd+xFR5fw@r1P!9=GB_O?Say%AHG^oaZ7x6ex>P;vvlHtjWijl z8MaL^>c(Wel}iZV?$x71DfzlG01PFy{!zG(26lc1dlp`Ie?5a8Ei(1qQS{0|UfvU& zMi(CxkHl1tyxfo2Gv-`GA{iBG;#Q&E@(Y-;Vg5{(HT0yZ<+!X+51(j{pFWEh=mp^DXxUI&(f>0baN!Y6T_fu&flkw-ad zBQ1)u+ihIkWkfm_HS=|Qj_@Hj>L;Af^9(W2iFZ}&#DwLEX2vL=2sWKP$Dk=jXJYFGI zm_IHFnxclL4pQ%#cE*Q`z5|NpigkC1#OFNa9`aP?!j z2H=c%rxu`uMtcU%xomf!F73aNanTy1j0m2{?8Tdv-(OiR7GZr+vaw{R3Tlk_Y|2n2 zi~@0(Xg6mGJgcz1>st)6kgnq774la$3$S~3C~OL*`8TPH$97$BqP#6kxQILqgH%&t zGp#Vz3A3K9fNOgPGTW$N$#zF%TgyBQW-U2x0mum)osu#~p^_oa7avb_YbY;z2Gj9G zysPgROIY;%m5pT5kB50@;ncm7@bwLR2f`F4-U9Yms*zH>*JJ-t58IFFA?{=*E=C7d zD6Y23qRXiA*g-T*Bv=#?68^MtxQ>oYeCEf&SY&LsT>5u@NRGgHg z__I!t(CB6?MZPoE24gt7sjmpx3UEoRWM4OL(fT7NXb-R-ci44s~isSHj0W6HVBcuT`*??xEn< zSMOOt3BNV2wOkD8-UZ5F?+uuixyB=IrrC?vV4^P%IOtNR+YjOZV|AJ z*?7zIK5!U|TJgB)yGi*AfPvvKIP#B%_hUNwAqLj6k{oSVMv!p9Yi3gTB$7xO{9k3V ziqA6XH>greVCnQafvV6W8PeacGg{vl9mIO4i!m!*a3g402vN1nq$>vWFEAgQqEv9$ zUvY8U^q@^6dAR)k^-C4t*PL8#*D1iK_OmIM!hpTj?tQ8>f)eh>l{8zQku@0N#tCVC zA!{(@ZdLk*Fr}@%Z-%Sm#CpMCOb~YmYhnAJ*rD_n!lZ*T$J%MOcPGs%T7_ZXTD3Ou zX4x$M`El;W`RPaQR-|+ay2V-d z-VX5IHt^n-l&e(ag)eIQgfrmYwy^umYmU;ho%h%?P_-zp6&P$))XzEtrXm~MprI7r zdt&B*HFSDwC~-Sh9Y_r`Imm$n1pVv%EN+{E+x2WR!LY(G^+@h#aI5K_$E`LFWcNAjmQ zf#w)~qOxuoOUQdHL|ASFVkK5-VM3RiPEzQ4M;*X z8{ao=FWQoGV)k&!7b@W9--h1c5!aP%)y%wmyf3X-{+l%jJests>h;nh@-WT=i)H~@ zF$;e{GxB$;@zcW_5exaYHhC%Z@&31-K4mP@iEZ$c*3W`{K|W6t5%AB(m;8^<#&4bD zy*~8QG=-wDaj>}Gc6VW#<&*y=)KoL*&|?^Z@ef3tx9hg*1kJtks4d_LvtvmR!pa{u zuEWZw=a~S>>?Z}#2_#LU7VFr{wl#-{2E)mqCkbtZFg!85sdIOCryD9uqE30`;OkE) zv$|4-TA?^A8+Ah1h|-;Z;Sp11&MK^gSb}PwWBt)oYyt=gnb6NAKAU^IBa^+PiXT;r zIFhdVl5QTbKKX7^7vbaQA3yo{(Z;PKR5@*dWcqN%?|r`7s|BsV+|(ri&0;c!zgoa~BE9iW0MUJ{@-+J>QAa zRp~N0B{S@5H?`+r+5uOlK?t36h2iparf;>br-3mT7lSkti`52+nb`0iCOJs- zEY2u#*cZgE8*n?eZLi*=q*?Aow!h%N3c0wlP*v?)lnT&d-9s_u)`N{^F@AlREhGA_ z*bPhBNtat5EiHsV8sm0;7vdE^OZD7D;P=xd8QqZ=cB~#fY$?1clmn!0vi(Pb?uM;g z*bUUS9>JP+2!wvS!V%}B9$CSxQ60iVIMm&#nmv%I`PTLAuJ*ZQ%@)!m3<95D#^zw zA`ruo#?>E}w*{5#x=w${CJTA<$`$=$-P;4Vykh!7qyxNi4u4+E-sp|iGsCQZc>mU# z5$t9SloIjS=^&Y!>H_Qjm3Ya~3X0<1xJAo#Tn&&)q(iUTH?c{gK005yExjP7SHV?D z(2ms!vL>Q-1UR*EH}l;Q6uWw=w*FCpOxmxV{hhXGeNdLzzgW=3Vd5ze7|kuG&5icv zGNZ4z3;-#q$bFlU-KN!%Whj$IrY=PfWgL>RrZw(`ZAFcii3`Zd^YYO7(^qMV&M!_q zPruHXEn-B|ofm|+czrSvEX*xz+Ud4!!&>v|ROAQ=pdPnYUOI+QOT%lUBHwHS@s_tRw9 z$+Kb5qt2}Y)3-cNO1XKfCC^B6hp_mgzjDiRtN4ZLRuOy!TX_oQ^R}u%<(tU{sKvM{ zvi=8rJ5aTdQ-8mmPa!>^tnjyxzf}CU{8~;UZq+ivRI<7(KS*=4WYI!rk&pFe5Ao`v z*$B~$sHVSv5@EDU|MqS1uIaaFb>h{eCNO+S&42`P${8cddI!=Y!6TYfX<*@q5qOG8 ze>Fq)gEmS8;k752ovh(KrYv?^Tq#dVNJ^XR_UCh1I&E3pKb?#hm)kCca(bao9Y1m! zx04v$1S5|AW-HTv`1UCVj!>8SC@HaKCiUCpWMR^q%8851G& zG>%2OqmZBzTU<`+ZH4)S_USY&7!MB^?0?sMo7h?Y1~yr^f!&_v=HB%7+$W#Z)R@9O z48=4|U66g#-G@f0{^Z%wo$su=opS-2S|0xqs)s@QAb zw&Bdj{X4N1eYw1CElnPnhg8x>uD#^sM(9p*2}NQb%@>i7#qi;(wva1?EX;jp>uq_DdC2AM?^^8XeKC2{7$m%Th_jW_#@9dm@RaZC z{E!Aimq7mq-a6GMi{5y+m(ppWyN@EWdnrX7oTn925hJkFHPeH8mc#$R1*|2t+k*T984j?UUjUXzwadR>amlt+! za&Zi^%FP|Q8G%Wd*%B*ogg6stgIDm{wt~{_C0Yt<*mKvYWmqrOY)6kxHc>|TzNe7? z2$UTlmGmTC*dWKk-%yW3h!qI!k4mu!j9;ztsASv1j*js!<$O98(*@o&>paMl9egvfYuz5E!18zV3bezExnD1Efnr(O zs_L<2=L8XADF&+`aG|rhnV>AWjUBi%+N=88Q)1c|3$&S_OvMRgOnT^gNZuT%0&O|=lnUgs z(#Xy4Z|f&XJllwPKM?+2>reFev5(1(YGdoy<1L7D^9n1`tF~mt?g&QBpEfl4`R!C( zR0G8{cytcK`xx>@hg-+GqoTCi_H%3Yv?Gd4q}!W@KN_d$1q%AU*xGj40?V0-z8oPV zdl$=Kyi}ILT~u~bMPi7!-Jv|9AjUNdiAiU=xINAfBGANVQyt2hQB|+r!y*HqB+>AX zBf6e(Hh8YEeCfvC_zUa=Z&*$$P~P)AG=){zd*YfBW((}ip4a;TusPS?CciCQgY8o0&dXOp3c z7vM)`HoJB&@4d*yQ-wTdl;$UIS5HNb`^ z37v;`mux|yZnu<8X`_$&E3FBaBe%P);qoPr?p3Ow`J+xxois3+yFR0UPx3~L6ZBda ze0xmLb(_3pYv5EN2MxmiuH_*9`bUn##d&&ll{Us-Xg}F?7O@JS5lyxXd3%ECei<(7 zbJkl=<&xFjnm5m6wLRBq+BSHl3zTs%6?8 zRHNSqAN|;Mh&xem|m>dsXm^TKeHNH zQQ;jRlEB9a(|MY3Av-65t+z)nCBr;YW)m~vS8VCv!D${V9(F9I9n%emF5Ji4>ROWE zw15qHz|rbO;7D~wa(?=*Z~g0|+06_j&^6`ED7~<9pmb|LyOnxp_dsoM%6YvxI&=8Z zUcJatJY(B_;MhaO%`=Q$m*63ua70HrAGgJUqo7T`0uLM5#oi|YDqT(5C_8E2ep)%# zkl9uhAL;XAtYddAE8-LS$|5Gajr_iJdOx5r)u@frD>Wzl-m98qLQ>A?uU%C=r zONqVr^GebXTle(AIpWTji*W7|U{baeC)%k%qc(u5xbh+c3D8Lr*#)@Bi}iAH&+?=i zRSAE={Q~n!KRsK#nJ?FY(Z#j4+u=c}J_Tb?6VU#1onsJ9ezr{HpF!p+q2k?tSvl|< zsHC|+J4>O(s4Yp34e@i^Ao;JzkU$2!`rd2AmeQC->{|k_atM)#nGc&z+u&l{fTFJT z0}%1-OhVS(7{*b!pcZDLG$C&6a&?Kr9>o3z4>8TzC%JrK3OWJN?DV?>3F7ficKEtW zMpP>5qZ@V7jy}R?3 zH72|IE&Eu$Y(~9?YPp)zxU}7)_HK8oqh8fOoB^U~VHKY8fZeTpP!f zQ!NXoI1RSn;FMx6BT6|GuE;8#VdfEMB7ItCfpWNF#J53GN3%8@su8)2RStC0Ly=Fr z=?4BoZ)ckW!v`(ZwG6@e0aFwqQ!G#RAV@Hzx85Z^_<_^K`gu3(!yD#7GTsh3NL;9I z-!3(yOwGs5E?p||NpnBj!=Jeb)4@Aw4fpov-92529e`_qh+oJ z0mRnplD_2~SsO=ICY-?+dxlEMinfM@xccKh!v4EqN5nTuKMVO)2l{x1eQZklt}w(}2pq@yxCEBsm-kb0VnU2{6jF=x$$L1Ef%7fXmkmFNdin zU7D(FsFaAjIbOBU>}@o-Qv8wDU>;d+?-oJLU;a<56H)EM|d{>n#7niQzgq9`6mP39WEiW z{npT%mzQ4wzVvf;KYWTqqHL4b*HD7q2PUy6&fFurpMX>>F+4*^lcI8One7qe3drpE z(a5$yy@!b*SsdoHP-XTb zp*_x@t$t_n-B|v@#J=ZXrU5pew^C-t91)XC+^6?gR66C0;Wpeh&I~fugr$rQ?8@V` z@#1G0^?P>=XE7VMqqY)hkLO6cjlOelYiF|EaC7_(hT&sw^WC;|nanE=4J}8a>tB-} zWhoX;fj!-aZXW(8>iXt3ai8n@!KRxantZLt?Lubx$X`3igy@U6Mhx0@u1mEeKF>a> zMxl8NmAF#_!0IK6mj$zRM<()nzv)Zq3g@J+OY6j|s6gE=>(-IMe63=UUX+ibKC`?G zLy<28fDV6Cyij>CR`CSa!fC>I|I=ojf6_hl$m@MK`|(@Av3AW4ddb;JzT@R z>ECjHIJWQj7a%Zqx6+eN6X??F|7g~Iq4oZC=ovYEvu1d!+HIiu&`_Al%Ko13>pDY& zwS*aaKn8Z?li~hX!p+owdxF$i`_?vCs-zf`yJ2&OZljMHVPIsb|hjmFQ^<>V)X*7h1__6f?`~JHN!X8@xF5w4zG|O81zFE z#f?-7v;qQ%z)wsruz15iOpqN^T%?uxPQXuCb> z`bBOS=%!KI3%;j9SrTlzjFWshvu*VqfYi7@Pazq&d+V&W0bdIp+=_*UPY;;1Y7QUM zhQeR^VofN;HV^lL1vOhrXV#omLwBRDsU3Avp9`R>ci$4{uT@5vl)W!x=FdiLCBt|3 zNoT5>e3T%2#vKW&0(p`c{x}2B+xCcWLp0geBc;k!0&;e(3;x6S=d5Qkk?TCB^-g-Nlkm;4i zsJ~=PK@L-QgM82yORX$gAmkPo9K`(hkgfd;C#66va>=CpgyzfBNmGsForvEOmmJzR zDuj-}fq$x=6rAn8XpQ5|i+(#IY9CSwUd_)OGEGPsY+d(SQ{#;eLu_w=7kSK#_p`j?D;B9~WB?82{VaU6Jqg`L@9%few`%7;sV^HI!*|v3iuT?ti zA)F3&fYJ($>XeJ~&9wQ5zc=S2+h~}!?p3jm0Lgruj-`jx?kls;MRa0Mf3D(n^N3AM zixcsR&4C9W>WI3N%xnfW=rDI&eEX%7_<$m*oa6AxBuwJ@*m$$_DzEc>5LC}elbT5~ zFv-V(Tcr`x(Xn)hZHFLJ`{-|OTH9K39anz2>7sET^Dd8_SgV-?!nx2c!6 zzf!^_qx_&P?&||O5}v>fx*%_m$QDyEqH_ElH-glLn(y2zvyK`&!hwr-f`z>xO6G-- z=Ngl!oj}{c!&&>DQGr%$`o^GBM*-(lZcn75B}vor&M$bZ0ySOKX*bo51#?f!^wYsg zg(t7z(&FKB15_sFPp|!%C>|f53%35nCj^zxoF6bE0h}|v@)v(NI9yn)vVi^)0>m14 zSGa;Y*YeNa7L2yW{$*!}Y#pM!Y+1cP6LDxuF@`u3;TGy&&KKg%?}ihsX3E0h}aryloczbuN7 z3*sv7(Pr>20?v}i{^HIqd5a{5E>ZrxbtRC{0a8dvH?*sRu1^A?aI=hxL#$8}z0yo# zJby@9(5ar2ki^fS4{gucG0`-DC5GBo3s?|;*mgOEg$Kp>yE&re%7G^)j#}9&0LCAw zqLrVZ78kGLl~ApKO>?+|1dz*^gba2Z($}^V7H}5FwI>{s*uH?Q2l-=<%_s`kfBgkq zGq`k;1DkWovibz=q7|6Lg0h>rvqkNBB_R%q@(uz8`k6v zNMm*F$AOyv1C8`>8ZDT?fesy6>R# z*=&WTS&T`93`++p_O1J@oDCs0wNK~AT}eRUg%b71RaYe3i!q2LaGSy1_jWU| zaK=_DoMG!>3dP`HG}mX_<9cDSUcKj(Cq$mr3^m9aFX*nK_XQXHmIf)_8^jJBUG)(o z{Ql1LI!_GMIQmA>-ic;@gjzJd1Vh4ryRt#zHT= zKW3Av8QMLr2RdeM!LB$!u;E<8t&YL@yj^Y*43=8gZbZnk7ort=X{KL|)a*d6xU%R6 zX{k5T%_)Dh4`UWyr>>cJcfdkVzpSshnvynUUU0z zf%PsD#Yc4IOwhMIe`s>g7yQs@`+3I_XhYNz_t(bjM|+AJh*Qs&P!rl`EP~MHoWomfYOQxescW%Mm* zYXkB#4NpEWvAPkKqEb>Et8e+_#aoq>wsd$A+mI6!7~1^ucz=b!w)IHA`P98Nl&Hh^ z-0x5Gw8(!I{m}@-2mKWXNH>`Kd=>hvdv8(?ZA!ixg9MJk2acJ4vRyV`-P-jxd!+o% zD6eE9UiP%pV>J*+k{A!1K%PdQNrry{=FJB@)KecZK*ZJQ=kl9PL6ak+?eHVfUF>7f z@4z&~9^ft2-btX|6NWen$m81N{ncB6<9I-U+_uVF;m5k$4ek?N)}%S-NT-pU1ygEa z@bBNB%v%hZSRZSc8MLuKbqTJiE^ z(=l0l;xg$nMXytb8+%tDe;|yMnSW8Po zKKEcWZu=7DzUUAlfO=eDI5?jGhdO{Nd6PMP{P}ae^@BAd%@*@=XRa`1?$MD%AL6!o z&M$JH3+t3to?&s&X${_y1$Ox3 z^7hfikKGph%IAty*xT7(+eE!}eO@tVx9FNi`f*L$jG_#jd0dvwd!!u7@VjfvR1`jg zsq4rjcqp?cU{T-#bIz~!2BnVfVP8BND6D#p(jOLp9YlLAfdcY=g7&Dusc(Wiu$7Yo z)6igVEk=}5MfT1tK~Syuyw6iJ3)sRNS@>dB0oSqgL*IXPboS3ad<{$Ga*U_r2Nft* zSUo;}n^X0uY*re`jA+45{igjjMAAsfm%1bSdk41YJT281crE{NN|HrOeJ-W04(Ev# zY!(ggPPwMyYd<5#DZ~Yb#)XFjJ{k#2T-aKn1L0T5*E#a@_QRkPX>ysYobO8`l2%W< zg_!@aayaSyDDk<%w>E-J5vpfS@CX~qG4nfzpD9Dq8vuJ1&ovbUvz)uMB)}d2vG9*y zlDyU2gi=UNIJiVs9_^&zFDI&emccx16JLP_SL_T$Wz|(~~z^ZKb zJU6~mYSJvg=fvSGPlBMXr%Uc#{nS8b@aydEJ_y#jRn*gFCpkTNJHqS9eLZW0<9c*I zQnl3jj}xpGl+12j3T)UU%D&0HDLh-Ad0IrBKf?+-nu54mxJ~gqM|D81uz*xP<-W{U zSPe(dOj{5M5^h(tfY_r>A$%U%LNJBZb{lqqRn54gX~P&!uz&PSnAUQ*)U$i4UiF9a zBSs90lA6WpZLPW6>V$R)Vj;mJYE!G7MlMy1(@ch4DCPagpI9M(0ZmSVo@3E3CaIfV z6i?S`+axM@m0#mJgRxr{gqS@Do5)b)J0U;UoMZ6OkyP@?#~rK%KyN2m2ayrQtfa%a zwKe^>1t`gqUp4n*-K5FuCHb-R(oi{zN%{(d-BHgwWuX|p4`#tJt)QeUS&Ro2M7)NO zL#0l%;42{O-D(FfhY7|*%PP}vyG4}u!PQ6?LY9tc!U3SxtHPiiLBehoY|W%5T`{d$ zk8FJ^(bo2j=e7^BqZJbL1#G1s~5$-fmLIWy@{^NNN;{&Ud8&2!4FkPPe6XThMHN5 zgG|}wvuwOk%+T%mDz%r*+{@xc=U{7wu#5Fg3pY{Xzy@gjOhY$n%9dmhWvoq%P zC$e7*Hk6<8fD*y>$lmF322hV5DWa#V z;bF4aVTLXG9r?hVzRBnPq*Sr`J$|g5k(zg+JpEJ3aGKOa;HR<8ZL!itl0421RL(vm z+oFvevFr3$=0;lWWDlGx@!%hD6aKNA(dQl$c-!lX&$_8W8LZ`g37P=SnGYfk~D_Qp~pha(Okij>ub+cce zXK2^&W|4iJ~9tT2X~$DxUl-2qXZZ! zp8fnE0FXd$zxfRC>a`|MJaod;^~2u4^EX>2>~GYEN`1!jPxLyx|JQ$<7eDWAVmwlv z;ObMvB9G^J?D2}E6U%J20<`0zT!++^bR6FjbPO2lNWrA&(ZcBu4AmAK)B<8zLBeA0G|D#n-JpT2%c)!vYOko1s!P$y)~XPU*wf9dLgY=9ht_s zTA8Cik1zA?+D_#)J=~es&*oI7Ny4AJ{S*A<#~(7IuCmcwS>Ephwtd&Ppq}qL7VHxy z-}hboz!(KTup9u-HEDqB;JF^I>oQeV{OHS9Ieegs5PLXtxxwW|j@`R<(^N(N>d`#+ zok-d4q};IQS*)ZDcFoBME^OK+j~{)f4|r$}_)McSJi zC?yf4QN-93VZA}31c_aeV-{axHflH$A`P1xaM!a8vfge363ODGuCx01Y3ubZwYS|dp1xs`{-#CxTWx4HIF^GqzU5cB^Vm2_BuHHYkw+kL#577T z;pBSE7oWq-Xv(?uCS*%T9AS9?hM}iCm%10Aaz5I3NPQ0xc*xla)^|t{L)DvKoem{^IcM zzrn}ee^vVf{`n2SUC;Y&H19=-nf?woZIxf8kcPv-mEx6x>9;pi04*7sdK z;N}S^j7mtNqo zw$)|V;X~Z_@y8(uh$~~{4$RRA6>&GE@$d@aW{1vlom2@N?GpE5k}#rIYZ`m0BuSc5 zD3*vjk>R(e8o~q+FfnaPXxp3piNm+;y~J9lib`GloJX2s>YZK=;uwAGFsj?+$Q=`` zE~Rkr0NnQwJap2W_1OTAe8Kkco3OvIZ#Tbsco(mC1fyhNpQaA{&s6hsCoj`Jd&waE zS(&djr2Ne*l)q8q?)h>4^BaGKBQq|(sGEu-6ZDcAzSO{Fx=hfD*T_2~l>I5D$GWUE zY9xtkrVeXGI=uDMksOHIY`Qsc1S3;bZo6TQ`^TmT%O!fH0%U-H-uRrPFjy~w;8PG2XvOHf{gkKT_E`DG_{7m^h-zvXVe9!Y3 zE2aFxYc4V|KF|4u4r{$}@}(J8YCfNPVwCb&k$p2yWobKNV=HAlNjUY;2A#I1H(H>* z-DB5F?_l|nMXEO*Vd?&hlwST^8Xtd{*7fsvCs#?!C3ZdaxoqBckmP~WL>l5$5KPbD zj84#5UIhzwFonKNB8(*eEF`G+L^UqqJefX~!=45Dt!)LM}(L)uB6kfR(Ml zF#cR0zW9()_)=*I=^ym+PaHkKTlP-!ombF$*MMJ$Qhx1`b0kYEJC%Rf^Irk>vAxBs zpZ*m7$FIBruOOI|c~(`4R=kYXmuSTsBz}=VO(A3tWQl+df;GyyBOIBjaQX5@Dp8N7 z8(3d6Ncgwi9Ii@HXljK54^8ibI3f`OB_vvFWUCEIvl)flP#ytk<_sdTX%Xg91Od&> zZF;L4gC(f0-HYfMLlAXC$_MuH{A!trAmCyz9C_gPf9vgE_Xa@RcITKtzY`(8-^7{{ zvO${)^D!pd>?-&8x3BtcgixemZ%FaAoxP!KPmadXcF2YhW)-(perZ#JPk-{u{NZok zL$4c|cj*t0<`z3zdwo|B_?X;27y|u#*M|EBYGv#+3haY|UGJ9rcY1LL4 z8K0+EbZDg&3S;9;&E^SmQxuDPc;M0k5f0^pQ>w!~dJXkb@^f%iU=x=<7e zu27W478Q4zdMeq{dB&an1hoxZzipxcF$W?==nXs}C{#6%*FmRZ$JXzXjtMbCSS6Yy zpCcI`MI{N!tO|uRMYg-3HBqXl^diP9mBD^d7)k{+?!*}D_dhbIqznc@*!hS)OG@*q zV+Sdri4X_>bl=VI;3Mzb`ua5hx88Y72=Q?ZcMT@3Lf=!NkntL~AD-rw-}ddaS~X;n zT6EvAu=}CDWnq~-Kied$jS;Y4Y?{Wr>m48CV;{KJEP$}{8v5OQHs8;#yDsGVdA?&6 z--iA;HnyrBW$RYuIS#Pzu?&jm%;(Hvamc{!PR=u@9 zeftN$J`KRFcfK6>07C5Q-)1H(+UqG!yvnyc|1O^X^k>khZ5l5B4yDHqx)wvApBS9l z+3-f8XfztU`PcuH#~v88U5nuAxn75F`^BH( zrW+2Dj*K(4vcRFr2wH@IBJFJviW-VM6Ru`THu31Pk#y0{9FEA*PFA=WX+}DWh+K(s zZa1^ziiOP$lGL2?UYekUAi=>693sbMw3MeDwP{EX;uyKUMfH($^gwvJh++3w+n^8FB(TS|9l6k=x$HJ@3CNE5-k5 z48Sc>y6NBh##mwq?F-^`$VV zwe9V&mzoRb7I@RI{t0VKL(x>$Za)O}4d?#89q3^Y|0_X1hn$y{{4$oGi|4v{o<|`N z{M;)pGdgw~h*`e$=s7<9n9FuJf}1ZBJ5`R(-NsV4$(hqV8nu-C_&D`W%E4#d%*jum zB#i}f?+lHV7M&D2i`&GrQ=}KxsW*E>N}?h~W3x#VE5bA92%`kuiN6xEZ))M zh+>&!ZNqwfX(!=oNEFFh(|qi%OJ}`pHtqyLe+OW_V>j&NJc`{l8cEem3p%qvJN8VO zuT=O7<@a{a@(b7P;|-o*5`l{egImB`75wn|HMUNkvz>gQ&G)-kKj!x9gD7rwz9{ zA$txTF!KWK)`-+{15z~J*chu1KY@-DgfttPvfYT8L0D>adHyZO*(W7?O2z!|oL*QA z|LmP#`uZ>cx87L+-U0kDVrS6bADyhb%#KQa;0M1SEg=becJ#KLvndAKvK>GQIk+y3 zA;|VI2%-7>XYS{1Z~im7?JJDvmC8R9`a5=Hmtp!1=l-q%{#-ez_h-Z(*BF3&AbH&j zRyln5nINXPxby&t<8g6g1mTvLo*co?SGo7>0?lro14nk#OyKmri;xfS$HwWkBix%0 zvVGr0W?%9=mj3*6^hT>Br&eg(aUAi;MZ<%NQeq`Y5=ELSk|?3uOK6@wN1UX@%gd;4 z2i*#dJ94Dmg@^4`mx%cZ*lM%q=mg_cK`qVoS8J8ZF2$lGc8W9^Gn0YNUxr-4PV2R! zx^n}9PxbIVe*NGKKOhAo2plvif;#YPDg65gh}BOB_N#&c_E2}pwWuZ{s=Rj zO@uFy-Xw@Q6dgv?7G61Fab2U8p#zW0gl_uqHx zv){~z-}BF268uLs0OFQA4k5(HK|G5qbl*HcBa%9|T)&_1c=ao(H?|Qf9is8-Ap>AE z+_kk_2gB?#8=}qUq*Tg#-}zBK^4`yyMUp%I7fE^vmtzh}um4!-B% z`lh+Zx1L`*F5ms!ZJu^ZfiwjfxfSo_W${n>f+LQ9`fX zHKW9K&l6v`Y|E$&E{7Z5YF!YLC>C_Pir5`Y<8cBX?dLc$n<6`1nwL9fEmwy07Yc(> z-MKuwu0OI8iAZD4D~|``fa|;!Bwa4l z8?6x73bZyiEL73 z$U=!StjX!wX%u?L-l!Bos=*x{VeNrO4DHx;hpGYtj=*9sUhre|4Nnei0K))-!zh}IEM)M6k58o43;T^*P@T5_G&vO0kKu^c<87n7z z*YoStY6_eZk6!Gs)-F*jS6SKeSXj|4thK={llnPw#R8{Ju2Y;ECs(bovDv1(-Xaz* z-ODxN(F%=AYovz{5P$wL(r%1cZxF{R#feFxUQF0aNa{^Qv4|{>(B7&+k|G@!f;{q; z+hE}`Ix>qegvxwVw%SG_gftOFV)_2n5%2?2*C+A{)YlTWS7YP#OT{Z1dU8-I^OT#9 z@Q33??m$?iA3}@t|3EwDy$_x;13W@Iz@yuQMWmX>l|G3aW3n{Odix@crbACDw1x&QS_q0>%62SK%Fu*UGzHgXyyVd6 zrf99HZ`as=>;NDJ-XHqlp)BNStZoo)ZrO@}yR$UtICMHa=8hlc?tG5@r2_Y?Y*rWl z_^p5PwP^rue%j9=_-znHqkUHx03DNeV!r!(U&Gk^E?TXI8O3dt-$mPTTn6AXdA+cQ zLHV($KSFS6;WBUj@9$t`;cwW!Jna3m@}F;rKt|yQ+|2nq!ryWp|7;n50x96vw?c`mQ@XtorUscE`WvVL}h%B@FOePjVK zK1Of5OA@8@Mn_1`te2g!VkfuDg!BQZ!aK$v^dW z!jq>-H?|P98miGY6zZ(BnsuxQf$%+a#`N=ikP?5qLV3iYCyTJvB!~9Mu$6*A4H7-5ie&99RUG9D0gi-Wx80>5B^!zOg_O;qj+k)?ZHO{wx3tpp1 zHSD5FWyTxZ)F-An*x01!J4n@KG%xX@Jl&4sa>lt361;+2+30%M?nJ>={qEwAvz04BJl#lR0%#Nt!BKNYN;z zh*M2B)08tcEC>5!Uj$j**vkel4go%cHp6$m@nz@g5T2OzPs^ftatOY)=+Pj-P z5NdtkLx*ntBkp*nYSM`8SO{j_u)> z_rbBkWPhhAC3z5XWD+6LljccV|99FzcuQUHNOD>2~r`=(JP^>Xxr z5!k4k(nz^{MVT)TehxW1%@5yrkY5QLX6*nEji7_(qZ(ebT;swcr|d}Xa4@dB-@{)w zh<~fqNBW6F_`%n}-A^Of+#o3yDc84&^Lff?LS89$RYzzpE;2nf&c=ETCr~Ul+PFEF zYQdw~u2HYG!EsP=OxTVX6A?#7yWD@Vg)UXtKRQ90Q#4TISfgB!Oa|NJ+M>6#O*}D5QtQww7vbD0 zaiU04O(;Da*G0HK-Byq3T{Fxc*u$lBOEkCZgzX-pTrupujSW<@4QI~T6=>fkA)20Ld}ED5*rQP>G3mtIJwC^oUYCyN z((@}!u!1?l*n|d!GGtmbN!7{XUz_o7MBPIzHChi$UR_za|Sh zoeqEaoA2b|&po{3Wjq_oK~Yp^_HV-o?j#GB&eww zqE?qqwM4qKh2Cr$FP|!+Skdlwi6TYVjfld8dacF!@)o^rgi|a+tjOJPJ!*N4bZx_K zLrM{bxne*->DVbZcHNj`7Z!SfUAvt#A4Z{IT6v2l+t4%c{*%`q=FR)2c%>9n&`1Oc zu!ZKA63zen_$7K57k7^CYPD@E?-eD!P7CUFDCOaY{x#fovsoD8I5?FeUayB+EO5*A zCKsxsjD#J!r4kcKkDw@6&QI|4ypO^~h?FVSMMV*-LQ;;poI?=h3Uqs2)>|FQ`64=u zNMg-$98j;0v)S%36+S_;n4_sC8TE>ER?jjqzMrMW37Q?(W=|i=#t|Cz>QDU|= zcS1!c611a~G*!e=%*>uS8x>>}3{9eKFIKh6#>0=Bvh0qEzyJ(fYPI>6n~yOAOqYs< z-+lb-8TFxeKlIgW0B*khClT`Z5TepwpOnS@w$`6_1>g9(*AUO|Vyn>{FmHwF40Ezc zyjj3tXXFcEXXVRmUmh$kt@8W7^7|~G|H=U>Pig?NeSKG^04})RfbnPYe?tH=zYlwV z%l30!DuLohzN<}=OyEih?kvbr9$jeDRb`YDQ0ocu`4P@-L~LzEIE6fWZ@rOT6Y`Uj zw1vag{b%TELAba^*zTbgH%Veek|?576UT}uNm1IN*NupKDQTJ##)@{QhgJ&R?4o-S zG~1-xH3(x!gl(d-QPJ&BgT*Cl0PK*DEdTTayR0Ix2!GKU0Nd1)%R!;Ukz23l9kW%Q z)1TH0F|Y*uR4?VX9y)_sSu+bbvT42T&XDpCbNX9mZ{MMP@S0b^NYzXlI(`f%?wL)y z+uNv-Q4;%|`>CST?NHB^VSAfMI9%^aTCHu|0OEF+LnBp|6G5lf!)bRYwYM2*Zc>v) z+HRiq$OwsWaJpSH4M{1Moe}2CGqjTxHrtn(8J{KHtTDf5hQ}_h^!xm=a|9D*_5o@I z?IOWX}99o)zB zOGS3&eLlNhn>hE5-}}9;aMj?WK$(+bm5d-0^A(Q{}EuO76w>ugsK09$YH?}c@s$|?Mv@vu-rNKP{-GJtTGyU%CifTl0^}^pUmTj? zlQUr7v+uZxw~ZCJ0b!^0YC_-?@VZ9GNA5oX+cit;9ct)l4Au5qL-YE#HsQ|O;M=|# zw(540um_Imt8hA9qWuT(wl>(B-_Pi!3*?iClI;cATg{=DSBNVf5h>#iG~<|E`7+z> z9<`}m#8MFYd3xi!@ar3hb{nBmgcj^6rrbUzxU|wF*J`4JF4q+bJl+j)bx5@o;`wbF z+cma(4pJ+WHo$Y=vun+faSz{tS~u~CiPZoYjF@FC!v`V5?56%=N>&Vl1c zxb=I!n^U!IL$tt5XLSX5a=_ttBmA0&Rr{UCZ{%41i}+0N-4pmufo!R2!uVW7yh8 zR0@bNL3M0%P%aOikI0wM8JjPkALRT&4(4Wf?OiwXzl;73T5lJ@7lBu=H+lGhCyY|} zk^b(W%(nyOw`IQiHazDUaQm$WhbR@y^q(V#VDU0)-#*gSRhZj_yS<5Y9r7FN6qA_c zBgdFtU%{D}pxf%;dV)qXqLj-~$D`A!v)qo5Qc%nV6yi2KN=+U+UDBFnWJj_>2<0%PGVci$+!na0vre0yC< zi58L+O(%}{^EbYOM?d++zw?_BnfJG3pMLkB9oucfdo#$x?}z+`;_LP=J$%PS2!|hk zMM$}H8$z`B@`;2)2S+(Fe~|57%xcY}=laY~ALZVM7m&F;lh^HqAWy3mA;!mOT-YED ze0sf@d=zg^Tg*D z%$w|V?VAIl#K6u`)Cd0r4q8b3qtm3@Jw&B!`_p}+?D;I;H#6(KV~6>_?!1vV_%4$e z@|79Y4Ij{&*In9R>5)^|wne*}&yMbDSa7e|7)hx%-0>#!MEBRSg>+8%EDtJzX zT#)1ZN)3T9Lq1Z?+_<9N7W9%7r4&jllrpS9trWd5qEyTil!~M(GXR=cDbuN`6x#P` zpSfVEt?pN(0U+3}R`{;jNlH?3vE4oP`5W$fGxxl&b9D{C&A0zB@OEINuVI7*0=bxU;0f}PM-g} zzmu%=H|+VX^5Y8Izi&K#;JO2#FI(m1n~6T2=OP@JI}dL0?As*m`X#nIEzU0c_=N(2 zH_m+*>Kr~ePcE2dBTSHm0wdG2Y}Z2;pIBk?*b$abFA~-|IL8jsIlVxb&k6+4aAGH_%@mGF0Nr6t1s)8AH#KO&p0*lCasLzHo`<$DZKw zi4$zBtP;i%PA-RAFpDBmDT$@SnTMa?Q@{L1IvceijlR;#{B_DNz7qA%W`p|zTo-9W z{H&?R^#|TR>+d%afJ-^hyy3NLoLllZc}cTaEAYhS5q9k=vuE}oqmv_?TkEh=Pr1C& zBFW_t#WD*gmeHeC@{^N3Kgrq^2c#X znxqh?gpIZV{!;8l+%7~Z$=Vk2(yD=;volcxN)t6=+umF1=i3H#_J`)w<>7_TWB2iW z{Gji!Ur0R6zu5rZ5T*R`{U?boF7BlDKAG~{nSC_uf{d5G*m%2U(_j?62u~~2#s=)4 zH%mUQI|ipu8zYg#q`e;To_T_HlQ^Gee07=a-TRp8vk6OK#T3(k zeE;P;6l{m`5B8<^@6U8rN>gIW*iUXA{5&Zxopzh`%S)U;d6ILd&ak?+Ml(*i_|OR+ z{>^ui_9Tb^WWXSX@9*id{z(r0r=$DBK5&Iq_6%{vj%IQY&QQ4TJN%ivXKA~G%vXqo$EoujPM_XpYb_+zKC72&NH0g~ z1#Gsv=u(MRy$uKV(_P&l*=&$RDQPdZ%C87xMK94-`BUOZnG_&RAWF%XOQ>FijuJ!E zX?3l#rxy7)3J(zMnIx^X204GVYECrAL|VeLK%nOi)>f}?&|cf-%VXobtdzq?umt=_ ztH&RH_CfUO`q1>A&cK8BM|NfFxw=r>hH4R>`*dSq%4L%t1Rkgqg(ZBnyHK!c$nuIA zG#cbg-$&TR(}J{EBHyf2h*!F zEp(7BkL5xe|4m(x5>sYIz$BNi@E*fV83x5H@KXE1v-!TlqB(YTj%NC5Hn30Jw5|x?=AXP;6dYUANQkje}_B(-(qPczt(AUrNGi4uE{-MW68;3iNZRfLl zwVZ55S^ercQ5(l(-)WBc?H^3Wc-tsdRAZQ|_~NvwzxZEOB1y~Kq5 ziBCmGgKvB> zjE%$6qEU3Pd)Y9N!1c!v?Y6-LE-k|Gqb8~usY2L8RH~>#9_f2HQA|FHP>zGA6{0%A z>{yAow!!X^Nw#`z#>%5~(vYp5;{9r+Vu|j9#LhC*mFtB zIkeWeVL~ULr&$@L6o;&b5o0=G%+;LU?4YzHR!|W!1vjQ0OUhnMq+q%%xqimy;#N$m z6wOwLiK%fz6;4x<)F^+FB&bxO9GBka7HO+9m>6^gFQC_KGjqdHo*sA{s+M@)#pUU> zcmLrZ{L>qN@!bxGkA5GLcLL)(qi#9G?H6AW`eVmGk#U}-Ydd>v4|IQ9iY1`rvenQf z$X6jhYAy>!7^%SSNjNkM2WMb<)R0G98&P+?J%}0*XOa)6@E`oqBd})J?T0|-f_+u3& z5A5agrA^{gk^=3uIxzxWt5Tz+mWDGzQYtm$({Jl6q#|mOaW1~(| zZ$YhP=G1pXGs-*XqiZeH#U=E@hN=JeLZZbD7#%a7RbCc*YTJ3@IcREJ-U-nYC@c?uZSh#4;lhlqHuU5_D ze9!FbavZaAtk;F3hi$`93krGk*cfVSi=b8`nwUUnh45U8NldxjqFgNzwjz{HSPv>B zQJ0>Q^6iRJ2UReoc~E%d^7LwAjFl*?;^5QNkf}b`emq$bDl3izHAIZPyxRLd20}6 zC*i;x?4N__aYI_k);nk6te+juAiT{Y1K(VCEy2h2t*5u3pX=Hv!1Zukj~jP)dB$~* zBI89`DxsBD`O>L`efy{JM@mf0%`kOn22m*zCxX-WE&->94Kx78+__AJmQdT<;wLcG?1>FI2C8=O7^*B>*iz-kpPTz~`nk=r!` z8m0uQb-&79FVCo3M+Q|& zQqWUvCftPl$X?owZANvQrW;T$6xeVy?d3J<*g3Yu@RdBB*dvP0BMqvCJEa2>8`AqWw%*Hz};yC)>|F!yyZHM zNXfo((Rs@g=S1?scYWxe)&R7&L(1c8DD?`$*m#>>WH!H``>T|nRQX}Z`-_36c5LHG z5LnMYRC~^jtQ3_Qg6s$i5R@P&gI@;U)~YKNn4W+=yI^h(#>dU`IIhk6JsTnTLs5q@ zLat{*e#iF>2H@M8zh}{Z*Fgx6?|beVm$yoM`Ml4UPERs9m1ksPj8m6G%HuOs3e#*S zAz|X|VswD8I}F=w5_S%FH@ch65mcA3Z*aaNMCxO%A1MmVIU0sizJdpuW06 z*zTC`R@prat(Il>Wnq8YZr`;E-)@`Qe%EZ|rQL$(JkvyBN*U~-)iU^yv=bVY9qlwa zW~jzmneVz@HSXDkx9U13|6iRd`iVm&D2J_{4R$3cuce^BMo_(W=y3V1Rb%+#tYK)Rp zbk{zF)-Bem|Net!w{YkSK!Z`^0MW1+L2TT+!11+PY_V>pZ z1}Q>d`_O~H8ib;W47{Sj1%f=3Dlj$yGjlL83)L}WK-|pxJAGr|_#UqBn+U-7?JR#6 z*EPdE9oMCjOZYc0-$kvZ2?{B*bCVpIe=3zqg>xHSQduGKB-?ceog9yT@f?wGIrgHv z*l2c0BE{;-1-2eKO?RzE+BIY!e5JA$55E@*^MRh~F7}Y5I z?r*xA#%YVlr&+67&M4PV-$Z}WNx-UmI{k8a^O`bI8g4vh9@FWX^C1e&a?w^BcFh@2U#S>FQZ5;0 zVY3Nwgl@G+T?enxgkk~Z2PB?H+*0_B26N?rZmUaqtUznC#@^Wx7J@MXoziO5aC<3E zu1ZvIGU~Z3L@nCg1gGHBZbwX(UFx-nW~Aum1IpDhPJM&@a-CkINjg$tPcVxs6h&XN zczKOj33{of9vP;eFCbB=nY@;2lu8Me`RF^HF6DBGBuPmUqx>pP`oH7n2v^tav?gb0 z9ov8)wAktK%{Lxp2B_w8!5=(+_97p7@0b5+4M1}fO5S%x09*N+px~=2^Y(G8Z2>!^W4-;oo%=ovjAtZ+aHZzj}n&5_&>qy?g?_ zBsKN^A<$37%7le!itD(P$IJ9K>yTK5N)j5U77P{;+N#jrd4qrKD8`6E6d>$;Ks5Pc zk@3CrET24sQmOI8I$MgFEnp4JcN_KwtGc?~LG8cSHJ*E<3^yG&ir;C&{656S`rv;G z0c)GaVMsfZz_F)Uk{FOTpC5$1E30PcXrm5eW5y61IfB2rfym`hp3AO4QW_tpxV=rS zI?EBMk*ywHkYlycWgBr*yMQ&Z8iel!82IXB!=dKnGW9_LTB;#5i;}*iaGcwJk>c4xQE0{>Nupe`d}T~l~{n|u?A|IAjb&pCE)GrNs86(%M+H zT&Dac)OT*ak?;M6r}LACc603TKD@oVX^)Q4333*!at5T8E0!wkxGfk~^lS%PW)Siw zGRO>xCBSH}KqAU?(-G?33bkI2Ug{wnhal(htV3Jea^nr`nU$PbE1-Q?Z3dLaio|Ka zsYiRXTM1k1Ew&fxgsq5F31VefVQH#pEp0OT`tN4@iSwlOwlM&)qL*s3%p*2){9{W5 z(s8Ez%7pt#YObe47=VbUUQv2P;v7I+qGpT{#$*T`i*nR^E`(_c%5Dx4!RA983 zLlF4pf2h>Fx6KVyv53>_kqf&>Avidl=dvg>wS0-h4cK2PaK7H)y4iVF)>kR04oR+x zANNS379tj;j)T+bQIHB<$g>qgr&VJ;g2@qwF*hcOJfe7;lBhFXNSVs}q;Zkzc!@Bs zQ7!J{)Z%&KFrk~eL`lkePotDT3Qdxlh^mu-whX{t7*h;flkZ0fNt_U;2}zuyk`yf+ zl1{fDL5txOz+wXRW}D-;9Oo9-we%*-}O&x002=LJA)7}1?HaQ?AmeN zH1JphAjP1|$+d&`9CuI}^gOuZsl5J$ckzb6=P5$)EJyO4IiFXJmUzM31bg?)B4?*) zRVs8nZ)ljsP+6}(V|~at^g+L&$f2J$*u%>W9%olIB_g05=U8v%S=jLS*yH0oaiK+} zlw)pkl+})8Y)_v5KXZQ`BujRkcY?p`Ypl8N`S$nft@UcJLZJW@3RM6Bg4jrc5Fk;6 z*jg!yBXz57G&W{q(=)Q^Y15c>_e_sQ(sYj~kq||Z5J-?BBm%@j5Cp2Q)n4`L?OW~{ znX!j&_ul#AUXSq1dMFYE3WS?Q#*&c{p6-6mJ?A^$`OY_=)wEjBY$&uAq?tx$!c3CZ z+T1Hm981a{dk>wPYb4KHu;n1L@+YZ6X3FONia5)VnMS8}h0oNmw?CisDWn|c>DqP4 zoY3t1p7!h4og@UBgQrf>+G*0>vf;TFwnezmL8z4Z?qMX5S_f|LlhlOd58MNDbH*WQ zZO%iI!Juo5pImr^5dfH96P}9*0`s2n8FP))>&ED7Rg-2kTLx275-Mdx9HXT)f-$bc z#8{1Fv%!6{i)6c7P$|)Cw;1zaqu-@es*s3)iL#)NhYl)CIGSv1idYM}j%K+uMkpNm zQA)WS5V#dCue1n*U1rCP=*Me2WfrR*c#C-6IIbuYgv;pGORRJ~#$}J5@<1nqj-o56OB_NZ^P>BKE@7d$#jzGXX3XqcR*%>}QKh31)a-r2d z{oK88|201UyUjP%0npjej7_frpBNhbKEoe60AVjGr@#Yn3yibCf^~VjsUPszeP?;M z>r%mtj1Cb@0LOuMID(Ic9)ESb!jlVA99WvinVX?ouMv6vXkUg7!5?X^7o9?}3XrD@ zVQABXLQlN?8{v6q*P|yxUbtQ3*S`?(uRfRXjpsAAyNaEb!}=|a7kDV`k||-3V5=4@ zrD^(z7pLh=R%tc5$h8JpKQYLErfn!_Fo877NK$2t-*k*vBeYR~R0V|}2~I#JtfEXl z%>H{s0Im=my89d(S8p)r_N+8mVVG6k#-@s?fE;~i?t~Hx1U~YhS*0<5ZjQgt;qx6@ ztNyU)FzgetdJZQ1x8QJ^z==~PnwS`eb`u`B4_aL~e-_r(;Lt(XY2X|_ytFnfSqtx)|Q)j+c`h^Yo4 zgQQK`i%F$qdCEbHm<_SOn9vN|5-sUct_4&DNTJEP1Kf(>m7BXn!bj+cR66uCNjm|@ zahdZYx~V2gZ3-Y2QJhinouTn(QX*xBmge`;by2;6IS;ObaJ)iAz}#Pwen^>j~@BCv33uv5?1IVeT#c3#EFaq*Y$+hKW z-ab9fL}9v5-o@(!B{Y-32?S3#f{%qRpBS(3#QYRXOLOSCX}YxFOLv%XW)+< z!Z2mnha>m}Y$10XmLOyH-$81Zt)}4l=TlyMzQ=2qJKVh0rrC}S=o2_Nj)PLzy00eH z5DgOIC^Z^?aYlIT2;Gfs6Xj=l$xos(yXs2|#ATM+D+>mxY%|Z8W%lI)EV<;`J||EL z0+!F5=GM!vktW$l8eB0ld~L@ELEf~j#cZFnCKq_tgvBpRlG!Wmr$ zLfG(scFN!eJG(ajZ}+4v@SRRMJ5e1P%2YSB#B3hnpda@xIQY1NRJ=pLt`}#R!V$fb@SNGw>(NL=N0Fql9dq+~lgqE|uyV6Ws}+$cjc^4@J9O?kfVi;%TOG6Vdmiyl$52D9 z>Q9!3`_kMyr4awvVdUCY!2xJnHm&VF_CxPmc&;_|@iAr&9OTAJuNoWIVmN!zPGH3- zU9xw6V9_zC%&hux3I`9^eW;joSXS7ZoL@f9u8f#S6QcHjIxeDAhRtmz zO0Xt1UL28?eHP1O#42L9t0}99gB3w6Q>G?7x~WU%d(4d2sgWY^h@u{ggB{YiPf2BH z(MRenD&axey-hY-gW;JlPC&8Vbxb;^Y>i(^%Ms9|X+r3@q*-RtKPAz2z>Crf>39ZE z&6S&+0#)1M0k;)=?9?%)0N?lPzw^@NSNWsgd-2V80QKo>i2W4-Ue^sMiWmUSaOT`d z`NS(2qzjoMy1mA=tGD>_?JYjliukmGZ+Jdyo(lqk99*u6P6JQ5f{&Mc z{>ns^w=GODvowdAouX5zlDh85P`o0BP#oI04}HxEPy38(WFXdhghp#Y97~!zeb#Tb zxqY?CR-;c+D!~iaOqU}NHM@o_mMKze{8~y=;wy&Sg9P2{+m+ZFe^`F~ao_(~Ddv_J z32QZ0E?u_2Qy}auU+rx;AhbZ}Q7T}@G+HuHuWQELE-Z{fGc8Q%E)VIQLay&Rh+NJU z#u5MkfB;EEK~%6MuL8LC7`An4UuP`#1-e(buk<-)(Lo z?!O1IwL@jBLMwJya0N?^RhS=RbG^y((jv_?;`EruR_5V2C61{GRSG##EwimX#=;0+ zM?_LkDZ54?IhE8Z9%+;i1SLA%CTSKCc>z1pXE~76#!C3XA+*@RBg4Vx;>tE>-43bm z(uz#_m#M6<^6Q}!kV-O0BxT2}^h!#Ulw?w)^LAn(Z28yDcpNqejpW0lR)>Xq&+@j= z=KzsFZok-AjZa;^b)fxw|KWdo^Bq8^p{Y-=A^2-|bO6K0dF@#gumGn(a&SftAvZAB zmWa|6-D=Zb+vK%d8+>77mtXJ2d`1ht>3Qt94ni2LfISYu%nI}ol+nx}I0L-Lg-?`x zJ~mn7(S<3dm*!EkQ?$z!GRGY$<_xq2%lpMV4ID%G3j8fGAbMA znD^&%IwrMk8IuM#ie5$bp)<-IOMqW zwzg?%pRrz>ql+bOY;;L8&1SR1wsz?EQ(B!AAq1!AmblU#5Ji$w#UrTI*y_a$w2Mms zsbFe+ikerZ6qXTg4bPpTH+X@u$}+E9y-rKJ_-T($=Ax7h`|Z71{cXKpDkBLd6}~VN zg=A)0i8CuGl4($`Yto=%f55OTXv}kMe2kwzu)u`laI@E6dgk;)zsDc_{`#Bi0E`p3 z#Mt!vfzfndAx6MbDJ;;1-F>AX$L593-j#J&qqf&zenCnJag1uV*mD^i= z^%8y`hi6@vmTTn2JVxoQutP(Q4v3%(%po`@1V7;lK2i4hxv3hDEKW1IG>^<3f^bJh z;S^A8y{}fDQ)Tx6bGaih$3ajqw1Q5el8_BDl4eZWjL_X=#NoG6ULr5|DP_L9R5cgD zzG15D`wmAdj-ETm*6JFaW^=ER=jUhmC;D}GfXJr^OJz9v(^H0{kx47s=#EzHAV8E$ z!yy-9*kNd$K`wMrTV=2 z*ci#~His6+X(bN*L6;<~8UY&NQb}Ffja{-NC2=ymvXAKO;*U?@CIW&I&8=q%{eVj4 zIP2S&X>;2CNre8BgUk%a*i6AGbNQ8iiL<= zFVHSfjdqWRAGn*-j^OyjnD`gZy;j$s|LkYpd=15CW@?f7%E zfI!8uDIMj2;LzyzA=WB405vK_t#0xB$`-%ZX!C1>jL+fllIPKL zouT$euIQR455^&ADhTEfoEPvuPw&e9H#yX0^bS`@gl+}w)6ePKfcR|NLC^MXemOGO@tH1f2z;!rs z?kqQ7yF?sC`&RngS6HW^#c)cHP$QMNJ@OIaL_hdP{XlfN^7$GJjd}~45dH{B1-5TUgl?}##smh z{&ZvK*p>U={;T}a@84N1_lN5MX08HHAvm<>!W074*rE3D{RE5iRL-5D{Lp=rPThqw zF#$@UdyzS@Lxa$x#*xg5TI8W{w(qgDw|oW8G8ha<8%@?%H~G%W7N2Q!`BWtNL&xQ! z=Mg!)4p216#3(|j0P_g$6@vGB4u7>);%Db4x$o#Q;jzPPFU->q%cgYI>5OXPG8;OC zkpmbaYE~mf?B!40iA=S}8Cu*#SdX6@xh}jff4epEYNgEbi4$CX=@n#tEOimwvlcEe z`FsKR6BscIv@-u+vt)L%6w*6PY*}Dv-SlZ~q z5$1WCnrcRtm}WBv^SMI90}mL6;N+zFEUi%8E~33lcF%oq?KV-Z&dH+-Y$lqAj~-=Z zr^T5QXGzy?P?cROjz?In&`Mo!0{pa(>jsR~>bS&c3Dn2&(-=P+kojZGjhAtOisw+S zxKv8h2)9l>XmEM8%Q!a(TauU(<;imdZjV>4Z=!IKS~5se9AG)IPr>gRj5& z4xrP}j7_g#Dgya3Yp$y##VM8X7w4=PrNFJ#2oEe$K7Wqz!Se)14kO`ciV;SU_;EfX4%u>9Go5tkzLiZyJ_cn(W=D+$rV82L>O|uebL*ZpHH5 z{(HSIl^Eg-#)7A(rx=@?=lZJ`M!(-<{Cm8B{Y={ykbkyPMtq~)Hr)IB?t{(E0ya~? zZHmt`1(Rdu;>>X#*G_N>TpI;Au-k$`jL0M`O`3C^Sm!V^XDQ>#T-;KQ%Cgm}p&gHn zLAPlHMY0SrH_dEC;x;23-@(7N%F@yp@n(~ICns2yk}?`^e9>@_l)~$^m@Elo6d|&N zy3|DdK5oB_8&v6Z`shl92?2eXF>p%^oN1IBBBFKbZ=mbZz$7yOns;t0W&u@8d zo~F?2GuUcyb7g}+U2E_g%^v?D)qK@;x#hViVT|5z<&1F|ILnMBZzA|_*LK+W{8tP} zl_n-MOYMGSd5Rzlp}TF%EgJ3{Y@%4hFW&F}`{K+6r8#iuAlmg=yMEo4;EKjy$ounL zWLU7!)-TwV-?sLO@kw*OHaCZ5Q6a<~9f9yH=obbi9VnFihJY_v+A>xf!lHh5Dvk(4 zoKDN6YB|=D@9Wlv={4we;lcah+I2W~jIh_G>?&sJlMGrN)cg^gR)d-9IB}LS<|*2{ zO+uNX0)ex+K|SdchT}|n87fQh@JO`62^`Ah5`$g`?R(6Y6wRo^xZ^Qdo~0oZ5*c%( zyhM}<;=yfBPu{?(x_Fgi#GQ;%b(WheuhQyg#F<8B8O;>pBt}X}KT)7F;{Y;goq$mV zl1dT?VVj54P*^n6mJi^0CJGp`UkmI&i>s^z0iQU2ms9XW__9kSo}Z6hb0B%?B0ni``^ z^6oU-qM9V;d17&fG>;C_(XALIBxZt6Z)1zAx7PW}T7!Sr>hs%D^EKCF-E&bw;9K+{ z0bbUc|M|NY&{wV-WHye5-zQSbk1wVs1qU#6d-{7gjYN~l6dU&DR!GJ zb~ZK(D?hI{{`_yWFqJ@x?@^`!Cyq@HK1A&ugUX*dgV@*}^{D6RKvBL*Dbo$;Sd9VU zj+}w-oAV=bGLXd-1W+zfef!(Uc6ZTn!f+I{9~!JD2Mk?-w=j>oaSLZ@5r1cgvDq=U zU%iGW6S@M%k^yUT%gnUbX|FX{IC_eB(C4nXGEpmIJn-2mRq1sj4lhj5Y_+IW1T`TM zGGKYCLTk50pO8@0Se_KAGCkl5bUNB+tHN_M>HQ-Hu_$WoG;n zSQcMyST+K9!&q#8YjyrOuc{QCgME(&96x_IE7xz(>vRf^VN`+G`=u82v)F`Cm`F!S zDuX8FD#Xe(T@A~6lM`_26g>aDMV^HPp=_7tk;4Yab3LW0XrFp|gu}B5p;nn!5B* zgqLYT-l*k0RUJcya9#GLK>Ofs|Twpy^h z4l66LwP{L7S!#|_npuYs?Q;zA$T18ZLXIJ%g>Evry)6~*XujhuD2YxYxR*4Y(8?mhOtFBQ=2HQ+stp@8(;XrSbK96EP~ z>#w{9|I|+VzcK zM{h8S477%^sx1fRpp|3jzkz3K+KfuVmMt2uZlJo|QS{*Z1qYDdgh?aD%doNw(sm=~J`YHF$m+9?xIXOK^GX=LF;rj`#=75QD zms%j{$b`xI5*_W(9SF+hF^>C+NjD)Z`_vspmO1RS`sgepiX^kM;5sMqD)aQ(SGcy( zW=Ra_X-%AFWXfp%Nv-g7LN_(@F?+G;1<5jHuz)P3>^ipam4kqzp`th*#Dn30*I`9K zXcrqj%TMFo`rZG}JgZQY$yTu@392u-h=knA*mfJ?TQh zDGVJ#WIiWOM~)%K6yjuW|NCweuHS&~Ja3|ro|VKJ4D9D5!ze?frbKDpW4=RZGbc_A zSGU~A3qanmwlDUr{uELK7#piIfAlCL)O2U-gwx}cD^_7 zYm00(HfVHOR2L30EqXMzx_Ck`Gat}xXQX}=Ssf=%2823csjgT{GlUjoZk^rK!Kpf= z+pCQE1LAIsr#e(777+e2E?r)^c9lptD3uz4mn=i7lq8jO5=q$;JTRGZVaG%UsZ9go zR1w&`OiGgqWQ+u!h6_X-jrcVAgy$S5-fhvm?`}RYR^{a67{B}Cg_E0y&;E11`}Kk> z)0^c0AjbkeIeNkFnJoi_2M^fQPuS~R6i93q8?fXVfyP~2BKqo=G4!|;NI(^Uzc^pD z6GXpn8b`J_%&p%v2P+2$ilizA3*L|lj*2KjVbt9#$?87_RUYxVC21qWa& z6+ax=`XFRBDgoMQJh^EL%XJV+8)wuTSS`hDoe2Yp*lBD5Vz<%0hK`?nQ4UQ5VqRT*`-qQ(SwAsQplheF*z9`gbBmvraT7Q zO-j?V_`bmNOAH)MZLrHkxkW9Ur55!NgDn!zCCUI9p=8E%B_Z{X;Q4}=FTISC2~ul( z(Ptoi;xwi;kfd2kKS@X|UerwrV4&?1tT;wnP-{~WkeGX|tRqb=h@IzBx#PD(VdTap z-+lBEJ|CyN_^D4Lwi*YW6Ziao^=r?4-zCBC-vL10Dfr1z3XosK60J4i;RC~Fo?%|A zi;)1sv_NQ$J3r6htABilFDg2NJg2uhx?minuoysKTcM>K^+OcK zR*h6@tg+kIwHAgQ=(;Azv8j*BGz2bbBQ|Z|N*UuXg>Y~dGRKICO2Zxu#_GsYh?twP z4nWX8aF9*cB{+GOtk*);e8eDudWoPs&Qi5R+V0}l%BZP%raBD*SK!y{)Lj=BjdD|z zR8-0yzVF}#4kZs18ZX{usP9w>xJSs9EGOE_L%V`saG zGj^DA1ixmJ|$<7@-wWk`ZT;o;Ci|&IL%79RsHnq2mrK0oo1~ z)fNcF6{d@lV$^5ZvYCW#k7l{X=CA!Gyz~+xP3BSh3tWEb=8wbyh_UG#2=N4hBjyGB z3&$bbY!IG3iIdA#4e@}2d>BQ>oW`G@Cwl26RNgOs$4vtgbOG6yRx@7}_yN*7hct$` z4{;aL9?0Ao*vMcoFo4ToP>2d5^O{W;hIm1mf=mp#MM?4*eEGkg=iP6}04V1CnKX{T zI)vGS%WSS~Fc=hu!G5nAf01*n3hzDIu*+nPYCq-V;sJJ=O{Oa@Ssb%486ehoP~#Jf zP1d+)<`|8rK`3Er%A?y!i4#e;Cy63StCJas!-2IyN~gVx7I0`{9^VN_y*mAJz}iNO z-L%XR|0)${z_h!~?P!vzi86>8UcUSsrKC?J1#uR!k!tFp86h6(n0CSNV`-J3q!E8j zl%k(V>b^7V2gr?ICWl1EAA@`t)^# z_!~v8yRdwBB_-jJg9RYNl0Oip9W}=ThS9LXo10_swLkfDe7TJZbZ+!{Xq0#C<3YW+Rcis$qR&sA@m5B^|dNW2~%wm1%n@U zaJnNUBt!Yv%vuvjd{oq!(4Q4=Bv%G&XQthx&mfdYhXlOM%s6 zHEcRhoRY7X={D z^Ng&Uk|X(d$1%sdS|&;bN-9GGZtj=}tk;8T%|rmcN3MhK&dpO9tJ1x310BZ<)5KC4 zVWR*)lLUhV*AeKM8ngYB#?mqerNYhn%nl;DV`EhNT`IMZetCjgdxxwypgzBh?`vqa zIJi_t%Y*~-WkOdXv_?1?o>q9eL#vr`a;(mnS7wm*aZ5g>s7<5W!0q)3$`S2YQ*Pg; zyEVWWi^-Vc;>rpeyDeIYK*|(HOL}oclBQ%*l4M5kBT3~@147!NAgMI@ev(S6fomFq zY)^n1R&dO*qSqUBisp@TS!yZtMfPkA(ZItm_1L)ar5}w00L0kTRb1!461fsjK28i! zSxRu&aE7!Pr2tywgrK~wz`6vj@D`Wo|M4GxpL<~=0+q{X<>VY~BZ3^UFSPa+6>;aGI)c|fjn!B!m{`D9lHRF2k3jeHbn9B$HF+BYGt4C7Yh5u$UqgM zf^HWApD1!ov(8Q%(d)Ai?6A9Odi7_PN=(lLY_5ocR$smYMfPT~doy?1R*EdkMuMM1 za7r5t!ShV%bZZ?PZIpn7wiBWpqYIEJ+@)pox%-H}^>zEzdFwc)A0P~I?IdSi4e`?q zHw=+ZNaT4;q$z`PmBln+XZa8_Y07fFP8Wx%xJ7xlgYIlnPI{1LbQ*p1Af{S(*cSzkPvTs^|_!YmF;({2?I&jV%WzPrB#}lfC`%P3$J&HV15}RZ*iw1k0Jmp|%P^uf zz_=JXf&n<*8K#&1IXi19f6na(a{#sJTe$AyxX#g0Dab|vJ5Br($8f^{WywHVh*7tz zbrhno0tPcP3|@Qf`-}o|Ysrl~UqP)5*02di@72cpUV3;+8e}XugW^17qC%#2jnS z+y+;mm11`@8yfTBvpp_d2pLu$a>K@+uUyr)`1;ThIC~90e@}5_{FW`tN=f~(W5`IM z`>Bbt$|edZ%}fy-J7To@Z(lDMzjZvG3zZTg3uJ zrawNx$<1{p=jt?ZnTWfLsg&wuh~6EbqLft@e22l#8uRgM=rp4f`}BJWho-uOWk`26@F$P6v2~g2>n*0sWol`c%|Swz87gp2 z0p96G#4@$=?bN@cvjkh;6~riaeMq}?MY;RG(h(K3y9FOWQRko4#8=kI>-=XoXG zBFQAQ1_rFTI>E};8k25JS!ej62d$J4L3JX)i8Wy;ka334no=O?bQ03URIDcIW#X!b&^=V8 z%;2>b(K1EIgeb{asO~ZoZsWKERySg5)62+sgI902Da(kp*f9J|FMu)h*kS-?0<=*A z$}&x&wABX0$bu!3vhSLuO6g&XaITRf5Ehq83#n{g4ahNpTuxpY94o9W(BAylKN<%B z(A>T*W|!WM=N=m&$L2y(tv2GwVVqK#T)|gh`UOOR#A5J4jn;}_ewM+j7m(Y3(TT`* zVfX-@mcbLo$8Gmp!MWJTLMllzRUvHmi09{#l}XC7PrcKpS}IX* z?{a2#j?(QL_;rt11kBVl+3hweN^yn85gMTtsdNYefg?4ZE18)TWRb)Z2{U6cv6N&b zpLG2e_+=`)uaQZKBl|>2%5r6cR!>nG++w@qFtK!ijqL`vHu?_ zcLJsgS2!$}1?#;ODYfMTm`-y#%xSoJ-YiDHf8C$$L+!LSX^ZR8e|m%LJ%{O%QoG(K{=>^KRzmzwpMyph zrs}XX0}B%-mlt9*C8-GX<)6Jr17Jj{CP_^ckUJ}d!5lQUkt+Xt`;k^xUamIC8eN7R zdcq}3z0q@5pm8a3?}aN6nTEU18CtI6jsQa8?70^OvJcafaCi|z^S0FhjWKQ^AXBt% z_i@V=n3^GOcTK2TF2k`?uyV^d3n5@`);@L&$;kH&v@nQqe2@N-Y0AwQr<$>_(d4m1 z3-ni4d2V`!$!?pmN`>9}Bu57W;@u`**~N3U4JtHFBne82YDE$F8kxk@!j##`l;x>D zjvgZn6qTTYlmiykWyVwsMam$_$dZUKYLI$mCgKL+;vsIWZ*r}nNYO-DMkmV{Br&~A zk!GnW0ZPLFY$lpPoa+N%oP*Lsy0%OeVc-w3Yps+G0QIOe+wGfhU(394VBc&9b1$@p zED@9|4&Cj~{^%UQ&cp19E2Yp}(ryR1s{y$^}f`vWIPj70H=;~GE z=H?H$W4RYCP~~!FmDu~X;VPXQSpHl&2I==4cy{ zvs#AP30RtinF%NbCIZPrwj#*3KQGXFq|UR4-kYxsh1Fk=9H?;|A>eZ0u0B!fATwk9 z!ZFnrT@2q{qu;NEYkDmlOUHGsTuPA=TwMK^=3sf={;$rc<=b`e{VuAVLamH9K8apF zME2f~zzg3otJOpI!|IwL5GA&C_|$ROZkWgQI%tKS8iQktls22-hX}vSgsXAd5#OFY zKokwQYjT$P>#q_`OFVZ1r?Y|A>f)8ab6s>Q8JqTrGLY?r@d?wdSFJ=eHWlqQGfLgKoz3dc@%3CQO#$wT%LzUI51O zRKxdRyao%?us8$L<7UO|^a|fyhzJ~u1%%;VGEnh?)@rO>z1$uJ00_I7Y8NMKx!$)!sz){_#wXh539C=ClDWjo0%>Td_aN{5|+ zaRAc37ArGDa@Yo_H9F03g8(h91Aw7{qilrL?v6AhEhQM0k*iVd@fccp_?0Guoj=on zes~UG?Z(aW-}?uTJEih5*=q06*%zHIYGEFy6c!dOG1_T8GD6cxrwL|eiLPA!3seM( zTb@gag0r#r`VE}G(CF`!!wb^277Arn+}q9JX9`g?3i~~-bwFCfTOKe3nOYULcMa!z z_+5;gkJ7^xdbnqzxFi&ezsN&K5?U(*b~goCYK+(kFrokL6+_`fA$a?P@Yz2w3{AmE zEW{C}HMkU-GG@7qSFcghreqvU*QmbqD*nM^v?TP$##y+1jq!MwT9P43g0Y<*vcH8Z z6(SV4nGpsJDjM00aYISkNpX{uaw%bVN7L^sLbpe$RHj~=rLL>Ea)Y4%G#i64CY%jw z&L-0n9dy4zSoO$u6M|#E$Vz9OX4fOlVzMm7lZsZR>8G)w`q~_StCx^u+LQoOO{(;8 ziqy!EL1zlb_t3UsUKh)}xjtl?AfjZ1Wfg|K2&7$H6#`{gtEKuOQJ(pi40iH2-f{ck zIRM~){`G(J+CTZk&-|^YJ3Y29Uj^4Q14JDM-R+?cF4+q@XVE!@5O*(QMkqzFv_$Vu zevl{td!QW9_Lf_kqxVE0quO>ZYGQGUVW&+FVuI2N5&Cd?4lZul3P8c|^T)3J%%|RJ zF8C+k0XJ^Ji6h2?-&ie_(+a!n*b^RxR>ZTw2iVgGu$P2nKEg&17UZi>W`KiCDWLyu z!Qk`ye@*~0&Oi)XcSAUP9BSo}b8~Ws>Oi2`*;EKL0fKaO9i8P-ih{HE!1XI|`MTjc z*l4GE_#kPsZN|i>sp%9fh2VQQVMtgC%)eL;3061gRXwB#m|lOC*=Cn`GGwBkqUs*& zr8zv;r`m0zwZ>Btks3{Y9j7>fMh-HBj+vf}NTUpyWt6;xL7cHPd6-xvY~B7U6?v0h z>eGlTbkjQ1-a4Wr=w}o7VE_|9!`j+KI;l(GhxkE&@A;G*he4W=BpFefk))b9Q>2+D zmD=S0QXw;}rr^i{SbqDvLt)>R6E#XMl0(kJ)2#C{aA9F8fxP|b^ zpN0=U39np$sd4z_UxZ)y8CaTUh)L`T^)d9=GzAnmIqk5p^2>r_uor}O9V5M63K5=z zTM{fE=@Z93gqFWwlx!cO?{2{f88}vJ3>bO$3Dd&6zhYv{6Fo31j~5L{uHQs!IQWPi z!YTy3`l2~L&0SMATsi<*M(^r1^ZRDYS8k~%UsU|KlDr(W# z{u6qG6*{doq%{0}jYfEiQ0~(2D1z2aBBkiY9*!5HbPA+qf$&_ya*4w;GaQ(oWodSn zv08=DchOp*m9$F0X7v{Nkk%pVQz7HT0)UoiHVWs>-8b^bVR1Ny)I zvn=C>>Hq-#efR9Ne(ML{Yg>1%1HB&Fb5Y~7tgcUk>u~q^Cio88@oihM&FhDQQTOe`*?I(TKp_<;=VD5~|0 zS}A5{Q=zhydby83F-6ty(`{a&({GT;j5y73R3A^bnDwsWjMqt0Mchv4re$h=m27v1 zl1x!rqIE)9r^G6yr&4^+rB(@crFSX6y6+%}>7{w^lVP zfoBJCHapO0nx+V4Mk*;Qlpv+D#%7F6OJjWA;xeUs?)f3?nQbe^4*QVO7`!a3_L&^X zkY~zv8R|U~dvy-LI0F9RzlYrze*GW8;aLOT{p`Eo;gcg!)2kq^ufVMp_{Q_-W)m)4 zGZ(<(oLOCqTai1EH-Hp#{yaP^l7)(qgX_Xh2fP6N(VwNIX2AD&>E(G4{-~=jk5E#J zD(4hoG%U^{PMsJr{tDOEkb#KC^*qE@gLG}fIQx9KB?_)yg6Vl!UN%t>+7Mbi-`u;N znFElfW-?I}0T6F*6SrD$a~uD{Dz23Hn@yyr=})!sExOxJ}r3jd6DaS9dt%zr?J+ zj;l0lTUF3iy0tpvl?lB1BykWSJdYp<@jQ>7N=ambF9g#<5hW2)rf8Mn2q>3)W~awF zc3^?i#}9D)&;m2lb_>z$D9_D6XZTCY^#Alv ze+YY4D4P{P!CbS@DA*JMxq_lkzUAC?Tw|cSeK?4YIdAgt^t@=E(9Dq1c#QbL^uU!QE&zV+%SN(O=Pn@B7Zprg`vCe zH;qACo96t_Et*zk*D*V}xMX+%#oh!_NS)AT_TF3_HB%>SbqO*_d(5S^RKxca;=m+Z z!3>M5*Qx3hr;|{f@L-VO9Vn5l^+*R1zKD>!1FE%%okm8#r>KWr+{z?vC28MUV<~u< zxo{n=5~jQr0xx4iuJKZQ8b9q3WF6`U??Q5z=U@E_WRgS~$?sHVq*+FkW$dP=;U~*1 z=r>$jv~2_uIF3sYR;Y~Cs7%xeDpkXOkS6ih!Wmtw!>WKiE>fEAzdKyjqYKx*sxk;` zcTt}FS47R|P8RW|IDp^%U;pK;U;LGS_`qGKPMrGmAAcQ{50KQ_u)nHRlc%b@Os}j$ zN->XCw$o1GO-_=otROf3!s4fQK3usIDAwe2KyU~K=Et>wep|6qgmnTh-8TIJ=MTfJ zE$F2X`tayE#MKoO{Tw@J!v1dG+)f>Xqle(Z^Y8~>vVHUWzsDZ4eDZR>`rpa;b-oT@ zj5UtfjOWqq4rG$qr5?f)q_GckbEehQVPx3Cfzu~o!HjvswZ~!4a8GkQyf8ptUqM9? zR4Rt2UhEBUJ-B_t_Nik+eVIZ~GE(5>ib(?;$2`|^X!NEX!ZnM7fQlCoDvj6c6G%x} zO2RZ_vOOTJf~X&4etUyjA`x+hZpBQV3Q4cG5u}uZl%$su2GH5+;E4#G_8AL%g!5zg z-W-SJ=ef2!OF!{(vIhOgCyP>CM=%xLW@}Jl!fP`&dxl=-a_Pne1~Mg0BZL}_0@Jvp zsVo?~9y0$@C2|(r_2lanD8JpNO-0!=x6Gt%JP|2Y6d!} zG)1Qpl`7KyfZ9)e;Ld#eKVuU@;Jgk)kmS+D5b#S2V4o_0e}(XW&r~3b34n&pHVhII z+D_O!&G+GvbLdtF-gYm1>6>uw6g>MXy#Gmf@ioMQ_rSmTP58*W&FAiS>p2z>r{8ns zACVsStr-1eWMqzDYipcd*M^WA8wK>==HmCAgPAEanWt9ej^oJy&-0O&Z=eSe!FY+O zm(B0v459=lRnQs0`+gQG6J}wM85)f@H-m!_$Vhiv zsLdUan#6N(l8kzz$JP16WNpFHl^2kujCf$mWJ0F6C51|3TrZ{HjEQ?Oq1Qs|1Xm1r z;8cVDAY;2ZK!_flf#yW{d9tKINRMV#W+R#4YG;CRH6V1lRE~H!OCQ1!A(@OVi#0=r z6@*Ti2&>Fj>VU#`T|CD@sl30$TvJ+0hIv2AsAHp1Iq;_yZYf~YB$J3AHr~S zzV~c}2sgh^dZ758X~3Hj0RVjIQ~zf56My%Y9=`Yd>65?t$KOEZ?X(J`zEcX#&Hm$B zj}Df$f}6SkkhrxPa&r^8{{2lwE(H#uFAVzox`S0XP%soN8IfEH;w8h{evv9G*wY3* zHx8*nG|Z~YnZpJ{_`nnJnJBl$k$X@hX^To-xe23jeE zBan$?u$!1tE~C&L$A$IVi0hX@2ud>^nRcKZ8>cxxiGJj5aOSL0Y-+a=w{H)Xn&ocO zT*{8X6@s7|f(yw^1;>GU;Lr<73`*0SzIhEf>m#a~8wbx5k4-S$TSawa>XQ;3M@)>R zs3bz@n5k+)mP90R#3At#YnNZ6-B+~YGD64rZjU&2nN-_|EMZ)#NNM!VGC=z9l`DZ=B8n864n~9 zxNIb?=I0Gt@PS7RB{?1#2b9E+rKo6tsE*UUZ;`Q;U7T8(?d7{!?lu^U66$oIAM)@6 z577;Lruu#STh}SoBqcAwkr_cKNxB0(CuXWTAnB)6ykYWI0Z%;& zfA3>B_nt<4@ZE4^8Q$?$*k~~G;kTMnX>LRXTOM%@_8EU3CFSqc#gM?};ww95=;e(Y zh(G*1BCx>U{0!W4#u&2W*j|7llhJ;P@8b+&d;MfUx^=0q_0}5*!f%rZ;$%r=B$^PJ5>|R-A?NEjG#5m3R z9N)P2twgRzRb`xHj;%(Enbrp3l)^7%Y+oPH+3B-=yNg3aE$HDpZG4)HhaI9`8v)dv zZH`qhk!BH>x+U7NWFzr8EY~?U5hFr}(%C7flT@+nHZi48CvJ` zT!mJdjb=^wpFc)Rgq8>;O?a=R{dO2hkiD zou&8(4iJCynIH0A=0@bPMtTWz>@+c=n&Rr)QfO?Yd4F9=wS0+d8J&gc|ddG*&tM0qYQ1hl&7<>ir%pAfLT z0LKp(BANWYfWiw9VHvU0M6GR%sKNGoM;_u1Kp`5A-(|=vQEX(^5a#0FX`Az0tHayh z1y6q+W~QOF1 z#Nu>HqoHuCg3^h*=w83cD;K^=q!NN)nKbF5Qi)D7`u%}v2C@}osq+f6w(yam2xm%> zw*r{8!_Eb;5kcO&rUj@$!k!M*T;D=TGozu`-`iX_Jo!Z@FuW)nyi$+2wMR1SO?Lp# z{oa3E|Ea(Ji}$|${FyWV?i=4Gi<1!pDoxFPmO{JIW+PcIWl1|q4>`mLlQ8*+;a!elPJB6Ho*e%CiOd#)Vk5i-kJ2Pgw+7R&FSCOqAi>gI85pd;( z`HXH4P9B4&pB?Q^@f=z#K)B9OiD*9o^v?g2`8#H2jAJ@>2o5aS&&*43xzo$lgI%0* z3D!2zjopz`+g}mMgYru69;x6${mvpy}FESir zTvvnR;i@iyH(+I}M0b!PvL24^FyU_@RF@Tb7xi+=c-A4586s7bB28}q)29T^)JJHv z6E56*%`|q}DnODZ#7Txs6={-@L@`l6A{s;_iKz%kEiBi~Oa#g-16C_F3?8M*37#hG z*N%%E#Fj85EY4!1zZ@`5lhMqH*Ig|8HkCn8J5IU&&xt#E6Uv+K0089K2d@0}2k!Zs z*Q*uh#b;k+G~reoO}qM-SsjJ~i0LrY&S{idE0i*6fw!Hp09%0;S42bUC~BFF|f zz9JdyptBCHY~u<^XAnTTOWAihJM|JiDcX@#oS5y7sm>;eq!}#H8+5rD!$4{d-RB`n z?_mAvr@6i{Kq^g=#KYWP<~o1262fa!$aVFn~QC09>ywobWZ`)(gW+>PO)K{_QV)^4s6J zboF!p&D$QPHa|PU0$k68HM_e7)zfV6q+hG!ucHJNCCDfy4NADDPXFLL_PWh71&0ER zx*#HInTo^bdaocu5eu**oH&0Rjvs&<>+r%AxNsG=o3OaZ>cwrixk_a&fXClKdh|F- zxbRQ@p;Z;S1E%1J5il%tA@?&;fe@~BRun)=d*R?1ArE0keHA6X3q&5LR6<`hioM!3 zszSr6K~csF+rq8&5I2yr3h#Tr0rn=RM#pLpqhDBol}(tKh7bQ7y!D-M^`brJJ>wj; zFk&I~37nU|i&rlhTtrFIc8g@?8sV$Y5icG=E+6Mwk}-YaGz)_^N++OWPzhQ^#JwGq z8jxmP`tdHE-Wo}|Ns#$2X2CUO!-wr}6CdL>$!6c!buRf5(rTATe*Nsp|*L%h2|ytPKOyFuD(qp}#t zaLm$fumF24Ic3Wd&1LJd#3)sh8G{ZzwCCp+2zM+4jxHdGyJ)TcKJ|mcU;IcS0Dz78 zqZj_p+aLKmx9Tbh9r~gomo6U*hxG>>R~iMrqF4Mv#^MI>4hJ16flhW z&Bf@5QFw1V`-a0mbH3~##!|JfJdmp_62(zi%| z_QUX*{{)$$yn2c3*jebd4NGtzvOXL>DiuO_qZy0^_M%Z=b`aVb<&3Ulgg731cx22J zA|2t_2|o_{>UCq3LxtzUJ@&JO7=AS8?}aOujj?a-;=XzTJs6n$KThEOhhgO=oHzjo zm*FEHgMa(~GgRUECDR;KshcRUS~FSzZ+R=~*>9o#uJaKXKkyHi`@cofoceb|+Z_iCh zwCmvv`sm?I!5`MPFP3)ph4@9#uNXcThh*kp*~tTNV+(%igYes5fd@~+`VQ(>egXZ@ zeifd43;fO(U||NX-6T7AH+=0Irabzs=SMkp4)zJ7tPHxaYBK`ya))If?_n_~DU8=) zd1>$ag-Kh4Qs|pE&3lWz0=c4)y$!1XhmV2hBOZFxtkRu6Bne)ZfnPzyn+Vm#p^w7=p(D;rc9^bJD3LH$t#D~a z5+o902mzI74mhyw3g+hmqQ&>pd-dyFTr)CzQbORC5Za|5Wy3a-EH&l4IzH`04kaSZ zO^np&m6;8ol(eJ4Fp5G^O5E#{_WS5KGmgg1M}}u6A{B*eG(UI!q663;1r)Dqd-F;a zlJ;ldN0b8O+yCRYfA7Cv&Sd&mKJ;Gm!f;5XZ%Rt}(aPulEf?Q>IvTAOpj>3J%;qiyecZ}DdUV#@c zn*G2398M*KotF6@PaZcE;rt{I^$Em?xtA*gm=)n1N@Y<`U8jvY?_xn)WP1K~bahD^L3g34b4?UQi;%KPQ zDfr9dR7!%$43sOFN2BY4iSjD#iCNU*daBuulRdAYKn$n;fGA|` zrsSC*vci9y%)yT^ z0sy%B)i16;`k|k_|HF^mf9BtR=LH7c9zz8jt;{OrxuY3>#mc}i|F#o)GfRv~V%XjJ zAv=Mhg!xEAZ!h1y5dIHUbn{iyB{;lzKQyJR#-K* z_>ku#g3vey&qWMJiWgS;?{$3(H^A{XNjqQvkwyRj|Ljx0{ePK`V)eBfXB*c! zZQ-jFq^au*731m@#+OOcKJlQ1QeD!{v!MGZJurYAA&spbyM2f{DT8LhpaT!rU^al; zuP90ij?Y8+fMV+Kz1-edr{h7%1z&)cnlv`ToPp=yA&Al;|7W=R7rV7}PUkPMwfDCE zDjW=1$Z;LQsYxp~tA|sQhN+uUkR<5A0Nw8q)N3X^dtEchot%JxtcTG2GW>{B0D!0e zm;d|ofBNEu-}$Bc?q=@T;Q|uvnG1L@$P1zd?8>JA=M{m(PX0|Ih$D0+Vd>xxc`pm8 zz@EuL1=L^Kc(7OrK-k|&I5Y*9){Iz)E6{-l|NK?-(h~gI zZ<}tpFaI&T|4E};fEdYj=d=3!&|DZn2})&jxn!J2xir+))1{Ib(QO@p_B?3p!i7uF zXc&@?AB@t1W5*2`cm6)JZ+D+HJ?QguP^sV^K4MyYUw8>lo@R(V-+#XW>ZT`cKZ8l3 zK$*!vAOGv-|82KmW^Uw2lN7G4;2l4T-e{vslV)DPU1y=yG{^F(pW@orzKq;hp(0!O zjTPp<@NelgHj(MTg#KBKmN8QGVf#g7e}yb<;-~?xPH}XE=ar~>CGMVRQ}R7d%y^VS z2moIh(OqJ2Buw2WC?66C2_o&XetE!T3C2Tn8w;RnMV7|Ls?=)%RUaxIcxL@Dj=&y* z(JDW}@P;xD!<$BEiRTHbQ{xtM)^?tuW6onP&XVImKv1odT)SqP>Gp*EZ@>~!S%w_^ zQ}_|50QvS^RetsFKJ|{jHJF=qzy9=htbQEksKxP+05S~!^LR>IHJ>5sq73p-{;(MV-R{9|)0}+I8>%c31V%;2bIrvOhNF8wuudXZ zXD%Sdu485ZoH=QpJHq^(5b%@lGlN2+*f2C-e%VAC{T@90Fgl7LD1#?pX$f9_(R|+Z z>*n}a#bJX}X5s=1sYd6q? z7W$!gBR}_>jNf{h@%}brBBAEQRGgTK8&kFS715;>`cy@eTHsQdJVPnDM2VO)Q;Io9 z5{*qW*6-5mnM)>Bf^Gt14osZ^f5CwbfhteXUti~$%N>;7s~eNpYIU!hFc?VF>|@sn z*9L1UpW7kD5YyJhR6v z#G518Y4>(evFSqOVUj!jVi*kkbAcaT?B;l*cRYX!IJqmz`pbvWM5 zOeh}@5S@I{7K8ylJCBHbb=nu&^sSt`mTARSTl3DOuW`c&rZYT zTjrR!R$w*o&Hr02o7#D)WST=N6_Y-MC9`t-x!#|<4;K<9s`#rvV zz*oNty#XSQ;gLto^KU$3RG$4{L>(@6ooQu0rx-;|Op@I5F0yC7Yoa&LK~z2FPC<85 z8nIJXfoI0Eo97ZH1JD_cD+o&^s382KR$XMwb|FTdu{#17$?m>M4+zD`esC$CJM#gtuiHQ{`#{`>u zCUV`OVx49Xx-OyX(TUZN(`CB-1is@?^<2uXizfsqf%09-wF*kRXzieI(Pl;*8P1+` zL1^%mCcAZebT0Q@v){uZbb+4*^||7Ue`yY2>xFM^ocoENI{Q~1x$o{zzjm3{&aU}I z-Y67X1tVEF(rTZ3)p`^SAk2HB!JDwRmQ+(T@O=JWu7@YMO zpya?q^L2XN2(6)|0(w2Dw>3M7;DUt18pHx9r4SQ>%fH{_O5hmXn52N{=d1p{Xh7O1 zL1`26_hUm6GLVNLlO_VNtbTmQ0Uw-FU>pP<64y8a95gNxXZU^x2fx!JxqS=c((VM| z-H8QA6ZjygFYSN#Uz!5|_;y#n^0(jn4u~)Q$+gvv$% z=TPgfkQPY$dYoyZL=T0g@?h3r1SYAJTF@7g*i&d6ly;HYv&L_7e-jND2jB`9cVmlm zC13dqxXvB7VI;N<;(egLai@3vr8rKqo%bD z^kWaf;yk?c3gXeX!neN#gVX?ZANsI~1U9$q^^`LKZOH$jpEg%`W7|3yHJbXIJL+N$ z%yCA|UP433#T}bMJ@{_)*d$cz<~`r~0tyG`xj&-R*`hjLrxbUo=!8&3gd!nyGD>cW zBVv$!gzn&XF5`#+PX7ubZBq^dbY>z)FUxpx#>0&y_Z+r6E+UlZP@$DTDi^I? zlyK47Lum)4O$4A2IIfR#V}*2Wt#B2;Q2}oV0B!>B2KDUsdgouN0|0n7b}xMViMRjl z$zzAy&;QBOLM8bZggX1~*e!;|ozUoc8RM;GDN2F>fc z92smf`x9qLUb@1dHiKxj(3!@o3X~I?|FvE*?X&e7964l|gTgU+ejfHOE#mzA&#`>^ zF8Blbr}!kvY}tU07+u^_Jku4qV)Ut2=OGN3gOZXfz$VUBUc}q*AjZ=(PatptXy{ zH^z@^SAG}A2~d}BlD=+4-W!>&0K_feU7%ihBm4VHcL2Q$&u<-m+Y_h%#@ik_|NGZ( zvAwy)>!JWOdm4rE2q2%Krqpn}lCk2{tTOwyz_U7@m`<+NMvs9F7Cg&J){aZFC6Nj) zzA|9Y&efC)<-k(F$+u0?xNQe_xDJ(xkYtcC9IKT#+$_`(4<5q3yp3Mjg^4Px?9e=S zikD)B1vqlh4DhU!A?-qI8xqXQoO99h z+`rqg{pi-=Z8wb4Prrw7T|*DvTE`JB0^uM#UAX$H=?~agL1dQ5vvv*A2%4+IltDNU zpePGTsAEcMKxyX&rD_E+Ig8qOl|aWhPKwHQC|AeuWE*Dg!s~6D04+=KeSywk&VhTw zjM@Q@)Cnogr-U*16Cq(K#&bZ|1>U`)3^GtsfHa`6s|BZzO2+GYs0eI?o?N7MQFzAqZ56=r$|SE{ zC*9ef*4n15;q(2#x4vPG|MH(@e}Cx?0N~p#`SM?T&*Oi8;nZ>QpT7L3jG}LxT`JB{2v}fuJ(~1c@%eL8+qoi(Z)M{2-u257xK}bSXq>QxsK;5(nwL(uy`nBu%1#~P1u$dc7u89 zSrhlNLN9=GbR06tfBtHd%|3KvQ=#ofwpfxvFE;nN2y~R$h`>e$NoGR-)Ry~%5}+J> zAvk|jQY(X0V#p;km#%}xM`_<0zl-CR7`%LqwAFcoYY|>={9FX*DUjFyJht~^;Q*q` zFE{4j^3J<{@vRTt^Pg7M*jig38MfsGj2L%nUj&fTtUzdCNIylixr7IQqsdGrcF*s{$k3(eInj@3clNKp{*U@6nU6 zc6$T>4tcTmvFlKs&qzDUe77`?UKn$rHZw!e-=#uKMWlxFR0(j?Hr~m{sE3;9;uldW z!u3LQ{V+*q+kAXbB8ntYFGFRTpIdZL6CRW86!$n}sYG4uBO4iPLjORC^4WLM`mN{q zQbP~J{+x9lXW-TXqJg4sdjgWo{ysBQiA2J{;sA-2mOw(u5j=QQ5e9|Jn32q*#6{!T zDu9pUlxe?sgRI+sgDbH(vTb;MzXIZ2kgfcAZSTjz0RVix5ncS~J0JU7N6y^k{@x#d zVlX7;_&fl~*d9>TQ^c=@{F+B*(Rj~nB@ z=Pc3ofb7sbtnI)fXUu25cHNMH%4HL(mrCrWilaxDxL<&8FOON@Pz~u#@8?$5 z*jTlie|d*f91k09_N@M@=m4+|08@`o6I7NBjo-0-N9qo~Ag=^W9v&xZ#W=2mR+_ud zmvB9o)^0jH^uro#uDav6969W=y`u|h0egDtNfex4f<_PSIS98JaQ{(6cVGsKBpIAo zg555hI{^!Gl+rHM15?B=-ZGPQuW!Pcg9dThZjS2yVF*%kV}72WtAw|uh+<8zF(67T?N{2Bz7XcenJ}*vqJdP79Kb{%c@p2+71riqb_E~WtmO?;7K0(rP;qkw$NVTC(w`N9;n%mp`FH~HS$szf+~Xpl1n z^OB$_qyUQTM(%hDZMcpevE~FOw7+i&QVowDhwom8`3czV<1N-vCk{bd!NGaBwT+%0 zN8H>b^+TwanLOwax0RVWc=fiO5>qy!szE>_)to#y$K68U+mkyLxct^2L$|vlW0Zx} zKedja(>2CFJqJrurhfIUmyP4;4B*^dM$+r8Z-Zx^fhXSu&%ZdT#7J#tUFD5Z*4fD1 z=_owkVR~NDU6mT%@N|q%N&svJ)CcBfdCS`$Dd^UD=0f*8)6rJY zup6n@f`(1hJT@b+3JoCO&IKNv$UXORulxuI|g&Yl2vfAxwaR0aAk{fe*hQO z;M6Q)kRp!F!B&%OW)hxXG2#Di7alo=ytGdL+!14p51(Yt-@)nj%ru`POU8JIxx7L* z8vM)MKD&0@l#k%8z*~TB@$EbFGMy`0?v!?CS%T0+zZq0ppc zyDc1*B4k3~2|`y8&K-dEDyRsVB__uXeB6l{91Wgl2GN$rr|}M)<6hv@X@kPoHU}(c zE!5l?(_X;XQMf&I7!+Ln<_@mw;zWsoo;;x97>!uN%0+nK2H=zc&ouJn{Q!v^iB}z} z!rPAQ&4~1H!q4!BoqpsY(<-;0T}SHd&w#65_sicGh!276@E6>EtRet_Z*25l{m8rC z{eHuTgy?;nb*gXz1>4{ISf5)Pz)0eWy@(oU3U{7Q&Svf*nc zr?qng3NlLqY~7M{5Q%|3klGAvEQ*esMoX2TYPyN;Nyxhylz zPHG5U8n+$v1IOUXs+q8JWyNX$gqHQ^v91L7E>3esfM+WL)zIU2y0H-i$(N#G3Xs|; zAT@RU<$3tf2jKV|Jo6IVcM`6y8Ybcc55QNxVgSe&Up9=x7hi!7e+VvIfS>s&y!5i+ z5bRS&5<^4JsoQdd*W`V(`3QHN;K+!QlM#3lPsMnukEi4N-+bpC4Z(B1Cumz2E*hyVZbejkb)%!f2zIc-FUcH1$%s6k~16K&r zRFeujI!4%2B1}_Wl3J2aG7A5b3{H%}Bg=c6eRKizE8c6@qu(Fr=F1Iq-aT0;vW&L9 ztUrN+hEEIlxF-97xbHu94uF*_joyJ1r~dJKp19}BJG!ocI_&%v`V7-{fte8cqfZ*LVGK;aw>)3@CCEjD1)Gt7NT zsU(`}zc%Y-5&&=D08Q*k0n&VaJWC^=9PQ1S%>5fI7@FYrlrd!_@gQsLapQQmX1 z!T7vDUp5uauMgl{JH-#ddBSJ)T941aaFu~Hy;{RLr`l90J zx&2tB0QvTtzx{jv=Wo3DYW7b)@NOL6AE^epE}~LH7bUHSjV{hUUccp_3lOFH8-8EC zB=Cd%zHoGCo_eCj#Y>U7aQAF-s80}<3_n2BLdXQjxT4X=Kos5 z0DoR+h&M9jJ8A)vgm8S0wqK+Fz%k=Y$}alFRotm6eC}ze2k<8^LEylX_ga;t#0sUP zkV(FMZIwUPW~Fk_j3fA^@iNTMTHGM8l;X-zJj4ixgr*AcsZYbB=b_Ppd(Xq$A4VTI z0aSvx&B;vtNh5ezF!2!_HTLZQikl*zj0 z(8hQ0Rf3ld2y}{1VibS1sqwqQh?Hs#ZexS2*Cp#2?uRN@(JqJyfxb6{lOD_p#0D%T za3zB7lZR0E{t92bS*G0se1}9sGlQK3x~VaCtqh}kQkXR)wwg3?W~Tn6HuryU7VeuL zWraln5Ccsa8FwuJFQD13asBG9v2UAVm|H<1E0=j^6j=(yzXb6~P5J{HKm0gG0DxY- zy6YW3d*qj&di?%x_WE4Ce9inKNAS}4^(8?C*w)Wc^NA%CIj$uW-8l+KmBZnqKD#@k z-~Zf4>fE@kNfXKSTM8|+@4drHllGKxMEPW01X?MYTLTb+se2c>`AV0(r*mp~fs+p( zWTOWhtHbRMI3QDxj^m?td*HeFv0_Z64B8z^t&YJ8*4uDo#!%7H%%GKFV2sK$z4kkc zb9^XpDPz`*c>(_=EU~q^IVuO{T`g&9+udvwu)cwK=Ud>)3gWKQ@Y(+Y_upp>`NT2k z^o(-x#5hb(nW@5!hUptvSu_8mZ4K6d>gLYVin=IG{VtcZYf6E_a}kaP6@$oNFrd?D z;}H}3n$TBF)I5Aw;d_#)V`ovFO=?F^L3ew|2Sb3EUBHhc9;o=-KiHy{CTJ-ctbaPI@D13I1I&n_yaIUtlR*DN zO{)1JZ9kR{0N~lR-pfzC{n5Ysj)(8_e&b7DL*;05js+y~D8|aASMBeFD##((I=o2* zzDK&G^&aB~@G2g+Zx|Y|>%#eSB{nvV6F7G7BGt(qy)#`zD%c?nv_5Y z&OKb?=F44lmVgjAr%vJ=I)KoE)_e&s5j;2+(;E0Rk52M%x=CYl3=SS8=ye%OHt24~ zj2|DTzt)F`j)ImIVjcobEgpusJ|6auJeio*tU}eRKjc#wlPkq2P5v`Am zKUY(>;eWD~4Dp>e`$*8~g?;~IR zW889;tkXhhD_{(`agWm~<-KDu)h)?OR|6JWlHCi?cERmAq(A!!bh^#I`=h5(2M^KT z-o_CwV&MVWH?EO+WxQ~L&9x4Vu4cPq8Z&phMysVafI%dP6L{MJI5Y;S6lB)u^ZOAF zDva?5AvZUCRyR7}fp8tG#aJ@PVy^BytQ-kbNzwwLz5g4;|74ij{*bmGTL-}AjooDN z=&^tJ-gn*q?I_~X#Vh9ZVUIw(F9OJ8FGjp~Fi$jZ7zOxNHLEz_cVlf-i`7cg*fpxH z0Ii*v&Thn0ADHImjTDvG_iD}9VioQ9^tSt^3B`BV9R$d}kvjA5y&Gq48YQ8VfIE|AJ|t0nq3T5$dd^b<2pN7*GONeyo`v<|@Y zQE^OTX`T=IE+tG9a6rIk!wSu{0v3?Bu;pN2YFUCJLp=C^xkPMJyI5O;2k(R1x8c!8 z;fr5_C!d6`f5Q-$u3rPJsOZ}tGeRP{T2s#97*UPDFEiKx4B@KQiiQgBY5zrT^N}pUmKi zgD_V$#xLz~&-|t^prI6yA#h7&F0Hz(@ASZT44vDnn44cR&vWsXA%RSQazQ!&CshBx zdo#@J$JYS>FE<7k9=iXYzw_=#A9R1?%YTZ@vf;`lG{y<+7YG@S>Q*D%B)=E#9ixCe zTzjKU72aTmIx4Qb+(9Kq4oqml%yNy{r4qMZ-32WepL7WVkHFEmE4l#-TzKkdyGPbAOdD{`&vObA6BQR)=0Ug_2K}X?ndJ)fYo@PbQ59WVf4{_Fk(% z_tasSurqCQ3PhH#`uV+e08XjGE4N^~(>KR6s6bGMpbCD)U_q``X3huC7)(on_}>$? z|A#lr#(u0F0Gl@(&AGz||M5>g`QYAcn{o{J_cJC6c=VmHdeh{(X^KGO z2#Jg{(zZ0l?@AygjU!YNQwcOqr-e@1_^v|k+=47JW8$PnXPV%^A*#yjUNB? zMuVktNbH2X^GwWm{V-WjV&Y7X2``{^&pUbfH~)bD_}vwGo1DOM&ROQ8+lAS?p3_q+xI0iw@ zJoigRztIb9i+Szw((!QJUUmciP(Q4fCNoo0T3@0+W;HfG9&M~@hV;UqDU$MGZP_?AmXS!iL|%pUl_ zPs4NHGSf30fgU8tK{6@@>csRM^xHT(p*B_F;B1MvobkAEYZp%^lpIACYwEMJxPArV zh;*xo+}I?IV%}eed*12u^!7YwRyHZ$3-a!ivK!$Y3fR2slXRc{GXMMwt7Jf&D3W#) zccMm|WhklWc8yYx@;stQBXQ`(nr^dCFVU0){KR1hJwhQH`~5`>>U7&l~!+J;lQuF|J@H= z1YUaXCA)H2qtCH`Tr)5y28}3Kdx;hMqJWQmB;@*SL7Lpz3&=R*BOk7?x*>=oNl zwf9y8M7hF!f9+AWF03JUI>Z-Nm|iGTK7I(!-NWLvOD_W7b*-?l%l(Ue*1A5f&;&t% zgU^*$uF~$N#B*ijbQ$^y>8UxKD=ox{X-bVg&Rb8AJbNAS@G-hC?U0^agbhXnROxk(#g(x72O?mLZGQ9N>`1W_rs(#^B zSXzcJe+54J({SS^yzOnKi}37OlQO*H9q`%TgQtE1KJ~8+rFhUm)I&tYGqH4~5 zej7*$-3(tCKEUc)4>f303Cm0@&f&&As$)~U<(`nu?LI1!%sp_9pY87Qv!@m8N^U&Y z;%EZyfd7Ac?;S4LRh@bN_CBHF&7pH{wNfi~OKRnS5=cUzY)N1S8*GO8jA4vDJTrp> z;|JT=#`77B4K~;$5iF3w638HdQ3OdXbt|iLtGjRCzWLUzbi&^A$KI#TxmQh=XmzXB z^VF@nRp*?lQ+3wbE4=Gn3_G0+E~_9)d7i#&H=p?KUSdb05Coy75y13#!wl}ku$nhR zK^Q_K&}kD;Q`6zVrOT}oW9$5}7Oj;((x8MOvIaos%RIWh!Hfp-osjQ_LYIBq3HcJ_ zN@n%%n+I!8hW$f;XrT35c>b9${3_Jz)o%cREkl#f9e>J6@4WiFGu_YKb01-&p5ocj zCgYqCttZujS>PahprpMxQxSN6t0s=)EJ722#S0ydS>>|!7@vn8)l5#BRlho&CI|Dy zJmr$0(SXhkYZ-gwxmFl5|IFi9ebxyq?8~!bIHWrtv3^NJ5c^aciiYy(^cBj< z#SZt-A&#Rd=b%}cVsOa{8l(Fmt|Q`zu7ykKT)l?=T$S3y6jKu+aS*d=?+Cx$P^fjF zmwBvq70v;{zB*L5HW@g5fQRl@eDc8&qqw0a3^k&s2Ni3YjhL?aK3YgBHHR<~)M_!! zFzxs6_280a=F&+(K9Qb%i!DkpmY{NF9@*BQiZF_w?}kEh>oUVqawW6+&s)IhfA9hH z>Z7Rq;0Fyf*Yn83U;kC<)?r})m>M465qm3s|Jpa6x)sgl$2OT2JYi`JnrYmcv=FzT zrx_#ADhW#4dmf{d#_{HKs$x*H!=s9wdoW6POv2iduKn6byVgHni` zk9*2V)cO}QF%4_yRoQaDA&4Y0h-MSXVD-R zIRYQ!EX;S{OE@$~$1}J9OKTejEl`o+`Ilz2cd2B)s3$fVSY6E;;(7zlSZ}uL>oe){ zjgP_cC&T!tp#^*HDa7QYDQo3@$a`o%XJEsPD(HZo{u~1fa#RmYal*yNGWo)8L>!QF zVCDQOyC2!c=!+B7rUUF0QuZrY8iITpdd^aW%OuZlbLd#&(SPf5_U~-)@&6cyPM`Wr zoX(S}HEA|tWAh?KGgQn>DH;t;Jv5p9MhFXwaPd-F1RgEd9~1kB!n*$wA}I*{GLLMl z(Qq7ep&Rl&M)8Z?Q0jzYr*Z%NJf$Ve_@h5~KmTXpJeCjiPJeU%=$rZUr@sBGRIS6q z002Y7m5s}fS@Z5IFTK$H?A`aGThoLilZmcZGhBC>w$zr)N%IQ{kxAYq+?82LJmX?_ zfo9EM>fUfcjx9UWet=ESX|_H!MpO@RT!qM&S@)I;I6yZNO{5juMqC`BaD531Itu}3 zF51HZwTzj)`zhrr%uI(kNIUw^BT_)G|;cT9!apC}C-!$RA2@DH@ zKutG@_SIn3eA8@{K!aTev}S9u#5G+7dNH|xGJ-wjB9HGIoy}yKtp-H4ZTE#OaN+re zsd(*iu=z>2>=M{*8EW?r!HFlqx4vb(t9!l!|NZ@N`&Zz`o8hlNoHqJ|b^xsBn%^XB z8v5|4LA^4=)PYGP0V7XtVZqV?`UX0v2^iZ^K`XZP>d!cXoISbO$-hPF=wI-~qXD&uvcx(NxiU%);6G$x}0D2)>KeG+)GeVbIgff@3E?{A*Yr|-Xg8v#V88@t zEr+ohJ*Uni3_DP}hm8UBJPQnRX*2=~iw8MRnp}Vc7CP`nB?-qSXpyW&aRwMHJGhGEYZLGL{9h1{D(1_7{roeG| z?@^M6o|!~-=3!_mEeX0VD8=@22iJ5K=&{MbPT=`sfv5M4roDVM;C74ZD?W@ccu4y#reA$|MZ}iXDGKaw6_YPWbghbRRLS`Y zM+rO;qvHlH+Hm`6=&>wa7pdT&UL?)T&Tx!dVO8>}3|gmyPwAt@xn?2)eN~aDh13+Az zoWAezrR?0X9@jUJ)ug2rWmc9bO8xi56G%jB+ahGJqr&sdh5lo_0BPC3=k@?~9XlU6 zQ>9drG)sM`!KH-S99L*s-1+9q6|6h4o1zmDQfAM_$7wcVG-gzk5Sm6H%~)vL_#u$Q zN>XoxL`ourK#ewO%8<%bg<=EVb>SJ@_pQf~T{)NxnE$#JeCy$HRIE&+&S(Y0iI7$V zszF5m!T~l&T3*0_EBSJuh$p7gTtK!Y7=)=8Ffne}fJVnmSD@>fa$utY#~o`rcKKy0XZRihu?M(F2=}=|sZxiR0RX6no2gdbO|$73ZaYK1AtKv~J5zgU6~Ic; zaxJuA(efgTmbi=_h<>aWkf3GfN^^9ED1!bK{p62dL#1ZNwp(Hnsil20MQmj?sHt$Onh#v8=?D}<4~Mv?z*7S!bLU-SJoSxn zzBCrH@U)f0!l7BIwfgT9h3;6kjNTQCn0#@VAT~-JDyTOU7yElTWr;26VIxeD2?4Mx zzc4HRu1Sw)_csXhK4HGkB>alqQ0lcSzjgcFJg1y>CSSekDo%7=1Y$dIp%BitL#tsd}=Qi|$ilbP`b^Lz8e&5)57CJ^F^#F7PIzlKz03w8jxJev0akb&e zl{R1F*y*^Qgtaqpg%8dq18we#;0KS5@-I=y(4rhgtdWtLnM%_@L^KFTQ10$vbjMy4 zFf~y%NkD7!ZaD^yoo5nz8tXlX6xSb#?8@)*+_1xzktRVQN09G@f_42%y-?~(SAI9o z+2@_dmoB}8qZ}6yTR>kVguCldYm&KU4?_`A^I4>P2l>38D1VE1&6Nhxp)(zUnpR7t z&P=owtrs1L58hs_qG-1AO9@9Ghgh%>?3{LlN#Z3(6+)o2rlY$XIX=P2v(H(!AV3Ss zG8F+G zn`Ga*lg$v3#fwar;Mr#xTJM{0ge}`)>kBZvzXVDr001!xNklIich}NviL{YJ`t^{^;w)*K60Xz?mKLL9BW|OyIVFEVk zC$y%!Z-8*uE~fVEo_!1}XD0`L5W0TxAJ ziqLFvCT8XlC_BMPHEB%OfCyAbxMwfH@CYi_2%(s&hy3}d=68BwdKJ7dSfsisHS^xR z^X^p5soLEwbRYKm*7vP%?cHskG6t0qn%4l`vEZ}5lTMlL;b0l)l!U_Pkt*$rw))be zry;pXMSVCHYrDSVCUMd%u|#Mc-ovzCE;-`d8i24)<|dW~kiu^t?jQJa1ySj_fZpUZ z3y8hAMt-4mxJSuEynIRz%jm0u@9_0E4}q!^|EJgY#)dzPp;Y9f)NZTuU-j$k=k17n zHl*H*l}#Re9(KE*ammKeZI0bdWVUPN_OFJIjhbqgxv|5p-Fbz)gNL35?}s;(@FMwW z5<@(_ZuJ(QmG|h1NV@GnVDy`0l7MqKq3`R#0L#qk#?FW4`c5WMtL|R5yG0QLmkgS@ z88)tEPtQHXA?A#q{ya5!9p_%!9vYY8*sZpGwx!GCg60B_a}Z|njZxIH!tQ<{Tc_^{ z?(x^qt(W@q7XUX7O;4(e!9|aWw@*20ZUiQhnnbH;F!wc8_r0EYZ+w*+Tywi$r%&k{ z-D|_K|E(_f-jB;00fh?l#cGDvwTd&?liK%~nZN8Tq=)1%R_0W<8jU64NSaU#^9HQU z|1n!$+w>tc!AO=)YbVeKUHr$^E3G&RWln%9Y2B<$BI&FFtov);A zRNmIl2`}N=3VDTZS|i;rmEH1_NH$nEuSfsobiHp}Yik&9*iZgZ1*PP|E*>5{!(a8i zPEURe6KajYw|3&}uax!Rrl;H?ZpTl!nj0f*H4IG;Z99eH4~K7HS6s()*vXVi5% zwML?wzT?Lh_0fD|N#}c;6g98lF}_>R?Fgcz@pvL>RHb2%eBNaBtVedle$ z7_t_EU_uH*8ST}hH~dlq_r5PSe!i88p(-3~Q!Zm5aby%;ZafqIm``}`z{R<+JEZzm z<~`=N%=64Dx6C~MXbF6NtX?ICm)`XOi7>r~+2l4GDqZYIB1+DW&gp;G=$SC!_l_Wq z$I{cg;=$J?bif7WjvXgq{lw31w43Zn=X*9jOxZtsmAHMIP3y@^2VDJNGKsXOs|>j} z$v?8=Y4;jS?!B|u5nr#X45o=>Z*vzP?)SJtHDO?&eLS*0buGL&#_aR(y}TUPu&jIe zy98bIa}ygiIv8(#_(fZhVvcsi1rZ@TIB~y8*|4n4xz%lN)MChzRKoLv ze6BFE-a?Ek%Lekv6JM;5Yk9~PEWA@$f*eA!o1yL*G1Oo&_6il~3iw zX_7R_YxI738mQc`-Fnr2E@^Oz)zpArlPka2VpYZ`T-^A?r}(&8!lyZ!>{9?&_={i? zp53l6_2QcJ@zAw`0kZ_=SzN>wzf1MbBPL6(rl(x?0hiT_bCZcDgu@@wGPvj$3XAbu zQDnE_n?7wgN@=EZCQ%*vy*9W^A2#n$WJJ}2+v|BH`r7Y0R>FZej+MH#7N^x<*}gaN zNx#SB&vZWapdw7t))0R!TbrNW*EmscuSCc8xvzyQXdzM>TO6_~+WEtkRQz%ymd!TN z{yIPH(+6{dZyPx0QRinDM-rZ>p73la>XNeSGo4i=v0-ujxNYFwFn-&#kW2a;Ucutf zo8R5+F*!!;3lHUgvQCe_nv-iktfDztBM2M~%lfLQdGltZrHM(^q{@|VMOm)!$}Q)5 z4NcsgdCQ0{j2opr{+=$RT&v@9QQXGtsU0cX%h_oaVF?0duW?a_Er0eK_A?cOZA#Q8 zsky--ZjL98rU$Pq2l6++tz7VJjr}cZbAHyE%?`&Wv(vCwzfEx2PX;NNG->xGXj|=K zc6AxOeaKza-%%C%lQ}ldREM4UnyQEuL1Jc!SGtNPzY%(S;*MIgfg8E_@f)YLf$HzC z)`ax^56||0Ief)@WfK1e3DXse9Iy5bmh|5S7e0ms>{^#s%KF+U|5g$omR>(Pn3e3Z z4(fVv@cWU;Q?ro3V8PKS$L=BGssog)h!p16DBFDQ!x>I88~*v~TamRb3_D|9x?)x| z6_Z0r5n7+ezn0V_XdD!8Jn?0SUl5}r&Atz^gWqhPcUQVbDio@^TRvB_HH-gaeV}&d z`2NO>yk0TG)lc6P?zWdw#7KEw?|jSPD#$oRL;O=;t5<3-x6IfKOXylgV?xuT+1H6T zi>-g?<==B9wfnf?{#0$tv4}!_AAk7dq|`B5wNU2riQ@&!ucP+`e*N5)Y5dgbD{3C& zYjEf`cIbWarLuSL6h~Iq9HJ5nFRK_kLZYUZKJS?z_QRe_QkG|iMb^#an&?o*gHnAH zR|kn2p5K-eA10#1?UQQx^79tIjo$r@;#>J{c5i2&=s>ENEhgsN@3)*mleBy(O($w8 zgF&uCfxmVWGVi1811$X~{kI+sOM02J`cHAC3;n3r*>F0yrnnfO)$rp>jArg|UH2zHW(h>c#gK6tc-V zjw^IHdpeX@T-CroYg>6|uzC^Y0iH2mgl3ic;t&yq=RIG3-FE!ODz&3^An?;Aqm60D zWRF8)CM(0F<@?jS8) zqy1pl^V6@WQGrL7e+?~prKdQMj1Q+I;6z)m=@T|^J~L`($s2ulLa~mcA&P^`L+vjfpbw%1Ro{4<>m&ZJsi@*HM0>ux`L7zfJOJNY$; z44vOhzL6t!5O#e+m`+1=y#QPPQmbbxndr-RIwH=1Z@=_kebc{2iO_sp)23s-FDy2c;Op!G7PWXm`biY1E_3whq+|vp%k#&*f~vanL0hpR%*B+v+*X zRoE|Lq|O9PVI%)2)H5dCb4&J=xi}Wp_Tf))%+GF8rNX)i=eY^ijS)9CJ-YYaJ2)Ad!IH=YfM^esk3iex%GLCM*_%=p@hN$;iS ztq#dN!~PimQWc$8 zDABXsiFdEyPUmOfroC1fm(JeC{bne+-+A3~ln5KWyCS|f-z8OEK0!0{%{RAgLYOY^ zX(0uD#=_7ii)022mHq?fA!aeTxL)2731C%4@v*5v{*Igj`_k{(>8`p54HIT5$LrU` zeb0$3y*eU%$}cr-BAV@7(1TN88b`6d+bzCf*fef?o&^X^-CVEe;V2ub%T3PyRYi|G3sYwQnh&S1r=1 zq9y81T)S5#C;pkO4yG?V6U5cZ2RLZ`Zbl+iZp|}`YoCXT}W(4L@b%(oE%MlRQ(qt~$_i|T}v5%{s=j320lUas<&H71)N zCqLWTEj+!=0?}(Y6Hl`fesd8RV)H@6(g~eoR8&FgrUs4oYr6sNRv}wP>`DwZpSDD zL}uKwkd=z-li0FnO5$rT;5T6*$2}5Ft6fh0&Yr~efPUyKh9{|;HjJ*TlgL#3*E`vl z9-ig8rDw%)#goYTJUnf?6v}hSlVt>OIKmI?zI0!XGAAhBD#$viBEIca&LSHwt7h!4RNIjSIwKqMepS7zbzK6T5|!TWrPy`ZAJqH zi(%tl9Ttu^&yOXg;O;jZMvSd$Io}^#%X&*Fa<&A!mu^#!^P&Fi* ztlKK!&2aVI)7ia+$z_gE;R9TeHEz4*JY34avppo`TGwC6Tl z;i+g}%6uf8O>BYhwd1!t5$_zKe}*qb3Rip(;g%^>mC?1Enx|E~s))lF;%57NuG4mZ zb+aQX?5I95(?r~JS%xK)H2p4R`0g^VXi|?95kcYwwv0pg%~qGg+S+-(+O>Zb4P?=0 zp}XsTHsfV!*PidWcXWq?9NI;wY!1?ptwgtS7X|mdg~9v<9Q;Ttq34Is2dA%Zw!G`> zO)?u(w&(pq`ct*p`3AvL@d!CB#L3z6{%t#rGz~k;=4_KBo%^-|*GgxYEVil-673d*6hL+4W~JSL;Vk5&4i-b4ntReJY*5(p3gHc zv;I?PVqfyH!!E40^9O^b5r1L2?TOc2Wsk3WiPqQFN^c!Ly=KnN;%MkCmE^Orw{!D& zpnAp3JXr&SY+(h%;78w-*DX3OY@@kjXO%MZ!&$91U#C~t$_%928+?DkvLhEwMZbDG znG`x0X8Qqahwm=3Bq;8tNvx>KU@?X6j%dFXH-{>7aT%{9q4V7gwBl>F^9ngGF2jTt z4&fOxa|xcgF}cI!;oAx$@Uslju6bt;E>^_%_L>CP4PtceM#OWP6fv`mauYAU5G+Xl zV$oJIy(|BNe}8MUwCO}+d-#s%#*>a(&)r_X(QXwRIpNhf7$Hv3&X4?+`BL~r zBj&26Psv_!f+1_vm?&>gfj!7{9U&c=O8IP zk$~sp>lQxY>wueYEH_2t3NtoB!@bA3@Ihf}ZX~v`6T!=Hv}zubw$Th0-{$~PkO5-^@#`;u8aI~miY5o*u7>b>)^X*&6nc7e4R#eDQc>7>w9PJiQGJ%cR3dc z7p0GJk$K&P)koCwJ9Qas1`=ZKLwZAdY~hqF(SJ6MXBCHbbg5$UQ*gIeg6qCCS%iPu zCAndL!inKKuayRd2-@?x(=5&?jxl;Z?7+O(C(AhhAeXYGE(mK=)zMvI7|4s;j*e!| z3g#+sTDvupsjI0XxvJ|^*;nz_KVDtq`Js%27P|oE>^EKme9GkuKBD&?-fWm}Y12F- zsCVC%oFL151z!^{bwYo2c=7S0sJ1^liI+5HNxwa7yxM57muO?O8ext1{9Q+gZ&M^$ zja=Mw@^>^`Gi7J8Sf?ic6lZe;1vl%rs@_|Eo&!H+=hQL2^{}w&5?u z!#5Ar<3HfG?^)hSqm1J2dt^d8v`ntp5`VCpqS&I-r~CPqD+8Mm^eq#=e4=9lsi&XN>29^VH(tI@D6`#iptg6X1e=9 zi~YG=q!y-#{_VneXwX<~mR;UgnORE}k4Re5TE7I%JoC(WXTH=8-jo*XdC|g|!QxSz zTRV1*CN~FNjkIfLUjF&aurf>f=Ki+)%l&+r&)sa*=I2qm(ie|d^B%qoRJQ{wW((+0 z={Kof2y&KE8{Bu)7P%Z&S&@vYeku!YmEH7l^BN>lKH=xAyXTgnp~JUG;QT5q;N?9V z|I$saSMvR%Ox>I7z1s@$oR{_!=`kHbzU=_7PTb6quf!g`33B)^L$kskRTpb(4WC@EJihy~nJhORduUa~$WAV5 z@`=nk)KFQ*+716w{hMNqNb`&Y4ZPG1ZfYCs^F);!R4)}3nmlqx|IC=GwM`&F&jUW! znVwKK|FBiMwJv--Tco*^Vu1T4PqeLRvvZwJRKDcJ=b9JHYq$l;ckTop?D~C@o4yq} zH>vKl=_9Cq6xPW>nG_-BuGS}hhf}f{$sRsTZ=o9y!>-fgMJ~!O$;%6n{WAWx+56k( z#hrw%{65X|hiTuP?)ul4M$_j%FJQ7_(RqRuevJt8vV948YV}P*ie!nXN`qZZjr>_l z`E4e7q5yk86h>{!NISu1)JIwoeK#(L&ZtqVz~dT9IR4r4!4Z#HILDVbJG)_*8asm$ z<`-MTPekv;Ja=BW^;Vbv9KJJN;Z%$xK>YFWnnSF;?x3*WF@7ByOB zTPkjx9e9O{yG5RKw(I-Njn6kb&Y4zyI?=OzSc5A!PJ*<%E^IxbKDTpiCVY{fHzSYX zJ%7pFns8z*#3L!9bV^J9J^q`FZ5cT~UKw@`HMRo(_FvB;#|TI7Q_B+uko+3|JeQF5 zTg9Vj-ff$B<^8Bs(gn-*!6UN147F+QUnmlpYx&9h z(S`h!cPI^wIa7Gh<>{~5Ufl&vH!B5}mxbfn-sMyu_MGR>6}Mp_qTT)N+Y)QH`J-1; z%-XkgD`9xlcB_>tIb{2On-p2gYg%Fz7Mh#$`(M8V%^-LKd z>=lw{EV2X9dgZH~B{Y_v#m5AnEehR9a!Gs{Np9@@zGmZ=N;=dter7(;G2zSI3ptTb zC!aL?zPoEiE=A0t^H2_zM|#suJ8Y-`9}P<|d4Ju46(= z;G9z?bZtuJtUth5dCS#M-C=o;aNn7Gd-3E)>EOZ7Dj9$E=A>x*-v*((x6k^t?$?Yc zh0ci{7m`T^3Dd*xkc{uTdGXt`)pj}ZSyL@GPvV`1y}GVo+=fC;%jFc;cbV=%D9$}J zr8>v6s+J<@@7gItpzf79XgSc)y>!kPA8F#2BR{?bt6$z<9PUiPl$OHUWm@c&#|bythZim49ULqZO>V0)QQ8ZS-#{0> z{b)chNWJruIAEf&Aj?tv?G_eGVd;|85tP-rUttkBOpzU%W%vX`U?E_^m2yx<*h8&U zC2e397~Jo8e&Y=n_LijSt&P^ZG0MU3{7{!FA5*xWHOWJ~sgek!_eVJn^3IEZ`56Xt zCAKOY!UWF#{UeQWK598N3-*klE46(x%Gbz76`BVF{lY$6I!Ab;Ui5>2Vh?4Y+)Dnl z%$iSuBy?X%M%#B8S{?SylYK|`t;W*!4D7`O3#*O%0o1lT15ZEMT>Kbq zk))c82}2pLs^IgrOtbW@V7)|C2qp3BmcN$Asm?qvB1e~;FUIj?7|PySD$d4>tJEkK z>acH3DK2kIY>f@gc&X2hb)YY7Y)dgdX--?q>;H&zX`tw-As<^$njBq~B};_KtKZv` z!EYWV_nB>mC-sJZa>@uRbN#U{eeOt9M^`0%ZAeXR*G*fK7Wb%WUcF6y%D&CeOouwn zoVT*=0{1Po94>0PCxu-sY_FmpiEcz&6I|8YO4RzYd!t9xJbHfFJosa^3s zaw9p&j0wLqd&H{f#iWP^JuU61803%InILJLXC2bri zThsRD#D=TaWOoO5BIQiBRjac?<1Gq>d(w1yeN(dmJmvDF=#HB=z8|gh*flMF-2VOg z&vLsrTjnWX`?1JBOL~c^&jYp$vF=$PYEgCHBgj`ZB3aa{b)R}u3W-^{$nB?FM`rMf zWR7p-7gA01i^o2r3(qw&=t4UQ1rXiJD7w!wS6tVa_(KzuarmlzFFsu8Jp|i-yde}= z@j=ezM-Kw;A~>$vpxuJy)n7W zEXsrKFw2|U?x|G1d1UnygpF3_HXPm0oXSO26fgK1)r1=G@1$j?Z7-~tiWbOCh5moJzsTv;UOcUyDxr(6Q0er z*-sa~y0sJ(-AEPxP`kC}_Ra#%(h6BrzPhHk{2R(N=iGS55UfMO{v|Kd;h2qLx$E9ZDVgpqdj(1<}FKOGhj+Atnf3iCvzummr z^u#m0(PZ&P%tqPt0q$|Qqt4`=bd)RYMsV!Ov@&;D8F!;eY{ z=)80N?TaC9+3Sfu28ISjFUn{IPJYZDfgLiDS6hE>AEt#!C+shi`N!Nz!BD@d?iT%& zly#1*Px=!YoxZGXt`K2x2BoWRC=uG1Jb#7e#416nl6ydGX2EK)Q2JtQlYde%Cv%nG zLX!)&#IzS#P1;%KCMR#$$zP)49tftd4N#SJpW^wY@ZxJ^zV_E$-gUOV?vP&vdEun> zo>|6@GI)G7GGEg=a8k(A->-{F=UfFYIpM|pHV0NLi3Ix3`WyFbZVD6mG>vTVQ74~u z8jpQ1Y#!${M6X6Dc+Y#K`CjN9{`d*K#6|k9g>$^9>_MjLIJLLjfKZd3-u^rIgRdP9 zTFE|#P1Lg~yvv%bH2jD=??%BvcX1<3vboc6=_-?-A{__$#Uh)^V_nI+`Re(As-=F7Qp6;XEvWan0RrimnbhM`7y02D2UwEH|#s10>rMGtR1Y?L};FiG$ zV+$DzUA*s2{8MM8g5)q@7+w~M*++@2l#(+!;pPwS*%t{-7qx$na@ly)5vb!VI`yg> z3D)iOH4x}p`KrzkM#S>=N#ln7F~yzrd)!aso|s{PM(!Ti&D5o)tsRBGdEW*C5^wd> zBYoVLSnzHo_=Ud6Z~S^mOo-#)wcKdWpi=u+a574|=koJPMgwX;NK^g{|8HCURzI%T z@yAQIKHNF@^Dtq1&_(0vSnO+Q;s(aC!-jOyR$@cbMCCcs!HoBkekB|-ro09z3EK8w zT3lIG28gB?upU9^-hKWr5uQmATV4+z?xwa{NV|+^FYW3m-xgX*>7jgS>UP*LBb=k7 zrk~lpH?Txl=5{e_j?|u}fy%hji{AbRom#u zXc$3;a4hdGRXTGL*HDw>R6T*pHQS|~`DH1GpGtYhU*?#<4X#WI*1YAO7v-?LF#c3g z=lVC3A%jqyZWM=xa`Ul5`t=+0(~JIdyFSU^zZEE%NQzf(&g9$*yF#tdC|%_FYZy~v zaXFg2$}wY+{FR*J6jvrM6RUofxqLTgi{{0m7=avt%KcO^0&QXLflQwIfVcfl54tmw zqf^E|z33IDHku^dJ}Hz^t&r$aighB7F#hySoZQli*eElVpJ0T8HNPlue0#q|ks+W& z%s{(Jqg>Z7IrNX!#!2UQZtCGU{_Cc?xE#W+T90%*d1JN) z<4ud-2`bxP{YhnT{!`@7UjG(V!TTp9X4V6WX0}7VwkPt*N^60P2WULO%M+g#Lj=h3 z7e_|ensTPneki0eVjN>{SikrRKjXG6`)egP+wLX5m9ZF2G&jZC3q;pa-rZw5JjTg3 zy*fIhchRpTIv}a&AUgV;jL*m=f@k-16(hB{F8_SL+kaC-Ppb&Uk-*!xrnLF+{WI>* zg6?JEeLhEwN3A!?A3ra-P=2qD#Ef&h`YFoDpS_oFZe;bxDDyY{rAZM8BaHwEB1)ojy;@Y(-nAw>kaZphc)Fph~2LxS^i=F>0I(dnIRg9Il3)Sb&jE?GO@WTSRY0n~V^Mnh)HWLuBjd{aZ5PYZhH9ryPE(Gn-tnZTI`GCF^1`GyX7())$N+f=fd zHMn$W+G5QI(n_3PBkWHuuPW^((Hf^C@zi)qzXY^4LE-n#p<6Ya;z;fWmUm*vnd#Xj z1$FOlmYuyau-yHcbj}g%SElV{?Vox7=<0~Cb{An7^PtA*( zKH&?xtU-rz-%M_7xu>b#tD}h?ipeYaN$Zkd=klC;h`b~_{26Y?tTo=3VE4J6ZAIp} zzHOV5{I0!Q4<9D}RCs8e_c;7j;>xa7WRk6`+2Pw-YST|wTq8;pEx41z)}7oK3+~4|r zd&!Axqv?0UXz1eZ=*Gb`%Z0YBu}dZHT3^zfLP7|?lK$MzT)el^TQ_Py`R)ECmMn~< zq=rLA_5KH=_DAXG{1h~HUZ>#RpK@mm7UQ_+msTo$!7<$AVqFlT&B=_{=bv)%y5hKmnRqJrUOM)AJ>e?I*n}xH*SNr3x z^_%twqD#I{$R@Aa?o#)si6!sS)w!5?6_GZL%y z@x6%DPeS{AS{wW&neu0Hlev9^a0T}WE$tsZH6t(8Y2knF%%?={)hx7T_be}B@s(`e z?ZuF$ynE{*I&&TVEG2gK$7k%yo4uzxM!8ITiQI>Uk@)PM?uRI052?sTYIyswT!FdN8?iOKdN6Fm_vraAlBxXWlT1ld(YDo% zVpCeeYIVemK>ft~NaV+KQ;y-NFHd%!?&qUSjyLv%YOpfp%uk%-^0^8xMO2^Xr|Gzs znistu)RcGoXQ+ZFb;(zDo2=D#{^IaHlSpgm-ZS(EZa`HW!esYn)oOjtzKq2 z`_yvf@Zv?hJOXrUgE!wzpIdj_@@DidJ*Fqoi@VxuEZ;84u$oG|ho4(!B2LWimHT~H zZmIJia4>7(_wR*+AZD|LK+?`@1h+}W4oB@ImfH-*?YP6s%L;7k>S8Zj62Eap>WJjF zD3@_bpZx6K<@^*$DuTYj`YnIOFAGlT)6zg=wRPK%ZW+6llWwNbbH6ICGnoqA&&zlh zF|6AD-Rj2H_q!LiKh=qno4HrVC7NBmK5{jmdnRPK?z5@d~KEa_hyUVv8T$qUXu;=a_a zZe5&b_tCKmv-Mz#=(4B|Tz~8KC~Tm7Adu6^}hk^t^Dj)*jr*y-??n=XsX>isjk-lAje;>gQc9&>cuu3a~cfN}ISGH`Fkh zE@?>6sECWBhRXzw2~_lB#0-r@36|}i54h!6rrSoAycL*EA{9m1nhdqnl)NBmPvtaw zy&Oa0_At1MhL7#$=UC5siYrOWiT*M6jDauS&U=n}FaN+}b2*}V@OF`EjeJy#$HgYJ zJK_a_iWP&-OCV9*F7%A-MV^eA`&Rzys$jv@indv_LA{IBtC%M+o zv+hsdRzi0jS+PdoKPYpi*XAX5zsrPI7|<(s0beIu(ZI#jn~a`GJEnFU{bD5e5A&zV z(cV9dRS)d&_B`7~mF%7hD;vZ4*YihL5;mP^24sZa6>EyRSj!~fjZetYW(6Nkw zhuWEUM)V?&()71`E@&Sq`>O+S$M63%T4fs-$MsD|#Bjfy^uUhob6WnPV=oY{$v&O0 z?T(8^pg?J|6@P|Eskz8vAgzJ3s)Fw6r%|1!p6-lVj!9M?OuOq*y^lik4CG1uamEjh zMSni#uDI#sn%KBZ1MRZAzUfOsJ-gn;(6GcrSzdx--a&Ww+GW_6J);ZEkNljIjgPp-!f#bv_*u{EjTy_#H_OCK&C~gCn^|jD zZ_K~+kY&#ZeMpZv0@L`M4Sx0%#n;Ct*$N*6)E3?C!*1Kezw>l)Ch=nl`+|G5hpInI zb5K%80ev^8-n@!S(3L-)w}I*&S8O#9*=oFfs9{@q`ih|DB`mqj{MQ;TJNdX<6dI1i zLR)SDLqo(WMVgXYQ{hDWJht;U9U8V#l}t{;%=3H56eiO@~I|&l+Bo3b$EqN9sphBi+M;Px}Z@ z2!D3^ivP)nUDhXT$LU|knq6Z*A@I=EJg-r$W*@~5AFIF-0S5|Uhqv%h`Fs0+ZvIaM z{?kSPi$M@H8bK4|BlP(2%bW>u|I<$O-)&+T^xspVNC^>IS~5hRi4w`6Cq>>7qmcp# zpAP@u?Jxc3IT0BIhK16^K!s2-(IA>E)W}_S8f27{7Wu_RivSt|1P~+02_b^O4>=%= ze`5f1?_#yw`bif!i;-L^ucn|y8f9~Vw4nST!Iftw+ zeI#0#>yetCcoNjt5!YT_Zn2pfF9fc85CK~g1YFcXfY}8U@bx4BA%T?OtS}a^QzL)^ z3-O~6K#qq7bfnl*?0;iGh(cNj(Fia69fI?pEC>`ND8&8(g0N8`1f_ZQqEi!3ulBYl zysR#_-bjI0LAvHi4D2lsU}^+$8~igYFCoC&0|R2CNr9au5rB07m?1q$&!GO zU^c+ZivJfs39JbUJfxG33^_v$#esqB|KA`G;UNgrEQFp6!DFRH&Tum!o>GFy3r`2S zwdi1x6JHlnU}K5^YBJfUX>h3Dlq^t1y&$>jtz** z(*p@<5+HO2);l{I$cmzXsU8A!ln@}q^-l~)Abt)Gd=M7H3-T)!K-k@LKv0YZ(81oI zu8amv_1+_ghwEnnI6>ZxJpNxA16pzfp&&+-m}!t1Hag@F#Q(Q$IiZG&2|)a35umJq z0`dy@5Gx%Jl;r@tQrv*;3@e~#qXxvJ_y8A+2E-7fFed{191&3VfE&aG(*R9*1aLAU z03Qbd5EP(iBmnLq3Lw0~6}YC_0U10sCbr|=NK53$HgLHsfZkd?sz5pgoW#zzMz=_vs|5dlD>(Etx> z8xb5-#E@%l6mYgcf$Bm^u)FmbG*v5t%TN>9U_8-K|KQ*GJIH8AfP$YD&?rs;>Y1TH z$W#<4!+eR3;{cQIA5I_t*;X5$2}4ef5B^T>Kl0|3drA^SorMGJ zWC%Db_RkRHg}l+B0RbTfVn+SN0F~-5_S5IF!aNb-Lx8z48l=Y|U}nM+>});;#TmrF zL3eZsE0d7_dV28M%e+48kAO02$AEl7<- z{?@*}20RzkkTd-7yiiZ@n3*7E6@V)%1aLLj0a~0EpoHlF%FY=e8MOdOuK*Z#3&3VX z2pn&ag4bOktH1WYT0#8if6o|jGb0EqJ)+6Sf^4x+A%GI<9Tnu27!Ps`@A#f}1Jgm8e^SpqnSfTAJ-EL<5uP_{Bis}KeSIXGZ?LP zeL}6qzzXa*xf7y zUp~5lOsIiQrU*z)L_mHH0^*|(pbzz37GBnpLkRu_|EICj^$Bc%Zi4Wpit1`U=F4{r?(+?$#KjuIiT74KKEB z=8rgjYAq8apnZq(pL5-qq} zP6qO7a6xGv0wxDk!2Yi$&{oR;0$dOfauoqjD-cjxfPg2(2ng_pzR?l^5{9sb^k@N| zu_(ZSIggVx1E}uz0RneVfW52_Fh(i>rLPMRb1#5gwgXswS-_%22uvJsKuNj9_JD)X&$G$RM6{6o(Npbo;mhlbjW1t=UGfFULV7y>*% zL{0!WpjS0AqXM2+X@GwS6$nlv2FVq8psWRsDl~Xeh6A?0=Yr)~fA9cue#(6@j7fbh zj6pd9YAX>C3-!PldV{n2Xuy7%0g&6B1;if40QY7wz)M{Nltul3$nPpZJ6Zsgo&rE= zDFVdE5{^p%qazLI6bXTXE*4l=QvMVcLIuISBs^NG|G5w_K(8|~T7dMn=V&L#$ZzXG zPb1_D}NBcSmG0xBT)>GxnvpeHoEgaXPJp^vhl26RqR zfGXe;z`fxOaBepO!Ux-cJFf>2g#`f|S6hI(pau|iNr32|hrDG%DS&$w0IqQW^!_CP=^PecVNJiDinC~5CeX!rGu~YAs{aq0j?Gh^J4_O zYC*uWDg+chL_lBw0_<#2;NoQz&@zU8!IBuT+VKNIF9U!Z~jsqYX$^g++0~i@WfT4lD6Y4X>z7IXsZAdBc|40ljs<9&P#vUO< zZyxF-$H;6Osv&>ZXB@DPpJGHo-cRwPFpz&7EWqI60Akn+Szw($6EyITMu7;3 zF|z;#YF}YM#$5!o*God~+dxM>F9`I2-XHQ`1@pcP=6oK+9ubBBe?Q2-D+-v~p}-|4 z6fktf1=3ge0pBeXKpO1>F!50UQ}hO43U>i{^&G&By$29?*bhzA0V2-|5K(e~oD&6z zvIHQMU;zZ=xPRvg@gG3!_uxG#9RH8UK=)(h+t&rcx=PO~cWYvx0{i)=2*H5Rd${0E78+zcLV@&56u9b&fUcLy;KR5( zNDfB>TgdIB2N3@=1SG+n54{CzAq4Ud>)|>a-q#S|brS(DL0DiMDhkx@x&YSnFo2f{ z`7dq)*k|7XZv7s>E$abD=xu;_Tmi^M9e^nC0F)>LK*DozT>C?HReFNpgH zj{ER2IUN7pBj%FVXfyldPkoph>vI@|^&I$n+U=Ce%hMwIU1I+aiV0{SzFP^;8j{0X+;I)PDGye;p7zj3=OgzL$#)u79NATHXfE`3?%) zdw>GDB`A=14+UgI5FibEr?S*PLr(Oc9+!9r_I+3*>2TbIJ|F;M_kp<|9|4;!TB@g>{@-AS=Q&;15kh@ofSM=>d!vFp+|z^4kAS$+9-+Z~nETf7wS3I*_w2BS zVE^D}MSv=NULxc?E*9nltaqO)F#qBDCkp2Ob#D}i4MTzKbQE}9f0`p`kW+*U+6Gxc zP=yt^Tp9tSA7=rYwh@5$dJ*6}TLjFn-UDoM20(5G0hEIkz!)e1d_^umEkyyi#c=>T z7sL;>>$G-H@nccQ0o;T4`)~2DE)Sfpp9pK8xYT&r;{$)FQ2{%d(38;wRUJb-20XbDwL4X7FGxv)SkX?)c5iuwrbq22cm`-t{0QAoQ?h^q$=<~0` ze2B+^_CMn?so)1FOz}ws|q09 z^9InjO#*_tkASmx8PGf`0;Ex4fX>$eu-T{s{tE&?Op_Lfo`vgEPRJ4UKl44s54j(s zCqh{NE&iRYZKSs&44IxR)Q<}h+VydUdkmpi5F14d9PCH{9`yRBnE#G{$$L_KsQECi zr|T6tS?F0{zIZ`gDGw3wpacOnFc)|k|KVJK9o|FyV*Dszpo<3Qp{`tkniv)F&j^Gy zf87sq9}e>Z_Kru{P#d2hAP449$#Zh>Vn_jldFqk#6+MGV+7|QaH1e6t2jnqC6=j62|L zh#L^KkpuiH)bJ8bIDlUO1-M|%ooX}|_ANX#@|A`V5u-YNGvQwj34RoE)q@+cH)Alc zGNRb^a>jzRyJR5iJ{|D#r24;c|F`C$4xDNs55z73HBA+AX?GnBE?XnO2=+B=+f%*x zC+~$gAm>mUgn3{bcu+u00tZM-pn;qO)YNmZFKEG>fi;tq0ArSb0XJ`;!JXSM_o886 zNP#&}j}JyaGJt`P`k;G04Agzd2jw#_K;}#jDEj&VSPV`B$^Lbq^}G?t#)kl5&x?T9 zfD3R)Vj+GE+-F4r7CML@4c|wB+{3yr7Gpx;u#-b1|8hWIi}16dh{Sl1S~a*o6BkJa zvLW{S8H_+&oZ!E5|6i~(K?H& zQV_-f{#+E!M^FF@_d>8hS{SaE;p;DGB7ffxxe06kR1>^>FyKx+9Cu(Ir6ZuBl@Pp} zV*(#nbiv3<3}~7z0MBRYKHoO8_@j*b&%Ls^G-~j@%ctBJd zABaLfcDi2$_vry039`pbh8QrAAc&6OKltH15m=W9%u_=+@1J%SMBsiJ9ms#g2))?9 za*u(rBPWEM!yG;bYh7O#a;*<}RzbtP4_qM3h5noCr?^jZ{Y|j;KXDM^ z!vFyRTp+-Y1Ej<-Kn>zIhPmTl4tqYVo#+TO2!#3<2X!+g1r73`cWiDa2EA|D!RTil z@b+s6=vmAIFX!vP%atC`_2WHAdp`oMzW)kBTbh7bQV`JgJr87!;65>2f6JVM`w{T( zi^BXn2lGuv2OP_%m^dQTpPs39E?6jd9(Ei8yRX{zyfVZ)TpbpKp5)^XsuGx1WVkg9uc zRn>kgsSWSh_dUBAV9w0ym|tSby;v75yktn|AYoK8?f85NtLMtFXT2fL9&*KwOMSX)M4hfIz43BN~oet$$7*FmoR zV@7emo5nq#?O)D4WY-=!PFyg@<@;@M?MWfdKU{`WkM`i~^W!-E?G3Db`~VvsJ;%(g zOOaBP%9!V2i0D)oEy67k5~xHZ`!|oig&S9<-#WTysNH_*oxY~3d#}fPzm;k*`m6L1 z*I65Vy3u}Tn@eez?OdaWGlv{;?^+DcZd35#hwb?J!(QSyOL3PF%d!$fBy#+=@Z}g2 z?PqRIJ5XSP?rgs&vp3iL0547U3;TfMLaYa3oQN?M!Z{Gn?~h0)4wAt>7|nStf0Iuh0edRb>7L4bQ z3h<}zH{qubdx%vo!}EvfxOqMZ$I7g*d6^QkIZo4(l!)%6hwwJ$XxGCAU6X1evWp1< zS}Neq@!gnhbZ;#Bfa9Hg;NzxHuL;5?cITW3ji7p^^>f?Kb*;>z;_IREMd&b+;dh-EI?@1WPDsjreDO%_{!WFHzOh)|r5lEVsh~$zeq?h`k)4;lD#Xf0H z49|&ebf*2?jD67DO~y4(gZrKmEqyrm10_T<$91l3zc~Ag_Rr^d zUA3So=jqDz8|F9C+Ot0B&)QFWq$Bsf_hQcy=Q}ZfBZ4IK>%p~+>)Q<8-=cA}NjWxq z(N1aIn&X@Esd2a_T)Njmvr*CTx_AOT@9xF8JEbT%IuzM!I-*CG2ionFp68_U{_}eM<7f+KNtnQOWzuu0kZ%*Li%Ofa%U5*1!uAp>NG4f`nAT28#x%vLc9$6bbIw>)nd&=44 zLwtI|JY1yDVxEfj2hn#K)m94wlB%OeY&A5fOKjJK zShp^59|Pu^wEdcD!K!V2I3%@%%btyh{N@ZY?`^@@GleKPH~=Xn;pm#-jEGn>1V*Uf z(VXi&{k)B6i;1;StjGDZ^{$-lg7e2C>HCr+dl0dYz7nPsa@|`jp=_6g0|#X|e!4o& z-H66F&x?5P*WxQN zv2MwTcC>>EhM~5omEZ@*=~?jo<~n*kIfIcmmty?sTx4zRf!-4X&~b2mw2n7J%l2CE z^pVyBVvJzRLIYy9ng=a~XGkD0nc38PCi0g$V`=Z-X>A8-S4@e&-}RUI?)BxJA;Ru-3rBx^ ziEUR7qIB(eOf2q$p~C_(ZB{t8l|^CfXdA9A#L-s<;^otwa|)6r#r`dUUz_?jOWu3Q zvk9}S)R?)<-$(OH{6HUKPiYuAcQmp~3(+@k80s}~f=rkAC+#?;rzs3NG=}wnmZ(1| z1r5&~h4TE}Uj9sL>ux$bB1d_8)s9P<~cuyqUl1IxMIZPmxiC%K#t zdvW!&H`hhtf&)~TUEC8_-rm9WPw#Q8;xtz8o{Blk(=ly+CzPzHO`lq0Y~9rflO{Gq z7xwR*$qsn>XxpwUXQt_0IG*!goB0o4Cw9}2q9P>SHOtzkO(}4Cl{(ZKnNy;XF?%Qm z&&Z;kJrbTVkx4P=esS!1FKb4uj2b7VMqjQjlt3A<@$Jo=_L*Tuv5=1LUS%#&lpKsmFdKfj5U`njtkW5J^Reh|L>-j-v;oXg@J>rW8|n>SihwW zrcHOFUCHxSGme?TbuS&;pJu&pJEKbdjwJf83C-n~&&%9)Z0d4g%t(tb1G5|vmm7h| zwD#~H)CmqTA<%I%V;>M>_tuB9RZVC{IY6(Q3k=y0ri%(-UA7Un^T)wsq#ycCa6l3L zVujO`D5WoO({}Q?cF1u0l-TbSxO!cN{YQ1Mc7+Zuop8gCKkT3#J|1fq7@=Q`z>EwL z+ua@sJ!+zRv^J(rbK|{lfrMCV)UIBMF}XF6#%PnT!t!?~(Fac+EtNiexL%|DV9J8Y z1-3s8OtVDSv?d7Z?GCpd-l*5184TP^A*)Y}(1m^xA0sG2EukGz3l>p!a2V)@+Nr^C zO$k8T;qHhZT^oHeb&)Zr7AEZQ#Pp4|ux_&)TXrk4X{QWJ%W7cZ>S|aa?0_;meEViO z?thbuktsYw@cuTcP2QZ73^7sqShmUsb4#0%gF>6kSj``LTDzL$D!7S%Wcu+>H#i@D z(z|qi{D{(7E^mhnH9+j(8fY0`3(Y&%M$`5-sNrq^g&q6AUi5>4J~%Dt`RT&Gy(t_c zbm1Lsi8cu}(YcoqV)|+!F2fpw$2%jlz?8lpf&W$7zf&dk1FzQA z(IU!}zFjS1#d5UkAV+kR41MG23*`JB(2MvAZQxY?JcPD;I1qrEUAKNWhQkKl|+ICXXFkIv*K3(iDRS zst_NqMB5HZgtjK<#aj#dHRO<)5p%cX*@5+K;GqlmU<3GtY9Y9Vf;2pO}S=R_ILrSu0g`?<@|gxHbb%!@G~{Lz*i_v-fRONXos zB_rm4X%cI~otu-S_wSC{9Ns^0>4b5%KlksgLA+mu$VfRth>5!MjB8GuOGBT0A^M&i zU5R-%SE|oK&50{D;rU95}{)L*IyBnK*@r6yVgajhoC;mx+Vu)QwC;oaCqSFQ(6#2bV^#D(n^xG2va z|F`X2-vuTlaItW< z{=1XAvm|+QzwvODyvc(-?nSJtMSuoE1L*5vJA63~YSaH$+nR0X{dQ*iUD@_#Y&-SI z2qY$=#)F8xbPSWwtv&s&Y;*ru`UQJdVk0qpPxy=c*f*l>%pZtXJYyeRWFM@rS3}m= z!L}0D{dc!tT+h~8rantM*-N#XG?G@iyU0EUdaKlZApAXA8uUMFam}`5A8=oA=X?L|B06W`kH!-yGefveGJ5w#u4v&@9U`~{zpD2ZL@l|9Px%qGf39!C@n9)wkmnuGvG9->n;QS*+z@#9XO7$NTKGy8 zsr^*tr^-{8KDfJO?ImdksjUCg5^WNRHn~L3w013HA$g>B z>wj7!|F=E=-}V6Q*uO|0s@^%6qyFKG3bs;GZR+gGy%iOBhRpnR9@@vUeUY%^J ze(!&<^0j|ORatf2oT~cdRMnHG2X(4y@7MOTR9B3p`ityX^%q13i_eP=&#fvCR+SYj z#SIZ(5GAjqz90M|UolnPK8&w?`RD%&c*KP{p81zJ5q0_Ef73tR13KgtX=zDvO-)Im zOWn->4~cqCkz{-pmKo1cEqR8RZm5zb@I3Krn$-VOO}TyJp%~&)UUnPfMs?+Zv^NTg zd7WkafFG=h15uLvncXj9D41)hTlb%@{^w6n*ZKM5%LX?tul6ZFm_KIX82{tVU1Z-m zkq_cTTu;P5Fx8~KiZht?7yAE|)V^2O;?ahhgMWJxeY{{&P3imhPjv6z+TnikXi?VI zb-fPHnd1HJh~(<%#xs9MVjctg>CvXwL``BbB7T7(&pW2nK(hWKj>86Bxl}{<-&B7w z2Ynh-BW@yTxAIfEu3y<8(4mclHpHE%k3m|B1~oVOJd?^{ zX~6o+cxLs`$Iu})VN*>5tT)VbrESzE+S0Czxq`KrIQCq7?jZq`ojDzc0OFKNA zWG}mQF!<7~qXt?N4+{t-ju>PL4}UZG1n46qSc6(?;!ecV1b!kk3dTHV`g$8+?jk3Q z$Zdq$wt8xQdha-!J@3CgT=&+^S<;uEzwVlUOj8)YMAFxmjIGV2QtG0gaV~zT!?Uiy zJN!IZA3qJad0U{Nhb?M5+fd(U4r5a-YCVaC5evvoGsM`;>hK{RAoP`ti$eZLHTquL zAz^$+ICxngK8{+?;{}I4ethom>eW&8T>2wwFXGPFR;RwxNa|73LiUr;GBEZ`CD)G_ ziwAx74IFi0QNtLz2D(sE^C5n3tRt`tnflx=bPb2;e~lz&XP`|VG3T$)2-!4i0IzAI z(RA_%ICZomKe#%Moya@>^T!v?&z|r7L)t*Stfa3anNX8{i27vc>Zo95tVBcN40VaW z8FM{UD2U0kPC}c@&%(xvxSNX-2?_exx~eALy)4G^VsgfKuLM_Et>NWoMH>{(jiFIk z487^IVAaDJaYN0p@5rb#AAWw`^v;8|zpD+rjzlb1B7PN1ZPicQiv&j(_3aeo2`bc@ zT0>pp$XrhZ2h*7Ct49pUCxE`h;VsC0aG{2@7ju6#heXT)!S^-bIwUuuKE;fFDQjvq zn!7;CFQsmD5eyT^OGq{*w>0C@4?jNiI(eB6_evw{HxDPqWRT2_Bon)8j7`D1=_x9? z(e>;E_9ur!Jq=h_Q=ld_(pJ=k*RRVt9Hfapx!#zts5!Q+tA%f06=TbC8^m=WAGQ@S zLE;3q^~h7Vs{xf;Ftx8PkTza6>NmyRys&Xt&Z`F z9k6Jz0d8OFK^T5Y!ex9`E`wT04=eX~r5^sjwH@J}s`I6kO&JTD62+?0nt_ zVp9&`T>HaqpzM(Z?ZR`=A2xyQh=9C(D5TERTt&x2H_RR(-L)})NvDd_rzb~>%15^P z$4!_pZivJ3)} z4wmlHz^auJuAhshj&e8(M-WHLrr&r=rH-_CI{hg!7|1k1_N3{GkYa;=iY_! z*y&IvbcQ^Pnn|G-Y|{=pL3PnMSQ8;F^&eSVN>RenpswZbrsIbfNH?$UGAk}>bu=<26vQKo`q)Yhm3s@_JVp;O&c9*t@9_pH)tt z`+EBSw^eEYQwP&0)JcZGC?)L4sWcoE4vi71(3p9KI*$tI7fgn{Pdw|-`4H?)y-z5V zO>CiMDhGAyPg(V@T9Qoux3HG2>lR51X8TIJw+u^2?PLA3z@ceBGM0r{BRO^yTr)U+ zv{iD{vL;vGM^1k&wF%Q@Sh-b!MGNSwKhzeF@8x0wd2FLHC2ZJAzVhNq{_21M=GO#T^)0x!@Y-~_(*5HVfJM5ZRRlM z1Ubw@IZt?*)a2j=o5nNjvK!3)W!1i zox?dtgNY$`;h0%St}^FtUJf;M{VKVn8R;^{&f#1xrtfT_4}#{T!)htD@|!P1w*4Kn zcV2@mZw91+>5$sDrFOCrbeovM-c3WT6%(;aSpT<5nUwMCJ8=8@28lSW`Rqx7#}d2B z5X*HUEJOyL`PBO>KdaWq81c2x-T3>lFVlo3h@Adn#=7#UcioKD1{qgft`#@=g)Z z@Uw@Rn*r+bep_*G*XBK7{RMx2;n({A^x>(LGt@{b+m_aA*dU9KLUWKYL<3Fen-ul_ zn$?_tb7J*Q^trU+xL`k)ESDiENv76z2o0Oiagi^F{(Z>V%_V=EV@2o}GgB+|Tk~gA zyS9JG4ka_tKBF|n%y(5p%qU;FVr{6DiJO7gcV{ft z++2e>cMhZQ?lt(Icz}>ysO_bT`t1Aq9G61dMXk_JMw(JI+n`PjZRyvk zC0V%EmyY*Kpnqz1HDqO3z`&qV7bxm(&VFww{Mo)TwCbpX&I5T?X;!Iw6dZG*e-u1x zG46#=$dTMJH}Y6QS^v(hX+LoMq^HUFcje@=$*6skqx_r+u0IUKsfXjS^Y&`2yL$*L z9$i4sGdIy~Z#i1#4MDS5FEsMihf6aJ*t7mZuRDQ&dpW~`C&y#|;F@Bs3V>o`MPm^K!N(J_n8{zEj0Gxk34u|ir#gV6nvG@5E6kPuX z`9}_-d*Kj-(jN7qR?o|uww9aliy87TTr8LqIawT``!YDjGGqP zocdB;H_4iFi+6)@<#7>CKiq^f&yM2gn;Tg6;0fj)+>WGzfoR{; z9ib7H2=Z4VK3a)A+k4(WbvVPJeBU7T*x|jGs4?l|R9p73eV8`6*(&4>)4;|h);L!l zjE8qpc>b7%_iu{v>|qX090)>ovRv)|_akS*&qoDs`jFk52;U(&ARa1m)fH;rxzN^m zI91-ejFd_ZiO|n2;(RaL&3*c!Auio(kE>6n;_CA)IRD}(PQSg5vX{>>mrkdld5MVW z*#vFcR!5tb)Sl$m#qF!pOD3dR%U8|yR@a|(w_+Pka14POIkk5E_<;_1`)W4%)j7C* zB^t-~Ib!2deaxJ|ahz+7?s*}IN%KLkF`np=UXQU1bSm{A4Ow4T(FV55o&Is|WupH( zMzH_6w`Fo4n8^AI{m0%t5&YuG4kM-IU3V_e)jNGCxw7*7pBRESdFtil7r>wT#OMzCNEuR_Iu|>} zN>Zq`2^xkxFV&aByp;_aWOhOGb4M`f{$AvtFT|+LJrI}Uj))#+@MrA3CLBXTlOlZ3 zIcZ8he)w=(+AyDhLRD%;egx}p%RXBX?5p{4Se7#;&+m@W zvy%}T6#^~Bjv)XKsT$W^Vk9-FD{!X9yY1uaNWZ=kW6FnPaA{j~PHTiV)Dr}@QlJ^f zOc3jz#x>{gZg<8ITgdZ3dz4I|Jxcpc^#9cx)O|hdgS)R+QaiI17pWaM@$L#Xo!LPS zW;(LRQhTwg9SZVmWB4HIOiyNAe*S2i_1)`#$(QFEA~74X4P%1*bl>+M8i?FEnHV*9 zEIRh@0b>htKy_$yG}4A)J7P|mo#A?92io2^h~(2VFmzi#^eYZRr_?%V7e}lxTt@7Q zHbp-L`&*8~yXx>PHXHYE_9O3ElROB{-#ztk|Lrt#-;d+ww`XwX`#acu?;Pf@ACKI^ zXcQE+#JWupTzB;_f4Z~K`HU53;9aZL$FQ&6|4Uib1{K>78{nh)AYq^vvSz1aWa)Us zWhJ9V!#a>GdG>8?2GedHup8404###O^wt3+9-WA!?cI?u!yVBnmgM^}mRGb4sp-^7 zPgOE@3wg|2%&23?!?Oq3SijJaZP3AvvJBk+`95xcenZXTO|058gWUC46fbooZ#fdh z#Z56VK|$=O-?MkGj=H{jcJP<_{UYP$zw%mhD7ozsA4o=9@Ds$oR374>5C zm;Lbeg6i_=v45@FfA$_wC~aOlM7nopQJqyw!q?`EuKy{uunqc58i*+B*X#0Jr*P6H zr`iH~otdY&!{*!Oc6DzSaLOwFM_x}W1_qmuf} zF6uZ#hqgCD?hq{u8y1Wr>Ul@^~-!Iz@9Wo=~)4wfhgf)he8WEY7K2%|~pcCB) z2C0#-T9^;Jl5F_q_#gwp5XhPmEx#<1vAmUEat~yLkjFC6jnctdz`2Lc>jWkXiNl%+M>j3u{XVh(B1D%G{IXDtO^U@=hV}hFPE#c7J4&I5>bfnZ_%rOHDp5lO}NaS&+L$u60bb z8ERR`L@cn|E~XFO0Ma zcWoEyiGy_EAFMqxiKs9I!h^{f=icpLBSS6P z$AUM@z8CeM>}D;=tc`wG_0?Y%ZMc17mh|@ZUeg_$dlY45RQsW8C-Nb~$@L`{urB-0 z#Ej<{NAg~YjW(n0L%y6^H!e7!UX6Js<9h+_l^j^1#q3F6&B)>U$R2Kt$d(%9O3G-D zSMpw~8%eL(@6FkUKQujlw2kBGy=KnvTK!rD$)2_fR-t7u+dwC&+B zEGhVmg2ySijJ{R%7u>!`)?dW=>CgK(ptlZVA8V?)i(a%p9H{{(-o1fbZ7t%Ke|Vyu zCk4ApGTKZnXm4H$ARjrzpKV~h>azcAsUNtn&b#InxFx zIR16eH&zoZ{iToOTD~QB?IyXGd%fIbC60Au-qf{=7|8#UMBjzP^N{4+Kx*jbByIO` zSA6y%pU~Wdv1iRVc4&(W>`2Vb^ducj99<2i)9pX6UE=kA*QUt3NA|@XK7DNHqD3Xa zBiOc1)TcM44PfQzEYofkpp^MGB|7zQNaQ?9^u?Idj-B4rS@xsgKhqxk!ZX ztRW^RkM2)ddG*4SF%@?fcYpC@Tl4SUowE7->5U%e6k}O_`OVn=AKk2mbr>VVM$+bZ z>D9zhnm`_3B6)lPzHU;T)V|e7KDn%TcyH8yyq8g!p|vIuUo{*KL^tm}Tmp_=6Gi|DZ&Fx;inos4-(;hni|hJ$Wk_Qu$w(fX||jrFXAS z8P1s+?dxK%$g5LbI>qNO{9ve*KJwbdq7GVrU=_sm+)X6u+c%f>&K#TSxp__EsNyO9 zM^pM*zwZ!1{S-MgR^&ezsTf~eQ~rr{SfD4DOvQ5_{@G+o0*i|+V;GxCI`mV!b!}TM zvnbE+!0@zsZ)3X~Q;)8J_N`^;-&>Q<;!wgum-bB~?)!X3hqbB3=UV3Stgz4!MslEzI?uG{rJ)L-&6++;=jyxmZq}nM)VU1-a`}GaJG!6ZD68H zzm1BV0&-Aj(=D3a5J&e!sW~XZccMlAas9ZCs5?3p5rZ7DdPCyY@4mlQ>+XGmD`JBF zgT&b1QgbKjvCO0qjG+x9Jz~Z-#HeU@Ytp~2QdGuJ^9iv)`sjv?jhTSOvl^(iA%^^n zOqb^_D?P^a>kZYoe0Zfa#{4xscE5RduFjR4i~nIA$XDV+8YDZ$EWb`HAEFLU)Qve2 zcek@+d@$k!fh}~AUgV0c+dLSDy(cnh^K~Mo>_8hu*U=Wrz%VHMoFVU<1lh3BaP8wr z?4sj==g$w>pFC6WH|wxx$6|Hw^zLqxCG2&ML3NyHT|*VzJ+%?m))?(#Opr$HXX#1< zw!H_|Epo7~%@-Vw5HagarKg>#GzCeCbCzGHhvqmMW# zh4}sDjo7*_Q#!C~Ozq^}^==3ZUr&pEUB>Jbv1+SZYauGe0J$>_uwb(adv@C5)}_8E z9HqkAl@gXMq}I9*ZDZJbvwD-MuAK zI=XLcos5BXZh8^>H#6eyL!YX+z8HhvesW}vmtzXg>LR}5?1}bB>#vE03yA%*4rx65 zCJ&*nHCut0N&c`c9tY*>Gf-{32U+d}`g~hM=IsR2rsgoA&z;x4!uirdH2USUQ|h+Q zoz`kppYB>{#WMwYuwt^PV-JdWiQ%moUuP!c{EZ=w%yA~-YR3_~F66ayM-YQ0j$bgA zI%p2@()BgbZAA*KH=|?xY=&&W0H{Kmpt>7l1M@s9e6{oy?iCl_wPmPuV0Uhv zF~e+cjTowgzc0`Jyf*I+_}mWl*{vJTHdE)(KhHH!_%X#}>veGsZpP|*z z(N=b=HF1$iqpRci{zz2Z=#58r`s3=EX!?X45FKrRur|gB4AD^glY}2h?MveNFR+KC zUX?zK`E%*N*w5Hww*zqf**si&aTv$n-o?_x+c79B3LQGuK)-l>f!i(zUaKw~&z0yW zoXGq6MLfr$Xk1NfUFVM3lP!^&tU`1jU4)hNN8hqSWG?H-cqn%8qW{FD5q&PyOLicp z-@k_ngV_Gj*&KVz7!Tx-3YYJ8WZa`wxcurUjy%7J;cV2NJZDXM=|EicqGke!T3xT z@S+b~jE%v)R5)AS2^)w@kL4H?@#s&Vx1|3d3pZbG!#VmswqDqV{OSEMbyhI4(oC>x zW6Y7C{&dEu;?@!|^(5jS5;cE~LIbpSB@Oldl07pW;oaLqm(T8ylNVAg&KFI0tw8*> zO-S1@2yyw%&?eT9d^j0;#>%Jxw52aF8T+?2$IL>Bv7dbK;Qba{e|H*(o}TAgkdN_` z+n~6_6BEbO{&M}|gh9s+_LItYcT-=VT06;&nf~!=ApzR6lG6P?WEE!+uTO+&BTHyB zuLjGMc5p0Pi8kk!B4J%ubY-lpHZe*hF=ov48FG|uHQ|`)gOdjsOKOS@j$U4aOW#&t z?SXli!+1Umm-{nDpB=TC;kUngcc}LB$2-;6{`G%J38qqFXG85-Q+-p%P4sz{IyoL~ z(&Ay}Q=73;7|*_cD5@>WN5ic}2%gyr-Lj03Q=mfWLdF8w&p6q8wCPjqf=j2mU{+B> z@dUUO>Y4NyEKa*D7)ZeLsZ>r4Og^XumX^NAho*wn2}VNtUi@x#60 z!RN*pdy_}#VE|R69gI>UP$xeY;UnFU!TCCExj8oM)W+Tea%|XQfOE&faOP+i;^Vqp z$Bh}IyAINZ+Jijh*G(G8n-h2byXo_%$0Ej@bnIZV%Z%ww_x4J*`Vt&%PObs5eR~Bo z87sq%&x#0OT!^SxKEGms35KL=Vnhblz--1L9VO;*HMDO@ei`kys5YjI=cor_W*Zs9 zQ;S^ff0#rc?b_T)mVfB*k=;NsS!@7AHT{sDbPYG2kDmYkrb7)auOU)$P_DDoe;e zdwgj8t*ZsTq06%&#zEbhzxv7orx3%^miZT);@5^L z-~W3_QxNg#MCSN5wa}A1se3VC{<|r}oyH$qdSFMo{_=%UUL(^TasoV5^62{-MmunN z4LGe{K;GwWs5-QOX&s#}T1siVms7ZM^za&UBKfQz6}#V&{u~ka-J9!{;G+%d&-jjG zMC@v7OgcXozWYzZVL%7ikT1nJ+{>FbRQRRzH+UA+n!M)j)zG~&xiMS=o6;5%ae+k) zn1X!zaSzwQvB%3W^}_ zjMZp`E*(|avf2%+7hB*ApG|e)I$$tzI%j zJqkq}o)wD%q$6cr4YP*Zj0*@-epk04V~jK*r^sCfv46$Ww;4uErCv?hUCt?ozvd_F z)LKL86KkyU_mamoagu#QAH}m?F{bCnW!2k|mtD6oB2?Ln{pD_HBvS~D%wJ0mwI#{H zP9~>6%*m&j%w_$GD0ASk>g!nluiyE?J>Uaz)e3@Z2RY>ra*pTnLn8lK67MsM&r~qK KWB%YTN&g2;C_c{s diff --git a/share/pixmaps/prcycoin-bc.ico b/share/pixmaps/prcycoin-bc.ico deleted file mode 100644 index f3522f1953e1c58d5bcf30b835832ef5c9d05c91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84494 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 diff --git a/share/pixmaps/send16.bmp b/share/pixmaps/send16.bmp deleted file mode 100644 index 676b5c4b490e0859578ae599af54aa3de26d5d3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1334 zcmYk5Jx^OP6oy|?if#e5^t<#cRBdTfU1zbxz?iX8m;M2UN?sTsJ~LYQ7gH)G3saMH zyB~}P>RC^tqazJ22kKf^qtTH%)*+8HB(`iz!{JD6Ym}Tk7?DT0LLYf-R`9Lfu|hGN{Hh5!TD1R4whhJ=^V zS4W7?sJSvv_HRM}BgTY`h7z_r3!Cba8Q^tE($rUtjC@AJfm>U2Se|a=Q6{ASdcovs^b%O|_~O^A9J3 zo8Gy{cW=fyyV5$bWwCUxW^1*ko3u|Q!khV8bNYU6kCq$$b?M$c zXwEFX|G1o6qw%(MADT1u`ciJFjYp+xPCtD)5ti!rOE=q`nY3s1`n}Q>|Lf1qO_lCf Z2B?~wyHmPbfR5?STF&s_p4QyW^e;amw9xQ85j>RFfcv<;txRlgMp#`4+F#he?a^n U34{0`aiBa{9Y{S$UjqXJ0D?~%)Bpeg diff --git a/share/pixmaps/send16masknoshadow.bmp b/share/pixmaps/send16masknoshadow.bmp deleted file mode 100644 index faf24e0d8aa81faf80072c7807e52d749cad63c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126 zcmZ?rtz&=yJ0PV2!~#&v$iN7eZ~&8-#Q*>Q!Geqp3=E71fcOCre_&wv{{x8s0P#N{ U1}Xv5AU;qWBo9^xQV-Mz01_z}*8l(j diff --git a/share/pixmaps/send20.bmp b/share/pixmaps/send20.bmp deleted file mode 100644 index 2b90422b38467ae30a2b6a866adbf0ad3c3f97f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1478 zcmZXSKWrOi7{;GaLQNamP(c#|QaKSso$~KuQiKB~Sfms~DLR@G4onc1ZpoM-LzWCy zrW+Vekxuf^0gqWCdGvy0mVEN)Oz9FSLza-qkr-Zn=R}0i&wlRv?)Sa-KF@b{`Tn27 z8jRb|N;g@(bgCic2K=|7!F2A@wXWLMR;S-l%UasBO*O5lhBegf^^{nmZnvk{Vs*M* z)vd1NFwv^5s?+Ie*_N3*YNI7vQmfNe&1zceFR9&btA#=fRqNMS(;o#EsMUh^LuMEX z`hm(;R&W?-bCV3Ha#)dXz6w@Qv)Pnqp2A+J@_t##W}?cIic0$>h22o2HmXLWA%EXj z&T>i`iR#U|WKyYDQqT#cz7!|1>IwW%T5c>Wx1Up`g-^$q_F>7g^h631&JZt2J*nI* zs}|R!uH?1I5QkDn3gSSeMoE>pBDEzy@#Qr<`LVB3y(BO3REP`m>+sl9exSU(I()UD ze4X{Gr_uVT@~e48a>x`Fg^DObDS{W_5uDA4MHIm!cnV8lDJ+Gh8Kc(09o)ej%)xjU zk--dR4macD#A8bFIr(tUKP1JUD(39oM0*4yQ;KPdK}x0+@087yCMn)2-b^U-hU1^& zpW@FJqCVqfNXd{|mH@8e;Pen?uDkB#>=(#Rj30j=G8h?*3`Pbc1CJnjlEKJeWN>7l z4Wgb5Mg}8;k%86-P6i``k--RH_&b^z4;n=gJtFQSa@e4ERujonQ;Um>T3K1q`ue&y zHa4`qy{)aSE$!^=Xm@v4dwY92I5^PJ(UFdikM-Bzrr#ew*4o+{Zvdf^`qjovy#Co%$I+@J$@dB6B8f(^6~4>pU}%==y%-wtc z`osH^S7B4r)6+9EckZw;_raBil`&XhDx=xP?CkZot6ui($jfisni}w_EB+5zMp!mp zc<$!Ztz7BRSQc>pbPVUO41f0E-0{K-mo9vH_i9%4?^yU_=-W@Ty#E;s&wTgc|Io$i T{JW>;KP#Mn?J0D&nXUc-U3=Ry diff --git a/share/pixmaps/send20mask.bmp b/share/pixmaps/send20mask.bmp deleted file mode 100644 index f124d0da084e68cac62312e9fa8a0fbf9c7c5075..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142 zcmZ?r?PGudJ0PV2#3E44$iN7e2mq2o+z`wJ7J(4||Nm!TJix%f_yCAM0PznX{=>jv m|BrzIC Date: Thu, 23 Mar 2023 16:28:33 -0400 Subject: [PATCH 115/391] build: use a static .tiff for macOS .dmg over generating --- .../workflows/prcy-build-factory-debug.yml | 2 +- .../workflows/prcy-build-factory-ubuntu20.yml | 2 +- .github/workflows/prcy-build-factory.yml | 2 +- .gitignore | 2 -- Makefile.am | 25 ++++--------- configure.ac | 5 +-- contrib/gitian-descriptors/gitian-osx.yml | 3 -- contrib/macdeploy/background.svg | 34 ------------------ contrib/macdeploy/background.tiff | Bin 0 -> 18464 bytes contrib/macdeploy/macdeployqtplus | 2 +- depends/README.md | 2 +- doc/build-osx.md | 6 +--- doc/dependencies.md | 4 +-- 13 files changed, 14 insertions(+), 75 deletions(-) delete mode 100644 contrib/macdeploy/background.svg create mode 100644 contrib/macdeploy/background.tiff diff --git a/.github/workflows/prcy-build-factory-debug.yml b/.github/workflows/prcy-build-factory-debug.yml index eb46f64266..f987e35acb 100644 --- a/.github/workflows/prcy-build-factory-debug.yml +++ b/.github/workflows/prcy-build-factory-debug.yml @@ -184,7 +184,7 @@ jobs: - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y python3-setuptools libcap-dev zlib1g-dev cmake librsvg2-bin libtiff-tools imagemagick libz-dev libbz2-dev libtinfo5 + sudo apt-get install -y python3-setuptools libcap-dev zlib1g-dev cmake libz-dev libbz2-dev libtinfo5 - name: Get macOS SDK run: | mkdir -p depends/sdk-sources depends/SDKs diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml index d77947397b..f37a67d3e9 100644 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ b/.github/workflows/prcy-build-factory-ubuntu20.yml @@ -250,7 +250,7 @@ jobs: - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y python3-setuptools libcap-dev librsvg2-bin libtiff-tools + sudo apt-get install -y python3-setuptools libcap-dev - name: Get macOS SDK run: | mkdir -p depends/sdk-sources depends/SDKs diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index d9bf7ad8ed..6f091deff1 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -249,7 +249,7 @@ jobs: - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y python3-setuptools libcap-dev librsvg2-bin libtiff-tools + sudo apt-get install -y python3-setuptools libcap-dev - name: Get macOS SDK run: | mkdir -p depends/sdk-sources depends/SDKs diff --git a/.gitignore b/.gitignore index 98ef6e9435..642c21f81d 100644 --- a/.gitignore +++ b/.gitignore @@ -101,7 +101,6 @@ src/qt/test/moc*.cpp Makefile prcycoin-qt PRCYcoin-Qt.app -background.tiff* # Unit-tests Makefile.test @@ -119,7 +118,6 @@ qrc_*.cpp build osx_volname dist/ -*.background.tiff #lcov *.gcno diff --git a/Makefile.am b/Makefile.am index 7735a11a0f..552b881aa5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,9 +33,7 @@ OSX_APP=PRCYcoin-Qt.app OSX_VOLNAME = $(subst $(space),-,$(PACKAGE_NAME)) OSX_DMG = $(OSX_VOLNAME).dmg OSX_TEMP_ISO = $(OSX_DMG:.dmg=).temp.iso -OSX_BACKGROUND_SVG=background.svg -OSX_BACKGROUND_IMAGE=background.tiff -OSX_BACKGROUND_IMAGE_DPIS=36 72 +OSX_BACKGROUND_IMAGE=$(top_srcdir)/contrib/macdeploy/background.tiff OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns OSX_PLIST=$(top_builddir)/share/qt/Info.plist #not installed @@ -67,7 +65,6 @@ LINUX_PACKAGING = $(top_srcdir)/share/pixmaps/prcycoin16.xpm \ $(top_srcdir)/share/pixmaps/prcycoin128.png OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_INSTALLER_ICONS) \ - $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_SVG) \ $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh @@ -121,20 +118,13 @@ osx_volname: echo $(OSX_VOLNAME) >$@ if BUILD_DARWIN -$(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) $(OSX_BACKGROUND_IMAGE) +$(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -$(OSX_BACKGROUND_IMAGE).png: contrib/macdeploy/$(OSX_BACKGROUND_SVG) - sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d 36 -p 36 -o $@ -$(OSX_BACKGROUND_IMAGE)@2x.png: contrib/macdeploy/$(OSX_BACKGROUND_SVG) - sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d 72 -p 72 -o $@ -$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE).png $(OSX_BACKGROUND_IMAGE)@2x.png - tiffutil -cathidpicheck $^ -out $@ - deploydir: $(OSX_DMG) else APP_DIST_DIR=$(top_builddir)/dist -APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE) $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications +APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/background.tiff $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications $(APP_DIST_DIR)/Applications: @rm -f $@ @@ -149,12 +139,9 @@ $(OSX_TEMP_ISO): $(APP_DIST_EXTRAS) $(OSX_DMG): $(OSX_TEMP_ISO) $(DMG) dmg "$<" "$@" -dpi%.$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_SVG) - sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d $* -p $* | $(IMAGEMAGICK_CONVERT) - $@ -OSX_BACKGROUND_IMAGE_DPIFILES := $(foreach dpi,$(OSX_BACKGROUND_IMAGE_DPIS),dpi$(dpi).$(OSX_BACKGROUND_IMAGE)) -$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE_DPIFILES) +$(APP_DIST_DIR)/.background/background.tiff: $(MKDIR_P) $(@D) - $(TIFFCP) -c none $(OSX_BACKGROUND_IMAGE_DPIFILES) $@ + cp $(OSX_BACKGROUND_IMAGE) $@ $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) @@ -281,4 +268,4 @@ clean-docs: clean-local: clean-docs rm -rf coverage_percent.txt test_prcycoin.coverage/ total.coverage/ test/tmp/ cache/ $(OSX_APP) rm -rf test/functional/__pycache__ test/functional/test_framework/__pycache__ test/cache share/rpcauth/__pycache__ - rm -rf osx_volname dist/ dpi36.background.tiff dpi72.background.tiff + rm -rf osx_volname dist/ diff --git a/configure.ac b/configure.ac index 758c66d7f2..eb0c2d2ef5 100644 --- a/configure.ac +++ b/configure.ac @@ -511,7 +511,6 @@ case $host in LEVELDB_TARGET_FLAGS="-DOS_MACOSX" if test x$cross_compiling != xyes; then BUILD_OS=darwin - AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_CHECK_PROG([BREW],brew, brew) if test x$BREW = xbrew; then dnl These Homebrew packages may be keg-only, meaning that they won't be found @@ -546,9 +545,6 @@ case $host in AC_PATH_TOOL([OTOOL], [otool], otool) AC_PATH_PROGS([XORRISOFS], [xorrisofs], xorrisofs) AC_PATH_PROGS([DMG], [dmg], dmg) - AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) - AC_PATH_PROGS([IMAGEMAGICK_CONVERT], [convert],convert) - AC_PATH_PROGS([TIFFCP], [tiffcp],tiffcp) dnl libtool will try to strip the static lib, which is a problem for dnl cross-builds because strip attempts to call a hard-coded ld, @@ -1297,6 +1293,7 @@ AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])]) AC_CONFIG_LINKS([contrib/filter-lcov.py:contrib/filter-lcov.py]) +AC_CONFIG_LINKS([contrib/macdeploy/background.tiff:contrib/macdeploy/background.tiff]) AC_CONFIG_LINKS([test/functional/test_runner.py:test/functional/test_runner.py]) AC_CONFIG_LINKS([test/util/bitcoin-util-test.py:test/util/bitcoin-util-test.py]) AC_CONFIG_LINKS([test/util/rpcauth-test.py:test/util/rpcauth-test.py]) diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index fdc84fce9e..e9e60e960b 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -13,14 +13,11 @@ packages: - "git" - "pkg-config" - "autoconf" -- "librsvg2-bin" -- "libtiff-tools" - "libtool" - "automake" - "faketime" - "bsdmainutils" - "cmake" -- "imagemagick" - "libcap-dev" - "libz-dev" - "libbz2-dev" diff --git a/contrib/macdeploy/background.svg b/contrib/macdeploy/background.svg deleted file mode 100644 index 9c330af451..0000000000 --- a/contrib/macdeploy/background.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - PACKAGE_NAME - - - - - diff --git a/contrib/macdeploy/background.tiff b/contrib/macdeploy/background.tiff new file mode 100644 index 0000000000000000000000000000000000000000..1fb088c8374ac3acd5c4f4eb6ea6b5869723fd2f GIT binary patch literal 18464 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", bg_path) - shutil.copy2('background.tiff', bg_path) + shutil.copy2('contrib/macdeploy/background.tiff', bg_path) os.symlink("/Applications", os.path.join(disk_root, "Applications")) diff --git a/depends/README.md b/depends/README.md index 88c87c6ca9..27255996e0 100644 --- a/depends/README.md +++ b/depends/README.md @@ -37,7 +37,7 @@ The paths are automatically configured and no other options are needed unless ta #### For macOS cross compilation - sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python3-setuptools + sudo apt-get install curl bsdmainutils cmake libcap-dev libz-dev libbz2-dev python3-setuptools Note: You must obtain the macOS SDK before proceeding with a cross-compile. Under the depends directory, create a subdirectory named `SDKs`. diff --git a/doc/build-osx.md b/doc/build-osx.md index eabdbcd1d6..7db04dd99c 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -20,11 +20,7 @@ Dependencies See [dependencies.md](dependencies.md) for a complete overview. -If you want to build the disk image with `make deploy` (.dmg / optional), you need RSVG: - - brew install librsvg - -and [`macdeployqtplus`](../contrib/macdeploy/README.md) dependencies: +[`macdeployqtplus`](../contrib/macdeploy/README.md) dependencies: ```shell pip3 install ds_store mac_alias ``` diff --git a/doc/dependencies.md b/doc/dependencies.md index 4c4c4866a6..b150c515b5 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -16,7 +16,6 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | libevent | [2.1.11-stable](https://github.com/libevent/libevent/releases) | [2.0.21](https://github.com/PRCYCoin/PRCYCoin/pull/385) | No | | | | libjpeg | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L65) | | libpng | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L64) | -| librsvg | | | | | | | MiniUPnPc | [2.2.2](https://miniupnp.tuxfamily.org/files) | | No | | | | OpenSSL | [1.0.1k](https://www.openssl.org/source) | | Yes | | | | PCRE | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L66) | @@ -39,5 +38,4 @@ Some dependencies are not needed in all configurations. The following are some f * If the qrencode dependency is absent, QR support won't be added. To force an error when that happens, pass `--with-qrencode`. * ZeroMQ is needed only with the `--with-zmq` option. -#### Other -* librsvg is only needed if you need to run `make deploy` on (cross-compilation to) macOS. +#### Other \ No newline at end of file From 643a7eea393f0c560295c2685729261d279a162f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 16:34:44 -0400 Subject: [PATCH 116/391] build: Add var printing target to src/Makefile.am See https://github.com/bitcoin/bitcoin/commit/181989f6c9427fc266dbdcc84cb60ac03e67cdb2 for more info. --- src/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index c458d8dccb..a5ba1ca63e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,6 +2,10 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +# Pattern rule to print variables, e.g. make print-top_srcdir +print-%: + @echo $* = $($*) + DIST_SUBDIRS = secp256k1 secp256k1-mw univalue AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS) $(LTO_LDFLAGS) AM_CXXFLAGS = $(DEBUG_CXXFLAGS) $(HARDENED_CXXFLAGS) $(WARN_CXXFLAGS) $(NOWARN_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS) $(LTO_CXXFLAGS) From 424a9514e9875dde01f83803c4501728b8754cc8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 16:35:48 -0400 Subject: [PATCH 117/391] build: Make xorrisofs reproducible with -volume_date We need this to be after a '--' as '-volume_date' is a xorriso flag, not a xorrisofs flag. See the respective man pages. For more details: https://issues.guix.info/issue/35283#2 --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 7735a11a0f..43cc4d769f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -144,7 +144,7 @@ $(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt .INTERMEDIATE: $(OSX_TEMP_ISO) $(OSX_TEMP_ISO): $(APP_DIST_EXTRAS) - $(XORRISOFS) -D -l -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -o $@ dist + $(XORRISOFS) -D -l -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -o $@ dist -- $(if $(SOURCE_DATE_EPOCH),-volume_date all_file_dates =$(SOURCE_DATE_EPOCH)) $(OSX_DMG): $(OSX_TEMP_ISO) $(DMG) dmg "$<" "$@" From e9e3384b4a5a8e6d873eef7e6608e0367c3b9edc Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 16:46:15 -0400 Subject: [PATCH 118/391] build: Proper quoting for var printing targets Previously, if the value contained syntax that was meaningful to make, the printing would fail. Quoting properly avoids this. --- Makefile.am | 2 +- depends/Makefile | 2 +- src/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 43cc4d769f..3b1d2f07d3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ # Pattern rule to print variables, e.g. make print-top_srcdir print-%: - @echo $* = $($*) + @echo '$*' = '$($*)' ACLOCAL_AMFLAGS = -I build-aux/m4 SUBDIRS = src diff --git a/depends/Makefile b/depends/Makefile index 9a02f5f00f..84f7d83932 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -2,7 +2,7 @@ # Pattern rule to print variables, e.g. make print-top_srcdir print-%: - @echo $* = $($*) + @echo '$*' = '$($*)' # When invoking a sub-make, keep only the command line variable definitions # matching the pattern in the filter function. diff --git a/src/Makefile.am b/src/Makefile.am index a5ba1ca63e..ba1e828987 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,7 +4,7 @@ # Pattern rule to print variables, e.g. make print-top_srcdir print-%: - @echo $* = $($*) + @echo '$*' = '$($*)' DIST_SUBDIRS = secp256k1 secp256k1-mw univalue AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS) $(LTO_LDFLAGS) From d1d656732f0d2842cb49da32628cc07a784f7c2b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 16:48:15 -0400 Subject: [PATCH 119/391] depends: Improve id string robustness Environment variables and search paths can drastically effect the operation of build tools. Include these in our id string to mitigate against false cache hits. --- depends/Makefile | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index 84f7d83932..5093522a3c 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -116,19 +116,28 @@ include builders/$(build_os).mk include builders/default.mk include packages/packages.mk +full_env=$(shell printenv) + build_id_string:=$(BUILD_ID_SALT) -build_id_string+=$(shell $(build_CC) --version 2>/dev/null) -build_id_string+=$(shell $(build_AR) --version 2>/dev/null) -build_id_string+=$(shell $(build_CXX) --version 2>/dev/null) -build_id_string+=$(shell $(build_RANLIB) --version 2>/dev/null) -build_id_string+=$(shell $(build_STRIP) --version 2>/dev/null) + +# GCC only prints COLLECT_LTO_WRAPPER when invoked with just "-v", but we want +# the information from "-v -E -" as well, so just include both. +# +# '3>&1 1>&2 2>&3 > /dev/null' is supposed to swap stdin and stdout and silence +# stdin, since we only want the stderr output +build_id_string+=$(shell $(build_CC) -v < /dev/null 3>&1 1>&2 2>&3 > /dev/null) $(shell $(build_CC) -v -E - < /dev/null 3>&1 1>&2 2>&3 > /dev/null) +build_id_string+=$(shell $(build_AR) --version 2>/dev/null) $(filter AR_%,$(full_env)) ZERO_AR_DATE=$(ZERO_AR_DATE) +build_id_string+=$(shell $(build_CXX) -v < /dev/null 3>&1 1>&2 2>&3 > /dev/null) $(shell $(build_CXX) -v -E - < /dev/null 3>&1 1>&2 2>&3 > /dev/null) +build_id_string+=$(shell $(build_RANLIB) --version 2>/dev/null) $(filter RANLIB_%,$(full_env)) +build_id_string+=$(shell $(build_STRIP) --version 2>/dev/null) $(filter STRIP_%,$(full_env)) + $(host_arch)_$(host_os)_id_string:=$(HOST_ID_SALT) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_CC) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_AR) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null) +$(host_arch)_$(host_os)_id_string+=$(shell $(host_CC) -v < /dev/null 3>&1 1>&2 2>&3 > /dev/null) $(shell $(host_CC) -v -E - < /dev/null 3>&1 1>&2 2>&3 > /dev/null) +$(host_arch)_$(host_os)_id_string+=$(shell $(host_AR) --version 2>/dev/null) $(filter AR_%,$(full_env)) ZERO_AR_DATE=$(ZERO_AR_DATE) +$(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) -v < /dev/null 3>&1 1>&2 2>&3 > /dev/null) $(shell $(host_CXX) -v -E - < /dev/null 3>&1 1>&2 2>&3 > /dev/null) +$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null) $(filter RANLIB_%,$(full_env)) +$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null) $(filter STRIP_%,$(full_env)) ifneq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) # Make sure that cache is invalidated when switching between system and From 6fa038eba4e778a5bc924a8235fd7ef693c56db0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 16:55:25 -0400 Subject: [PATCH 120/391] depends: Fix id_string invocations We now use a script named gen_id to generate the base build_id/host_id. This solves 2 problems: 1. GNU Make special-casing exit code 127 (command not found) meant that warnings about missing tools would propagate to the user's terminal and broke our opportunistic build_id construction. 2. This change ensures that we don't have arbitrary characters in our make variables that would be misinterpreted by Make. See comments in depends/Makefile and depends/gen_id for more information. --- depends/Makefile | 52 ++++++++++++++++------------------ depends/funcs.mk | 2 +- depends/gen_id | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 29 deletions(-) create mode 100644 depends/gen_id diff --git a/depends/Makefile b/depends/Makefile index 5093522a3c..d6a7893d5f 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -116,35 +116,31 @@ include builders/$(build_os).mk include builders/default.mk include packages/packages.mk -full_env=$(shell printenv) - -build_id_string:=$(BUILD_ID_SALT) - -# GCC only prints COLLECT_LTO_WRAPPER when invoked with just "-v", but we want -# the information from "-v -E -" as well, so just include both. +# Previously, we directly invoked the well-known programs using $(shell ...) +# to contruct build_id_string. However, that was problematic because: # -# '3>&1 1>&2 2>&3 > /dev/null' is supposed to swap stdin and stdout and silence -# stdin, since we only want the stderr output -build_id_string+=$(shell $(build_CC) -v < /dev/null 3>&1 1>&2 2>&3 > /dev/null) $(shell $(build_CC) -v -E - < /dev/null 3>&1 1>&2 2>&3 > /dev/null) -build_id_string+=$(shell $(build_AR) --version 2>/dev/null) $(filter AR_%,$(full_env)) ZERO_AR_DATE=$(ZERO_AR_DATE) -build_id_string+=$(shell $(build_CXX) -v < /dev/null 3>&1 1>&2 2>&3 > /dev/null) $(shell $(build_CXX) -v -E - < /dev/null 3>&1 1>&2 2>&3 > /dev/null) -build_id_string+=$(shell $(build_RANLIB) --version 2>/dev/null) $(filter RANLIB_%,$(full_env)) -build_id_string+=$(shell $(build_STRIP) --version 2>/dev/null) $(filter STRIP_%,$(full_env)) - - -$(host_arch)_$(host_os)_id_string:=$(HOST_ID_SALT) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_CC) -v < /dev/null 3>&1 1>&2 2>&3 > /dev/null) $(shell $(host_CC) -v -E - < /dev/null 3>&1 1>&2 2>&3 > /dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_AR) --version 2>/dev/null) $(filter AR_%,$(full_env)) ZERO_AR_DATE=$(ZERO_AR_DATE) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) -v < /dev/null 3>&1 1>&2 2>&3 > /dev/null) $(shell $(host_CXX) -v -E - < /dev/null 3>&1 1>&2 2>&3 > /dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null) $(filter RANLIB_%,$(full_env)) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null) $(filter STRIP_%,$(full_env)) - -ifneq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -# Make sure that cache is invalidated when switching between system and -# depends-managed, pinned clang -build_id_string+=system_clang -$(host_arch)_$(host_os)_id_string+=system_clang -endif +# 1. When invoking a shell, GNU Make special-cases exit code 127 (command not +# found) by not capturing the output but instead passing it through. This is +# not done for any other exit code. +# +# 2. Characters like '#' (from these programs' output) would end up in make +# variables like build_id_string, which would be wrongly interpreted by make +# when these variables were used. +# +# Therefore, we should avoid having arbitrary strings in make variables where +# possible. The gen_id script used here hashes the output to construct a +# "make-safe" id. +# +# Also note that these lines need to be: +# +# 1. After including {hosts,builders}/*.mk, since they rely on the tool +# variables (e.g. build_CC, host_STRIP, etc.) to be set. +# +# 2. Before including packages/*.mk (excluding packages/packages.mk), since +# they rely on the build_id variables +# +build_id:=$(shell env CC='$(build_CC)' CXX='$(build_CXX)' AR='$(build_AR)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' ./gen_id '$(BUILD_ID_SALT)') +$(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' CXX='$(host_CXX)' AR='$(host_AR)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' ./gen_id '$(HOST_ID_SALT)') qrencode_packages_$(NO_QR) = $(qrencode_packages) diff --git a/depends/funcs.mk b/depends/funcs.mk index 4b07c116a9..d4194793b6 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -49,7 +49,7 @@ define int_get_build_id $(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies)) $(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($($(1)_type)_native_binutils) $($(1)_dependencies))) $(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash))) -$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id_string)) +$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id)) $(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))) final_build_id_long+=$($(package)_build_id_long) diff --git a/depends/gen_id b/depends/gen_id new file mode 100644 index 0000000000..ac69ca7ee1 --- /dev/null +++ b/depends/gen_id @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# Usage: env [ CC=... ] [ CXX=... ] [ AR=... ] [ RANLIB=... ] [ STRIP=... ] \ +# [ DEBUG=... ] ./build-id [ID_SALT]... +# +# Prints to stdout a SHA256 hash representing the current toolset, used by +# depends/Makefile as a build id for caching purposes (detecting when the +# toolset has changed and the cache needs to be invalidated). +# +# If the DEBUG environment variable is non-empty and the system has `tee` +# available in its $PATH, the pre-image to the SHA256 hash will be printed to +# stderr. This is to help developers debug caching issues in depends. + +# This script explicitly does not `set -e` because id determination is mostly +# opportunistic: it is fine that things fail, as long as they fail consistently. + +# Command variables (CC/CXX/AR) which can be blank are invoked with `bash -c`, +# because the "command not found" error message printed by shells often include +# the line number, like so: +# +# ./depends/gen_id: line 43: --version: command not found +# +# By invoking with `bash -c`, we ensure that the line number is always 1 + +( + # Redirect stderr to stdout + exec 2>&1 + + echo "BEGIN ALL" + + # Include any ID salts supplied via command line + echo "BEGIN ID SALT" + echo "$@" + echo "END ID SALT" + + # GCC only prints COLLECT_LTO_WRAPPER when invoked with just "-v", but we want + # the information from "-v -E -" as well, so just include both. + echo "BEGIN CC" + bash -c "${CC} -v" + bash -c "${CC} -v -E -xc -o /dev/null - < /dev/null" + bash -c "${CC} -v -E -xobjective-c -o /dev/null - < /dev/null" + echo "END CC" + + echo "BEGIN CXX" + bash -c "${CXX} -v" + bash -c "${CXX} -v -E -xc++ -o /dev/null - < /dev/null" + bash -c "${CXX} -v -E -xobjective-c++ -o /dev/null - < /dev/null" + echo "END CXX" + + echo "BEGIN AR" + bash -c "${AR} --version" + env | grep '^AR_' + echo "ZERO_AR_DATE=${ZERO_AR_DATE}" + echo "END AR" + + echo "BEGIN RANLIB" + bash -c "${RANLIB} --version" + env | grep '^RANLIB_' + echo "END RANLIB" + + echo "BEGIN STRIP" + bash -c "${STRIP} --version" + env | grep '^STRIP_' + echo "END STRIP" + + echo "END ALL" +) | if [ -n "$DEBUG" ] && command -v tee > /dev/null 2>&1; then + # When debugging and `tee` is available, output the preimage to stderr + # in addition to passing through stdin to stdout + tee >(cat 1>&2) + else + # Otherwise, passthrough stdin to stdout + cat + fi | ${SHA256SUM} - | cut -d' ' -f1 From 4a573fbbee6310039eadad8f9be3930e88b1caab Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 17:48:54 -0400 Subject: [PATCH 121/391] build, qt: Align frameworks with macOS codesign tool requirements Currently the codesign tool fails to sign copied frameworks. --- contrib/macdeploy/macdeployqtplus | 67 +++++++++++++++---------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 759dbdb3b2..9588ce4a50 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -245,48 +245,47 @@ def copyFramework(framework: FrameworkInfo, path: str, verbose: int) -> Optional toDir = os.path.join(path, framework.destinationDirectory) toPath = os.path.join(toDir, framework.binaryName) - if not os.path.exists(fromPath): - raise RuntimeError(f"No file at {fromPath}") - if os.path.exists(toPath): - return None # Already there + if framework.isDylib(): + if not os.path.exists(fromPath): + raise RuntimeError(f"No file at {fromPath}") - if not os.path.exists(toDir): - os.makedirs(toDir) + if os.path.exists(toPath): + return None # Already there - shutil.copy2(fromPath, toPath) - if verbose: - print("Copied:", fromPath) - print(" to:", toPath) + if not os.path.exists(toDir): + os.makedirs(toDir) + + shutil.copy2(fromPath, toPath) + if verbose: + print("Copied:", fromPath) + print(" to:", toPath) + else: + to_dir = os.path.join(path, "Contents", "Frameworks", framework.frameworkName) + if os.path.exists(to_dir): + return None # Already there + + from_dir = framework.frameworkPath + if not os.path.exists(from_dir): + raise RuntimeError(f"No directory at {from_dir}") + + shutil.copytree(from_dir, to_dir, symlinks=True) + if verbose: + print("Copied:", from_dir) + print(" to:", to_dir) + + headers_link = os.path.join(to_dir, "Headers") + if os.path.exists(headers_link): + os.unlink(headers_link) + + headers_dir = os.path.join(to_dir, framework.binaryDirectory, "Headers") + if os.path.exists(headers_dir): + shutil.rmtree(headers_dir) permissions = os.stat(toPath) if not permissions.st_mode & stat.S_IWRITE: os.chmod(toPath, permissions.st_mode | stat.S_IWRITE) - if not framework.isDylib(): # Copy resources for real frameworks - - linkfrom = os.path.join(path, "Contents","Frameworks", framework.frameworkName, "Versions", "Current") - linkto = framework.version - if not os.path.exists(linkfrom): - os.symlink(linkto, linkfrom) - print("Linked:", linkfrom, "->", linkto) - fromResourcesDir = framework.sourceResourcesDirectory - if os.path.exists(fromResourcesDir): - toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory) - shutil.copytree(fromResourcesDir, toResourcesDir, symlinks=True) - if verbose: - print("Copied resources:", fromResourcesDir) - print(" to:", toResourcesDir) - fromContentsDir = framework.sourceVersionContentsDirectory - if not os.path.exists(fromContentsDir): - fromContentsDir = framework.sourceContentsDirectory - if os.path.exists(fromContentsDir): - toContentsDir = os.path.join(path, framework.destinationVersionContentsDirectory) - shutil.copytree(fromContentsDir, toContentsDir, symlinks=True) - if verbose: - print("Copied Contents:", fromContentsDir) - print(" to:", toContentsDir) - return toPath def deployFrameworks(frameworks: List[FrameworkInfo], bundlePath: str, binaryPath: str, strip: bool, verbose: int, deploymentInfo: Optional[DeploymentInfo] = None) -> DeploymentInfo: From 0d218cd3ecf28975697b7fd457e7fa6dbddbc427 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 17:53:10 -0400 Subject: [PATCH 122/391] build, qt: (Re-)sign package Starting with macOS 11 on Apple silicon, executables must be signed before they are allowed to run. --- contrib/macdeploy/macdeployqtplus | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 9588ce4a50..ef8887f30e 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -16,7 +16,7 @@ # along with this program. If not, see . # -import sys, re, os, shutil, stat, os.path +import sys, re, os, platform, shutil, stat, subprocess, os.path from argparse import ArgumentParser from ds_store import DSStore from mac_alias import Alias @@ -541,6 +541,8 @@ ds.flush() ds.close() # ------------------------------------------------ +if platform.system() == "Darwin": + subprocess.check_call(f"codesign --deep --force --sign - {target}", shell=True) if config.dmg is not None: From 544debdfdf0e63e1a9382e77294b4783e480fa94 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 19:05:08 -0400 Subject: [PATCH 123/391] build: Try posix-specific CXX first for mingw32 host --- depends/hosts/mingw32.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index dbfb62fdcf..2080f80ce7 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -1,3 +1,7 @@ +ifneq ($(shell which $(host)-g++-posix),) +mingw32_CXX := $(host)-g++-posix +endif + mingw32_CFLAGS=-pipe mingw32_CXXFLAGS=$(mingw32_CFLAGS) From a2b2e5f2e8d6a57d070d667d7005402aa65b576f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 19:07:15 -0400 Subject: [PATCH 124/391] doc: Drop no longer required notes for Windows builds --- doc/build-windows.md | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/doc/build-windows.md b/doc/build-windows.md index 8e83f027d5..e1a887c282 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -81,10 +81,6 @@ The first step is to install the mingw-w64 cross-compilation tool chain: sudo apt install g++-mingw-w64-x86-64 -Ubuntu Bionic 18.04 [1](#footnote1): - - sudo update-alternatives --config x86_64-w64-mingw32-g++ # Set the default mingw32 g++ compiler option to posix. - Once the toolchain is installed the build steps are common: Note that for WSL the PRCYCoin source path MUST be somewhere in the default mount file system, for @@ -117,14 +113,4 @@ way. This will install to `c:\workspace\prcycoin`, for example: You can also create an installer using: - make deploy - -Footnotes ---------- - -1: Starting from Ubuntu Xenial 16.04, both the 32 and 64 bit Mingw-w64 packages install two different -compiler options to allow a choice between either posix or win32 threads. The default option is win32 threads which is the more -efficient since it will result in binary code that links directly with the Windows kernel32.lib. Unfortunately, the headers -required to support win32 threads conflict with some of the classes in the C++11 standard library, in particular std::mutex. -It's not possible to build the PRCYCoin code using the win32 version of the Mingw-w64 cross compilers (at least not without -modifying headers in the PRCYCoin source code). + make deploy \ No newline at end of file From 26666d2821333abf761ccf7df907fedc2aa9adfe Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 19:10:27 -0400 Subject: [PATCH 125/391] build: Replace `which` command with `command -v` This change made in a way that is compatible with GNU Make versions older than 4.3. --- depends/hosts/mingw32.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index 2080f80ce7..18045fcc25 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -1,4 +1,4 @@ -ifneq ($(shell which $(host)-g++-posix),) +ifneq ($(shell $(SHELL) $(.SHELLFLAGS) "command -v $(host)-g++-posix"),) mingw32_CXX := $(host)-g++-posix endif From 8fd8f99e743561a7bbff2a97170c220b0c6323cf Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 14:19:11 -0400 Subject: [PATCH 126/391] doc: Add build guide for OpenBSD 5.7 Add a specific build guide for OpenBSD. This is slightly different than building for Linux due to different dependencies, and a compiler issue. Update README.md --- doc/README.md | 1 + doc/build-openbsd.md | 187 +++++++++++++++++++++++++++++++++++++++++++ doc/build-unix.md | 2 + 3 files changed, 190 insertions(+) create mode 100644 doc/build-openbsd.md diff --git a/doc/README.md b/doc/README.md index 58d8db63c6..063a8e1dbb 100644 --- a/doc/README.md +++ b/doc/README.md @@ -39,6 +39,7 @@ The following are developer notes on how to build PRCYCoin on your native platfo - [macOS Build Notes](build-osx.md) - [Unix Build Notes](build-unix.md) - [Windows Build Notes](build-windows.md) +- [OpenBSD Build Notes](build-openbsd.md) - [Gitian Building Guide](gitian-building.md) Development diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md new file mode 100644 index 0000000000..28fa784515 --- /dev/null +++ b/doc/build-openbsd.md @@ -0,0 +1,187 @@ +OpenBSD build guide +====================== +(updated for OpenBSD 5.7) + +This guide describes how to build bitcoind and command-line utilities on OpenBSD. + +As OpenBSD is most common as a server OS, we will not bother with the GUI. + +Preparation +------------- + +Run the following as root to install the base dependencies for building: + +```bash +pkg_add gmake libtool libevent +pkg_add autoconf # (select highest version, e.g. 2.69) +pkg_add automake # (select highest version, e.g. 1.15) +pkg_add python # (select version 2.7.x, not 3.x) +ln -sf /usr/local/bin/python2.7 /usr/local/bin/python2 +``` + +The default C++ compiler that comes with OpenBSD 5.7 is g++ 4.2. This version is old (from 2007), and is not able to compile the current version of Bitcoin Core. It is possible to patch it up to compile, but with the planned transition to C++11 this is a losing battle. So here we will be installing a newer compiler. + +GCC +------- + +You can install a newer version of gcc with: + +```bash +pkg_add g++ # (select newest 4.x version, e.g. 4.9.2) +``` + +This compiler will not overwrite the system compiler, it will be installed as `egcc` and `eg++` in `/usr/local/bin`. + +### Building boost + +Do not use `pkg_add boost`! The boost version installed thus is compiled using the `g++` compiler not `eg++`, which will result in a conflict between `/usr/local/lib/libestdc++.so.XX.0` and `/usr/lib/libstdc++.so.XX.0`, resulting in a test crash: + + test_bitcoin:/usr/lib/libstdc++.so.57.0: /usr/local/lib/libestdc++.so.17.0 : WARNING: symbol(_ZN11__gnu_debug17_S_debug_me ssagesE) size mismatch, relink your program + ... + Segmentation fault (core dumped) + +This makes it necessary to build boost, or at least the parts used by Bitcoin Core, manually: + +``` +# Pick some path to install boost to, here we create a directory within the bitcoin directory +BITCOIN_ROOT=$(pwd) +BOOST_PREFIX="${BITCOIN_ROOT}/boost" +mkdir -p $BOOST_PREFIX + +# Fetch the source and verify that it is not tampered with +wget http://heanet.dl.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.bz2 +echo '727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca boost_1_59_0.tar.bz2' | sha256 -c +# MUST output: (SHA256) boost_1_59_0.tar.bz2: OK +tar -xjf boost_1_59_0.tar.bz2 + +# Boost 1.59 needs two small patches for OpenBSD +cd boost_1_59_0 +# Also here: https://gist.githubusercontent.com/laanwj/bf359281dc319b8ff2e1/raw/92250de8404b97bb99d72ab898f4a8cb35ae1ea3/patch-boost_test_impl_execution_monitor_ipp.patch +patch -p0 < /usr/ports/devel/boost/patches/patch-boost_test_impl_execution_monitor_ipp +# https://github.com/boostorg/filesystem/commit/90517e459681790a091566dce27ca3acabf9a70c +sed 's/__OPEN_BSD__/__OpenBSD__/g' < libs/filesystem/src/path.cpp > libs/filesystem/src/path.cpp.tmp +mv libs/filesystem/src/path.cpp.tmp libs/filesystem/src/path.cpp + +# Build w/ minimum configuration necessary for bitcoin +echo 'using gcc : : eg++ : "-fvisibility=hidden -fPIC" "" "ar" "strip" "ranlib" "" : ;' > user-config.jam +config_opts="runtime-link=shared threadapi=pthread threading=multi link=static variant=release --layout=tagged --build-type=complete --user-config=user-config.jam -sNO_BZIP2=1" +./bootstrap.sh --without-icu --with-libraries=chrono,filesystem,program_options,system,thread,test +./b2 -d2 -j2 -d1 ${config_opts} --prefix=${BOOST_PREFIX} stage +./b2 -d0 -j4 ${config_opts} --prefix=${BOOST_PREFIX} install +``` + +### OpenSSL + +OpenBSD uses a replacement of OpenSSL: LibreSSL. This can cause compatibility issues, hence `./configure` will bark if you try to compile with this library: + + Detected LibreSSL: This is NOT supported, and may break consensus compatibility! + +To install a 'real' OpenSSL use: + + pkg_add openssl + +Any program linked against this library can only be used after setting the dynamic library path: + + export LD_LIBRARY_PATH="/usr/local/lib/eopenssl" + +(otherwise there will be an error about not being able to find `libcrypto.so.1.0`) + +Alternatively, pass `--with-libressl` to `./configure`, however as the warning says, this is NOT supported, and may cause problems syncing the chain, or the node to fork off the network in unexpected circumstances. + +### Building BerkeleyDB + +BerkeleyDB is only necessary for the wallet functionality. To skip this, pass `--disable-wallet` to `./configure`. + +See "Berkeley DB" in [build_unix.md](build_unix.md) for instructions on how to build BerkeleyDB 4.8. +You cannot use the BerkeleyDB library from ports, for the same reason as boost above (g++/libstd++ incompatibility). + +```bash +# Pick some path to install BDB to, here we create a directory within the bitcoin directory +BITCOIN_ROOT=$(pwd) +BDB_PREFIX="${BITCOIN_ROOT}/db4" +mkdir -p $BDB_PREFIX + +# Fetch the source and verify that it is not tampered with +wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' +echo '12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz' | sha256 -c +# MUST output: (SHA256) db-4.8.30.NC.tar.gz: OK +tar -xzf db-4.8.30.NC.tar.gz + +# Build the library and install to specified prefix +cd db-4.8.30.NC/build_unix/ +# Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime +../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX CC=egcc CXX=eg++ CPP=ecpp +make install +``` + +### Building Bitcoin Core + +**Important**: use `gmake`, not `make`. The non-GNU `make` will exit with a horrible error. + +Preparation: +```bash +export AUTOCONF_VERSION=2.69 # replace this with the autoconf version that you installed +export AUTOMAKE_VERSION=1.15 # replace this with the automake version that you installed +./autogen.sh +``` + +To configure with wallet: +```bash +./configure --with-gui=no --with-boost=$BOOST_PREFIX \ + CC=egcc CXX=eg++ CPP=ecpp \ + SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ + CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" \ + LDFLAGS="-L${BDB_PREFIX}/lib/" CPPFLAGS="-I${BDB_PREFIX}/include/" +``` + +To configure without wallet: +```bash +./configure --disable-wallet --with-gui=no --with-boost=$BOOST_PREFIX \ + CC=egcc CXX=eg++ CPP=ecpp \ + SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ + CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" +``` + +Build and run the tests: +```bash +gmake +export LD_LIBRARY_PATH="/usr/local/lib/eopenssl" +gmake check +``` + +Clang (not currently working) +------------------------------ + +Using a newer g++ results in linking the new code to a new libstdc++. +Libraries built with the old g++, will still import the old library. +This gives conflicts, necessitating rebuild of all C++ dependencies of the application. + +With clang this can - at least theoretically - be avoided because it uses the +base system's libstdc++. + +```bash +pkg_add llvm boost +``` + +```bash +./configure --disable-wallet --with-gui=no CC=clang CXX=clang++ \ + SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ + CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" +gmake +``` + +However, this does not appear to work. Compilation succeeds, but link fails +with many 'local symbol discarded' errors: + + local symbol 150: discarded in section `.text._ZN10tinyformat6detail14FormatIterator6finishEv' from libbitcoin_util.a(libbitcoin_util_a-random.o) + local symbol 151: discarded in section `.text._ZN10tinyformat6detail14FormatIterator21streamStateFromFormatERSoRjPKcii' from libbitcoin_util.a(libbitcoin_util_a-random.o) + local symbol 152: discarded in section `.text._ZN10tinyformat6detail12convertToIntIA13_cLb0EE6invokeERA13_Kc' from libbitcoin_util.a(libbitcoin_util_a-random.o) + +According to similar reported errors this is a binutils (ld) issue in 2.15, the +version installed by OpenBSD 5.7: + +- http://openbsd-archive.7691.n7.nabble.com/UPDATE-cppcheck-1-65-td248900.html +- https://llvm.org/bugs/show_bug.cgi?id=9758 + +There is no known workaround for this. + diff --git a/doc/build-unix.md b/doc/build-unix.md index 8155cb020c..1f164783e4 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -2,6 +2,8 @@ UNIX BUILD NOTES ==================== Some notes on how to build PRCYCoin in Unix. +(for OpenBSD specific instructions, see [build-openbsd.md](build-openbsd.md)) + Note --------------------- Always use absolute paths to configure and compile PRCYCoin and the dependencies, From aab9f9d313e0ed8e20de3abe4101fb47db48ddb1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 14:33:26 -0400 Subject: [PATCH 127/391] doc: Update build-openbsd for 0.13.0+ and OpenBSD 5.9 - Python 3 now supported. - Bump boost version to 1.61 - one boost patch no longer needed. - All checked with OpenBSD 5.9, except for the clang part, I left this as-is for someone adventurous. - Mention overriding resource limits, OpenBSD's default ulimit does not suffice for building Bitcoin Core with gcc 4.9.3. --- doc/build-openbsd.md | 55 ++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 28fa784515..90c710c467 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,6 +1,6 @@ OpenBSD build guide ====================== -(updated for OpenBSD 5.7) +(updated for OpenBSD 5.9) This guide describes how to build bitcoind and command-line utilities on OpenBSD. @@ -15,11 +15,10 @@ Run the following as root to install the base dependencies for building: pkg_add gmake libtool libevent pkg_add autoconf # (select highest version, e.g. 2.69) pkg_add automake # (select highest version, e.g. 1.15) -pkg_add python # (select version 2.7.x, not 3.x) -ln -sf /usr/local/bin/python2.7 /usr/local/bin/python2 +pkg_add python # (select highest version, e.g. 3.5) ``` -The default C++ compiler that comes with OpenBSD 5.7 is g++ 4.2. This version is old (from 2007), and is not able to compile the current version of Bitcoin Core. It is possible to patch it up to compile, but with the planned transition to C++11 this is a losing battle. So here we will be installing a newer compiler. +The default C++ compiler that comes with OpenBSD 5.9 is g++ 4.2. This version is old (from 2007), and is not able to compile the current version of Bitcoin Core, primarily as it has no C++11 support, but even before there were issues. So here we will be installing a newer compiler. GCC ------- @@ -27,7 +26,7 @@ GCC You can install a newer version of gcc with: ```bash -pkg_add g++ # (select newest 4.x version, e.g. 4.9.2) +pkg_add g++ # (select newest 4.x version, e.g. 4.9.3) ``` This compiler will not overwrite the system compiler, it will be installed as `egcc` and `eg++` in `/usr/local/bin`. @@ -38,7 +37,7 @@ Do not use `pkg_add boost`! The boost version installed thus is compiled using t test_bitcoin:/usr/lib/libstdc++.so.57.0: /usr/local/lib/libestdc++.so.17.0 : WARNING: symbol(_ZN11__gnu_debug17_S_debug_me ssagesE) size mismatch, relink your program ... - Segmentation fault (core dumped) + Segmentation fault (core dumped) This makes it necessary to build boost, or at least the parts used by Bitcoin Core, manually: @@ -49,18 +48,15 @@ BOOST_PREFIX="${BITCOIN_ROOT}/boost" mkdir -p $BOOST_PREFIX # Fetch the source and verify that it is not tampered with -wget http://heanet.dl.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.bz2 -echo '727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca boost_1_59_0.tar.bz2' | sha256 -c -# MUST output: (SHA256) boost_1_59_0.tar.bz2: OK -tar -xjf boost_1_59_0.tar.bz2 +curl -o boost_1_61_0.tar.bz2 http://heanet.dl.sourceforge.net/project/boost/boost/1.61.0/boost_1_61_0.tar.bz2 +echo 'a547bd06c2fd9a71ba1d169d9cf0339da7ebf4753849a8f7d6fdb8feee99b640 boost_1_61_0.tar.bz2' | sha256 -c +# MUST output: (SHA256) boost_1_61_0.tar.bz2: OK +tar -xjf boost_1_61_0.tar.bz2 -# Boost 1.59 needs two small patches for OpenBSD -cd boost_1_59_0 +# Boost 1.61 needs one small patch for OpenBSD +cd boost_1_61_0 # Also here: https://gist.githubusercontent.com/laanwj/bf359281dc319b8ff2e1/raw/92250de8404b97bb99d72ab898f4a8cb35ae1ea3/patch-boost_test_impl_execution_monitor_ipp.patch -patch -p0 < /usr/ports/devel/boost/patches/patch-boost_test_impl_execution_monitor_ipp -# https://github.com/boostorg/filesystem/commit/90517e459681790a091566dce27ca3acabf9a70c -sed 's/__OPEN_BSD__/__OpenBSD__/g' < libs/filesystem/src/path.cpp > libs/filesystem/src/path.cpp.tmp -mv libs/filesystem/src/path.cpp.tmp libs/filesystem/src/path.cpp +patch -p0 < /usr/ports/devel/boost/patches/patch-boost_test_impl_execution_monitor_ipp # Build w/ minimum configuration necessary for bitcoin echo 'using gcc : : eg++ : "-fvisibility=hidden -fPIC" "" "ar" "strip" "ranlib" "" : ;' > user-config.jam @@ -102,7 +98,7 @@ BDB_PREFIX="${BITCOIN_ROOT}/db4" mkdir -p $BDB_PREFIX # Fetch the source and verify that it is not tampered with -wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' +curl -o db-4.8.30.NC.tar.gz 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' echo '12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz' | sha256 -c # MUST output: (SHA256) db-4.8.30.NC.tar.gz: OK tar -xzf db-4.8.30.NC.tar.gz @@ -110,10 +106,26 @@ tar -xzf db-4.8.30.NC.tar.gz # Build the library and install to specified prefix cd db-4.8.30.NC/build_unix/ # Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime -../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX CC=egcc CXX=eg++ CPP=ecpp -make install +../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX CC=egcc CXX=eg++ CPP=ecpp +make install # do NOT use -jX, this is broken ``` +### Resource limits + +The standard ulimit restrictions in OpenBSD are very strict: + + data(kbytes) 1572864 + +This is, unfortunately, no longer enough to compile some `.cpp` files in the project, +at least with gcc 4.9.3 (see issue https://github.com/bitcoin/bitcoin/issues/6658). +If your user is in the `staff` group the limit can be raised with: + + ulimit -d 3000000 + +The change will only affect the current shell and processes spawned by it. To +make the change system-wide, change `datasize-cur` and `datasize-max` in +`/etc/login.conf`, and reboot. + ### Building Bitcoin Core **Important**: use `gmake`, not `make`. The non-GNU `make` will exit with a horrible error. @@ -124,6 +136,7 @@ export AUTOCONF_VERSION=2.69 # replace this with the autoconf version that you i export AUTOMAKE_VERSION=1.15 # replace this with the automake version that you installed ./autogen.sh ``` +Make sure `BDB_PREFIX` and `BOOST_PREFIX` are set to the appropriate paths from the above steps. To configure with wallet: ```bash @@ -144,8 +157,7 @@ To configure without wallet: Build and run the tests: ```bash -gmake -export LD_LIBRARY_PATH="/usr/local/lib/eopenssl" +gmake # can use -jX here for parallelism gmake check ``` @@ -184,4 +196,3 @@ version installed by OpenBSD 5.7: - https://llvm.org/bugs/show_bug.cgi?id=9758 There is no known workaround for this. - From f68400932f2bbdf9eb2e9dae8ad8555aff3ca6ce Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 14:34:10 -0400 Subject: [PATCH 128/391] doc: Add build instructions for FreeBSD --- doc/build-unix.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/doc/build-unix.md b/doc/build-unix.md index 1f164783e4..b11434c13d 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -283,3 +283,35 @@ To build executables for ARM: For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory. + +Building on FreeBSD +-------------------- + +(Updated as of FreeBSD 10.3) + +Clang is installed by default as `cc` compiler, this makes it easier to get +started than on [OpenBSD](build-openbsd.md). Installing dependencies: + + pkg install autoconf automake libtool pkgconf + pkg install boost-libs openssl libevent2 + +(`libressl` instead of `openssl` will also work) + +For the wallet (optional): + + pkg install db5 + +This will give a warning "configure: WARNING: Found Berkeley DB other +than 4.8; wallets opened by this build will not be portable!", but as FreeBSD never +had a binary release, this may not matter. If backwards compatibility +with 4.8-built Bitcoin Core is needed follow the steps under "Berkeley DB" above. + +Then build using: + + ./autogen.sh + ./configure --with-incompatible-bdb CPPFLAGS=-I/usr/local/include/db5 LDFLAGS=-L/usr/local/lib/db5 + make + +*Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement). +It is not suitable for debugging a multi-threaded C++ program, not even for getting backtraces. Please install the package `gdb` and +use the versioned gdb command e.g. `gdb7111`. \ No newline at end of file From 9cfa1d28e549a03ce6ed7a70d804c97f2b83968a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 14:40:17 -0400 Subject: [PATCH 129/391] Update OpenBSD and FreeBSD build steps Re-try with most recent versions, and use BDB_CFLAGS/BDB_LIBS to directly point at BerkeleyDB instead of CPPFLAGS hacks. --- doc/build-openbsd.md | 6 ++++-- doc/build-unix.md | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 90c710c467..81eb09b180 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,6 +1,6 @@ OpenBSD build guide ====================== -(updated for OpenBSD 5.9) +(updated for OpenBSD 6.0) This guide describes how to build bitcoind and command-line utilities on OpenBSD. @@ -144,7 +144,7 @@ To configure with wallet: CC=egcc CXX=eg++ CPP=ecpp \ SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" \ - LDFLAGS="-L${BDB_PREFIX}/lib/" CPPFLAGS="-I${BDB_PREFIX}/include/" + BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include" ``` To configure without wallet: @@ -164,6 +164,8 @@ gmake check Clang (not currently working) ------------------------------ +WARNING: This is outdated, needs to be updated for OpenBSD 6.0 and re-tried. + Using a newer g++ results in linking the new code to a new libstdc++. Libraries built with the old g++, will still import the old library. This gives conflicts, necessitating rebuild of all C++ dependencies of the application. diff --git a/doc/build-unix.md b/doc/build-unix.md index b11434c13d..12972db8e9 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -287,7 +287,7 @@ For further documentation on the depends system see [README.md](../depends/READM Building on FreeBSD -------------------- -(Updated as of FreeBSD 10.3) +(Updated as of FreeBSD 11.0) Clang is installed by default as `cc` compiler, this makes it easier to get started than on [OpenBSD](build-openbsd.md). Installing dependencies: @@ -309,7 +309,7 @@ with 4.8-built Bitcoin Core is needed follow the steps under "Berkeley DB" above Then build using: ./autogen.sh - ./configure --with-incompatible-bdb CPPFLAGS=-I/usr/local/include/db5 LDFLAGS=-L/usr/local/lib/db5 + ./configure --with-incompatible-bdb BDB_CFLAGS="-I/usr/local/include/db5" BDB_LIBS="-L/usr/local/lib -ldb_cxx-5" make *Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement). From 4c56ba81349b81d83ea089e6aee5d1e92972a026 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 14:48:08 -0400 Subject: [PATCH 130/391] doc: Update FreeBSD build instructions to use bdb4 Use Berkeley DB 4 as recommended on other platforms. --- doc/build-unix.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 12972db8e9..bae8d46b55 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -299,17 +299,13 @@ started than on [OpenBSD](build-openbsd.md). Installing dependencies: For the wallet (optional): - pkg install db5 - -This will give a warning "configure: WARNING: Found Berkeley DB other -than 4.8; wallets opened by this build will not be portable!", but as FreeBSD never -had a binary release, this may not matter. If backwards compatibility -with 4.8-built Bitcoin Core is needed follow the steps under "Berkeley DB" above. + ./contrib/install_db4.sh `pwd` + setenv BDB_PREFIX $PWD/db4 Then build using: ./autogen.sh - ./configure --with-incompatible-bdb BDB_CFLAGS="-I/usr/local/include/db5" BDB_LIBS="-L/usr/local/lib -ldb_cxx-5" + ./configure BDB_CFLAGS="-I${BDB_PREFIX}/include" BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx" make *Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement). From 04b34f3fb98c4a42636cd06cb3d08b74d362a2f8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 14:53:42 -0400 Subject: [PATCH 131/391] [doc] Create build-netbsd.md --- doc/build-netbsd.md | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 doc/build-netbsd.md diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md new file mode 100644 index 0000000000..5bf2d6b59b --- /dev/null +++ b/doc/build-netbsd.md @@ -0,0 +1,49 @@ +NetBSD build guide +====================== +(updated for NetBSD 7.0) + +This guide describes how to build bitcoind and command-line utilities on NetBSD. + +This guide does not contain instructions for building the GUI. + +Preparation +------------- + +You will need the following modules, which can be installed via pkgsrc or pkgin: + +``` +autoconf +automake +boost +db4 +git +gmake +libevent +libtool +python27 +``` + +Download the source code: +``` +git clone https://github.com/bitcoin/bitcoin +``` + +See [dependencies.md](dependencies.md) for a complete overview. + +### Building Bitcoin Core + +**Important**: Use `gmake` (the non-GNU `make` will exit with an error). + +With wallet: +``` +./autogen.sh +./configure CPPFLAGS="-I/usr/pkg/include" LDFLAGS="-L/usr/pkg/lib" BOOST_CPPFLAGS="-I/usr/pkg/include" BOOST_LDFLAGS="-L/usr/pkg/lib" +gmake +``` + +Without wallet: +``` +./autogen.sh +./configure --disable-wallet CPPFLAGS="-I/usr/pkg/include" LDFLAGS="-L/usr/pkg/lib" BOOST_CPPFLAGS="-I/usr/pkg/include" BOOST_LDFLAGS="-L/usr/pkg/lib" +gmake +``` From 6802e1d087e9abd29a985fa5c74d3e9b504e29b0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 14:58:55 -0400 Subject: [PATCH 132/391] Add NetBSD build instruction links --- doc/README.md | 1 + doc/build-unix.md | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/README.md b/doc/README.md index 063a8e1dbb..1f1c7a8b53 100644 --- a/doc/README.md +++ b/doc/README.md @@ -40,6 +40,7 @@ The following are developer notes on how to build PRCYCoin on your native platfo - [Unix Build Notes](build-unix.md) - [Windows Build Notes](build-windows.md) - [OpenBSD Build Notes](build-openbsd.md) +- [NetBSD Build Notes](build-netbsd.md) - [Gitian Building Guide](gitian-building.md) Development diff --git a/doc/build-unix.md b/doc/build-unix.md index bae8d46b55..e615169823 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -2,7 +2,8 @@ UNIX BUILD NOTES ==================== Some notes on how to build PRCYCoin in Unix. -(for OpenBSD specific instructions, see [build-openbsd.md](build-openbsd.md)) +(For BSD specific instructions, see [build-openbsd.md](build-openbsd.md) and/or +[build-netbsd.md](build-netbsd.md)) Note --------------------- From 6b3052fcf473148fbbaeecfe40e2a41add3d7d0f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 15:03:15 -0400 Subject: [PATCH 133/391] doc: split FreeBSD build instructions out of build-unix.md docs: Linked to the 'Building on FreeBSD' section of the Unix guide where it lists BSD specific guides. Created a FreeBSD build guide (doc/build-freebsd.md). Added in warning about the version of 'gdb' installed by default. Removed the FreeBSD build instructions now that they have their own guide (doc/build-freebsd.md). Updated the sentence to refer to the BSD guides in the 'doc' directory for more specific BSD build instructions. Minor grammatical fix. --- doc/README.md | 1 + doc/build-freebsd.md | 46 ++++++++++++++++++++++++++++++++++++++++++++ doc/build-unix.md | 31 +---------------------------- 3 files changed, 48 insertions(+), 30 deletions(-) create mode 100644 doc/build-freebsd.md diff --git a/doc/README.md b/doc/README.md index 1f1c7a8b53..6f9f149ec4 100644 --- a/doc/README.md +++ b/doc/README.md @@ -39,6 +39,7 @@ The following are developer notes on how to build PRCYCoin on your native platfo - [macOS Build Notes](build-osx.md) - [Unix Build Notes](build-unix.md) - [Windows Build Notes](build-windows.md) +- [FreeBSD Build Notes](build-freeebsd.md) - [OpenBSD Build Notes](build-openbsd.md) - [NetBSD Build Notes](build-netbsd.md) - [Gitian Building Guide](gitian-building.md) diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md new file mode 100644 index 0000000000..c2e4e36dff --- /dev/null +++ b/doc/build-freebsd.md @@ -0,0 +1,46 @@ +FreeBSD build guide +====================== +(updated for FreeBSD 11.1) + +This guide describes how to build bitcoind and command-line utilities on FreeBSD. + +This guide does not contain instructions for building the GUI. + +## Preparation + +You will need the following dependencies, which can be installed as root via pkg: + +``` +pkg install autoconf automake boost-libs git gmake libevent libtool openssl pkgconf +``` + +For the wallet (optional): +``` +./contrib/install_db4.sh `pwd` +export BDB_PREFIX='$PWD/db4' +``` + +See [dependencies.md](dependencies.md) for a complete overview. + +Download the source code: +``` +git clone https://github.com/bitcoin/bitcoin +``` + +## Building Bitcoin Core + +**Important**: Use `gmake` (the non-GNU `make` will exit with an error). + +``` +./autogen.sh + +./configure # to build with wallet OR +./configure --disable-wallet # to build without wallet + +gmake +``` + +*Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement). +It is not suitable for debugging a multi-threaded C++ program, not even for getting backtraces. Please install the package `gdb` and +use the versioned gdb command (e.g. `gdb7111`). + diff --git a/doc/build-unix.md b/doc/build-unix.md index e615169823..a74d1f573f 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -2,8 +2,7 @@ UNIX BUILD NOTES ==================== Some notes on how to build PRCYCoin in Unix. -(For BSD specific instructions, see [build-openbsd.md](build-openbsd.md) and/or -[build-netbsd.md](build-netbsd.md)) +(For BSD specific instructions, see `build-*bsd.md` in this directory.) Note --------------------- @@ -284,31 +283,3 @@ To build executables for ARM: For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory. - -Building on FreeBSD --------------------- - -(Updated as of FreeBSD 11.0) - -Clang is installed by default as `cc` compiler, this makes it easier to get -started than on [OpenBSD](build-openbsd.md). Installing dependencies: - - pkg install autoconf automake libtool pkgconf - pkg install boost-libs openssl libevent2 - -(`libressl` instead of `openssl` will also work) - -For the wallet (optional): - - ./contrib/install_db4.sh `pwd` - setenv BDB_PREFIX $PWD/db4 - -Then build using: - - ./autogen.sh - ./configure BDB_CFLAGS="-I${BDB_PREFIX}/include" BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx" - make - -*Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement). -It is not suitable for debugging a multi-threaded C++ program, not even for getting backtraces. Please install the package `gdb` and -use the versioned gdb command e.g. `gdb7111`. \ No newline at end of file From 06fa1bce4cae0e9251345e5fc94d8d07de021771 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 15:07:56 -0400 Subject: [PATCH 134/391] doc: Update build-openbsd for 6.1 - Bump "updated for" - Fix link to boost (haenet mirror is broken) - Upgrade boost version to 1.64 --- doc/build-openbsd.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 81eb09b180..0a4c50517d 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,6 +1,6 @@ OpenBSD build guide ====================== -(updated for OpenBSD 6.0) +(updated for OpenBSD 6.1) This guide describes how to build bitcoind and command-line utilities on OpenBSD. @@ -48,13 +48,13 @@ BOOST_PREFIX="${BITCOIN_ROOT}/boost" mkdir -p $BOOST_PREFIX # Fetch the source and verify that it is not tampered with -curl -o boost_1_61_0.tar.bz2 http://heanet.dl.sourceforge.net/project/boost/boost/1.61.0/boost_1_61_0.tar.bz2 -echo 'a547bd06c2fd9a71ba1d169d9cf0339da7ebf4753849a8f7d6fdb8feee99b640 boost_1_61_0.tar.bz2' | sha256 -c -# MUST output: (SHA256) boost_1_61_0.tar.bz2: OK -tar -xjf boost_1_61_0.tar.bz2 +curl -o boost_1_64_0.tar.bz2 https://netcologne.dl.sourceforge.net/project/boost/boost/1.64.0/boost_1_64_0.tar.bz2 +echo '7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332 boost_1_64_0.tar.bz2' | sha256 -c +# MUST output: (SHA256) boost_1_64_0.tar.bz2: OK +tar -xjf boost_1_64_0.tar.bz2 -# Boost 1.61 needs one small patch for OpenBSD -cd boost_1_61_0 +# Boost 1.64 needs one small patch for OpenBSD +cd boost_1_64_0 # Also here: https://gist.githubusercontent.com/laanwj/bf359281dc319b8ff2e1/raw/92250de8404b97bb99d72ab898f4a8cb35ae1ea3/patch-boost_test_impl_execution_monitor_ipp.patch patch -p0 < /usr/ports/devel/boost/patches/patch-boost_test_impl_execution_monitor_ipp From 8e3132aa81ee48bdf39f93b30993583376444b40 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:14:54 -0400 Subject: [PATCH 135/391] [Docs] Update OpenBSD Build Instructions for OpenBSD 6.2 --- doc/build-openbsd.md | 108 ++++++++++--------------------------------- 1 file changed, 24 insertions(+), 84 deletions(-) diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 0a4c50517d..b55cefcc3b 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,10 +1,10 @@ OpenBSD build guide ====================== -(updated for OpenBSD 6.1) +(updated for OpenBSD 6.2) This guide describes how to build bitcoind and command-line utilities on OpenBSD. -As OpenBSD is most common as a server OS, we will not bother with the GUI. +OpenBSD is most commonly used as a server OS, so this guide does not contain instructions for building the GUI. Preparation ------------- @@ -12,60 +12,28 @@ Preparation Run the following as root to install the base dependencies for building: ```bash -pkg_add gmake libtool libevent +pkg_add git gmake libevent libtool pkg_add autoconf # (select highest version, e.g. 2.69) pkg_add automake # (select highest version, e.g. 1.15) -pkg_add python # (select highest version, e.g. 3.5) +pkg_add python # (select highest version, e.g. 3.6) +pkg_add boost + +git clone https://github.com/bitcoin/bitcoin.git ``` -The default C++ compiler that comes with OpenBSD 5.9 is g++ 4.2. This version is old (from 2007), and is not able to compile the current version of Bitcoin Core, primarily as it has no C++11 support, but even before there were issues. So here we will be installing a newer compiler. +See [dependencies.md](dependencies.md) for a complete overview. GCC ------- -You can install a newer version of gcc with: +The default C++ compiler that comes with OpenBSD 6.2 is g++ 4.2.1. This version is old (from 2007), and is not able to compile the current version of Bitcoin Core because it has no C++11 support. We'll install a newer version of GCC: ```bash -pkg_add g++ # (select newest 4.x version, e.g. 4.9.3) -``` - -This compiler will not overwrite the system compiler, it will be installed as `egcc` and `eg++` in `/usr/local/bin`. - -### Building boost - -Do not use `pkg_add boost`! The boost version installed thus is compiled using the `g++` compiler not `eg++`, which will result in a conflict between `/usr/local/lib/libestdc++.so.XX.0` and `/usr/lib/libstdc++.so.XX.0`, resulting in a test crash: - - test_bitcoin:/usr/lib/libstdc++.so.57.0: /usr/local/lib/libestdc++.so.17.0 : WARNING: symbol(_ZN11__gnu_debug17_S_debug_me ssagesE) size mismatch, relink your program - ... - Segmentation fault (core dumped) - -This makes it necessary to build boost, or at least the parts used by Bitcoin Core, manually: - -``` -# Pick some path to install boost to, here we create a directory within the bitcoin directory -BITCOIN_ROOT=$(pwd) -BOOST_PREFIX="${BITCOIN_ROOT}/boost" -mkdir -p $BOOST_PREFIX - -# Fetch the source and verify that it is not tampered with -curl -o boost_1_64_0.tar.bz2 https://netcologne.dl.sourceforge.net/project/boost/boost/1.64.0/boost_1_64_0.tar.bz2 -echo '7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332 boost_1_64_0.tar.bz2' | sha256 -c -# MUST output: (SHA256) boost_1_64_0.tar.bz2: OK -tar -xjf boost_1_64_0.tar.bz2 - -# Boost 1.64 needs one small patch for OpenBSD -cd boost_1_64_0 -# Also here: https://gist.githubusercontent.com/laanwj/bf359281dc319b8ff2e1/raw/92250de8404b97bb99d72ab898f4a8cb35ae1ea3/patch-boost_test_impl_execution_monitor_ipp.patch -patch -p0 < /usr/ports/devel/boost/patches/patch-boost_test_impl_execution_monitor_ipp - -# Build w/ minimum configuration necessary for bitcoin -echo 'using gcc : : eg++ : "-fvisibility=hidden -fPIC" "" "ar" "strip" "ranlib" "" : ;' > user-config.jam -config_opts="runtime-link=shared threadapi=pthread threading=multi link=static variant=release --layout=tagged --build-type=complete --user-config=user-config.jam -sNO_BZIP2=1" -./bootstrap.sh --without-icu --with-libraries=chrono,filesystem,program_options,system,thread,test -./b2 -d2 -j2 -d1 ${config_opts} --prefix=${BOOST_PREFIX} stage -./b2 -d0 -j4 ${config_opts} --prefix=${BOOST_PREFIX} install -``` + pkg_add g++ + ``` + This compiler will not overwrite the system compiler, it will be installed as `egcc` and `eg++` in `/usr/local/bin`. + ### OpenSSL OpenBSD uses a replacement of OpenSSL: LibreSSL. This can cause compatibility issues, hence `./configure` will bark if you try to compile with this library: @@ -88,7 +56,7 @@ Alternatively, pass `--with-libressl` to `./configure`, however as the warning s BerkeleyDB is only necessary for the wallet functionality. To skip this, pass `--disable-wallet` to `./configure`. -See "Berkeley DB" in [build_unix.md](build_unix.md) for instructions on how to build BerkeleyDB 4.8. +See "Berkeley DB" in [build-unix.md](build-unix.md#berkeley-db) for instructions on how to build BerkeleyDB 4.8. You cannot use the BerkeleyDB library from ports, for the same reason as boost above (g++/libstd++ incompatibility). ```bash @@ -116,8 +84,8 @@ The standard ulimit restrictions in OpenBSD are very strict: data(kbytes) 1572864 -This is, unfortunately, no longer enough to compile some `.cpp` files in the project, -at least with gcc 4.9.3 (see issue https://github.com/bitcoin/bitcoin/issues/6658). +This, unfortunately, may no longer be enough to compile some `.cpp` files in the project, +at least with GCC 4.9.4 (see issue [#6658](https://github.com/bitcoin/bitcoin/issues/6658)). If your user is in the `staff` group the limit can be raised with: ulimit -d 3000000 @@ -136,12 +104,11 @@ export AUTOCONF_VERSION=2.69 # replace this with the autoconf version that you i export AUTOMAKE_VERSION=1.15 # replace this with the automake version that you installed ./autogen.sh ``` -Make sure `BDB_PREFIX` and `BOOST_PREFIX` are set to the appropriate paths from the above steps. +Make sure `BDB_PREFIX` is set to the appropriate path from the above steps. To configure with wallet: ```bash -./configure --with-gui=no --with-boost=$BOOST_PREFIX \ - CC=egcc CXX=eg++ CPP=ecpp \ +./configure --with-gui=no CC=egcc CXX=eg++ CPP=ecpp \ SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" \ BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include" @@ -149,52 +116,25 @@ To configure with wallet: To configure without wallet: ```bash -./configure --disable-wallet --with-gui=no --with-boost=$BOOST_PREFIX \ - CC=egcc CXX=eg++ CPP=ecpp \ +./configure --disable-wallet --with-gui=no CC=egcc CXX=eg++ CPP=ecpp \ SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" ``` Build and run the tests: ```bash -gmake # can use -jX here for parallelism +gmake # use -jX here for parallelism gmake check ``` -Clang (not currently working) +Clang ------------------------------ -WARNING: This is outdated, needs to be updated for OpenBSD 6.0 and re-tried. - -Using a newer g++ results in linking the new code to a new libstdc++. -Libraries built with the old g++, will still import the old library. -This gives conflicts, necessitating rebuild of all C++ dependencies of the application. - -With clang this can - at least theoretically - be avoided because it uses the -base system's libstdc++. - -```bash -pkg_add llvm boost -``` - ```bash +pkg_add llvm ./configure --disable-wallet --with-gui=no CC=clang CXX=clang++ \ SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" -gmake +gmake # use -jX here for parallelism +gmake check ``` - -However, this does not appear to work. Compilation succeeds, but link fails -with many 'local symbol discarded' errors: - - local symbol 150: discarded in section `.text._ZN10tinyformat6detail14FormatIterator6finishEv' from libbitcoin_util.a(libbitcoin_util_a-random.o) - local symbol 151: discarded in section `.text._ZN10tinyformat6detail14FormatIterator21streamStateFromFormatERSoRjPKcii' from libbitcoin_util.a(libbitcoin_util_a-random.o) - local symbol 152: discarded in section `.text._ZN10tinyformat6detail12convertToIntIA13_cLb0EE6invokeERA13_Kc' from libbitcoin_util.a(libbitcoin_util_a-random.o) - -According to similar reported errors this is a binutils (ld) issue in 2.15, the -version installed by OpenBSD 5.7: - -- http://openbsd-archive.7691.n7.nabble.com/UPDATE-cppcheck-1-65-td248900.html -- https://llvm.org/bugs/show_bug.cgi?id=9758 - -There is no known workaround for this. From 01f3cd44f215c3c762e7b381a9a420f39db9ae48 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:18:54 -0400 Subject: [PATCH 136/391] doc: Update OpenBSD build instructions for 6.2 There is no more need to install a compiler. This simplifies instructions a lot. --- doc/build-openbsd.md | 93 ++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 56 deletions(-) diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index b55cefcc3b..1d1f33b328 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -23,17 +23,12 @@ git clone https://github.com/bitcoin/bitcoin.git See [dependencies.md](dependencies.md) for a complete overview. -GCC -------- +**Important**: From OpenBSD 6.2 onwards a C++11-supporting clang compiler is +part of the base image, and while building it is necessary to make sure that this +compiler is used and not ancient g++ 4.2.1. This is done by appending +`CC=cc CXX=c++` to configuration commands. Mixing different compilers +within the same executable will result in linker errors. -The default C++ compiler that comes with OpenBSD 6.2 is g++ 4.2.1. This version is old (from 2007), and is not able to compile the current version of Bitcoin Core because it has no C++11 support. We'll install a newer version of GCC: - -```bash - pkg_add g++ - ``` - - This compiler will not overwrite the system compiler, it will be installed as `egcc` and `eg++` in `/usr/local/bin`. - ### OpenSSL OpenBSD uses a replacement of OpenSSL: LibreSSL. This can cause compatibility issues, hence `./configure` will bark if you try to compile with this library: @@ -54,45 +49,23 @@ Alternatively, pass `--with-libressl` to `./configure`, however as the warning s ### Building BerkeleyDB -BerkeleyDB is only necessary for the wallet functionality. To skip this, pass `--disable-wallet` to `./configure`. +BerkeleyDB is only necessary for the wallet functionality. To skip this, pass +`--disable-wallet` to `./configure` and skip to the next section. -See "Berkeley DB" in [build-unix.md](build-unix.md#berkeley-db) for instructions on how to build BerkeleyDB 4.8. -You cannot use the BerkeleyDB library from ports, for the same reason as boost above (g++/libstd++ incompatibility). +It is recommended to use Berkeley DB 4.8. You cannot use the BerkeleyDB library +from ports, for the same reason as boost above (g++/libstd++ incompatibility). +If you have to build it yourself, you can use [the installation script included +in contrib/](/contrib/install_db4.sh) like so -```bash -# Pick some path to install BDB to, here we create a directory within the bitcoin directory -BITCOIN_ROOT=$(pwd) -BDB_PREFIX="${BITCOIN_ROOT}/db4" -mkdir -p $BDB_PREFIX - -# Fetch the source and verify that it is not tampered with -curl -o db-4.8.30.NC.tar.gz 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' -echo '12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz' | sha256 -c -# MUST output: (SHA256) db-4.8.30.NC.tar.gz: OK -tar -xzf db-4.8.30.NC.tar.gz - -# Build the library and install to specified prefix -cd db-4.8.30.NC/build_unix/ -# Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime -../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX CC=egcc CXX=eg++ CPP=ecpp -make install # do NOT use -jX, this is broken +```shell +./contrib/install_db4.sh `pwd` CC=cc CXX=c++ ``` -### Resource limits +from the root of the repository. Then set `BDB_PREFIX` for the next section: -The standard ulimit restrictions in OpenBSD are very strict: - - data(kbytes) 1572864 - -This, unfortunately, may no longer be enough to compile some `.cpp` files in the project, -at least with GCC 4.9.4 (see issue [#6658](https://github.com/bitcoin/bitcoin/issues/6658)). -If your user is in the `staff` group the limit can be raised with: - - ulimit -d 3000000 - -The change will only affect the current shell and processes spawned by it. To -make the change system-wide, change `datasize-cur` and `datasize-max` in -`/etc/login.conf`, and reboot. +```shell +export BDB_PREFIX="$PWD/db4" +``` ### Building Bitcoin Core @@ -108,7 +81,7 @@ Make sure `BDB_PREFIX` is set to the appropriate path from the above steps. To configure with wallet: ```bash -./configure --with-gui=no CC=egcc CXX=eg++ CPP=ecpp \ +./configure --with-gui=no CC=cc CXX=c++ \ SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" \ BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include" @@ -116,7 +89,7 @@ To configure with wallet: To configure without wallet: ```bash -./configure --disable-wallet --with-gui=no CC=egcc CXX=eg++ CPP=ecpp \ +./configure --disable-wallet --with-gui=no CC=cc CXX=c++ \ SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" ``` @@ -127,14 +100,22 @@ gmake # use -jX here for parallelism gmake check ``` -Clang ------------------------------- +Resource limits +------------------- -```bash -pkg_add llvm -./configure --disable-wallet --with-gui=no CC=clang CXX=clang++ \ - SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ - CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" -gmake # use -jX here for parallelism -gmake check -``` +If the build runs into out-of-memory errors, the instructions in this section +might help. + +The standard ulimit restrictions in OpenBSD are very strict: + + data(kbytes) 1572864 + +This, unfortunately, in some cases not enough to compile some `.cpp` files in the project, +(see issue [#6658](https://github.com/bitcoin/bitcoin/issues/6658)). +If your user is in the `staff` group the limit can be raised with: + + ulimit -d 3000000 + +The change will only affect the current shell and processes spawned by it. To +make the change system-wide, change `datasize-cur` and `datasize-max` in +`/etc/login.conf`, and reboot. From 35f3bda86b18b7edfd17868a4035e0b394646cd9 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:19:54 -0400 Subject: [PATCH 137/391] docs: Update OpenBSD build instructions for OpenBSD 6.3 --- doc/build-openbsd.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 1d1f33b328..fea929fde5 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,6 +1,6 @@ OpenBSD build guide ====================== -(updated for OpenBSD 6.2) +(updated for OpenBSD 6.3) This guide describes how to build bitcoind and command-line utilities on OpenBSD. @@ -12,11 +12,10 @@ Preparation Run the following as root to install the base dependencies for building: ```bash -pkg_add git gmake libevent libtool +pkg_add git gmake libevent libtool boost pkg_add autoconf # (select highest version, e.g. 2.69) pkg_add automake # (select highest version, e.g. 1.15) pkg_add python # (select highest version, e.g. 3.6) -pkg_add boost git clone https://github.com/bitcoin/bitcoin.git ``` @@ -73,8 +72,15 @@ export BDB_PREFIX="$PWD/db4" Preparation: ```bash -export AUTOCONF_VERSION=2.69 # replace this with the autoconf version that you installed -export AUTOMAKE_VERSION=1.15 # replace this with the automake version that you installed + +# Replace this with the autoconf version that you installed. Include only +# the major and minor parts of the version: use "2.69" for "autoconf-2.69p2". +export AUTOCONF_VERSION=2.69 + +# Replace this with the automake version that you installed. Include only +# the major and minor parts of the version: use "1.15" for "automake-1.15.1". +export AUTOMAKE_VERSION=1.15 + ./autogen.sh ``` Make sure `BDB_PREFIX` is set to the appropriate path from the above steps. From 641008f219072fc28a00fef2a6a9783889a8f46e Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:28:22 -0400 Subject: [PATCH 138/391] Fix incorrect shell quoting in FreeBSD build instructions. --- doc/build-freebsd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index c2e4e36dff..48746ce0c2 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -17,7 +17,7 @@ pkg install autoconf automake boost-libs git gmake libevent libtool openssl pkgc For the wallet (optional): ``` ./contrib/install_db4.sh `pwd` -export BDB_PREFIX='$PWD/db4' +export BDB_PREFIX="$PWD/db4" ``` See [dependencies.md](dependencies.md) for a complete overview. From 903e0c12d037709f4ae99233a3dd4e48d79e714b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:31:08 -0400 Subject: [PATCH 139/391] doc: Update OpenBSD build guide for 6.4 --- doc/build-openbsd.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index fea929fde5..e9b715df61 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,6 +1,6 @@ OpenBSD build guide ====================== -(updated for OpenBSD 6.3) +(updated for OpenBSD 6.4) This guide describes how to build bitcoind and command-line utilities on OpenBSD. @@ -14,7 +14,7 @@ Run the following as root to install the base dependencies for building: ```bash pkg_add git gmake libevent libtool boost pkg_add autoconf # (select highest version, e.g. 2.69) -pkg_add automake # (select highest version, e.g. 1.15) +pkg_add automake # (select highest version, e.g. 1.16) pkg_add python # (select highest version, e.g. 3.6) git clone https://github.com/bitcoin/bitcoin.git @@ -78,8 +78,8 @@ Preparation: export AUTOCONF_VERSION=2.69 # Replace this with the automake version that you installed. Include only -# the major and minor parts of the version: use "1.15" for "automake-1.15.1". -export AUTOMAKE_VERSION=1.15 +# the major and minor parts of the version: use "1.16" for "automake-1.16.1". +export AUTOMAKE_VERSION=1.16 ./autogen.sh ``` From cd8549d10f970aa31344681111120dae46544494 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:32:09 -0400 Subject: [PATCH 140/391] Various textual improvements in build docs --- doc/build-freebsd.md | 2 +- doc/build-openbsd.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index 48746ce0c2..7ec62ea779 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -29,7 +29,7 @@ git clone https://github.com/bitcoin/bitcoin ## Building Bitcoin Core -**Important**: Use `gmake` (the non-GNU `make` will exit with an error). +**Important**: Use `gmake` (the non-GNU `make` will exit with an error): ``` ./autogen.sh diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index e9b715df61..3656d4ea97 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -54,7 +54,7 @@ BerkeleyDB is only necessary for the wallet functionality. To skip this, pass It is recommended to use Berkeley DB 4.8. You cannot use the BerkeleyDB library from ports, for the same reason as boost above (g++/libstd++ incompatibility). If you have to build it yourself, you can use [the installation script included -in contrib/](/contrib/install_db4.sh) like so +in contrib/](/contrib/install_db4.sh) like so: ```shell ./contrib/install_db4.sh `pwd` CC=cc CXX=c++ @@ -116,7 +116,7 @@ The standard ulimit restrictions in OpenBSD are very strict: data(kbytes) 1572864 -This, unfortunately, in some cases not enough to compile some `.cpp` files in the project, +This is, unfortunately, in some cases not enough to compile some `.cpp` files in the project, (see issue [#6658](https://github.com/bitcoin/bitcoin/issues/6658)). If your user is in the `staff` group the limit can be raised with: From 5165a2ada88ffd4bf286d331ebef3c1aee41f222 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:33:12 -0400 Subject: [PATCH 141/391] FreeBSD: Document Python 3 requirement for 'gmake check' --- doc/build-freebsd.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index 7ec62ea779..70f5dfc882 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -14,6 +14,12 @@ You will need the following dependencies, which can be installed as root via pkg pkg install autoconf automake boost-libs git gmake libevent libtool openssl pkgconf ``` +In order to run the test suite (recommended), you will need to have Python 3 installed: + +``` +pkg install python3 +``` + For the wallet (optional): ``` ./contrib/install_db4.sh `pwd` @@ -36,10 +42,22 @@ git clone https://github.com/bitcoin/bitcoin ./configure # to build with wallet OR ./configure --disable-wallet # to build without wallet +``` + +followed by either: +``` gmake ``` +to build without testing, or + +``` +gmake check +``` + +to also run the test suite (recommended, if Python 3 is installed). + *Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement). It is not suitable for debugging a multi-threaded C++ program, not even for getting backtraces. Please install the package `gdb` and use the versioned gdb command (e.g. `gdb7111`). From 3b1a09644947babd4470d864f5c2dbf18aa0c337 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:35:44 -0400 Subject: [PATCH 142/391] doc: update NetBSD build instructions for 8.0 --- doc/build-netbsd.md | 52 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md index 5bf2d6b59b..ab422f6aa7 100644 --- a/doc/build-netbsd.md +++ b/doc/build-netbsd.md @@ -1,6 +1,6 @@ NetBSD build guide ====================== -(updated for NetBSD 7.0) +(updated for NetBSD 8.0) This guide describes how to build bitcoind and command-line utilities on NetBSD. @@ -15,21 +15,38 @@ You will need the following modules, which can be installed via pkgsrc or pkgin: autoconf automake boost -db4 git gmake libevent libtool -python27 -``` +pkg-config +python37 -Download the source code: -``` -git clone https://github.com/bitcoin/bitcoin +git clone https://github.com/bitcoin/bitcoin.git ``` See [dependencies.md](dependencies.md) for a complete overview. +### Building BerkeleyDB + +BerkeleyDB is only necessary for the wallet functionality. To skip this, pass +`--disable-wallet` to `./configure` and skip to the next section. + +It is recommended to use Berkeley DB 4.8. You cannot use the BerkeleyDB library +from ports, for the same reason as boost above (g++/libstd++ incompatibility). +If you have to build it yourself, you can use [the installation script included +in contrib/](/contrib/install_db4.sh) like so: + +```shell +./contrib/install_db4.sh `pwd` +``` + +from the root of the repository. Then set `BDB_PREFIX` for the next section: + +```shell +export BDB_PREFIX="$PWD/db4" +``` + ### Building Bitcoin Core **Important**: Use `gmake` (the non-GNU `make` will exit with an error). @@ -37,13 +54,26 @@ See [dependencies.md](dependencies.md) for a complete overview. With wallet: ``` ./autogen.sh -./configure CPPFLAGS="-I/usr/pkg/include" LDFLAGS="-L/usr/pkg/lib" BOOST_CPPFLAGS="-I/usr/pkg/include" BOOST_LDFLAGS="-L/usr/pkg/lib" -gmake +./configure --with-gui=no CPPFLAGS="-I/usr/pkg/include" \ + LDFLAGS="-L/usr/pkg/lib" \ + BOOST_CPPFLAGS="-I/usr/pkg/include" \ + BOOST_LDFLAGS="-L/usr/pkg/lib" \ + BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ + BDB_CFLAGS="-I${BDB_PREFIX}/include" ``` Without wallet: ``` ./autogen.sh -./configure --disable-wallet CPPFLAGS="-I/usr/pkg/include" LDFLAGS="-L/usr/pkg/lib" BOOST_CPPFLAGS="-I/usr/pkg/include" BOOST_LDFLAGS="-L/usr/pkg/lib" -gmake +./configure --with-gui=no --disable-wallet \ + CPPFLAGS="-I/usr/pkg/include" \ + LDFLAGS="-L/usr/pkg/lib" \ + BOOST_CPPFLAGS="-I/usr/pkg/include" \ + BOOST_LDFLAGS="-L/usr/pkg/lib" +``` + +Build and run the tests: +```bash +gmake # use -jX here for parallelism +gmake check ``` From 53acba56d554362e5165c2148910526f73350fa7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:37:04 -0400 Subject: [PATCH 143/391] doc: update FreeBSD build guide for 12.0 --- doc/build-freebsd.md | 56 ++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index 70f5dfc882..d22b6e8383 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -1,6 +1,6 @@ FreeBSD build guide ====================== -(updated for FreeBSD 11.1) +(updated for FreeBSD 12.0) This guide describes how to build bitcoind and command-line utilities on FreeBSD. @@ -10,55 +10,51 @@ This guide does not contain instructions for building the GUI. You will need the following dependencies, which can be installed as root via pkg: -``` +```shell pkg install autoconf automake boost-libs git gmake libevent libtool openssl pkgconf + +git clone https://github.com/bitcoin/bitcoin.git ``` In order to run the test suite (recommended), you will need to have Python 3 installed: -``` +```shell pkg install python3 ``` -For the wallet (optional): -``` -./contrib/install_db4.sh `pwd` -export BDB_PREFIX="$PWD/db4" -``` - See [dependencies.md](dependencies.md) for a complete overview. -Download the source code: -``` -git clone https://github.com/bitcoin/bitcoin +### Building BerkeleyDB + +BerkeleyDB is only necessary for the wallet functionality. To skip this, pass +`--disable-wallet` to `./configure` and skip to the next section. + +```shell +./contrib/install_db4.sh `pwd` +export BDB_PREFIX="$PWD/db4" ``` ## Building Bitcoin Core **Important**: Use `gmake` (the non-GNU `make` will exit with an error): -``` +With wallet: +```shell ./autogen.sh - -./configure # to build with wallet OR -./configure --disable-wallet # to build without wallet +./configure --with-gui=no \ + BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ + BDB_CFLAGS="-I${BDB_PREFIX}/include" ``` -followed by either: - -``` -gmake +Without wallet: +```shell +./autogen.sh +./configure --with-gui=no --disable-wallet ``` -to build without testing, or +followed by: +```shell +gmake # use -jX here for parallelism +gmake check # Run tests if Python 3 is available ``` -gmake check -``` - -to also run the test suite (recommended, if Python 3 is installed). - -*Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement). -It is not suitable for debugging a multi-threaded C++ program, not even for getting backtraces. Please install the package `gdb` and -use the versioned gdb command (e.g. `gdb7111`). - From 4e5fd005dd5f19620bb45bdbdc80d900d780e532 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:48:26 -0400 Subject: [PATCH 144/391] doc: mention MAKE=gmake workaround when building on a BSD Fixes: https://github.com/bitcoin/bitcoin/issues/14404 --- doc/build-freebsd.md | 21 +++++++++++---------- doc/build-netbsd.md | 14 ++++++++------ doc/build-openbsd.md | 13 ++++++++----- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index d22b6e8383..f48855a344 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -10,15 +10,15 @@ This guide does not contain instructions for building the GUI. You will need the following dependencies, which can be installed as root via pkg: -```shell -pkg install autoconf automake boost-libs git gmake libevent libtool openssl pkgconf +```bash +pkg install autoconf automake boost-libs git gmake libevent libtool pkgconf git clone https://github.com/bitcoin/bitcoin.git ``` In order to run the test suite (recommended), you will need to have Python 3 installed: -```shell +```bash pkg install python3 ``` @@ -29,32 +29,33 @@ See [dependencies.md](dependencies.md) for a complete overview. BerkeleyDB is only necessary for the wallet functionality. To skip this, pass `--disable-wallet` to `./configure` and skip to the next section. -```shell +```bash ./contrib/install_db4.sh `pwd` export BDB_PREFIX="$PWD/db4" ``` ## Building Bitcoin Core -**Important**: Use `gmake` (the non-GNU `make` will exit with an error): +**Important**: Use `gmake` (the non-GNU `make` will exit with an error). With wallet: -```shell +```bash ./autogen.sh ./configure --with-gui=no \ BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ - BDB_CFLAGS="-I${BDB_PREFIX}/include" + BDB_CFLAGS="-I${BDB_PREFIX}/include" \ + MAKE=gmake ``` Without wallet: -```shell +```bash ./autogen.sh -./configure --with-gui=no --disable-wallet +./configure --with-gui=no --disable-wallet MAKE=gmake ``` followed by: -```shell +```bash gmake # use -jX here for parallelism gmake check # Run tests if Python 3 is available ``` diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md index ab422f6aa7..47049a780e 100644 --- a/doc/build-netbsd.md +++ b/doc/build-netbsd.md @@ -37,13 +37,13 @@ from ports, for the same reason as boost above (g++/libstd++ incompatibility). If you have to build it yourself, you can use [the installation script included in contrib/](/contrib/install_db4.sh) like so: -```shell +```bash ./contrib/install_db4.sh `pwd` ``` from the root of the repository. Then set `BDB_PREFIX` for the next section: -```shell +```bash export BDB_PREFIX="$PWD/db4" ``` @@ -52,24 +52,26 @@ export BDB_PREFIX="$PWD/db4" **Important**: Use `gmake` (the non-GNU `make` will exit with an error). With wallet: -``` +```bash ./autogen.sh ./configure --with-gui=no CPPFLAGS="-I/usr/pkg/include" \ LDFLAGS="-L/usr/pkg/lib" \ BOOST_CPPFLAGS="-I/usr/pkg/include" \ BOOST_LDFLAGS="-L/usr/pkg/lib" \ BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ - BDB_CFLAGS="-I${BDB_PREFIX}/include" + BDB_CFLAGS="-I${BDB_PREFIX}/include" \ + MAKE=gmake ``` Without wallet: -``` +```bash ./autogen.sh ./configure --with-gui=no --disable-wallet \ CPPFLAGS="-I/usr/pkg/include" \ LDFLAGS="-L/usr/pkg/lib" \ BOOST_CPPFLAGS="-I/usr/pkg/include" \ - BOOST_LDFLAGS="-L/usr/pkg/lib" + BOOST_LDFLAGS="-L/usr/pkg/lib" \ + MAKE=gmake ``` Build and run the tests: diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 3656d4ea97..202c37db72 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -56,19 +56,19 @@ from ports, for the same reason as boost above (g++/libstd++ incompatibility). If you have to build it yourself, you can use [the installation script included in contrib/](/contrib/install_db4.sh) like so: -```shell +```bash ./contrib/install_db4.sh `pwd` CC=cc CXX=c++ ``` from the root of the repository. Then set `BDB_PREFIX` for the next section: -```shell +```bash export BDB_PREFIX="$PWD/db4" ``` ### Building Bitcoin Core -**Important**: use `gmake`, not `make`. The non-GNU `make` will exit with a horrible error. +**Important**: Use `gmake` (the non-GNU `make` will exit with an error). Preparation: ```bash @@ -90,14 +90,17 @@ To configure with wallet: ./configure --with-gui=no CC=cc CXX=c++ \ SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" \ - BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include" + BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ + BDB_CFLAGS="-I${BDB_PREFIX}/include" \ + MAKE=gmake ``` To configure without wallet: ```bash ./configure --disable-wallet --with-gui=no CC=cc CXX=c++ \ SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ - CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" + CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" \ + MAKE=gmake ``` Build and run the tests: From 640f5a23698066c501d7771309011bbf5f57847f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 16:54:24 -0400 Subject: [PATCH 145/391] doc: set CC_FOR_BUILD when building on OpenBSD Closes: https://github.com/bitcoin/bitcoin/issues/19559 While https://github.com/bitcoin/bitcoin/issues/19559 has been fixed upstream, it makes sense to not only recommend using `CC_FOR_BUILD`here until the fix is pulled in as part of our next libsecp update, but after discussing with Cory, he suggested we should be setting this on OpenBSD (which still has the an ancient GCC) regardless. --- doc/build-openbsd.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 202c37db72..85777b5b97 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,6 +1,6 @@ OpenBSD build guide ====================== -(updated for OpenBSD 6.4) +(updated for OpenBSD 6.7) This guide describes how to build bitcoind and command-line utilities on OpenBSD. @@ -15,7 +15,7 @@ Run the following as root to install the base dependencies for building: pkg_add git gmake libevent libtool boost pkg_add autoconf # (select highest version, e.g. 2.69) pkg_add automake # (select highest version, e.g. 1.16) -pkg_add python # (select highest version, e.g. 3.6) +pkg_add python # (select highest version, e.g. 3.8) git clone https://github.com/bitcoin/bitcoin.git ``` @@ -23,10 +23,10 @@ git clone https://github.com/bitcoin/bitcoin.git See [dependencies.md](dependencies.md) for a complete overview. **Important**: From OpenBSD 6.2 onwards a C++11-supporting clang compiler is -part of the base image, and while building it is necessary to make sure that this -compiler is used and not ancient g++ 4.2.1. This is done by appending -`CC=cc CXX=c++` to configuration commands. Mixing different compilers -within the same executable will result in linker errors. +part of the base image, and while building it is necessary to make sure that +this compiler is used and not ancient g++ 4.2.1. This is done by appending +`CC=cc CC_FOR_BUILD=cc CXX=c++` to configuration commands. Mixing different +compilers within the same executable will result in errors. ### OpenSSL @@ -97,7 +97,7 @@ To configure with wallet: To configure without wallet: ```bash -./configure --disable-wallet --with-gui=no CC=cc CXX=c++ \ +./configure --disable-wallet --with-gui=no CC=cc CC_FOR_BUILD=cc CXX=c++ \ SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" \ MAKE=gmake From 1ed5039755f93271be2516ef65c323830adfd184 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 17:01:59 -0400 Subject: [PATCH 146/391] doc: Update macOS cross compilation dependencies for Focal --- depends/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/README.md b/depends/README.md index 27255996e0..90f23a5242 100644 --- a/depends/README.md +++ b/depends/README.md @@ -37,7 +37,7 @@ The paths are automatically configured and no other options are needed unless ta #### For macOS cross compilation - sudo apt-get install curl bsdmainutils cmake libcap-dev libz-dev libbz2-dev python3-setuptools + sudo apt-get install curl bsdmainutils cmake libcap-dev libz-dev libbz2-dev python3-setuptools libtinfo5 Note: You must obtain the macOS SDK before proceeding with a cross-compile. Under the depends directory, create a subdirectory named `SDKs`. From 431e811cf8c503f4414449365784c19ade3a8398 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 17:03:07 -0400 Subject: [PATCH 147/391] [Actions] Update Focal workflow to use libtinfo5 package --- .github/workflows/prcy-build-factory-ubuntu20.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml index f37a67d3e9..6b545fea2c 100644 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ b/.github/workflows/prcy-build-factory-ubuntu20.yml @@ -250,7 +250,7 @@ jobs: - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y python3-setuptools libcap-dev + sudo apt-get install -y python3-setuptools libcap-dev libtinfo5 - name: Get macOS SDK run: | mkdir -p depends/sdk-sources depends/SDKs From f38df21712bff27816401b27a04d63df05bc9bac Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 17:24:55 -0400 Subject: [PATCH 148/391] Clarify need to specify --prefix with depends If not cross compiling, it might actually be nice for it to be picked up automatically. But for now clarify the readme to try to minimize confusion. https://github.com/chaincodelabs/libmultiprocess/issues/4#issuecomment-515619707 https://github.com/chaincodelabs/libmultiprocess/issues/5#issuecomment-518826298 --- depends/README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/depends/README.md b/depends/README.md index 27255996e0..e88d25661a 100644 --- a/depends/README.md +++ b/depends/README.md @@ -12,14 +12,18 @@ For example: make HOST=x86_64-w64-mingw32 -j4 -A prefix will be generated that's suitable for plugging into Bitcoin's -configure. In the above example, a dir named x86_64-w64-mingw32 will be +**Bitcoin's configure script by default will ignore the depends output.** In +order for it to pick up libraries, tools, and settings from the depends build, +you must point it at the appropriate `--prefix` directory generated by the +build. In the above example, a prefix dir named x86_64-w64-mingw32 will be created. To use it for Bitcoin: ./configure --prefix=`pwd`/depends/x86_64-w64-mingw32 Common `host-platform-triplets` for cross compilation are: +- `i686-pc-linux-gnu` for Linux 32 bit +- `x86_64-pc-linux-gnu` for x86 Linux - `x86_64-w64-mingw32` for Win64 - `x86_64-apple-darwin18` for macOS - `arm-linux-gnueabihf` for Linux ARM 32 bit From 5f61d76a662034facaad41299cbab0bb521fd87e Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 17:33:58 -0400 Subject: [PATCH 149/391] packages.md: document depends build targets --- depends/packages.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/depends/packages.md b/depends/packages.md index 955a6be7a0..a6c368c653 100644 --- a/depends/packages.md +++ b/depends/packages.md @@ -180,4 +180,19 @@ For us, it's much easier to just link a static `libsecondary` into a shared `libprimary` anyway that we'll throw away. We don't care if the end-user has a static or dynamic `libseconday`, that's not our concern. With a static `libseconday`, when we need to link `libprimary` into our executable, there's no -dependency chain to worry about as `libprimary` has all the symbols. \ No newline at end of file +dependency chain to worry about as `libprimary` has all the symbols. + +## Build targets: + +To build an individual package (useful for debugging), following build targets are available. + + make ${package} + make ${package}_fetched + make ${package}_extracted + make ${package}_preprocessed + make ${package}_configured + make ${package}_built + make ${package}_staged + make ${package}_postprocessed + make ${package}_cached + make ${package}_cached_checksum \ No newline at end of file From 357cc2550629fd8a319d664ea0521e22ec556d87 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 17:51:34 -0400 Subject: [PATCH 150/391] doc: Convert depends options list from html to markdown This makes it easier to read in `less`, which is important for install instructions. --- depends/README.md | 53 +++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 34 deletions(-) diff --git a/depends/README.md b/depends/README.md index 8549deae7e..3395e254c1 100644 --- a/depends/README.md +++ b/depends/README.md @@ -78,42 +78,27 @@ this is apparently fixed in gcc-8.1.0. pkg_add bash gtar ### Dependency Options + The following can be set when running make: `make FOO=bar` -

-
SOURCES_PATH
-
downloaded sources will be placed here
-
BASE_CACHE
-
built packages will be placed here
-
SDK_PATH
-
Path where sdk's can be found (used by macOS)
-
FALLBACK_DOWNLOAD_PATH
-
If a source file can't be fetched, try here before giving up
-
NO_QT
-
Don't download/build/cache qt and its dependencies
-
NO_QR
-
Don't download/build/cache packages needed for enabling qrencode
-
NO_ZMQ
-
Don't download/build/cache packages needed for enabling zeromq
-
NO_WALLET
-
Don't download/build/cache libs needed to enable the wallet
-
NO_UPNP
-
Don't download/build/cache packages needed for enabling upnp
-
ALLOW_HOST_PACKAGES
-
Packages that are missed in dependencies (due to `NO_*` option or -build script logic) are searched for among the host system packages using -`pkg-config`. It allows building with packages of other (newer) versions
-
DEBUG
-
disable some optimizations and enable more runtime checking
-
HOST_ID_SALT
-
Optional salt to use when generating host package ids
-
BUILD_ID_SALT
-
Optional salt to use when generating build package ids
-
FORCE_USE_SYSTEM_CLANG
-
(EXPERTS ONLY) When cross-compiling for macOS, use clang found in the -system's $PATH rather than the default prebuilt release of clang -from llvm.org
-
+- `SOURCES_PATH`: Downloaded sources will be placed here +- `BASE_CACHE`: Built packages will be placed here +- `SDK_PATH`: Path where SDKs can be found (used by macOS) +- `FALLBACK_DOWNLOAD_PATH`: If a source file can't be fetched, try here before giving up +- `NO_QT`: Don't download/build/cache Qt and its dependencies +- `NO_QR`: Don't download/build/cache packages needed for enabling qrencode +- `NO_ZMQ`: Don't download/build/cache packages needed for enabling ZeroMQ +- `NO_WALLET`: Don't download/build/cache libs needed to enable the wallet +- `NO_UPNP`: Don't download/build/cache packages needed for enabling UPnP +- `ALLOW_HOST_PACKAGES`: Packages that are missed in dependencies (due to `NO_*` option or + build script logic) are searched for among the host system packages using + `pkg-config`. It allows building with packages of other (newer) versions +- `DEBUG`: Disable some optimizations and enable more runtime checking +- `HOST_ID_SALT`: Optional salt to use when generating host package ids +- `BUILD_ID_SALT`: Optional salt to use when generating build package ids +- `FORCE_USE_SYSTEM_CLANG`: (EXPERTS ONLY) When cross-compiling for macOS, use Clang found in the + system's `$PATH` rather than the default prebuilt release of Clang + from llvm.org. Clang 8 or later is required. If some packages are not built, for example `make NO_WALLET=1`, the appropriate options will be passed to bitcoin's configure. In this case, `--disable-wallet`. From 2e953ab7b953053a70f7176b1adc6323eaa6cd9d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 19:09:13 -0400 Subject: [PATCH 151/391] doc: Use CONFIG_SITE instead of --prefix --- depends/README.md | 15 +++++++++------ doc/build-unix.md | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/depends/README.md b/depends/README.md index 3395e254c1..87c3221daf 100644 --- a/depends/README.md +++ b/depends/README.md @@ -12,15 +12,18 @@ For example: make HOST=x86_64-w64-mingw32 -j4 -**Bitcoin's configure script by default will ignore the depends output.** In +**Bitcoin Core's `configure` script by default will ignore the depends output.** In order for it to pick up libraries, tools, and settings from the depends build, -you must point it at the appropriate `--prefix` directory generated by the -build. In the above example, a prefix dir named x86_64-w64-mingw32 will be -created. To use it for Bitcoin: +you must set the `CONFIG_SITE` environment variable to point to a `config.site` settings file. +In the above example, a file named `depends/x86_64-w64-mingw32/share/config.site` will be +created. To use it during compilation: - ./configure --prefix=`pwd`/depends/x86_64-w64-mingw32 + CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure -Common `host-platform-triplets` for cross compilation are: +The default install prefix when using `config.site` is `--prefix=depends/`, +so depends build outputs will be installed in that location. + +Common `host-platform-triplet`s for cross compilation are: - `i686-pc-linux-gnu` for Linux 32 bit - `x86_64-pc-linux-gnu` for x86 Linux diff --git a/doc/build-unix.md b/doc/build-unix.md index a74d1f573f..4ee3a25bcc 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -278,7 +278,7 @@ To build executables for ARM: make HOST=arm-linux-gnueabihf NO_QT=1 cd .. ./autogen.sh - ./configure --prefix=$PWD/depends/arm-linux-gnueabihf --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ + CONFIG_SITE=$PWD/depends/arm-linux-gnueabihf/share/config.site ./configure --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ make From 53d369e6e1d4a36657030feb0633dcd012b29fa7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 19:09:30 -0400 Subject: [PATCH 152/391] [Actions] Switch from `--prefix=` to `CONFIG_SITE=` --- .github/workflows/prcy-build-factory-debug.yml | 12 ++++++------ .github/workflows/prcy-build-factory-ubuntu20.yml | 12 ++++++------ .github/workflows/prcy-build-factory.yml | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/prcy-build-factory-debug.yml b/.github/workflows/prcy-build-factory-debug.yml index f987e35acb..e3bf9bcbd5 100644 --- a/.github/workflows/prcy-build-factory-debug.yml +++ b/.github/workflows/prcy-build-factory-debug.yml @@ -88,7 +88,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-pc-linux-gnu) --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/x86_64-pc-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -137,7 +137,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-w64-mingw32) --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/x86_64-w64-mingw32/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -201,7 +201,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin18) --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/x86_64-apple-darwin18/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -245,7 +245,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/aarch64-linux-gnu) --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/aarch64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -289,7 +289,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/arm-linux-gnueabihf) --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/arm-linux-gnueabihf/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -333,7 +333,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/riscv64-linux-gnu) --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/riscv64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml index 6b545fea2c..fed69bb7b4 100644 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ b/.github/workflows/prcy-build-factory-ubuntu20.yml @@ -142,7 +142,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-pc-linux-gnu) --enable-upnp-default + CONFIG_SITE=$(realpath depends/x86_64-pc-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -197,7 +197,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-w64-mingw32) --enable-upnp-default + CONFIG_SITE=$(realpath depends/x86_64-w64-mingw32/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -267,7 +267,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin18) --enable-upnp-default + CONFIG_SITE=$(realpath depends/x86_64-apple-darwin18/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -317,7 +317,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/aarch64-linux-gnu) --enable-upnp-default + CONFIG_SITE=$(realpath depends/aarch64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -367,7 +367,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/arm-linux-gnueabihf) --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default + CONFIG_SITE=$(realpath depends/arm-linux-gnueabihf/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -417,7 +417,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/riscv64-linux-gnu) --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default + CONFIG_SITE=$(realpath depends/riscv64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 6f091deff1..6bcf8e62d8 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -141,7 +141,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-pc-linux-gnu) --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports + CONFIG_SITE=$(realpath depends/x86_64-pc-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -196,7 +196,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-w64-mingw32) --enable-upnp-default --enable-reduce-exports + CONFIG_SITE=$(realpath depends/x86_64-w64-mingw32/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-reduce-exports make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -266,7 +266,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin18) --enable-upnp-default --enable-reduce-exports + CONFIG_SITE=$(realpath depends/x86_64-apple-darwin18/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-reduce-exports make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -316,7 +316,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/aarch64-linux-gnu) --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports + CONFIG_SITE=$(realpath depends/aarch64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -366,7 +366,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/arm-linux-gnueabihf) --enable-glibc-back-compat --enable-reduce-exports --enable-upnp-default CXXFLAGS=-Wno-psabi + CONFIG_SITE=$(realpath depends/arm-linux-gnueabihf/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-glibc-back-compat --enable-reduce-exports --enable-upnp-default CXXFLAGS=-Wno-psabi make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -416,7 +416,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/riscv64-linux-gnu) --enable-reduce-exports --enable-upnp-default + CONFIG_SITE=$(realpath depends/riscv64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-reduce-exports --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact From 8a6dd45f7f67e76827677308b89d040471796b40 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 22:20:08 -0400 Subject: [PATCH 153/391] rpc: work-around an upstream libevent bug A rare race condition may trigger while awaiting the body of a message, see upsteam commit 5ff8eb26371c4dc56f384b2de35bea2d87814779 for details. This may fix some reported rpc hangs/crashes. --- src/httpserver.cpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 08f612cec1..30bd3efbe2 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -255,6 +256,16 @@ static std::string RequestMethodString(HTTPRequest::RequestMethod m) /** HTTP request callback */ static void http_request_cb(struct evhttp_request* req, void* arg) { + // Disable reading to work around a libevent bug, fixed in 2.2.0. + if (event_get_version_number() < 0x02020001) { + evhttp_connection* conn = evhttp_request_get_connection(req); + if (conn) { + bufferevent* bev = evhttp_connection_get_bufferevent(conn); + if (bev) { + bufferevent_disable(bev, EV_READ); + } + } + } std::unique_ptr hreq(new HTTPRequest(req)); LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n", @@ -620,8 +631,21 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply) struct evbuffer* evb = evhttp_request_get_output_buffer(req); assert(evb); evbuffer_add(evb, strReply.data(), strReply.size()); - HTTPEvent* ev = new HTTPEvent(eventBase, true, - std::bind(evhttp_send_reply, req, nStatus, (const char*)NULL, (struct evbuffer *)NULL)); + auto req_copy = req; + HTTPEvent* ev = new HTTPEvent(eventBase, true, [req_copy, nStatus]{ + evhttp_send_reply(req_copy, nStatus, nullptr, nullptr); + // Re-enable reading from the socket. This is the second part of the libevent + // workaround above. + if (event_get_version_number() < 0x02020001) { + evhttp_connection* conn = evhttp_request_get_connection(req_copy); + if (conn) { + bufferevent* bev = evhttp_connection_get_bufferevent(conn); + if (bev) { + bufferevent_enable(bev, EV_READ | EV_WRITE); + } + } + } + }); ev->trigger(0); replySent = true; req = 0; // transferred back to main thread From 51449396244ded21621a92b0db045aa36d722ea5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 22:21:05 -0400 Subject: [PATCH 154/391] rpc: further constrain the libevent workaround The bug was introduced in 2.1.6-beta, versions before that don't need the workaround. --- src/httpserver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 30bd3efbe2..69502ea058 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -257,7 +257,7 @@ static std::string RequestMethodString(HTTPRequest::RequestMethod m) static void http_request_cb(struct evhttp_request* req, void* arg) { // Disable reading to work around a libevent bug, fixed in 2.2.0. - if (event_get_version_number() < 0x02020001) { + if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) { evhttp_connection* conn = evhttp_request_get_connection(req); if (conn) { bufferevent* bev = evhttp_connection_get_bufferevent(conn); @@ -636,7 +636,7 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply) evhttp_send_reply(req_copy, nStatus, nullptr, nullptr); // Re-enable reading from the socket. This is the second part of the libevent // workaround above. - if (event_get_version_number() < 0x02020001) { + if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) { evhttp_connection* conn = evhttp_request_get_connection(req_copy); if (conn) { bufferevent* bev = evhttp_connection_get_bufferevent(conn); From b3c0a591dc429bbc44080c4875b04ee6fdbdddd8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 13:49:50 -0400 Subject: [PATCH 155/391] build: Suppress -Wdeprecated-copy warnings --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index eb0c2d2ef5..6b2a763e0f 100644 --- a/configure.ac +++ b/configure.ac @@ -331,6 +331,7 @@ if test "x$CXXFLAGS_overridden" = "xno"; then AX_CHECK_COMPILE_FLAG([-Wunused-local-typedef],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-unused-local-typedef"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wdeprecated-register],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-register"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-implicit-fallthrough"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wdeprecated-copy],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-copy"],,[[$CXXFLAG_WERROR]]) fi enable_sse42=no From 942cc48eb632d0b543c536c1f766e0ae986e8431 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 13:55:01 -0400 Subject: [PATCH 156/391] build: fix mutex detection when building bdb on macOS Starting with the Clang shipped with Xcode 12, Apple has enabled -Werror=implicit-function-declaration by default. This causes bdbs mutex detection to fail when building on macOS (not cross-compiling): checking for mutexes... UNIX/fcntl configure: WARNING: NO SHARED LATCH IMPLEMENTATION FOUND FOR THIS PLATFORM. configure: error: Unable to find a mutex implementation as previously emitted warnings are being turned into errors. i.e: error: implicitly declaring library function 'exit' with type 'void (int) __attribute__((noreturn))' [-Werror,-Wimplicit-function-declaration] Append -Wno-error=implicit-function-declaration to cflags so that -Wimplicit-function-declaration returns to being a warning, and the configure checks will succeed. Fixes https://github.com/bitcoin/bitcoin/issues/19411. --- depends/packages/bdb.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 7f5011ff08..2b20a4ddeb 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -13,6 +13,7 @@ $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic $(package)_config_opts_netbsd=--with-pic $(package)_config_opts_openbsd=--with-pic +$(package)_cflags+=-Wno-error=implicit-function-declaration $(package)_cxxflags=-std=c++17 $(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef From 1643d554b3d27e4d2d96c4924ccc67ffe9e6fb4b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 14:50:38 -0400 Subject: [PATCH 157/391] build: fix unoptimized libraries in depends We need to append-to rather than set CXXFLAGS, otherwise we loose -O2 & -pipe. Currently this results in zeromq being built without optimizations at all (or whatever the compiler would default too, essentially always -O0). Bdb is the same, for the CXX portion of its code. C code has been built with -O2. Boost has actually been uneffected because it receives -O3 from it's own build flags. --- depends/packages/bdb.mk | 2 +- depends/packages/boost.mk | 2 +- depends/packages/zeromq.mk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 2b20a4ddeb..0e00daf251 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -14,7 +14,7 @@ $(package)_config_opts_freebsd=--with-pic $(package)_config_opts_netbsd=--with-pic $(package)_config_opts_openbsd=--with-pic $(package)_cflags+=-Wno-error=implicit-function-declaration -$(package)_cxxflags=-std=c++17 +$(package)_cxxflags+=-std=c++17 $(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 576fab1a27..e5d529bdd2 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -32,7 +32,7 @@ else $(package)_toolset_$(host_os)=gcc endif $(package)_config_libraries=chrono,filesystem,program_options,system,thread,test -$(package)_cxxflags=-std=c++17 -fvisibility=hidden +$(package)_cxxflags+=-std=c++17 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC $(package)_cxxflags_freebsd=-fPIC $(package)_cxxflags_openbsd=-fPIC diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index b5cca1dae8..c74ae15b31 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -16,7 +16,7 @@ define $(package)_set_vars $(package)_config_opts_netbsd=--with-pic $(package)_config_opts_openbsd=--with-pic $(package)_config_opts_android=--with-pic - $(package)_cxxflags=-std=c++17 + $(package)_cxxflags+=-std=c++17 endef define $(package)_preprocess_cmds From 8ad30adee74abb9feb5801b66c9080d59cc1f13f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 15:19:36 -0400 Subject: [PATCH 158/391] rpc: Set HTTP Content-Type in prcycoin-cli We don't set any `Content-Type` in the client. It is more consistent with our other JSON-RPC use to set it to `application/json`. Note that our server doesn't enforce content types, so it doesn't make a difference in practice. But it is fairly strange HTTP behavior to not set it. This came up in https://github.com/bitcoin/bitcoin/issues/18950. --- src/prcycoin-cli.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prcycoin-cli.cpp b/src/prcycoin-cli.cpp index 6ca05fd89d..599a2cd2af 100644 --- a/src/prcycoin-cli.cpp +++ b/src/prcycoin-cli.cpp @@ -179,6 +179,7 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) assert(output_headers); evhttp_add_header(output_headers, "Host", host.c_str()); evhttp_add_header(output_headers, "Connection", "close"); + evhttp_add_header(output_headers, "Content-Type", "application/json"); evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str()); // Attach request data From 77f5582e24147ac134cd8812a92085486e2f4575 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 15:29:41 -0400 Subject: [PATCH 159/391] Added additional config option for multiple RPC users. --- share/rpcuser/README.md | 11 ++++++++ share/rpcuser/rpcuser.py | 41 ++++++++++++++++++++++++++++++ src/httprpc.cpp | 54 +++++++++++++++++++++++++++++++++++++++- src/init.cpp | 1 + 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 share/rpcuser/README.md create mode 100644 share/rpcuser/rpcuser.py diff --git a/share/rpcuser/README.md b/share/rpcuser/README.md new file mode 100644 index 0000000000..7c2c909a42 --- /dev/null +++ b/share/rpcuser/README.md @@ -0,0 +1,11 @@ +RPC Tools +--------------------- + +### [RPCUser](/share/rpcuser) ### + +Create an RPC user login credential. + +Usage: + +./rpcuser.py + diff --git a/share/rpcuser/rpcuser.py b/share/rpcuser/rpcuser.py new file mode 100644 index 0000000000..9fd176908b --- /dev/null +++ b/share/rpcuser/rpcuser.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import hashlib +import sys +import os +from random import SystemRandom +import base64 +import hmac + +if len(sys.argv) < 2: + sys.stderr.write('Please include username as an argument.\n') + sys.exit(0) + +username = sys.argv[1] + +#This uses os.urandom() underneath +cryptogen = SystemRandom() + +#Create 16 byte hex salt +salt_sequence = [cryptogen.randrange(256) for i in range(16)] +hexseq = list(map(hex, salt_sequence)) +salt = "".join([x[2:] for x in hexseq]) + +#Create 32 byte b64 password +password = base64.urlsafe_b64encode(os.urandom(32)) + +digestmod = hashlib.sha256 + +if sys.version_info.major >= 3: + password = password.decode('utf-8') + digestmod = 'SHA256' + +m = hmac.new(bytearray(salt, 'utf-8'), bytearray(password, 'utf-8'), digestmod) +result = m.hexdigest() + +print("String to be appended to bitcoin.conf:") +print("rpcauth="+username+":"+salt+"$"+result) +print("Your password:\n"+password) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 9aea450dba..55cced6396 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -16,6 +16,8 @@ #include "util.h" #include "utilstrencodings.h" #include "guiinterface.h" +#include "crypto/hmac_sha256.h" +#include #include // boost::trim @@ -78,6 +80,50 @@ static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const Uni req->WriteReply(nStatus, strReply); } +//This function checks username and password against -rpcauth +//entries from config file. +static bool multiUserAuthorized(std::string strUserPass) +{ + if (strUserPass.find(":") == std::string::npos) { + return false; + } + std::string strUser = strUserPass.substr(0, strUserPass.find(":")); + std::string strPass = strUserPass.substr(strUserPass.find(":") + 1); + + if (mapMultiArgs.count("-rpcauth") > 0) { + //Search for multi-user login/pass "rpcauth" from config + for (std::string strRPCAuth : mapMultiArgs["-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]; + + unsigned int KEY_SIZE = 32; + unsigned char *out = new unsigned char[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; +} + static bool RPCAuthorized(const std::string& strAuth) { if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called @@ -87,7 +133,12 @@ static bool RPCAuthorized(const std::string& strAuth) std::string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); std::string strUserPass = DecodeBase64(strUserPass64); - return TimingResistantEqual(strUserPass, strRPCUserColonPass); + + //Check if authorized under single-user field + if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) { + return true; + } + return multiUserAuthorized(strUserPass); } static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) @@ -163,6 +214,7 @@ static bool InitRPCAuthentication() return false; } } else { + LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation."); strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } return true; diff --git a/src/init.cpp b/src/init.cpp index 6d8fc55df2..a1eaa5ed68 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -554,6 +554,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-rpcbind=", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)")); strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); + strUsage += HelpMessageOpt("-rpcauth=", _("Username and hashed password for JSON-RPC connections. The field comes in the format: :$. A canonical python script is included in share/rpcuser. This option can be specified multiple times")); strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 59683, 59685)); strUsage += HelpMessageOpt("-rpcallowip=", _("Allow JSON-RPC connections from specified source. Valid for 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). This option can be specified multiple times")); strUsage += HelpMessageOpt("-rpcthreads=", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS)); From 768b505cf8d26e70bc5f426e06319312fedd0d2a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 16:11:47 -0400 Subject: [PATCH 160/391] build: set minimum required Boost to 1.58 Any systems which only have an older install-able Boost can use depends. Fixes: https://github.com/bitcoin/bitcoin/issues/19506 --- configure.ac | 4 ++-- doc/dependencies.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 6b2a763e0f..06a9206cc6 100644 --- a/configure.ac +++ b/configure.ac @@ -931,9 +931,9 @@ fi if test x$use_boost = xyes; then dnl Minimum required Boost version -define(MINIMUM_REQUIRED_BOOST, 1.57.0) +define(MINIMUM_REQUIRED_BOOST, 1.58.0) -dnl Check for boost libs +dnl Check for Boost libs AX_BOOST_BASE([MINIMUM_REQUIRED_BOOST]) if test x$want_boost = xno; then AC_MSG_ERROR([[only libbitcoinconsensus can be built without boost]]) diff --git a/doc/dependencies.md b/doc/dependencies.md index b150c515b5..4db97d2c7b 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -6,7 +6,7 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | Dependency | Version used | Minimum required | CVEs | Shared | [Bundled Qt library](https://doc.qt.io/qt-5/configure-options.html#third-party-libraries) | | --- | --- | --- | --- | --- | --- | | Berkeley DB | [4.8.30](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.x | No | | | -| Boost | [1.71.0](https://www.boost.org/users/download/) | [1.57.0](https://github.com/PRCYCoin/PRCYCoin/pull/286) | No | | | +| Boost | [1.71.0](https://www.boost.org/users/download/) | [1.58.0](https://github.com/PRCYCoin/PRCYCoin/pull/286) | No | | | | Clang | | [3.3+](https://llvm.org/releases/download.html) (C++11 support) | | | | | D-Bus | [1.10.18](https://cgit.freedesktop.org/dbus/dbus/tree/NEWS?h=dbus-1.10) | | No | Yes | | | Fontconfig | [2.12.6](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | From c65edd1b124108ed2e76d45c1bbffbe4b7ef66f9 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 15:25:01 -0400 Subject: [PATCH 161/391] build: actually stop configure if Boost isn't available If Boost is not found via AX_BOOST_BASE, we don't actually stop configuring, only a warning is emitted: ```bash checking for boostlib >= 1.58.0 (105800)... configure: We could not detect the boost libraries (version MINIMUM_REQUIRED_BOOST or higher). If you have a staged boost library (still not installed) please specify $BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation. ``` Instead we would usually fail when one of the other AX_BOOST_* macros fails to find a library. These macros are slowly being removed, and in any case, it makes more sense to fail earlier if Boost is missing. If Boost is unavailable, the failure now looks like: ```bash checking for boostlib >= 1.58.0 (105800)... configure: We could not detect the boost libraries (version 1.58.0 or higher). If you have a staged boost library (still not installed) please specify $BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation. configure: error: Boost is not available! ``` Note that we now just pass the version into AX_BOOST_BASE, which fixes it's display in the output (rather than MINIMUM_REQUIRED_BOOST). --- configure.ac | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 06a9206cc6..cdc5e887e6 100644 --- a/configure.ac +++ b/configure.ac @@ -930,11 +930,8 @@ fi if test x$use_boost = xyes; then -dnl Minimum required Boost version -define(MINIMUM_REQUIRED_BOOST, 1.58.0) - -dnl Check for Boost libs -AX_BOOST_BASE([MINIMUM_REQUIRED_BOOST]) +dnl Check for Boost headers +AX_BOOST_BASE([1.58.0],[],[AC_MSG_ERROR([Boost is not available!])]) if test x$want_boost = xno; then AC_MSG_ERROR([[only libbitcoinconsensus can be built without boost]]) fi From c65f84123dd38dccc027769be7454191a5faa744 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 16:15:36 -0400 Subject: [PATCH 162/391] build: set minimum required Boost to 1.64.0 --- configure.ac | 2 +- doc/dependencies.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index cdc5e887e6..7504e85557 100644 --- a/configure.ac +++ b/configure.ac @@ -931,7 +931,7 @@ fi if test x$use_boost = xyes; then dnl Check for Boost headers -AX_BOOST_BASE([1.58.0],[],[AC_MSG_ERROR([Boost is not available!])]) +AX_BOOST_BASE([1.64.0],[],[AC_MSG_ERROR([Boost is not available!])]) if test x$want_boost = xno; then AC_MSG_ERROR([[only libbitcoinconsensus can be built without boost]]) fi diff --git a/doc/dependencies.md b/doc/dependencies.md index 4db97d2c7b..f763460b06 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -6,7 +6,7 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | Dependency | Version used | Minimum required | CVEs | Shared | [Bundled Qt library](https://doc.qt.io/qt-5/configure-options.html#third-party-libraries) | | --- | --- | --- | --- | --- | --- | | Berkeley DB | [4.8.30](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.x | No | | | -| Boost | [1.71.0](https://www.boost.org/users/download/) | [1.58.0](https://github.com/PRCYCoin/PRCYCoin/pull/286) | No | | | +| Boost | [1.71.0](https://www.boost.org/users/download/) | [1.64.0](https://github.com/PRCYCoin/PRCYCoin/pull/286) | No | | | | Clang | | [3.3+](https://llvm.org/releases/download.html) (C++11 support) | | | | | D-Bus | [1.10.18](https://cgit.freedesktop.org/dbus/dbus/tree/NEWS?h=dbus-1.10) | | No | Yes | | | Fontconfig | [2.12.6](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | From 1207f666df82fcce4f980778b6aeaf7f1941a29e Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 16:35:05 -0400 Subject: [PATCH 163/391] rpc: Add WWW-Authenticate header to 401 response A WWW-Authenticate header must be present in the 401 response to make clients know that they can authenticate, and how. WWW-Authenticate: Basic realm="jsonrpc" Fixes https://github.com/bitcoin/bitcoin/issues/7462. --- src/httprpc.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 55cced6396..7e013fbde8 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -21,6 +21,9 @@ #include // boost::trim +/** WWW-Authenticate to present with 401 Unauthorized response */ +static const char* WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; + /** Simple one-shot callback timer to be used by the RPC mechanism to e.g. * re-lock the wellet. */ @@ -151,6 +154,7 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) // Check authorization std::pair authHeader = req->GetHeader("authorization"); if (!authHeader.first) { + req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA); req->WriteReply(HTTP_UNAUTHORIZED); return false; } @@ -163,6 +167,7 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) shouldn't have their RPC port exposed. */ MilliSleep(250); + req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA); req->WriteReply(HTTP_UNAUTHORIZED); return false; } From 4f55cb211414b472a845c305086ba119575d4492 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 16:36:39 -0400 Subject: [PATCH 164/391] Fix doxygen comment for payTxFee --- src/wallet/wallet.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 39ba4aca21..8782562b57 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -47,9 +47,7 @@ #endif CWallet* pwalletMain = nullptr; -/** - * Settings - */ +/** Transaction fee set by the user */ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; unsigned int nTxConfirmTarget = 1; From 0683d30b548636f1e6f928feb25aa87acf9d13d1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 16:45:18 -0400 Subject: [PATCH 165/391] [doc] Fix markdown --- doc/README.md | 2 +- share/rpcuser/README.md | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/README.md b/doc/README.md index 6f9f149ec4..c6e998da63 100644 --- a/doc/README.md +++ b/doc/README.md @@ -39,7 +39,7 @@ The following are developer notes on how to build PRCYCoin on your native platfo - [macOS Build Notes](build-osx.md) - [Unix Build Notes](build-unix.md) - [Windows Build Notes](build-windows.md) -- [FreeBSD Build Notes](build-freeebsd.md) +- [FreeBSD Build Notes](build-freebsd.md) - [OpenBSD Build Notes](build-openbsd.md) - [NetBSD Build Notes](build-netbsd.md) - [Gitian Building Guide](gitian-building.md) diff --git a/share/rpcuser/README.md b/share/rpcuser/README.md index 7c2c909a42..12a8e6fb0c 100644 --- a/share/rpcuser/README.md +++ b/share/rpcuser/README.md @@ -7,5 +7,4 @@ Create an RPC user login credential. Usage: -./rpcuser.py - + ./rpcuser.py From b536d692e656d396d22925a642982bdc8a96fcef Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 16:45:28 -0400 Subject: [PATCH 166/391] Make sure LogPrintf strings are line-terminated --- src/httprpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 7e013fbde8..069f01788e 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -219,7 +219,7 @@ static bool InitRPCAuthentication() return false; } } else { - LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation."); + LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation.\n"); strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } return true; From fdc43fbf787339f602249952032d219e79e8a10d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 16:46:42 -0400 Subject: [PATCH 167/391] Fix dnl comment and alignment for OpenSSL/Libevent in configure.ac --- configure.ac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 6b2a763e0f..257d11393d 100644 --- a/configure.ac +++ b/configure.ac @@ -991,13 +991,13 @@ if test x$use_boost = xyes; then BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" fi -dnl libevent check - AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) - AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) +AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) +AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) - AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) - AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) +AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) +AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) +dnl libevent check if test x$build_bitcoin_cli$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench != xnonononono; then PKG_CHECK_MODULES([EVENT], [libevent >= 2.0.21], [use_libevent=yes], [AC_MSG_ERROR([libevent version 2.0.21 or greater not found.])]) if test x$TARGET_OS != xwindows; then From 6c006ac48f15bf9e2aeb87c155e40658355a323b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 27 Mar 2023 16:15:59 -0400 Subject: [PATCH 168/391] build: remove workaround for Boost and std::atomic --- configure.ac | 5 ----- 1 file changed, 5 deletions(-) diff --git a/configure.ac b/configure.ac index 7504e85557..108e4df67e 100644 --- a/configure.ac +++ b/configure.ac @@ -940,11 +940,6 @@ AX_BOOST_FILESYSTEM AX_BOOST_PROGRAM_OPTIONS AX_BOOST_THREAD AX_BOOST_CHRONO - -dnl Boost 1.56 through 1.62 allow using std::atomic instead of its own atomic -dnl counter implementations. In 1.63 and later the std::atomic approach is default. -m4_pattern_allow(DBOOST_AC_USE_STD_ATOMIC) dnl otherwise it's treated like a macro -BOOST_CPPFLAGS="-DBOOST_SP_USE_STD_ATOMIC -DBOOST_AC_USE_STD_ATOMIC $BOOST_CPPFLAGS" fi if test x$use_reduce_exports = xyes; then From bbb932a03e789db96b58cbfdde9b318da3fd7d15 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 22:52:04 -0400 Subject: [PATCH 169/391] http: Do a pending c++11 simplification Use std::unique_ptr for handling work items. This makes the code more RAII and, as mentioned in the comment, is what I planned when I wrote the code in the first place. --- src/httpserver.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 69502ea058..44b5b5a062 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -71,8 +71,7 @@ class WorkQueue /** Mutex protects entire object */ std::mutex cs; std::condition_variable cond; - /* XXX in C++11 we can use std::unique_ptr here and avoid manual cleanup */ - std::deque queue; + std::deque> queue; bool running; size_t maxDepth; int numThreads; @@ -101,15 +100,11 @@ class WorkQueue numThreads(0) { } - /*( Precondition: worker threads have all stopped + /** Precondition: worker threads have all stopped * (call WaitExit) */ ~WorkQueue() { - while (!queue.empty()) { - delete queue.front(); - queue.pop_front(); - } } /** Enqueue a work item */ bool Enqueue(WorkItem* item) @@ -118,7 +113,7 @@ class WorkQueue if (queue.size() >= maxDepth) { return false; } - queue.push_back(item); + queue.emplace_back(std::unique_ptr(item)); cond.notify_one(); return true; } @@ -127,18 +122,17 @@ class WorkQueue { ThreadCounter count(*this); while (running) { - WorkItem* i = 0; + std::unique_ptr i; { std::unique_lock lock(cs); while (running && queue.empty()) cond.wait(lock); if (!running) break; - i = queue.front(); + i = std::move(queue.front()); queue.pop_front(); } (*i)(); - delete i; } } /** Interrupt and exit loops */ From cae179484d17dc3163718fef110ea87dfa47cab6 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 22:53:37 -0400 Subject: [PATCH 170/391] http: Add log message when work queue is full More useful error reporting. --- src/httpserver.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 44b5b5a062..6223cd9ae0 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -300,8 +300,10 @@ static void http_request_cb(struct evhttp_request* req, void* arg) assert(workQueue); if (workQueue->Enqueue(item.get())) item.release(); /* if true, queue took ownership */ - else + else { + LogPrintf("WARNING: request rejected because http work queue depth exceeded, it can be increased with the -rpcworkqueue= setting\n"); item->req->WriteReply(HTTP_INTERNAL, "Work queue depth exceeded"); + } } else { hreq->WriteReply(HTTP_NOTFOUND); } From 3bf336cd6b503d0cdb6d753d447294aa168ab085 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 22:54:51 -0400 Subject: [PATCH 171/391] http: use std::move to move HTTPRequest into HTTPWorkItem Thanks to Cory Fields for the idea. --- src/httpserver.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 6223cd9ae0..64d25ad9cc 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -45,8 +45,8 @@ static const size_t MAX_HEADERS_SIZE = 8192; class HTTPWorkItem : public HTTPClosure { public: - HTTPWorkItem(HTTPRequest* req, const std::string &path, const HTTPRequestHandler& func): - req(req), path(path), func(func) + HTTPWorkItem(std::unique_ptr req, const std::string &path, const HTTPRequestHandler& func): + req(std::move(req)), path(path), func(func) { } void operator()() @@ -296,7 +296,7 @@ static void http_request_cb(struct evhttp_request* req, void* arg) // Dispatch to worker thread if (i != iend) { - std::unique_ptr item(new HTTPWorkItem(hreq.release(), path, i->handler)); + std::unique_ptr item(new HTTPWorkItem(std::move(hreq), path, i->handler)); assert(workQueue); if (workQueue->Enqueue(item.get())) item.release(); /* if true, queue took ownership */ From 3dda317898265b01862f6f8c633ff3ed68955cd8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 23:07:00 -0400 Subject: [PATCH 172/391] Do not shadow member variables --- src/httprpc.cpp | 2 +- src/httpserver.cpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 7e013fbde8..4cda8e78c4 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -45,7 +45,7 @@ class HTTPRPCTimer : public RPCTimerBase class HTTPRPCTimerInterface : public RPCTimerInterface { public: - HTTPRPCTimerInterface(struct event_base* base) : base(base) + HTTPRPCTimerInterface(struct event_base* _base) : base(_base) { } const char* Name() diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 64d25ad9cc..a839b825c3 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -45,8 +45,8 @@ static const size_t MAX_HEADERS_SIZE = 8192; class HTTPWorkItem : public HTTPClosure { public: - HTTPWorkItem(std::unique_ptr req, const std::string &path, const HTTPRequestHandler& func): - req(std::move(req)), path(path), func(func) + HTTPWorkItem(std::unique_ptr _req, const std::string &_path, const HTTPRequestHandler& _func): + req(std::move(_req)), path(_path), func(_func) { } void operator()() @@ -95,8 +95,8 @@ class WorkQueue }; public: - WorkQueue(size_t maxDepth) : running(true), - maxDepth(maxDepth), + WorkQueue(size_t _maxDepth) : running(true), + maxDepth(_maxDepth), numThreads(0) { } @@ -161,8 +161,8 @@ class WorkQueue struct HTTPPathHandler { HTTPPathHandler() {} - HTTPPathHandler(std::string prefix, bool exactMatch, HTTPRequestHandler handler): - prefix(prefix), exactMatch(exactMatch), handler(handler) + HTTPPathHandler(std::string _prefix, bool _exactMatch, HTTPRequestHandler _handler): + prefix(_prefix), exactMatch(_exactMatch), handler(_handler) { } std::string prefix; @@ -546,8 +546,8 @@ static void httpevent_callback_fn(evutil_socket_t, short, void* data) delete self; } -HTTPEvent::HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const std::function& handler): - deleteWhenTriggered(deleteWhenTriggered), handler(handler) +HTTPEvent::HTTPEvent(struct event_base* base, bool _deleteWhenTriggered, const std::function& _handler): + deleteWhenTriggered(_deleteWhenTriggered), handler(_handler) { ev = event_new(base, -1, 0, httpevent_callback_fn, this); assert(ev); @@ -563,7 +563,7 @@ void HTTPEvent::trigger(struct timeval* tv) else evtimer_add(ev, tv); // trigger after timeval passed } -HTTPRequest::HTTPRequest(struct evhttp_request* req) : req(req), +HTTPRequest::HTTPRequest(struct evhttp_request* _req) : req(_req), replySent(false) { } From 06f2fdd30eb13a2b04d140c07cfb611b8f439001 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 24 Mar 2023 23:09:13 -0400 Subject: [PATCH 173/391] [Trivial] Missing comments/whitespace --- src/httpserver.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index a839b825c3..54a4e03923 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -182,6 +182,7 @@ static std::vector rpc_allow_subnets; static WorkQueue* workQueue = 0; //! Handlers for (sub)paths std::vector pathHandlers; +//! Bound listening sockets std::vector boundSockets; /** Check if a network address is allowed to access the HTTP server */ @@ -315,6 +316,7 @@ static void http_reject_request_cb(struct evhttp_request* req, void*) LogPrint(BCLog::HTTP, "Rejecting request while shutting down\n"); evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL); } + /** Event dispatcher thread */ static bool ThreadHTTP(struct event_base* base, struct evhttp* http) { @@ -488,9 +490,11 @@ void InterruptHTTPServer() { LogPrint(BCLog::HTTP, "Interrupting HTTP server\n"); if (eventHTTP) { + // Unlisten sockets for (evhttp_bound_socket *socket : boundSockets) { evhttp_del_accept_socket(eventHTTP, socket); } + // Reject requests on current connections evhttp_set_gencb(eventHTTP, http_reject_request_cb, NULL); } if (workQueue) @@ -517,7 +521,6 @@ void StopHTTPServer() if (threadResult.valid() && threadResult.wait_for(std::chrono::milliseconds(2000)) == std::future_status::timeout) { LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n"); event_base_loopbreak(eventBase); - } threadHTTP.join(); } From 0a3f325f976eb10232e7050d5894037ace77e651 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 29 Mar 2023 14:41:31 -0400 Subject: [PATCH 174/391] [Depends] Bump zlib to v1.2.13 --- depends/packages/zlib.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/packages/zlib.mk b/depends/packages/zlib.mk index 12675691b9..7d929b65f6 100644 --- a/depends/packages/zlib.mk +++ b/depends/packages/zlib.mk @@ -1,8 +1,8 @@ package=zlib -$(package)_version=1.2.11 +$(package)_version=1.2.13 $(package)_download_path=https://www.zlib.net -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=d14c38e313afc35a9a8760dadf26042f51ea0f5d154b0630a31da0540107fb98 define $(package)_set_vars $(package)_config_opts= CC="$($(package)_cc)" From 21aae69f490bbe3a45722498d8133403b8be807d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 11:35:02 -0400 Subject: [PATCH 175/391] build: support LTO in depends No Qt for now. --- depends/Makefile | 6 ++++-- depends/README.md | 1 + depends/config.site.in | 4 ++++ depends/gen_id | 6 +++++- depends/hosts/android.mk | 5 +++++ depends/hosts/darwin.mk | 6 ++++++ depends/hosts/freebsd.mk | 6 ++++++ depends/hosts/linux.mk | 6 ++++++ depends/hosts/mingw32.mk | 6 ++++++ depends/hosts/netbsd.mk | 6 ++++++ depends/hosts/openbsd.mk | 6 ++++++ 11 files changed, 55 insertions(+), 3 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index d6a7893d5f..46898a7dc3 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -37,6 +37,7 @@ NO_QR ?= NO_WALLET ?= NO_ZMQ ?= NO_UPNP ?= +LTO ?= FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources BUILD = $(shell ./config.guess) @@ -139,8 +140,8 @@ include packages/packages.mk # 2. Before including packages/*.mk (excluding packages/packages.mk), since # they rely on the build_id variables # -build_id:=$(shell env CC='$(build_CC)' CXX='$(build_CXX)' AR='$(build_AR)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' ./gen_id '$(BUILD_ID_SALT)') -$(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' CXX='$(host_CXX)' AR='$(host_AR)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' ./gen_id '$(HOST_ID_SALT)') +build_id:=$(shell env CC='$(build_CC)' CXX='$(build_CXX)' AR='$(build_AR)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' ./gen_id '$(BUILD_ID_SALT)') +$(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' CXX='$(host_CXX)' AR='$(host_AR)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' ./gen_id '$(HOST_ID_SALT)') qrencode_packages_$(NO_QR) = $(qrencode_packages) @@ -225,6 +226,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@no_zmq@|$(NO_ZMQ)|' \ -e 's|@no_wallet@|$(NO_WALLET)|' \ -e 's|@no_upnp@|$(NO_UPNP)|' \ + -e 's|@lto@|$(LTO)|' \ -e 's|@debug@|$(DEBUG)|' \ $< > $@ $(AT)touch $@ diff --git a/depends/README.md b/depends/README.md index 87c3221daf..34877c91f4 100644 --- a/depends/README.md +++ b/depends/README.md @@ -102,6 +102,7 @@ The following can be set when running make: `make FOO=bar` - `FORCE_USE_SYSTEM_CLANG`: (EXPERTS ONLY) When cross-compiling for macOS, use Clang found in the system's `$PATH` rather than the default prebuilt release of Clang from llvm.org. Clang 8 or later is required. +- `LTO`: Use LTO when building packages. If some packages are not built, for example `make NO_WALLET=1`, the appropriate options will be passed to bitcoin's configure. In this case, `--disable-wallet`. diff --git a/depends/config.site.in b/depends/config.site.in index f1a59a5861..78fe935ef6 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -67,6 +67,10 @@ if test "x@host_os@" = xdarwin; then PORT=no fi +if test -z "$enable_lto" && test -n "@lto@"; then + enable_lto=yes +fi + PATH="${depends_prefix}/native/bin:${PATH}" PKG_CONFIG="$(which pkg-config) --static" diff --git a/depends/gen_id b/depends/gen_id index ac69ca7ee1..a0cd586461 100644 --- a/depends/gen_id +++ b/depends/gen_id @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Usage: env [ CC=... ] [ CXX=... ] [ AR=... ] [ RANLIB=... ] [ STRIP=... ] \ -# [ DEBUG=... ] ./build-id [ID_SALT]... +# [ DEBUG=... ] [ LTO=... ] ./build-id [ID_SALT]... # # Prints to stdout a SHA256 hash representing the current toolset, used by # depends/Makefile as a build id for caching purposes (detecting when the @@ -63,6 +63,10 @@ env | grep '^STRIP_' echo "END STRIP" + echo "BEGIN LTO" + echo "LTO=${LTO}" + echo "END LTO" + echo "END ALL" ) | if [ -n "$DEBUG" ] && command -v tee > /dev/null 2>&1; then # When debugging and `tee` is available, output the preimage to stderr diff --git a/depends/hosts/android.mk b/depends/hosts/android.mk index 4784f77a72..df70ef10ec 100644 --- a/depends/hosts/android.mk +++ b/depends/hosts/android.mk @@ -8,4 +8,9 @@ android_AR=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)-ar android_CXX=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang++ android_CC=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang android_RANLIB=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)-ranlib +endif + +ifneq ($(LTO),) +android_CFLAGS += -flto +android_LDFLAGS += -flto endif \ No newline at end of file diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index c2f6a60b62..b16d0540cb 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -110,6 +110,12 @@ darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include darwin_CFLAGS=-pipe + +ifneq ($(LTO),) +darwin_CFLAGS += -flto +darwin_LDFLAGS += -flto +endif + darwin_CXXFLAGS=$(darwin_CFLAGS) darwin_release_CFLAGS=-O2 diff --git a/depends/hosts/freebsd.mk b/depends/hosts/freebsd.mk index 0a62347b57..853fa0f457 100644 --- a/depends/hosts/freebsd.mk +++ b/depends/hosts/freebsd.mk @@ -1,4 +1,10 @@ freebsd_CFLAGS=-pipe + +ifneq ($(LTO),) +freebsd_CFLAGS += -flto +freebsd_LDFLAGS += -flto +endif + freebsd_CXXFLAGS=$(freebsd_CFLAGS) freebsd_release_CFLAGS=-O2 diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk index b13a0f1ad7..8c719c1954 100644 --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -1,4 +1,10 @@ linux_CFLAGS=-pipe + +ifneq ($(LTO),) +linux_CFLAGS += -flto +linux_LDFLAGS += -flto +endif + linux_CXXFLAGS=$(linux_CFLAGS) linux_release_CFLAGS=-O2 diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index 18045fcc25..3f631a211a 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -3,6 +3,12 @@ mingw32_CXX := $(host)-g++-posix endif mingw32_CFLAGS=-pipe + +ifneq ($(LTO),) +mingw32_CFLAGS += -flto +mingw32_LDFLAGS += -flto +endif + mingw32_CXXFLAGS=$(mingw32_CFLAGS) mingw32_release_CFLAGS=-O2 diff --git a/depends/hosts/netbsd.mk b/depends/hosts/netbsd.mk index b3e4545a64..9e48248b7e 100644 --- a/depends/hosts/netbsd.mk +++ b/depends/hosts/netbsd.mk @@ -1,4 +1,10 @@ netbsd_CFLAGS=-pipe + +ifneq ($(LTO),) +netbsd_CFLAGS += -flto +netbsd_LDFLAGS += -flto +endif + netbsd_CXXFLAGS=$(netbsd_CFLAGS) netbsd_release_CFLAGS=-O2 diff --git a/depends/hosts/openbsd.mk b/depends/hosts/openbsd.mk index dc8393e04c..918cd2880e 100644 --- a/depends/hosts/openbsd.mk +++ b/depends/hosts/openbsd.mk @@ -1,4 +1,10 @@ openbsd_CFLAGS=-pipe + +ifneq ($(LTO),) +openbsd_CFLAGS += -flto +openbsd_LDFLAGS += -flto +endif + openbsd_CFLAGS_CXXFLAGS=$(openbsd_CFLAGS) openbsd_CFLAGS_release_CFLAGS=-O2 From 10695323f3498c6da4e2d2e28225ab714197cbc7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 14:19:06 -0400 Subject: [PATCH 176/391] build: fix copypasta in OpenBSD C{XX} flags --- depends/hosts/openbsd.mk | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/depends/hosts/openbsd.mk b/depends/hosts/openbsd.mk index 918cd2880e..c4a629e021 100644 --- a/depends/hosts/openbsd.mk +++ b/depends/hosts/openbsd.mk @@ -1,17 +1,16 @@ openbsd_CFLAGS=-pipe +openbsd_CXXFLAGS=$(openbsd_CFLAGS) ifneq ($(LTO),) openbsd_CFLAGS += -flto openbsd_LDFLAGS += -flto endif -openbsd_CFLAGS_CXXFLAGS=$(openbsd_CFLAGS) +openbsd_release_CFLAGS=-O2 +openbsd_release_CXXFLAGS=$(openbsd_release_CFLAGS) -openbsd_CFLAGS_release_CFLAGS=-O2 -openbsd_CFLAGS_release_CXXFLAGS=$(openbsd_release_CFLAGS) - -openbsd_CFLAGS_debug_CFLAGS=-O1 -openbsd_CFLAGS_debug_CXXFLAGS=$(openbsd_debug_CFLAGS) +openbsd_debug_CFLAGS=-O1 +openbsd_debug_CXXFLAGS=$(openbsd_debug_CFLAGS) ifeq (86,$(findstring 86,$(build_arch))) i686_openbsd_CC=clang -m32 From 5777ea2171815b57239262ac72a96c95e3d79248 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 14:53:26 -0400 Subject: [PATCH 177/391] Replace $(AT) with .SILENCE. This reduces the amount of syntax noise in the makefiles. --- depends/Makefile | 23 +++++++------- depends/funcs.mk | 78 ++++++++++++++++++++++++------------------------ 2 files changed, 49 insertions(+), 52 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index 46898a7dc3..9a7683292b 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -105,10 +105,6 @@ host_prefix=$($(host_arch)_$(host_os)_prefix) build_prefix=$(host_prefix)/native build_host=$(build) -AT_$(V):= -AT_:=@ -AT:=$(AT_$(V)) - all: install include hosts/$(host_os).mk @@ -174,12 +170,12 @@ include funcs.mk final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in) final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)) $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) - $(AT)rm -rf $(@D) - $(AT)mkdir -p $(@D) - $(AT)echo copying packages: $^ - $(AT)echo to: $(@D) - $(AT)cd $(@D); $(foreach package,$^, $(build_TAR) xf $($(package)_cached); ) - $(AT)touch $@ + rm -rf $(@D) + mkdir -p $(@D) + echo copying packages: $^ + echo to: $(@D) + cd $(@D); $(foreach package,$^, $(build_TAR) xf $($(package)_cached); ) + touch $@ # $PATH is not preserved between ./configure and make by convention. Its # modification and overriding at ./configure time is (as I understand it) @@ -206,8 +202,8 @@ $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) # we expect them to be available in $PATH at all times, more specificity does # not hurt. $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_build_id) - $(AT)@mkdir -p $(@D) - $(AT)sed -e 's|@HOST@|$(host)|' \ + @mkdir -p $(@D) + sed -e 's|@HOST@|$(host)|' \ -e 's|@CC@|$(host_CC)|' \ -e 's|@CXX@|$(host_CXX)|' \ -e 's|@AR@|$(host_AR)|' \ @@ -229,7 +225,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@lto@|$(LTO)|' \ -e 's|@debug@|$(DEBUG)|' \ $< > $@ - $(AT)touch $@ + touch $@ define check_or_remove_cached @@ -277,3 +273,4 @@ download: download-osx download-linux download-win $(foreach package,$(all_packages),$(eval $(call ext_add_stages,$(package)))) .PHONY: install cached clean clean-all download-one download-osx download-linux download-win download check-packages check-sources +$(V).SILENT: \ No newline at end of file diff --git a/depends/funcs.mk b/depends/funcs.mk index d4194793b6..dc344f4b54 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -165,53 +165,53 @@ endef define int_add_cmds $($(1)_fetched): - $(AT)mkdir -p $$(@D) $(SOURCES_PATH) - $(AT)rm -f $$@ - $(AT)touch $$@ - $(AT)cd $$(@D); $(call $(1)_fetch_cmds,$(1)) - $(AT)cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);) - $(AT)touch $$@ + mkdir -p $$(@D) $(SOURCES_PATH) + rm -f $$@ + touch $$@ + cd $$(@D); $(call $(1)_fetch_cmds,$(1)) + cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);) + touch $$@ $($(1)_extracted): | $($(1)_fetched) - $(AT)echo Extracting $(1)... - $(AT)mkdir -p $$(@D) - $(AT)cd $$(@D); $(call $(1)_extract_cmds,$(1)) - $(AT)touch $$@ + echo Extracting $(1)... + mkdir -p $$(@D) + cd $$(@D); $(call $(1)_extract_cmds,$(1)) + touch $$@ $($(1)_preprocessed): | $($(1)_extracted) - $(AT)echo Preprocessing $(1)... - $(AT)mkdir -p $$(@D) $($(1)_patch_dir) - $(AT)$(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;) - $(AT)cd $$(@D); $(call $(1)_preprocess_cmds, $(1)) - $(AT)touch $$@ + echo Preprocessing $(1)... + mkdir -p $$(@D) $($(1)_patch_dir) + $(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;) + cd $$(@D); $(call $(1)_preprocess_cmds, $(1)) + touch $$@ $($(1)_configured): | $($(1)_dependencies) $($(1)_preprocessed) - $(AT)echo Configuring $(1)... - $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), $(build_TAR) --no-same-owner -xf $($(package)_cached); ) - $(AT)mkdir -p $$(@D) - $(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1)) - $(AT)touch $$@ + echo Configuring $(1)... + rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), $(build_TAR) --no-same-owner -xf $($(package)_cached); ) + mkdir -p $$(@D) + +cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1)) + touch $$@ $($(1)_built): | $($(1)_configured) - $(AT)echo Building $(1)... - $(AT)mkdir -p $$(@D) - $(AT)+cd $$(@D); $($(1)_build_env) $(call $(1)_build_cmds, $(1)) - $(AT)touch $$@ + echo Building $(1)... + mkdir -p $$(@D) + +cd $$(@D); $($(1)_build_env) $(call $(1)_build_cmds, $(1)) + touch $$@ $($(1)_staged): | $($(1)_built) - $(AT)echo Staging $(1)... - $(AT)mkdir -p $($(1)_staging_dir)/$(host_prefix) - $(AT)cd $($(1)_build_dir); $($(1)_stage_env) $(call $(1)_stage_cmds, $(1)) - $(AT)rm -rf $($(1)_extract_dir) - $(AT)touch $$@ + echo Staging $(1)... + mkdir -p $($(1)_staging_dir)/$(host_prefix) + cd $($(1)_build_dir); $($(1)_stage_env) $(call $(1)_stage_cmds, $(1)) + rm -rf $($(1)_extract_dir) + touch $$@ $($(1)_postprocessed): | $($(1)_staged) - $(AT)echo Postprocessing $(1)... - $(AT)cd $($(1)_staging_prefix_dir); $(call $(1)_postprocess_cmds) - $(AT)touch $$@ + echo Postprocessing $(1)... + cd $($(1)_staging_prefix_dir); $(call $(1)_postprocess_cmds) + touch $$@ $($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed) - $(AT)echo Caching $(1)... - $(AT)cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | $(build_TAR) --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - - $(AT)mkdir -p $$(@D) - $(AT)rm -rf $$(@D) && mkdir -p $$(@D) - $(AT)mv $$($(1)_staging_dir)/$$(@F) $$(@) - $(AT)rm -rf $($(1)_staging_dir) + echo Caching $(1)... + cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | $(build_TAR) --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - + mkdir -p $$(@D) + rm -rf $$(@D) && mkdir -p $$(@D) + mv $$($(1)_staging_dir)/$$(@F) $$(@) + rm -rf $($(1)_staging_dir) $($(1)_cached_checksum): $($(1)_cached) - $(AT)cd $$(@D); $(build_SHA256SUM) $$( $$(@) + cd $$(@D); $(build_SHA256SUM) $$( $$(@) .PHONY: $(1) $(1): | $($(1)_cached_checksum) From 2f9bdaabe61c37d4abd40d3bdaafa4c1898c38ad Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 15:06:14 -0400 Subject: [PATCH 178/391] build, refactor: Drop useless `call` Make function --- depends/funcs.mk | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index dc344f4b54..b65fde511e 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -168,40 +168,40 @@ $($(1)_fetched): mkdir -p $$(@D) $(SOURCES_PATH) rm -f $$@ touch $$@ - cd $$(@D); $(call $(1)_fetch_cmds,$(1)) + cd $$(@D); $($(1)_fetch_cmds) cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);) touch $$@ $($(1)_extracted): | $($(1)_fetched) echo Extracting $(1)... mkdir -p $$(@D) - cd $$(@D); $(call $(1)_extract_cmds,$(1)) + cd $$(@D); $($(1)_extract_cmds) touch $$@ $($(1)_preprocessed): | $($(1)_extracted) echo Preprocessing $(1)... mkdir -p $$(@D) $($(1)_patch_dir) $(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;) - cd $$(@D); $(call $(1)_preprocess_cmds, $(1)) + cd $$(@D); $($(1)_preprocess_cmds) touch $$@ $($(1)_configured): | $($(1)_dependencies) $($(1)_preprocessed) echo Configuring $(1)... rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), $(build_TAR) --no-same-owner -xf $($(package)_cached); ) mkdir -p $$(@D) - +cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1)) + +cd $$(@D); $($(1)_config_env) $($(1)_config_cmds) touch $$@ $($(1)_built): | $($(1)_configured) echo Building $(1)... mkdir -p $$(@D) - +cd $$(@D); $($(1)_build_env) $(call $(1)_build_cmds, $(1)) + +cd $$(@D); $($(1)_build_env) $($(1)_build_cmds) touch $$@ $($(1)_staged): | $($(1)_built) echo Staging $(1)... mkdir -p $($(1)_staging_dir)/$(host_prefix) - cd $($(1)_build_dir); $($(1)_stage_env) $(call $(1)_stage_cmds, $(1)) + cd $($(1)_build_dir); $($(1)_stage_env) $($(1)_stage_cmds) rm -rf $($(1)_extract_dir) touch $$@ $($(1)_postprocessed): | $($(1)_staged) echo Postprocessing $(1)... - cd $($(1)_staging_prefix_dir); $(call $(1)_postprocess_cmds) + cd $($(1)_staging_prefix_dir); $($(1)_postprocess_cmds) touch $$@ $($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed) echo Caching $(1)... From 1dc1a2bea4a0f0211fcc29125da3fac28af8b2c7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 15:47:26 -0400 Subject: [PATCH 179/391] depends: Add file-based logging for individual packages --- depends/Makefile | 2 +- depends/README.md | 5 ++++- depends/funcs.mk | 15 +++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index 9a7683292b..cfc5ed78e3 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -255,7 +255,7 @@ clean-all: clean @rm -rf $(SOURCES_PATH) x86_64* i686* mips* arm* aarch64* riscv32* riscv64* clean: - @rm -rf $(WORK_PATH) $(BASE_CACHE) $(BUILD) + @rm -rf $(WORK_PATH) $(BASE_CACHE) $(BUILD) *.log install: check-packages $(host_prefix)/share/config.site diff --git a/depends/README.md b/depends/README.md index 34877c91f4..e704649a01 100644 --- a/depends/README.md +++ b/depends/README.md @@ -101,7 +101,10 @@ The following can be set when running make: `make FOO=bar` - `BUILD_ID_SALT`: Optional salt to use when generating build package ids - `FORCE_USE_SYSTEM_CLANG`: (EXPERTS ONLY) When cross-compiling for macOS, use Clang found in the system's `$PATH` rather than the default prebuilt release of Clang - from llvm.org. Clang 8 or later is required. + from llvm.org. Clang 8 or later is required +- `LOG`: Use file-based logging for individual packages. During a package build its log file + resides in the `depends` directory, and the log file is printed out automatically in case + of build error. After successful build log files are moved along with package archives - `LTO`: Use LTO when building packages. If some packages are not built, for example `make NO_WALLET=1`, the appropriate diff --git a/depends/funcs.mk b/depends/funcs.mk index b65fde511e..bdf0ecd329 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -67,6 +67,7 @@ $(1)_cached_checksum:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_bui $(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id) $(1)_prefixbin:=$($($(1)_type)_prefix)/bin/ $(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz +$(1)_build_log:=$(BASEDIR)/$(1)-$($(1)_version)-$($(1)_build_id).log $(1)_all_sources=$($(1)_file_name) $($(1)_extra_sources) #stamps @@ -85,6 +86,7 @@ $(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path)) # The default behavior for tar will try to set ownership when running as uid 0 and may not succeed, --no-same-owner disables this behavior $(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)),$$($(1)_download_file),$($(1)_file_name),$($(1)_sha256_hash)) $(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_TAR) --no-same-owner --strip-components=1 -xf $$($(1)_source) +$(1)_preprocess_cmds ?= true $(1)_build_cmds ?= $(1)_config_cmds ?= $(1)_stage_cmds ?= @@ -164,6 +166,10 @@ endif endef define int_add_cmds +ifneq ($(LOG),) +$(1)_logging = >>$$($(1)_build_log) 2>&1 || { if test -f $$($(1)_build_log); then cat $$($(1)_build_log); fi; exit 1; } +endif + $($(1)_fetched): mkdir -p $$(@D) $(SOURCES_PATH) rm -f $$@ @@ -180,23 +186,23 @@ $($(1)_preprocessed): | $($(1)_extracted) echo Preprocessing $(1)... mkdir -p $$(@D) $($(1)_patch_dir) $(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;) - cd $$(@D); $($(1)_preprocess_cmds) + { cd $$(@D); $($(1)_preprocess_cmds); } $$($(1)_logging) touch $$@ $($(1)_configured): | $($(1)_dependencies) $($(1)_preprocessed) echo Configuring $(1)... rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), $(build_TAR) --no-same-owner -xf $($(package)_cached); ) mkdir -p $$(@D) - +cd $$(@D); $($(1)_config_env) $($(1)_config_cmds) + +{ cd $$(@D); $($(1)_config_env) $($(1)_config_cmds); } $$($(1)_logging) touch $$@ $($(1)_built): | $($(1)_configured) echo Building $(1)... mkdir -p $$(@D) - +cd $$(@D); $($(1)_build_env) $($(1)_build_cmds) + +{ cd $$(@D); $($(1)_build_env) $($(1)_build_cmds); } $$($(1)_logging) touch $$@ $($(1)_staged): | $($(1)_built) echo Staging $(1)... mkdir -p $($(1)_staging_dir)/$(host_prefix) - cd $($(1)_build_dir); $($(1)_stage_env) $($(1)_stage_cmds) + +{ cd $($(1)_build_dir); $($(1)_stage_env) $($(1)_stage_cmds); } $$($(1)_logging) rm -rf $($(1)_extract_dir) touch $$@ $($(1)_postprocessed): | $($(1)_staged) @@ -210,6 +216,7 @@ $($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed) rm -rf $$(@D) && mkdir -p $$(@D) mv $$($(1)_staging_dir)/$$(@F) $$(@) rm -rf $($(1)_staging_dir) + if test -f $($(1)_build_log); then mv $($(1)_build_log) $$(@D); fi $($(1)_cached_checksum): $($(1)_cached) cd $$(@D); $(build_SHA256SUM) $$( $$(@) From 0ab2e943bf7a4b562f1b9d54f609fedc75925659 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 16:58:58 -0400 Subject: [PATCH 180/391] build: libevent 2.1.12-stable --- depends/packages/libevent.mk | 14 ++++---------- .../libevent/0001-fix-windows-getaddrinfo.patch | 15 --------------- doc/dependencies.md | 2 +- 3 files changed, 5 insertions(+), 26 deletions(-) delete mode 100644 depends/patches/libevent/0001-fix-windows-getaddrinfo.patch diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index 699304af76..0b2ef01223 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -1,14 +1,8 @@ package=libevent -$(package)_version=2.1.11-stable -$(package)_download_path=https://github.com/libevent/libevent/archive/ -$(package)_file_name=release-$($(package)_version).tar.gz -$(package)_sha256_hash=229393ab2bf0dc94694f21836846b424f3532585bac3468738b7bf752c03901e -$(package)_patches=0001-fix-windows-getaddrinfo.patch - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/0001-fix-windows-getaddrinfo.patch && \ - ./autogen.sh -endef +$(package)_version=2.1.12-stable +$(package)_download_path=https://github.com/libevent/libevent/releases/download/release-$($(package)_version)/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb # When building for Windows, we set _WIN32_WINNT to target the same Windows # version as we do in configure. Due to quirks in libevents build system, this diff --git a/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch b/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch deleted file mode 100644 index a98cd90bd5..0000000000 --- a/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -ur libevent-2.1.8-stable.orig/configure.ac libevent-2.1.8-stable/configure.ac ---- libevent-2.1.8-stable.orig/configure.ac 2017-01-29 17:51:00.000000000 +0000 -+++ libevent-2.1.8-stable/configure.ac 2020-03-07 01:11:16.311335005 +0000 -@@ -389,6 +389,10 @@ - #ifdef HAVE_NETDB_H - #include - #endif -+#ifdef _WIN32 -+#include -+#include -+#endif - ]], - [[ - getaddrinfo; -Only in libevent-2.1.8-stable: configure.ac~ diff --git a/doc/dependencies.md b/doc/dependencies.md index f763460b06..7ec83d16ec 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -13,7 +13,7 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | FreeType | [2.11.0](https://download.savannah.gnu.org/releases/freetype) | | No | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) (Android only) | | GCC | | [4.8+](https://gcc.gnu.org/) (C++11 support) | | | | | HarfBuzz-NG | | | | | | -| libevent | [2.1.11-stable](https://github.com/libevent/libevent/releases) | [2.0.21](https://github.com/PRCYCoin/PRCYCoin/pull/385) | No | | | +| libevent | [2.1.12-stable](https://github.com/libevent/libevent/releases) | [2.0.21](https://github.com/PRCYCoin/PRCYCoin/pull/385) | No | | | | libjpeg | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L65) | | libpng | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L64) | | MiniUPnPc | [2.2.2](https://miniupnp.tuxfamily.org/files) | | No | | | From 8266a2b890d1ccffa070e21ae59404c25c497cec Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 17:41:56 -0400 Subject: [PATCH 181/391] build: don't install Boost cmake config files --- depends/packages/boost.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index e5d529bdd2..980efaaf86 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -53,5 +53,5 @@ define $(package)_build_cmds endef define $(package)_stage_cmds - b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) install + b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) --no-cmake-config install endef From 0adf9c6e8472dd1964cf652ab021a677d1453569 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 17:42:35 -0400 Subject: [PATCH 182/391] build: remove duplicate -fvisibility=hidden from Boost build Boost already sets this by default. --- depends/packages/boost.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 980efaaf86..372e65db98 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -32,7 +32,7 @@ else $(package)_toolset_$(host_os)=gcc endif $(package)_config_libraries=chrono,filesystem,program_options,system,thread,test -$(package)_cxxflags+=-std=c++17 -fvisibility=hidden +$(package)_cxxflags+=-std=c++17 $(package)_cxxflags_linux=-fPIC $(package)_cxxflags_freebsd=-fPIC $(package)_cxxflags_openbsd=-fPIC From 27bca6a1ad84bcab30dcafcd47ba8ca49b488e9c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 17:52:05 -0400 Subject: [PATCH 183/391] build: Make $(package)_*_env available to all $(package)_*_cmds --- depends/funcs.mk | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index bdf0ecd329..1d1463bf3d 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -87,9 +87,9 @@ $(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path)) $(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)),$$($(1)_download_file),$($(1)_file_name),$($(1)_sha256_hash)) $(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_TAR) --no-same-owner --strip-components=1 -xf $$($(1)_source) $(1)_preprocess_cmds ?= true -$(1)_build_cmds ?= -$(1)_config_cmds ?= -$(1)_stage_cmds ?= +$(1)_build_cmds ?= true +$(1)_config_cmds ?= true +$(1)_stage_cmds ?= true $(1)_set_vars ?= @@ -192,17 +192,17 @@ $($(1)_configured): | $($(1)_dependencies) $($(1)_preprocessed) echo Configuring $(1)... rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), $(build_TAR) --no-same-owner -xf $($(package)_cached); ) mkdir -p $$(@D) - +{ cd $$(@D); $($(1)_config_env) $($(1)_config_cmds); } $$($(1)_logging) + +{ cd $$(@D); export $($(1)_config_env); $($(1)_config_cmds); } $$($(1)_logging) touch $$@ $($(1)_built): | $($(1)_configured) echo Building $(1)... mkdir -p $$(@D) - +{ cd $$(@D); $($(1)_build_env) $($(1)_build_cmds); } $$($(1)_logging) + +{ cd $$(@D); export $($(1)_build_env); $($(1)_build_cmds); } $$($(1)_logging) touch $$@ $($(1)_staged): | $($(1)_built) echo Staging $(1)... mkdir -p $($(1)_staging_dir)/$(host_prefix) - +{ cd $($(1)_build_dir); $($(1)_stage_env) $($(1)_stage_cmds); } $$($(1)_logging) + +{ cd $($(1)_build_dir); export $($(1)_stage_env); $($(1)_stage_cmds); } $$($(1)_logging) rm -rf $($(1)_extract_dir) touch $$@ $($(1)_postprocessed): | $($(1)_staged) From 4c536ce2a8875bf11a91506524e925259c7bac34 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 17:54:54 -0400 Subject: [PATCH 184/391] build: Move environment variables into `$(package)_config_env` --- depends/funcs.mk | 1 + depends/packages/qt.mk | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index 1d1463bf3d..af89a92aea 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -137,6 +137,7 @@ $(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$( $(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig $(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig +$(1)_config_env+=PKG_CONFIG_SYSROOT_DIR=/ $(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH) $(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH) $(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index c557d3b303..f38d24071e 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -25,6 +25,7 @@ $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) define $(package)_set_vars +$(package)_config_env = QT_MAC_SDK_NO_VERSION_CHECK=1 $(package)_config_opts_release = -release $(package)_config_opts_release += -silent $(package)_config_opts_debug = -debug @@ -236,8 +237,6 @@ define $(package)_preprocess_cmds endef define $(package)_config_cmds - export PKG_CONFIG_SYSROOT_DIR=/ && \ - export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \ ./configure $($(package)_config_opts) && \ echo "host_build: QT_CONFIG ~= s/system-zlib/zlib" >> mkspecs/qconfig.pri && \ echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \ From 5e08d142bfab44f635df3e1bad476d4b8cafa4ef Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 30 Mar 2023 17:56:59 -0400 Subject: [PATCH 185/391] build: Make dependency package archive timestamps deterministic --- depends/funcs.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index bdf0ecd329..b880f80bc5 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -211,7 +211,9 @@ $($(1)_postprocessed): | $($(1)_staged) touch $$@ $($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed) echo Caching $(1)... - cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | $(build_TAR) --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - + cd $$($(1)_staging_dir)/$(host_prefix); \ + find . ! -name '.stamp_postprocessed' -print0 | TZ=UTC xargs -0r touch -h -m -t 200001011200; \ + find . ! -name '.stamp_postprocessed' | LC_ALL=C sort | $(build_TAR) --numeric-owner --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - mkdir -p $$(@D) rm -rf $$(@D) && mkdir -p $$(@D) mv $$($(1)_staging_dir)/$$(@F) $$(@) From f91d1444596a0bc105a2cd2bcb952998647e93cf Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 31 Mar 2023 14:45:09 -0400 Subject: [PATCH 186/391] build: Pass missed `strip` tool via `config.site` --- depends/config.site.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/depends/config.site.in b/depends/config.site.in index 78fe935ef6..8e6d11e1d5 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -108,6 +108,11 @@ if test -n "@NM@"; then ac_cv_path_ac_pt_NM="${NM}" fi +if test -n "@STRIP@"; then + STRIP="@STRIP@" + ac_cv_path_ac_pt_STRIP="${STRIP}" +fi + if test -n "@debug@"; then enable_reduce_exports=no fi From e3acb19b23c6a75bc1ddd8e6a1841d90956db8b1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 31 Mar 2023 14:45:45 -0400 Subject: [PATCH 187/391] scripted-diff: Rename INSTALLNAMETOOL -> INSTALL_NAME_TOOL This change makes naming of `install_name_tool` consistent across the whole build system. -BEGIN VERIFY SCRIPT- sed --in-place --expression='s/INSTALLNAMETOOL/INSTALL_NAME_TOOL/g' $(git grep --files-with-matches 'INSTALLNAMETOOL') -END VERIFY SCRIPT- --- Makefile.am | 2 +- configure.ac | 2 +- contrib/macdeploy/macdeployqtplus | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 29046bbf95..fdf0609a9b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -144,7 +144,7 @@ $(APP_DIST_DIR)/.background/background.tiff: cp $(OSX_BACKGROUND_IMAGE) $@ $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) - INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) + INSTALL_NAME_TOOL=$(INSTALL_NAME_TOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) deploydir: $(APP_DIST_EXTRAS) endif diff --git a/configure.ac b/configure.ac index 50cac728d5..8339a74e29 100644 --- a/configure.ac +++ b/configure.ac @@ -542,7 +542,7 @@ case $host in BUILD_OS=darwin ;; *) - AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) + AC_PATH_TOOL([INSTALL_NAME_TOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) AC_PATH_PROGS([XORRISOFS], [xorrisofs], xorrisofs) AC_PATH_PROGS([DMG], [dmg], dmg) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index ef8887f30e..a2f61753b1 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -211,7 +211,7 @@ def getFrameworks(binaryPath: str, verbose: int) -> List[FrameworkInfo]: return libraries def runInstallNameTool(action: str, *args): - installnametoolbin=os.getenv("INSTALLNAMETOOL", "install_name_tool") + installnametoolbin=os.getenv("INSTALL_NAME_TOOL", "install_name_tool") run([installnametoolbin, "-"+action] + list(args), check=True) def changeInstallName(oldName: str, newName: str, binaryPath: str, verbose: int): From 951de04ab00fe00619adab8646844d8b0dcd6634 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 31 Mar 2023 14:46:54 -0400 Subject: [PATCH 188/391] build: No need to provide defaults for darwin-specific tools --- depends/builders/default.mk | 2 -- depends/hosts/default.mk | 2 -- 2 files changed, 4 deletions(-) diff --git a/depends/builders/default.mk b/depends/builders/default.mk index 0370fb9acb..7911ffd973 100644 --- a/depends/builders/default.mk +++ b/depends/builders/default.mk @@ -5,8 +5,6 @@ default_build_TAR = tar default_build_RANLIB = ranlib default_build_STRIP = strip default_build_NM = nm -default_build_OTOOL = otool -default_build_INSTALL_NAME_TOOL = install_name_tool define add_build_tool_func build_$(build_os)_$1 ?= $$(default_build_$1) diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk index 258619a9d0..409fb568ef 100644 --- a/depends/hosts/default.mk +++ b/depends/hosts/default.mk @@ -8,8 +8,6 @@ default_host_AR = $(host_toolchain)ar default_host_RANLIB = $(host_toolchain)ranlib default_host_STRIP = $(host_toolchain)strip default_host_LIBTOOL = $(host_toolchain)libtool -default_host_INSTALL_NAME_TOOL = $(host_toolchain)install_name_tool -default_host_OTOOL = $(host_toolchain)otool default_host_NM = $(host_toolchain)nm define add_host_tool_func From 6a43b62d6152ab804ffbc7f8b41d7a92de89578a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 31 Mar 2023 14:47:51 -0400 Subject: [PATCH 189/391] build: Pass missed darwin-specific tools via `config.site` --- depends/Makefile | 2 ++ depends/config.site.in | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/depends/Makefile b/depends/Makefile index cfc5ed78e3..cfd911f6cc 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -210,6 +210,8 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@RANLIB@|$(host_RANLIB)|' \ -e 's|@NM@|$(host_NM)|' \ -e 's|@STRIP@|$(host_STRIP)|' \ + -e 's|@OTOOL@|$(host_OTOOL)|' \ + -e 's|@INSTALL_NAME_TOOL@|$(host_INSTALL_NAME_TOOL)|' \ -e 's|@build_os@|$(build_os)|' \ -e 's|@host_os@|$(host_os)|' \ -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \ diff --git a/depends/config.site.in b/depends/config.site.in index 8e6d11e1d5..bc6dd9ed23 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -113,6 +113,18 @@ if test -n "@STRIP@"; then ac_cv_path_ac_pt_STRIP="${STRIP}" fi +if test "@host_os@" = darwin; then + if test -n "@OTOOL@"; then + OTOOL="@OTOOL@" + ac_cv_path_ac_pt_OTOOL="${OTOOL}" + fi + + if test -n "@INSTALL_NAME_TOOL@"; then + INSTALL_NAME_TOOL="@INSTALL_NAME_TOOL@" + ac_cv_path_ac_pt_INSTALL_NAME_TOOL="${INSTALL_NAME_TOOL}" + fi +fi + if test -n "@debug@"; then enable_reduce_exports=no fi From 9ec5bf50bc399eff25cfde155cdbdf3948293767 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 31 Mar 2023 14:59:26 -0400 Subject: [PATCH 190/391] build: Let the depends build system define a path to `dsymutil` tool --- depends/Makefile | 1 + depends/builders/darwin.mk | 2 ++ depends/builders/default.mk | 2 +- depends/config.site.in | 5 +++++ depends/hosts/darwin.mk | 2 +- depends/hosts/default.mk | 2 +- 6 files changed, 11 insertions(+), 3 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index cfd911f6cc..be3a6eb4d7 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -212,6 +212,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@STRIP@|$(host_STRIP)|' \ -e 's|@OTOOL@|$(host_OTOOL)|' \ -e 's|@INSTALL_NAME_TOOL@|$(host_INSTALL_NAME_TOOL)|' \ + -e 's|@DSYMUTIL@|$(host_DSYMUTIL)|' \ -e 's|@build_os@|$(build_os)|' \ -e 's|@host_os@|$(host_os)|' \ -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \ diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index 986ad9b03d..7858ab0120 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -6,6 +6,7 @@ build_darwin_STRIP:=$(shell xcrun -f strip) build_darwin_OTOOL:=$(shell xcrun -f otool) build_darwin_NM:=$(shell xcrun -f nm) build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) +build_darwin_DSYMUTIL:=$(shell xcrun -f dsymutil) build_darwin_SHA256SUM=shasum -a 256 build_darwin_DOWNLOAD=curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o @@ -19,5 +20,6 @@ darwin_LIBTOOL:=$(shell xcrun -f libtool) darwin_OTOOL:=$(shell xcrun -f otool) darwin_NM:=$(shell xcrun -f nm) darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) +darwin_DSYMUTIL:=$(shell xcrun -f dsymutil) darwin_native_binutils= darwin_native_toolchain= diff --git a/depends/builders/default.mk b/depends/builders/default.mk index 7911ffd973..cc6dec66c2 100644 --- a/depends/builders/default.mk +++ b/depends/builders/default.mk @@ -11,7 +11,7 @@ build_$(build_os)_$1 ?= $$(default_build_$1) build_$(build_arch)_$(build_os)_$1 ?= $$(build_$(build_os)_$1) build_$1=$$(build_$(build_arch)_$(build_os)_$1) endef -$(foreach var,CC CXX AR TAR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL,$(eval $(call add_build_tool_func,$(var)))) +$(foreach var,CC CXX AR TAR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL DSYMUTIL,$(eval $(call add_build_tool_func,$(var)))) define add_build_flags_func build_$(build_arch)_$(build_os)_$1 += $(build_$(build_os)_$1) build_$1=$$(build_$(build_arch)_$(build_os)_$1) diff --git a/depends/config.site.in b/depends/config.site.in index bc6dd9ed23..e8be21e8d7 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -123,6 +123,11 @@ if test "@host_os@" = darwin; then INSTALL_NAME_TOOL="@INSTALL_NAME_TOOL@" ac_cv_path_ac_pt_INSTALL_NAME_TOOL="${INSTALL_NAME_TOOL}" fi + + if test -n "@DSYMUTIL@"; then + DSYMUTIL="@DSYMUTIL@" + ac_cv_path_ac_pt_DSYMUTIL="${DSYMUTIL}" + fi fi if test -n "@debug@"; then diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index b16d0540cb..62ddb02b43 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -38,7 +38,7 @@ clangxx_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang++") clang_resource_dir=$(shell clang -print-resource-dir) endif -cctools_TOOLS=AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL +cctools_TOOLS=AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL DSYMUTIL # Make-only lowercase function lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1)))))))))))))))))))))))))) diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk index 409fb568ef..ea60f025de 100644 --- a/depends/hosts/default.mk +++ b/depends/hosts/default.mk @@ -33,5 +33,5 @@ host_$1 = $$($(host_arch)_$(host_os)_$1) host_$(release_type)_$1 = $$($(host_arch)_$(host_os)_$(release_type)_$1) endef -$(foreach tool,CC CXX AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL,$(eval $(call add_host_tool_func,$(tool)))) +$(foreach tool,CC CXX AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL DSYMUTIL,$(eval $(call add_host_tool_func,$(tool)))) $(foreach flags,CFLAGS CXXFLAGS CPPFLAGS LDFLAGS, $(eval $(call add_host_flags_func,$(flags)))) From badd0e4898ed5fa70a62893adb40ed814860261d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 31 Mar 2023 15:00:22 -0400 Subject: [PATCH 191/391] build: No longer need to hack the `PATH` variable in `config.site` Now all of the tools have well-defined absolute paths to them. --- depends/config.site.in | 1 - 1 file changed, 1 deletion(-) diff --git a/depends/config.site.in b/depends/config.site.in index e8be21e8d7..50b9a9caae 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -71,7 +71,6 @@ if test -z "$enable_lto" && test -n "@lto@"; then enable_lto=yes fi -PATH="${depends_prefix}/native/bin:${PATH}" PKG_CONFIG="$(which pkg-config) --static" # These two need to remain exported because pkg-config does not see them From 6d84a50085326cf92e79a8485bf4c70a223da4ea Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 31 Mar 2023 15:17:34 -0400 Subject: [PATCH 192/391] build: Drop redundant checks for ranlib and strip tools These checks are handled by the `LT_INIT` macro. --- configure.ac | 2 -- 1 file changed, 2 deletions(-) diff --git a/configure.ac b/configure.ac index 8339a74e29..e681933139 100644 --- a/configure.ac +++ b/configure.ac @@ -83,8 +83,6 @@ LT_INIT([pic-only]) dnl Check/return PATH for base programs. AC_PATH_TOOL(AR, ar) -AC_PATH_TOOL(RANLIB, ranlib) -AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) AC_PATH_PROG(LCOV, lcov) dnl Python 3.6 is specified in .python-version and should be used if available, see doc/dependencies.md From aa3e74a9facf2b3773977ac7140f9a483ba26510 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 31 Mar 2023 15:48:31 -0400 Subject: [PATCH 193/391] build: perform all .tiff copying in macdeployqtplus By copying the .tiff earlier in the macdeploy process, we can unify the logic in the deploy script. --- Makefile.am | 7 +------ contrib/macdeploy/macdeployqtplus | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Makefile.am b/Makefile.am index fdf0609a9b..9b904b6942 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,7 +33,6 @@ OSX_APP=PRCYcoin-Qt.app OSX_VOLNAME = $(subst $(space),-,$(PACKAGE_NAME)) OSX_DMG = $(OSX_VOLNAME).dmg OSX_TEMP_ISO = $(OSX_DMG:.dmg=).temp.iso -OSX_BACKGROUND_IMAGE=$(top_srcdir)/contrib/macdeploy/background.tiff OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns OSX_PLIST=$(top_builddir)/share/qt/Info.plist #not installed @@ -124,7 +123,7 @@ $(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) deploydir: $(OSX_DMG) else APP_DIST_DIR=$(top_builddir)/dist -APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/background.tiff $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications +APP_DIST_EXTRAS=$(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications $(APP_DIST_DIR)/Applications: @rm -f $@ @@ -139,10 +138,6 @@ $(OSX_TEMP_ISO): $(APP_DIST_EXTRAS) $(OSX_DMG): $(OSX_TEMP_ISO) $(DMG) dmg "$<" "$@" -$(APP_DIST_DIR)/.background/background.tiff: - $(MKDIR_P) $(@D) - cp $(OSX_BACKGROUND_IMAGE) $@ - $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) INSTALL_NAME_TOOL=$(INSTALL_NAME_TOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index a2f61753b1..ba7bcb4d84 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -544,6 +544,16 @@ ds.close() if platform.system() == "Darwin": subprocess.check_call(f"codesign --deep --force --sign - {target}", shell=True) +print("+ Installing background.tiff +") + +bg_path = os.path.join('dist', '.background', 'background.tiff') +os.mkdir(os.path.dirname(bg_path)) + +tiff_path = os.path.join('contrib', 'macdeploy', 'background.tiff') +shutil.copy2(tiff_path, bg_path) + +# ------------------------------------------------ + if config.dmg is not None: print("+ Preparing .dmg disk image +") @@ -570,14 +580,6 @@ if config.dmg is not None: m = re.search(r"/Volumes/(.+$)", output) disk_root = m.group(0) - print("+ Applying fancy settings +") - - bg_path = os.path.join(disk_root, ".background", os.path.basename('background.tiff')) - os.mkdir(os.path.dirname(bg_path)) - if verbose: - print('background.tiff', "->", bg_path) - shutil.copy2('contrib/macdeploy/background.tiff', bg_path) - os.symlink("/Applications", os.path.join(disk_root, "Applications")) print("+ Finalizing .dmg disk image +") From 9ab6b9d901f83b85720082bfb0d67ee98b9b8de2 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 31 Mar 2023 15:55:23 -0400 Subject: [PATCH 194/391] build: perform /Applications symlink generation in macdeployqtplus By generating the symlink earlier in the macdeploy process, we can unify the logic in the deploy script. --- Makefile.am | 12 ++---------- contrib/macdeploy/macdeployqtplus | 11 ++++++----- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9b904b6942..65152b7533 100644 --- a/Makefile.am +++ b/Makefile.am @@ -123,16 +123,8 @@ $(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) deploydir: $(OSX_DMG) else APP_DIST_DIR=$(top_builddir)/dist -APP_DIST_EXTRAS=$(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications -$(APP_DIST_DIR)/Applications: - @rm -f $@ - @cd $(@D); $(LN_S) /Applications $(@F) - -$(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt - -.INTERMEDIATE: $(OSX_TEMP_ISO) -$(OSX_TEMP_ISO): $(APP_DIST_EXTRAS) +$(OSX_TEMP_ISO): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt $(XORRISOFS) -D -l -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -o $@ dist -- $(if $(SOURCE_DATE_EPOCH),-volume_date all_file_dates =$(SOURCE_DATE_EPOCH)) $(OSX_DMG): $(OSX_TEMP_ISO) @@ -141,7 +133,7 @@ $(OSX_DMG): $(OSX_TEMP_ISO) $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) INSTALL_NAME_TOOL=$(INSTALL_NAME_TOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) -deploydir: $(APP_DIST_EXTRAS) +deploydir: $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt endif if TARGET_DARWIN diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index ba7bcb4d84..4a4630aeac 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -554,6 +554,12 @@ shutil.copy2(tiff_path, bg_path) # ------------------------------------------------ +print("+ Generating symlink for /Applications +") + +os.symlink("/Applications", os.path.join('dist', "Applications")) + +# ------------------------------------------------ + if config.dmg is not None: print("+ Preparing .dmg disk image +") @@ -577,11 +583,6 @@ if config.dmg is not None: print("Attaching temp image...") output = run(["hdiutil", "attach", tempname, "-readwrite"], check=True, universal_newlines=True, stdout=PIPE).stdout - m = re.search(r"/Volumes/(.+$)", output) - disk_root = m.group(0) - - os.symlink("/Applications", os.path.join(disk_root, "Applications")) - print("+ Finalizing .dmg disk image +") run(["hdiutil", "detach", f"/Volumes/{appname}"], universal_newlines=True) From 72f5b4b79394cc83e5d2de41a88ec460dff7978c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 31 Mar 2023 16:26:54 -0400 Subject: [PATCH 195/391] build: don't compress macOS DMG --- .gitignore | 1 - Makefile.am | 7 +-- configure.ac | 1 - contrib/macdeploy/README.md | 11 +---- depends/packages/native_libdmg-hfsplus.mk | 24 ---------- depends/packages/packages.mk | 2 +- .../remove-libcrypto-dependency.patch | 45 ------------------- 7 files changed, 3 insertions(+), 88 deletions(-) delete mode 100644 depends/packages/native_libdmg-hfsplus.mk delete mode 100644 depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch diff --git a/.gitignore b/.gitignore index 642c21f81d..4ee1677587 100644 --- a/.gitignore +++ b/.gitignore @@ -88,7 +88,6 @@ src/qt/test/moc*.cpp *.log *.trs *.dmg -*.iso *.raw.h diff --git a/Makefile.am b/Makefile.am index 65152b7533..877d154de3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,7 +32,6 @@ space := $(empty) $(empty) OSX_APP=PRCYcoin-Qt.app OSX_VOLNAME = $(subst $(space),-,$(PACKAGE_NAME)) OSX_DMG = $(OSX_VOLNAME).dmg -OSX_TEMP_ISO = $(OSX_DMG:.dmg=).temp.iso OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns OSX_PLIST=$(top_builddir)/share/qt/Info.plist #not installed @@ -124,12 +123,9 @@ deploydir: $(OSX_DMG) else APP_DIST_DIR=$(top_builddir)/dist -$(OSX_TEMP_ISO): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt +$(OSX_DMG): deploydir $(XORRISOFS) -D -l -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -o $@ dist -- $(if $(SOURCE_DATE_EPOCH),-volume_date all_file_dates =$(SOURCE_DATE_EPOCH)) -$(OSX_DMG): $(OSX_TEMP_ISO) - $(DMG) dmg "$<" "$@" - $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) INSTALL_NAME_TOOL=$(INSTALL_NAME_TOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) @@ -137,7 +133,6 @@ deploydir: $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt endif if TARGET_DARWIN -appbundle: $(OSX_APP_BUILT) deploy: $(OSX_DMG) endif if TARGET_WINDOWS diff --git a/configure.ac b/configure.ac index e681933139..7c1a4577b1 100644 --- a/configure.ac +++ b/configure.ac @@ -543,7 +543,6 @@ case $host in AC_PATH_TOOL([INSTALL_NAME_TOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) AC_PATH_PROGS([XORRISOFS], [xorrisofs], xorrisofs) - AC_PATH_PROGS([DMG], [dmg], dmg) dnl libtool will try to strip the static lib, which is a problem for dnl cross-builds because strip attempts to call a hard-coded ld, diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md index 5552e53d7f..897453d2cf 100644 --- a/contrib/macdeploy/README.md +++ b/contrib/macdeploy/README.md @@ -94,16 +94,7 @@ redistributed. [`xorrisofs`](https://www.gnu.org/software/xorriso/) is used to create the DMG. -`xorrisofs` cannot compress DMGs, so afterwards, the DMG tool from the -`libdmg-hfsplus` project is used to compress it. There are several bugs in this -tool and its maintainer has seemingly abandoned the project. - -The DMG tool has the ability to create DMGs from scratch as well, but this functionality is -broken. Only the compression feature is currently used. Ideally, the creation could be fixed -and `xorrisofs` would no longer be necessary. - -Background images and other features can be added to DMG files by inserting a -`.DS_Store` during creation. +A background image is added to DMG files by inserting a `.DS_Store` during creation. As of OS X 10.9 Mavericks, using an Apple-blessed key to sign binaries is a requirement in order to satisfy the new Gatekeeper requirements. Because this private key cannot be diff --git a/depends/packages/native_libdmg-hfsplus.mk b/depends/packages/native_libdmg-hfsplus.mk deleted file mode 100644 index 8493f1d979..0000000000 --- a/depends/packages/native_libdmg-hfsplus.mk +++ /dev/null @@ -1,24 +0,0 @@ -package=native_libdmg-hfsplus -$(package)_version=7ac55ec64c96f7800d9818ce64c79670e7f02b67 -$(package)_download_path=https://github.com/planetbeing/libdmg-hfsplus/archive -$(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=56fbdc48ec110966342f0ecddd6f8f89202f4143ed2a3336e42bbf88f940850c -$(package)_build_subdir=build -$(package)_patches=remove-libcrypto-dependency.patch - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/remove-libcrypto-dependency.patch && \ - mkdir build -endef - -define $(package)_config_cmds - cmake -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix) .. -endef - -define $(package)_build_cmds - $(MAKE) -C dmg -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) -C dmg install -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 3bd2cfec90..a43c83e48a 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -19,7 +19,7 @@ darwin_native_packages = native_ds_store native_mac_alias $(host_arch)_$(host_os)_native_packages += native_b2 ifneq ($(build_os),darwin) -darwin_native_packages += native_cctools native_libtapi native_libdmg-hfsplus +darwin_native_packages += native_cctools native_libtapi ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) darwin_native_packages+= native_clang diff --git a/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch b/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch deleted file mode 100644 index f346c8f2cf..0000000000 --- a/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3e5fd3fb56bc9ff03beb535979e33dcf83fe1f70 Mon Sep 17 00:00:00 2001 -From: Cory Fields -Date: Thu, 8 May 2014 12:39:42 -0400 -Subject: [PATCH] dmg: remove libcrypto dependency - ---- - dmg/CMakeLists.txt | 16 ---------------- - 1 file changed, 16 deletions(-) - -diff --git a/dmg/CMakeLists.txt b/dmg/CMakeLists.txt -index eec62d6..3969f64 100644 ---- a/dmg/CMakeLists.txt -+++ b/dmg/CMakeLists.txt -@@ -1,12 +1,5 @@ --INCLUDE(FindOpenSSL) - INCLUDE(FindZLIB) - --FIND_LIBRARY(CRYPTO_LIBRARIES crypto -- PATHS -- /usr/lib -- /usr/local/lib -- ) -- - IF(NOT ZLIB_FOUND) - message(FATAL_ERROR "zlib is required for dmg!") - ENDIF(NOT ZLIB_FOUND) -@@ -18,15 +11,6 @@ link_directories(${PROJECT_BINARY_DIR}/common ${PROJECT_BINARY_DIR}/hfs) - - add_library(dmg adc.c base64.c checksum.c dmgfile.c dmglib.c filevault.c io.c partition.c resources.c udif.c) - --IF(OPENSSL_FOUND) -- add_definitions(-DHAVE_CRYPT) -- include_directories(${OPENSSL_INCLUDE_DIR}) -- target_link_libraries(dmg ${CRYPTO_LIBRARIES}) -- IF(WIN32) -- TARGET_LINK_LIBRARIES(dmg gdi32) -- ENDIF(WIN32) --ENDIF(OPENSSL_FOUND) -- - target_link_libraries(dmg common hfs z) - - add_executable(dmg-bin dmg.c) --- -2.22.0 - From f68024c459e70969fb4c12a5cd61e0bc7537ca95 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 10:04:19 -0400 Subject: [PATCH 196/391] [Actions] Remove if statement to enable Ubuntu 20 builds --- .github/workflows/prcy-build-factory-ubuntu20.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml index fed69bb7b4..3fd63d6c03 100644 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ b/.github/workflows/prcy-build-factory-ubuntu20.yml @@ -11,7 +11,6 @@ jobs: create-source-distribution: name: Create Source Distribution runs-on: ubuntu-20.04 - if: "contains(github.event.head_commit.message, '[focal]')" env: ARTIFACT_DIR: source steps: From 339fd82ba794390044ec9442fe7ea2773cfea82f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 10:05:30 -0400 Subject: [PATCH 197/391] [Actions] Replace Ubuntu 18 Actions with Ubuntu 20 --- .../workflows/prcy-build-factory-ubuntu20.yml | 431 ------------------ .github/workflows/prcy-build-factory.yml | 80 +--- 2 files changed, 14 insertions(+), 497 deletions(-) delete mode 100644 .github/workflows/prcy-build-factory-ubuntu20.yml diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml deleted file mode 100644 index 3fd63d6c03..0000000000 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ /dev/null @@ -1,431 +0,0 @@ -# Copyright (c) 2018-2020 The Veil developers -# Copyright (c) 2020 The DAPS Project -# Copyright (c) 2020 The PRivaCY Coin Developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -name: Github Actions CI for PRCY (Ubuntu 20) -on: [push, pull_request] -env: - SOURCE_ARTIFACT: source -jobs: - create-source-distribution: - name: Create Source Distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: source - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Create Version Variable - run: | - export VERSION=$(cat version.txt | sed 's/[^0-9,.]//g') - export TAG=v${VERSION} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - echo "TAG=${TAG}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Print Variables - run: | - echo "VERSION=${VERSION}" - echo "TAG=${TAG}" - printenv - - name: Create Distribution Tarball - run: | - mkdir -p $ARTIFACT_DIR - touch prcycoin.tar.gz - tar -czf prcycoin.tar.gz --exclude=prcycoin.tar.gz . - - name: Download Dependencies - run: make -C depends download - - name: Create Dependencies Tarball - run: tar -czf depends.tar.gz depends - - name: Prepare Files for Artifact - run: | - mv depends.tar.gz prcycoin.tar.gz $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - path: ${{ env.ARTIFACT_DIR }} - build-linux: - name: Build for Linux - needs: create-source-distribution - runs-on: ubuntu-18.04 - env: - ARTIFACT_DIR: prcycoin-linux - TEST_LOG_ARTIFACT_DIR: test-logs - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - # May need qt to configure qt and include prcycoin-qt.1 in distribution - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y libssl1.0-dev libevent-dev libboost-all-dev - sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode-dev - sudo add-apt-repository ppa:pivx/pivx - sudo apt-get update - sudo apt-get install -y libdb4.8-dev libdb4.8++-dev - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - strip $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-linux - path: ${{ env.ARTIFACT_DIR }} - build-x86_64-linux: - name: Build for x86 Linux 64bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-x86_64-linux - TEST_LOG_ARTIFACT_DIR: test-logs - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y python3-zmq - - name: Build Dependencies - run: make -C depends -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - CONFIG_SITE=$(realpath depends/x86_64-pc-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - strip $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-x86_64-linux - path: ${{ env.ARTIFACT_DIR }} - build-win64: - name: Build for Win64 - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-win64 - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y g++-mingw-w64-x86-64 gcc-mingw-w64-x86-64 nsis - - name: Switch MinGW GCC and G++ to POSIX Threading - run: | - sudo update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix - sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix - - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=x86_64-w64-mingw32 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - CONFIG_SITE=$(realpath depends/x86_64-w64-mingw32/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default - make -j$(nproc) - make deploy -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - strip $SOURCE_ARTIFACT/src/{prcycoin-cli.exe,prcycoin-tx.exe,prcycoind.exe,qt/prcycoin-qt.exe} - mv $SOURCE_ARTIFACT/{prcycoin-*.exe,src/prcycoin-cli.exe,src/prcycoin-tx.exe,src/prcycoind.exe,src/qt/prcycoin-qt.exe} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-win64 - path: ${{ env.ARTIFACT_DIR }} - build-osx64: - name: Build for MacOSX - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-macosx - SDK_URL: https://bitcoincore.org/depends-sources/sdks - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - export XCODE_VERSION=12.1 - export XCODE_BUILD_ID=12A7403 - echo "VERSION=${VERSION}" >> $GITHUB_ENV - echo "XCODE_VERSION=${XCODE_VERSION}" >> $GITHUB_ENV - echo "XCODE_BUILD_ID=${XCODE_BUILD_ID}" >> $GITHUB_ENV - export OSX_SDK_BASENAME=Xcode-$XCODE_VERSION-$XCODE_BUILD_ID-extracted-SDK-with-libcxx-headers.tar.gz - export OSX_SDK_PATH=depends/sdk-sources/$OSX_SDK_BASENAME - echo "OSX_SDK_BASENAME=${OSX_SDK_BASENAME}" >> $GITHUB_ENV - echo "OSX_SDK_PATH=${OSX_SDK_PATH}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y python3-setuptools libcap-dev libtinfo5 - - name: Get macOS SDK - run: | - mkdir -p depends/sdk-sources depends/SDKs - if [ -n "${{ env.XCODE_VERSION }}" ] && [ ! -f "${{ env.OSX_SDK_PATH }}" ]; then - curl --location --fail "${{ env.SDK_URL }}/${{ env.OSX_SDK_BASENAME }}" -o "${{ env.OSX_SDK_PATH }}" - fi - if [ -n "${{ env.XCODE_VERSION }}" ] && [ -f "${{ env.OSX_SDK_PATH }}" ]; then - tar -C "depends/SDKs" -xf "${{ env.OSX_SDK_PATH }}" - fi - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build Dependencies - run: make -C depends HOST=x86_64-apple-darwin18 -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - CONFIG_SITE=$(realpath depends/x86_64-apple-darwin18/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default - make -j$(nproc) - make deploy -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - mv $SOURCE_ARTIFACT/{*.dmg,src/prcycoin-cli,src/prcycoin-tx,src/prcycoind,src/qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-macosx - path: ${{ env.ARTIFACT_DIR }} - build-aarch64-linux: - name: Build for ARM Linux 64bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-aarch64-linux - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y python3-zmq g++-aarch64-linux-gnu - - name: Build Dependencies - run: make -C depends HOST=aarch64-linux-gnu -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - CONFIG_SITE=$(realpath depends/aarch64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-aarch64-linux - path: ${{ env.ARTIFACT_DIR }} - build-arm-linux-gnueabihf: - name: Build for ARM Linux 32bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-arm32 - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y g++-arm-linux-gnueabihf - - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=arm-linux-gnueabihf - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - CONFIG_SITE=$(realpath depends/arm-linux-gnueabihf/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-arm32 - path: ${{ env.ARTIFACT_DIR }} - build-riscv64-linux-gnu: - name: Build for RISC-V 64-bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-riscv64 - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y g++-riscv64-linux-gnu binutils-riscv64-linux-gnu - - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu NO_QT=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - CONFIG_SITE=$(realpath depends/riscv64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-riscv64 - path: ${{ env.ARTIFACT_DIR }} diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 6bcf8e62d8..4a54bb067c 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -3,14 +3,15 @@ # Copyright (c) 2020 The PRivaCY Coin Developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -name: Github Actions CI for PRCY +name: Github Actions CI for PRCY (Ubuntu 20) on: [push, pull_request] env: SOURCE_ARTIFACT: source jobs: create-source-distribution: name: Create Source Distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 + if: "!contains(github.event.head_commit.message, '[debug]')" env: ARTIFACT_DIR: source steps: @@ -50,63 +51,10 @@ jobs: with: name: ${{ env.SOURCE_ARTIFACT }} path: ${{ env.ARTIFACT_DIR }} - build-linux: - name: Build for Linux - needs: create-source-distribution - runs-on: ubuntu-18.04 - env: - ARTIFACT_DIR: prcycoin-linux - TEST_LOG_ARTIFACT_DIR: test-logs - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - # May need qt to configure qt and include prcycoin-qt.1 in distribution - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y libssl1.0-dev libevent-dev libboost-all-dev - sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode-dev - sudo add-apt-repository ppa:pivx/pivx - sudo apt-get update - sudo apt-get install -y libdb4.8-dev libdb4.8++-dev - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - strip $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-linux - path: ${{ env.ARTIFACT_DIR }} build-x86_64-linux: name: Build for x86 Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-x86_64-linux TEST_LOG_ARTIFACT_DIR: test-logs @@ -138,7 +86,7 @@ jobs: - name: Build Dependencies run: make -C depends -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY + - name: Build PRCY run: | ./autogen.sh CONFIG_SITE=$(realpath depends/x86_64-pc-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports @@ -158,7 +106,7 @@ jobs: build-win64: name: Build for Win64 needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-win64 steps: @@ -213,7 +161,7 @@ jobs: build-osx64: name: Build for MacOSX needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-macosx SDK_URL: https://bitcoincore.org/depends-sources/sdks @@ -249,7 +197,7 @@ jobs: - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y python3-setuptools libcap-dev + sudo apt-get install -y python3-setuptools libcap-dev libtinfo5 - name: Get macOS SDK run: | mkdir -p depends/sdk-sources depends/SDKs @@ -282,7 +230,7 @@ jobs: build-aarch64-linux: name: Build for ARM Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-aarch64-linux steps: @@ -332,7 +280,7 @@ jobs: build-arm-linux-gnueabihf: name: Build for ARM Linux 32bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-arm32 steps: @@ -382,7 +330,7 @@ jobs: build-riscv64-linux-gnu: name: Build for RISC-V 64-bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-riscv64 steps: @@ -411,7 +359,7 @@ jobs: sudo apt-get update sudo apt-get install -y g++-riscv64-linux-gnu binutils-riscv64-linux-gnu - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu + run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu NO_QT=1 working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | @@ -422,8 +370,8 @@ jobs: - name: Prepare Files for Artifact run: | mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR + chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} + mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} $ARTIFACT_DIR - name: Upload Artifact uses: actions/upload-artifact@v1 with: From 46d8833df792cbd168febb441d4a234fc7ad40f7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 10:12:58 -0400 Subject: [PATCH 198/391] [Actions] Re-enable Qt for riscv64-linux-gnu --- .github/workflows/prcy-build-factory-debug.yml | 6 +++--- .github/workflows/prcy-build-factory.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/prcy-build-factory-debug.yml b/.github/workflows/prcy-build-factory-debug.yml index e3bf9bcbd5..a1d18f75c6 100644 --- a/.github/workflows/prcy-build-factory-debug.yml +++ b/.github/workflows/prcy-build-factory-debug.yml @@ -328,7 +328,7 @@ jobs: sudo apt-get update sudo apt-get install -y g++-riscv64-linux-gnu binutils-riscv64-linux-gnu - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu NO_QT=1 + run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | @@ -339,8 +339,8 @@ jobs: - name: Prepare Files for Artifact run: | mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} $ARTIFACT_DIR + chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} + mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact uses: actions/upload-artifact@v1 with: diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 4a54bb067c..c74a8baa8e 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -359,7 +359,7 @@ jobs: sudo apt-get update sudo apt-get install -y g++-riscv64-linux-gnu binutils-riscv64-linux-gnu - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu NO_QT=1 + run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | @@ -370,8 +370,8 @@ jobs: - name: Prepare Files for Artifact run: | mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} $ARTIFACT_DIR + chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} + mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact uses: actions/upload-artifact@v1 with: From 43b1f73f3f3b058d4705d746c5daa9a3359ed22d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 10:17:56 -0400 Subject: [PATCH 199/391] [Actions] Update Debug build - Use Ubuntu 20 - Add Commit Hash / Version - Updated build configuration --- .../workflows/prcy-build-factory-debug.yml | 93 ++++++++++++------- 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/.github/workflows/prcy-build-factory-debug.yml b/.github/workflows/prcy-build-factory-debug.yml index a1d18f75c6..662448c25e 100644 --- a/.github/workflows/prcy-build-factory-debug.yml +++ b/.github/workflows/prcy-build-factory-debug.yml @@ -3,14 +3,14 @@ # Copyright (c) 2020 The PRivaCY Coin Developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -name: Github Actions CI for PRCY - DEBUG_LOCKORDER +name: Github Actions CI for PRCY (Ubuntu 20 --enable-debug) on: [push, pull_request] env: SOURCE_ARTIFACT: source jobs: create-source-distribution: name: Create Source Distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 if: "contains(github.event.head_commit.message, '[debug]')" env: ARTIFACT_DIR: source @@ -23,22 +23,17 @@ jobs: export TAG=v${VERSION} echo "VERSION=${VERSION}" >> $GITHUB_ENV echo "TAG=${TAG}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Print Variables run: | echo "VERSION=${VERSION}" echo "TAG=${TAG}" printenv - # May need qt to configure qt and include prcycoin-qt.1 in distribution - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y build-essential libtool bsdmainutils autotools-dev autoconf pkg-config automake python3 - sudo apt-get install -y libssl1.0-dev libzmq5 libgmp-dev libevent-dev libboost-all-dev libsodium-dev cargo - sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode-dev - sudo apt-get install -y software-properties-common g++-multilib binutils-gold patch - sudo add-apt-repository ppa:pivx/pivx - sudo apt-get update - sudo apt-get install -y libdb4.8-dev libdb4.8++-dev - name: Create Distribution Tarball run: | mkdir -p $ARTIFACT_DIR @@ -59,7 +54,7 @@ jobs: build-x86_64-linux: name: Build for x86 Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-x86_64-linux-debug TEST_LOG_ARTIFACT_DIR: test-logs @@ -78,6 +73,12 @@ jobs: run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') echo "VERSION=${VERSION}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update @@ -88,7 +89,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - CONFIG_SITE=$(realpath depends/x86_64-pc-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/x86_64-pc-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports --enable-debug make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -105,7 +106,7 @@ jobs: build-win64: name: Build for Win64 needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-win64-debug steps: @@ -123,6 +124,12 @@ jobs: run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') echo "VERSION=${VERSION}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update @@ -137,7 +144,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - CONFIG_SITE=$(realpath depends/x86_64-w64-mingw32/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/x86_64-w64-mingw32/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-reduce-exports --enable-debug make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -154,7 +161,7 @@ jobs: build-osx64: name: Build for MacOSX needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-macosx-debug SDK_URL: https://bitcoincore.org/depends-sources/sdks @@ -172,8 +179,8 @@ jobs: shell: bash run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - export XCODE_VERSION=10.2.1 - export XCODE_BUILD_ID=10E1001 + export XCODE_VERSION=12.1 + export XCODE_BUILD_ID=12A7403 echo "VERSION=${VERSION}" >> $GITHUB_ENV echo "XCODE_VERSION=${XCODE_VERSION}" >> $GITHUB_ENV echo "XCODE_BUILD_ID=${XCODE_BUILD_ID}" >> $GITHUB_ENV @@ -181,10 +188,16 @@ jobs: export OSX_SDK_PATH=depends/sdk-sources/$OSX_SDK_BASENAME echo "OSX_SDK_BASENAME=${OSX_SDK_BASENAME}" >> $GITHUB_ENV echo "OSX_SDK_PATH=${OSX_SDK_PATH}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y python3-setuptools libcap-dev zlib1g-dev cmake libz-dev libbz2-dev libtinfo5 + sudo apt-get install -y python3-setuptools libcap-dev libtinfo5 - name: Get macOS SDK run: | mkdir -p depends/sdk-sources depends/SDKs @@ -201,7 +214,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - CONFIG_SITE=$(realpath depends/x86_64-apple-darwin18/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/x86_64-apple-darwin18/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-reduce-exports --enable-debug make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -217,7 +230,7 @@ jobs: build-aarch64-linux: name: Build for ARM Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-aarch64-linux-debug steps: @@ -235,17 +248,23 @@ jobs: run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') echo "VERSION=${VERSION}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y python3-zmq libcap-dev cmake g++-aarch64-linux-gnu + sudo apt-get install -y python3-zmq g++-aarch64-linux-gnu - name: Build Dependencies run: make -C depends HOST=aarch64-linux-gnu -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - CONFIG_SITE=$(realpath depends/aarch64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/aarch64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports --enable-debug make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -261,7 +280,7 @@ jobs: build-arm-linux-gnueabihf: name: Build for ARM Linux 32bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-arm32-debug steps: @@ -279,17 +298,23 @@ jobs: run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') echo "VERSION=${VERSION}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y g++-arm-linux-gnueabihf libzmq5 libgmp-dev + sudo apt-get install -y g++-arm-linux-gnueabihf - name: Build Dependencies run: make -C depends -j$(nproc) HOST=arm-linux-gnueabihf working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - CONFIG_SITE=$(realpath depends/arm-linux-gnueabihf/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/arm-linux-gnueabihf/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-glibc-back-compat --enable-reduce-exports --enable-upnp-default CXXFLAGS=-Wno-psabi --enable-debug make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -305,7 +330,7 @@ jobs: build-riscv64-linux-gnu: name: Build for RISC-V 64-bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-riscv64-debug steps: @@ -323,6 +348,12 @@ jobs: run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') echo "VERSION=${VERSION}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update @@ -333,7 +364,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - CONFIG_SITE=$(realpath depends/riscv64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/riscv64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-reduce-exports --enable-upnp-default --enable-debug make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -345,4 +376,4 @@ jobs: uses: actions/upload-artifact@v1 with: name: prcycoin-v${{ env.VERSION }}-riscv64-debug - path: ${{ env.ARTIFACT_DIR }} \ No newline at end of file + path: ${{ env.ARTIFACT_DIR }} From 980fedabf4170807e6b99c457547522e023103ac Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 12:59:20 -0400 Subject: [PATCH 200/391] [Build] Fix glibc compat add missing function declaration --- src/compat/glibc_compat.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp index 0d457e93f3..dc95ae3722 100644 --- a/src/compat/glibc_compat.cpp +++ b/src/compat/glibc_compat.cpp @@ -17,6 +17,8 @@ extern "C" void* memcpy(void* a, const void* b, size_t c) return memmove(a, b, c); } +extern "C" void __chk_fail(void) __attribute__((__noreturn__)); + #if defined(__i386__) || defined(__arm__) extern "C" int64_t __udivmoddi4(uint64_t u, uint64_t v, uint64_t* rp); From e95e24afe3ad14232067d31f63f9519a16218744 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 14:45:02 -0400 Subject: [PATCH 201/391] build, refactor: Use conventional version notation for boost package Dot is used as a separator in versions of other depends packages. --- depends/packages/boost.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 372e65db98..f079138a8a 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,7 +1,7 @@ package=boost -$(package)_version=1_71_0 -$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/ -$(package)_file_name=boost_$($(package)_version).tar.bz2 +$(package)_version=1.71.0 +$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$($(package)_version)/source/ +$(package)_file_name=boost_$(subst .,_,$($(package)_version)).tar.bz2 $(package)_sha256_hash=d73a8da01e8bf8c7eda40b4c84915071a8c8a0df4a6734537ddde4a8580524ee $(package)_dependencies=native_b2 $(package)_patches=fix_openbsd_test_lib.patch From 23200ff6f984580cd698a3fc3520d02d9b8a30cc Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 14:45:38 -0400 Subject: [PATCH 202/391] build, refactor: Reuse expat package version in its download path --- depends/packages/expat.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index c2089d1ccb..50791ebc6e 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,6 +1,6 @@ package=expat $(package)_version=2.4.1 -$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_4_1/ +$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_$(subst .,_,$($(package)_version))/ $(package)_file_name=$(package)-$($(package)_version).tar.xz $(package)_sha256_hash=cf032d0dba9b928636548e32b327a2d66b1aab63c4f4a13dd132c2d1d2f2fb6a From 11e81fc09d23ab3b11eb75ee7d9b5153d08ee6be Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 14:55:21 -0400 Subject: [PATCH 203/391] build: pass -fno-lto when building expat Otherwise it's autoconf endianess check will fail to determine what the endianess is.. --- depends/packages/expat.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 50791ebc6e..349319138e 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -9,6 +9,7 @@ define $(package)_set_vars $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts += --without-xmlwf $(package)_config_opts_linux=--with-pic + $(package)_cflags += -fno-lto endef define $(package)_config_cmds From 048fc10f17af57562fdf42d43b30f4f45cec03d8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 15:10:08 -0400 Subject: [PATCH 204/391] build: Use Link Time Optimization for Qt code on Linux See: https://www.qt.io/blog/2019/01/02/qt-applications-lto --- depends/packages/qt.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index f38d24071e..3155347d01 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -116,6 +116,9 @@ $(package)_config_opts_linux += -no-feature-sessionmanager $(package)_config_opts_linux += -fontconfig $(package)_config_opts_linux += -no-opengl $(package)_config_opts_linux += -dbus-runtime +ifneq ($(LTO),) +$(package)_config_opts_linux += -ltcg +endif $(package)_config_opts_arm_linux += -platform linux-g++ -xplatform bitcoin-linux-g++ $(package)_config_opts_i686_linux = -xplatform linux-g++-32 $(package)_config_opts_x86_64_linux = -xplatform linux-g++-64 From 01e23c3281041270e53fc1cbe624c6257e41fbcd Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 15:13:10 -0400 Subject: [PATCH 205/391] depends: expat 2.4.8 --- depends/packages/expat.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 349319138e..6f40f4e497 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,8 +1,8 @@ package=expat -$(package)_version=2.4.1 +$(package)_version=2.4.8 $(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_$(subst .,_,$($(package)_version))/ $(package)_file_name=$(package)-$($(package)_version).tar.xz -$(package)_sha256_hash=cf032d0dba9b928636548e32b327a2d66b1aab63c4f4a13dd132c2d1d2f2fb6a +$(package)_sha256_hash=f79b8f904b749e3e0d20afeadecf8249c55b2e32d4ebb089ae378df479dcaf25 define $(package)_set_vars $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples From 77cf50a12a854f2498d2350b0a35003aa6b313bc Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 15:13:25 -0400 Subject: [PATCH 206/391] depends: re-enable using -flto when building expat --- depends/packages/expat.mk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 6f40f4e497..bb203d06f8 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -4,12 +4,15 @@ $(package)_download_path=https://github.com/libexpat/libexpat/releases/download/ $(package)_file_name=$(package)-$($(package)_version).tar.xz $(package)_sha256_hash=f79b8f904b749e3e0d20afeadecf8249c55b2e32d4ebb089ae378df479dcaf25 +# -D_DEFAULT_SOURCE defines __USE_MISC, which exposes additional +# definitions in endian.h, which are required for a working +# endianess check in configure when building with -flto. define $(package)_set_vars $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts += --without-xmlwf $(package)_config_opts_linux=--with-pic - $(package)_cflags += -fno-lto + $(package)_cppflags += -D_DEFAULT_SOURCE endef define $(package)_config_cmds From c431ecf7a010dca9bf04b326cc8b24a7cb47d8b8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 15:17:15 -0400 Subject: [PATCH 207/391] build: Fix autoconf variable names for tools found by `AC_PATH_TOOL` See the `AC_PATH_TOOL` macro implementation. --- configure.ac | 1 + depends/config.site.in | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 7c1a4577b1..5e45848e85 100644 --- a/configure.ac +++ b/configure.ac @@ -1368,6 +1368,7 @@ echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CPPFLAGS" echo " CXX = $CXX" echo " CXXFLAGS = $LTO_CXXFLAGS $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" echo " LDFLAGS = $LTO_LDFLAGS $PTHREAD_CFLAGS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" +echo " AR = $AR" echo " ARFLAGS = $ARFLAGS" echo " PIC_FLAGS = $PIC_FLAGS" echo " QT_PIE_FLAGS = $QT_PIE_FLAGS" diff --git a/depends/config.site.in b/depends/config.site.in index 50b9a9caae..228628bcbe 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -94,7 +94,7 @@ PYTHONPATH="${depends_prefix}/native/lib/python3/dist-packages${PYTHONPATH:+${PA if test -n "@AR@"; then AR="@AR@" - ac_cv_path_ac_pt_AR="${AR}" + ac_cv_path_AR="${AR}" fi if test -n "@RANLIB@"; then @@ -115,17 +115,17 @@ fi if test "@host_os@" = darwin; then if test -n "@OTOOL@"; then OTOOL="@OTOOL@" - ac_cv_path_ac_pt_OTOOL="${OTOOL}" + ac_cv_path_OTOOL="${OTOOL}" fi if test -n "@INSTALL_NAME_TOOL@"; then INSTALL_NAME_TOOL="@INSTALL_NAME_TOOL@" - ac_cv_path_ac_pt_INSTALL_NAME_TOOL="${INSTALL_NAME_TOOL}" + ac_cv_path_INSTALL_NAME_TOOL="${INSTALL_NAME_TOOL}" fi if test -n "@DSYMUTIL@"; then DSYMUTIL="@DSYMUTIL@" - ac_cv_path_ac_pt_DSYMUTIL="${DSYMUTIL}" + ac_cv_path_DSYMUTIL="${DSYMUTIL}" fi fi From 71cc507a73ac2046ec2164c86c3e72802a693ae7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 15:51:27 -0400 Subject: [PATCH 208/391] depends: default to using GCC tool wrappers (with GCC) This improves support for LTO by using gcc wrappers for ar, nm, ranlib, that correctly setup plugin arguments for LTO. Other HOSTS are using clang. --- depends/hosts/linux.mk | 4 ++++ depends/hosts/mingw32.mk | 4 ++++ depends/hosts/netbsd.mk | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk index 8c719c1954..9786db0038 100644 --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -3,6 +3,10 @@ linux_CFLAGS=-pipe ifneq ($(LTO),) linux_CFLAGS += -flto linux_LDFLAGS += -flto + +linux_AR = $(host_toolchain)gcc-ar +linux_NM = $(host_toolchain)gcc-nm +linux_RANLIB = $(host_toolchain)gcc-ranlib endif linux_CXXFLAGS=$(linux_CFLAGS) diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index 3f631a211a..910cb21e9f 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -7,6 +7,10 @@ mingw32_CFLAGS=-pipe ifneq ($(LTO),) mingw32_CFLAGS += -flto mingw32_LDFLAGS += -flto + +mingw32_AR = $(host_toolchain)gcc-ar +mingw32_NM = $(host_toolchain)gcc-nm +mingw32_RANLIB = $(host_toolchain)gcc-ranlib endif mingw32_CXXFLAGS=$(mingw32_CFLAGS) diff --git a/depends/hosts/netbsd.mk b/depends/hosts/netbsd.mk index 9e48248b7e..9586283cad 100644 --- a/depends/hosts/netbsd.mk +++ b/depends/hosts/netbsd.mk @@ -3,6 +3,10 @@ netbsd_CFLAGS=-pipe ifneq ($(LTO),) netbsd_CFLAGS += -flto netbsd_LDFLAGS += -flto + +netbsd_AR = $(host_toolchain)gcc-ar +netbsd_NM = $(host_toolchain)gcc-nm +netbsd_RANLIB = $(host_toolchain)gcc-ranlib endif netbsd_CXXFLAGS=$(netbsd_CFLAGS) From 485bf9c5d517a4def5f66c435f20ea3758f46d78 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 4 Apr 2023 13:28:08 -0400 Subject: [PATCH 209/391] depends: openssl 1.0.2u also adjust configure options to fix compile --- depends/packages/openssl.mk | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index c909416798..f85dfe2e76 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -1,35 +1,28 @@ package=openssl -$(package)_version=1.0.1k -$(package)_download_path=https://www.openssl.org/source/old +$(package)_version=1.0.2u +$(package)_download_path=https://www.openssl.org/source/old/1.0.2 $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c +$(package)_sha256_hash=ecd0c6ffb493dd06707d38b14bb4d8c2288bb7033735606569d8f90f89669d16 define $(package)_set_vars $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" $(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl -$(package)_config_opts+=no-camellia $(package)_config_opts+=no-capieng -$(package)_config_opts+=no-cast -$(package)_config_opts+=no-comp $(package)_config_opts+=no-dso $(package)_config_opts+=no-dtls1 $(package)_config_opts+=no-ec_nistp_64_gcc_128 $(package)_config_opts+=no-gost $(package)_config_opts+=no-gmp $(package)_config_opts+=no-heartbeats -$(package)_config_opts+=no-idea $(package)_config_opts+=no-jpake $(package)_config_opts+=no-krb5 $(package)_config_opts+=no-libunbound $(package)_config_opts+=no-md2 -$(package)_config_opts+=no-mdc2 -$(package)_config_opts+=no-rc4 $(package)_config_opts+=no-rc5 $(package)_config_opts+=no-rdrand $(package)_config_opts+=no-rfc3779 $(package)_config_opts+=no-rsax $(package)_config_opts+=no-sctp -$(package)_config_opts+=no-seed $(package)_config_opts+=no-sha0 $(package)_config_opts+=no-shared $(package)_config_opts+=no-ssl-trace @@ -39,7 +32,6 @@ $(package)_config_opts+=no-static_engine $(package)_config_opts+=no-store $(package)_config_opts+=no-unit-test $(package)_config_opts+=no-weak-ssl-ciphers -$(package)_config_opts+=no-whirlpool $(package)_config_opts+=no-zlib $(package)_config_opts+=no-zlib-dynamic $(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags) From 15297e534e9d0d0dca4c4170f3f367ad2add1f85 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Apr 2023 17:44:36 -0400 Subject: [PATCH 210/391] depends: Fix file permission for gen_id --- depends/gen_id | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 depends/gen_id diff --git a/depends/gen_id b/depends/gen_id old mode 100644 new mode 100755 From 7e0ef90e36001271d915a7c75716b68fff503e46 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 5 Apr 2023 08:23:26 -0400 Subject: [PATCH 211/391] contrib: Add deterministic Guix builds. --- contrib/guix/README.md | 202 +++++++++++++++++++++++++++++++++ contrib/guix/guix-build.sh | 39 +++++++ contrib/guix/libexec/build.sh | 206 ++++++++++++++++++++++++++++++++++ contrib/guix/manifest.scm | 155 +++++++++++++++++++++++++ depends/packages/qt.mk | 3 +- 5 files changed, 604 insertions(+), 1 deletion(-) create mode 100644 contrib/guix/README.md create mode 100644 contrib/guix/guix-build.sh create mode 100644 contrib/guix/libexec/build.sh create mode 100644 contrib/guix/manifest.scm diff --git a/contrib/guix/README.md b/contrib/guix/README.md new file mode 100644 index 0000000000..dd7fe58428 --- /dev/null +++ b/contrib/guix/README.md @@ -0,0 +1,202 @@ +# Bootstrappable PRCYcoin Builds + +This directory contains the files necessary to perform bootstrappable PRCYcoin +builds. + +[Bootstrappability][b17e] furthers our binary security guarantees by allowing us +to _audit and reproduce_ our toolchain instead of blindly _trusting_ binary +downloads. + +We achieve bootstrappability by using Guix as a functional package manager. + +## Requirements + +Conservatively, a x86_64 machine with: + +- 2 or more logical cores +- 4GB of free disk space on the partition that /gnu/store will reside in +- 24GB of free disk space on the partition that the prcycoin repository resides in + +> Note: these requirements are slightly less onerous than those of Gitian builds + +## Setup + +**If you're just testing this out, you can use the +[Dockerfile][fanquake/guix-docker] for convenience. It automatically speeds up +your builds by [using substitutes](#speeding-up-builds-with-substitute-servers). +Should you choose to use the Dockerfile, you can skip this section.** + +Otherwise, follow the [Guix installation guide][guix/bin-install]. + +> Note: For those who like to keep their filesystems clean, Guix is designed to +> be very standalone and _will not_ conflict with your system's package +> manager/existing setup. It _only_ touches `/var/guix`, `/gnu`, and +> `~/.config/guix`. + +After installation, you may want to consider [adding substitute +servers](#speeding-up-builds-with-substitute-servers) to speed up your build if +that fits your security model. (skippable if you're using the +[Dockerfile][fanquake/guix-docker]) + +Once Guix is installed, deploy our patched version into your current Guix +profile. The changes there are slowly being upstreamed. + +```sh +guix pull --url=https://github.com/dongcarl/guix.git \ + --branch=2019-05-bitcoin-staging \ + --max-jobs=4 # change accordingly +``` + +Make sure that you are using your current profile. (You are prompted to do this +at the end of the `guix pull`) + +```bash +export PATH="${HOME}/.config/guix/current/bin${PATH:+:}$PATH" +``` + +> Note: There is ongoing work to eliminate this `guix pull` step using Guix +> [inferiors][guix/inferiors] and [channels][guix/channels]. + +## Usage + +### As a Development Environment + +For a PRCYcoin depends development environment, simply invoke + +```sh +guix environment --manifest=contrib/guix/manifest.scm +``` + +And you'll land back in your shell with all the build dependencies required for +a `depends` build injected into your environment. + +### As a Tool for Deterministic Builds + +From the top of a clean PRCYcoin repository: + +```sh +./contrib/guix/guix-build.sh +``` + +After the build finishes successfully (check the status code please), compare +hashes: + +```sh +find output/ -type f -print0 | sort -z | xargs -r0 sha256sum +``` + +#### Recognized environment variables + +* _**HOSTS**_ + + Override the space-separated list of platform triples for which to perform a + bootstrappable build. _(defaults to "i686-linux-gnu x86\_64-linux-gnu + arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu")_ + + > Windows and OS X platform triplet support are WIP. + +* _**SOURCES_PATH**_ + + Set the depends tree download cache for sources. This is passed through to the + depends tree. Setting this to the same directory across multiple builds of the + depends tree can eliminate unnecessary redownloading of package sources. + +* _**MAX_JOBS**_ + + Override the maximum number of jobs to run simultaneously, you might want to + do so on a memory-limited machine. This may be passed to `make` as in `make + --jobs="$MAX_JOBS"` or `xargs` as in `xargs -P"$MAX_JOBS"`. _(defaults to the + value of `nproc` outside the container)_ + +* _**SOURCE_DATE_EPOCH**_ + + Override the reference timestamp used for bit-for-bit reproducibility, the + variable name conforms to [standard][r12e/source-date-epoch]. _(defaults to + the output of `$(git log --format=%at -1)`)_ + +* _**V**_ + + If non-empty, will pass `V=1` to all `make` invocations, making `make` output + verbose. + +* _**ADDITIONAL_GUIX_ENVIRONMENT_FLAGS**_ + + Additional flags to be passed to `guix environment`. For a fully-bootstrapped + build, set this to `--bootstrap --no-substitutes`. Note that a + fully-bootstrapped build will take quite a long time on the first run. + +## Tips and Tricks + +### Speeding up builds with substitute servers + +_This whole section is automatically done in the convenience +[Dockerfiles][fanquake/guix-docker]_ + +For those who are used to life in the fast _(and trustful)_ lane, you can use +[substitute servers][guix/substitutes] to enable binary downloads of packages. + +> For those who only want to use substitutes from the official Guix build farm +> and have authorized the build farm's signing key during Guix's installation, +> you don't need to do anything. + +#### Authorize the signing keys + +For the official Guix build farm at https://ci.guix.gnu.org, run as root: + +``` +guix archive --authorize < ~root/.config/guix/current/share/guix/ci.guix.gnu.org.pub +``` + +For dongcarl's substitute server at https://guix.carldong.io, run as root: + +```sh +wget -qO- 'https://guix.carldong.io/signing-key.pub' | guix archive --authorize +``` + +#### Use the substitute servers + +The official Guix build farm at https://ci.guix.gnu.org is automatically used +unless the `--no-substitutes` flag is supplied. + +This can be overridden for all `guix` invocations by passing the +`--substitute-urls` option to your invocation of `guix-daemon`. This can also be +overridden on a call-by-call basis by passing the same `--substitute-urls` +option to client tools such at `guix environment`. + +To use dongcarl's substitute server for PRCYcoin builds after having +[authorized his signing key](#authorize-the-signing-keys): + +``` +export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--substitute-urls="https://guix.carldong.io https://ci.guix.gnu.org"' +``` + +## FAQ + +### How can I trust the binary installation? + +As mentioned at the bottom of [this manual page][guix/bin-install]: + +> The binary installation tarballs can be (re)produced and verified simply by +> running the following command in the Guix source tree: +> +> make guix-binary.x86_64-linux.tar.xz + +### When will Guix be packaged in debian? + +Vagrant Cascadian has been making good progress on this +[here][debian/guix-package]. We have all the pieces needed to put up an APT +repository and will likely put one up soon. + +[b17e]: http://bootstrappable.org/ +[r12e/source-date-epoch]: https://reproducible-builds.org/docs/source-date-epoch/ + +[guix/install.sh]: https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh +[guix/bin-install]: https://www.gnu.org/software/guix/manual/en/html_node/Binary-Installation.html +[guix/env-setup]: https://www.gnu.org/software/guix/manual/en/html_node/Build-Environment-Setup.html +[guix/substitutes]: https://www.gnu.org/software/guix/manual/en/html_node/Substitutes.html +[guix/substitute-server-auth]: https://www.gnu.org/software/guix/manual/en/html_node/Substitute-Server-Authorization.html +[guix/inferiors]: https://www.gnu.org/software/guix/manual/en/html_node/Inferiors.html +[guix/channels]: https://www.gnu.org/software/guix/manual/en/html_node/Channels.html + +[debian/guix-package]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=850644 +[fanquake/guix-docker]: https://github.com/fanquake/core-review/tree/master/guix diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh new file mode 100644 index 0000000000..61b9ab1f1b --- /dev/null +++ b/contrib/guix/guix-build.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +export LC_ALL=C +set -e -o pipefail + +# Determine the maximum number of jobs to run simultaneously (overridable by +# environment) +MAX_JOBS="${MAX_JOBS:-$(nproc)}" + +# Download the depends sources now as we won't have internet access in the build +# container +make -C "${PWD}/depends" -j"$MAX_JOBS" download ${V:+V=1} ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} + +# Determine the reference time used for determinism (overridable by environment) +SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log --format=%at -1)}" + +# Deterministically build PRCYcoin for HOSTs (overriable by environment) +for host in ${HOSTS=i686-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu}; do + + # Display proper warning when the user interrupts the build + trap 'echo "** INT received while building ${host}, you may want to clean up the relevant output and distsrc-* directories before rebuilding"' INT + + # Run the build script 'contrib/guix/build.sh' in the build container + # specified by 'contrib/guix/manifest.scm' + # shellcheck disable=SC2086 + guix environment --manifest="${PWD}/contrib/guix/manifest.scm" \ + --container \ + --pure \ + --no-cwd \ + --share="$PWD"=/prcycoin \ + ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ + ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ + -- env HOST="$host" \ + MAX_JOBS="$MAX_JOBS" \ + SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ + ${V:+V=1} \ + ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ + bash -c "cd /prcycoin && bash contrib/guix/libexec/build.sh" + +done diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh new file mode 100644 index 0000000000..ef9ee9201a --- /dev/null +++ b/contrib/guix/libexec/build.sh @@ -0,0 +1,206 @@ +#!/usr/bin/env bash +export LC_ALL=C +set -e -o pipefail + +# Check that environment variables assumed to be set by the environment are set +echo "Building for platform triple ${HOST:?not set} with reference timestamp ${SOURCE_DATE_EPOCH:?not set}..." +echo "At most ${MAX_JOBS:?not set} jobs will run at once..." + +##################### +# Environment Setup # +##################### + +# The depends folder also serves as a base-prefix for depends packages for +# $HOSTs after successfully building. +BASEPREFIX="${PWD}/depends" + +# Setup an output directory for our build +OUTDIR="${OUTDIR:-${PWD}/output}" +[ -e "$OUTDIR" ] || mkdir -p "$OUTDIR" + +# Setup the directory where our PRCYcoin build for HOST will occur +DISTSRC="${DISTSRC:-${PWD}/distsrc-${HOST}}" +if [ -e "$DISTSRC" ]; then + echo "DISTSRC directory '${DISTSRC}' exists, probably because of previous builds... Aborting..." + exit 1 +else + mkdir -p "$DISTSRC" +fi + +# Given a package name and an output name, return the path of that output in our +# current guix environment +store_path() { + grep --extended-regexp "/[^-]{32}-${1}-cross-${HOST}-[^-]+${2:+-${2}}" "${GUIX_ENVIRONMENT}/manifest" \ + | head --lines=1 \ + | sed --expression='s|^[[:space:]]*"||' \ + --expression='s|"[[:space:]]*$||' +} + +# Determine output paths to use in CROSS_* environment variables +CROSS_GLIBC="$(store_path glibc)" +CROSS_GLIBC_STATIC="$(store_path glibc static)" +CROSS_KERNEL="$(store_path linux-libre-headers)" +CROSS_GCC="$(store_path gcc)" + +# Set environment variables to point Guix's cross-toolchain to the right +# includes/libs for $HOST +export CROSS_C_INCLUDE_PATH="${CROSS_GCC}/include:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" +export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" +export CROSS_LIBRARY_PATH="${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib:${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_KERNEL}/lib" + +# Disable Guix ld auto-rpath behavior +export GUIX_LD_WRAPPER_DISABLE_RPATH=yes + +# Make /usr/bin if it doesn't exist +[ -e /usr/bin ] || mkdir -p /usr/bin + +# Symlink file and env to a conventional path +[ -e /usr/bin/file ] || ln -s --no-dereference "$(command -v file)" /usr/bin/file +[ -e /usr/bin/env ] || ln -s --no-dereference "$(command -v env)" /usr/bin/env + +# Determine the correct value for -Wl,--dynamic-linker for the current $HOST +glibc_dynamic_linker=$( + case "$HOST" in + i686-linux-gnu) echo /lib/ld-linux.so.2 ;; + x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; + arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; + aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; + riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; + *) exit 1 ;; + esac +) + +# Environment variables for determinism +export QT_RCC_TEST=1 +export QT_RCC_SOURCE_DATE_OVERRIDE=1 +export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" +export TZ="UTC" + +#################### +# Depends Building # +#################### + +# Build the depends tree, overriding variables that assume multilib gcc +make -C depends --jobs="$MAX_JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + i686_linux_CC=i686-linux-gnu-gcc \ + i686_linux_CXX=i686-linux-gnu-g++ \ + i686_linux_AR=i686-linux-gnu-ar \ + i686_linux_RANLIB=i686-linux-gnu-ranlib \ + i686_linux_NM=i686-linux-gnu-nm \ + i686_linux_STRIP=i686-linux-gnu-strip \ + x86_64_linux_CC=x86_64-linux-gnu-gcc \ + x86_64_linux_CXX=x86_64-linux-gnu-g++ \ + x86_64_linux_AR=x86_64-linux-gnu-ar \ + x86_64_linux_RANLIB=x86_64-linux-gnu-ranlib \ + x86_64_linux_NM=x86_64-linux-gnu-nm \ + x86_64_linux_STRIP=x86_64-linux-gnu-strip \ + qt_config_opts_i686_linux='-platform linux-g++ -xplatform bitcoin-linux-g++' + + +########################### +# Source Tarball Building # +########################### + +# Create the source tarball and move it to "${OUTDIR}/src" if not already there +if [ -z "$(find "${OUTDIR}/src" -name 'prcycoin-*.tar.gz')" ]; then + ./autogen.sh + env CONFIG_SITE="${BASEPREFIX}/${HOST}/share/config.site" ./configure --prefix=/ + make dist GZIP_ENV='-9n' ${V:+V=1} + mkdir -p "${OUTDIR}/src" + mv "$(find "${PWD}" -name 'prcycoin-*.tar.gz')" "${OUTDIR}/src/" +fi + +# Determine the full path to our source tarball +SOURCEDIST="$(find "${OUTDIR}/src" -name 'prcycoin-*.tar.gz')" +# Determine our distribution name (e.g. prcycoin-0.18.0) +DISTNAME="$(basename "$SOURCEDIST" '.tar.gz')" + +########################### +# Binary Tarball Building # +########################### + +# Create a spec file to normalize ssp linking behaviour +spec_file="$(mktemp)" +cat << EOF > "$spec_file" +*link_ssp: +%{fstack-protector|fstack-protector-all|fstack-protector-strong|fstack-protector-explicit:} +EOF + +# Similar flags to Gitian +CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" +HOST_CFLAGS="-O2 -g -specs=${spec_file} -ffile-prefix-map=${PWD}=." +HOST_CXXFLAGS="-O2 -g -specs=${spec_file} -ffile-prefix-map=${PWD}=." +HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -static-libstdc++" + +# Make $HOST-specific native binaries from depends available in $PATH +export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${SOURCEDIST}" + + # Configure this DISTSRC for $HOST + # shellcheck disable=SC2086 + env CONFIG_SITE="${BASEPREFIX}/${HOST}/share/config.site" \ + ./configure --prefix=/ \ + --disable-ccache \ + --disable-maintainer-mode \ + --disable-dependency-tracking \ + ${CONFIGFLAGS} \ + CFLAGS="${HOST_CFLAGS}" \ + CXXFLAGS="${HOST_CXXFLAGS}" \ + LDFLAGS="${HOST_LDFLAGS}" + + sed -i.old 's/-lstdc++ //g' config.status libtool src/univalue/config.status src/univalue/libtool + + # Build PRCYcoin + make --jobs="$MAX_JOBS" ${V:+V=1} + + # Perform basic ELF security checks on a series of executables. + make -C src --jobs=1 check-security ${V:+V=1} + # Check that executables only contain allowed gcc, glibc and libstdc++ + # version symbols for Linux distro back-compatibility. + make -C src --jobs=1 check-symbols ${V:+V=1} + + # Setup the directory where our PRCYcoin build for HOST will be + # installed. This directory will also later serve as the input for our + # binary tarballs. + INSTALLPATH="${PWD}/installed/${DISTNAME}" + mkdir -p "${INSTALLPATH}" + # Install built PRCYcoin to $INSTALLPATH + make install DESTDIR="${INSTALLPATH}" ${V:+V=1} + ( + cd installed + + # Prune libtool and object archives + find . -name "lib*.la" -delete + find . -name "lib*.a" -delete + + # Prune pkg-config files + rm -r "${DISTNAME}/lib/pkgconfig" + + # Split binaries and libraries from their debug symbols + { + find "${DISTNAME}/bin" -type f -executable -print0 + find "${DISTNAME}/lib" -type f -print0 + } | xargs -0 -n1 -P"$MAX_JOBS" -I{} "${DISTSRC}/contrib/devtools/split-debug.sh" {} {} {}.dbg + + cp "${DISTSRC}/doc/README.md" "${DISTNAME}/" + + # Finally, deterministically produce {non-,}debug binary tarballs ready + # for release + find "${DISTNAME}" -not -name "*.dbg" -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" && exit 1 ) + find "${DISTNAME}" -name "*.dbg" -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz" && exit 1 ) + ) +) diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm new file mode 100644 index 0000000000..467e7c983f --- /dev/null +++ b/contrib/guix/manifest.scm @@ -0,0 +1,155 @@ +(define-module (prcycoin) + #:use-module (gnu) + #:use-module (gnu packages) + #:use-module (gnu packages autotools) + #:use-module (gnu packages base) + #:use-module (gnu packages bash) + #:use-module (gnu packages check) + #:use-module (gnu packages commencement) + #:use-module (gnu packages compression) + #:use-module (gnu packages cross-base) + #:use-module (gnu packages file) + #:use-module (gnu packages gawk) + #:use-module (gnu packages gcc) + #:use-module (gnu packages linux) + #:use-module (gnu packages perl) + #:use-module (gnu packages pkg-config) + #:use-module (gnu packages python) + #:use-module (gnu packages shells) + #:use-module (guix build-system trivial) + #:use-module (guix gexp) + #:use-module (guix packages) + #:use-module (guix profiles) + #:use-module (guix utils)) + +(define (make-ssp-fixed-gcc xgcc) + "Given a XGCC package, return a modified package that uses the SSP function +from glibc instead of from libssp.so. Taken from: +http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html" + (package + (inherit xgcc) + (arguments + (substitute-keyword-arguments (package-arguments xgcc) + ((#:make-flags flags) + `(cons "gcc_cv_libc_provides_ssp=yes" ,flags)))))) + +(define (make-gcc-rpath-link xgcc) + "Given a XGCC package, return a modified package that replace each instance of +-rpath in the default system spec that's inserted by Guix with -rpath-link" + (package + (inherit xgcc) + (arguments + (substitute-keyword-arguments (package-arguments xgcc) + ((#:phases phases) + `(modify-phases ,phases + (add-after 'pre-configure 'replace-rpath-with-rpath-link + (lambda _ + (substitute* (cons "gcc/config/rs6000/sysv4.h" + (find-files "gcc/config" + "^gnu-user.*\\.h$")) + (("-rpath=") "-rpath-link=")) + #t)))))))) + +(define (make-cross-toolchain target + base-gcc-for-libc + base-kernel-headers + base-libc + base-gcc) + "Create a cross-compilation toolchain package for TARGET" + (let* ((xbinutils (cross-binutils target)) + ;; 1. Build a cross-compiling gcc without targeting any libc, derived + ;; from BASE-GCC-FOR-LIBC + (xgcc-sans-libc (cross-gcc target + #:xgcc base-gcc-for-libc + #:xbinutils xbinutils)) + ;; 2. Build cross-compiled kernel headers with XGCC-SANS-LIBC, derived + ;; from BASE-KERNEL-HEADERS + (xkernel (cross-kernel-headers target + base-kernel-headers + xgcc-sans-libc + xbinutils)) + ;; 3. Build a cross-compiled libc with XGCC-SANS-LIBC and XKERNEL, + ;; derived from BASE-LIBC + (xlibc (cross-libc target + base-libc + xgcc-sans-libc + xbinutils + xkernel)) + ;; 4. Build a cross-compiling gcc targeting XLIBC, derived from + ;; BASE-GCC + (xgcc (cross-gcc target + #:xgcc base-gcc + #:xbinutils xbinutils + #:libc xlibc))) + ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and + ;; XGCC + (package + (name (string-append target "-toolchain")) + (version (package-version xgcc)) + (source #f) + (build-system trivial-build-system) + (arguments '(#:builder (begin (mkdir %output) #t))) + (propagated-inputs + `(("binutils" ,xbinutils) + ("libc" ,xlibc) + ("libc:static" ,xlibc "static") + ("gcc" ,xgcc))) + (synopsis (string-append "Complete GCC tool chain for " target)) + (description (string-append "This package provides a complete GCC tool +chain for " target " development.")) + (home-page (package-home-page xgcc)) + (license (package-license xgcc))))) + +(define* (make-prcycoin-cross-toolchain target + #:optional + (base-gcc-for-libc gcc-5) + (base-kernel-headers linux-libre-headers-4.19) + (base-libc glibc-2.27) + (base-gcc (make-gcc-rpath-link + (make-ssp-fixed-gcc gcc-9)))) + "Convienience wrapper around MAKE-CROSS-TOOLCHAIN with default values +desirable for building PRCYcoin release binaries." + (make-cross-toolchain target + base-gcc-for-libc + base-kernel-headers + base-libc + base-gcc)) + +(packages->manifest + (list ;; The Basics + bash + tcsh + which + coreutils + util-linux + ;; File(system) inspection + file + grep + diffutils + findutils + ;; File transformation + patch + gawk + sed + ;; Compression and archiving + tar + bzip2 + gzip + xz + zlib + ;; Build tools + gnu-make + libtool + autoconf + automake + pkg-config + ;; Scripting + perl + python + ;; Toolchains + (make-gcc-toolchain gcc-9 glibc-2.27) + (make-prcycoin-cross-toolchain "riscv64-linux-gnu" gcc-8) + (make-prcycoin-cross-toolchain "x86_64-linux-gnu") + (make-prcycoin-cross-toolchain "i686-linux-gnu") + (make-prcycoin-cross-toolchain "aarch64-linux-gnu") + (make-prcycoin-cross-toolchain "arm-linux-gnueabihf" gcc-6))) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 3155347d01..2665712e92 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -236,7 +236,8 @@ define $(package)_preprocess_cmds sed -i.old "s|QMAKE_CXXFLAGS += |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ sed -i.old "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \ sed -i.old "s|QMAKE_CC = clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \ - sed -i.old "s|QMAKE_CXX = clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf + sed -i.old "s|QMAKE_CXX = clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \ + sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf endef define $(package)_config_cmds From 14acd311eef95c8561478d2dada3402bdaaf7277 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 5 Apr 2023 08:31:14 -0400 Subject: [PATCH 212/391] contrib: guix: Clarify SOURCE_DATE_EPOCH. --- contrib/guix/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/guix/README.md b/contrib/guix/README.md index dd7fe58428..bf43738f16 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -110,9 +110,9 @@ find output/ -type f -print0 | sort -z | xargs -r0 sha256sum * _**SOURCE_DATE_EPOCH**_ - Override the reference timestamp used for bit-for-bit reproducibility, the - variable name conforms to [standard][r12e/source-date-epoch]. _(defaults to - the output of `$(git log --format=%at -1)`)_ + Override the reference UNIX timestamp used for bit-for-bit reproducibility, + the variable name conforms to [standard][r12e/source-date-epoch]. _(defaults + to the output of `$(git log --format=%at -1)`)_ * _**V**_ From 6b6daa1b652119cfd76f91c6980ff1c08e9f510d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 5 Apr 2023 08:34:20 -0400 Subject: [PATCH 213/391] contrib: guix: Various improvements. - Clearer and more accurate prose - Pin `guix pull' to commit rather than branch - Just use `use-module' instead of `define-module' - Use `bash-minimal' instead of `bash' - Remove unneeded `tcsh' from manifest - Explicitly use `python-3.7' - Add comments about how {native,cross}-toolchains are produced and why --- contrib/guix/README.md | 5 +-- contrib/guix/guix-build.sh | 4 +-- contrib/guix/manifest.scm | 65 ++++++++++++++++++++------------------ 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/contrib/guix/README.md b/contrib/guix/README.md index bf43738f16..156c77fed8 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -15,7 +15,8 @@ Conservatively, a x86_64 machine with: - 2 or more logical cores - 4GB of free disk space on the partition that /gnu/store will reside in -- 24GB of free disk space on the partition that the prcycoin repository resides in +- 24GB of free disk space on the partition that the PRCYcoin git repository + resides in > Note: these requirements are slightly less onerous than those of Gitian builds @@ -43,7 +44,7 @@ profile. The changes there are slowly being upstreamed. ```sh guix pull --url=https://github.com/dongcarl/guix.git \ - --branch=2019-05-bitcoin-staging \ + --commit=82c77e52b8b46e0a3aad2cb12307c2e30547deec \ --max-jobs=4 # change accordingly ``` diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index 61b9ab1f1b..c3b0fc5bab 100644 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -19,8 +19,8 @@ for host in ${HOSTS=i686-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64- # Display proper warning when the user interrupts the build trap 'echo "** INT received while building ${host}, you may want to clean up the relevant output and distsrc-* directories before rebuilding"' INT - # Run the build script 'contrib/guix/build.sh' in the build container - # specified by 'contrib/guix/manifest.scm' + # Run the build script 'contrib/guix/libexec/build.sh' in the build + # container specified by 'contrib/guix/manifest.scm' # shellcheck disable=SC2086 guix environment --manifest="${PWD}/contrib/guix/manifest.scm" \ --container \ diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 467e7c983f..f613bfe407 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -1,26 +1,25 @@ -(define-module (prcycoin) - #:use-module (gnu) - #:use-module (gnu packages) - #:use-module (gnu packages autotools) - #:use-module (gnu packages base) - #:use-module (gnu packages bash) - #:use-module (gnu packages check) - #:use-module (gnu packages commencement) - #:use-module (gnu packages compression) - #:use-module (gnu packages cross-base) - #:use-module (gnu packages file) - #:use-module (gnu packages gawk) - #:use-module (gnu packages gcc) - #:use-module (gnu packages linux) - #:use-module (gnu packages perl) - #:use-module (gnu packages pkg-config) - #:use-module (gnu packages python) - #:use-module (gnu packages shells) - #:use-module (guix build-system trivial) - #:use-module (guix gexp) - #:use-module (guix packages) - #:use-module (guix profiles) - #:use-module (guix utils)) +(use-modules (gnu) + (gnu packages) + (gnu packages autotools) + (gnu packages base) + (gnu packages bash) + (gnu packages check) + (gnu packages commencement) + (gnu packages compression) + (gnu packages cross-base) + (gnu packages file) + (gnu packages gawk) + (gnu packages gcc) + (gnu packages linux) + (gnu packages perl) + (gnu packages pkg-config) + (gnu packages python) + (gnu packages shells) + (guix build-system trivial) + (guix gexp) + (guix packages) + (guix profiles) + (guix utils)) (define (make-ssp-fixed-gcc xgcc) "Given a XGCC package, return a modified package that uses the SSP function @@ -101,7 +100,7 @@ chain for " target " development.")) (license (package-license xgcc))))) (define* (make-prcycoin-cross-toolchain target - #:optional + #:key (base-gcc-for-libc gcc-5) (base-kernel-headers linux-libre-headers-4.19) (base-libc glibc-2.27) @@ -117,8 +116,7 @@ desirable for building PRCYcoin release binaries." (packages->manifest (list ;; The Basics - bash - tcsh + bash-minimal which coreutils util-linux @@ -145,11 +143,16 @@ desirable for building PRCYcoin release binaries." pkg-config ;; Scripting perl - python - ;; Toolchains + python-3.7 + ;; Native gcc 9 toolchain targeting glibc 2.27 (make-gcc-toolchain gcc-9 glibc-2.27) - (make-prcycoin-cross-toolchain "riscv64-linux-gnu" gcc-8) - (make-prcycoin-cross-toolchain "x86_64-linux-gnu") + ;; Cross gcc 9 toolchains targeting glibc 2.27 (make-prcycoin-cross-toolchain "i686-linux-gnu") + (make-prcycoin-cross-toolchain "x86_64-linux-gnu") (make-prcycoin-cross-toolchain "aarch64-linux-gnu") - (make-prcycoin-cross-toolchain "arm-linux-gnueabihf" gcc-6))) + (make-prcycoin-cross-toolchain "arm-linux-gnueabihf") + ;; The glibc 2.27 for riscv64 needs gcc 7 to successfully build (see: + ;; https://www.gnu.org/software/gcc/gcc-7/changes.html#riscv). The final + ;; toolchain is still a gcc 9 toolchain targeting glibc 2.27. + (make-prcycoin-cross-toolchain "riscv64-linux-gnu" + #:base-gcc-for-libc gcc-7))) From e3f0179acc379d44df3157ed821a3b9b57629df8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 5 Apr 2023 08:35:21 -0400 Subject: [PATCH 214/391] contrib: guix: Additional clarifications re: substitutes --- contrib/guix/README.md | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/contrib/guix/README.md b/contrib/guix/README.md index 156c77fed8..c4d291b88d 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -22,10 +22,13 @@ Conservatively, a x86_64 machine with: ## Setup -**If you're just testing this out, you can use the +### Installing Guix + +If you're just testing this out, you can use the [Dockerfile][fanquake/guix-docker] for convenience. It automatically speeds up your builds by [using substitutes](#speeding-up-builds-with-substitute-servers). -Should you choose to use the Dockerfile, you can skip this section.** +If you don't want this behaviour, refer to the [next +section](#choosing-your-security-model). Otherwise, follow the [Guix installation guide][guix/bin-install]. @@ -34,10 +37,32 @@ Otherwise, follow the [Guix installation guide][guix/bin-install]. > manager/existing setup. It _only_ touches `/var/guix`, `/gnu`, and > `~/.config/guix`. +### Choosing your security model + +Guix allows us to achieve better binary security by using our CPU time to build +everything from scratch. However, it doesn't sacrifice user choice in pursuit of +this: users can decide whether or not to bootstrap and to use substitutes. + After installation, you may want to consider [adding substitute servers](#speeding-up-builds-with-substitute-servers) to speed up your build if -that fits your security model. (skippable if you're using the -[Dockerfile][fanquake/guix-docker]) +that fits your security model (say, if you're just testing that this works). +This is skippable if you're using the [Dockerfile][fanquake/guix-docker]. + +If you prefer not to use any substitutes, make sure to set +`ADDITIONAL_GUIX_ENVIRONMENT_FLAGS` like the following snippet. The first build +will take a while, but the resulting packages will be cached for future builds. + +```sh +export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--no-substitutes' +``` + +Likewise, to perform a bootstrapped build (takes even longer): + +```sh +export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--bootstrap --no-substitutes' +``` + +### Using the right Guix Once Guix is installed, deploy our patched version into your current Guix profile. The changes there are slowly being upstreamed. @@ -55,7 +80,7 @@ at the end of the `guix pull`) export PATH="${HOME}/.config/guix/current/bin${PATH:+:}$PATH" ``` -> Note: There is ongoing work to eliminate this `guix pull` step using Guix +> Note: There is ongoing work to eliminate this entire section using Guix > [inferiors][guix/inferiors] and [channels][guix/channels]. ## Usage @@ -123,7 +148,8 @@ find output/ -type f -print0 | sort -z | xargs -r0 sha256sum * _**ADDITIONAL_GUIX_ENVIRONMENT_FLAGS**_ Additional flags to be passed to `guix environment`. For a fully-bootstrapped - build, set this to `--bootstrap --no-substitutes`. Note that a + build, set this to `--bootstrap --no-substitutes` (refer to the [security + model section](#choosing-your-security-model) for more details). Note that a fully-bootstrapped build will take quite a long time on the first run. ## Tips and Tricks From e687ce9339be866f061a00cf1eb0cbaf306641b6 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 5 Apr 2023 12:39:32 -0400 Subject: [PATCH 215/391] contrib: guix: More robust search paths, add checks - store_path() previously only worked for cross compilation packages, we remove this assumption here - Add CROSS_GCC_LIB variable which points to where gcc libs/headers are located - Add gcc libs/headers to our CROSS_*_PATH environment variables - Check that all directories in CROSS_*_PATH are sane --- contrib/guix/libexec/build.sh | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index ef9ee9201a..03f8fe8de1 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -30,23 +30,38 @@ fi # Given a package name and an output name, return the path of that output in our # current guix environment store_path() { - grep --extended-regexp "/[^-]{32}-${1}-cross-${HOST}-[^-]+${2:+-${2}}" "${GUIX_ENVIRONMENT}/manifest" \ + grep --extended-regexp "/[^-]{32}-${1}-[^-]+${2:+-${2}}" "${GUIX_ENVIRONMENT}/manifest" \ | head --lines=1 \ | sed --expression='s|^[[:space:]]*"||' \ --expression='s|"[[:space:]]*$||' } # Determine output paths to use in CROSS_* environment variables -CROSS_GLIBC="$(store_path glibc)" -CROSS_GLIBC_STATIC="$(store_path glibc static)" -CROSS_KERNEL="$(store_path linux-libre-headers)" -CROSS_GCC="$(store_path gcc)" +CROSS_GLIBC="$(store_path glibc-cross-${HOST})" +CROSS_GLIBC_STATIC="$(store_path glibc-cross-${HOST} static)" +CROSS_KERNEL="$(store_path linux-libre-headers-cross-${HOST})" +CROSS_GCC="$(store_path gcc-cross-${HOST})" +CROSS_GCC_LIBS=( "${CROSS_GCC}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... +CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) # Set environment variables to point Guix's cross-toolchain to the right # includes/libs for $HOST -export CROSS_C_INCLUDE_PATH="${CROSS_GCC}/include:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" -export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" -export CROSS_LIBRARY_PATH="${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib:${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_KERNEL}/lib" +# +# NOTE: CROSS_C_INCLUDE_PATH is missing ${CROSS_GCC_LIB}/include-fixed, because +# the limits.h in it is missing a '#include_next ' +# +export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" +export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" +export CROSS_LIBRARY_PATH="${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" + +# Sanity check CROSS_*_PATH directories +IFS=':' read -ra PATHS <<< "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" +for p in "${PATHS[@]}"; do + if [ ! -d "$p" ]; then + echo "'$p' doesn't exist or isn't a directory... Aborting..." + exit 1 + fi +done # Disable Guix ld auto-rpath behavior export GUIX_LD_WRAPPER_DISABLE_RPATH=yes From d83b201f8418f6fe00ea64800b535e504ab0577b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 5 Apr 2023 12:41:54 -0400 Subject: [PATCH 216/391] contrib: guix: Remove ssp spec file hack This hack is no longer needed after fixing our cross-compilation search paths. --- contrib/guix/libexec/build.sh | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 03f8fe8de1..d407e7af21 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -136,17 +136,10 @@ DISTNAME="$(basename "$SOURCEDIST" '.tar.gz')" # Binary Tarball Building # ########################### -# Create a spec file to normalize ssp linking behaviour -spec_file="$(mktemp)" -cat << EOF > "$spec_file" -*link_ssp: -%{fstack-protector|fstack-protector-all|fstack-protector-strong|fstack-protector-explicit:} -EOF - # Similar flags to Gitian CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" -HOST_CFLAGS="-O2 -g -specs=${spec_file} -ffile-prefix-map=${PWD}=." -HOST_CXXFLAGS="-O2 -g -specs=${spec_file} -ffile-prefix-map=${PWD}=." +HOST_CFLAGS="-O2 -g -ffile-prefix-map=${PWD}=." +HOST_CXXFLAGS="-O2 -g -ffile-prefix-map=${PWD}=." HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -static-libstdc++" # Make $HOST-specific native binaries from depends available in $PATH From 0756ac5bcff38773631bd032298065a356762a15 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 6 Apr 2023 15:25:23 -0400 Subject: [PATCH 217/391] guix: Pin Guix using `guix time-machine` --- contrib/guix/guix-build.sh | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index c3b0fc5bab..358e91e00c 100644 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -13,6 +13,12 @@ make -C "${PWD}/depends" -j"$MAX_JOBS" download ${V:+V=1} ${SOURCES_PATH:+SOURCE # Determine the reference time used for determinism (overridable by environment) SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log --format=%at -1)}" +time-machine() { + guix time-machine --url=https://github.com/dongcarl/guix.git \ + --commit=b3a7c72c8b2425f8ddb0fc6e3b1caeed40f86dee \ + -- "$@" +} + # Deterministically build PRCYcoin for HOSTs (overriable by environment) for host in ${HOSTS=i686-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu}; do @@ -22,18 +28,18 @@ for host in ${HOSTS=i686-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64- # Run the build script 'contrib/guix/libexec/build.sh' in the build # container specified by 'contrib/guix/manifest.scm' # shellcheck disable=SC2086 - guix environment --manifest="${PWD}/contrib/guix/manifest.scm" \ - --container \ - --pure \ - --no-cwd \ - --share="$PWD"=/prcycoin \ - ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ - ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ - -- env HOST="$host" \ - MAX_JOBS="$MAX_JOBS" \ - SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ - ${V:+V=1} \ - ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ - bash -c "cd /prcycoin && bash contrib/guix/libexec/build.sh" + time-machine environment --manifest="${PWD}/contrib/guix/manifest.scm" \ + --container \ + --pure \ + --no-cwd \ + --share="$PWD"=/prcycoin \ + ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ + ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ + -- env HOST="$host" \ + MAX_JOBS="$MAX_JOBS" \ + SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ + ${V:+V=1} \ + ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ + bash -c "cd /prcycoin && bash contrib/guix/libexec/build.sh" done From be3380d4cf6ab38ca551709d48b74cef797f763a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 11:30:01 -0400 Subject: [PATCH 218/391] guix: Update documentation for time-machine Wait a minute, doc. Are you telling me you built a time machine... Out of a functional package manager? --- contrib/guix/README.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/contrib/guix/README.md b/contrib/guix/README.md index c4d291b88d..b8967e9781 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -62,15 +62,16 @@ Likewise, to perform a bootstrapped build (takes even longer): export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--bootstrap --no-substitutes' ``` -### Using the right Guix +### Using a version of Guix with `guix time-machine` capabilities -Once Guix is installed, deploy our patched version into your current Guix -profile. The changes there are slowly being upstreamed. +> Note: This entire section can be skipped if you are already using a version of +> Guix that has [the `guix time-machine` command][guix/time-machine]. + +Once Guix is installed, if it doesn't have the `guix time-machine` command, pull +the latest `guix`. ```sh -guix pull --url=https://github.com/dongcarl/guix.git \ - --commit=82c77e52b8b46e0a3aad2cb12307c2e30547deec \ - --max-jobs=4 # change accordingly +guix pull --max-jobs=4 # change number of jobs accordingly ``` Make sure that you are using your current profile. (You are prompted to do this @@ -80,9 +81,6 @@ at the end of the `guix pull`) export PATH="${HOME}/.config/guix/current/bin${PATH:+:}$PATH" ``` -> Note: There is ongoing work to eliminate this entire section using Guix -> [inferiors][guix/inferiors] and [channels][guix/channels]. - ## Usage ### As a Development Environment @@ -224,6 +222,7 @@ repository and will likely put one up soon. [guix/substitute-server-auth]: https://www.gnu.org/software/guix/manual/en/html_node/Substitute-Server-Authorization.html [guix/inferiors]: https://www.gnu.org/software/guix/manual/en/html_node/Inferiors.html [guix/channels]: https://www.gnu.org/software/guix/manual/en/html_node/Channels.html +[guix/time-machine]: https://guix.gnu.org/manual/en/html_node/Invoking-guix-time_002dmachine.html [debian/guix-package]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=850644 [fanquake/guix-docker]: https://github.com/fanquake/core-review/tree/master/guix From 5151c9d524512187e079d7ceff3f3b2f1a770cf3 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 11:45:59 -0400 Subject: [PATCH 219/391] build: Skip i686 build by default in guix and gitian --- .travis.yml | 9 --------- contrib/gitian-descriptors/gitian-linux.yml | 2 +- contrib/guix/README.md | 2 +- contrib/guix/guix-build.sh | 2 +- doc/release-process.md | 1 - 5 files changed, 3 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 05686243f8..ef88979392 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,15 +85,6 @@ jobs: PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64" GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" -# 32-bit + dash - - stage: test - env: >- - HOST=i686-pc-linux-gnu - PACKAGES="g++-multilib python3-zmq" - DEP_OPTS="NO_QT=1" - GOAL="install" - BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" - CONFIG_SHELL="/bin/dash" # x86_64 Linux (uses qt5 dev package instead of depends Qt to speed up build and avoid timeout) - stage: test env: >- diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index fcfc58afde..ac3653cd45 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -40,7 +40,7 @@ script: | set -e -o pipefail WRAP_DIR=$HOME/wrapped - HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" + HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" FAKETIME_HOST_PROGS="gcc g++" FAKETIME_PROGS="date ar ranlib nm" diff --git a/contrib/guix/README.md b/contrib/guix/README.md index b8967e9781..fb56961556 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -114,7 +114,7 @@ find output/ -type f -print0 | sort -z | xargs -r0 sha256sum * _**HOSTS**_ Override the space-separated list of platform triples for which to perform a - bootstrappable build. _(defaults to "i686-linux-gnu x86\_64-linux-gnu + bootstrappable build. _(defaults to "x86\_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu")_ > Windows and OS X platform triplet support are WIP. diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index 358e91e00c..e9545a717c 100644 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -20,7 +20,7 @@ time-machine() { } # Deterministically build PRCYcoin for HOSTs (overriable by environment) -for host in ${HOSTS=i686-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu}; do +for host in ${HOSTS=x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu}; do # Display proper warning when the user interrupts the build trap 'echo "** INT received while building ${host}, you may want to clean up the relevant output and distsrc-* directories before rebuilding"' INT diff --git a/doc/release-process.md b/doc/release-process.md index 53cef8bdf5..e155fad166 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -251,7 +251,6 @@ The list of files should be: ``` prcycoin-${VERSION}-aarch64-linux-gnu.tar.gz prcycoin-${VERSION}-arm-linux-gnueabihf.tar.gz -prcycoin-${VERSION}-i686-pc-linux-gnu.tar.gz prcycoin-${VERSION}-riscv64-linux-gnu.tar.gz prcycoin-${VERSION}-x86_64-linux-gnu.tar.gz prcycoin-${VERSION}-osx64.tar.gz From d3eee80098958f6863695a19ffa2ec7d8fb31d05 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 11:47:36 -0400 Subject: [PATCH 220/391] guix: Remove now-unnecessary gcc make flag Previously, Guix would produce a gcc which did not know to use the SSP function from glibc, and required a gcc make flag for it to do so, in my attempt to fix it upstream I realized that this is no longer the case. This can be verified by performing a Guix build and doing readelf -s ... | grep __stack_chk to check that symbols are coming from glibc, and doing readelf -d ... | grep NEEDED | grep ssp to see that libssp.so is not being depended on --- contrib/guix/manifest.scm | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index f613bfe407..09bef94dee 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -21,17 +21,6 @@ (guix profiles) (guix utils)) -(define (make-ssp-fixed-gcc xgcc) - "Given a XGCC package, return a modified package that uses the SSP function -from glibc instead of from libssp.so. Taken from: -http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html" - (package - (inherit xgcc) - (arguments - (substitute-keyword-arguments (package-arguments xgcc) - ((#:make-flags flags) - `(cons "gcc_cv_libc_provides_ssp=yes" ,flags)))))) - (define (make-gcc-rpath-link xgcc) "Given a XGCC package, return a modified package that replace each instance of -rpath in the default system spec that's inserted by Guix with -rpath-link" @@ -104,8 +93,7 @@ chain for " target " development.")) (base-gcc-for-libc gcc-5) (base-kernel-headers linux-libre-headers-4.19) (base-libc glibc-2.27) - (base-gcc (make-gcc-rpath-link - (make-ssp-fixed-gcc gcc-9)))) + (base-gcc (make-gcc-rpath-link gcc-9))) "Convienience wrapper around MAKE-CROSS-TOOLCHAIN with default values desirable for building PRCYcoin release binaries." (make-cross-toolchain target From a85dd5252dba0b84cfb109804d2dcd6d49178e1d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 12:03:01 -0400 Subject: [PATCH 221/391] guix: Build support for Windows --- contrib/guix/guix-build.sh | 40 ++++--- contrib/guix/libexec/build.sh | 191 ++++++++++++++++++++++++++-------- contrib/guix/manifest.scm | 119 +++++++++++++-------- 3 files changed, 245 insertions(+), 105 deletions(-) diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index e9545a717c..2797752ad8 100644 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -20,26 +20,32 @@ time-machine() { } # Deterministically build PRCYcoin for HOSTs (overriable by environment) -for host in ${HOSTS=x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu}; do +for host in ${HOSTS=x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu x86_64-w64-mingw32}; do # Display proper warning when the user interrupts the build trap 'echo "** INT received while building ${host}, you may want to clean up the relevant output and distsrc-* directories before rebuilding"' INT - # Run the build script 'contrib/guix/libexec/build.sh' in the build - # container specified by 'contrib/guix/manifest.scm' - # shellcheck disable=SC2086 - time-machine environment --manifest="${PWD}/contrib/guix/manifest.scm" \ - --container \ - --pure \ - --no-cwd \ - --share="$PWD"=/prcycoin \ - ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ - ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ - -- env HOST="$host" \ - MAX_JOBS="$MAX_JOBS" \ - SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ - ${V:+V=1} \ - ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ - bash -c "cd /prcycoin && bash contrib/guix/libexec/build.sh" + ( + # Required for 'contrib/guix/manifest.scm' to output the right manifest + # for the particular $HOST we're building for + export HOST="$host" + + # Run the build script 'contrib/guix/libexec/build.sh' in the build + # container specified by 'contrib/guix/manifest.scm'. + # shellcheck disable=SC2086 + time-machine environment --manifest="${PWD}/contrib/guix/manifest.scm" \ + --container \ + --pure \ + --no-cwd \ + --share="$PWD"=/prcycoin \ + ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ + ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ + -- env HOST="$host" \ + MAX_JOBS="$MAX_JOBS" \ + SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ + ${V:+V=1} \ + ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ + bash -c "cd /prcycoin && bash contrib/guix/libexec/build.sh" + ) done diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index d407e7af21..b424c7f617 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -36,23 +36,41 @@ store_path() { --expression='s|"[[:space:]]*$||' } -# Determine output paths to use in CROSS_* environment variables -CROSS_GLIBC="$(store_path glibc-cross-${HOST})" -CROSS_GLIBC_STATIC="$(store_path glibc-cross-${HOST} static)" -CROSS_KERNEL="$(store_path linux-libre-headers-cross-${HOST})" -CROSS_GCC="$(store_path gcc-cross-${HOST})" -CROSS_GCC_LIBS=( "${CROSS_GCC}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... -CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) - # Set environment variables to point Guix's cross-toolchain to the right # includes/libs for $HOST -# -# NOTE: CROSS_C_INCLUDE_PATH is missing ${CROSS_GCC_LIB}/include-fixed, because -# the limits.h in it is missing a '#include_next ' -# -export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" -export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" -export CROSS_LIBRARY_PATH="${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" +case "$HOST" in + *mingw*) + # Determine output paths to use in CROSS_* environment variables + CROSS_GLIBC="$(store_path "mingw-w64-x86_64-winpthreads")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIBS=( "${CROSS_GCC}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + NATIVE_GCC="$(store_path gcc-glibc-2.27-toolchain)" + export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC}/lib64" + export CPATH="${NATIVE_GCC}/include" + + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" + ;; + *linux*) + CROSS_GLIBC="$(store_path glibc-cross-${HOST})" + CROSS_GLIBC_STATIC="$(store_path glibc-cross-${HOST} static)" + CROSS_KERNEL="$(store_path linux-libre-headers-cross-${HOST})" + CROSS_GCC="$(store_path gcc-cross-${HOST})" + CROSS_GCC_LIBS=( "${CROSS_GCC}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + # NOTE: CROSS_C_INCLUDE_PATH is missing ${CROSS_GCC_LIB}/include-fixed, because + # the limits.h in it is missing a '#include_next ' + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" + ;; + *) + exit 1 ;; +esac # Sanity check CROSS_*_PATH directories IFS=':' read -ra PATHS <<< "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" @@ -74,16 +92,20 @@ export GUIX_LD_WRAPPER_DISABLE_RPATH=yes [ -e /usr/bin/env ] || ln -s --no-dereference "$(command -v env)" /usr/bin/env # Determine the correct value for -Wl,--dynamic-linker for the current $HOST -glibc_dynamic_linker=$( - case "$HOST" in - i686-linux-gnu) echo /lib/ld-linux.so.2 ;; - x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; - arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; - aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; - riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; - *) exit 1 ;; - esac -) +case "$HOST" in + *linux*) + glibc_dynamic_linker=$( + case "$HOST" in + i686-linux-gnu) echo /lib/ld-linux.so.2 ;; + x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; + arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; + aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; + riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; + *) exit 1 ;; + esac + ) + ;; +esac # Environment variables for determinism export QT_RCC_TEST=1 @@ -111,7 +133,8 @@ make -C depends --jobs="$MAX_JOBS" HOST="$HOST" \ x86_64_linux_RANLIB=x86_64-linux-gnu-ranlib \ x86_64_linux_NM=x86_64-linux-gnu-nm \ x86_64_linux_STRIP=x86_64-linux-gnu-strip \ - qt_config_opts_i686_linux='-platform linux-g++ -xplatform bitcoin-linux-g++' + qt_config_opts_i686_linux='-platform linux-g++ -xplatform bitcoin-linux-g++' \ + mingw32_CFLAGS='-DMINGW_HAS_SECURE_API=1 -pipe' ########################### @@ -136,11 +159,26 @@ DISTNAME="$(basename "$SOURCEDIST" '.tar.gz')" # Binary Tarball Building # ########################### -# Similar flags to Gitian -CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" -HOST_CFLAGS="-O2 -g -ffile-prefix-map=${PWD}=." -HOST_CXXFLAGS="-O2 -g -ffile-prefix-map=${PWD}=." -HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -static-libstdc++" +# CONFIGFLAGS +CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests" +case "$HOST" in + *linux*) CONFIGFLAGS+=" --enable-glibc-back-compat" ;; +esac + +# CFLAGS +HOST_CFLAGS="-O2 -g" +case "$HOST" in + *linux*) HOST_CFLAGS+=" -ffile-prefix-map=${PWD}=." ;; + *mingw*) HOST_CFLAGS+=" -fno-ident" ;; +esac + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +# LDFLAGS +case "$HOST" in + *linux*) HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -static-libstdc++" ;; +esac # Make $HOST-specific native binaries from depends available in $PATH export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" @@ -160,7 +198,7 @@ export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" ${CONFIGFLAGS} \ CFLAGS="${HOST_CFLAGS}" \ CXXFLAGS="${HOST_CXXFLAGS}" \ - LDFLAGS="${HOST_LDFLAGS}" + ${HOST_LDFLAGS:+LDFLAGS="${HOST_LDFLAGS}"} sed -i.old 's/-lstdc++ //g' config.status libtool src/univalue/config.status src/univalue/libtool @@ -169,9 +207,21 @@ export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" # Perform basic ELF security checks on a series of executables. make -C src --jobs=1 check-security ${V:+V=1} - # Check that executables only contain allowed gcc, glibc and libstdc++ - # version symbols for Linux distro back-compatibility. - make -C src --jobs=1 check-symbols ${V:+V=1} + + case "$HOST" in + *linux*) + # Check that executables only contain allowed gcc, glibc and libstdc++ + # version symbols for Linux distro back-compatibility. + make -C src --jobs=1 check-symbols ${V:+V=1} + ;; + esac + + # Make the os-specific installers + case "$HOST" in + *mingw*) + make deploy ${V:+V=1} + ;; + esac # Setup the directory where our PRCYcoin build for HOST will be # installed. This directory will also later serve as the input for our @@ -180,9 +230,21 @@ export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" mkdir -p "${INSTALLPATH}" # Install built PRCYcoin to $INSTALLPATH make install DESTDIR="${INSTALLPATH}" ${V:+V=1} + + case "$HOST" in + *mingw*) + cp -f --target-directory="$OUTDIR" ./*-setup-unsigned.exe + ;; + esac ( cd installed + case "$HOST" in + *mingw*) + mv --target-directory="$DISTNAME"/lib/ "$DISTNAME"/bin/*.dll + ;; + esac + # Prune libtool and object archives find . -name "lib*.la" -delete find . -name "lib*.a" -delete @@ -196,19 +258,56 @@ export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" find "${DISTNAME}/lib" -type f -print0 } | xargs -0 -n1 -P"$MAX_JOBS" -I{} "${DISTSRC}/contrib/devtools/split-debug.sh" {} {} {}.dbg - cp "${DISTSRC}/doc/README.md" "${DISTNAME}/" + case "$HOST" in + *mingw*) + cp "${DISTSRC}/doc/README_windows.txt" "${DISTNAME}/readme.txt" + ;; + *linux*) + cp "${DISTSRC}/doc/README.md" "${DISTNAME}/" + ;; + esac # Finally, deterministically produce {non-,}debug binary tarballs ready # for release - find "${DISTNAME}" -not -name "*.dbg" -print0 \ - | sort --zero-terminated \ - | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ - | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" \ - || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" && exit 1 ) - find "${DISTNAME}" -name "*.dbg" -print0 \ - | sort --zero-terminated \ - | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ - | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz" \ - || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz" && exit 1 ) + case "$HOST" in + *mingw*) + find "${DISTNAME}" -not -name "*.dbg" \ + | sort \ + | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" && exit 1 ) + find "${DISTNAME}" -name "*.dbg" \ + | sort \ + | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}-debug.zip" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}-debug.zip" && exit 1 ) + ;; + *linux*) + find "${DISTNAME}" -not -name "*.dbg" -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" && exit 1 ) + find "${DISTNAME}" -name "*.dbg" -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz" && exit 1 ) + ;; + esac ) ) + +case "$HOST" in + *mingw*) + cp -rf --target-directory=. contrib/windeploy + ( + cd ./windeploy + mkdir unsigned + cp --target-directory=unsigned/ "$OUTDIR"/prcycoin-*-setup-unsigned.exe + find . -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz" && exit 1 ) + ) + ;; +esac diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 09bef94dee..14427c72f2 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -10,11 +10,14 @@ (gnu packages file) (gnu packages gawk) (gnu packages gcc) + (gnu packages installers) (gnu packages linux) + (gnu packages mingw) (gnu packages perl) (gnu packages pkg-config) (gnu packages python) (gnu packages shells) + (guix build-system gnu) (guix build-system trivial) (guix gexp) (guix packages) @@ -94,7 +97,7 @@ chain for " target " development.")) (base-kernel-headers linux-libre-headers-4.19) (base-libc glibc-2.27) (base-gcc (make-gcc-rpath-link gcc-9))) - "Convienience wrapper around MAKE-CROSS-TOOLCHAIN with default values + "Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values desirable for building PRCYcoin release binaries." (make-cross-toolchain target base-gcc-for-libc @@ -102,45 +105,77 @@ desirable for building PRCYcoin release binaries." base-libc base-gcc)) +(define (make-gcc-with-pthreads gcc) + (package-with-extra-configure-variable gcc "--enable-threads" "posix")) + +(define (make-mingw-pthreads-cross-toolchain target) + "Create a cross-compilation toolchain package for TARGET" + (let* ((xbinutils (cross-binutils target)) + (pthreads-xlibc mingw-w64-x86_64-winpthreads) + (pthreads-xgcc (make-gcc-with-pthreads + (cross-gcc target + #:xgcc (make-ssp-fixed-gcc gcc) + #:xbinutils xbinutils + #:libc pthreads-xlibc)))) + ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and + ;; XGCC + (package + (name (string-append target "-posix-toolchain")) + (version (package-version pthreads-xgcc)) + (source #f) + (build-system trivial-build-system) + (arguments '(#:builder (begin (mkdir %output) #t))) + (propagated-inputs + `(("binutils" ,xbinutils) + ("libc" ,pthreads-xlibc) + ("gcc" ,pthreads-xgcc))) + (synopsis (string-append "Complete GCC tool chain for " target)) + (description (string-append "This package provides a complete GCC tool +chain for " target " development.")) + (home-page (package-home-page pthreads-xgcc)) + (license (package-license pthreads-xgcc))))) + + (packages->manifest - (list ;; The Basics - bash-minimal - which - coreutils - util-linux - ;; File(system) inspection - file - grep - diffutils - findutils - ;; File transformation - patch - gawk - sed - ;; Compression and archiving - tar - bzip2 - gzip - xz - zlib - ;; Build tools - gnu-make - libtool - autoconf - automake - pkg-config - ;; Scripting - perl - python-3.7 - ;; Native gcc 9 toolchain targeting glibc 2.27 - (make-gcc-toolchain gcc-9 glibc-2.27) - ;; Cross gcc 9 toolchains targeting glibc 2.27 - (make-prcycoin-cross-toolchain "i686-linux-gnu") - (make-prcycoin-cross-toolchain "x86_64-linux-gnu") - (make-prcycoin-cross-toolchain "aarch64-linux-gnu") - (make-prcycoin-cross-toolchain "arm-linux-gnueabihf") - ;; The glibc 2.27 for riscv64 needs gcc 7 to successfully build (see: - ;; https://www.gnu.org/software/gcc/gcc-7/changes.html#riscv). The final - ;; toolchain is still a gcc 9 toolchain targeting glibc 2.27. - (make-prcycoin-cross-toolchain "riscv64-linux-gnu" - #:base-gcc-for-libc gcc-7))) + (append + (list ;; The Basics + bash-minimal + which + coreutils + util-linux + ;; File(system) inspection + file + grep + diffutils + findutils + ;; File transformation + patch + gawk + sed + ;; Compression and archiving + tar + bzip2 + gzip + xz + zlib + ;; Build tools + gnu-make + libtool + autoconf + automake + pkg-config + ;; Scripting + perl + python-3.7 + ;; Native gcc 9 toolchain targeting glibc 2.27 + (make-gcc-toolchain gcc-9 glibc-2.27)) + (let ((target (getenv "HOST"))) + (cond ((string-suffix? "-mingw32" target) + ;; Windows + (list zip (make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32") nsis-x86_64)) + ((string-contains target "riscv64-linux-") + (list (make-prcycoin-cross-toolchain "riscv64-linux-gnu" + #:base-gcc-for-libc gcc-7))) + ((string-contains target "-linux-") + (list (make-prcycoin-cross-toolchain target))) + (else '()))))) From f2ccaf441cfe5bba7412f2549c9879a6b62745a3 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 12:11:03 -0400 Subject: [PATCH 222/391] guix: Improve guix-build.sh documentation --- contrib/guix/guix-build.sh | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index 2797752ad8..70526d0136 100644 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -13,6 +13,8 @@ make -C "${PWD}/depends" -j"$MAX_JOBS" download ${V:+V=1} ${SOURCES_PATH:+SOURCE # Determine the reference time used for determinism (overridable by environment) SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log --format=%at -1)}" +# Execute "$@" in a pinned, possibly older version of Guix, for reproducibility +# across time. time-machine() { guix time-machine --url=https://github.com/dongcarl/guix.git \ --commit=b3a7c72c8b2425f8ddb0fc6e3b1caeed40f86dee \ @@ -32,6 +34,53 @@ for host in ${HOSTS=x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv # Run the build script 'contrib/guix/libexec/build.sh' in the build # container specified by 'contrib/guix/manifest.scm'. + # + # Explanation of `guix environment` flags: + # + # --container run command within an isolated container + # + # Running in an isolated container minimizes build-time differences + # between machines and improves reproducibility + # + # --pure unset existing environment variables + # + # Same rationale as --container + # + # --no-cwd do not share current working directory with an + # isolated container + # + # When --container is specified, the default behavior is to share + # the current working directory with the isolated container at the + # same exact path (e.g. mapping '/home/satoshi/prcycoin/' to + # '/home/satoshi/prcycoin/'). This means that the $PWD inside the + # container becomes a source of irreproducibility. --no-cwd disables + # this behaviour. + # + # --share=SPEC for containers, share writable host file system + # according to SPEC + # + # --share="$PWD"=/prcycoin + # + # maps our current working directory to /prcycoin + # inside the isolated container, which we later cd + # into. + # + # While we don't want to map our current working directory to the + # same exact path (as this introduces irrepreducibility), we do want + # it to be at a _fixed_ path _somewhere_ inside the isolated + # container so that we have something to build. '/prcycoin' was + # chosen arbitrarily. + # + # ${SOURCES_PATH:+--share="$SOURCES_PATH"} + # + # make the downloaded depends sources path available + # inside the isolated container + # + # The isolated container has no network access as it's in a + # different network namespace from the main machine, so we have to + # make the downloaded depends sources available to it. The sources + # should have been downloaded prior to this invocation. + # # shellcheck disable=SC2086 time-machine environment --manifest="${PWD}/contrib/guix/manifest.scm" \ --container \ From 12659fca7243afe312a6636895c6368e00dd0f68 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 13:19:10 -0400 Subject: [PATCH 223/391] guix: Appease shellcheck. --- contrib/guix/guix-build.sh | 1 + contrib/guix/libexec/build.sh | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index 70526d0136..54c3ba40ec 100644 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -22,6 +22,7 @@ time-machine() { } # Deterministically build PRCYcoin for HOSTs (overriable by environment) +# shellcheck disable=SC2153 for host in ${HOSTS=x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu x86_64-w64-mingw32}; do # Display proper warning when the user interrupts the build diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index b424c7f617..87335a800a 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -55,10 +55,10 @@ case "$HOST" in export CROSS_LIBRARY_PATH="${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" ;; *linux*) - CROSS_GLIBC="$(store_path glibc-cross-${HOST})" - CROSS_GLIBC_STATIC="$(store_path glibc-cross-${HOST} static)" - CROSS_KERNEL="$(store_path linux-libre-headers-cross-${HOST})" - CROSS_GCC="$(store_path gcc-cross-${HOST})" + CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")" + CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)" + CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" CROSS_GCC_LIBS=( "${CROSS_GCC}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) From a800a201c20bde4d170e3af592a7c42a06116189 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 13:20:19 -0400 Subject: [PATCH 224/391] guix: Remove dead links from README. --- contrib/guix/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/contrib/guix/README.md b/contrib/guix/README.md index fb56961556..113bdcbc13 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -220,8 +220,6 @@ repository and will likely put one up soon. [guix/env-setup]: https://www.gnu.org/software/guix/manual/en/html_node/Build-Environment-Setup.html [guix/substitutes]: https://www.gnu.org/software/guix/manual/en/html_node/Substitutes.html [guix/substitute-server-auth]: https://www.gnu.org/software/guix/manual/en/html_node/Substitute-Server-Authorization.html -[guix/inferiors]: https://www.gnu.org/software/guix/manual/en/html_node/Inferiors.html -[guix/channels]: https://www.gnu.org/software/guix/manual/en/html_node/Channels.html [guix/time-machine]: https://guix.gnu.org/manual/en/html_node/Invoking-guix-time_002dmachine.html [debian/guix-package]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=850644 From c8af79e2d3342303480f08a0b668b79d98393ba2 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 13:38:53 -0400 Subject: [PATCH 225/391] guix: Make x86_64-w64-mingw32 builds reproducible - Add "--no-insert-timestamp" LDFLAG for x86_64-w64-mingw32 builds "The option --no-insert-timestamp can be used to insert a zero value for the timestamp, this ensuring that binaries produced from identical sources will compare identically." - ld(1) - Set "SetDateSave off" in NSIS script From https://nsis.sourceforge.io/Docs/Chapter4.html#flags "This command sets the file date/time saving flag which is used by the File command to determine whether or not to save the last write date and time of the file, so that it can be restored on installation. Valid flags are 'on' and 'off'. 'on' is the default." - Add commented out NSIS options for reproducibility debugging in NSIS script - Make ZIPs deterministic by reseting file modification times to SOURCE_DATE_EPOCH using touch(1) (Reference: https://reproducible-builds.org/docs/archives/) --- contrib/guix/libexec/build.sh | 5 +++++ share/setup.nsi.in | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 87335a800a..25ac5cf7ed 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -178,6 +178,7 @@ HOST_CXXFLAGS="$HOST_CFLAGS" # LDFLAGS case "$HOST" in *linux*) HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -static-libstdc++" ;; + *mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;; esac # Make $HOST-specific native binaries from depends available in $PATH @@ -271,10 +272,14 @@ export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" # for release case "$HOST" in *mingw*) + find "${DISTNAME}" -not -name "*.dbg" -print0 \ + | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" find "${DISTNAME}" -not -name "*.dbg" \ | sort \ | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" \ || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" && exit 1 ) + find "${DISTNAME}" -name "*.dbg" -print0 \ + | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" find "${DISTNAME}" -name "*.dbg" \ | sort \ | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}-debug.zip" \ diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 86cafef46f..df42a27200 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -2,6 +2,11 @@ Name "@PACKAGE_NAME@ (64-bit)" RequestExecutionLevel highest SetCompressor /SOLID lzma +SetDateSave off + +# Uncomment these lines when investigating reproducibility errors +#SetCompress off +#SetDatablockOptimize off # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" From 43d3c23eed8341a7221c81faec1760b7bb5e4459 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 13:39:24 -0400 Subject: [PATCH 226/391] guix: Set the well-known timezone env var --- contrib/guix/libexec/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 25ac5cf7ed..d9360d029a 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +export TZ=UTC export LC_ALL=C set -e -o pipefail From 420fbfd5dab33c8360b4fac3d58e4d927824ecca Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 13:39:57 -0400 Subject: [PATCH 227/391] guix: Use gcc-8 for mingw-w64 instead of 7 We're using mingw-w64 6.0.0, which is paired with gcc-8 in most distros. --- contrib/guix/manifest.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 14427c72f2..5b8766e9a6 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -114,7 +114,7 @@ desirable for building PRCYcoin release binaries." (pthreads-xlibc mingw-w64-x86_64-winpthreads) (pthreads-xgcc (make-gcc-with-pthreads (cross-gcc target - #:xgcc (make-ssp-fixed-gcc gcc) + #:xgcc (make-ssp-fixed-gcc gcc-8) #:xbinutils xbinutils #:libc pthreads-xlibc)))) ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and From 39e6cafe1d81c1ae7495a563e431978d0d6350fb Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 13:40:32 -0400 Subject: [PATCH 228/391] guix: Bump time-machine for mingw-w64 patches This bump will includes a couple of commits which improve the reproducibility of the mingw-w64 toolchain. Most of which came from debian. They will be upstreamed as upstream Guix release timeline allows. --- contrib/guix/guix-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index 54c3ba40ec..c6e4aad317 100644 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -17,7 +17,7 @@ SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log --format=%at -1)}" # across time. time-machine() { guix time-machine --url=https://github.com/dongcarl/guix.git \ - --commit=b3a7c72c8b2425f8ddb0fc6e3b1caeed40f86dee \ + --commit=cf347affd642c709f7e423f7111794ffdb09f5a6 \ -- "$@" } From 4cf8ad74f8a5819d4294d7421f28f49d0799fc87 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 13:42:53 -0400 Subject: [PATCH 229/391] guix: Reinstate make-ssp-fixed-gcc Unfortunately, gcc is still not smart enough to detect whether or not mingw-w64 provides ssp, so let's put it back just for mingw-w64. --- contrib/guix/manifest.scm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 5b8766e9a6..cb19b64fd1 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -24,6 +24,17 @@ (guix profiles) (guix utils)) +(define (make-ssp-fixed-gcc xgcc) + "Given a XGCC package, return a modified package that uses the SSP function +from glibc instead of from libssp.so. Taken from: +http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html" + (package + (inherit xgcc) + (arguments + (substitute-keyword-arguments (package-arguments xgcc) + ((#:make-flags flags) + `(cons "gcc_cv_libc_provides_ssp=yes" ,flags)))))) + (define (make-gcc-rpath-link xgcc) "Given a XGCC package, return a modified package that replace each instance of -rpath in the default system spec that's inserted by Guix with -rpath-link" From 21888f052454baf2b62fb2a090f97935383679e6 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 13:57:41 -0400 Subject: [PATCH 230/391] guix: Spelling fixes --- contrib/guix/guix-build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index c6e4aad317..9641ed303b 100644 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -21,7 +21,7 @@ time-machine() { -- "$@" } -# Deterministically build PRCYcoin for HOSTs (overriable by environment) +# Deterministically build PRCYcoin for HOSTs (overridable by environment) # shellcheck disable=SC2153 for host in ${HOSTS=x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu x86_64-w64-mingw32}; do @@ -67,7 +67,7 @@ for host in ${HOSTS=x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv # into. # # While we don't want to map our current working directory to the - # same exact path (as this introduces irrepreducibility), we do want + # same exact path (as this introduces irreproducibility), we do want # it to be at a _fixed_ path _somewhere_ inside the isolated # container so that we have something to build. '/prcycoin' was # chosen arbitrarily. From 585e2ed0cc27934ac990b566fb906763b7e36e5f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 13:58:43 -0400 Subject: [PATCH 231/391] guix: Expand on INT trap message --- contrib/guix/guix-build.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index 9641ed303b..29d5514da0 100644 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -21,12 +21,26 @@ time-machine() { -- "$@" } +# Function to be called when building for host ${1} and the user interrupts the +# build +int_trap() { +cat << EOF +** INT received while building ${1}, you may want to clean up the relevant + output, deploy, and distsrc-* directories before rebuilding +Hint: To blow everything away, you may want to use: + $ git clean -xdff --exclude='/depends/SDKs/*' +Specifically, this will remove all files without an entry in the index, +excluding the SDK directory. Practically speaking, this means that all ignored +and untracked files and directories will be wiped, allowing you to start anew. +EOF +} + # Deterministically build PRCYcoin for HOSTs (overridable by environment) # shellcheck disable=SC2153 for host in ${HOSTS=x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu x86_64-w64-mingw32}; do # Display proper warning when the user interrupts the build - trap 'echo "** INT received while building ${host}, you may want to clean up the relevant output and distsrc-* directories before rebuilding"' INT + trap 'int_trap ${host}' INT ( # Required for 'contrib/guix/manifest.scm' to output the right manifest From 992c80d11d75dc94ecf11edc42167c37a2127130 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Apr 2023 14:00:14 -0400 Subject: [PATCH 232/391] guix: Check mingw symbols, improve SSP fix docs --- contrib/guix/libexec/build.sh | 2 +- contrib/guix/manifest.scm | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index d9360d029a..0aa38d6104 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -211,7 +211,7 @@ export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" make -C src --jobs=1 check-security ${V:+V=1} case "$HOST" in - *linux*) + *linux*|*mingw*) # Check that executables only contain allowed gcc, glibc and libstdc++ # version symbols for Linux distro back-compatibility. make -C src --jobs=1 check-symbols ${V:+V=1} diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index cb19b64fd1..924c2c32e6 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -26,7 +26,10 @@ (define (make-ssp-fixed-gcc xgcc) "Given a XGCC package, return a modified package that uses the SSP function -from glibc instead of from libssp.so. Taken from: +from glibc instead of from libssp.so. Our `symbol-check' script will complain if +we link against libssp.so, and thus will ensure that this works properly. + +Taken from: http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html" (package (inherit xgcc) From d691a80812b43df06959f0fc42987a4f49772a04 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 18 Apr 2023 09:08:28 -0400 Subject: [PATCH 233/391] guix: Bump to upstream commit with mingw-w64 changes Most of the mingw-w64 toolchain changes have now been upstreamed, we can point to a commit that exists upstream. NOTE: I'm not changing the URL yet until we see that Guix upstream will accept all my patches for macOS. ----- The Guix tree that's referred to by this commit contains the following changes relevant to our mingw-w64 build: b066c25026 Adds a PACKAGES-WITH-*PATCHES procedure which we can use in the future to apply patches to packages if those patches are not considered appropriate to upstream Guix 4719b71572 Adds mingw-w64 (the libc itself) reproducibility patches, taken from debian. 79825bee07 + 401d28e433 + c1c50cb5b0 Add mingw-w64 specific binutils patches, taken from debian. Specifically, the "Make DLL import libraries reproducible" patch made libbitcoinconsensus.dll.a build reproducibly. The followup commits were hotfixes for my mistakes. 0f864175dc Bumps mingw-w64 to v7.0.0. This is the first release that enables secure APIs by default (which we need), and gains _FORTIFY_SOURCE support. This will also be what Ubuntu Focal 20.04 LTS releases with. cdf00cf75d Bumps NSIS to v3.05. This is the first release that includes a fix for a reproducibility bug found by some of the electrum developers. See details here: https://sourceforge.net/p/nsis/bugs/1230/ --- contrib/guix/guix-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index 29d5514da0..06edc4efed 100644 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -17,7 +17,7 @@ SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log --format=%at -1)}" # across time. time-machine() { guix time-machine --url=https://github.com/dongcarl/guix.git \ - --commit=cf347affd642c709f7e423f7111794ffdb09f5a6 \ + --commit=b066c25026f21fb57677aa34692a5034338e7ee3 \ -- "$@" } From 9090872af8f868cce83249b8d4b94d673e95c71d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 18 Apr 2023 09:10:01 -0400 Subject: [PATCH 234/391] guix: Don't set MINGW_HAS_SECURE_API CFLAG in depends This is no longer needed after 3bef7c22 in the mingw-w64 git repository, which is first included in mingw-w64 v7.0.0. As of the previous bump to our Guix time machine, we now use mingw-w64 v7.0.0. --- contrib/guix/libexec/build.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 0aa38d6104..f7ee9b4482 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -134,8 +134,7 @@ make -C depends --jobs="$MAX_JOBS" HOST="$HOST" \ x86_64_linux_RANLIB=x86_64-linux-gnu-ranlib \ x86_64_linux_NM=x86_64-linux-gnu-nm \ x86_64_linux_STRIP=x86_64-linux-gnu-strip \ - qt_config_opts_i686_linux='-platform linux-g++ -xplatform bitcoin-linux-g++' \ - mingw32_CFLAGS='-DMINGW_HAS_SECURE_API=1 -pipe' + qt_config_opts_i686_linux='-platform linux-g++ -xplatform bitcoin-linux-g++' ########################### From e137f38a5f8c3e3bb9039b9e2af1a8651e490a5f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 18 Apr 2023 09:11:07 -0400 Subject: [PATCH 235/391] guix: Use gcc-9 for mingw-w64 instead of 8 The libtool unsorted 'find' determinism issue seemed to have been solved in gcc-9's git: d41cd173e23ebea7c758644d6ad6e0fde1c2e3a6 or SVN: r262451 Furthermore, it seems that Ubuntu Focal 20.04 LTS is going to ship with gcc 9 and mingw-w64 7, which will match what we have now. ----- A note on this: Careful observers will see that previously I stated that all released versions of gcc were bootstrapped with a libtool 2.2.7a, meaning that they all had the unsorted 'find' determinism issue first resolved in libtool 2.2.7b. However, I was mistaken, gcc's ltmain.sh CLAIMS it was generated by libtool 2.2.7a, but it was in fact edited manually. It seems that gcc maintains their own versions of ltmain.sh and libtool.m4, and only sometimes backports patches from upstream. Quite confusing. --- contrib/guix/manifest.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 924c2c32e6..7e4a190940 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -128,7 +128,7 @@ desirable for building PRCYcoin release binaries." (pthreads-xlibc mingw-w64-x86_64-winpthreads) (pthreads-xgcc (make-gcc-with-pthreads (cross-gcc target - #:xgcc (make-ssp-fixed-gcc gcc-8) + #:xgcc (make-ssp-fixed-gcc gcc-9) #:xbinutils xbinutils #:libc pthreads-xlibc)))) ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and From dbe0fea37c2df092d19c8695f8277260fd10e83a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 18 Apr 2023 09:18:06 -0400 Subject: [PATCH 236/391] guix: Appease travis. --- contrib/guix/libexec/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index f7ee9b4482..508b83b958 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -export TZ=UTC export LC_ALL=C set -e -o pipefail +export TZ=UTC # Check that environment variables assumed to be set by the environment are set echo "Building for platform triple ${HOST:?not set} with reference timestamp ${SOURCE_DATE_EPOCH:?not set}..." From 774109cd30b7f26f696e43ec7344f77a870eb821 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 20 Apr 2023 22:06:58 -0400 Subject: [PATCH 237/391] depends: boost 1.72 --- depends/packages/boost.mk | 6 +-- .../patches/boost/fix_openbsd_test_lib.patch | 38 ------------------- 2 files changed, 2 insertions(+), 42 deletions(-) delete mode 100644 depends/patches/boost/fix_openbsd_test_lib.patch diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index f079138a8a..497bd2e987 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,10 +1,9 @@ package=boost -$(package)_version=1.71.0 +$(package)_version=1.72.0 $(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$($(package)_version)/source/ $(package)_file_name=boost_$(subst .,_,$($(package)_version)).tar.bz2 -$(package)_sha256_hash=d73a8da01e8bf8c7eda40b4c84915071a8c8a0df4a6734537ddde4a8580524ee +$(package)_sha256_hash=59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722 $(package)_dependencies=native_b2 -$(package)_patches=fix_openbsd_test_lib.patch define $(package)_set_vars $(package)_config_opts_release=variant=release @@ -40,7 +39,6 @@ $(package)_cxxflags_android=-fPIC endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/fix_openbsd_test_lib.patch && \ echo "using $($(package)_toolset_$(host_os)) : : $($(package)_cxx) : \"$($(package)_cflags)\" \"$($(package)_cxxflags)\" \"$($(package)_cppflags)\" \"$($(package)_ldflags)\" \"$($(package)_ar)\" \"$(host_STRIP)\" \"$(host_RANLIB)\" \"$(host_WINDRES)\" : ;" > user-config.jam endef diff --git a/depends/patches/boost/fix_openbsd_test_lib.patch b/depends/patches/boost/fix_openbsd_test_lib.patch deleted file mode 100644 index 84351065a3..0000000000 --- a/depends/patches/boost/fix_openbsd_test_lib.patch +++ /dev/null @@ -1,38 +0,0 @@ -commit 684f067dde3b798877655cdda4eab8d7c26b2510 -Author: George Koehler -Date: Thu Oct 3 20:06:38 2019 -0400 - - OpenBSD is missing SI_ASYNCIO and SI_MESGQ - - Check if SI_ASYNCIO and SI_MESGQ are defined as macros. This allows - to run tests on OpenBSD 6.5, where the macros are missing. - - This is identical to patch-boost_test_impl_execution_monitor_ipp in - OpenBSD Ports, except that I added a comment. - - Can be removed when we use Boost 1.72.x or later. - -diff --git a/boost/test/impl/execution_monitor.ipp b/boost/test/impl/execution_monitor.ipp -index ccc44972..77a01e21 100644 ---- a/boost/test/impl/execution_monitor.ipp -+++ b/boost/test/impl/execution_monitor.ipp -@@ -391,14 +391,19 @@ system_signal_exception::report() const - report_error( execution_exception::system_error, - "signal: the expiration of a timer set by timer_settimer()" ); - break; -+// OpenBSD was missing SI_ASYNCIO and SI_MESGQ -+#ifdef SI_ASYNCIO - case SI_ASYNCIO: - report_error( execution_exception::system_error, - "signal: generated by the completion of an asynchronous I/O request" ); - break; -+#endif -+#ifdef SI_MESGQ - case SI_MESGQ: - report_error( execution_exception::system_error, - "signal: generated by the the arrival of a message on an empty message queue" ); - break; -+#endif - default: - break; - } From 9d64fcf6eb0e88e0f43e13507ea00d86533192cc Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 20 Apr 2023 22:39:44 -0400 Subject: [PATCH 238/391] http: add missing header bootlegged by boost < 1.72 httpserver.cpp:74:10: error: no template named 'deque' in namespace 'std' std::deque> queue; ~~~~~^ --- src/httpserver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 69502ea058..09346b4a29 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include From 21d57244b78917aa1f79e303afc1b879f6b60917 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 21 Apr 2023 12:13:04 -0400 Subject: [PATCH 239/391] build: Remove src/obj directory from repository This directory is automatically created by the build process (in the build target directory, see bitcoin#16588) and doesn't need to be in the repository nor in the tarballs. Move associated ignore directive to top-level `.gitignore` file. --- .gitignore | 1 + src/obj/.gitignore | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 src/obj/.gitignore diff --git a/.gitignore b/.gitignore index 4ee1677587..10b2d8046c 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ libtool src/config/prcycoin-config.h src/config/prcycoin-config.h.in src/config/stamp-h1 +src/obj src/secp256k1-mw/build-aux/compile src/secp256k1-mw/build-aux/config.guess src/secp256k1-mw/build-aux/config.sub diff --git a/src/obj/.gitignore b/src/obj/.gitignore deleted file mode 100644 index d6b7ef32c8..0000000000 --- a/src/obj/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore From 939535a267e6a7688c2c938c45122a5640bc0e60 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 21 Apr 2023 12:26:00 -0400 Subject: [PATCH 240/391] [Qt] Debug window: remove "Build date". The build date does only makes sense for custom/self-compiled versions because we are using static build-dates for our deterministic release builds. Coming from btc@4856f1d6712cdb2eac8712e379fd1e351583d78f --- src/qt/clientmodel.cpp | 5 ----- src/qt/clientmodel.h | 1 - src/qt/forms/rpcconsole.ui | 25 +------------------------ src/qt/rpcconsole.cpp | 1 - 4 files changed, 1 insertion(+), 31 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 0e153196d4..c62ab1c13c 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -215,11 +215,6 @@ QString ClientModel::formatFullVersion() const return QString::fromStdString(FormatFullVersion()); } -QString ClientModel::formatBuildDate() const -{ - return QString::fromStdString(CLIENT_DATE); -} - bool ClientModel::isReleaseVersion() const { return CLIENT_VERSION_IS_RELEASE; diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 3251cc2442..3bd6490de9 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -75,7 +75,6 @@ class ClientModel : public QObject QString getStatusBarWarnings() const; QString formatFullVersion() const; - QString formatBuildDate() const; bool isReleaseVersion() const; QString clientName() const; QString formatClientStartupTime() const; diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui index 62bf34328f..41b24ed9aa 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -17,7 +17,7 @@ - 4 + 0 @@ -145,29 +145,6 @@ - - - - Build date - - - - - - - IBeamCursor - - - N/A - - - Qt::PlainText - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 2d72e0b5b6..9539bb8155 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -487,7 +487,6 @@ void RPCConsole::setClientModel(ClientModel* model) // Provide initial values ui->clientVersion->setText(model->formatFullVersion()); ui->clientName->setText(model->clientName()); - ui->buildDate->setText(model->formatBuildDate()); ui->dataDir->setText(model->dataDir()); ui->startupTime->setText(model->formatClientStartupTime()); ui->networkName->setText(QString::fromStdString(Params().NetworkIDString())); From 9a278dce6f33b4b869211f2de5213945f392b0f7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 21 Apr 2023 12:32:36 -0400 Subject: [PATCH 241/391] build: Get rid of `CLIENT_DATE` Putting the build date in the executable is a practice that has no place in these days, now that deterministic building is increasingly common. Continues https://github.com/bitcoin/bitcoin/pull/7732 which did this for the GUI. --- share/genbuild.sh | 7 ------- src/clientversion.cpp | 9 --------- src/clientversion.h | 1 - src/init.cpp | 2 +- src/wallet/rpcdump.cpp | 2 +- 5 files changed, 2 insertions(+), 19 deletions(-) diff --git a/share/genbuild.sh b/share/genbuild.sh index fb5daeb145..6753934904 100755 --- a/share/genbuild.sh +++ b/share/genbuild.sh @@ -24,7 +24,6 @@ git_check_in_repo() { DESC="" SUFFIX="" -LAST_COMMIT_DATE="" if [ "${BITCOIN_GENBUILD_NO_GIT}" != "1" -a -e "$(which git 2>/dev/null)" -a "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ] && git_check_in_repo share/genbuild.sh; then # clean 'dirty' status of touched files that haven't been modified git diff >/dev/null 2>/dev/null @@ -38,9 +37,6 @@ if [ "${BITCOIN_GENBUILD_NO_GIT}" != "1" -a -e "$(which git 2>/dev/null)" -a "$( # otherwise generate suffix from git, i.e. string like "59887e8-dirty" SUFFIX=$(git rev-parse --short HEAD) git diff-index --quiet HEAD -- || SUFFIX="$SUFFIX" - - # get a string like "2012-04-10 16:27:19 +0200" - LAST_COMMIT_DATE="$(git log -n 1 --format="%ci")" fi if [ -n "$DESC" ]; then @@ -54,7 +50,4 @@ fi # only update build.h if necessary if [ "$INFO" != "$NEWINFO" ]; then echo "$NEWINFO" >"$FILE" - if [ -n "$LAST_COMMIT_DATE" ]; then - echo "#define BUILD_DATE \"$LAST_COMMIT_DATE\"" >> "$FILE" - fi fi \ No newline at end of file diff --git a/src/clientversion.cpp b/src/clientversion.cpp index 14f8fd3505..b62210c39a 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -67,16 +67,7 @@ const std::string CLIENT_NAME("PRCY"); #endif #endif -#ifndef BUILD_DATE -#ifdef GIT_COMMIT_DATE -#define BUILD_DATE GIT_COMMIT_DATE -#else -#define BUILD_DATE __DATE__ ", " __TIME__ -#endif -#endif - const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX); -const std::string CLIENT_DATE(BUILD_DATE); static std::string FormatVersion(int nVersion) { diff --git a/src/clientversion.h b/src/clientversion.h index 1df409cc42..d0a5820254 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -43,7 +43,6 @@ static const int CLIENT_VERSION = extern const std::string CLIENT_NAME; extern const std::string CLIENT_BUILD; -extern const std::string CLIENT_DATE; std::string FormatFullVersion(); diff --git a/src/init.cpp b/src/init.cpp index a1eaa5ed68..b4736fdab3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -900,7 +900,7 @@ void InitLogging() #else version_string += " (release build)"; #endif - LogPrintf("PRCY version %s (%s)\n", version_string, CLIENT_DATE); + LogPrintf("PRCY version %s\n", version_string); } /** Initialize prcy. diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index b35633813a..5668b35af5 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -378,7 +378,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) std::sort(vKeyBirth.begin(), vKeyBirth.end()); // produce output - file << strprintf("# Wallet dump created by PRCY %s (%s)\n", CLIENT_BUILD, CLIENT_DATE); + file << strprintf("# Wallet dump created by PRCY%s\n", CLIENT_BUILD); file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime())); file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString()); file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime())); From bb86362aa266113ea89b953faf7e99f310cc4e6d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 23 Apr 2023 15:38:34 -0400 Subject: [PATCH 242/391] Avoid launching as admin when NSIS installer ends. The Bitcoin Core NSIS script runs with elevated privileges. Unfortunately, this means that it launches Bitcoin Core itself with elevated privileges when the user chooses to launch Bitcoin Core at the end of the installation procedure. This commit works around the issue by having explorer.exe launch Bitcoin Core. Seems to be a similar approach to what http://nsis.sourceforge.net/ShellExecAsUser_plug-in does, but without a plugin. h/t to "UK" at https://mdb-blog.blogspot.se/2013/01/nsis-lunch-program-as-user-from-uac.html?showComment=1410158039989#c2463780017054126736 for the sample code. Fixes https://github.com/bitcoin/bitcoin/issues/7990. --- share/setup.nsi.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/setup.nsi.in b/share/setup.nsi.in index df42a27200..1289947df1 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -24,7 +24,8 @@ SetDateSave off !define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup !define MUI_STARTMENUPAGE_DEFAULTFOLDER "@PACKAGE_NAME@" -!define MUI_FINISHPAGE_RUN $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ +!define MUI_FINISHPAGE_RUN "$WINDIR\explorer.exe" +!define MUI_FINISHPAGE_RUN_PARAMETERS $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" !define MUI_UNWELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" !define MUI_UNFINISHPAGE_NOAUTOCLOSE From 1b4ae634269c3502c0eb37553bf84393717f2d6d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 23 Apr 2023 15:42:52 -0400 Subject: [PATCH 243/391] build: set Unicode true for NSIS installer Now that we are using Focal for gitian builds, and have NSIS 3.0+ available (also in Guix), we can create installers that support unicode. Unicode is only becoming the default beginning with the 3.07 release, https://nsis.sourceforge.io/Docs/AppendixF.html#v3.07-cl, so we need to set this attribute to get support. Should close: https://github.com/bitcoin/bitcoin/issues/13817 --- share/setup.nsi.in | 1 + 1 file changed, 1 insertion(+) diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 1289947df1..bdedf45d8e 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -3,6 +3,7 @@ Name "@PACKAGE_NAME@ (64-bit)" RequestExecutionLevel highest SetCompressor /SOLID lzma SetDateSave off +Unicode true # Uncomment these lines when investigating reproducibility errors #SetCompress off From 117142046d18ab17c4dd8738666bcee9e8055386 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 23 Apr 2023 15:46:23 -0400 Subject: [PATCH 244/391] build: force CRCCheck in Windows installer Otherwise a user can pass /NCRC on the command line and bypass the crc check, meaning they could install a potentially corrupted installer. --- share/setup.nsi.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/setup.nsi.in b/share/setup.nsi.in index bdedf45d8e..d91c459bf8 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -54,7 +54,7 @@ Var StartMenuGroup # Installer attributes OutFile @abs_top_srcdir@/@PACKAGE_TARNAME@-@PACKAGE_VERSION@-win64-setup-unsigned.exe InstallDir $PROGRAMFILES64\PRCYcoin -CRCCheck on +CRCCheck force XPStyle on BrandingText " " ShowInstDetails show From 1aca7d0d35f65114efe5dde0e95db74d4ea5735c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 23 Apr 2023 16:11:53 -0400 Subject: [PATCH 245/391] build: Fix `make deploy` for Windows when building out of source tree --- share/setup.nsi.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/share/setup.nsi.in b/share/setup.nsi.in index d91c459bf8..7668dea8b9 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -73,13 +73,13 @@ ShowUninstDetails show Section -Main SEC0000 SetOutPath $INSTDIR SetOverwrite on - File @abs_top_srcdir@/release/@BITCOIN_GUI_NAME@@EXEEXT@ + File @abs_top_builddir@/release/@BITCOIN_GUI_NAME@@EXEEXT@ File /oname=COPYING.txt @abs_top_srcdir@/COPYING File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt SetOutPath $INSTDIR\daemon - File @abs_top_srcdir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ - File @abs_top_srcdir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ - File @abs_top_srcdir@/release/@BITCOIN_TX_NAME@@EXEEXT@ + File @abs_top_builddir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ + File @abs_top_builddir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ + File @abs_top_builddir@/release/@BITCOIN_TX_NAME@@EXEEXT@ SetOutPath $INSTDIR\doc File /r /x Makefile* @abs_top_srcdir@/doc\*.* SetOutPath $INSTDIR From ea7280bdce097afe0af2286969ec6dfdeaa8fd88 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 24 Apr 2023 10:19:19 -0400 Subject: [PATCH 246/391] rpc: remove .conf file check for combinedust in autocombinedust This allows the setting to be changed on the fly again, no longer requiring a restart. Value is checked on launch and set back to config anyway. --- src/wallet/rpcwallet.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c13b92eac0..38ab301beb 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2235,7 +2235,6 @@ UniValue getstakesplitthreshold(const UniValue& params, bool fHelp) UniValue autocombinedust(const UniValue& params, bool fHelp) { - if(pwalletMain->fCombineDust){ bool fEnable; if (params.size() >= 1) fEnable = params[0].get_bool(); @@ -2271,11 +2270,6 @@ UniValue autocombinedust(const UniValue& params, bool fHelp) result.push_back(Pair("autocombinedust", params[0].get_bool())); result.push_back(Pair("amount", int(pwalletMain->nAutoCombineThreshold))); return result; - } - else{ - throw std::runtime_error( - "autocombinedust is disabled in your prcycoin.conf"); - } } UniValue printMultiSend() From da3dc40226dedc26375573e992fe437b39bb5ad6 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 24 Apr 2023 09:10:41 -0400 Subject: [PATCH 247/391] build: add libcurl 8.0.1 --- depends/packages/libcurl.mk | 36 ++++++++++++++++++++++++++++++++++++ depends/packages/packages.mk | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 depends/packages/libcurl.mk diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk new file mode 100644 index 0000000000..3bfabdae37 --- /dev/null +++ b/depends/packages/libcurl.mk @@ -0,0 +1,36 @@ +package=libcurl +$(package)_version=8.0.1 +$(package)_dependencies=openssl +$(package)_download_path=https://curl.haxx.se/download +$(package)_file_name=curl-$($(package)_version).tar.xz +$(package)_sha256_hash=0a381cd82f4d00a9a334438b8ca239afea5bfefcfa9a1025f2bf118e79e0b5f0 +$(package)_config_opts=--disable-shared --enable-static --prefix=$(host_prefix) --host=$(HOST) --with-openssl +$(package)_config_opts+=--disable-manual --disable-ntlm-wb --with-random=/dev/urandom +$(package)_config_opts+=--disable-curldebug --disable-libcurl-option --disable-ldap --disable-ldaps +$(package)_config_opts+=--disable-dependency-tracking --enable-option-checking +$(package)_config_opts+=CFLAGS="$($(package)_cflags) -fPIC" +$(package)_conf_tool=./configure + +define $(package)_set_vars + $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" +endef + +define $(package)_config_cmds + echo '=== config for $(package):' && \ + echo '$($(package)_config_env) $($(package)_conf_tool) $($(package)_config_opts)' && \ + echo '=== ' && \ + $($(package)_config_env) $($(package)_conf_tool) $($(package)_config_opts) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + echo 'Staging dir: $($(package)_staging_dir)$(host_prefix)' && \ + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf share/man lib/*.la +endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index a43c83e48a..666bc9973a 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,4 +1,4 @@ -packages:=boost openssl libevent +packages:=boost openssl libevent libcurl qt_packages = qrencode zlib From 20e2cba0f011f75d0aacaf6492ef033c7fa4160f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 24 Apr 2023 11:42:16 -0400 Subject: [PATCH 248/391] build: add libcurl function files --- configure.ac | 7 ++++ contrib/prcycoin-qt.pro | 2 ++ src/Makefile.am | 8 +++-- src/Makefile.qt.include | 8 ++--- src/curl_json.cpp | 72 +++++++++++++++++++++++++++++++++++++++++ src/curl_json.h | 36 +++++++++++++++++++++ 6 files changed, 126 insertions(+), 7 deletions(-) create mode 100644 src/curl_json.cpp create mode 100644 src/curl_json.h diff --git a/configure.ac b/configure.ac index 5e45848e85..7cf94182c9 100644 --- a/configure.ac +++ b/configure.ac @@ -1000,6 +1000,11 @@ if test "x$use_qr" != xno; then BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) fi +dnl curl check +PKG_CHECK_MODULES([CURL], [libcurl],, [AC_MSG_ERROR([libcurl not found.])]) +AC_CHECK_HEADER([curl/curl.h],, [AC_MSG_ERROR([libcurl header not found.])]) +AC_CHECK_LIB([curl], [main],CURL_LIBS=-lcurl, AC_MSG_ERROR(libcurl missing)) + save_CXXFLAGS="${CXXFLAGS}" CXXFLAGS="${CXXFLAGS} ${CRYPTO_CFLAGS} ${SSL_CFLAGS}" AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT @@ -1271,6 +1276,8 @@ AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) AC_SUBST(CRYPTO_LIBS) AC_SUBST(SSL_LIBS) +AC_SUBST(CURL_CFLAGS) +AC_SUBST(CURL_LIBS) AC_SUBST(USE_NUM_OPENSSL) AC_SUBST(HAVE_FDATASYNC) AC_SUBST(HAVE_FULLFSYNC) diff --git a/contrib/prcycoin-qt.pro b/contrib/prcycoin-qt.pro index 090a61e9c2..c0b6296f8d 100644 --- a/contrib/prcycoin-qt.pro +++ b/contrib/prcycoin-qt.pro @@ -86,6 +86,7 @@ HEADERS += src/activemasternode.h \ src/compressor.h \ src/core_io.h \ src/cuckoocache.h \ + src/curl_json.h \ src/crypter.h \ src/eccryptoverify.h \ src/ecdhutil.h \ @@ -412,6 +413,7 @@ SOURCES += src/activemasternode.cpp \ src/compressor.cpp \ src/core_read.cpp \ src/core_write.cpp \ + src/curl_json.cpp \ src/crypter.cpp \ src/prcycoin-cli.cpp \ src/prcycoin-tx.cpp \ diff --git a/src/Makefile.am b/src/Makefile.am index ba1e828987..115248e31e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,7 +22,7 @@ else LIBUNIVALUE = $(UNIVALUE_LIBS) endif -BITCOIN_INCLUDES=-I$(builddir) $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) +BITCOIN_INCLUDES=-I$(builddir) $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) $(CURL_CFLAGS) BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include BITCOIN_INCLUDES += -I$(srcdir)/secp256k1-mw/include @@ -121,6 +121,7 @@ BITCOIN_CORE_H = \ core_io.h \ cuckoocache.h \ crypter.h \ + curl_json.h \ wallet/db.h \ fs.h \ eccryptoverify.h \ @@ -211,7 +212,7 @@ obj/build.h: FORCE libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h # server: shared between prcycoind and prcycoin-qt -libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) +libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) $(CURL_CFLAGS) libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_server_a_SOURCES = \ addrman.cpp \ @@ -220,6 +221,7 @@ libbitcoin_server_a_SOURCES = \ chain.cpp \ checkpoints.cpp \ consensus/tx_verify.cpp \ + curl_json.cpp \ httprpc.cpp \ httpserver.cpp \ init.cpp \ @@ -452,7 +454,7 @@ prcycoind_LDADD = \ $(LIBSECP256K1) \ $(LIBSECP256K1_2) -prcycoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) +prcycoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(CURL_LIBS) # prcycoin-cli binary # prcycoin_cli_SOURCES = prcycoin-cli.cpp diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 27ba3bdf8d..16bbb49424 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -389,7 +389,7 @@ BITCOIN_QT_INCLUDES = -I$(builddir)/qt -I$(srcdir)/qt -I$(srcdir)/qt/forms \ -I$(builddir)/qt/forms -DQT_NO_KEYWORDS qt_libbitcoinqt_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ - $(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(QR_CFLAGS) + $(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(QR_CFLAGS) $(CURL_CFLAGS) qt_libbitcoinqt_a_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) qt_libbitcoinqt_a_OBJCXXFLAGS = $(AM_OBJCXXFLAGS) $(QT_PIE_FLAGS) @@ -408,7 +408,7 @@ $(qt_libbitcoinqt_a_OBJECTS) $(qt_prcycoin_qt_OBJECTS) : | $(QT_MOC) # prcycoin-qt binary # qt_prcycoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ - $(QT_INCLUDES) $(QR_CFLAGS) + $(QT_INCLUDES) $(QR_CFLAGS) $(CURL_CFLAGS) qt_prcycoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) qt_prcycoin_qt_SOURCES = qt/prcycoin.cpp @@ -418,7 +418,7 @@ endif if TARGET_WINDOWS qt_prcycoin_qt_SOURCES += $(BITCOIN_RC) endif -qt_prcycoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER) $(LIBSECP256K1) $(LIBSECP256K1_2) +qt_prcycoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER) $(LIBSECP256K1) $(LIBSECP256K1_2) $(CURL_LIBS) if ENABLE_WALLET qt_prcycoin_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET) $(LIBBITCOIN_ZXCVBN) endif @@ -428,7 +428,7 @@ endif qt_prcycoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ - $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) -lqrencode + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) -lqrencode $(CURL_LIBS) qt_prcycoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_prcycoin_qt_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX diff --git a/src/curl_json.cpp b/src/curl_json.cpp new file mode 100644 index 0000000000..3aeffbda23 --- /dev/null +++ b/src/curl_json.cpp @@ -0,0 +1,72 @@ +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "curl_json.h" +#include "util.h" + +#include + +JsonDownload downloadedJSON; + +static size_t writer(char *in, size_t size, size_t nmemb, std::string *out) +{ + out->append((char*)in, size * nmemb); + return size * nmemb; +} + +void getHttpsJson(std::string url) +{ + { + JsonDownload newDownload; + downloadedJSON = newDownload; + } + + downloadedJSON.failed = false; + downloadedJSON.complete = false; + downloadedJSON.URL = url; + std::string response_string; + + curl_global_init(CURL_GLOBAL_ALL); + CURL *curl; + CURLcode res; + + struct curl_slist *headers=NULL; // init to NULL is important + + headers = curl_slist_append(headers, "Accept: application/json"); + headers = curl_slist_append(headers, "Content-Type: application/json"); + headers = curl_slist_append(headers, "charset: utf-8"); + + curl = curl_easy_init(); + if(curl) { + + curl_easy_setopt(curl, CURLOPT_URL, downloadedJSON.URL.c_str()); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string); + res = curl_easy_perform(curl); + + if(CURLE_OK == res) { + char *ct; + /* ask for the content-type */ + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct); + if((CURLE_OK == res) && ct) { + downloadedJSON.response = response_string; + downloadedJSON.failed = false; + downloadedJSON.complete = true; + } + } else { + downloadedJSON.response = ""; + downloadedJSON.failed = false; + downloadedJSON.complete = false; + } + } + /* always cleanup */ + curl_easy_cleanup(curl); + curl_slist_free_all(headers); + curl_global_cleanup(); + +} diff --git a/src/curl_json.h b/src/curl_json.h new file mode 100644 index 0000000000..b92c11698b --- /dev/null +++ b/src/curl_json.h @@ -0,0 +1,36 @@ +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef PRCYCOIN_CURLJSON_H +#define PRCYCOIN_CURLJSON_H + +#include + +#include + +#define TIME_IN_US 1 +#define TIMETYPE curl_off_t +#define TIMEOPT CURLINFO_TOTAL_TIME_T +#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3000000 + +struct CurlProgress { + TIMETYPE lastruntime; /* type depends on version, see above */ + CURL *curl; +}; + +struct JsonDownload { + std::string URL = ""; + std::string response = ""; + bool failed = false; + bool complete = false; + CURL *curl; + CurlProgress prog; +}; + +extern JsonDownload downloadedJSON; + +static size_t writer(char *in, size_t size, size_t nmemb, std::string *out); +extern void getHttpsJson(std::string url); + +#endif From e6a0681705a95ca87fa1888e1cf232e10fe771f8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 24 Apr 2023 11:43:45 -0400 Subject: [PATCH 249/391] qt: use libcurl for price fetch --- src/qt/overviewpage.cpp | 42 +++++++++++++++++++---------------------- src/qt/overviewpage.h | 6 +++--- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 2975c02c54..bfd79d407c 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -9,6 +9,7 @@ #include "ui_overviewpage.h" #include "bitcoinunits.h" #include "clientmodel.h" +#include "curl_json.h" #include "guiconstants.h" #include "guiutil.h" #include "init.h" @@ -123,12 +124,21 @@ OverviewPage::OverviewPage(QWidget* parent) : QDialog(parent, Qt::WindowSystemMe pingNetworkInterval->start(); // Init getCurrencyValueInterval - getCurrencyValueInterval = new QTimer(this); + updateJSONtimer = new QTimer(this); + updateGUItimer = new QTimer(this); manager = new QNetworkAccessManager(this); - connect(getCurrencyValueInterval, SIGNAL(timeout()), this, SLOT(getCurrencyValue())); - connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(setCurrencyValue(QNetworkReply*))); - getCurrencyValueInterval->setInterval(300000); - getCurrencyValueInterval->start(); + reply = nullptr; + + connect(updateJSONtimer, SIGNAL(timeout()), SLOT(getCurrencyValue())); + connect(updateGUItimer, SIGNAL(timeout()), SLOT(setCurrencyValue())); + + updateJSONtimer->setInterval(300000); //Check every 5 minutes. + updateJSONtimer->start(); + + updateGUItimer->setInterval(15000); //Check every 15 seconds. + updateGUItimer->start(); + + getCurrencyValue(); initSyncCircle(.8); @@ -573,19 +583,10 @@ void OverviewPage::getCurrencyValue() ui->labelCurrencyValue->setText(""); return; } - if (isRuninngQuery) { - return; - } - isRuninngQuery = true; - QNetworkRequest request; - QUrl coinGeckoUrl = QUrl("https://api.coingecko.com/api/v3/simple/price?ids=prcy-coin&vs_currencies=" + defaultCurrency + "&include_market_cap=false&include_24hr_vol=false&include_24hr_change=false&include_last_updated_at=false"); - request.setUrl(coinGeckoUrl); - request.setHeader(QNetworkRequest::ServerHeader, "application/json"); - reply = manager->get(request); - reply->ignoreSslErrors(); + getHttpsJson("https://api.coingecko.com/api/v3/simple/price?ids=prcy-coin&vs_currencies=" + defaultCurrency.toStdString() + "&include_market_cap=false&include_24hr_vol=false&include_24hr_change=false&include_last_updated_at=false"); } -void OverviewPage::setCurrencyValue(QNetworkReply* reply) +void OverviewPage::setCurrencyValue() { // Get Default Currency from Settings QString defaultCurrency = settings.value("strDefaultCurrency").toString(); @@ -608,12 +609,10 @@ void OverviewPage::setCurrencyValue(QNetworkReply* reply) defaultCurrencySymbol = "XAG"; } - reply->deleteLater(); - if(reply->error() == QNetworkReply::NoError) { + if (downloadedJSON.failed == false && downloadedJSON.complete == true) { try { // Parse data - QByteArray data = reply->readAll(); - QJsonDocument jsonDocument(QJsonDocument::fromJson(data)); + QJsonDocument jsonDocument(QJsonDocument::fromJson(downloadedJSON.response.c_str())); const QJsonObject item = jsonDocument.object(); const QJsonObject currency = item["prcy-coin"].toObject(); auto currencyValue = currency[defaultCurrency.toLower()].toDouble(); @@ -626,8 +625,5 @@ void OverviewPage::setCurrencyValue(QNetworkReply* reply) } catch (...) { LogPrintf("%s: Error parsing CoinGecko API JSON\n", __func__); } - } else { - LogPrintf("%s: Error checking for Alternative Currency value: %d\n", __func__, reply->error()); } - isRuninngQuery = false; } diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index f0700a88d1..72873df406 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -92,10 +92,10 @@ public Q_SLOTS: QRect getCircleGeometry(QWidget* parent, float ratioToParent); // Check Currency Value via CoinGecko.com API + QTimer* updateJSONtimer; + QTimer* updateGUItimer; QNetworkAccessManager* manager; QNetworkReply* reply; - QTimer* getCurrencyValueInterval; - bool isRuninngQuery = false; private Q_SLOTS: void updateDisplayUnit(); @@ -106,7 +106,7 @@ private Q_SLOTS: void updateLockStatus(int status); // Check Currency Value via CoinGecko.com API void getCurrencyValue(); - void setCurrencyValue(QNetworkReply* reply); + void setCurrencyValue(); }; #endif // BITCOIN_QT_OVERVIEWPAGE_H From c24c872bfcc7837a419e5bc1312ff73bdf0d0429 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 4 May 2023 16:39:15 -0400 Subject: [PATCH 250/391] tests: fix broken wallet test --- src/wallet/walletdb.cpp | 63 +++++++++++++++++++++++++++++++++++++++++ src/wallet/walletdb.h | 1 + 2 files changed, 64 insertions(+) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 8d79aae0d1..6cfd7ea994 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -463,6 +463,69 @@ void CWalletDB::ListAccountCreditDebit(const std::string& strAccount, std::list< pcursor->close(); } +DBErrors CWalletDB::ReorderTransactions(CWallet* pwallet) +{ + LOCK(pwallet->cs_wallet); + // Old wallets didn't have any defined order for transactions + // Probably a bad idea to change the output of this + + // First: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap. + typedef std::pair TxPair; + typedef std::multimap TxItems; + TxItems txByTime; + + for (std::map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { + CWalletTx* wtx = &((*it).second); + txByTime.insert(std::make_pair(wtx->nTimeReceived, TxPair(wtx, (CAccountingEntry*)0))); + } + std::list acentries; + ListAccountCreditDebit("", acentries); + for (CAccountingEntry& entry : acentries) { + txByTime.insert(std::make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry))); + } + + int64_t& nOrderPosNext = pwallet->nOrderPosNext; + nOrderPosNext = 0; + std::vector nOrderPosOffsets; + for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) { + CWalletTx* const pwtx = (*it).second.first; + CAccountingEntry* const pacentry = (*it).second.second; + int64_t& nOrderPos = (pwtx != 0) ? pwtx->nOrderPos : pacentry->nOrderPos; + + if (nOrderPos == -1) { + nOrderPos = nOrderPosNext++; + nOrderPosOffsets.push_back(nOrderPos); + + if (pwtx) { + if (!WriteTx(pwtx->GetHash(), *pwtx)) + return DB_LOAD_FAIL; + } else if (!WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) + return DB_LOAD_FAIL; + } else { + int64_t nOrderPosOff = 0; + for (const int64_t& nOffsetStart : nOrderPosOffsets) { + if (nOrderPos >= nOffsetStart) + ++nOrderPosOff; + } + nOrderPos += nOrderPosOff; + nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1); + + if (!nOrderPosOff) + continue; + + // Since we're changing the order, write it back + if (pwtx) { + if (!WriteTx(pwtx->GetHash(), *pwtx)) + return DB_LOAD_FAIL; + } else if (!WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) + return DB_LOAD_FAIL; + } + } + WriteOrderPosNext(nOrderPosNext); + + return DB_LOAD_OK; +} + class CWalletScanState { public: diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 8d0325cb4b..a60d76b7ab 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -179,6 +179,7 @@ class CWalletDB : public CDB CAmount GetAccountCreditDebit(const std::string& strAccount); void ListAccountCreditDebit(const std::string& strAccount, std::list& acentries); + DBErrors ReorderTransactions(CWallet* pwallet); DBErrors LoadWallet(CWallet* pwallet); DBErrors FindWalletTx(CWallet* pwallet, std::vector& vTxHash, std::vector& vWtx); DBErrors ZapWalletTx(CWallet* pwallet, std::vector& vWtx); From 5d0e95313bee399757e0bdf54ea30ef870529a4d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 31 May 2023 10:40:01 -0400 Subject: [PATCH 251/391] build: use our own FALLBACK_DOWNLOAD_PATH for depends --- depends/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/Makefile b/depends/Makefile index be3a6eb4d7..33e7c58b81 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -38,7 +38,7 @@ NO_WALLET ?= NO_ZMQ ?= NO_UPNP ?= LTO ?= -FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources +FALLBACK_DOWNLOAD_PATH ?= https://bootstrap.prcycoin.com/depends-sources BUILD = $(shell ./config.guess) HOST ?= $(BUILD) From 480446c9a134a79f38ff012dd867ffd47c5e6585 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 31 May 2023 13:04:18 -0400 Subject: [PATCH 252/391] depends: libcurl 8.1.2 --- depends/packages/libcurl.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk index 3bfabdae37..4099e3972a 100644 --- a/depends/packages/libcurl.mk +++ b/depends/packages/libcurl.mk @@ -1,9 +1,9 @@ package=libcurl -$(package)_version=8.0.1 +$(package)_version=8.1.2 $(package)_dependencies=openssl $(package)_download_path=https://curl.haxx.se/download $(package)_file_name=curl-$($(package)_version).tar.xz -$(package)_sha256_hash=0a381cd82f4d00a9a334438b8ca239afea5bfefcfa9a1025f2bf118e79e0b5f0 +$(package)_sha256_hash=31b1118eb8bfd43cd95d9a3f146f814ff874f6ed3999b29d94f4d1e7dbac5ef6 $(package)_config_opts=--disable-shared --enable-static --prefix=$(host_prefix) --host=$(HOST) --with-openssl $(package)_config_opts+=--disable-manual --disable-ntlm-wb --with-random=/dev/urandom $(package)_config_opts+=--disable-curldebug --disable-libcurl-option --disable-ldap --disable-ldaps From 51164a1e47867647bdff84e412ca5e56c11f26ac Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 5 Jun 2023 17:47:15 -0400 Subject: [PATCH 253/391] rpc: fix incorrect Sent amounts in `ListTransactions` function --- src/wallet/rpcwallet.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 38ab301beb..88cb57b974 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1167,7 +1167,14 @@ void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int n entry.push_back(Pair("account", strSentAccount)); MaybePushAddress(entry, s.destination); entry.push_back(Pair("category", "send")); - entry.push_back(Pair("amount", ValueFromAmount(-s.amount))); + + // Calculate amounts for this transaction + CAmount nCredit = wtx.GetCredit(filter); + CAmount nDebit = wtx.GetDebit(filter); + CAmount nNet = (nCredit > nDebit)? (nCredit - nDebit):(nDebit - nCredit); + CAmount nAmountWithoutFee = nNet - nFee; + + entry.push_back(Pair("amount", ValueFromAmount(-nAmountWithoutFee))); entry.push_back(Pair("vout", s.vout)); entry.push_back(Pair("fee", ValueFromAmount(-nFee))); if (fLong) From 9a2e387316ff430f3352b25810213d7cf754aba3 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 5 Jun 2023 17:47:36 -0400 Subject: [PATCH 254/391] rpc: fix amount in `gettransaction` --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 88cb57b974..efa6b4926d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1669,7 +1669,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) CAmount nDebit = wtx.GetDebit(filter); CAmount nNet = (nCredit > nDebit)? (nCredit - nDebit):(nDebit - nCredit); CAmount nFee = wtx.nTxFee; - entry.push_back(Pair("amount", ValueFromAmount(nNet))); + entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); if (wtx.IsFromMe(filter)) entry.push_back(Pair("fee", ValueFromAmount(nFee))); From b03e1e19960be39eb7d25f62557b5a376ea570cc Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 9 Jun 2023 09:58:05 -0400 Subject: [PATCH 255/391] wallet: move Params() calls outside of the loops when possible --- src/qt/sendcoinsdialog.cpp | 3 ++- src/rpc/masternode.cpp | 3 ++- src/wallet/wallet.cpp | 28 +++++++++++++++++++--------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 90a38ed3c6..d7e4d2ccdd 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -380,11 +380,12 @@ void SendCoinsDialog::sendTx() { pwalletMain->ComputeStealthPublicAddress("masteraccount", myAddress); bool showCheckBox = false; int indexOut = -1; + const CAmount collateralAmount = Params().MNCollateralAmt(); if (sendAddress == myAddress) { for (int i=0; i < (int)resultTx.vout.size(); i++) { CTxOut& out = resultTx.vout[i]; CAmount value = pwalletMain->getCTxOutValue(resultTx, out); - if (value == Params().MNCollateralAmt()) { + if (value == collateralAmount) { showCheckBox = true; indexOut = i; } diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index af709b75e9..9e08d80645 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -530,11 +530,12 @@ UniValue createmasternode(const UniValue& params, bool fHelp) UniValue ret(UniValue::VARR); int indexOut = -1; + const CAmount collateralAmount = Params().MNCollateralAmt(); for (int i=0; i < (int)wtx.vout.size(); i++) { UniValue obj(UniValue::VOBJ); CTxOut& out = wtx.vout[i]; CAmount value = pwalletMain->getCTxOutValue(wtx, out); - if (value == Params().MNCollateralAmt()) { + if (value == collateralAmount) { indexOut = i; // Lock collateral output diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8782562b57..49935c291c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1595,11 +1595,12 @@ CAmount CWalletTx::GetUnlockedCredit() const CAmount nCredit = 0; uint256 hashTx = GetHash(); + const CAmount collateralAmount = Params().MNCollateralAmt(); for (unsigned int i = 0; i < vout.size(); i++) { const CTxOut& txout = vout[i]; if (pwallet->IsSpent(hashTx, i) || pwallet->IsLockedCoin(hashTx, i)) continue; - if (fMasterNode && pwallet->getCTxOutValue(*this, vout[i]) == Params().MNCollateralAmt()) continue; // do not count MN-like outputs + if (fMasterNode && pwallet->getCTxOutValue(*this, vout[i]) == collateralAmount) continue; // do not count MN-like outputs nCredit += pwallet->GetCredit(*this, txout, ISMINE_SPENDABLE); } @@ -1619,6 +1620,7 @@ CAmount CWalletTx::GetLockedCredit() const CAmount nCredit = 0; uint256 hashTx = GetHash(); + const CAmount collateralAmount = Params().MNCollateralAmt(); for (unsigned int i = 0; i < vout.size(); i++) { const CTxOut& txout = vout[i]; @@ -1630,8 +1632,8 @@ CAmount CWalletTx::GetLockedCredit() const nCredit += pwallet->GetCredit(*this, txout, ISMINE_SPENDABLE); } - // Add masternode collaterals which are handled likc locked coins - else if (fMasterNode && pwallet->getCTxOutValue(*this, vout[i]) == Params().MNCollateralAmt()) { + // Add masternode collaterals which are handled like locked coins + else if (fMasterNode && pwallet->getCTxOutValue(*this, vout[i]) == collateralAmount) { nCredit += pwallet->GetCredit(*this, txout, ISMINE_SPENDABLE); } @@ -2434,6 +2436,7 @@ bool CWallet::AvailableCoins( if (IsLocked()) return false; vCoins.clear(); const bool fCoinsSelected = (coinControl != nullptr) && coinControl->HasSelected(); + const CAmount collateralAmount = Params().MNCollateralAmt(); { LOCK2(cs_main, cs_wallet); @@ -2453,7 +2456,7 @@ bool CWallet::AvailableCoins( bool found = false; CAmount value = getCTxOutValue(*pcoin, pcoin->vout[i]); if (nCoinType == ONLY_5000) { - found = value == Params().MNCollateralAmt(); + found = value == collateralAmount; } else { COutPoint outpoint(pcoin->GetHash(), i); if (IsCollateralized(outpoint)) { @@ -2566,6 +2569,9 @@ bool CWallet::SelectStakeCoins(std::list >& listInp std::vector vCoins; AvailableCoins(vCoins, true, NULL, false, STAKABLE_COINS); CAmount nAmountSelected = 0; + const CAmount collateralAmount = Params().MNCollateralAmt(); + const CAmount minStakingAmount = Params().MinimumStakeAmount(); + if (GetBoolArg("-prcystake", true)) { for (const COutput &out : vCoins) { //make sure not to outrun target amount @@ -2574,11 +2580,11 @@ bool CWallet::SelectStakeCoins(std::list >& listInp continue; //check that it is above Minimum Stake Amount - if (value < Params().MinimumStakeAmount()) + if (value < minStakingAmount) continue; //check that it is not MN Collateral - if (value == Params().MNCollateralAmt()) { + if (value == collateralAmount) { COutPoint outpoint(out.tx->GetHash(), out.i); if (IsCollateralized(outpoint)) { continue; @@ -2609,6 +2615,8 @@ bool CWallet::SelectStakeCoins(std::list >& listInp bool CWallet::MintableCoins() { CAmount nBalance = GetBalance(); + const CAmount collateralAmount = Params().MNCollateralAmt(); + const CAmount minStakingAmount = Params().MinimumStakeAmount(); // Regular PRCY if (nBalance > 0) { @@ -2628,7 +2636,7 @@ bool CWallet::MintableCoins() //check that it is not MN Collateral bool isCollateral = false; - if (nVal == Params().MNCollateralAmt()) { + if (nVal == collateralAmount) { COutPoint outpoint(out.tx->GetHash(), out.i); if (IsCollateralized(outpoint)) { isCollateral = true; @@ -2636,7 +2644,7 @@ bool CWallet::MintableCoins() } //nTxTime <= nTime: only stake with UTXOs that are received before nTime time - if (Params().IsRegTestNet() || (GetAdjustedTime() > Params().StakeMinAge() + nTxTime && nVal >= Params().MinimumStakeAmount() && !isCollateral)) + if (Params().IsRegTestNet() || (GetAdjustedTime() > Params().StakeMinAge() + nTxTime && nVal >= minStakingAmount && !isCollateral)) return true; } } @@ -2650,7 +2658,9 @@ StakingStatusError CWallet::StakingCoinStatus(CAmount& minFee, CAmount& maxFee) maxFee = 0; SetRingSize(0); CAmount nBalance = GetBalance(); + const CAmount collateralAmount = Params().MNCollateralAmt(); const CAmount minStakingAmount = Params().MinimumStakeAmount(); + if (IsMasternodeController()) { nBalance = GetSpendableBalance(); } @@ -2693,7 +2703,7 @@ StakingStatusError CWallet::StakingCoinStatus(CAmount& minFee, CAmount& maxFee) continue; } CAmount value = getCTxOutValue(*pcoin, pcoin->vout[i]); - if (value == Params().MNCollateralAmt()) { + if (value == collateralAmount) { COutPoint outpoint(wtxid, i); if (IsCollateralized(outpoint)) { continue; From 2a44556beeedc261782b043c934f7c756f7a1674 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 9 Jun 2023 11:41:27 -0400 Subject: [PATCH 256/391] wallet: replace push_back with emplace_back in transaction creation related functions --- src/wallet/wallet.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 49935c291c..2cbc2cfb43 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3182,7 +3182,7 @@ bool CWallet::CreateTransactionBulletProof(const CKey& txPrivDes, const CPubKey& CPubKey sharedSec; ECDHInfo::ComputeSharedSec(txPrivDes, recipientViewKey, sharedSec); EncodeTxOutAmount(txout, txout.nValue, sharedSec.begin()); - txNew.vout.push_back(txout); + txNew.vout.emplace_back(txout); nBytes += ::GetSerializeSize(*(CTxOut*)&txout, SER_NETWORK, PROTOCOL_VERSION); } @@ -3365,7 +3365,7 @@ bool CWallet::CreateTransaction(const std::vector >& strFailReason = _("Transaction amount too small"); return false; } - txNew.vout.push_back(txout); + txNew.vout.emplace_back(txout); } } else //UTXO Splitter Transaction { @@ -5350,7 +5350,7 @@ bool CWallet::SendAll(std::string des, CWalletTx& wtxNew, bool inclLocked) CPubKey sharedSec; ECDHInfo::ComputeSharedSec(wtxNew.txPrivM, pubViewKey, sharedSec); EncodeTxOutAmount(txout, txout.nValue, sharedSec.begin()); - txNew.vout.push_back(txout); + txNew.vout.emplace_back(txout); txNew.nTxFee = nFeeNeeded; //Fill vin @@ -5611,7 +5611,7 @@ bool CWallet::CreateSweepingTransaction(CAmount target, CAmount threshold, uint3 CPubKey sharedSec; ECDHInfo::ComputeSharedSec(wtxNew.txPrivM, pubViewKey, sharedSec); EncodeTxOutAmount(txout, txout.nValue, sharedSec.begin()); - txNew.vout.push_back(txout); + txNew.vout.emplace_back(txout); //nBytes += ::GetSerializeSize(*(CTxOut*)&txout, SER_NETWORK, PROTOCOL_VERSION); txNew.nTxFee = nFeeNeeded; From e6ab7458dfb48f230cbb935395e650e70c47eba2 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 7 Jun 2023 15:04:58 -0400 Subject: [PATCH 257/391] qt: update prompt in GUIUtil to be more generalized/reusable --- src/qt/guiutil.cpp | 17 ++++++++++------- src/qt/guiutil.h | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index e2834ce8ce..ae6a93b456 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -758,13 +758,16 @@ void setWindowless(QWidget* widget){ void disableTooltips(QWidget* widget){ } -void prompt(QString message){ - QMessageBox* errorPrompt = new QMessageBox(); - GUIUtil::setWindowless(errorPrompt); - errorPrompt->setStyleSheet(GUIUtil::loadStyleSheet()); - errorPrompt->setText(message); - errorPrompt->exec(); - errorPrompt->deleteLater(); +void prompt(const QString& title, const QString& message, QMessageBox::Icon icon) +{ + QMessageBox* promptBox = new QMessageBox(); + //setWindowless(promptBox); + promptBox->setStyleSheet(loadStyleSheet()); + promptBox->setIcon(icon); + promptBox->setWindowTitle(title); + promptBox->setText(message); + promptBox->exec(); + promptBox->deleteLater(); } void colorCalendarWidgetWeekends(QCalendarWidget* widget, QColor color) diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index b095bda3f3..d92161ab92 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -242,8 +242,8 @@ void disableTooltips(QWidget* widget); /** Check whether a theme is not build-in */ bool isExternal(QString theme); -//display a windowless prompt -void prompt(QString message); +//display a prompt +void prompt(const QString& title, const QString& message, QMessageBox::Icon icon = QMessageBox::Information); /* Convert QString to OS specific boost path through UTF-8 */ fs::path qstringToBoostPath(const QString& path); From 7ce5eb5de5dde8ee9265dc61e8d5fc706c36d102 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 7 Jun 2023 15:59:28 -0400 Subject: [PATCH 258/391] qt: use prompt and make sure texts are translatable --- src/qt/askpassphrasedialog.cpp | 70 +++---- src/qt/bitcoingui.cpp | 20 +- src/qt/coincontroldialog.cpp | 10 +- src/qt/encryptdialog.cpp | 66 +++---- src/qt/entermnemonics.cpp | 4 +- src/qt/optionspage.cpp | 343 ++++++++++++++------------------- src/qt/receivecoinsdialog.cpp | 14 +- src/qt/revealtxdialog.cpp | 10 +- src/qt/sendcoinsdialog.cpp | 95 ++++----- src/qt/sendcoinsentry.cpp | 17 +- src/qt/walletview.cpp | 20 +- 11 files changed, 284 insertions(+), 385 deletions(-) diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 2fcbc3c309..7acd73c89f 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -143,21 +143,17 @@ void AskPassphraseDialog::accept() ""); QApplication::quit(); } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("Wallet encryption failed due to an internal error. Your wallet was not encrypted. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted. Please try again."), + QMessageBox::Critical); } QDialog::accept(); // Success } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The supplied passphrases do not match. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The supplied passphrases do not match. Please try again."), + QMessageBox::Critical); } } else { QDialog::reject(); // Cancelled @@ -166,24 +162,20 @@ void AskPassphraseDialog::accept() case Mode::UnlockStaking: case Mode::Unlock: if (!model->setWalletLocked(false, oldpass, ui->stakingCheckBox->isChecked())) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Unlock Failed"); - msgBox.setText("The passphrase entered for the wallet unlock was incorrect. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Unlock Failed"), + tr("The passphrase entered for the wallet unlock was incorrect. Please try again."), + QMessageBox::Critical); } else { QDialog::accept(); // Success } break; case Mode::Decrypt: if (!model->setWalletEncrypted(false, oldpass)) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Decryption Failed"); - msgBox.setText("The passphrase entered for the wallet decryption was incorrect. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Decryption Failed"), + tr("The passphrase entered for the wallet decryption was incorrect. Please try again."), + QMessageBox::Critical); } else { QDialog::accept(); // Success } @@ -191,28 +183,22 @@ void AskPassphraseDialog::accept() case Mode::ChangePass: if (newpass1 == newpass2) { if (model->changePassphrase(oldpass, newpass1)) { - QMessageBox msgBox; - msgBox.setWindowTitle("Passphrase Change Successful"); - msgBox.setText("Wallet passphrase was successfully changed.\nPlease remember your passphrase as there is no way to recover it."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::prompt( + tr("Passphrase Change Successful"), + tr("Wallet passphrase was successfully changed.\nPlease remember your passphrase as there is no way to recover it."), + QMessageBox::Information); QDialog::accept(); // Success } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase entered for the wallet decryption was incorrect. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrase entered for the wallet decryption was incorrect. Please try again."), + QMessageBox::Critical); } } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The supplied passphrases do not match. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The supplied passphrases do not match. Please try again."), + QMessageBox::Critical); } break; } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 7e6c8e1a2e..0d79c9f17c 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1013,23 +1013,19 @@ void BitcoinGUI::serviceRequestFinished(QNetworkReply* reply) } else { LogPrintf("Check For Updates: No update available.\n"); if (!isStartup) { - QMessageBox msgBox; - msgBox.setWindowTitle("No Update Available"); - msgBox.setText("No update available.\n\nYour wallet is up to date."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::prompt( + tr("No Update Available"), + tr("No update available.\n\nYour wallet is up to date."), + QMessageBox::Information); } } } else { LogPrintf("Check For Updates: Error!\n"); QByteArray error = reply->readAll(); - QMessageBox msgBox; - msgBox.setWindowTitle("Error"); - msgBox.setText("Error checking for updates.\n\n" + error); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Error"), + tr("Error checking for updates.\n\n" + error), + QMessageBox::Critical); } isStartup = false; } diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 096a332c55..b98118dc7a 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -231,11 +231,11 @@ void CoinControlDialog::buttonToggleLockClicked() CoinControlDialog::updateLabels(model, this); updateDialogLabels(); } else { - QMessageBox msgBox; - msgBox.setObjectName("lockMessageBox"); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setText(tr("Please switch to \"List mode\" to use this function.")); - msgBox.exec(); + GUIUtil::prompt( + "lockMessageBox", + "", + tr("Please switch to \"List mode\" to use this function."), + QMessageBox::Warning); } } diff --git a/src/qt/encryptdialog.cpp b/src/qt/encryptdialog.cpp index 947e5f9e1d..35663a8a67 100644 --- a/src/qt/encryptdialog.cpp +++ b/src/qt/encryptdialog.cpp @@ -34,7 +34,7 @@ void EncryptDialog::setModel(WalletModel* model) void EncryptDialog::closeEvent (QCloseEvent *event) { QMessageBox::StandardButton reply; - reply = QMessageBox::warning(this, "Wallet Encryption Required", "There was no passphrase entered for the wallet.\n\nWallet encryption is required for the security of your funds.\n\nWhat would you like to do?", QMessageBox::Retry|QMessageBox::Close); + reply = QMessageBox::warning(this, tr("Wallet Encryption Required"), tr("There was no passphrase entered for the wallet.\n\nWallet encryption is required for the security of your funds.\n\nWhat would you like to do?"), QMessageBox::Retry|QMessageBox::Close); if (reply == QMessageBox::Retry) { event->ignore(); } else { @@ -45,7 +45,7 @@ void EncryptDialog::closeEvent (QCloseEvent *event) void EncryptDialog::on_btnCancel() { QMessageBox::StandardButton reply; - reply = QMessageBox::warning(this, "Wallet Encryption Required", "There was no passphrase entered for the wallet.\n\nWallet encryption is required for the security of your funds.\n\nWhat would you like to do?", QMessageBox::Retry|QMessageBox::Close); + reply = QMessageBox::warning(this, tr("Wallet Encryption Required"), tr("There was no passphrase entered for the wallet.\n\nWallet encryption is required for the security of your funds.\n\nWhat would you like to do?"), QMessageBox::Retry|QMessageBox::Close); if (reply == QMessageBox::Retry) { return; } else { @@ -63,66 +63,54 @@ void EncryptDialog::on_acceptPassphrase() { newPass2.assign(ui->linePwdConfirm->text().toStdString().c_str() ); if ( (!ui->linePwd->text().length()) || (!ui->linePwdConfirm->text().length()) ) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase entered for wallet encryption was empty. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); - return; + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrase entered for wallet encryption was empty. Please try again."), + QMessageBox::Critical); + return; } if (newPass == newPass2) { if (newPass.length() < 10) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase's length has to be more than 10. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrase's length has to be more than 10. Please try again."), + QMessageBox::Critical); return; } if (!pwalletMain->checkPassPhraseRule(newPass.c_str())) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase must contain lower, upper, digit, symbol. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrase must contain lower, upper, digit, symbol. Please try again."), + QMessageBox::Critical); return; } double guesses; int ret = zxcvbn_password_strength(newPass.c_str(), NULL, &guesses, NULL); if (ret < 0 || guesses < 10000) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrases entered for wallet encryption is too weak. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrases entered for wallet encryption is too weak. Please try again."), + QMessageBox::Critical); return; } if (model->setWalletEncrypted(true, newPass)) { pwalletMain->nTimeFirstKey = 1; model->setWalletLocked(false, newPass); - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Successful"); - msgBox.setText("Wallet passphrase was successfully set.\nPlease remember your passphrase as there is no way to recover it."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Successful"), + tr("Wallet passphrase was successfully set.\nPlease remember your passphrase as there is no way to recover it."), + QMessageBox::Information); accept(); } } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrases entered for wallet encryption do not match. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrases entered for wallet encryption do not match. Please try again."), + QMessageBox::Critical); return; } } diff --git a/src/qt/entermnemonics.cpp b/src/qt/entermnemonics.cpp index fc921665c0..11ca7a0442 100644 --- a/src/qt/entermnemonics.cpp +++ b/src/qt/entermnemonics.cpp @@ -26,12 +26,12 @@ void EnterMnemonics::on_next() std::string phrase = ui->mnemonics->toPlainText().trimmed().toStdString(); try { pwalletMain->GenerateNewHDChain(&phrase); - QMessageBox::information(this, "Recovery Phrase Import Successful", "Your mnemonics have been successfully imported into the wallet. Rescanning will be scheduled to recover all your funds.", QMessageBox::Ok); + QMessageBox::information(this, tr("Recovery Phrase Import Successful"), tr("Your mnemonics have been successfully imported into the wallet. Rescanning will be scheduled to recover all your funds."), QMessageBox::Ok); CBlockLocator loc = chainActive.GetLocator(chainActive[0]); pwalletMain->SetBestChain(loc); CWalletDB(pwalletMain->strWalletFile).WriteScannedBlockHeight(0); //reschedule to rescan entire chain to recover all funds and history accept(); } catch (const std::exception& ex) { - QMessageBox::warning(this, "Recovery Phrase Invalid", "Recovery phrase is invalid. Please try again and double check all words.", QMessageBox::Ok); + QMessageBox::warning(this, tr("Recovery Phrase Invalid"), tr("Recovery phrase is invalid. Please try again and double check all words."), QMessageBox::Ok); } } diff --git a/src/qt/optionspage.cpp b/src/qt/optionspage.cpp index dab97ecfd1..f47d2a9966 100644 --- a/src/qt/optionspage.cpp +++ b/src/qt/optionspage.cpp @@ -211,21 +211,19 @@ void OptionsPage::on_pushButtonSave_clicked() { double dAmount = ui->lineEditWithhold->text().toDouble(); if (ui->lineEditWithhold->text().trimmed().isEmpty()) { ui->lineEditWithhold->setStyleSheet("border: 2px solid red"); - QMessageBox msgBox; - msgBox.setWindowTitle("Reserve Balance Empty"); - msgBox.setText("PRCY reserve amount is empty and must be a minimum of 1.\nPlease click Disable if you would like to turn it off."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::prompt( + tr("Reserve Balance Empty"), + tr("PRCY reserve amount is empty and must be a minimum of 1.\nPlease click Disable if you would like to turn it off."), + QMessageBox::Information); return; } - if (dAmount < 0.0 || dAmount > 250000000) { - QMessageBox msgBox; - msgBox.setWindowTitle("Invalid Reserve Amount"); - msgBox.setText("The amount you have attempted to keep as spendable is greater than the 250,000,000 (250M) limit. Please try a smaller amount."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + if (dAmount < 0.0 || dAmount > MAX_MONEY_OUT) { + CAmount maxMoneyInCoins = MAX_MONEY_OUT / COIN; + CAmount maxMoneyInMillions = maxMoneyInCoins / 1000000; + GUIUtil::prompt( + tr("Invalid Reserve Amount"), + tr("The amount you have attempted to keep as spendable is greater than the %1 (%2M) limit. Please try a smaller amount.").arg(maxMoneyInCoins).arg(maxMoneyInMillions), + QMessageBox::Warning); return; } nReserveBalance = getValidatedAmount(); @@ -235,14 +233,12 @@ void OptionsPage::on_pushButtonSave_clicked() { Q_EMIT model->stakingStatusChanged(nLastCoinStakeSearchInterval); ui->lineEditWithhold->setStyleSheet(GUIUtil::loadStyleSheet()); - + QString reserveBalance = ui->lineEditWithhold->text().trimmed(); - QMessageBox msgBox; - msgBox.setWindowTitle("Reserve Balance Set"); - msgBox.setText("Reserve balance of " + reserveBalance + " PRCY is successfully set."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::prompt( + tr("Reserve Balance Set"), + tr("Reserve balance of %1 PRCY is successfully set.").arg(reserveBalance), + QMessageBox::Information); } void OptionsPage::on_pushButtonDisable_clicked() { @@ -252,12 +248,10 @@ void OptionsPage::on_pushButtonDisable_clicked() { walletdb.WriteReserveAmount(0); Q_EMIT model->stakingStatusChanged(nLastCoinStakeSearchInterval); - QMessageBox msgBox; - msgBox.setWindowTitle("Reserve Balance Disabled"); - msgBox.setText("Reserve balance disabled."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::prompt( + tr("Reserve Balance Disabled"), + tr("Reserve balance disabled."), + QMessageBox::Information); } void OptionsPage::keyPressEvent(QKeyEvent* event) @@ -273,12 +267,10 @@ void OptionsPage::setMapper() void OptionsPage::on_pushButtonPassword_clicked() { if ( (!ui->lineEditNewPass->text().length()) || (!ui->lineEditNewPassRepeat->text().length()) ) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase entered for wallet encryption was empty or contained spaces. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrase entered for wallet encryption was empty or contained spaces. Please try again."), + QMessageBox::Critical); return; } //disable password submit button @@ -299,53 +291,41 @@ void OptionsPage::on_pushButtonPassword_clicked() double guesses; if (oldPass == newPass) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase you have entered is the same as your old passphrase. Please use a different passphrase if you would like to change it."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrase you have entered is the same as your old passphrase. Please use a different passphrase if you would like to change it."), + QMessageBox::Critical); } else if (newPass.length() < 10) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase's length has to be more than 10. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrase's length has to be more than 10. Please try again."), + QMessageBox::Critical); } else if (!pwalletMain->checkPassPhraseRule(newPass.c_str())) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase must contain lower, upper, digit, symbol. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrase must contain lower, upper, digit, symbol. Please try again."), + QMessageBox::Critical); } else if (zxcvbn_password_strength(newPass.c_str(), NULL, &guesses, NULL) < 0 || guesses < 10000) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase is too weak. You must use a minimum passphrase length of 10 characters and use uppercase letters, lowercase letters, numbers, and symbols. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrase is too weak. You must use a minimum passphrase length of 10 characters and use uppercase letters, lowercase letters, numbers, and symbols. Please try again."), + QMessageBox::Critical); } else if (model->changePassphrase(oldPass, newPass)) { - QMessageBox msgBox; - msgBox.setWindowTitle("Passphrase Change Successful"); - msgBox.setText("Wallet passphrase was successfully changed.\nPlease remember your passphrase as there is no way to recover it."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::prompt( + tr("Passphrase Change Successful"), + tr("Wallet passphrase was successfully changed.\nPlease remember your passphrase as there is no way to recover it."), + QMessageBox::Information); success = true; } } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrases entered for wallet encryption do not match. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Encryption Failed"), + tr("The passphrases entered for wallet encryption do not match. Please try again."), + QMessageBox::Critical); } if (success) @@ -374,20 +354,17 @@ void OptionsPage::on_pushButtonBackup_clicked(){ if (model->backupWallet(QString(filename))) { ui->pushButtonBackup->setStyleSheet("border: 2px solid green"); - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Backup Successful"); - msgBox.setText("Wallet has been successfully backed up to " + filename); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + QString msg = tr("Wallet has been successfully backed up to "); + GUIUtil::prompt( + tr("Wallet Backup Successful"), + msg + filename, + QMessageBox::Information); } else { ui->pushButtonBackup->setStyleSheet("border: 2px solid red"); - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Backup Failed"); - msgBox.setText("Wallet backup failed. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Wallet Backup Failed"), + tr("Wallet backup failed. Please try again."), + QMessageBox::Critical); } ui->pushButtonBackup->repaint(); } @@ -436,74 +413,72 @@ bool OptionsPage::matchNewPasswords() void OptionsPage::on_EnableStaking(ToggleButton* widget) { if (!masternodeSync.IsSynced()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Staking Disabled - Syncing Masternode list"); - msgBox.setText("Enable Staking is disabled when you are still syncing the Masternode list as this is required. Please allow the wallet to fully sync this list before attempting to Enable Staking."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + GUIUtil::prompt( + tr("Staking Disabled - Syncing Masternode list"), + tr("Enable Staking is disabled when you are still syncing the Masternode list as this is required. Please allow the wallet to fully sync this list before attempting to Enable Staking."), + QMessageBox::Warning); return; } int status = model->getEncryptionStatus(); if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - QMessageBox msgBox; - msgBox.setWindowTitle("Staking Setting"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Please unlock the wallet with your passphrase before changing this setting."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Staking Setting"), + tr("Please unlock the wallet with your passphrase before changing this setting."), + QMessageBox::Information); widget->setState(!widget->getState()); return; } + QString errorMessage; if (chainActive.Height() < Params().LAST_POW_BLOCK()) { if (widget->getState()) { - QString msg; - msg.sprintf("PoW blocks are still being mined.\nPlease wait until Block %d.", Params().LAST_POW_BLOCK()); - QMessageBox msgBox; - msgBox.setWindowTitle("Information"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText(msg); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + int lastPowBlock = Params().LAST_POW_BLOCK(); + errorMessage = tr("PoW blocks are still being mined.\nPlease wait until Block %1.").arg(lastPowBlock); + GUIUtil::prompt( + tr("Information"), + errorMessage, + QMessageBox::Information); } widget->setState(false); pwalletMain->WriteStakingStatus(false); return; } if (widget->getState()){ - QString error; CAmount minFee, maxFee; + const CAmount minStakingAmount = model->getMinStakingAmount(); StakingStatusError stt = pwalletMain->StakingCoinStatus(minFee, maxFee); - std::string errorMessage; - if (stt == StakingStatusError::UNSTAKABLE_BALANCE_TOO_LOW || + if (stt == StakingStatusError::UNSTAKABLE_BALANCE_TOO_LOW || stt == UNSTAKABLE_BALANCE_RESERVE_TOO_HIGH || stt == UNSTAKABLE_BALANCE_RESERVE_TOO_HIGH_CONSOLIDATION_FAILED || stt == UNSTAKABLE_BALANCE_TOO_LOW_CONSOLIDATION_FAILED) { - QMessageBox msgBox; + if (stt == StakingStatusError::UNSTAKABLE_BALANCE_TOO_LOW) { - errorMessage = "Your stakeable balance is under the threshold of 2500 PRCY. Please deposit more PRCY into your account in order to enable staking."; + errorMessage = tr("Your stakeable balance is under the threshold of %1 PRCY. Please deposit more PRCY into your account in order to enable staking.").arg(minStakingAmount); } else if (stt == UNSTAKABLE_BALANCE_TOO_LOW_CONSOLIDATION_FAILED) { - errorMessage = "Your balance requires a consolidation transaction which incurs a fee of between " + FormatMoney(minFee) + " to " + FormatMoney(maxFee) + " PRCY. However after that transaction fee, your balance will be below the staking threshold of 2500 PRCY. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking."; + errorMessage = tr("Your balance requires a consolidation transaction which incurs a fee of between %1 to %2 PRCY. However after that transaction fee, your balance will be below the staking threshold of %3 PRCY. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking.") + .arg(QString::fromStdString(FormatMoney(minFee))) + .arg(QString::fromStdString(FormatMoney(maxFee))) + .arg(minStakingAmount); } else if (stt == UNSTAKABLE_BALANCE_RESERVE_TOO_HIGH) { - errorMessage = "Your stakeable balance is under the threshold of 2500 PRCY. This is due to your reserve balance being too high. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking."; + errorMessage = tr("Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance being too high. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking.").arg(minStakingAmount); } else { SetRingSize(0); CAmount totalFee = maxFee + pwalletMain->ComputeFee(1, 2, MAX_RING_SIZE); - errorMessage = "Your stakeable balance is under the threshold of 2500 PRCY. This is due to your reserve balance of " + FormatMoney(nReserveBalance) + " PRCY being too high. The wallet software has tried to consolidate your funds with the reserve balance but without success because of a consolidation fee of " + FormatMoney(totalFee) + " PRCY. Please wait around 10 minutes for the wallet to resolve the reserve to enable staking."; + errorMessage = tr("Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance of %2 PRCY being too high. The wallet software has tried to consolidate your funds with the reserve balance but without success because of a consolidation fee of %3 PRCY. Please wait around 10 minutes for the wallet to resolve the reserve to enable staking.") + .arg(minStakingAmount) + .arg(QString::fromStdString(FormatMoney(nReserveBalance))) + .arg(QString::fromStdString(FormatMoney(totalFee))); } - QString msg = QString::fromStdString(errorMessage); - msgBox.setWindowTitle("Warning: Staking Issue"); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setText(msg); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Warning: Staking Issue"), + errorMessage, + QMessageBox::Warning); widget->setState(false); nLastCoinStakeSearchInterval = 0; Q_EMIT model->stakingStatusChanged(false); - pwalletMain->WriteStakingStatus(false); - return; - } + pwalletMain->WriteStakingStatus(false); + return; + } if (stt == StakingStatusError::STAKING_OK) { pwalletMain->WriteStakingStatus(true); Q_EMIT model->stakingStatusChanged(true); @@ -514,14 +489,18 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) return; } - QMessageBox::StandardButton reply; if (stt == StakingStatusError::STAKABLE_NEED_CONSOLIDATION) { - errorMessage = "In order to enable staking with 100% of your current balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between " + FormatMoney(minFee) + " to " + FormatMoney(maxFee) + " PRCY.\n\nWould you like to do this?"; + errorMessage = tr("In order to enable staking with 100%% of your current balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY.\n\nWould you like to do this?") + .arg(QString::fromStdString(FormatMoney(minFee))) + .arg(QString::fromStdString(FormatMoney(maxFee))); } else { - errorMessage = "In order to enable staking with 100% of your current balance except the reserve balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between " + FormatMoney(minFee) + " to " + FormatMoney(maxFee) + " PRCY.\n\nWould you like to do this?"; + errorMessage = tr("In order to enable staking with 100%% of your current balance except the reserve balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY.\n\nWould you like to do this?") + .arg(QString::fromStdString(FormatMoney(minFee))) + .arg(QString::fromStdString(FormatMoney(maxFee))); } - reply = QMessageBox::question(this, "Staking Needs Consolidation", QString::fromStdString(errorMessage), QMessageBox::Yes|QMessageBox::No|QMessageBox::Ignore); - if (reply == QMessageBox::Yes) { + QMessageBox::StandardButton reply; + reply = QMessageBox::question(this, tr("Staking Needs Consolidation"), errorMessage, QMessageBox::Yes|QMessageBox::No|QMessageBox::Ignore); + if (reply == QMessageBox::Yes) { pwalletMain->WriteStakingStatus(true); Q_EMIT model->stakingStatusChanged(true); model->generateCoins(true, 1); @@ -529,7 +508,6 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) pwalletMain->combineMode = CombineMode::ON; saveConsolidationSettingTime(ui->addNewFunds->isChecked()); bool success = false; - const CAmount minStakingAmount = model->getMinStakingAmount();; try { uint32_t nTime = pwalletMain->ReadAutoConsolidateSettingTime(); nTime = (nTime == 0)? GetAdjustedTime() : nTime; @@ -538,17 +516,14 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) minStakingAmount, nTime); if (success) { //nConsolidationTime = 1800; - QString msg = "Consolidation transaction created!"; - QMessageBox msgBox; - msgBox.setWindowTitle("Information"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText(msg); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Information"), + tr("Consolidation transaction created!"), + QMessageBox::Information); } } catch (const std::exception& err) { LogPrintf("Sweeping failed, will be done automatically when coins become mature"); - } + } return; } else if (reply == QMessageBox::No) { nLastCoinStakeSearchInterval = 0; @@ -606,7 +581,6 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) msgBox.exec(); return; } - if (success){ WalletUtil::getTx(pwalletMain, resultTx.GetHash()); QString txhash = resultTx.GetHash().GetHex().c_str(); @@ -619,7 +593,6 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); msgBox.setIcon(QMessageBox::Information); msgBox.exec(); - if (msgBox.clickedButton() == copyButton) { //Copy txhash to clipboard GUIUtil::setClipboard(txhash); @@ -645,12 +618,10 @@ void OptionsPage::on_Enable2FA(ToggleButton* widget) { int status = model->getEncryptionStatus(); if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - QMessageBox msgBox; - msgBox.setWindowTitle("2FA Setting"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Please unlock the wallet with your passphrase before changing this setting."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("2FA Setting"), + tr("Please unlock the wallet with your passphrase before changing this setting."), + QMessageBox::Information); ui->toggle2FA->setState(!ui->toggle2FA->getState()); return; @@ -695,12 +666,10 @@ void OptionsPage::dialogIsFinished(int result) { pwalletMain->Write2FALastTime(current.toTime_t()); enable2FA(); - QMessageBox msgBox; - msgBox.setWindowTitle("SUCCESS!"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Two-factor authentication has been successfully enabled."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("SUCCESS!"), + tr("Two-factor authentication has been successfully enabled."), + QMessageBox::Information); } if (result == QDialog::Rejected) @@ -760,7 +729,7 @@ void OptionsPage::enable2FA() { value.sprintf("%c", chrlist[5]); ui->code_6->setText(value); } - + int period = pwalletMain->Read2FAPeriod(); typeOf2FA = NONE2FA; if (period == 1) { @@ -824,7 +793,7 @@ void OptionsPage::on_week() { codedlg.setWindowTitle("2FA Code Verification"); codedlg.setStyleSheet(GUIUtil::loadStyleSheet()); connect(&codedlg, SIGNAL(finished (int)), this, SLOT(confirmDialogIsFinished(int))); - codedlg.exec(); + codedlg.exec(); } void OptionsPage::on_month() { @@ -845,12 +814,10 @@ void OptionsPage::onShowMnemonic() { if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Mnemonic Recovery Phrase"), + tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), + QMessageBox::Information); LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); return; } else { @@ -865,12 +832,10 @@ void OptionsPage::onShowMnemonic() { model->setWalletLocked(true); WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Mnemonic Recovery Phrase"), + tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), + QMessageBox::Information); LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); return; } else { @@ -928,12 +893,10 @@ void OptionsPage::mapPortUpnp_clicked(int state) } else { settings.setValue("fUseUPnP", false); } - QMessageBox msgBox; - msgBox.setWindowTitle("UPNP Settings"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("UPNP Settings successfully changed. Please restart the wallet for changes to take effect."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("UPNP Settings"), + tr("UPNP Settings successfully changed. Please restart the wallet for changes to take effect."), + QMessageBox::Information); } void OptionsPage::minimizeToTray_clicked(int state) @@ -964,20 +927,16 @@ void OptionsPage::changeDigits(int digit) if (reply == QMessageBox::Yes) { digit = ui->comboBox->currentText().toInt(); settings.setValue("2fadigits", digit); - QMessageBox msgBox; - msgBox.setWindowTitle("2FA Digit Settings"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("2FA Digit Settings have been changed successfully."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("2FA Digit Settings"), + tr("2FA Digit Settings have been changed successfully."), + QMessageBox::Information); return; } else { - QMessageBox msgBox; - msgBox.setWindowTitle("2FA Digit Settings"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("2FA Digit Settings have not been changed."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("2FA Digit Settings"), + tr("2FA Digit Settings have not been changed."), + QMessageBox::Information); return; } } @@ -1018,12 +977,10 @@ void OptionsPage::hideBalanceStaking_clicked(int state) { model->setWalletLocked(true); WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Hide Balance When Unlocked"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Hide Balance When Unlocked"), + tr("Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security."), + QMessageBox::Information); LogPrintf("Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security.\n"); settings.setValue("fHideBalance", true); ui->hideBalanceStaking->setChecked(true); @@ -1054,12 +1011,10 @@ void OptionsPage::lockSendStaking_clicked(int state) { model->setWalletLocked(true); WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Lock Send Tab When Unlocked"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Lock Send Tab When Unlocked"), + tr("Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security."), + QMessageBox::Information); LogPrintf("Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security.\n"); settings.setValue("fLockSendStaking", true); ui->lockSendStaking->setChecked(true); @@ -1103,12 +1058,10 @@ void OptionsPage::checkForUnlock() { int status = model->getEncryptionStatus(); if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - QMessageBox msgBox; - msgBox.setWindowTitle("Password Locked Setting"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Please unlock the wallet with your passphrase before changing this setting."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Password Locked Setting"), + tr("Please unlock the wallet with your passphrase before changing this setting."), + QMessageBox::Information); return; } } diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 01e05d5d42..eadb1b0ddd 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -189,13 +189,13 @@ void ReceiveCoinsDialog::updateDisplayUnit() void ReceiveCoinsDialog::on_receiveButton_clicked() { double dAmount = ui->reqAmount->text().toDouble(); - if (dAmount < 0.0 || dAmount > MAX_MONEY_OUT) { - QMessageBox msgBox; - msgBox.setWindowTitle("Invalid Amount"); - msgBox.setText("Invalid amount entered. Please enter an amount less than 2.1B PRCY."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + CAmount maxMoneyInCoins = MAX_MONEY_OUT / COIN; + CAmount maxMoneyInMillions = maxMoneyInCoins / 1000000; + if (dAmount < 0.0 || dAmount > maxMoneyInCoins) { + GUIUtil::prompt( + tr("Invalid Amount"), + tr("Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY.").arg(maxMoneyInCoins).arg(maxMoneyInMillions), + QMessageBox::Warning); return; } if (!model || !model->getOptionsModel() || !model->getAddressTableModel()) diff --git a/src/qt/revealtxdialog.cpp b/src/qt/revealtxdialog.cpp index 9f9e3dab2b..2ae6dbd08f 100644 --- a/src/qt/revealtxdialog.cpp +++ b/src/qt/revealtxdialog.cpp @@ -178,12 +178,10 @@ void RevealTxDialog::deleteTransaction() // Check it exists if (!pwalletMain->mapWallet.count(hash)) { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Invalid or non-wallet transaction id")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setText(tr("Invalid or non-wallet transaction id.")); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Invalid or non-wallet transaction id"), + tr("Invalid or non-wallet transaction id."), + QMessageBox::Critical); return; } // Erase it diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 90a38ed3c6..53182783e5 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -140,12 +140,10 @@ SendCoinsDialog::~SendCoinsDialog(){ void SendCoinsDialog::on_sendButton_clicked(){ if (!masternodeSync.IsBlockchainSynced()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Send Disabled - Syncing"); - msgBox.setText("Sending PRCY is disabled when you are still syncing the wallet. Please allow the wallet to fully sync before attempting to send a transaction."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + GUIUtil::prompt( + tr("Send Disabled - Syncing"), + tr("Sending PRCY is disabled when you are still syncing the wallet. Please allow the wallet to fully sync before attempting to send a transaction."), + QMessageBox::Warning); return; } if (!ui->entries->count()) @@ -166,22 +164,18 @@ void SendCoinsDialog::on_sendButton_clicked(){ form->errorAmount(isValidAmount); if (!isValidAddresss) { - QMessageBox msgBox; - msgBox.setWindowTitle("Invalid Address"); - msgBox.setText("Invalid address entered. Please make sure you are sending to a Stealth Address."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + GUIUtil::prompt( + tr("Invalid Address"), + tr("Invalid address entered. Please make sure you are sending to a Stealth Address."), + QMessageBox::Warning); return; } if (!isValidAmount) { - QMessageBox msgBox; - msgBox.setWindowTitle("Invalid Amount"); - msgBox.setText("Invalid amount entered. Please enter an amount less than your Spendable Balance."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + GUIUtil::prompt( + tr("Invalid Amount"), + tr("Invalid amount entered. Please enter an amount less than your Spendable Balance."), + QMessageBox::Warning); return; } @@ -251,19 +245,15 @@ void SendCoinsDialog::on_sendButton_clicked(){ CAmount spendable = pwalletMain->GetSpendableBalance(); if (!(recipient.amount <= nReserveBalance && recipient.amount <= spendable)) { if (recipient.amount > spendable) { - QMessageBox msgBox; - msgBox.setWindowTitle("Insufficient Spendable Funds!"); - msgBox.setText("Insufficient spendable funds. Send with smaller amount or wait for your coins become mature"); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::prompt( + tr("Insufficient Spendable Funds!"), + tr("Insufficient spendable funds. Send with smaller amount or wait for your coins become mature"), + QMessageBox::Information); } else if (recipient.amount > nReserveBalance) { - QMessageBox msgBox; - msgBox.setWindowTitle("Insufficient Reserve Funds!"); - msgBox.setText("Insufficient reserve funds. Send with smaller amount or turn off staking mode."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::prompt( + tr("Insufficient Reserve Funds!"), + tr("Insufficient reserve funds. Send with smaller amount or turn off staking mode."), + QMessageBox::Information); } return; } @@ -328,30 +318,23 @@ void SendCoinsDialog::sendTx() { send_amount, nTime); nReserveBalance = backupReserve; if (success) { - QString msg = "Consolidation transaction created!"; - QMessageBox msgBox; - msgBox.setWindowTitle("Information"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText(msg); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Information"), + tr("Consolidation transaction created!"), + QMessageBox::Information); } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Sweeping Transaction Creation Error"); - msgBox.setText(QString("Sweeping transaction creation failed due to an internal error. Please try again later.")); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Sweeping Transaction Creation Error"), + tr("Sweeping transaction creation failed due to an internal error. Please try again later."), + QMessageBox::Critical); } } catch (const std::exception& err1) { nReserveBalance = backupReserve; - QMessageBox msgBox; LogPrintf("ERROR:%s: %s\n", __func__, err1.what()); - msgBox.setWindowTitle("Sweeping Transaction Creation Error"); - msgBox.setText(QString("Sweeping transaction creation failed due to an internal error. Please try again later.")); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Sweeping Transaction Creation Error"), + tr("Sweeping transaction creation failed due to an internal error. Please try again later."), + QMessageBox::Critical); } return; } else { @@ -359,15 +342,13 @@ void SendCoinsDialog::sendTx() { } } else { QString msg = err.what(); - if (msg == "") { - msg = "Unable to create transaction. Please try again later."; + if (msg.isEmpty()) { + msg = tr("Unable to create transaction. Please try again later."); } - QMessageBox msgBox; - msgBox.setWindowTitle("Transaction Creation Error"); - msgBox.setText(msg); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::prompt( + tr("Transaction Creation Error"), + msg, + QMessageBox::Critical); } return; } diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 32a31762e8..f377053757 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -129,15 +129,16 @@ static inline int64_t roundint64(double d) return (int64_t)(d > 0 ? d + 0.5 : d - 0.5); } -CAmount SendCoinsEntry::getValidatedAmount() { +CAmount SendCoinsEntry::getValidatedAmount() +{ double dAmount = ui->payAmount->text().toDouble(); - if (dAmount < 0.0 || dAmount > MAX_MONEY_OUT) { - QMessageBox msgBox; - msgBox.setWindowTitle("Invalid Amount"); - msgBox.setText("Invalid amount entered. Please enter an amount less than 2.1B PRCY."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + CAmount maxMoneyInCoins = MAX_MONEY_OUT / COIN; + CAmount maxMoneyInMillions = maxMoneyInCoins / 1000000; + if (dAmount < 0.0 || dAmount > maxMoneyInCoins) { + GUIUtil::prompt( + tr("Invalid Amount"), + tr("Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY.").arg(maxMoneyInCoins).arg(maxMoneyInMillions), + QMessageBox::Warning); } CAmount nAmount = roundint64(dAmount * COIN); return nAmount; diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 79e09f465b..6ddda524fc 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -276,12 +276,10 @@ void WalletView::showSeedPhrase() if (encryptionStatus == WalletModel::Locked || encryptionStatus == WalletModel::UnlockedForStakingOnly) { WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Mnemonic Recovery Phrase"), + tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), + QMessageBox::Information); LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); return; } else { @@ -296,12 +294,10 @@ void WalletView::showSeedPhrase() walletModel->setWalletLocked(true); WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::prompt( + tr("Mnemonic Recovery Phrase"), + tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), + QMessageBox::Information); LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); return; } else { From 3d6e74a8bcb765f6e73d90c66c8a631bb2350576 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 8 Jun 2023 10:04:56 -0400 Subject: [PATCH 259/391] qt: add overloaded version of prompt this one accepts an objectName as first parameter for cases where they are used --- src/qt/guiutil.cpp | 16 +++++++++++----- src/qt/guiutil.h | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index ae6a93b456..e26e488597 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -758,14 +758,20 @@ void setWindowless(QWidget* widget){ void disableTooltips(QWidget* widget){ } -void prompt(const QString& title, const QString& message, QMessageBox::Icon icon) -{ +void prompt(const QString& title, const QString& message, QMessageBox::Icon icon) { + prompt("", title, message, icon); +} + +void prompt(const QString& objectName, const QString& title, const QString& message, QMessageBox::Icon icon) { QMessageBox* promptBox = new QMessageBox(); - //setWindowless(promptBox); - promptBox->setStyleSheet(loadStyleSheet()); + if (!objectName.isEmpty()) { + promptBox->setObjectName(objectName); + } + //GUIUtil::setWindowless(promptBox); + promptBox->setStyleSheet(GUIUtil::loadStyleSheet()); + promptBox->setText(message); promptBox->setIcon(icon); promptBox->setWindowTitle(title); - promptBox->setText(message); promptBox->exec(); promptBox->deleteLater(); } diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index d92161ab92..e32f989d7d 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -243,7 +243,8 @@ void disableTooltips(QWidget* widget); bool isExternal(QString theme); //display a prompt -void prompt(const QString& title, const QString& message, QMessageBox::Icon icon = QMessageBox::Information); +void prompt(const QString& title, const QString& message, QMessageBox::Icon icon); +void prompt(const QString& objectName, const QString& title, const QString& message, QMessageBox::Icon icon); /* Convert QString to OS specific boost path through UTF-8 */ fs::path qstringToBoostPath(const QString& path); From 3383905fe831aba33356bf9692b3211cb39e63d3 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 8 Jun 2023 10:37:20 -0400 Subject: [PATCH 260/391] qt: rename prompt to showMessageBox --- src/qt/askpassphrasedialog.cpp | 14 ++++----- src/qt/bitcoingui.cpp | 4 +-- src/qt/coincontroldialog.cpp | 2 +- src/qt/encryptdialog.cpp | 12 ++++---- src/qt/guiutil.cpp | 26 ++++++++-------- src/qt/guiutil.h | 6 ++-- src/qt/optionspage.cpp | 56 +++++++++++++++++----------------- src/qt/receivecoinsdialog.cpp | 2 +- src/qt/revealtxdialog.cpp | 2 +- src/qt/sendcoinsdialog.cpp | 18 +++++------ src/qt/sendcoinsentry.cpp | 2 +- src/qt/walletview.cpp | 4 +-- 12 files changed, 74 insertions(+), 74 deletions(-) diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 7acd73c89f..360baeb40e 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -143,14 +143,14 @@ void AskPassphraseDialog::accept() "
"); QApplication::quit(); } else { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted. Please try again."), QMessageBox::Critical); } QDialog::accept(); // Success } else { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The supplied passphrases do not match. Please try again."), QMessageBox::Critical); @@ -162,7 +162,7 @@ void AskPassphraseDialog::accept() case Mode::UnlockStaking: case Mode::Unlock: if (!model->setWalletLocked(false, oldpass, ui->stakingCheckBox->isChecked())) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Unlock Failed"), tr("The passphrase entered for the wallet unlock was incorrect. Please try again."), QMessageBox::Critical); @@ -172,7 +172,7 @@ void AskPassphraseDialog::accept() break; case Mode::Decrypt: if (!model->setWalletEncrypted(false, oldpass)) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Decryption Failed"), tr("The passphrase entered for the wallet decryption was incorrect. Please try again."), QMessageBox::Critical); @@ -183,19 +183,19 @@ void AskPassphraseDialog::accept() case Mode::ChangePass: if (newpass1 == newpass2) { if (model->changePassphrase(oldpass, newpass1)) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Passphrase Change Successful"), tr("Wallet passphrase was successfully changed.\nPlease remember your passphrase as there is no way to recover it."), QMessageBox::Information); QDialog::accept(); // Success } else { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrase entered for the wallet decryption was incorrect. Please try again."), QMessageBox::Critical); } } else { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The supplied passphrases do not match. Please try again."), QMessageBox::Critical); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 0d79c9f17c..88858a2bb4 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1013,7 +1013,7 @@ void BitcoinGUI::serviceRequestFinished(QNetworkReply* reply) } else { LogPrintf("Check For Updates: No update available.\n"); if (!isStartup) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("No Update Available"), tr("No update available.\n\nYour wallet is up to date."), QMessageBox::Information); @@ -1022,7 +1022,7 @@ void BitcoinGUI::serviceRequestFinished(QNetworkReply* reply) } else { LogPrintf("Check For Updates: Error!\n"); QByteArray error = reply->readAll(); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Error"), tr("Error checking for updates.\n\n" + error), QMessageBox::Critical); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index b98118dc7a..3dc53985aa 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -231,7 +231,7 @@ void CoinControlDialog::buttonToggleLockClicked() CoinControlDialog::updateLabels(model, this); updateDialogLabels(); } else { - GUIUtil::prompt( + GUIUtil::showMessageBox( "lockMessageBox", "", tr("Please switch to \"List mode\" to use this function."), diff --git a/src/qt/encryptdialog.cpp b/src/qt/encryptdialog.cpp index 35663a8a67..cf8972f725 100644 --- a/src/qt/encryptdialog.cpp +++ b/src/qt/encryptdialog.cpp @@ -63,7 +63,7 @@ void EncryptDialog::on_acceptPassphrase() { newPass2.assign(ui->linePwdConfirm->text().toStdString().c_str() ); if ( (!ui->linePwd->text().length()) || (!ui->linePwdConfirm->text().length()) ) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrase entered for wallet encryption was empty. Please try again."), QMessageBox::Critical); @@ -72,7 +72,7 @@ void EncryptDialog::on_acceptPassphrase() { if (newPass == newPass2) { if (newPass.length() < 10) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrase's length has to be more than 10. Please try again."), QMessageBox::Critical); @@ -80,7 +80,7 @@ void EncryptDialog::on_acceptPassphrase() { } if (!pwalletMain->checkPassPhraseRule(newPass.c_str())) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrase must contain lower, upper, digit, symbol. Please try again."), QMessageBox::Critical); @@ -90,7 +90,7 @@ void EncryptDialog::on_acceptPassphrase() { double guesses; int ret = zxcvbn_password_strength(newPass.c_str(), NULL, &guesses, NULL); if (ret < 0 || guesses < 10000) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrases entered for wallet encryption is too weak. Please try again."), QMessageBox::Critical); @@ -100,14 +100,14 @@ void EncryptDialog::on_acceptPassphrase() { if (model->setWalletEncrypted(true, newPass)) { pwalletMain->nTimeFirstKey = 1; model->setWalletLocked(false, newPass); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Successful"), tr("Wallet passphrase was successfully set.\nPlease remember your passphrase as there is no way to recover it."), QMessageBox::Information); accept(); } } else { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrases entered for wallet encryption do not match. Please try again."), QMessageBox::Critical); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index e26e488597..4c1c421c99 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -758,22 +758,22 @@ void setWindowless(QWidget* widget){ void disableTooltips(QWidget* widget){ } -void prompt(const QString& title, const QString& message, QMessageBox::Icon icon) { - prompt("", title, message, icon); +void showMessageBox(const QString& title, const QString& message, QMessageBox::Icon icon) { + showMessageBox("", title, message, icon); } -void prompt(const QString& objectName, const QString& title, const QString& message, QMessageBox::Icon icon) { - QMessageBox* promptBox = new QMessageBox(); +void showMessageBox(const QString& objectName, const QString& title, const QString& message, QMessageBox::Icon icon) { + QMessageBox* messageBox = new QMessageBox(); if (!objectName.isEmpty()) { - promptBox->setObjectName(objectName); - } - //GUIUtil::setWindowless(promptBox); - promptBox->setStyleSheet(GUIUtil::loadStyleSheet()); - promptBox->setText(message); - promptBox->setIcon(icon); - promptBox->setWindowTitle(title); - promptBox->exec(); - promptBox->deleteLater(); + messageBox->setObjectName(objectName); + } + //GUIUtil::setWindowless(messageBox); + messageBox->setStyleSheet(GUIUtil::loadStyleSheet()); + messageBox->setText(message); + messageBox->setIcon(icon); + messageBox->setWindowTitle(title); + messageBox->exec(); + messageBox->deleteLater(); } void colorCalendarWidgetWeekends(QCalendarWidget* widget, QColor color) diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index e32f989d7d..a44e25ffe3 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -242,9 +242,9 @@ void disableTooltips(QWidget* widget); /** Check whether a theme is not build-in */ bool isExternal(QString theme); -//display a prompt -void prompt(const QString& title, const QString& message, QMessageBox::Icon icon); -void prompt(const QString& objectName, const QString& title, const QString& message, QMessageBox::Icon icon); +/** Display styled MessageBox **/ +void showMessageBox(const QString& title, const QString& message, QMessageBox::Icon icon); +void showMessageBox(const QString& objectName, const QString& title, const QString& message, QMessageBox::Icon icon); /* Convert QString to OS specific boost path through UTF-8 */ fs::path qstringToBoostPath(const QString& path); diff --git a/src/qt/optionspage.cpp b/src/qt/optionspage.cpp index f47d2a9966..328425f468 100644 --- a/src/qt/optionspage.cpp +++ b/src/qt/optionspage.cpp @@ -211,7 +211,7 @@ void OptionsPage::on_pushButtonSave_clicked() { double dAmount = ui->lineEditWithhold->text().toDouble(); if (ui->lineEditWithhold->text().trimmed().isEmpty()) { ui->lineEditWithhold->setStyleSheet("border: 2px solid red"); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Reserve Balance Empty"), tr("PRCY reserve amount is empty and must be a minimum of 1.\nPlease click Disable if you would like to turn it off."), QMessageBox::Information); @@ -220,7 +220,7 @@ void OptionsPage::on_pushButtonSave_clicked() { if (dAmount < 0.0 || dAmount > MAX_MONEY_OUT) { CAmount maxMoneyInCoins = MAX_MONEY_OUT / COIN; CAmount maxMoneyInMillions = maxMoneyInCoins / 1000000; - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Invalid Reserve Amount"), tr("The amount you have attempted to keep as spendable is greater than the %1 (%2M) limit. Please try a smaller amount.").arg(maxMoneyInCoins).arg(maxMoneyInMillions), QMessageBox::Warning); @@ -235,7 +235,7 @@ void OptionsPage::on_pushButtonSave_clicked() { ui->lineEditWithhold->setStyleSheet(GUIUtil::loadStyleSheet()); QString reserveBalance = ui->lineEditWithhold->text().trimmed(); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Reserve Balance Set"), tr("Reserve balance of %1 PRCY is successfully set.").arg(reserveBalance), QMessageBox::Information); @@ -248,7 +248,7 @@ void OptionsPage::on_pushButtonDisable_clicked() { walletdb.WriteReserveAmount(0); Q_EMIT model->stakingStatusChanged(nLastCoinStakeSearchInterval); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Reserve Balance Disabled"), tr("Reserve balance disabled."), QMessageBox::Information); @@ -267,7 +267,7 @@ void OptionsPage::setMapper() void OptionsPage::on_pushButtonPassword_clicked() { if ( (!ui->lineEditNewPass->text().length()) || (!ui->lineEditNewPassRepeat->text().length()) ) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrase entered for wallet encryption was empty or contained spaces. Please try again."), QMessageBox::Critical); @@ -291,38 +291,38 @@ void OptionsPage::on_pushButtonPassword_clicked() double guesses; if (oldPass == newPass) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrase you have entered is the same as your old passphrase. Please use a different passphrase if you would like to change it."), QMessageBox::Critical); } else if (newPass.length() < 10) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrase's length has to be more than 10. Please try again."), QMessageBox::Critical); } else if (!pwalletMain->checkPassPhraseRule(newPass.c_str())) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrase must contain lower, upper, digit, symbol. Please try again."), QMessageBox::Critical); } else if (zxcvbn_password_strength(newPass.c_str(), NULL, &guesses, NULL) < 0 || guesses < 10000) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrase is too weak. You must use a minimum passphrase length of 10 characters and use uppercase letters, lowercase letters, numbers, and symbols. Please try again."), QMessageBox::Critical); } else if (model->changePassphrase(oldPass, newPass)) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Passphrase Change Successful"), tr("Wallet passphrase was successfully changed.\nPlease remember your passphrase as there is no way to recover it."), QMessageBox::Information); success = true; } } else { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Encryption Failed"), tr("The passphrases entered for wallet encryption do not match. Please try again."), QMessageBox::Critical); @@ -355,13 +355,13 @@ void OptionsPage::on_pushButtonBackup_clicked(){ if (model->backupWallet(QString(filename))) { ui->pushButtonBackup->setStyleSheet("border: 2px solid green"); QString msg = tr("Wallet has been successfully backed up to "); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Backup Successful"), msg + filename, QMessageBox::Information); } else { ui->pushButtonBackup->setStyleSheet("border: 2px solid red"); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Wallet Backup Failed"), tr("Wallet backup failed. Please try again."), QMessageBox::Critical); @@ -413,7 +413,7 @@ bool OptionsPage::matchNewPasswords() void OptionsPage::on_EnableStaking(ToggleButton* widget) { if (!masternodeSync.IsSynced()) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Staking Disabled - Syncing Masternode list"), tr("Enable Staking is disabled when you are still syncing the Masternode list as this is required. Please allow the wallet to fully sync this list before attempting to Enable Staking."), QMessageBox::Warning); @@ -421,7 +421,7 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) } int status = model->getEncryptionStatus(); if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Staking Setting"), tr("Please unlock the wallet with your passphrase before changing this setting."), QMessageBox::Information); @@ -434,7 +434,7 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) if (widget->getState()) { int lastPowBlock = Params().LAST_POW_BLOCK(); errorMessage = tr("PoW blocks are still being mined.\nPlease wait until Block %1.").arg(lastPowBlock); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Information"), errorMessage, QMessageBox::Information); @@ -469,7 +469,7 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) .arg(QString::fromStdString(FormatMoney(nReserveBalance))) .arg(QString::fromStdString(FormatMoney(totalFee))); } - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Warning: Staking Issue"), errorMessage, QMessageBox::Warning); @@ -516,7 +516,7 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) minStakingAmount, nTime); if (success) { //nConsolidationTime = 1800; - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Information"), tr("Consolidation transaction created!"), QMessageBox::Information); @@ -618,7 +618,7 @@ void OptionsPage::on_Enable2FA(ToggleButton* widget) { int status = model->getEncryptionStatus(); if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("2FA Setting"), tr("Please unlock the wallet with your passphrase before changing this setting."), QMessageBox::Information); @@ -666,7 +666,7 @@ void OptionsPage::dialogIsFinished(int result) { pwalletMain->Write2FALastTime(current.toTime_t()); enable2FA(); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("SUCCESS!"), tr("Two-factor authentication has been successfully enabled."), QMessageBox::Information); @@ -814,7 +814,7 @@ void OptionsPage::onShowMnemonic() { if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Mnemonic Recovery Phrase"), tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), QMessageBox::Information); @@ -832,7 +832,7 @@ void OptionsPage::onShowMnemonic() { model->setWalletLocked(true); WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Mnemonic Recovery Phrase"), tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), QMessageBox::Information); @@ -893,7 +893,7 @@ void OptionsPage::mapPortUpnp_clicked(int state) } else { settings.setValue("fUseUPnP", false); } - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("UPNP Settings"), tr("UPNP Settings successfully changed. Please restart the wallet for changes to take effect."), QMessageBox::Information); @@ -927,13 +927,13 @@ void OptionsPage::changeDigits(int digit) if (reply == QMessageBox::Yes) { digit = ui->comboBox->currentText().toInt(); settings.setValue("2fadigits", digit); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("2FA Digit Settings"), tr("2FA Digit Settings have been changed successfully."), QMessageBox::Information); return; } else { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("2FA Digit Settings"), tr("2FA Digit Settings have not been changed."), QMessageBox::Information); @@ -977,7 +977,7 @@ void OptionsPage::hideBalanceStaking_clicked(int state) { model->setWalletLocked(true); WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Hide Balance When Unlocked"), tr("Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security."), QMessageBox::Information); @@ -1011,7 +1011,7 @@ void OptionsPage::lockSendStaking_clicked(int state) { model->setWalletLocked(true); WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Lock Send Tab When Unlocked"), tr("Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security."), QMessageBox::Information); @@ -1058,7 +1058,7 @@ void OptionsPage::checkForUnlock() { int status = model->getEncryptionStatus(); if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Password Locked Setting"), tr("Please unlock the wallet with your passphrase before changing this setting."), QMessageBox::Information); diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index eadb1b0ddd..f5708f8f6e 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -192,7 +192,7 @@ void ReceiveCoinsDialog::on_receiveButton_clicked() CAmount maxMoneyInCoins = MAX_MONEY_OUT / COIN; CAmount maxMoneyInMillions = maxMoneyInCoins / 1000000; if (dAmount < 0.0 || dAmount > maxMoneyInCoins) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Invalid Amount"), tr("Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY.").arg(maxMoneyInCoins).arg(maxMoneyInMillions), QMessageBox::Warning); diff --git a/src/qt/revealtxdialog.cpp b/src/qt/revealtxdialog.cpp index 2ae6dbd08f..e70988363a 100644 --- a/src/qt/revealtxdialog.cpp +++ b/src/qt/revealtxdialog.cpp @@ -178,7 +178,7 @@ void RevealTxDialog::deleteTransaction() // Check it exists if (!pwalletMain->mapWallet.count(hash)) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Invalid or non-wallet transaction id"), tr("Invalid or non-wallet transaction id."), QMessageBox::Critical); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 53182783e5..08beb2eb69 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -140,7 +140,7 @@ SendCoinsDialog::~SendCoinsDialog(){ void SendCoinsDialog::on_sendButton_clicked(){ if (!masternodeSync.IsBlockchainSynced()) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Send Disabled - Syncing"), tr("Sending PRCY is disabled when you are still syncing the wallet. Please allow the wallet to fully sync before attempting to send a transaction."), QMessageBox::Warning); @@ -164,7 +164,7 @@ void SendCoinsDialog::on_sendButton_clicked(){ form->errorAmount(isValidAmount); if (!isValidAddresss) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Invalid Address"), tr("Invalid address entered. Please make sure you are sending to a Stealth Address."), QMessageBox::Warning); @@ -172,7 +172,7 @@ void SendCoinsDialog::on_sendButton_clicked(){ } if (!isValidAmount) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Invalid Amount"), tr("Invalid amount entered. Please enter an amount less than your Spendable Balance."), QMessageBox::Warning); @@ -245,12 +245,12 @@ void SendCoinsDialog::on_sendButton_clicked(){ CAmount spendable = pwalletMain->GetSpendableBalance(); if (!(recipient.amount <= nReserveBalance && recipient.amount <= spendable)) { if (recipient.amount > spendable) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Insufficient Spendable Funds!"), tr("Insufficient spendable funds. Send with smaller amount or wait for your coins become mature"), QMessageBox::Information); } else if (recipient.amount > nReserveBalance) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Insufficient Reserve Funds!"), tr("Insufficient reserve funds. Send with smaller amount or turn off staking mode."), QMessageBox::Information); @@ -318,12 +318,12 @@ void SendCoinsDialog::sendTx() { send_amount, nTime); nReserveBalance = backupReserve; if (success) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Information"), tr("Consolidation transaction created!"), QMessageBox::Information); } else { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Sweeping Transaction Creation Error"), tr("Sweeping transaction creation failed due to an internal error. Please try again later."), QMessageBox::Critical); @@ -331,7 +331,7 @@ void SendCoinsDialog::sendTx() { } catch (const std::exception& err1) { nReserveBalance = backupReserve; LogPrintf("ERROR:%s: %s\n", __func__, err1.what()); - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Sweeping Transaction Creation Error"), tr("Sweeping transaction creation failed due to an internal error. Please try again later."), QMessageBox::Critical); @@ -345,7 +345,7 @@ void SendCoinsDialog::sendTx() { if (msg.isEmpty()) { msg = tr("Unable to create transaction. Please try again later."); } - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Transaction Creation Error"), msg, QMessageBox::Critical); diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index f377053757..3636689870 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -135,7 +135,7 @@ CAmount SendCoinsEntry::getValidatedAmount() CAmount maxMoneyInCoins = MAX_MONEY_OUT / COIN; CAmount maxMoneyInMillions = maxMoneyInCoins / 1000000; if (dAmount < 0.0 || dAmount > maxMoneyInCoins) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Invalid Amount"), tr("Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY.").arg(maxMoneyInCoins).arg(maxMoneyInMillions), QMessageBox::Warning); diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 6ddda524fc..c0c1dacb15 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -276,7 +276,7 @@ void WalletView::showSeedPhrase() if (encryptionStatus == WalletModel::Locked || encryptionStatus == WalletModel::UnlockedForStakingOnly) { WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Mnemonic Recovery Phrase"), tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), QMessageBox::Information); @@ -294,7 +294,7 @@ void WalletView::showSeedPhrase() walletModel->setWalletLocked(true); WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - GUIUtil::prompt( + GUIUtil::showMessageBox( tr("Mnemonic Recovery Phrase"), tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), QMessageBox::Information); From d0f51fb6e863271682e4b259935fcfef2a8d83f2 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 7 Jun 2023 21:16:16 -0400 Subject: [PATCH 261/391] rpc: add blockheight to WalletTxToJSON --- src/wallet/rpcwallet.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index efa6b4926d..14da7be6e2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -58,6 +58,7 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) entry.push_back(Pair("generated", true)); if (confirms > 0) { entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); + entry.push_back(Pair("blockheight", mapBlockIndex[wtx.hashBlock]->nHeight)); entry.push_back(Pair("blockindex", wtx.nIndex)); entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime())); } @@ -1629,6 +1630,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) " \"confirmations\" : n, (numeric) The number of confirmations\n" " \"bcconfirmations\" : n, (numeric) The number of blockchain confirmations\n" " \"blockhash\" : \"hash\", (string) The block hash\n" + " \"blockheight\" : n, (numeric) The block height\n" " \"blockindex\" : xx, (numeric) The block index\n" " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n" " \"txid\" : \"transactionid\", (string) The transaction id.\n" From c6413e2caa440a8980a2cdeeb808084247c522c0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 8 Jun 2023 12:54:37 -0400 Subject: [PATCH 262/391] qt: consolidate showSeedPhrase code in WalletModel --- src/qt/optionspage.cpp | 60 +--------------------------------- src/qt/walletmodel.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++ src/qt/walletmodel.h | 2 ++ src/qt/walletview.cpp | 62 +---------------------------------- 4 files changed, 77 insertions(+), 120 deletions(-) diff --git a/src/qt/optionspage.cpp b/src/qt/optionspage.cpp index 328425f468..3c50a6792a 100644 --- a/src/qt/optionspage.cpp +++ b/src/qt/optionspage.cpp @@ -810,65 +810,7 @@ void OptionsPage::onShowMnemonic() { if(!model) return; - int status = model->getEncryptionStatus(); - if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); - if (!ctx.isValid()) { - GUIUtil::showMessageBox( - tr("Mnemonic Recovery Phrase"), - tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), - QMessageBox::Information); - LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); - return; - } else { - SecureString pass; - model->setWalletLocked(false, pass); - LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); - } - } else { - QMessageBox::StandardButton reply; - reply = QMessageBox::question(this, "Are You Sure?", "Are you sure you would like to view your Mnemonic Phrase?\nYou will be required to enter your passphrase. Failed or canceled attempts will be logged.", QMessageBox::Yes|QMessageBox::No); - if (reply == QMessageBox::Yes) { - model->setWalletLocked(true); - WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); - if (!ctx.isValid()) { - GUIUtil::showMessageBox( - tr("Mnemonic Recovery Phrase"), - tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), - QMessageBox::Information); - LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); - return; - } else { - SecureString pass; - model->setWalletLocked(false, pass); - LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); - } - } else { - LogPrintf("Attempt to view Mnemonic Phrase canceled.\n"); - return; - } - } - QString phrase = ""; - std::string recoverySeedPhrase = ""; - if (model->getSeedPhrase(recoverySeedPhrase)) { - phrase = QString::fromStdString(recoverySeedPhrase); - } - - QMessageBox msgBox; - QPushButton *copyButton = msgBox.addButton(tr("Copy"), QMessageBox::ActionRole); - QPushButton *okButton = msgBox.addButton(tr("OK"), QMessageBox::ActionRole); - copyButton->setStyleSheet("background:transparent;"); - copyButton->setIcon(QIcon(":/icons/editcopy")); - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setText("Below is your Mnemonic Recovery Phrase, consisting of 24 seed words. Please copy/write these words down in order. We strongly recommend keeping multiple copies in different locations."); - msgBox.setInformativeText("\n" + phrase + ""); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); - - if (msgBox.clickedButton() == copyButton) { - //Copy Mnemonic Recovery Phrase to clipboard - GUIUtil::setClipboard(phrase); - } + model->showSeedPhrase(); } void OptionsPage::setAutoConsolidate(int state) { diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 4cce4a0278..e4aad45fe5 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -34,6 +34,7 @@ #include #include #include +#include WalletModel::WalletModel(CWallet* wallet, OptionsModel* optionsModel, QObject* parent) : QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), @@ -355,6 +356,78 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction& tran return SendCoinsReturn(TransactionCommitFailed); } +void WalletModel::showSeedPhrase() +{ + WalletModel::EncryptionStatus encryptionStatus = getEncryptionStatus(); + + if (encryptionStatus == WalletModel::Locked || encryptionStatus == WalletModel::UnlockedForStakingOnly) { + WalletModel::UnlockContext ctx(requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); + if (!ctx.isValid()) { + GUIUtil::showMessageBox( + tr("Mnemonic Recovery Phrase"), + tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), + QMessageBox::Information); + LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); + return; + } else { + SecureString pass; + setWalletLocked(false, pass); + LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); + } + } else { + QMessageBox msgBox; + msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); + msgBox.setWindowTitle(tr("Are You Sure?")); + msgBox.setText(tr("Are you sure you would like to view your Mnemonic Phrase?\nYou will be required to enter your passphrase. Failed or canceled attempts will be logged.")); + msgBox.setStandardButtons(QMessageBox::Yes|QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::No); + msgBox.setIcon(QMessageBox::Question); + int reply = msgBox.exec(); + + if (reply == QMessageBox::Yes) { + setWalletLocked(true); + WalletModel::UnlockContext ctx(requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); + if (!ctx.isValid()) { + GUIUtil::showMessageBox( + tr("Mnemonic Recovery Phrase"), + tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), + QMessageBox::Information); + LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); + return; + } else { + SecureString pass; + setWalletLocked(false, pass); + LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); + } + } else { + LogPrintf("Attempt to view Mnemonic Phrase canceled.\n"); + return; + } + } + + QString phrase = ""; + std::string recoverySeedPhrase = ""; + if (getSeedPhrase(recoverySeedPhrase)) { + phrase = QString::fromStdString(recoverySeedPhrase); + } + + QMessageBox msgBox; + QPushButton *copyButton = msgBox.addButton(tr("Copy"), QMessageBox::ActionRole); + QPushButton *okButton = msgBox.addButton(tr("OK"), QMessageBox::ActionRole); + copyButton->setStyleSheet("background:transparent;"); + copyButton->setIcon(QIcon(":/icons/editcopy")); + msgBox.setWindowTitle(tr("Mnemonic Recovery Phrase")); + msgBox.setText(tr("Below is your Mnemonic Recovery Phrase, consisting of 24 seed words. Please copy/write these words down in order. We strongly recommend keeping multiple copies in different locations.")); + msgBox.setInformativeText("\n" + phrase + ""); + msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); + msgBox.exec(); + + if (msgBox.clickedButton() == copyButton) { + //Copy Mnemonic Recovery Phrase to clipboard + GUIUtil::setClipboard(phrase); + } +} + OptionsModel* WalletModel::getOptionsModel() { return optionsModel; diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index e9449f0871..83878662d2 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -185,6 +185,8 @@ class WalletModel : public QObject // Wallet backup bool backupWallet(const QString& filename); + void showSeedPhrase(); + // RAI object for unlocking wallet, returned by requestUnlock() class UnlockContext { diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index c0c1dacb15..b7132eb5c1 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -271,67 +271,7 @@ void WalletView::showSeedPhrase() if(!walletModel) return; - WalletModel::EncryptionStatus encryptionStatus = walletModel->getEncryptionStatus(); - - if (encryptionStatus == WalletModel::Locked || encryptionStatus == WalletModel::UnlockedForStakingOnly) { - WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); - if (!ctx.isValid()) { - GUIUtil::showMessageBox( - tr("Mnemonic Recovery Phrase"), - tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), - QMessageBox::Information); - LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); - return; - } else { - SecureString pass; - walletModel->setWalletLocked(false, pass); - LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); - } - } else { - QMessageBox::StandardButton reply; - reply = QMessageBox::question(this, "Are You Sure?", "Are you sure you would like to view your Mnemonic Phrase?\nYou will be required to enter your passphrase. Failed or canceled attempts will be logged.", QMessageBox::Yes|QMessageBox::No); - if (reply == QMessageBox::Yes) { - walletModel->setWalletLocked(true); - WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); - if (!ctx.isValid()) { - GUIUtil::showMessageBox( - tr("Mnemonic Recovery Phrase"), - tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), - QMessageBox::Information); - LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); - return; - } else { - SecureString pass; - walletModel->setWalletLocked(false, pass); - LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); - } - } else { - LogPrintf("Attempt to view Mnemonic Phrase canceled.\n"); - return; - } - } - - QString phrase = ""; - std::string recoverySeedPhrase = ""; - if (walletModel->getSeedPhrase(recoverySeedPhrase)) { - phrase = QString::fromStdString(recoverySeedPhrase); - } - - QMessageBox msgBox; - QPushButton *copyButton = msgBox.addButton(tr("Copy"), QMessageBox::ActionRole); - QPushButton *okButton = msgBox.addButton(tr("OK"), QMessageBox::ActionRole); - copyButton->setStyleSheet("background:transparent;"); - copyButton->setIcon(QIcon(":/icons/editcopy")); - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setText("Below is your Mnemonic Recovery Phrase, consisting of 24 seed words. Please copy/write these words down in order. We strongly recommend keeping multiple copies in different locations."); - msgBox.setInformativeText("\n" + phrase + ""); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); - - if (msgBox.clickedButton() == copyButton) { - //Copy Mnemonic Recovery Phrase to clipboard - GUIUtil::setClipboard(phrase); - } + walletModel->showSeedPhrase(); } void WalletView::changePassphrase() From 0063dd9ed97e73b11f304d752bd875e0ba490c7f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 15 Jun 2023 09:08:26 -0400 Subject: [PATCH 263/391] rpc: fix generate category for stake rewards in ListTransactions --- src/wallet/rpcwallet.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 14da7be6e2..99ffe0d7d5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1167,7 +1167,6 @@ void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int n entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("account", strSentAccount)); MaybePushAddress(entry, s.destination); - entry.push_back(Pair("category", "send")); // Calculate amounts for this transaction CAmount nCredit = wtx.GetCredit(filter); @@ -1175,7 +1174,19 @@ void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int n CAmount nNet = (nCredit > nDebit)? (nCredit - nDebit):(nDebit - nCredit); CAmount nAmountWithoutFee = nNet - nFee; - entry.push_back(Pair("amount", ValueFromAmount(-nAmountWithoutFee))); + if (wtx.IsCoinStake()) { + if (wtx.GetDepthInMainChain() < 1) { + entry.push_back(Pair("category", "orphan")); + } else if (wtx.GetBlocksToMaturity() > 0) { + entry.push_back(Pair("category", "immature")); + } else { + entry.push_back(Pair("category", "generate")); + } + entry.push_back(Pair("amount", ValueFromAmount(nAmountWithoutFee))); + } else { + entry.push_back(Pair("category", "send")); + entry.push_back(Pair("amount", ValueFromAmount(-nAmountWithoutFee))); + } entry.push_back(Pair("vout", s.vout)); entry.push_back(Pair("fee", ValueFromAmount(-nFee))); if (fLong) From 1900659ae47ed6dbfc9b5042831069be1fa549b3 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 20 Feb 2023 11:38:38 -0500 Subject: [PATCH 264/391] Convert EraseFromWallet to boolean --- src/qt/revealtxdialog.cpp | 8 +++++++- src/validationinterface.h | 1 + src/wallet/rpcwallet.cpp | 3 ++- src/wallet/wallet.cpp | 12 +++++------- src/wallet/wallet.h | 2 +- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/qt/revealtxdialog.cpp b/src/qt/revealtxdialog.cpp index e70988363a..9440741b7a 100644 --- a/src/qt/revealtxdialog.cpp +++ b/src/qt/revealtxdialog.cpp @@ -185,7 +185,13 @@ void RevealTxDialog::deleteTransaction() return; } // Erase it - pwalletMain->EraseFromWallet(hash); + if (!pwalletMain->EraseFromWallet(hash)) { + GUIUtil::showMessageBox( + tr("Unable to delete transaction id"), + tr("Unable to delete transaction id."), + QMessageBox::Critical); + return; + } // Display Success! dialog if not disabled QMessageBox msgBox; diff --git a/src/validationinterface.h b/src/validationinterface.h index 7599165b51..229dc7e3ed 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -33,6 +33,7 @@ class CValidationInterface { protected: virtual void UpdatedBlockTip(const CBlockIndex *pindex) {} virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {} + virtual bool EraseFromWallet(const uint256 &hash) { return false;} virtual void NotifyTransactionLock(const CTransaction &tx) {} virtual void SetBestChain(const CBlockLocator &locator) {} virtual bool UpdatedTransaction(const uint256 &hash) { return false;} diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 99ffe0d7d5..97e2b22733 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3143,7 +3143,8 @@ UniValue erasefromwallet(const UniValue& params, bool fHelp) if (!pwalletMain->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); - pwalletMain->EraseFromWallet(hash); + if (!pwalletMain->mapWallet.count(hash)) + return "Failed to delete transaction"; return "Done"; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2cbc2cfb43..69f560474b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1317,17 +1317,16 @@ void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock) } } -void CWallet::EraseFromWallet(const uint256& hash) +bool CWallet::EraseFromWallet(const uint256& hash) { if (!fFileBacked) - return; + return false; { LOCK(cs_wallet); if (mapWallet.erase(hash)) - CWalletDB(strWalletFile).EraseTx(hash); - LogPrintf("%s: Erased wtx %s from wallet\n", __func__, hash.GetHex()); + return CWalletDB(strWalletFile).EraseTx(hash); } - return; + return false; } @@ -1852,8 +1851,7 @@ void CWallet::DeleteTransactions(std::vector &removeTxs) CWalletDB walletdb(strWalletFile, "r+", false); for (int i = 0; i< removeTxs.size(); i++) { - if (mapWallet.erase(removeTxs[i])) { - walletdb.EraseTx(removeTxs[i]); + if (EraseFromWallet(removeTxs[i])) { LogPrint(BCLog::DELETETX,"DeleteTx - Deleting tx %s, %i.\n", removeTxs[i].ToString(),i); } else { LogPrint(BCLog::DELETETX,"DeleteTx - Deleting tx %failed.\n", removeTxs[i].ToString()); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b8baefca2f..5a00833b33 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -476,7 +476,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); void SyncTransaction(const CTransaction& tx, const CBlock* pblock); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate); - void EraseFromWallet(const uint256& hash); + bool EraseFromWallet(const uint256& hash); void ReorderWalletTransactions(std::map, CWalletTx*> &mapSorted, int64_t &maxOrderPos); void UpdateWalletTransactionOrder(std::map, CWalletTx*> &mapSorted, bool resetOrder); void DeleteTransactions(std::vector &removeTxs); From f3253c8cb6840b7600c9119a9bf0e0e4ce1a3f0c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 20 Feb 2023 11:40:30 -0500 Subject: [PATCH 265/391] Remove from spend maps --- src/wallet/wallet.cpp | 23 +++++++++++++++++++++++ src/wallet/wallet.h | 1 + 2 files changed, 24 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 69f560474b..7331b720f8 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1767,6 +1767,25 @@ bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb) return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this); } +void CWallet::RemoveFromSpends(const uint256& wtxid) +{ + if (mapTxSpends.size() > 0) + { + std::multimap::const_iterator itr = mapTxSpends.cbegin(); + while (itr != mapTxSpends.cend()) + { + if (itr->second == wtxid) + { + itr = mapTxSpends.erase(itr); + } + else + { + ++itr; + } + } + } +} + /** * Reorder the transactions based on block hieght and block index. * Transactions can get out of order when they are deleted and subsequently @@ -1851,7 +1870,11 @@ void CWallet::DeleteTransactions(std::vector &removeTxs) CWalletDB walletdb(strWalletFile, "r+", false); for (int i = 0; i< removeTxs.size(); i++) { + bool fRemoveFromSpends = !(mapWallet.at(removeTxs[i]).IsCoinBase()); if (EraseFromWallet(removeTxs[i])) { + if (fRemoveFromSpends) { + RemoveFromSpends(removeTxs[i]); + } LogPrint(BCLog::DELETETX,"DeleteTx - Deleting tx %s, %i.\n", removeTxs[i].ToString(),i); } else { LogPrint(BCLog::DELETETX,"DeleteTx - Deleting tx %failed.\n", removeTxs[i].ToString()); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 5a00833b33..9dd118308b 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -268,6 +268,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface TxSpends mapTxSpends; void AddToSpends(const COutPoint& outpoint, const uint256& wtxid); void AddToSpends(const uint256& wtxid); + void RemoveFromSpends(const uint256& wtxid); void SyncMetaData(std::pair); From 9315759dfd6832f34a32668da1cdcfea6a7f6b86 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 7 Jun 2023 09:15:17 -0400 Subject: [PATCH 266/391] DeleteTx updates includes: - fix GetSpendDepth - keep running DeleteWalletTransactions until no more can be deleted - updated thread locks - update RPC to return initial, new, deleted utxo_count --- src/init.cpp | 2 +- src/wallet/rpcwallet.cpp | 16 +++++++-- src/wallet/wallet.cpp | 75 +++++++++++++++++++++++++++++----------- src/wallet/wallet.h | 4 +-- 4 files changed, 72 insertions(+), 25 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index b4736fdab3..cab4c9e07e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1674,7 +1674,7 @@ bool AppInit2(bool isDaemon) //Sort Transactions by block and block index, then reorder LOCK2(cs_main, pwalletMain->cs_wallet); if (chainActive.Tip()) { - LogPrintf("Runnning transaction reorder\n"); + LogPrintf("Running transaction reorder\n"); int64_t maxOrderPos = 0; std::map, CWalletTx*> mapSorted; pwalletMain->ReorderWalletTransactions(mapSorted, maxOrderPos); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 97e2b22733..27f6912090 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3093,11 +3093,23 @@ UniValue erasewallettransactions(const UniValue& params, bool fHelp) { EnsureWallet(); EnsureWalletIsUnlocked(); + LOCK2(cs_main, pwalletMain->cs_wallet); + CBlockIndex* pindex = chainActive.Tip(); + int initialCount = (int)pwalletMain->mapWallet.size(); + int newCount, removedTxes = 0; - pwalletMain->DeleteWalletTransactions(pindex); + pwalletMain->DeleteWalletTransactions(pindex, false); - return "Done"; + newCount = (int)pwalletMain->mapWallet.size(); + removedTxes = initialCount - newCount; + + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("initial_utxo_count", initialCount)); + ret.push_back(Pair("new_utxo_count", newCount)); + ret.push_back(Pair("deleted_utxo_count", removedTxes)); + + return ret; } UniValue revealmnemonicphrase(const UniValue& params, bool fHelp) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 7331b720f8..008ea8e5a5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -895,6 +895,17 @@ unsigned int CWallet::GetSpendDepth(const uint256& hash, unsigned int n) const if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) return mit->second.GetDepthInMainChain(); // Spent } + + std::string outString = outpoint.hash.GetHex() + std::to_string(outpoint.n); + CKeyImage ki = outpointToKeyImages[outString]; + if (IsSpentKeyImage(ki.GetHex(), UINT256_ZERO)) { + std::string kiHex = ki.GetHex(); + int confirmations = 0; + if (CheckKeyImageSpendInMainChain(kiHex, confirmations)) { + return confirmations; // Spent + } + } + return 0; } @@ -1793,22 +1804,29 @@ void CWallet::RemoveFromSpends(const uint256& wtxid) */ void CWallet::ReorderWalletTransactions(std::map, CWalletTx*> &mapSorted, int64_t &maxOrderPos) { - LOCK2(cs_main, cs_wallet); + AssertLockHeld(cs_main); + AssertLockHeld(cs_wallet); int maxSortNumber = chainActive.Tip()->nHeight + 1; for (std::map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { CWalletTx* pwtx = &(it->second); - int confirms = pwtx->GetDepthInMainChain(); maxOrderPos = std::max(maxOrderPos, pwtx->nOrderPos); - if (confirms > 0) { - int wtxHeight = mapBlockIndex[pwtx->hashBlock]->nHeight; - auto key = std::make_pair(wtxHeight, pwtx->nIndex); - mapSorted.insert(make_pair(key, pwtx)); - } - else { + if (mapBlockIndex.count(pwtx->hashBlock) > 0) { + auto blockIndex = mapBlockIndex[pwtx->hashBlock]; + if (blockIndex) { + int wtxHeight = blockIndex->nHeight; + auto key = std::make_pair(wtxHeight, pwtx->nIndex); + mapSorted.insert(make_pair(key, pwtx)); + } else { + // handle null blockIndex + auto key = std::make_pair(maxSortNumber, 0); + mapSorted.insert(std::make_pair(key, pwtx)); + maxSortNumber++; + } + } else { auto key = std::make_pair(maxSortNumber, 0); mapSorted.insert(std::make_pair(key, pwtx)); maxSortNumber++; @@ -1821,7 +1839,8 @@ void CWallet::ReorderWalletTransactions(std::map, CWalletTx*> */ void CWallet::UpdateWalletTransactionOrder(std::map, CWalletTx*> &mapSorted, bool resetOrder) { - LOCK2(cs_main, cs_wallet); + AssertLockHeld(cs_main); + AssertLockHeld(cs_wallet); int64_t previousPosition = 0; std::map mapUpdatedTxs; @@ -1857,19 +1876,23 @@ void CWallet::UpdateWalletTransactionOrder(std::map, CWalletT nOrderPosNext = previousPosition++; CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext); LogPrint(BCLog::DELETETX,"Reorder Tx - Total Transactions Reordered %i, Next Position %i\n", mapUpdatedTxs.size(), nOrderPosNext); - } /** * Delete transactions from the Wallet */ -void CWallet::DeleteTransactions(std::vector &removeTxs) +bool CWallet::DeleteTransactions(std::vector &removeTxs, bool fRescan) { - LOCK(cs_wallet); + AssertLockHeld(cs_wallet); + + bool removingTransactions = false; + if (removeTxs.size() > 0) { + removingTransactions = true; + } CWalletDB walletdb(strWalletFile, "r+", false); - for (int i = 0; i< removeTxs.size(); i++) { + for (int i = 0; i < removeTxs.size(); i++) { bool fRemoveFromSpends = !(mapWallet.at(removeTxs[i]).IsCoinBase()); if (EraseFromWallet(removeTxs[i])) { if (fRemoveFromSpends) { @@ -1877,8 +1900,8 @@ void CWallet::DeleteTransactions(std::vector &removeTxs) } LogPrint(BCLog::DELETETX,"DeleteTx - Deleting tx %s, %i.\n", removeTxs[i].ToString(),i); } else { - LogPrint(BCLog::DELETETX,"DeleteTx - Deleting tx %failed.\n", removeTxs[i].ToString()); - return; + LogPrint(BCLog::DELETETX,"DeleteTx - Deleting tx %s failed.\n", removeTxs[i].ToString()); + return false; } } @@ -1886,18 +1909,21 @@ void CWallet::DeleteTransactions(std::vector &removeTxs) #ifdef __linux__ malloc_trim(0); #endif + + return removingTransactions; } -void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) +bool CWallet::DeleteWalletTransactions(const CBlockIndex* pindex, bool fRescan) { - LOCK2(cs_main, cs_wallet); + AssertLockHeld(cs_main); + AssertLockHeld(cs_wallet); int nDeleteAfter = (int)fDeleteTransactionsAfterNBlocks; bool runCompact = false; + bool deletedTransactions = false; auto startTime = GetTime(); if (pindex && fTxDeleteEnabled) { - //Check for acentries - exit function if found { std::list acentries; @@ -1905,7 +1931,7 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) walletdb.ListAccountCreditDebit("*", acentries); if (acentries.size() > 0) { LogPrintf("deletetx not compatible to account entries\n"); - return; + return false; } } //delete transactions @@ -2017,7 +2043,7 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) LogPrint(BCLog::DELETETX,"DeleteTx - Time to Select %s\n", DateTimeStrFormat("%H:%M:%S", selectTime - reorderTime)); //Delete Transactions from wallet - DeleteTransactions(removeTxs); + deletedTransactions = DeleteTransactions(removeTxs, fRescan); auto deleteTime = GetTime(); LogPrint(BCLog::DELETETX,"DeleteTx - Time to Delete %s\n", DateTimeStrFormat("%H:%M:%S", deleteTime - selectTime)); @@ -2030,6 +2056,8 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) auto totalTime = GetTime(); LogPrint(BCLog::DELETETX,"DeleteTx - Time to Run Total Function %s\n", DateTimeStrFormat("%H:%M:%S", totalTime - startTime)); } + + return deletedTransactions; } /** @@ -2072,6 +2100,11 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate, b if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) ret++; } + + //Delete Transactions + if (pindex->nHeight % fDeleteInterval == 0) + while(DeleteWalletTransactions(pindex, true)) {} + pindex = chainActive.Next(pindex); if (GetTime() >= nNow + 60) { nNow = GetTime(); @@ -2083,6 +2116,8 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate, b } } ShowProgress(_("Rescanning... Please do not interrupt this process as it could lead to a corrupt wallet."), 100); // hide progress dialog in GUI + //Delete transactions + while(DeleteWalletTransactions(chainActive.Tip(), true)) {} } return ret; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 9dd118308b..7b585a2df0 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -480,8 +480,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool EraseFromWallet(const uint256& hash); void ReorderWalletTransactions(std::map, CWalletTx*> &mapSorted, int64_t &maxOrderPos); void UpdateWalletTransactionOrder(std::map, CWalletTx*> &mapSorted, bool resetOrder); - void DeleteTransactions(std::vector &removeTxs); - void DeleteWalletTransactions(const CBlockIndex* pindex); + bool DeleteTransactions(std::vector &removeTxs, bool fRescan = false); + bool DeleteWalletTransactions(const CBlockIndex* pindex, bool fRescan = false); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false, bool fromStartup = false, int height = -1); void ReacceptWalletTransactions(); void ResendWalletTransactions(); From 8ff6cc7452aea26325fe3269fe775287cb517cd8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 22 Jun 2023 18:29:25 -0400 Subject: [PATCH 267/391] qt: fix fee copy in RevealTxDialog --- src/qt/revealtxdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/revealtxdialog.cpp b/src/qt/revealtxdialog.cpp index 9440741b7a..748055ab9a 100644 --- a/src/qt/revealtxdialog.cpp +++ b/src/qt/revealtxdialog.cpp @@ -82,7 +82,7 @@ void RevealTxDialog::setTxAmount(QString amount) void RevealTxDialog::setTxFee(CAmount fee) { int nDisplayUnit; - ui->lblTxFee->setText(BitcoinUnits::formatHtmlWithUnit(0, fee, false, BitcoinUnits::separatorAlways)); + ui->lblTxFee->setText(BitcoinUnits::format(nDisplayUnit, fee, false, BitcoinUnits::separatorAlways)); } void RevealTxDialog::setTxPaymentID(uint64_t paymentID) From 983f25d133535f1787e2bfdfcd9306aa6a1388d5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 23 Jun 2023 11:01:59 -0400 Subject: [PATCH 268/391] qt: adjust setTxAmount to use CAmount --- src/qt/historypage.cpp | 10 +++++++++- src/qt/revealtxdialog.cpp | 4 ++-- src/qt/revealtxdialog.h | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/qt/historypage.cpp b/src/qt/historypage.cpp index 2662aaee78..311ea7985e 100644 --- a/src/qt/historypage.cpp +++ b/src/qt/historypage.cpp @@ -103,7 +103,15 @@ void HistoryPage::on_cellClicked(int row, int column) QString address = cell->data(0).toString(); //3 is column index for amount cell = ui->tableView->item(row, 3); - QString amount = cell->data(0).toString(); + QString amountQString = cell->data(0).toString(); + + // Remove any sequence of whitespace with a single space and remove spaces + amountQString = amountQString.simplified(); + amountQString.remove(' '); + + double amountDouble = amountQString.toDouble(); + CAmount amount = static_cast(amountDouble * COIN); + std::string stdAddress = address.trimmed().toStdString(); if (pwalletMain->addrToTxHashMap.count(stdAddress) == 1) { RevealTxDialog txdlg; diff --git a/src/qt/revealtxdialog.cpp b/src/qt/revealtxdialog.cpp index 748055ab9a..dfd2aa1473 100644 --- a/src/qt/revealtxdialog.cpp +++ b/src/qt/revealtxdialog.cpp @@ -73,10 +73,10 @@ void RevealTxDialog::setTxPrivKey(QString strPrivKey) ui->lblPrivateKey->setText(strPrivKey); } -void RevealTxDialog::setTxAmount(QString amount) +void RevealTxDialog::setTxAmount(CAmount amount) { int nDisplayUnit; - ui->lblTxAmount->setText(amount.append(" PRCY")); + ui->lblTxAmount->setText(BitcoinUnits::format(nDisplayUnit, amount, false, BitcoinUnits::separatorAlways)); } void RevealTxDialog::setTxFee(CAmount fee) diff --git a/src/qt/revealtxdialog.h b/src/qt/revealtxdialog.h index d93acba055..9c878c88bc 100644 --- a/src/qt/revealtxdialog.h +++ b/src/qt/revealtxdialog.h @@ -22,7 +22,7 @@ class RevealTxDialog : public QDialog void setTxID(QString strId); void setTxAddress(QString strAddr); void setTxPrivKey(QString strPrivKey); - void setTxAmount(QString amount); + void setTxAmount(CAmount amount); void setTxFee(CAmount fee); void setTxPaymentID(uint64_t paymentID); void setTxRingSize(int64_t ringSize); From 8e0f2421de3c488deb98e377352eec3744b81a17 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 23 Jun 2023 11:03:32 -0400 Subject: [PATCH 269/391] qt: improve on_cellClicked for HistoryPage - comments - efficiency - readability --- src/qt/historypage.cpp | 125 ++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 64 deletions(-) diff --git a/src/qt/historypage.cpp b/src/qt/historypage.cpp index 311ea7985e..9aefb353fa 100644 --- a/src/qt/historypage.cpp +++ b/src/qt/historypage.cpp @@ -94,15 +94,12 @@ void HistoryPage::connectWidgets() //add functions to widget signals void HistoryPage::on_cellClicked(int row, int column) { if (pwalletMain->IsLocked()) return; - //1 is column index for type - QTableWidgetItem* cell = ui->tableView->item(row, 1); - QString type = cell->data(0).toString(); - std::string stdType = type.trimmed().toStdString(); - //2 is column index for address - cell = ui->tableView->item(row, 2); - QString address = cell->data(0).toString(); - //3 is column index for amount - cell = ui->tableView->item(row, 3); + + // Get cell data and convert QString to std::string + std::string type = ui->tableView->item(row, 1)->data(0).toString().trimmed().toStdString(); + std::string address = ui->tableView->item(row, 2)->data(0).toString().trimmed().toStdString(); + + QTableWidgetItem* cell = ui->tableView->item(row, 3); //3 is column index for amount QString amountQString = cell->data(0).toString(); // Remove any sequence of whitespace with a single space and remove spaces @@ -112,69 +109,69 @@ void HistoryPage::on_cellClicked(int row, int column) double amountDouble = amountQString.toDouble(); CAmount amount = static_cast(amountDouble * COIN); - std::string stdAddress = address.trimmed().toStdString(); - if (pwalletMain->addrToTxHashMap.count(stdAddress) == 1) { - RevealTxDialog txdlg; - txdlg.setStyleSheet(GUIUtil::loadStyleSheet()); - - txdlg.setTxID(pwalletMain->addrToTxHashMap[stdAddress].c_str()); - - txdlg.setTxAddress(stdAddress.c_str()); - bool privkeyFound = false; - std::string txHash = pwalletMain->addrToTxHashMap[stdAddress]; - if (IsHex(txHash)) { - uint256 hash; - hash.SetHex(txHash); - - if (pwalletMain && pwalletMain->mapWallet.count(hash) == 1) { - CWalletTx tx = pwalletMain->mapWallet[hash]; - for (size_t i = 0; i < tx.vout.size(); i++) { - txnouttype type; - std::vector addresses; - int nRequired; - - if (ExtractDestinations(tx.vout[i].scriptPubKey, type, addresses, nRequired)) { - std::string parseddAddress = CBitcoinAddress(addresses[0]).ToString(); - if (stdAddress == parseddAddress) { - if (tx.IsCoinStake() && !tx.vout[i].txPriv.empty()) { - CKey txPriv; - txPriv.Set(tx.vout[i].txPriv.begin(), tx.vout[i].txPriv.end(), true); - txdlg.setTxPrivKey(CBitcoinSecret(txPriv).ToString().c_str()); + // Check if address exists in the hash map + auto it = pwalletMain->addrToTxHashMap.find(address); + if (it == pwalletMain->addrToTxHashMap.end()) return; + + // Create transaction dialog + RevealTxDialog txdlg; + txdlg.setStyleSheet(GUIUtil::loadStyleSheet()); + txdlg.setTxID(it->second.c_str()); + txdlg.setTxAddress(address.c_str()); + + // Retrieve transaction details + bool privkeyFound = false; + std::string txHash = it->second; + if (IsHex(txHash)) { + uint256 hash; + hash.SetHex(txHash); + + if (pwalletMain && pwalletMain->mapWallet.count(hash) == 1) { + CWalletTx tx = pwalletMain->mapWallet[hash]; + for (size_t i = 0; i < tx.vout.size(); i++) { + txnouttype type; + std::vector addresses; + int nRequired; + + if (ExtractDestinations(tx.vout[i].scriptPubKey, type, addresses, nRequired)) { + std::string parsedAddress = CBitcoinAddress(addresses[0]).ToString(); + if (address == parsedAddress) { + if (tx.IsCoinStake() && !tx.vout[i].txPriv.empty()) { + CKey txPriv; + txPriv.Set(tx.vout[i].txPriv.begin(), tx.vout[i].txPriv.end(), true); + txdlg.setTxPrivKey(CBitcoinSecret(txPriv).ToString().c_str()); + privkeyFound = true; + } else { + std::string key = txHash + std::to_string(i); + std::string secret; + if (CWalletDB(pwalletMain->strWalletFile).ReadTxPrivateKey(key, secret)) { + txdlg.setTxPrivKey(secret.c_str()); privkeyFound = true; - } else { - std::string key = txHash + std::to_string(i); - std::string secret; - if (CWalletDB(pwalletMain->strWalletFile).ReadTxPrivateKey(key, secret)) { - txdlg.setTxPrivKey(secret.c_str()); - privkeyFound = true; - } } } } } - txdlg.setTxAmount(amount); - txdlg.setTxFee(tx.nTxFee); - if (tx.hasPaymentID) { - txdlg.setTxPaymentID(tx.paymentID); - } else { - txdlg.setTxPaymentID(0); - } - txdlg.setTxRingSize(tx.vin[0].decoys.size() + 1); } + txdlg.setTxAmount(amount); + txdlg.setTxFee(tx.nTxFee); + if (tx.hasPaymentID) { + txdlg.setTxPaymentID(tx.paymentID); + } else { + txdlg.setTxPaymentID(0); + } + txdlg.setTxRingSize(tx.vin[0].decoys.size() + 1); } - std::string txdlgMsg = "Request from Sender (if applicable)"; - if (stdType == "Minted") { - privkeyFound = false; - txdlgMsg = "Minted transactions do not have a PrivKey"; - } - if (pwalletMain->IsLocked()) { - privkeyFound = false; - txdlgMsg = "Wallet must be unlocked to view PrivKey"; - } - if (!privkeyFound) txdlg.setTxPrivKey(std::string(txdlgMsg).c_str()); - - txdlg.exec(); } + // Determine message to display in case private key is not found + std::string txdlgMsg = "Request from Sender (if applicable)"; + if (type == "Minted") { + privkeyFound = false; + txdlgMsg = "Minted transactions do not have a PrivKey"; + } + if (!privkeyFound) txdlg.setTxPrivKey(std::string(txdlgMsg).c_str()); + + // Show dialog + txdlg.exec(); } void HistoryPage::resizeEvent(QResizeEvent* event) From eab71dac5842fb342b79db4e642da956f234c82a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 23 Jun 2023 12:11:07 -0400 Subject: [PATCH 270/391] qt: improve RevealTxDialog UI - add block height/hash - move buttons to the right side - use groupboxes - simplify code for signal/slots of the buttons --- src/qt/forms/revealtxdialog.ui | 785 +++++++++++++++++++-------------- src/qt/historypage.cpp | 19 +- src/qt/revealtxdialog.cpp | 104 +++-- src/qt/revealtxdialog.h | 6 + 4 files changed, 557 insertions(+), 357 deletions(-) diff --git a/src/qt/forms/revealtxdialog.ui b/src/qt/forms/revealtxdialog.ui index 51ae940796..620739e389 100644 --- a/src/qt/forms/revealtxdialog.ui +++ b/src/qt/forms/revealtxdialog.ui @@ -7,7 +7,7 @@ 0 0 750 - 290 + 402 @@ -15,333 +15,470 @@ - - - - - Copy transaction ID to clipboard - - - - - - - - - - - 83 - 0 - - - - TxId - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - - - - - - - - - - - - - - - Copy address to clipboard - - - - - - - - - - - 83 - 0 - - - - Address - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - - - - - - - - Copy transaction private key to clipboard - - - - - - - - - - - 83 - 0 - - - - PrivKey - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - - - - - - - - Copy Transaction Amount to clipboard - - - - - - - - - - - 83 - 0 - - - - Amount - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - - - - - - - - Copy Transaction Fee to clipboard - - - - - - - - - - - 83 - 0 - - - - Fee - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - + + + Transaction Details + + + + + + + + + 83 + 0 + + + + TXID: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + + + + + + + + Copy transaction ID to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Address: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy address to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Private Key: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy transaction private key to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Amount: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy Transaction Amount to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Fee: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy Transaction Fee to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Ring Size: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy Payment ID to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Payment ID: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy Payment ID to clipboard + + + + + + + + + + - - - - - Copy Payment ID to clipboard - - - - - - - - - - - 83 - 0 - - - - Ring Size - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - + + + In Block: + + + + + + + + + 83 + 0 + + + + Height: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + + + + + + + + Copy address to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Hash: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + + + + + + + + Copy address to clipboard + + + + + + + + + + - - - - - Copy Payment ID to clipboard - - - - - - - - - - - 83 - 0 - - - - Payment ID - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - + + + Qt::Horizontal + + + + 40 + 20 + + + diff --git a/src/qt/historypage.cpp b/src/qt/historypage.cpp index 9aefb353fa..08c259f2c4 100644 --- a/src/qt/historypage.cpp +++ b/src/qt/historypage.cpp @@ -160,13 +160,30 @@ void HistoryPage::on_cellClicked(int row, int column) txdlg.setTxPaymentID(0); } txdlg.setTxRingSize(tx.vin[0].decoys.size() + 1); + + // Get block index object using block hash + BlockMap::iterator it = mapBlockIndex.find(tx.hashBlock); + if (it != mapBlockIndex.end()) { + CBlockIndex* pindex = it->second; + + // Get block height + int blockHeight = pindex->nHeight; + txdlg.setBlockHeight(blockHeight); + + // Get block hash + uint256 blockHash = *pindex->phashBlock; + txdlg.setBlockHash(blockHash.ToString().c_str()); + } else { + txdlg.setBlockHeight(-1); + txdlg.setBlockHash("Not in block"); + } } } // Determine message to display in case private key is not found std::string txdlgMsg = "Request from Sender (if applicable)"; if (type == "Minted") { privkeyFound = false; - txdlgMsg = "Minted transactions do not have a PrivKey"; + txdlgMsg = "Minted transactions do not have a Private Key"; } if (!privkeyFound) txdlg.setTxPrivKey(std::string(txdlgMsg).c_str()); diff --git a/src/qt/revealtxdialog.cpp b/src/qt/revealtxdialog.cpp index dfd2aa1473..48df507fe3 100644 --- a/src/qt/revealtxdialog.cpp +++ b/src/qt/revealtxdialog.cpp @@ -17,38 +17,7 @@ RevealTxDialog::RevealTxDialog(QWidget *parent) : { ui->setupUi(this); - ui->pushButtonCopyID->setStyleSheet("background:transparent;"); - ui->pushButtonCopyID->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyID, SIGNAL(clicked()), this, SLOT(copyID())); - - ui->pushButtonCopyAddr->setStyleSheet("background:transparent;"); - ui->pushButtonCopyAddr->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyAddr, SIGNAL(clicked()), this, SLOT(copyAddress())); - - ui->pushButtonCopyPrivKey->setStyleSheet("background:transparent;"); - ui->pushButtonCopyPrivKey->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyPrivKey, SIGNAL(clicked()), this, SLOT(copyPrivateKey())); - - ui->pushButtonCopyTxAmount->setStyleSheet("background:transparent;"); - ui->pushButtonCopyTxAmount->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyTxAmount, SIGNAL(clicked()), this, SLOT(copyTxAmount())); - - ui->pushButtonCopyTxFee->setStyleSheet("background:transparent;"); - ui->pushButtonCopyTxFee->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyTxFee, SIGNAL(clicked()), this, SLOT(copyTxFee())); - - ui->pushButtonCopyTxPaymentID->setStyleSheet("background:transparent;"); - ui->pushButtonCopyTxPaymentID->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyTxPaymentID, SIGNAL(clicked()), this, SLOT(copyTxPaymentID())); - - ui->pushButtonCopyTxRingSize->setStyleSheet("background:transparent;"); - ui->pushButtonCopyTxRingSize->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyTxRingSize, SIGNAL(clicked()), this, SLOT(copyTxRingSize())); - - ui->pushButtonOpenTXID->setStyleSheet("background:transparent;"); - ui->pushButtonOpenTXID->setIcon(QIcon(":/icons/eye")); - connect(ui->pushButtonOpenTXID, SIGNAL(clicked()), this, SLOT(openTXinExplorer())); - + setupButtons(); ui->buttonBox->button(QDialogButtonBox::Reset)->setText("Delete Transaction?"); connect(ui->buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), this, SLOT(deleteTransaction())); } @@ -58,6 +27,45 @@ RevealTxDialog::~RevealTxDialog() delete ui; } +struct ButtonInfo +{ + QString name; + void (RevealTxDialog::*slot)(); +}; + +void RevealTxDialog::setupButtons() +{ + std::vector buttons = { + {"pushButtonCopyID", &RevealTxDialog::copyID}, + {"pushButtonCopyAddr", &RevealTxDialog::copyAddress}, + {"pushButtonCopyPrivKey", &RevealTxDialog::copyPrivateKey}, + {"pushButtonCopyTxAmount", &RevealTxDialog::copyTxAmount}, + {"pushButtonCopyTxFee", &RevealTxDialog::copyTxFee}, + {"pushButtonCopyTxPaymentID", &RevealTxDialog::copyTxPaymentID}, + {"pushButtonCopyTxRingSize", &RevealTxDialog::copyTxRingSize}, + {"pushButtonOpenTXID", &RevealTxDialog::openTXinExplorer}, + {"pushButtonCopyBlockHash", &RevealTxDialog::copyBlockHash}, + {"pushButtonCopyBlockHeight", &RevealTxDialog::copyBlockHeight}, + {"pushButtonOpenBlock", &RevealTxDialog::openBlockInExplorer}, + {"pushButtonOpenBlock1", &RevealTxDialog::openBlockInExplorer}, + }; + + for(const auto& button : buttons) + { + QPushButton *pushButton = this->findChild(button.name); + if(pushButton != nullptr) + { + pushButton->setStyleSheet("background:transparent;"); + if(button.name == "pushButtonOpenTXID" || button.name == "pushButtonOpenBlock" || button.name == "pushButtonOpenBlock1") { + pushButton->setIcon(QIcon(":/icons/eye")); + } else { + pushButton->setIcon(QIcon(":/icons/editcopy")); + } + connect(pushButton, &QPushButton::clicked, this, button.slot); + } + } +} + void RevealTxDialog::setTxID(QString strId) { ui->lblTxID->setText(strId); @@ -100,6 +108,16 @@ void RevealTxDialog::setTxRingSize(int64_t ringSize) ui->lblTxRingSize->setText(QString::number(ringSize)); } +void RevealTxDialog::setBlockHeight(int blockHeight) +{ + ui->lblBlockHeight->setText(QString::number(blockHeight)); +} + +void RevealTxDialog::setBlockHash(QString blockHash) +{ + ui->lblBlockHash->setText(blockHash); +} + void RevealTxDialog::on_buttonBox_accepted() { //We currently don't do anything on accept @@ -140,6 +158,16 @@ void RevealTxDialog::copyTxRingSize(){ clipboard->setText(ui->lblTxRingSize->text()); } +void RevealTxDialog::copyBlockHeight(){ + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(ui->lblBlockHeight->text()); +} + +void RevealTxDialog::copyBlockHash(){ + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(ui->lblBlockHash->text()); +} + void RevealTxDialog::openTXinExplorer() { QString URL; @@ -152,6 +180,18 @@ void RevealTxDialog::openTXinExplorer() QDesktopServices::openUrl(QUrl(URL.append(ui->lblTxID->text()))); } +void RevealTxDialog::openBlockInExplorer() +{ + QString URL; + // Adjust link depending on Network + if (Params().NetworkID() == CBaseChainParams::MAIN) { + URL = "https://explorer.prcycoin.com/block/"; + } else if (Params().NetworkID() == CBaseChainParams::TESTNET){ + URL = "https://testnet.prcycoin.com/block/"; + } + QDesktopServices::openUrl(QUrl(URL.append(ui->lblBlockHash->text()))); +} + void RevealTxDialog::deleteTransaction() { bool hideSuccess = settings.value("fHideDeleteSuccess", false).toBool(); diff --git a/src/qt/revealtxdialog.h b/src/qt/revealtxdialog.h index 9c878c88bc..927c2cf94e 100644 --- a/src/qt/revealtxdialog.h +++ b/src/qt/revealtxdialog.h @@ -19,6 +19,7 @@ class RevealTxDialog : public QDialog explicit RevealTxDialog(QWidget *parent = 0); ~RevealTxDialog(); + void setupButtons(); void setTxID(QString strId); void setTxAddress(QString strAddr); void setTxPrivKey(QString strPrivKey); @@ -26,6 +27,8 @@ class RevealTxDialog : public QDialog void setTxFee(CAmount fee); void setTxPaymentID(uint64_t paymentID); void setTxRingSize(int64_t ringSize); + void setBlockHeight(int blockheight); + void setBlockHash(QString blockHash); private Q_SLOTS: void on_buttonBox_accepted(); @@ -36,7 +39,10 @@ private Q_SLOTS: void copyTxFee(); void copyTxPaymentID(); void copyTxRingSize(); + void copyBlockHash(); + void copyBlockHeight(); void openTXinExplorer(); + void openBlockInExplorer(); void deleteTransaction(); private: From 0388d0d3e4b2df4becbf9872080dc81a19a9aba1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 25 Jun 2023 19:28:29 -0400 Subject: [PATCH 271/391] scripted-diff: Use UniValue.pushKV instead of push_back(Pair()) -BEGIN VERIFY SCRIPT- git grep -l "push_back(Pair" | xargs sed -i "s/push_back(Pair(\(.*\)));/pushKV(\1);/g" -END VERIFY SCRIPT- --- src/rest.cpp | 16 +-- src/rpc/blockchain.cpp | 212 +++++++++++++++++------------------ src/rpc/budget.cpp | 210 +++++++++++++++++------------------ src/rpc/masternode.cpp | 174 ++++++++++++++--------------- src/rpc/mining.cpp | 136 +++++++++++------------ src/rpc/misc.cpp | 144 ++++++++++++------------ src/rpc/net.cpp | 100 ++++++++--------- src/rpc/protocol.cpp | 18 +-- src/rpc/rawtransaction.cpp | 148 ++++++++++++------------- src/wallet/rpcdump.cpp | 10 +- src/wallet/rpcwallet.cpp | 220 ++++++++++++++++++------------------- 11 files changed, 694 insertions(+), 694 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index 5367ee5282..eb35962e7e 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -550,24 +550,24 @@ static bool rest_getutxos(HTTPRequest *req, const std::string &strURIPart) { // pack in some essentials // use more or less the same output as mentioned in Bip64 - objGetUTXOResponse.push_back(Pair("chainHeight", chainActive.Height())); - objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex())); - objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation)); + objGetUTXOResponse.pushKV("chainHeight", chainActive.Height()); + objGetUTXOResponse.pushKV("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex()); + objGetUTXOResponse.pushKV("bitmap", bitmapStringRepresentation); UniValue utxos(UniValue::VARR); for ( const CCoin &coin : outs) { UniValue utxo(UniValue::VOBJ); - utxo.push_back(Pair("txvers", (int32_t) coin.nTxVer)); - utxo.push_back(Pair("height", (int32_t) coin.nHeight)); - utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue))); + utxo.pushKV("txvers", (int32_t) coin.nTxVer); + utxo.pushKV("height", (int32_t) coin.nHeight); + utxo.pushKV("value", ValueFromAmount(coin.out.nValue)); // include the script in a json output UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true); - utxo.push_back(Pair("scriptPubKey", o)); + utxo.pushKV("scriptPubKey", o); utxos.push_back(utxo); } - objGetUTXOResponse.push_back(Pair("utxos", utxos)); + objGetUTXOResponse.pushKV("utxos", utxos); // return json string std::string strJSON = objGetUTXOResponse.write() + "\n"; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a0e4aec12e..eae5b7cabd 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -67,45 +67,45 @@ double GetDifficulty(const CBlockIndex* blockindex) UniValue blockheaderToJSON(const CBlockIndex* blockindex) { UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); + result.pushKV("hash", blockindex->GetBlockHash().GetHex()); int confirmations = -1; // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", confirmations)); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", blockindex->nVersion)); - result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); - result.push_back(Pair("time", (int64_t)blockindex->nTime)); - result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); - result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce)); - result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); - result.push_back(Pair("acc_checkpoint", blockindex->nAccumulatorCheckpoint.GetHex())); + result.pushKV("confirmations", confirmations); + result.pushKV("height", blockindex->nHeight); + result.pushKV("version", blockindex->nVersion); + result.pushKV("merkleroot", blockindex->hashMerkleRoot.GetHex()); + result.pushKV("time", (int64_t)blockindex->nTime); + result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast()); + result.pushKV("nonce", (uint64_t)blockindex->nNonce); + result.pushKV("bits", strprintf("%08x", blockindex->nBits)); + result.pushKV("difficulty", GetDifficulty(blockindex)); + result.pushKV("chainwork", blockindex->nChainWork.GetHex()); + result.pushKV("acc_checkpoint", blockindex->nAccumulatorCheckpoint.GetHex()); if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()); CBlockIndex *pnext = chainActive.Next(blockindex); if (pnext) - result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); return result; } UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", block.GetHash().GetHex())); + result.pushKV("hash", block.GetHash().GetHex()); int confirmations = -1; // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", confirmations)); - result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", block.nVersion)); - result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); - result.push_back(Pair("acc_checkpoint", block.nAccumulatorCheckpoint.GetHex())); + result.pushKV("confirmations", confirmations); + result.pushKV("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)); + result.pushKV("height", blockindex->nHeight); + result.pushKV("version", block.nVersion); + result.pushKV("merkleroot", block.hashMerkleRoot.GetHex()); + result.pushKV("acc_checkpoint", block.nAccumulatorCheckpoint.GetHex()); UniValue txs(UniValue::VARR); for (const CTransaction& tx : block.vtx) { if (txDetails) { @@ -115,23 +115,23 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx } else txs.push_back(tx.GetHash().GetHex()); } - result.push_back(Pair("tx", txs)); - result.push_back(Pair("time", block.GetBlockTime())); - result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); - result.push_back(Pair("nonce", (uint64_t)block.nNonce)); - result.push_back(Pair("bits", strprintf("%08x", block.nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + result.pushKV("tx", txs); + result.pushKV("time", block.GetBlockTime()); + result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast()); + result.pushKV("nonce", (uint64_t)block.nNonce); + result.pushKV("bits", strprintf("%08x", block.nBits)); + result.pushKV("difficulty", GetDifficulty(blockindex)); + result.pushKV("chainwork", blockindex->nChainWork.GetHex()); if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()); CBlockIndex* pnext = chainActive.Next(blockindex); if (pnext) - result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); - result.push_back(Pair("modifier", strprintf("%016x", blockindex->nStakeModifier))); + result.pushKV("modifier", strprintf("%016x", blockindex->nStakeModifier)); - result.push_back(Pair("moneysupply",ValueFromAmount(blockindex->nMoneySupply))); + result.pushKV("moneysupply",ValueFromAmount(blockindex->nMoneySupply)); std::string minetype = "PoW"; if (blockindex->IsProofOfStake()) { minetype = "PoS"; @@ -139,12 +139,12 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx minetype = "PoA"; } - result.push_back(Pair("minetype", minetype)); + result.pushKV("minetype", minetype); if (blockindex->IsProofOfAudit()) { //This is a PoA block //Read information of PoS blocks audited by this PoA block - result.push_back(Pair("previouspoahash", block.hashPrevPoABlock.GetHex())); + result.pushKV("previouspoahash", block.hashPrevPoABlock.GetHex()); UniValue posBlockInfos(UniValue::VARR); bool auditResult = true; for (int i = 0; i < block.posBlocksAudited.size(); i++) { @@ -154,9 +154,9 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx posBlockInfos.push_back(objPoSBlockInfo); auditResult = auditResult & (block.posBlocksAudited[i].nTime > 0); } - result.push_back(Pair("auditsuccess", auditResult? "true": "false")); - result.push_back(Pair("posblocks", posBlockInfos)); - result.push_back(Pair("poscount", (int)block.posBlocksAudited.size())); + result.pushKV("auditsuccess", auditResult? "true": "false"); + result.pushKV("posblocks", posBlockInfos); + result.pushKV("poscount", (int)block.posBlocksAudited.size()); } return result; @@ -266,8 +266,8 @@ UniValue waitfornewblock(const UniValue& params, bool fHelp) block = latestblock; } UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("hash", block.hash.GetHex())); - ret.push_back(Pair("height", block.height)); + ret.pushKV("hash", block.hash.GetHex()); + ret.pushKV("height", block.height); return ret; } @@ -311,8 +311,8 @@ UniValue waitforblock(const UniValue& params, bool fHelp) } UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("hash", block.hash.GetHex())); - ret.push_back(Pair("height", block.height)); + ret.pushKV("hash", block.hash.GetHex()); + ret.pushKV("height", block.height); return ret; } @@ -356,8 +356,8 @@ UniValue waitforblockheight(const UniValue& params, bool fHelp) block = latestblock; } UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("hash", block.hash.GetHex())); - ret.push_back(Pair("height", block.height)); + ret.pushKV("hash", block.hash.GetHex()); + ret.pushKV("height", block.height); return ret; } @@ -386,12 +386,12 @@ UniValue mempoolToJSON(bool fVerbose = false) const uint256& hash = entry.first; const CTxMemPoolEntry& e = entry.second; UniValue info(UniValue::VOBJ); - info.push_back(Pair("size", (int)e.GetTxSize())); - info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); - info.push_back(Pair("time", e.GetTime())); - info.push_back(Pair("height", (int)e.GetHeight())); - info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); - info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); + info.pushKV("size", (int)e.GetTxSize()); + info.pushKV("fee", ValueFromAmount(e.GetFee())); + info.pushKV("time", e.GetTime()); + info.pushKV("height", (int)e.GetHeight()); + info.pushKV("startingpriority", e.GetPriority(e.GetHeight())); + info.pushKV("currentpriority", e.GetPriority(chainActive.Height())); const CTransaction& tx = e.GetTx(); std::set setDepends; for (const CTxIn& txin : tx.vin) { @@ -404,8 +404,8 @@ UniValue mempoolToJSON(bool fVerbose = false) depends.push_back(dep); } - info.push_back(Pair("depends", depends)); - o.push_back(Pair(hash.ToString(), info)); + info.pushKV("depends", depends); + o.pushKV(hash.ToString(), info); } return o; } else { @@ -621,13 +621,13 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) CCoinsStats stats; FlushStateToDisk(); if (pcoinsTip->GetStats(stats)) { - ret.push_back(Pair("height", (int64_t)stats.nHeight)); - ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); - ret.push_back(Pair("transactions", (int64_t)stats.nTransactions)); - ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs)); - ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize)); - ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); - ret.push_back(Pair("total_amount", ValueFromAmount(chainActive.Tip()->nMoneySupply))); + ret.pushKV("height", (int64_t)stats.nHeight); + ret.pushKV("bestblock", stats.hashBlock.GetHex()); + ret.pushKV("transactions", (int64_t)stats.nTransactions); + ret.pushKV("txouts", (int64_t)stats.nTransactionOutputs); + ret.pushKV("bytes_serialized", (int64_t)stats.nSerializedSize); + ret.pushKV("hash_serialized", stats.hashSerialized.GetHex()); + ret.pushKV("total_amount", ValueFromAmount(chainActive.Tip()->nMoneySupply)); } return ret; } @@ -694,17 +694,17 @@ UniValue gettxout(const UniValue& params, bool fHelp) BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); CBlockIndex* pindex = it->second; - ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex())); + ret.pushKV("bestblock", pindex->GetBlockHash().GetHex()); if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT) - ret.push_back(Pair("confirmations", 0)); + ret.pushKV("confirmations", 0); else - ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1)); - ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); + ret.pushKV("confirmations", pindex->nHeight - coins.nHeight + 1); + ret.pushKV("value", ValueFromAmount(coins.vout[n].nValue)); UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true); - ret.push_back(Pair("scriptPubKey", o)); - ret.push_back(Pair("version", coins.nVersion)); - ret.push_back(Pair("coinbase", coins.fCoinBase)); + ret.pushKV("scriptPubKey", o); + ret.pushKV("version", coins.nVersion); + ret.pushKV("coinbase", coins.fCoinBase); return ret; } @@ -748,19 +748,19 @@ static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nR pstart = pstart->pprev; } UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("status", nFound >= nRequired)); - rv.push_back(Pair("found", nFound)); - rv.push_back(Pair("required", nRequired)); - rv.push_back(Pair("window", Params().ToCheckBlockUpgradeMajority())); + rv.pushKV("status", nFound >= nRequired); + rv.pushKV("found", nFound); + rv.pushKV("required", nRequired); + rv.pushKV("window", Params().ToCheckBlockUpgradeMajority()); return rv; } static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex) { UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("id", name)); - rv.push_back(Pair("version", version)); - rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, Params().EnforceBlockUpgradeMajority()))); - rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, Params().RejectBlockOutdatedMajority()))); + rv.pushKV("id", name); + rv.pushKV("version", version); + rv.pushKV("enforce", SoftForkMajorityDesc(version, pindex, Params().EnforceBlockUpgradeMajority())); + rv.pushKV("reject", SoftForkMajorityDesc(version, pindex, Params().RejectBlockOutdatedMajority())); return rv; } @@ -799,17 +799,17 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) LOCK(cs_main); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("chain", Params().NetworkIDString())); - obj.push_back(Pair("blocks", (int)chainActive.Height())); - obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); - obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); - obj.push_back(Pair("difficulty", (double)GetDifficulty())); - obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(chainActive.Tip()))); - obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); + obj.pushKV("chain", Params().NetworkIDString()); + obj.pushKV("blocks", (int)chainActive.Height()); + obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1); + obj.pushKV("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()); + obj.pushKV("difficulty", (double)GetDifficulty()); + obj.pushKV("verificationprogress", Checkpoints::GuessVerificationProgress(chainActive.Tip())); + obj.pushKV("chainwork", chainActive.Tip()->nChainWork.GetHex()); CBlockIndex* tip = chainActive.Tip(); UniValue softforks(UniValue::VARR); softforks.push_back(SoftForkDesc("bip65", 5, tip)); - obj.push_back(Pair("softforks", softforks)); + obj.pushKV("softforks", softforks); return obj; } @@ -882,11 +882,11 @@ UniValue getchaintips(const UniValue& params, bool fHelp) UniValue res(UniValue::VARR); for (const CBlockIndex* block : setTips) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("height", block->nHeight)); - obj.push_back(Pair("hash", block->phashBlock->GetHex())); + obj.pushKV("height", block->nHeight); + obj.pushKV("hash", block->phashBlock->GetHex()); const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight; - obj.push_back(Pair("branchlen", branchLen)); + obj.pushKV("branchlen", branchLen); std::string status; if (chainActive.Contains(block)) { @@ -908,7 +908,7 @@ UniValue getchaintips(const UniValue& params, bool fHelp) // No clue. status = "unknown"; } - obj.push_back(Pair("status", status)); + obj.pushKV("status", status); res.push_back(obj); } @@ -959,10 +959,10 @@ UniValue getfeeinfo(const UniValue& params, bool fHelp) UniValue mempoolInfoToJSON() { UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("size", (int64_t) mempool.size())); - ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); + ret.pushKV("size", (int64_t) mempool.size()); + ret.pushKV("bytes", (int64_t) mempool.GetTotalTxSize()); - //ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + //ret.pushKV("usage", (int64_t) mempool.DynamicMemoryUsage()); return ret; } @@ -1128,10 +1128,10 @@ UniValue getinvalid (const UniValue& params, bool fHelp) } UniValue objTx(UniValue::VOBJ); - objTx.push_back(Pair("inv_out", it.first.ToString())); + objTx.pushKV("inv_out", it.first.ToString()); CAmount nValue = tx.vout[out.n].nValue; - objTx.push_back(Pair("value", FormatMoney(nValue))); + objTx.pushKV("value", FormatMoney(nValue)); //Search the txin's to see if any of them are "valid". UniValue objMixedValid(UniValue::VOBJ); @@ -1150,7 +1150,7 @@ UniValue getinvalid (const UniValue& params, bool fHelp) //This is a valid outpoint that mixed with an invalid outpoint. Investigate this person. //Information leakage, not covering their tracks well enough CAmount nValid = txPrev.vout[in2.prevout.n].nValue; - objMixedValid.push_back(Pair(FormatMoney(nValid), in2.prevout.ToString())); + objMixedValid.pushKV(FormatMoney(nValid), in2.prevout.ToString()); nMixedValid += nValid; mapMixedValid[in2.prevout] = 1; @@ -1163,9 +1163,9 @@ UniValue getinvalid (const UniValue& params, bool fHelp) if (!coins || !coins->IsAvailable(out.n)) fSpent = true; - objTx.push_back(Pair("spent", fSpent)); + objTx.pushKV("spent", fSpent); if (!objMixedValid.empty()) - objTx.push_back(Pair("mixed_with_valid", objMixedValid)); + objTx.pushKV("mixed_with_valid", objMixedValid); CScript scriptPubKey = tx.vout[out.n].scriptPubKey; if (!fSpent) { @@ -1186,13 +1186,13 @@ UniValue getinvalid (const UniValue& params, bool fHelp) UniValue objAddresses(UniValue::VOBJ); for (auto it : mapBanAddress) - objAddresses.push_back(Pair(it.first.ToString(), FormatMoney(it.second))); + objAddresses.pushKV(it.first.ToString(), FormatMoney(it.second)); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("addresses_with_invalid", objAddresses)); - obj.push_back(Pair("total_unspent", FormatMoney(nUnspent))); - obj.push_back(Pair("total_minted", FormatMoney(nMint))); - obj.push_back(Pair("total_valid_used", FormatMoney(nMixedValid))); + obj.pushKV("addresses_with_invalid", objAddresses); + obj.pushKV("total_unspent", FormatMoney(nUnspent)); + obj.pushKV("total_minted", FormatMoney(nMint)); + obj.pushKV("total_valid_used", FormatMoney(nMixedValid)); ret.push_back(obj); return ret; @@ -1422,8 +1422,8 @@ UniValue getblockindexstats(const UniValue& params, bool fHelp) { validaterange(params, heightStart, heightEnd); // return object UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("Starting block", heightStart)); - ret.push_back(Pair("Ending block", heightEnd)); + ret.pushKV("Starting block", heightStart); + ret.pushKV("Ending block", heightEnd); bool fFeeOnly = false; if (params.size() > 2) { @@ -1495,12 +1495,12 @@ UniValue getblockindexstats(const UniValue& params, bool fHelp) { CFeeRate nFeeRate = CFeeRate(nFees, nBytes); // return UniValue object - ret.push_back(Pair("txcount", (int64_t)nTxCount)); - ret.push_back(Pair("txcount_all", (int64_t)nTxCount_all)); - ret.push_back(Pair("txbytes", (int64_t)nBytes)); - ret.push_back(Pair("ttlfee", FormatMoney(nFees))); - ret.push_back(Pair("ttlfee_all", FormatMoney(nFees_all))); - ret.push_back(Pair("feeperkb", FormatMoney(nFeeRate.GetFeePerK()))); + ret.pushKV("txcount", (int64_t)nTxCount); + ret.pushKV("txcount_all", (int64_t)nTxCount_all); + ret.pushKV("txbytes", (int64_t)nBytes); + ret.pushKV("ttlfee", FormatMoney(nFees)); + ret.pushKV("ttlfee_all", FormatMoney(nFees_all)); + ret.pushKV("feeperkb", FormatMoney(nFeeRate.GetFeePerK())); return ret; } diff --git a/src/rpc/budget.cpp b/src/rpc/budget.cpp index 577e3d29d0..9201e80f72 100644 --- a/src/rpc/budget.cpp +++ b/src/rpc/budget.cpp @@ -28,27 +28,27 @@ void budgetToJSON(CBudgetProposal* pbudgetProposal, UniValue& bObj) ExtractDestination(pbudgetProposal->GetPayee(), address1); CBitcoinAddress address2(address1); - bObj.push_back(Pair("Name", pbudgetProposal->GetName())); - bObj.push_back(Pair("URL", pbudgetProposal->GetURL())); - bObj.push_back(Pair("Hash", pbudgetProposal->GetHash().ToString())); - bObj.push_back(Pair("FeeHash", pbudgetProposal->nFeeTXHash.ToString())); - bObj.push_back(Pair("BlockStart", (int64_t)pbudgetProposal->GetBlockStart())); - bObj.push_back(Pair("BlockEnd", (int64_t)pbudgetProposal->GetBlockEnd())); - bObj.push_back(Pair("TotalPaymentCount", (int64_t)pbudgetProposal->GetTotalPaymentCount())); - bObj.push_back(Pair("RemainingPaymentCount", (int64_t)pbudgetProposal->GetRemainingPaymentCount())); - bObj.push_back(Pair("PaymentAddress", address2.ToString())); - bObj.push_back(Pair("Ratio", pbudgetProposal->GetRatio())); - bObj.push_back(Pair("Yeas", (int64_t)pbudgetProposal->GetYeas())); - bObj.push_back(Pair("Nays", (int64_t)pbudgetProposal->GetNays())); - bObj.push_back(Pair("Abstains", (int64_t)pbudgetProposal->GetAbstains())); - bObj.push_back(Pair("TotalPayment", ValueFromAmount(pbudgetProposal->GetAmount() * pbudgetProposal->GetTotalPaymentCount()))); - bObj.push_back(Pair("MonthlyPayment", ValueFromAmount(pbudgetProposal->GetAmount()))); - bObj.push_back(Pair("IsEstablished", pbudgetProposal->IsEstablished())); + bObj.pushKV("Name", pbudgetProposal->GetName()); + bObj.pushKV("URL", pbudgetProposal->GetURL()); + bObj.pushKV("Hash", pbudgetProposal->GetHash().ToString()); + bObj.pushKV("FeeHash", pbudgetProposal->nFeeTXHash.ToString()); + bObj.pushKV("BlockStart", (int64_t)pbudgetProposal->GetBlockStart()); + bObj.pushKV("BlockEnd", (int64_t)pbudgetProposal->GetBlockEnd()); + bObj.pushKV("TotalPaymentCount", (int64_t)pbudgetProposal->GetTotalPaymentCount()); + bObj.pushKV("RemainingPaymentCount", (int64_t)pbudgetProposal->GetRemainingPaymentCount()); + bObj.pushKV("PaymentAddress", address2.ToString()); + bObj.pushKV("Ratio", pbudgetProposal->GetRatio()); + bObj.pushKV("Yeas", (int64_t)pbudgetProposal->GetYeas()); + bObj.pushKV("Nays", (int64_t)pbudgetProposal->GetNays()); + bObj.pushKV("Abstains", (int64_t)pbudgetProposal->GetAbstains()); + bObj.pushKV("TotalPayment", ValueFromAmount(pbudgetProposal->GetAmount() * pbudgetProposal->GetTotalPaymentCount())); + bObj.pushKV("MonthlyPayment", ValueFromAmount(pbudgetProposal->GetAmount())); + bObj.pushKV("IsEstablished", pbudgetProposal->IsEstablished()); std::string strError = ""; - bObj.push_back(Pair("IsValid", pbudgetProposal->IsValid(strError))); - bObj.push_back(Pair("IsValidReason", strError.c_str())); - bObj.push_back(Pair("fValid", pbudgetProposal->fValid)); + bObj.pushKV("IsValid", pbudgetProposal->IsValid(strError)); + bObj.pushKV("IsValidReason", strError.c_str()); + bObj.pushKV("fValid", pbudgetProposal->fValid); } UniValue preparebudget(const UniValue& params, bool fHelp) @@ -290,9 +290,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) while (true) { if (!CMessageSigner::GetKeysFromSecret(strMasterNodePrivKey, keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("node", "local")); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Masternode signing error, could not set key correctly.")); + statusObj.pushKV("node", "local"); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Masternode signing error, could not set key correctly."); resultsObj.push_back(statusObj); break; } @@ -300,9 +300,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) CMasternode* pmn = mnodeman.Find(activeMasternode.vin); if (pmn == NULL) { failed++; - statusObj.push_back(Pair("node", "local")); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Failure to find masternode in list : " + activeMasternode.vin.ToString())); + statusObj.pushKV("node", "local"); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Failure to find masternode in list : " + activeMasternode.vin.ToString()); resultsObj.push_back(statusObj); break; } @@ -310,9 +310,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) CBudgetVote vote(activeMasternode.vin, hash, nVote); if (!vote.Sign(keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("node", "local")); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Failure to sign.")); + statusObj.pushKV("node", "local"); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Failure to sign."); resultsObj.push_back(statusObj); break; } @@ -322,22 +322,22 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) success++; budget.mapSeenMasternodeBudgetVotes.insert(std::make_pair(vote.GetHash(), vote)); vote.Relay(); - statusObj.push_back(Pair("node", "local")); - statusObj.push_back(Pair("result", "success")); - statusObj.push_back(Pair("error", "")); + statusObj.pushKV("node", "local"); + statusObj.pushKV("result", "success"); + statusObj.pushKV("error", ""); } else { failed++; - statusObj.push_back(Pair("node", "local")); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Error voting : " + strError)); + statusObj.pushKV("node", "local"); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Error voting : " + strError); } resultsObj.push_back(statusObj); break; } UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -356,9 +356,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) if (!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Masternode signing error, could not set key correctly.")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Masternode signing error, could not set key correctly."); resultsObj.push_back(statusObj); continue; } @@ -366,9 +366,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) CMasternode* pmn = mnodeman.Find(pubKeyMasternode); if (pmn == NULL) { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Can't find masternode by pubkey")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Can't find masternode by pubkey"); resultsObj.push_back(statusObj); continue; } @@ -376,9 +376,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) CBudgetVote vote(pmn->vin, hash, nVote); if (!vote.Sign(keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Failure to sign.")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Failure to sign."); resultsObj.push_back(statusObj); continue; } @@ -388,22 +388,22 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) budget.mapSeenMasternodeBudgetVotes.insert(std::make_pair(vote.GetHash(), vote)); vote.Relay(); success++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "success")); - statusObj.push_back(Pair("error", "")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "success"); + statusObj.pushKV("error", ""); } else { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", strError.c_str())); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", strError.c_str()); } resultsObj.push_back(statusObj); } UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -429,9 +429,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) if(!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)){ failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Masternode signing error, could not set key correctly.")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Masternode signing error, could not set key correctly."); resultsObj.push_back(statusObj); continue; } @@ -440,9 +440,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) if(pmn == NULL) { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Can't find masternode by pubkey")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Can't find masternode by pubkey"); resultsObj.push_back(statusObj); continue; } @@ -450,9 +450,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) CBudgetVote vote(pmn->vin, hash, nVote); if(!vote.Sign(keyMasternode, pubKeyMasternode)){ failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Failure to sign.")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Failure to sign."); resultsObj.push_back(statusObj); continue; } @@ -462,22 +462,22 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) budget.mapSeenMasternodeBudgetVotes.insert(std::make_pair(vote.GetHash(), vote)); vote.Relay(); success++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "success")); - statusObj.push_back(Pair("error", "")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "success"); + statusObj.pushKV("error", ""); } else { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", strError.c_str())); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", strError.c_str()); } resultsObj.push_back(statusObj); } UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -520,11 +520,11 @@ UniValue getbudgetvotes(const UniValue& params, bool fHelp) std::map::iterator it = pbudgetProposal->mapVotes.begin(); while (it != pbudgetProposal->mapVotes.end()) { UniValue bObj(UniValue::VOBJ); - bObj.push_back(Pair("mnId", (*it).second.vin.prevout.hash.ToString())); - bObj.push_back(Pair("nHash", (*it).first.ToString().c_str())); - bObj.push_back(Pair("Vote", (*it).second.GetVoteString())); - bObj.push_back(Pair("nTime", (int64_t)(*it).second.nTime)); - bObj.push_back(Pair("fValid", (*it).second.fValid)); + bObj.pushKV("mnId", (*it).second.vin.prevout.hash.ToString()); + bObj.pushKV("nHash", (*it).first.ToString().c_str()); + bObj.pushKV("Vote", (*it).second.GetVoteString()); + bObj.pushKV("nTime", (int64_t)(*it).second.nTime); + bObj.pushKV("fValid", (*it).second.fValid); ret.push_back(bObj); @@ -604,8 +604,8 @@ UniValue getbudgetprojection(const UniValue& params, bool fHelp) UniValue bObj(UniValue::VOBJ); budgetToJSON(pbudgetProposal, bObj); - bObj.push_back(Pair("Alloted", ValueFromAmount(pbudgetProposal->GetAllotted()))); - bObj.push_back(Pair("TotalBudgetAlloted", ValueFromAmount(nTotalAllotted))); + bObj.pushKV("Alloted", ValueFromAmount(pbudgetProposal->GetAllotted())); + bObj.pushKV("TotalBudgetAlloted", ValueFromAmount(nTotalAllotted)); ret.push_back(bObj); } @@ -782,18 +782,18 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp) if (!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("errorMessage", "Masternode signing error, could not set key correctly.")); - resultsObj.push_back(Pair(mne.getAlias(), statusObj)); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("errorMessage", "Masternode signing error, could not set key correctly."); + resultsObj.pushKV(mne.getAlias(), statusObj); continue; } CMasternode* pmn = mnodeman.Find(pubKeyMasternode); if (pmn == NULL) { failed++; - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("errorMessage", "Can't find masternode by pubkey")); - resultsObj.push_back(Pair(mne.getAlias(), statusObj)); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("errorMessage", "Can't find masternode by pubkey"); + resultsObj.pushKV(mne.getAlias(), statusObj); continue; } @@ -801,9 +801,9 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp) CFinalizedBudgetVote vote(pmn->vin, hash); if (!vote.Sign(keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("errorMessage", "Failure to sign.")); - resultsObj.push_back(Pair(mne.getAlias(), statusObj)); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("errorMessage", "Failure to sign."); + resultsObj.pushKV(mne.getAlias(), statusObj); continue; } @@ -812,18 +812,18 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp) budget.mapSeenFinalizedBudgetVotes.insert(std::make_pair(vote.GetHash(), vote)); vote.Relay(); success++; - statusObj.push_back(Pair("result", "success")); + statusObj.pushKV("result", "success"); } else { failed++; - statusObj.push_back(Pair("result", strError.c_str())); + statusObj.pushKV("result", strError.c_str()); } - resultsObj.push_back(Pair(mne.getAlias(), statusObj)); + resultsObj.pushKV(mne.getAlias(), statusObj); } UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -867,19 +867,19 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp) std::vector winningFbs = budget.GetFinalizedBudgets(); for (CFinalizedBudget* finalizedBudget : winningFbs) { UniValue bObj(UniValue::VOBJ); - bObj.push_back(Pair("FeeTX", finalizedBudget->nFeeTXHash.ToString())); - bObj.push_back(Pair("Hash", finalizedBudget->GetHash().ToString())); - bObj.push_back(Pair("BlockStart", (int64_t)finalizedBudget->GetBlockStart())); - bObj.push_back(Pair("BlockEnd", (int64_t)finalizedBudget->GetBlockEnd())); - bObj.push_back(Pair("Proposals", finalizedBudget->GetProposals())); - bObj.push_back(Pair("VoteCount", (int64_t)finalizedBudget->GetVoteCount())); - bObj.push_back(Pair("Status", finalizedBudget->GetStatus())); + bObj.pushKV("FeeTX", finalizedBudget->nFeeTXHash.ToString()); + bObj.pushKV("Hash", finalizedBudget->GetHash().ToString()); + bObj.pushKV("BlockStart", (int64_t)finalizedBudget->GetBlockStart()); + bObj.pushKV("BlockEnd", (int64_t)finalizedBudget->GetBlockEnd()); + bObj.pushKV("Proposals", finalizedBudget->GetProposals()); + bObj.pushKV("VoteCount", (int64_t)finalizedBudget->GetVoteCount()); + bObj.pushKV("Status", finalizedBudget->GetStatus()); std::string strError = ""; - bObj.push_back(Pair("IsValid", finalizedBudget->IsValid(strError))); - bObj.push_back(Pair("IsValidReason", strError.c_str())); + bObj.pushKV("IsValid", finalizedBudget->IsValid(strError)); + bObj.pushKV("IsValidReason", strError.c_str()); - resultObj.push_back(Pair(finalizedBudget->GetName(), bObj)); + resultObj.pushKV(finalizedBudget->GetName(), bObj); } return resultObj; @@ -901,11 +901,11 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp) std::map::iterator it = pfinalBudget->mapVotes.begin(); while (it != pfinalBudget->mapVotes.end()) { UniValue bObj(UniValue::VOBJ); - bObj.push_back(Pair("nHash", (*it).first.ToString().c_str())); - bObj.push_back(Pair("nTime", (int64_t)(*it).second.nTime)); - bObj.push_back(Pair("fValid", (*it).second.fValid)); + bObj.pushKV("nHash", (*it).first.ToString().c_str()); + bObj.pushKV("nTime", (int64_t)(*it).second.nTime); + bObj.pushKV("fValid", (*it).second.fValid); - obj.push_back(Pair((*it).second.vin.prevout.ToStringShort(), bObj)); + obj.pushKV((*it).second.vin.prevout.ToStringShort(), bObj); it++; } diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 9e08d80645..535a8ad2ea 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -213,19 +213,19 @@ UniValue listmasternodes(const UniValue& params, bool fHelp) LookupHost(strHost.c_str(), node, false); std::string strNetwork = GetNetworkName(node.GetNetwork()); - obj.push_back(Pair("rank", (strStatus == "ENABLED" ? s.first : 0))); - obj.push_back(Pair("network", strNetwork)); - obj.push_back(Pair("txhash", strTxHash)); - obj.push_back(Pair("outidx", (uint64_t)oIdx)); - obj.push_back(Pair("pubkey", HexStr(mn->pubKeyMasternode))); - obj.push_back(Pair("status", strStatus)); - obj.push_back(Pair("addr", CBitcoinAddress(mn->pubKeyCollateralAddress.GetID()).ToString())); + obj.pushKV("rank", (strStatus == "ENABLED" ? s.first : 0)); + obj.pushKV("network", strNetwork); + obj.pushKV("txhash", strTxHash); + obj.pushKV("outidx", (uint64_t)oIdx); + obj.pushKV("pubkey", HexStr(mn->pubKeyMasternode)); + obj.pushKV("status", strStatus); + obj.pushKV("addr", CBitcoinAddress(mn->pubKeyCollateralAddress.GetID()).ToString()); std::string mnStealth(mn->vin.masternodeStealthAddress.begin(), mn->vin.masternodeStealthAddress.end()); - obj.push_back(Pair("stealthaddress", mnStealth)); - obj.push_back(Pair("version", mn->protocolVersion)); - obj.push_back(Pair("lastseen", (int64_t)mn->lastPing.sigTime)); - obj.push_back(Pair("activetime", (int64_t)(mn->lastPing.sigTime - mn->sigTime))); - obj.push_back(Pair("lastpaid", (int64_t)mn->GetLastPaid())); + obj.pushKV("stealthaddress", mnStealth); + obj.pushKV("version", mn->protocolVersion); + obj.pushKV("lastseen", (int64_t)mn->lastPing.sigTime); + obj.pushKV("activetime", (int64_t)(mn->lastPing.sigTime - mn->sigTime)); + obj.pushKV("lastpaid", (int64_t)mn->GetLastPaid()); ret.push_back(obj); } @@ -260,13 +260,13 @@ UniValue getmasternodecount (const UniValue& params, bool fHelp) mnodeman.CountNetworks(ActiveProtocol(), ipv4, ipv6, onion); - obj.push_back(Pair("total", mnodeman.size())); - obj.push_back(Pair("stable", mnodeman.stable_size())); - obj.push_back(Pair("enabled", mnodeman.CountEnabled())); - obj.push_back(Pair("inqueue", nCount)); - obj.push_back(Pair("ipv4", ipv4)); - obj.push_back(Pair("ipv6", ipv6)); - obj.push_back(Pair("onion", onion)); + obj.pushKV("total", mnodeman.size()); + obj.pushKV("stable", mnodeman.stable_size()); + obj.pushKV("enabled", mnodeman.CountEnabled()); + obj.pushKV("inqueue", nCount); + obj.pushKV("ipv4", ipv4); + obj.pushKV("ipv6", ipv6); + obj.pushKV("onion", onion); return obj; } @@ -294,11 +294,11 @@ UniValue masternodecurrent (const UniValue& params, bool fHelp) CMasternode* winner = mnodeman.GetNextMasternodeInQueueForPayment(nHeight, true, nCount); if (winner) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("protocol", (int64_t)winner->protocolVersion)); - obj.push_back(Pair("txhash", winner->vin.prevout.hash.ToString())); - obj.push_back(Pair("pubkey", CBitcoinAddress(winner->pubKeyCollateralAddress.GetID()).ToString())); - obj.push_back(Pair("lastseen", (winner->lastPing == CMasternodePing()) ? winner->sigTime : (int64_t)winner->lastPing.sigTime)); - obj.push_back(Pair("activeseconds", (winner->lastPing == CMasternodePing()) ? 0 : (int64_t)(winner->lastPing.sigTime - winner->sigTime))); + obj.pushKV("protocol", (int64_t)winner->protocolVersion); + obj.pushKV("txhash", winner->vin.prevout.hash.ToString()); + obj.pushKV("pubkey", CBitcoinAddress(winner->pubKeyCollateralAddress.GetID()).ToString()); + obj.pushKV("lastseen", (winner->lastPing == CMasternodePing()) ? winner->sigTime : (int64_t)winner->lastPing.sigTime); + obj.pushKV("activeseconds", (winner->lastPing == CMasternodePing()) ? 0 : (int64_t)(winner->lastPing.sigTime - winner->sigTime)); return obj; } @@ -321,9 +321,9 @@ bool StartMasternodeEntry(UniValue& statusObjRet, CMasternodeBroadcast& mnbRet, fSuccessRet = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage, mnbRet); - statusObjRet.push_back(Pair("alias", mne.getAlias())); - statusObjRet.push_back(Pair("result", fSuccessRet ? "success" : "failed")); - statusObjRet.push_back(Pair("error", fSuccessRet ? "" : errorMessage)); + statusObjRet.pushKV("alias", mne.getAlias()); + statusObjRet.pushKV("result", fSuccessRet ? "success" : "failed"); + statusObjRet.pushKV("error", fSuccessRet ? "" : errorMessage); return true; } @@ -351,7 +351,7 @@ void SerializeMNB(UniValue& statusObjRet, const CMasternodeBroadcast& mnb, const successful++; CDataStream ssMnb(SER_NETWORK, PROTOCOL_VERSION); ssMnb << mnb; - statusObjRet.push_back(Pair("hex", HexStr(ssMnb.begin(), ssMnb.end()))); + statusObjRet.pushKV("hex", HexStr(ssMnb.begin(), ssMnb.end())); } else { failed++; } @@ -454,8 +454,8 @@ UniValue startmasternode (const UniValue& params, bool fHelp) pwalletMain->Lock(); UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Successfully started %d masternodes, failed to start %d, total %d", successful, failed, successful + failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Successfully started %d masternodes, failed to start %d, total %d", successful, failed, successful + failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -485,8 +485,8 @@ UniValue startmasternode (const UniValue& params, bool fHelp) pwalletMain->Lock(); if(!found) { - statusObj.push_back(Pair("success", false)); - statusObj.push_back(Pair("error_message", "Could not find alias in config. Verify with list-conf.")); + statusObj.pushKV("success", false); + statusObj.pushKV("error_message", "Could not find alias in config. Verify with list-conf."); } return statusObj; @@ -543,9 +543,9 @@ UniValue createmasternode(const UniValue& params, bool fHelp) pwalletMain->LockCoin(collateralOut); LogPrintf("Masternode transaction: %s:%i has been locked\n", wtx.GetHash().GetHex().c_str(), indexOut); - obj.push_back(Pair("txhash", wtx.GetHash().GetHex().c_str())); - obj.push_back(Pair("outputidx", indexOut)); - obj.push_back(Pair("genkey", CBitcoinSecret(secret).ToString())); + obj.pushKV("txhash", wtx.GetHash().GetHex().c_str()); + obj.pushKV("outputidx", indexOut); + obj.pushKV("genkey", CBitcoinSecret(secret).ToString()); ret.push_back(obj); } } @@ -597,8 +597,8 @@ UniValue getmasternodeoutputs (const UniValue& params, bool fHelp) UniValue ret(UniValue::VARR); for (COutput& out : possibleCoins) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("txhash", out.tx->GetHash().ToString())); - obj.push_back(Pair("outputidx", out.i)); + obj.pushKV("txhash", out.tx->GetHash().ToString()); + obj.pushKV("outputidx", out.i); ret.push_back(obj); } @@ -655,12 +655,12 @@ UniValue listmasternodeconf (const UniValue& params, bool fHelp) strStatus.find(strFilter) == std::string::npos) continue; UniValue mnObj(UniValue::VOBJ); - mnObj.push_back(Pair("alias", mne.getAlias())); - mnObj.push_back(Pair("address", mne.getIp())); - mnObj.push_back(Pair("privateKey", mne.getPrivKey())); - mnObj.push_back(Pair("txHash", mne.getTxHash())); - mnObj.push_back(Pair("outputIndex", mne.getOutputIndex())); - mnObj.push_back(Pair("status", strStatus)); + mnObj.pushKV("alias", mne.getAlias()); + mnObj.pushKV("address", mne.getIp()); + mnObj.pushKV("privateKey", mne.getPrivKey()); + mnObj.pushKV("txHash", mne.getTxHash()); + mnObj.pushKV("outputIndex", mne.getOutputIndex()); + mnObj.pushKV("status", strStatus); ret.push_back(mnObj); } @@ -695,12 +695,12 @@ UniValue getmasternodestatus (const UniValue& params, bool fHelp) if (pmn) { UniValue mnObj(UniValue::VOBJ); - mnObj.push_back(Pair("txhash", activeMasternode.vin.prevout.hash.ToString())); - mnObj.push_back(Pair("outputidx", (uint64_t)activeMasternode.vin.prevout.n)); - mnObj.push_back(Pair("netaddr", activeMasternode.service.ToString())); - mnObj.push_back(Pair("addr", CBitcoinAddress(pmn->pubKeyCollateralAddress.GetID()).ToString())); - mnObj.push_back(Pair("status", activeMasternode.GetStatus())); - mnObj.push_back(Pair("message", activeMasternode.GetStatusMessage())); + mnObj.pushKV("txhash", activeMasternode.vin.prevout.hash.ToString()); + mnObj.pushKV("outputidx", (uint64_t)activeMasternode.vin.prevout.n); + mnObj.pushKV("netaddr", activeMasternode.service.ToString()); + mnObj.pushKV("addr", CBitcoinAddress(pmn->pubKeyCollateralAddress.GetID()).ToString()); + mnObj.pushKV("status", activeMasternode.GetStatus()); + mnObj.pushKV("message", activeMasternode.GetStatusMessage()); return mnObj; } throw std::runtime_error("Masternode not found in the list of available masternodes. Current status: " @@ -768,7 +768,7 @@ UniValue getmasternodewinners (const UniValue& params, bool fHelp) for (int i = nHeight - nLast; i < nHeight + 20; i++) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("nHeight", i)); + obj.pushKV("nHeight", i); std::string strPayment = GetRequiredPaymentsString(i); if (strFilter != "" && strPayment.find(strFilter) == std::string::npos) continue; @@ -782,24 +782,24 @@ UniValue getmasternodewinners (const UniValue& params, bool fHelp) std::size_t pos = t.find(":"); std::string strAddress = t.substr(0,pos); uint64_t nVotes = atoi(t.substr(pos+1)); - addr.push_back(Pair("address", strAddress)); - addr.push_back(Pair("nVotes", nVotes)); + addr.pushKV("address", strAddress); + addr.pushKV("nVotes", nVotes); winner.push_back(addr); } - obj.push_back(Pair("winner", winner)); + obj.pushKV("winner", winner); } else if (strPayment.find("Unknown") == std::string::npos) { UniValue winner(UniValue::VOBJ); std::size_t pos = strPayment.find(":"); std::string strAddress = strPayment.substr(0,pos); uint64_t nVotes = atoi(strPayment.substr(pos+1)); - winner.push_back(Pair("address", strAddress)); - winner.push_back(Pair("nVotes", nVotes)); - obj.push_back(Pair("winner", winner)); + winner.pushKV("address", strAddress); + winner.pushKV("nVotes", nVotes); + obj.pushKV("winner", winner); } else { UniValue winner(UniValue::VOBJ); - winner.push_back(Pair("address", strPayment)); - winner.push_back(Pair("nVotes", 0)); - obj.push_back(Pair("winner", winner)); + winner.pushKV("address", strPayment); + winner.pushKV("nVotes", 0); + obj.pushKV("winner", winner); } ret.push_back(obj); @@ -849,7 +849,7 @@ UniValue getmasternodescores (const UniValue& params, bool fHelp) } } if (pBestMasternode) - obj.push_back(Pair(strprintf("%d", nHeight), pBestMasternode->vin.prevout.hash.ToString().c_str())); + obj.pushKV(strprintf("%d", nHeight), pBestMasternode->vin.prevout.hash.ToString().c_str()); } return obj; @@ -880,9 +880,9 @@ UniValue getcurrentseesawreward (const UniValue& params, bool fHelp) CAmount masternodeReward = GetSeeSaw(nReward, 0, nblockHeight); CAmount stakingnodeReward = nReward - masternodeReward; - obj.push_back(Pair("Masternode Reward", ValueFromAmount(masternodeReward))); - obj.push_back(Pair("Staking Reward", ValueFromAmount(stakingnodeReward))); - obj.push_back(Pair("Total Reward", ValueFromAmount(nReward))); + obj.pushKV("Masternode Reward", ValueFromAmount(masternodeReward)); + obj.pushKV("Staking Reward", ValueFromAmount(stakingnodeReward)); + obj.pushKV("Total Reward", ValueFromAmount(nReward)); return obj; } @@ -915,10 +915,10 @@ UniValue getseesawrewardwithheight (const UniValue& params, bool fHelp) CAmount masternodeReward = GetSeeSaw(nReward, 0, nblockHeight); CAmount stakingnodeReward = nReward - masternodeReward; - obj.push_back(Pair("Block Height", nblockHeight)); - obj.push_back(Pair("Masternode Reward", ValueFromAmount(masternodeReward))); - obj.push_back(Pair("Staking Reward", ValueFromAmount(stakingnodeReward))); - obj.push_back(Pair("Total Reward", ValueFromAmount(nReward))); + obj.pushKV("Block Height", nblockHeight); + obj.pushKV("Masternode Reward", ValueFromAmount(masternodeReward)); + obj.pushKV("Staking Reward", ValueFromAmount(stakingnodeReward)); + obj.pushKV("Total Reward", ValueFromAmount(nReward)); return obj; } @@ -947,8 +947,8 @@ UniValue getseesawrewardratio (const UniValue& params, bool fHelp) CAmount masternodeReward = GetSeeSaw(nReward, 0, nblockHeight); int masternodeRatio = (masternodeReward * 100)/nReward; - obj.push_back(Pair("Masternode Reward Ratio", masternodeRatio)); - obj.push_back(Pair("Staking Reward Ratio", 100 - masternodeRatio)); + obj.pushKV("Masternode Reward Ratio", masternodeRatio); + obj.pushKV("Staking Reward Ratio", 100 - masternodeRatio); return obj; } @@ -1021,7 +1021,7 @@ UniValue createmasternodebroadcast(const UniValue& params, bool fHelp) bool found = false; UniValue statusObj(UniValue::VOBJ); - statusObj.push_back(Pair("alias", alias)); + statusObj.pushKV("alias", alias); for (CMasternodeConfig::CMasternodeEntry mne : masternodeConfig.getEntries()) { if(mne.getAlias() == alias) { @@ -1037,8 +1037,8 @@ UniValue createmasternodebroadcast(const UniValue& params, bool fHelp) } if(!found) { - statusObj.push_back(Pair("success", false)); - statusObj.push_back(Pair("error_message", "Could not find alias in config. Verify with list-conf.")); + statusObj.pushKV("success", false); + statusObj.pushKV("error_message", "Could not find alias in config. Verify with list-conf."); } return statusObj; @@ -1070,8 +1070,8 @@ UniValue createmasternodebroadcast(const UniValue& params, bool fHelp) } UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Successfully created broadcast messages for %d masternodes, failed to create %d, total %d", successful, failed, successful + failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Successfully created broadcast messages for %d masternodes, failed to create %d, total %d", successful, failed, successful + failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -1118,22 +1118,22 @@ UniValue decodemasternodebroadcast(const UniValue & params, bool fHelp) UniValue resultObj(UniValue::VOBJ); - resultObj.push_back(Pair("vin", mnb.vin.prevout.ToString())); - resultObj.push_back(Pair("addr", mnb.addr.ToString())); - resultObj.push_back(Pair("pubkeycollateral", CBitcoinAddress(mnb.pubKeyCollateralAddress.GetID()).ToString())); - resultObj.push_back(Pair("pubkeymasternode", CBitcoinAddress(mnb.pubKeyMasternode.GetID()).ToString())); - resultObj.push_back(Pair("vchsig", EncodeBase64(&mnb.sig[0], mnb.sig.size()))); - resultObj.push_back(Pair("sigtime", mnb.sigTime)); - resultObj.push_back(Pair("protocolversion", mnb.protocolVersion)); - resultObj.push_back(Pair("nlastdsq", mnb.nLastDsq)); + resultObj.pushKV("vin", mnb.vin.prevout.ToString()); + resultObj.pushKV("addr", mnb.addr.ToString()); + resultObj.pushKV("pubkeycollateral", CBitcoinAddress(mnb.pubKeyCollateralAddress.GetID()).ToString()); + resultObj.pushKV("pubkeymasternode", CBitcoinAddress(mnb.pubKeyMasternode.GetID()).ToString()); + resultObj.pushKV("vchsig", EncodeBase64(&mnb.sig[0], mnb.sig.size())); + resultObj.pushKV("sigtime", mnb.sigTime); + resultObj.pushKV("protocolversion", mnb.protocolVersion); + resultObj.pushKV("nlastdsq", mnb.nLastDsq); UniValue lastPingObj(UniValue::VOBJ); - lastPingObj.push_back(Pair("vin", mnb.lastPing.vin.prevout.ToString())); - lastPingObj.push_back(Pair("blockhash", mnb.lastPing.blockHash.ToString())); - lastPingObj.push_back(Pair("sigtime", mnb.lastPing.sigTime)); - lastPingObj.push_back(Pair("vchsig", EncodeBase64(&mnb.lastPing.vchSig[0], mnb.lastPing.vchSig.size()))); + lastPingObj.pushKV("vin", mnb.lastPing.vin.prevout.ToString()); + lastPingObj.pushKV("blockhash", mnb.lastPing.blockHash.ToString()); + lastPingObj.pushKV("sigtime", mnb.lastPing.sigTime); + lastPingObj.pushKV("vchsig", EncodeBase64(&mnb.lastPing.vchSig[0], mnb.lastPing.vchSig.size())); - resultObj.push_back(Pair("lastping", lastPingObj)); + resultObj.pushKV("lastping", lastPingObj); return resultObj; } diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index f22293d9b0..2d20b1b7dd 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -335,19 +335,19 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) LOCK(cs_main); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("blocks", (int)chainActive.Height())); - obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); - obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); - obj.push_back(Pair("difficulty", (double)GetDifficulty())); - obj.push_back(Pair("errors", GetWarnings("statusbar"))); - obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); - obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); - obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); - obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); - obj.push_back(Pair("chain", Params().NetworkIDString())); + obj.pushKV("blocks", (int)chainActive.Height()); + obj.pushKV("currentblocksize", (uint64_t)nLastBlockSize); + obj.pushKV("currentblocktx", (uint64_t)nLastBlockTx); + obj.pushKV("difficulty", (double)GetDifficulty()); + obj.pushKV("errors", GetWarnings("statusbar")); + obj.pushKV("genproclimit", (int)GetArg("-genproclimit", -1)); + obj.pushKV("networkhashps", getnetworkhashps(params, false)); + obj.pushKV("pooledtx", (uint64_t)mempool.size()); + obj.pushKV("testnet", Params().TestnetToBeDeprecatedFieldRPC()); + obj.pushKV("chain", Params().NetworkIDString()); #ifdef ENABLE_WALLET - obj.push_back(Pair("generate", getgenerate(params, false))); - obj.push_back(Pair("hashespersec", gethashespersec(params, false))); + obj.pushKV("generate", getgenerate(params, false)); + obj.pushKV("hashespersec", gethashespersec(params, false)); #endif return obj; } @@ -620,26 +620,26 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("data", EncodeHexTx(tx))); + entry.pushKV("data", EncodeHexTx(tx)); - entry.push_back(Pair("hash", txHash.GetHex())); + entry.pushKV("hash", txHash.GetHex()); UniValue deps(UniValue::VARR); for (const CTxIn& in : tx.vin) { if (setTxIndex.count(in.prevout.hash)) deps.push_back(setTxIndex[in.prevout.hash]); } - entry.push_back(Pair("depends", deps)); + entry.pushKV("depends", deps); int index_in_template = i - 1; - entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); - entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template])); + entry.pushKV("fee", pblocktemplate->vTxFees[index_in_template]); + entry.pushKV("sigops", pblocktemplate->vTxSigOps[index_in_template]); transactions.push_back(entry); } UniValue aux(UniValue::VOBJ); - aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); + aux.pushKV("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())); uint256 hashTarget = uint256().SetCompact(pblock->nBits); @@ -653,36 +653,36 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UniValue aVotes(UniValue::VARR); UniValue result(UniValue::VOBJ); - result.push_back(Pair("capabilities", aCaps)); - result.push_back(Pair("version", pblock->nVersion)); - result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); - result.push_back(Pair("transactions", transactions)); - result.push_back(Pair("coinbaseaux", aux)); - result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].GetValueOut())); - result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast))); - result.push_back(Pair("target", hashTarget.GetHex())); - result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast() + 1)); - result.push_back(Pair("mutable", aMutable)); - result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("curtime", pblock->GetBlockTime())); - result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); - result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight + 1))); - result.push_back(Pair("votes", aVotes)); + result.pushKV("capabilities", aCaps); + result.pushKV("version", pblock->nVersion); + result.pushKV("previousblockhash", pblock->hashPrevBlock.GetHex()); + result.pushKV("transactions", transactions); + result.pushKV("coinbaseaux", aux); + result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0].GetValueOut()); + result.pushKV("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)); + result.pushKV("target", hashTarget.GetHex()); + result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast() + 1); + result.pushKV("mutable", aMutable); + result.pushKV("noncerange", "00000000ffffffff"); + result.pushKV("curtime", pblock->GetBlockTime()); + result.pushKV("bits", strprintf("%08x", pblock->nBits)); + result.pushKV("height", (int64_t)(pindexPrev->nHeight + 1)); + result.pushKV("votes", aVotes); if (pblock->payee != CScript()) { CTxDestination address1; ExtractDestination(pblock->payee, address1); CBitcoinAddress address2(address1); - result.push_back(Pair("payee", address2.ToString().c_str())); - result.push_back(Pair("payee_amount", (int64_t)pblock->vtx[0].vout[1].nValue)); + result.pushKV("payee", address2.ToString().c_str()); + result.pushKV("payee_amount", (int64_t)pblock->vtx[0].vout[1].nValue); } else { - result.push_back(Pair("payee", "")); - result.push_back(Pair("payee_amount", "")); + result.pushKV("payee", ""); + result.pushKV("payee_amount", ""); } - result.push_back(Pair("masternode_payments", pblock->nTime > Params().StartMasternodePayments())); - result.push_back(Pair("enforce_masternode_payments", true)); + result.pushKV("masternode_payments", pblock->nTime > Params().StartMasternodePayments()); + result.pushKV("enforce_masternode_payments", true); return result; } @@ -790,31 +790,31 @@ UniValue getpoablocktemplate(const UniValue& params, bool fHelp) UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("data", EncodeHexTx(tx))); + entry.pushKV("data", EncodeHexTx(tx)); - entry.push_back(Pair("hash", txHash.GetHex())); + entry.pushKV("hash", txHash.GetHex()); UniValue deps(UniValue::VARR); for (const CTxIn& in : tx.vin) { if (setTxIndex.count(in.prevout.hash)) deps.push_back(setTxIndex[in.prevout.hash]); } - entry.push_back(Pair("depends", deps)); + entry.pushKV("depends", deps); int index_in_template = i - 1; - entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); - entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template])); + entry.pushKV("fee", pblocktemplate->vTxFees[index_in_template]); + entry.pushKV("sigops", pblocktemplate->vTxSigOps[index_in_template]); transactions.push_back(entry); } UniValue coinbasetxn(UniValue::VOBJ); CTransaction& tx = pblock->vtx[0]; - coinbasetxn.push_back(Pair("data", EncodeHexTx(tx))); - coinbasetxn.push_back(Pair("hash", tx.GetHash().GetHex())); + coinbasetxn.pushKV("data", EncodeHexTx(tx)); + coinbasetxn.pushKV("hash", tx.GetHash().GetHex()); UniValue aux(UniValue::VOBJ); - aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); + aux.pushKV("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())); UniValue aMutable(UniValue::VARR); if (aMutable.empty()) { @@ -828,7 +828,7 @@ UniValue getpoablocktemplate(const UniValue& params, bool fHelp) for (size_t idx = 0; idx < pblock->posBlocksAudited.size(); idx++) { UniValue entry(UniValue::VOBJ); PoSBlockSummary pos = pblock->posBlocksAudited.at(idx); - entry.push_back(Pair("data", EncodeHexPoSBlockSummary(pos))); + entry.pushKV("data", EncodeHexPoSBlockSummary(pos)); posBlocksAudited.push_back(entry); } @@ -838,32 +838,32 @@ UniValue getpoablocktemplate(const UniValue& params, bool fHelp) pblock->SetVersionPoABlock(); UniValue result(UniValue::VOBJ); - result.push_back(Pair("version", pblock->nVersion)); - result.push_back(Pair("previouspoablockhash", pblock->hashPrevPoABlock.GetHex())); - result.push_back(Pair("poamerkleroot", poaMerkleRoot.GetHex())); - result.push_back(Pair("transactions", transactions)); - result.push_back(Pair("coinbasetxn", coinbasetxn)); - result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].GetValueOut())); - result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("curtime", pblock->GetBlockTime())); - result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); - result.push_back(Pair("target", hashTarget.GetHex())); - result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight + 1))); - result.push_back(Pair("posblocksaudited", posBlocksAudited)); + result.pushKV("version", pblock->nVersion); + result.pushKV("previouspoablockhash", pblock->hashPrevPoABlock.GetHex()); + result.pushKV("poamerkleroot", poaMerkleRoot.GetHex()); + result.pushKV("transactions", transactions); + result.pushKV("coinbasetxn", coinbasetxn); + result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0].GetValueOut()); + result.pushKV("noncerange", "00000000ffffffff"); + result.pushKV("curtime", pblock->GetBlockTime()); + result.pushKV("bits", strprintf("%08x", pblock->nBits)); + result.pushKV("target", hashTarget.GetHex()); + result.pushKV("height", (int64_t)(pindexPrev->nHeight + 1)); + result.pushKV("posblocksaudited", posBlocksAudited); if (pblock->payee != CScript()) { CTxDestination address1; ExtractDestination(pblock->payee, address1); CBitcoinAddress address2(address1); - result.push_back(Pair("payee", address2.ToString().c_str())); - result.push_back(Pair("payee_amount", (int64_t)pblock->vtx[0].vout[1].nValue)); + result.pushKV("payee", address2.ToString().c_str()); + result.pushKV("payee_amount", (int64_t)pblock->vtx[0].vout[1].nValue); } else { - result.push_back(Pair("payee", "")); - result.push_back(Pair("payee_amount", "")); + result.pushKV("payee", ""); + result.pushKV("payee_amount", ""); } - result.push_back(Pair("masternode_payments", pblock->nTime > Params().StartMasternodePayments())); - result.push_back(Pair("enforce_masternode_payments", true)); + result.pushKV("masternode_payments", pblock->nTime > Params().StartMasternodePayments()); + result.pushKV("enforce_masternode_payments", true); return result; } } @@ -875,11 +875,11 @@ UniValue setminingnbits(const UniValue& params, bool fHelp) { unsigned int nbits = (unsigned int) params[0].get_int64(); int changed= params[1].get_int(); UniValue result(UniValue::VOBJ); - result.push_back(Pair("previous_bits", strprintf("%08x", N_BITS))); + result.pushKV("previous_bits", strprintf("%08x", N_BITS)); if (changed) { N_BITS = nbits; } - result.push_back(Pair("current_bits", strprintf("%08x", N_BITS))); + result.pushKV("current_bits", strprintf("%08x", N_BITS)); return result; } diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index b489948797..c2dbe7eebd 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -77,32 +77,32 @@ UniValue getinfo(const UniValue ¶ms, bool fHelp) { GetProxy(NET_IPV4, proxy); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("version", CLIENT_VERSION)); - obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); + obj.pushKV("version", CLIENT_VERSION); + obj.pushKV("protocolversion", PROTOCOL_VERSION); #ifdef ENABLE_WALLET if (pwalletMain) { - obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); - obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); + obj.pushKV("walletversion", pwalletMain->GetVersion()); + obj.pushKV("balance", ValueFromAmount(pwalletMain->GetBalance())); } #endif - obj.push_back(Pair("blocks", (int) chainActive.Height())); - obj.push_back(Pair("synced", masternodeSync.IsBlockchainSynced())); - obj.push_back(Pair("timeoffset", GetTimeOffset())); - obj.push_back(Pair("connections", (int) vNodes.size())); - obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string()))); - obj.push_back(Pair("difficulty", (double) GetDifficulty())); - obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); - obj.push_back(Pair("moneysupply",ValueFromAmount(chainActive.Tip()->nMoneySupply))); + obj.pushKV("blocks", (int) chainActive.Height()); + obj.pushKV("synced", masternodeSync.IsBlockchainSynced()); + obj.pushKV("timeoffset", GetTimeOffset()); + obj.pushKV("connections", (int) vNodes.size()); + obj.pushKV("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string())); + obj.pushKV("difficulty", (double) GetDifficulty()); + obj.pushKV("testnet", Params().TestnetToBeDeprecatedFieldRPC()); + obj.pushKV("moneysupply",ValueFromAmount(chainActive.Tip()->nMoneySupply)); #ifdef ENABLE_WALLET if (pwalletMain) { - obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); + obj.pushKV("keypoololdest", pwalletMain->GetOldestKeyPoolTime()); } if (pwalletMain && pwalletMain->IsCrypted()) - obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); - obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); + obj.pushKV("unlocked_until", nWalletUnlockTime); + obj.pushKV("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())); #endif - obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); + obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())); #ifdef ENABLE_WALLET if (pwalletMain) { bool nStaking = false; @@ -111,25 +111,25 @@ UniValue getinfo(const UniValue ¶ms, bool fHelp) { else if (mapHashedBlocks.count(chainActive.Tip()->nHeight - 1) && nLastCoinStakeSearchInterval) nStaking = true; if (pwalletMain->IsLocked()) { - obj.push_back(Pair("staking mode", ("disabled"))); - obj.push_back(Pair("staking status", ("inactive (wallet locked)"))); + obj.pushKV("staking mode", ("disabled")); + obj.pushKV("staking status", ("inactive (wallet locked)")); } else { - obj.push_back(Pair("staking mode", (pwalletMain->ReadStakingStatus() ? "enabled" : "disabled"))); + obj.pushKV("staking mode", (pwalletMain->ReadStakingStatus() ? "enabled" : "disabled")); if (vNodes.empty()) { - obj.push_back(Pair("staking status", ("inactive (no peer connections)"))); + obj.pushKV("staking status", ("inactive (no peer connections)")); } else if (!masternodeSync.IsSynced()) { - obj.push_back(Pair("staking status", ("inactive (syncing masternode list)"))); + obj.pushKV("staking status", ("inactive (syncing masternode list)")); } else if (!pwalletMain->MintableCoins() && pwalletMain->combineMode == CombineMode::ON) { - obj.push_back(Pair("staking status", ("delayed (waiting for 100 blocks)"))); + obj.pushKV("staking status", ("delayed (waiting for 100 blocks)")); } else if (!pwalletMain->MintableCoins()) { - obj.push_back(Pair("staking status", ("inactive (no mintable coins)"))); + obj.pushKV("staking status", ("inactive (no mintable coins)")); } else { - obj.push_back(Pair("staking status", (nStaking ? "active (attempting to mint a block)" : "idle (waiting for next round)"))); + obj.pushKV("staking status", (nStaking ? "active (attempting to mint a block)" : "idle (waiting for next round)")); } } } #endif - obj.push_back(Pair("errors", GetWarnings("statusbar"))); + obj.pushKV("errors", GetWarnings("statusbar")); return obj; } @@ -147,7 +147,7 @@ UniValue getversion(const UniValue ¶ms, bool fHelp) { LOCK(cs_main); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("version", CLIENT_VERSION)); + obj.pushKV("version", CLIENT_VERSION); return obj; } @@ -193,22 +193,22 @@ UniValue mnsync(const UniValue ¶ms, bool fHelp) { if (strMode == "status") { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("IsBlockchainSynced", masternodeSync.IsBlockchainSynced())); - obj.push_back(Pair("lastMasternodeList", masternodeSync.lastMasternodeList)); - obj.push_back(Pair("lastMasternodeWinner", masternodeSync.lastMasternodeWinner)); - obj.push_back(Pair("lastBudgetItem", masternodeSync.lastBudgetItem)); - obj.push_back(Pair("lastFailure", masternodeSync.lastFailure)); - obj.push_back(Pair("nCountFailures", masternodeSync.nCountFailures)); - obj.push_back(Pair("sumMasternodeList", masternodeSync.sumMasternodeList)); - obj.push_back(Pair("sumMasternodeWinner", masternodeSync.sumMasternodeWinner)); - obj.push_back(Pair("sumBudgetItemProp", masternodeSync.sumBudgetItemProp)); - obj.push_back(Pair("sumBudgetItemFin", masternodeSync.sumBudgetItemFin)); - obj.push_back(Pair("countMasternodeList", masternodeSync.countMasternodeList)); - obj.push_back(Pair("countMasternodeWinner", masternodeSync.countMasternodeWinner)); - obj.push_back(Pair("countBudgetItemProp", masternodeSync.countBudgetItemProp)); - obj.push_back(Pair("countBudgetItemFin", masternodeSync.countBudgetItemFin)); - obj.push_back(Pair("RequestedMasternodeAssets", masternodeSync.RequestedMasternodeAssets)); - obj.push_back(Pair("RequestedMasternodeAttempt", masternodeSync.RequestedMasternodeAttempt)); + obj.pushKV("IsBlockchainSynced", masternodeSync.IsBlockchainSynced()); + obj.pushKV("lastMasternodeList", masternodeSync.lastMasternodeList); + obj.pushKV("lastMasternodeWinner", masternodeSync.lastMasternodeWinner); + obj.pushKV("lastBudgetItem", masternodeSync.lastBudgetItem); + obj.pushKV("lastFailure", masternodeSync.lastFailure); + obj.pushKV("nCountFailures", masternodeSync.nCountFailures); + obj.pushKV("sumMasternodeList", masternodeSync.sumMasternodeList); + obj.pushKV("sumMasternodeWinner", masternodeSync.sumMasternodeWinner); + obj.pushKV("sumBudgetItemProp", masternodeSync.sumBudgetItemProp); + obj.pushKV("sumBudgetItemFin", masternodeSync.sumBudgetItemFin); + obj.pushKV("countMasternodeList", masternodeSync.countMasternodeList); + obj.pushKV("countMasternodeWinner", masternodeSync.countMasternodeWinner); + obj.pushKV("countBudgetItemProp", masternodeSync.countBudgetItemProp); + obj.pushKV("countBudgetItemFin", masternodeSync.countBudgetItemFin); + obj.pushKV("RequestedMasternodeAssets", masternodeSync.RequestedMasternodeAssets); + obj.pushKV("RequestedMasternodeAttempt", masternodeSync.RequestedMasternodeAttempt); return obj; } @@ -235,11 +235,11 @@ class DescribeAddressVisitor : public boost::static_visitor { UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; - obj.push_back(Pair("isscript", false)); + obj.pushKV("isscript", false); if (mine == ISMINE_SPENDABLE) { pwalletMain->GetPubKey(keyID, vchPubKey); - obj.push_back(Pair("pubkey", HexStr(vchPubKey))); - obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed())); + obj.pushKV("pubkey", HexStr(vchPubKey)); + obj.pushKV("iscompressed", vchPubKey.IsCompressed()); } return obj; } @@ -247,21 +247,21 @@ class DescribeAddressVisitor : public boost::static_visitor UniValue operator()(const CScriptID &scriptID) const { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("isscript", true)); + obj.pushKV("isscript", true); CScript subscript; pwalletMain->GetCScript(scriptID, subscript); std::vector addresses; txnouttype whichType; int nRequired; ExtractDestinations(subscript, whichType, addresses, nRequired); - obj.push_back(Pair("script", GetTxnOutputType(whichType))); - obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end()))); + obj.pushKV("script", GetTxnOutputType(whichType)); + obj.pushKV("hex", HexStr(subscript.begin(), subscript.end())); UniValue a(UniValue::VARR); for (const CTxDestination& addr : addresses) a.push_back(CBitcoinAddress(addr).ToString()); - obj.push_back(Pair("addresses", a)); + obj.pushKV("addresses", a); if (whichType == TX_MULTISIG) - obj.push_back(Pair("sigsrequired", nRequired)); + obj.pushKV("sigsrequired", nRequired); return obj; } }; @@ -302,22 +302,22 @@ UniValue validateaddress(const UniValue& params, bool fHelp) bool isValid = address.IsValid(); UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("isvalid", isValid)); + ret.pushKV("isvalid", isValid); if (isValid) { CTxDestination dest = address.Get(); std::string currentAddress = address.ToString(); - ret.push_back(Pair("address", currentAddress)); + ret.pushKV("address", currentAddress); CScript scriptPubKey = GetScriptForDestination(dest); - ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())); #ifdef ENABLE_WALLET isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; - ret.push_back(Pair("ismine", bool(mine & ISMINE_SPENDABLE))); - ret.push_back(Pair("iswatchonly", bool(mine & ISMINE_WATCH_ONLY))); + ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE)); + ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)); UniValue detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); ret.pushKVs(detail); if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) - ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); + ret.pushKV("account", pwalletMain->mapAddressBook[dest].name); #endif } return ret; @@ -351,7 +351,7 @@ UniValue validatestealthaddress(const UniValue& params, bool fHelp) if (!CWallet::DecodeStealthAddress(addr, viewKey, spendKey, hasPaymentID, paymentID)) { isValid = false; } - ret.push_back(Pair("isvalid", isValid)); + ret.pushKV("isvalid", isValid); return ret; } @@ -451,8 +451,8 @@ UniValue createmultisig(const UniValue& params, bool fHelp) { CBitcoinAddress address(innerID); UniValue result(UniValue::VOBJ); - result.push_back(Pair("address", address.ToString())); - result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); + result.pushKV("address", address.ToString()); + result.pushKV("redeemScript", HexStr(inner.begin(), inner.end())); return result; } @@ -624,13 +624,13 @@ UniValue getstakingstatus(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("haveconnections", !vNodes.empty())); + obj.pushKV("haveconnections", !vNodes.empty()); if (pwalletMain) { - obj.push_back(Pair("walletunlocked", !pwalletMain->IsLocked())); - obj.push_back(Pair("mintablecoins", pwalletMain->MintableCoins())); - obj.push_back(Pair("enoughcoins", nReserveBalance <= pwalletMain->GetBalance())); + obj.pushKV("walletunlocked", !pwalletMain->IsLocked()); + obj.pushKV("mintablecoins", pwalletMain->MintableCoins()); + obj.pushKV("enoughcoins", nReserveBalance <= pwalletMain->GetBalance()); } - obj.push_back(Pair("masternodes-synced", masternodeSync.IsSynced())); + obj.pushKV("masternodes-synced", masternodeSync.IsSynced()); bool nStaking = false; if (mapHashedBlocks.count(chainActive.Tip()->nHeight)) @@ -638,20 +638,20 @@ UniValue getstakingstatus(const UniValue& params, bool fHelp) else if (mapHashedBlocks.count(chainActive.Tip()->nHeight - 1) && nLastCoinStakeSearchInterval) nStaking = true; if (pwalletMain->IsLocked()) { - obj.push_back(Pair("staking mode", ("disabled"))); - obj.push_back(Pair("staking status", ("inactive (wallet locked)"))); + obj.pushKV("staking mode", ("disabled")); + obj.pushKV("staking status", ("inactive (wallet locked)")); } else { - obj.push_back(Pair("staking mode", (pwalletMain->ReadStakingStatus() ? "enabled" : "disabled"))); + obj.pushKV("staking mode", (pwalletMain->ReadStakingStatus() ? "enabled" : "disabled")); if (vNodes.empty()) { - obj.push_back(Pair("staking status", ("inactive (no peer connections)"))); + obj.pushKV("staking status", ("inactive (no peer connections)")); } else if (!masternodeSync.IsSynced()) { - obj.push_back(Pair("staking status", ("inactive (syncing masternode list)"))); + obj.pushKV("staking status", ("inactive (syncing masternode list)")); } else if (!pwalletMain->MintableCoins() && pwalletMain->combineMode == CombineMode::ON) { - obj.push_back(Pair("staking status", ("delayed (waiting for 100 blocks)"))); + obj.pushKV("staking status", ("delayed (waiting for 100 blocks)")); } else if (!pwalletMain->MintableCoins()) { - obj.push_back(Pair("staking status", ("inactive (no mintable coins)"))); + obj.pushKV("staking status", ("inactive (no mintable coins)")); } else { - obj.push_back(Pair("staking status", (nStaking ? "active (attempting to mint a block)" : "idle (waiting for next round)"))); + obj.pushKV("staking status", (nStaking ? "active (attempting to mint a block)" : "idle (waiting for next round)")); } } return obj; diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 71cd4d8afe..ee447d6cd6 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -118,38 +118,38 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); CNodeStateStats statestats; bool fStateStats = GetNodeStateStats(stats.nodeid, statestats); - obj.push_back(Pair("id", stats.nodeid)); - obj.push_back(Pair("addr", stats.addrName)); + obj.pushKV("id", stats.nodeid); + obj.pushKV("addr", stats.addrName); if (!(stats.addrLocal.empty())) - obj.push_back(Pair("addrlocal", stats.addrLocal)); - obj.push_back(Pair("services", strprintf("%016x", stats.nServices))); - obj.push_back(Pair("lastsend", stats.nLastSend)); - obj.push_back(Pair("lastrecv", stats.nLastRecv)); - obj.push_back(Pair("bytessent", stats.nSendBytes)); - obj.push_back(Pair("bytesrecv", stats.nRecvBytes)); - obj.push_back(Pair("conntime", stats.nTimeConnected)); - obj.push_back(Pair("timeoffset", stats.nTimeOffset)); - obj.push_back(Pair("pingtime", stats.dPingTime)); + obj.pushKV("addrlocal", stats.addrLocal); + obj.pushKV("services", strprintf("%016x", stats.nServices)); + obj.pushKV("lastsend", stats.nLastSend); + obj.pushKV("lastrecv", stats.nLastRecv); + obj.pushKV("bytessent", stats.nSendBytes); + obj.pushKV("bytesrecv", stats.nRecvBytes); + obj.pushKV("conntime", stats.nTimeConnected); + obj.pushKV("timeoffset", stats.nTimeOffset); + obj.pushKV("pingtime", stats.dPingTime); if (stats.dPingWait > 0.0) - obj.push_back(Pair("pingwait", stats.dPingWait)); - obj.push_back(Pair("version", stats.nVersion)); + obj.pushKV("pingwait", stats.dPingWait); + obj.pushKV("version", stats.nVersion); // Use the sanitized form of subver here, to avoid tricksy remote peers from // corrupting or modifiying the JSON output by putting special characters in // their ver message. - obj.push_back(Pair("subver", stats.cleanSubVer)); - obj.push_back(Pair("inbound", stats.fInbound)); - obj.push_back(Pair("startingheight", stats.nStartingHeight)); + obj.pushKV("subver", stats.cleanSubVer); + obj.pushKV("inbound", stats.fInbound); + obj.pushKV("startingheight", stats.nStartingHeight); if (fStateStats) { - obj.push_back(Pair("banscore", statestats.nMisbehavior)); - obj.push_back(Pair("synced_headers", statestats.nSyncHeight)); - obj.push_back(Pair("synced_blocks", statestats.nCommonHeight)); + obj.pushKV("banscore", statestats.nMisbehavior); + obj.pushKV("synced_headers", statestats.nSyncHeight); + obj.pushKV("synced_blocks", statestats.nCommonHeight); UniValue heights(UniValue::VARR); for (int height : statestats.vHeightInFlight) { heights.push_back(height); } - obj.push_back(Pair("inflight", heights)); + obj.pushKV("inflight", heights); } - obj.push_back(Pair("whitelisted", stats.fWhitelisted)); + obj.pushKV("whitelisted", stats.fWhitelisted); ret.push_back(obj); } @@ -270,16 +270,16 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp) for (const AddedNodeInfo& info : vInfo) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("addednode", info.strAddedNode)); - obj.push_back(Pair("connected", info.fConnected)); + obj.pushKV("addednode", info.strAddedNode); + obj.pushKV("connected", info.fConnected); UniValue addresses(UniValue::VARR); if (info.fConnected) { UniValue address(UniValue::VOBJ); - address.push_back(Pair("address", info.resolvedAddress.ToString())); - address.push_back(Pair("connected", info.fInbound ? "inbound" : "outbound")); + address.pushKV("address", info.resolvedAddress.ToString()); + address.pushKV("connected", info.fInbound ? "inbound" : "outbound"); addresses.push_back(address); } - obj.push_back(Pair("addresses", addresses)); + obj.pushKV("addresses", addresses); ret.push_back(obj); } @@ -303,9 +303,9 @@ UniValue getnettotals(const UniValue& params, bool fHelp) HelpExampleCli("getnettotals", "") + HelpExampleRpc("getnettotals", "")); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv())); - obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent())); - obj.push_back(Pair("timemillis", GetTimeMillis())); + obj.pushKV("totalbytesrecv", CNode::GetTotalBytesRecv()); + obj.pushKV("totalbytessent", CNode::GetTotalBytesSent()); + obj.pushKV("timemillis", GetTimeMillis()); return obj; } @@ -319,11 +319,11 @@ static UniValue GetNetworksInfo() proxyType proxy; UniValue obj(UniValue::VOBJ); GetProxy(network, proxy); - obj.push_back(Pair("name", GetNetworkName(network))); - obj.push_back(Pair("limited", IsLimited(network))); - obj.push_back(Pair("reachable", IsReachable(network))); - obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string())); - obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials)); + obj.pushKV("name", GetNetworkName(network)); + obj.pushKV("limited", IsLimited(network)); + obj.pushKV("reachable", IsReachable(network)); + obj.pushKV("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string()); + obj.pushKV("proxy_randomize_credentials", proxy.randomize_credentials); networks.push_back(obj); } return networks; @@ -368,26 +368,26 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp) LOCK(cs_main); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("version", CLIENT_VERSION)); - obj.push_back(Pair("subversion", strSubVersion)); - obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); - obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices))); - obj.push_back(Pair("timeoffset", GetTimeOffset())); - obj.push_back(Pair("connections", (int)vNodes.size())); - obj.push_back(Pair("networks", GetNetworksInfo())); - obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); + obj.pushKV("version", CLIENT_VERSION); + obj.pushKV("subversion", strSubVersion); + obj.pushKV("protocolversion", PROTOCOL_VERSION); + obj.pushKV("localservices", strprintf("%016x", nLocalServices)); + obj.pushKV("timeoffset", GetTimeOffset()); + obj.pushKV("connections", (int)vNodes.size()); + obj.pushKV("networks", GetNetworksInfo()); + obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())); UniValue localAddresses(UniValue::VARR); { LOCK(cs_mapLocalHost); for (const std::pair &item : mapLocalHost) { UniValue rec(UniValue::VOBJ); - rec.push_back(Pair("address", item.first.ToString())); - rec.push_back(Pair("port", item.second.nPort)); - rec.push_back(Pair("score", item.second.nScore)); + rec.pushKV("address", item.first.ToString()); + rec.pushKV("port", item.second.nPort); + rec.pushKV("score", item.second.nScore); localAddresses.push_back(rec); } } - obj.push_back(Pair("localaddresses", localAddresses)); + obj.pushKV("localaddresses", localAddresses); return obj; } @@ -463,10 +463,10 @@ UniValue listbanned(const UniValue& params, bool fHelp) { CBanEntry banEntry = (*it).second; UniValue rec(UniValue::VOBJ); - rec.push_back(Pair("address", (*it).first.ToString())); - rec.push_back(Pair("banned_until", banEntry.nBanUntil)); - rec.push_back(Pair("ban_created", banEntry.nCreateTime)); - rec.push_back(Pair("ban_reason", banEntry.banReasonToString())); + rec.pushKV("address", (*it).first.ToString()); + rec.pushKV("banned_until", banEntry.nBanUntil); + rec.pushKV("ban_created", banEntry.nCreateTime); + rec.pushKV("ban_reason", banEntry.banReasonToString()); bannedAddresses.push_back(rec); } return bannedAddresses; diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index 4b17c9dfe8..a70b9d553c 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -33,9 +33,9 @@ std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id) { UniValue request(UniValue::VOBJ); - request.push_back(Pair("method", strMethod)); - request.push_back(Pair("params", params)); - request.push_back(Pair("id", id)); + request.pushKV("method", strMethod); + request.pushKV("params", params); + request.pushKV("id", id); return request.write() + "\n"; } @@ -43,11 +43,11 @@ UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const Un { UniValue reply(UniValue::VOBJ); if (!error.isNull()) - reply.push_back(Pair("result", NullUniValue)); + reply.pushKV("result", NullUniValue); else - reply.push_back(Pair("result", result)); - reply.push_back(Pair("error", error)); - reply.push_back(Pair("id", id)); + reply.pushKV("result", result); + reply.pushKV("error", error); + reply.pushKV("id", id); return reply; } @@ -60,8 +60,8 @@ std::string JSONRPCReply(const UniValue& result, const UniValue& error, const Un UniValue JSONRPCError(int code, const std::string& message) { UniValue error(UniValue::VOBJ); - error.push_back(Pair("code", code)); - error.push_back(Pair("message", message)); + error.pushKV("code", code); + error.pushKV("message", message); return error; } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 5b7d603966..20644277d7 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -37,52 +37,52 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud std::vector addresses; int nRequired; - out.push_back(Pair("asm", scriptPubKey.ToString())); + out.pushKV("asm", scriptPubKey.ToString()); if (fIncludeHex) - out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())); if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) { - out.push_back(Pair("type", GetTxnOutputType(type))); + out.pushKV("type", GetTxnOutputType(type)); return; } - out.push_back(Pair("reqSigs", nRequired)); - out.push_back(Pair("type", GetTxnOutputType(type))); + out.pushKV("reqSigs", nRequired); + out.pushKV("type", GetTxnOutputType(type)); UniValue a(UniValue::VARR); for (const CTxDestination& addr : addresses) a.push_back(CBitcoinAddress(addr).ToString()); - out.push_back(Pair("addresses", a)); + out.pushKV("addresses", a); } void PoSBlockInfoToJSON(const uint256 hashBlock, int64_t nTime, int height, UniValue& entry) { - entry.push_back(Pair("posblockhash", hashBlock.GetHex())); - entry.push_back(Pair("time", nTime)); - entry.push_back(Pair("height", height)); - entry.push_back(Pair("isauditsuccessful", nTime > 0? "true":"false")); + entry.pushKV("posblockhash", hashBlock.GetHex()); + entry.pushKV("time", nTime); + entry.pushKV("height", height); + entry.pushKV("isauditsuccessful", nTime > 0? "true":"false"); } void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { - entry.push_back(Pair("txid", tx.GetHash().GetHex())); - entry.push_back(Pair("version", tx.nVersion)); - entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); - entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); - entry.push_back(Pair("txfee", ValueFromAmount(tx.nTxFee))); + entry.pushKV("txid", tx.GetHash().GetHex()); + entry.pushKV("version", tx.nVersion); + entry.pushKV("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)); + entry.pushKV("locktime", (int64_t)tx.nLockTime); + entry.pushKV("txfee", ValueFromAmount(tx.nTxFee)); if (tx.hasPaymentID && pwalletMain->IsMine(tx)) { - entry.push_back(Pair("paymentid", tx.paymentID)); + entry.pushKV("paymentid", tx.paymentID); } - entry.push_back(Pair("txType", (int64_t)tx.txType)); + entry.pushKV("txType", (int64_t)tx.txType); #ifdef ENABLE_WALLET LOCK(pwalletMain->cs_wallet); - entry.push_back(Pair("direction", pwalletMain->GetTransactionType(tx))); + entry.pushKV("direction", pwalletMain->GetTransactionType(tx)); #endif UniValue vin(UniValue::VARR); for (const CTxIn& txin : tx.vin) { UniValue in(UniValue::VOBJ); if (tx.IsCoinBase()) - in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + in.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); else { { //decoys @@ -92,8 +92,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) allDecoys.insert(allDecoys.begin(), txin.prevout); for (size_t i = 0; i < allDecoys.size(); i++) { UniValue decoy(UniValue::VOBJ); - decoy.push_back(Pair("txid", allDecoys[i].hash.GetHex())); - decoy.push_back(Pair("vout", (int64_t)allDecoys[i].n)); + decoy.pushKV("txid", allDecoys[i].hash.GetHex()); + decoy.pushKV("vout", (int64_t)allDecoys[i].n); #ifdef ENABLE_WALLET std::map::const_iterator mi = pwalletMain->mapWallet.find(allDecoys[i].hash); if (mi != pwalletMain->mapWallet.end()) { @@ -108,49 +108,49 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) CKey blind; pwalletMain->RevealTxOutAmount(prev, prev.vout[allDecoys[i].n], decodedAmount, blind); if (pwalletMain->IsLocked()) { - decoy.push_back(Pair("decoded_amount", "Wallet is Locked")); + decoy.pushKV("decoded_amount", "Wallet is Locked"); } else { - decoy.push_back(Pair("decoded_amount", ValueFromAmount(decodedAmount))); + decoy.pushKV("decoded_amount", ValueFromAmount(decodedAmount)); } - decoy.push_back(Pair("isMine", true)); + decoy.pushKV("isMine", true); } } } else { - decoy.push_back(Pair("isMine", false)); + decoy.pushKV("isMine", false); } } } #endif decoys.push_back(decoy); } - in.push_back(Pair("decoys", decoys)); + in.pushKV("decoys", decoys); } UniValue o(UniValue::VOBJ); - o.push_back(Pair("asm", txin.scriptSig.ToString())); - o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); - in.push_back(Pair("scriptSig", o)); + o.pushKV("asm", txin.scriptSig.ToString()); + o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); + in.pushKV("scriptSig", o); } - in.push_back(Pair("sequence", (int64_t)txin.nSequence)); - in.push_back(Pair("keyimage", txin.keyImage.GetHex())); - in.push_back(Pair("ringsize", (int64_t) (txin.decoys.size() + 1))); + in.pushKV("sequence", (int64_t)txin.nSequence); + in.pushKV("keyimage", txin.keyImage.GetHex()); + in.pushKV("ringsize", (int64_t) (txin.decoys.size() + 1)); vin.push_back(in); } - entry.push_back(Pair("vin", vin)); + entry.pushKV("vin", vin); UniValue vout(UniValue::VARR); for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; UniValue out(UniValue::VOBJ); - out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - out.push_back(Pair("n", (int64_t)i)); + out.pushKV("value", ValueFromAmount(txout.nValue)); + out.pushKV("n", (int64_t)i); UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(txout.scriptPubKey, o, true); - out.push_back(Pair("scriptPubKey", o)); - out.push_back(Pair("encoded_amount", txout.maskValue.amount.GetHex())); - out.push_back(Pair("encoded_mask", txout.maskValue.mask.GetHex())); + out.pushKV("scriptPubKey", o); + out.pushKV("encoded_amount", txout.maskValue.amount.GetHex()); + out.pushKV("encoded_mask", txout.maskValue.mask.GetHex()); CPubKey txPubKey(txout.txPub); - out.push_back(Pair("txpubkey", txPubKey.GetHex())); - out.push_back(Pair("commitment", HexStr(txout.commitment.begin(), txout.commitment.end()))); + out.pushKV("txpubkey", txPubKey.GetHex()); + out.pushKV("commitment", HexStr(txout.commitment.begin(), txout.commitment.end())); #ifdef ENABLE_WALLET if (pwalletMain->IsMine(txout)) { @@ -166,32 +166,32 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) pBlind = blind.begin(); } if (pwalletMain->IsLocked()) { - out.push_back(Pair("decoded_amount", "Wallet is Locked")); + out.pushKV("decoded_amount", "Wallet is Locked"); } else { - out.push_back(Pair("decoded_amount", ValueFromAmount(decodedAmount))); + out.pushKV("decoded_amount", ValueFromAmount(decodedAmount)); } - out.push_back(Pair("isMine", true)); + out.pushKV("isMine", true); } else { - out.push_back(Pair("isMine", false)); + out.pushKV("isMine", false); } #endif vout.push_back(out); } - entry.push_back(Pair("vout", vout)); + entry.pushKV("vout", vout); if (!hashBlock.IsNull()) { - entry.push_back(Pair("blockhash", hashBlock.GetHex())); + entry.pushKV("blockhash", hashBlock.GetHex()); BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (chainActive.Contains(pindex)) { - entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight)); - entry.push_back(Pair("time", pindex->GetBlockTime())); - entry.push_back(Pair("blocktime", pindex->GetBlockTime())); + entry.pushKV("confirmations", 1 + chainActive.Height() - pindex->nHeight); + entry.pushKV("time", pindex->GetBlockTime()); + entry.pushKV("blocktime", pindex->GetBlockTime()); } else - entry.push_back(Pair("confirmations", 0)); + entry.pushKV("confirmations", 0); } } } @@ -242,10 +242,10 @@ UniValue getrawtransactionbyblockheight(const UniValue& params, bool fHelp) std::string strHex = EncodeHexTx(tx); hexs.push_back(strHex); } - result.push_back(Pair("hexs", hexs)); - result.push_back(Pair("blockhash", block.GetHash().GetHex())); - result.push_back(Pair("confirmations", chainActive.Height() - nHeight + 1)); - result.push_back(Pair("blocktime", block.GetBlockTime())); + result.pushKV("hexs", hexs); + result.pushKV("blockhash", block.GetHash().GetHex()); + result.pushKV("confirmations", chainActive.Height() - nHeight + 1); + result.pushKV("blocktime", block.GetBlockTime()); return result; } @@ -365,7 +365,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) } UniValue result(UniValue::VOBJ); - if (blockindex) result.push_back(Pair("in_active_chain", in_active_chain)); + if (blockindex) result.pushKV("in_active_chain", in_active_chain); TxToJSON(tx, hash_block, result); return result; } @@ -452,27 +452,27 @@ UniValue listunspent(const UniValue& params, bool fHelp) CAmount nValue = pwalletMain->getCTxOutValue(*out.tx, out.tx->vout[out.i]); const CScript& pk = out.tx->vout[out.i].scriptPubKey; UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); - entry.push_back(Pair("vout", out.i)); + entry.pushKV("txid", out.tx->GetHash().GetHex()); + entry.pushKV("vout", out.i); CTxDestination address; if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { - entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); + entry.pushKV("address", CBitcoinAddress(address).ToString()); if (pwalletMain->mapAddressBook.count(address)) - entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + entry.pushKV("account", pwalletMain->mapAddressBook[address].name); } - entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); + entry.pushKV("scriptPubKey", HexStr(pk.begin(), pk.end())); if (pk.IsPayToScriptHash()) { CTxDestination address; if (ExtractDestination(pk, address)) { const CScriptID& hash = boost::get(address); CScript redeemScript; if (pwalletMain->GetCScript(hash, redeemScript)) - entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); + entry.pushKV("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())); } } - entry.push_back(Pair("amount", ValueFromAmount(nValue))); - entry.push_back(Pair("confirmations", out.nDepth)); - entry.push_back(Pair("spendable", out.fSpendable)); + entry.pushKV("amount", ValueFromAmount(nValue)); + entry.pushKV("confirmations", out.nDepth); + entry.pushKV("spendable", out.fSpendable); results.push_back(entry); } @@ -549,7 +549,7 @@ UniValue getunspentcount(const UniValue& params, bool fHelp) ++count; } UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("unspentcount", count)); + obj.pushKV("unspentcount", count); return obj; } #endif @@ -755,7 +755,7 @@ UniValue decodescript(const UniValue& params, bool fHelp) } ScriptPubKeyToJSON(script, r, false); - r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString())); + r.pushKV("p2sh", CBitcoinAddress(CScriptID(script)).ToString()); return r; } @@ -763,11 +763,11 @@ UniValue decodescript(const UniValue& params, bool fHelp) static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage) { UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("txid", txin.prevout.hash.ToString())); - entry.push_back(Pair("vout", (uint64_t)txin.prevout.n)); - entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); - entry.push_back(Pair("sequence", (uint64_t)txin.nSequence)); - entry.push_back(Pair("error", strMessage)); + entry.pushKV("txid", txin.prevout.hash.ToString()); + entry.pushKV("vout", (uint64_t)txin.prevout.n); + entry.pushKV("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); + entry.pushKV("sequence", (uint64_t)txin.nSequence); + entry.pushKV("error", strMessage); vErrorsRet.push_back(entry); } @@ -1015,10 +1015,10 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) bool fComplete = vErrors.empty(); UniValue result(UniValue::VOBJ); - result.push_back(Pair("hex", EncodeHexTx(mergedTx))); - result.push_back(Pair("complete", fComplete)); + result.pushKV("hex", EncodeHexTx(mergedTx)); + result.pushKV("complete", fComplete); if (!vErrors.empty()) { - result.push_back(Pair("errors", vErrors)); + result.pushKV("errors", vErrors); } return result; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 5668b35af5..320f0bf798 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -403,7 +403,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) file.close(); UniValue reply(UniValue::VOBJ); - reply.push_back(Pair("filename", filepath.string())); + reply.pushKV("filename", filepath.string()); return reply; } @@ -442,8 +442,8 @@ UniValue bip38encrypt(const UniValue& params, bool fHelp) std::string encryptedOut = BIP38_Encrypt(strAddress, strPassphrase, privKey, vchSecret.IsCompressed()); UniValue result(UniValue::VOBJ); - result.push_back(Pair("Addess", strAddress)); - result.push_back(Pair("Encrypted Key", encryptedOut)); + result.pushKV("Addess", strAddress); + result.pushKV("Encrypted Key", encryptedOut); return result; } @@ -476,7 +476,7 @@ UniValue bip38decrypt(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_WALLET_ERROR, "Failed To Decrypt"); UniValue result(UniValue::VOBJ); - result.push_back(Pair("privatekey", HexStr(privKey))); + result.pushKV("privatekey", HexStr(privKey)); CKey key; key.Set(privKey.begin(), privKey.end(), fCompressed); @@ -487,7 +487,7 @@ UniValue bip38decrypt(const UniValue& params, bool fHelp) CPubKey pubkey = key.GetPubKey(); pubkey.IsCompressed(); assert(key.VerifyPubKey(pubkey)); - result.push_back(Pair("Address", CBitcoinAddress(pubkey.GetID()).ToString())); + result.pushKV("Address", CBitcoinAddress(pubkey.GetID()).ToString()); CKeyID vchAddress = pubkey.GetID(); { pwalletMain->MarkDirty(); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 27f6912090..5dc26f7b36 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -52,31 +52,31 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) { int confirms = wtx.GetDepthInMainChain(false); int confirmsTotal = GetIXConfirmations(wtx.GetHash()) + confirms; - entry.push_back(Pair("confirmations", confirmsTotal)); - entry.push_back(Pair("bcconfirmations", confirms)); + entry.pushKV("confirmations", confirmsTotal); + entry.pushKV("bcconfirmations", confirms); if (wtx.IsCoinBase() || wtx.IsCoinStake()) - entry.push_back(Pair("generated", true)); + entry.pushKV("generated", true); if (confirms > 0) { - entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); - entry.push_back(Pair("blockheight", mapBlockIndex[wtx.hashBlock]->nHeight)); - entry.push_back(Pair("blockindex", wtx.nIndex)); - entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime())); + entry.pushKV("blockhash", wtx.hashBlock.GetHex()); + entry.pushKV("blockheight", mapBlockIndex[wtx.hashBlock]->nHeight); + entry.pushKV("blockindex", wtx.nIndex); + entry.pushKV("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()); } uint256 hash = wtx.GetHash(); - entry.push_back(Pair("txid", hash.GetHex())); + entry.pushKV("txid", hash.GetHex()); UniValue conflicts(UniValue::VARR); for (const uint256& conflict : wtx.GetConflicts()) conflicts.push_back(conflict.GetHex()); - entry.push_back(Pair("walletconflicts", conflicts)); - entry.push_back(Pair("time", wtx.GetTxTime())); - entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived)); + entry.pushKV("walletconflicts", conflicts); + entry.pushKV("time", wtx.GetTxTime()); + entry.pushKV("timereceived", (int64_t)wtx.nTimeReceived); if (wtx.hasPaymentID && pwalletMain->IsMine(wtx)) { - entry.push_back(Pair("paymentid", wtx.paymentID)); + entry.pushKV("paymentid", wtx.paymentID); } for (const PAIRTYPE(std::string, std::string) & item : wtx.mapValue) - entry.push_back(Pair(item.first, item.second)); + entry.pushKV(item.first, item.second); } std::string AccountFromValue(const UniValue& value) @@ -681,11 +681,11 @@ UniValue getbalances(const UniValue& params, bool fHelp) HelpExampleCli("getbalances", "")); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("total", ValueFromAmount(pwalletMain->GetBalance()))); - obj.push_back(Pair("spendable", ValueFromAmount(pwalletMain->GetSpendableBalance()))); - obj.push_back(Pair("pending", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); - obj.push_back(Pair("immature", ValueFromAmount(pwalletMain->GetImmatureBalance()))); - obj.push_back(Pair("locked", ValueFromAmount(pwalletMain->GetLockedCoins()))); + obj.pushKV("total", ValueFromAmount(pwalletMain->GetBalance())); + obj.pushKV("spendable", ValueFromAmount(pwalletMain->GetSpendableBalance())); + obj.pushKV("pending", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())); + obj.pushKV("immature", ValueFromAmount(pwalletMain->GetImmatureBalance())); + obj.pushKV("locked", ValueFromAmount(pwalletMain->GetLockedCoins())); return obj; } @@ -1041,19 +1041,19 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) } else { UniValue obj(UniValue::VOBJ); if (fIsWatchonly) - obj.push_back(Pair("involvesWatchonly", true)); - obj.push_back(Pair("address", address.ToString())); - obj.push_back(Pair("account", strAccount)); - obj.push_back(Pair("amount", ValueFromAmount(nAmount))); - obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); - obj.push_back(Pair("bcconfirmations", (nBCConf == std::numeric_limits::max() ? 0 : nBCConf))); + obj.pushKV("involvesWatchonly", true); + obj.pushKV("address", address.ToString()); + obj.pushKV("account", strAccount); + obj.pushKV("amount", ValueFromAmount(nAmount)); + obj.pushKV("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf)); + obj.pushKV("bcconfirmations", (nBCConf == std::numeric_limits::max() ? 0 : nBCConf)); UniValue transactions(UniValue::VARR); if (it != mapTally.end()) { for (const uint256& item : (*it).second.txids) { transactions.push_back(item.GetHex()); } } - obj.push_back(Pair("txids", transactions)); + obj.pushKV("txids", transactions); ret.push_back(obj); } } @@ -1065,11 +1065,11 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) int nBCConf = (*it).second.nBCConf; UniValue obj(UniValue::VOBJ); if ((*it).second.fIsWatchonly) - obj.push_back(Pair("involvesWatchonly", true)); - obj.push_back(Pair("account", (*it).first)); - obj.push_back(Pair("amount", ValueFromAmount(nAmount))); - obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); - obj.push_back(Pair("bcconfirmations", (nBCConf == std::numeric_limits::max() ? 0 : nBCConf))); + obj.pushKV("involvesWatchonly", true); + obj.pushKV("account", (*it).first); + obj.pushKV("amount", ValueFromAmount(nAmount)); + obj.pushKV("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf)); + obj.pushKV("bcconfirmations", (nBCConf == std::numeric_limits::max() ? 0 : nBCConf)); ret.push_back(obj); } } @@ -1144,7 +1144,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) { CBitcoinAddress addr; if (addr.Set(dest)) - entry.push_back(Pair("address", addr.ToString())); + entry.pushKV("address", addr.ToString()); } void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) @@ -1164,8 +1164,8 @@ void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int n for (const COutputEntry& s : listSent) { UniValue entry(UniValue::VOBJ); if (involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) - entry.push_back(Pair("involvesWatchonly", true)); - entry.push_back(Pair("account", strSentAccount)); + entry.pushKV("involvesWatchonly", true); + entry.pushKV("account", strSentAccount); MaybePushAddress(entry, s.destination); // Calculate amounts for this transaction @@ -1176,19 +1176,19 @@ void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int n if (wtx.IsCoinStake()) { if (wtx.GetDepthInMainChain() < 1) { - entry.push_back(Pair("category", "orphan")); + entry.pushKV("category", "orphan"); } else if (wtx.GetBlocksToMaturity() > 0) { - entry.push_back(Pair("category", "immature")); + entry.pushKV("category", "immature"); } else { - entry.push_back(Pair("category", "generate")); + entry.pushKV("category", "generate"); } - entry.push_back(Pair("amount", ValueFromAmount(nAmountWithoutFee))); + entry.pushKV("amount", ValueFromAmount(nAmountWithoutFee)); } else { - entry.push_back(Pair("category", "send")); - entry.push_back(Pair("amount", ValueFromAmount(-nAmountWithoutFee))); + entry.pushKV("category", "send"); + entry.pushKV("amount", ValueFromAmount(-nAmountWithoutFee)); } - entry.push_back(Pair("vout", s.vout)); - entry.push_back(Pair("fee", ValueFromAmount(-nFee))); + entry.pushKV("vout", s.vout); + entry.pushKV("fee", ValueFromAmount(-nFee)); if (fLong) WalletTxToJSON(wtx, entry); ret.push_back(entry); @@ -1204,21 +1204,21 @@ void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int n if (fAllAccounts || (account == strAccount)) { UniValue entry(UniValue::VOBJ); if (involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) - entry.push_back(Pair("involvesWatchonly", true)); - entry.push_back(Pair("account", account)); + entry.pushKV("involvesWatchonly", true); + entry.pushKV("account", account); MaybePushAddress(entry, r.destination); if (wtx.IsCoinBase()) { if (wtx.GetDepthInMainChain() < 1) - entry.push_back(Pair("category", "orphan")); + entry.pushKV("category", "orphan"); else if (wtx.GetBlocksToMaturity() > 0) - entry.push_back(Pair("category", "immature")); + entry.pushKV("category", "immature"); else - entry.push_back(Pair("category", "generate")); + entry.pushKV("category", "generate"); } else { - entry.push_back(Pair("category", "receive")); + entry.pushKV("category", "receive"); } - entry.push_back(Pair("amount", ValueFromAmount(r.amount))); - entry.push_back(Pair("vout", r.vout)); + entry.pushKV("amount", ValueFromAmount(r.amount)); + entry.pushKV("vout", r.vout); if (fLong) WalletTxToJSON(wtx, entry); ret.push_back(entry); @@ -1233,12 +1233,12 @@ void AcentryToJSON(const CAccountingEntry& acentry, const std::string& strAccoun if (fAllAccounts || acentry.strAccount == strAccount) { UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("account", acentry.strAccount)); - entry.push_back(Pair("category", "move")); - entry.push_back(Pair("time", acentry.nTime)); - entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit))); - entry.push_back(Pair("otheraccount", acentry.strOtherAccount)); - entry.push_back(Pair("comment", acentry.strComment)); + entry.pushKV("account", acentry.strAccount); + entry.pushKV("category", "move"); + entry.pushKV("time", acentry.nTime); + entry.pushKV("amount", ValueFromAmount(acentry.nCreditDebit)); + entry.pushKV("otheraccount", acentry.strOtherAccount); + entry.pushKV("comment", acentry.strComment); ret.push_back(entry); } } @@ -1538,7 +1538,7 @@ UniValue listaccounts(const UniValue& params, bool fHelp) UniValue ret(UniValue::VOBJ); for (const PAIRTYPE(std::string, CAmount) & accountBalance : mapAccountBalances) { - ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); + ret.pushKV(accountBalance.first, ValueFromAmount(accountBalance.second)); } return ret; } @@ -1620,8 +1620,8 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : UINT256_ZERO; UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("transactions", transactions)); - ret.push_back(Pair("lastblock", lastblock.GetHex())); + ret.pushKV("transactions", transactions); + ret.pushKV("lastblock", lastblock.GetHex()); return ret; } @@ -1682,18 +1682,18 @@ UniValue gettransaction(const UniValue& params, bool fHelp) CAmount nDebit = wtx.GetDebit(filter); CAmount nNet = (nCredit > nDebit)? (nCredit - nDebit):(nDebit - nCredit); CAmount nFee = wtx.nTxFee; - entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); + entry.pushKV("amount", ValueFromAmount(nNet - nFee)); if (wtx.IsFromMe(filter)) - entry.push_back(Pair("fee", ValueFromAmount(nFee))); + entry.pushKV("fee", ValueFromAmount(nFee)); WalletTxToJSON(wtx, entry); UniValue details(UniValue::VARR); ListTransactions(wtx, "*", 0, false, details, filter); - entry.push_back(Pair("details", details)); + entry.pushKV("details", details); std::string strHex = EncodeHexTx(static_cast(wtx)); - entry.push_back(Pair("hex", strHex)); + entry.pushKV("hex", strHex); return entry; } @@ -2056,8 +2056,8 @@ UniValue listlockunspent(const UniValue& params, bool fHelp) for (COutPoint& outpt : vOutpts) { UniValue o(UniValue::VOBJ); - o.push_back(Pair("txid", outpt.hash.GetHex())); - o.push_back(Pair("vout", (int)outpt.n)); + o.pushKV("txid", outpt.hash.GetHex()); + o.pushKV("vout", (int)outpt.n); ret.push_back(o); } @@ -2113,17 +2113,17 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); - obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); - obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); - obj.push_back(Pair("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance()))); - obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); - obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); - obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); + obj.pushKV("walletversion", pwalletMain->GetVersion()); + obj.pushKV("balance", ValueFromAmount(pwalletMain->GetBalance())); + obj.pushKV("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())); + obj.pushKV("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance())); + obj.pushKV("txcount", (int)pwalletMain->mapWallet.size()); + obj.pushKV("keypoololdest", pwalletMain->GetOldestKeyPoolTime()); + obj.pushKV("keypoolsize", (int)pwalletMain->GetKeyPoolSize()); if (pwalletMain->IsCrypted()) - obj.push_back(Pair("walletunlocked", !pwalletMain->IsLocked())); - obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); - obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); + obj.pushKV("walletunlocked", !pwalletMain->IsLocked()); + obj.pushKV("unlocked_until", nWalletUnlockTime); + obj.pushKV("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())); return obj; } @@ -2143,7 +2143,7 @@ UniValue gettxcount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); + obj.pushKV("txcount", (int)pwalletMain->mapWallet.size()); return obj; } @@ -2191,8 +2191,8 @@ UniValue reservebalance(const UniValue& params, bool fHelp) } UniValue result(UniValue::VOBJ); - result.push_back(Pair("reserve", (nReserveBalance > 0))); - result.push_back(Pair("amount", ValueFromAmount(nReserveBalance))); + result.pushKV("reserve", (nReserveBalance > 0)); + result.pushKV("amount", ValueFromAmount(nReserveBalance)); return result; } @@ -2227,12 +2227,12 @@ UniValue setstakesplitthreshold(const UniValue& params, bool fHelp) UniValue result(UniValue::VOBJ); pwalletMain->nStakeSplitThreshold = nStakeSplitThreshold; - result.push_back(Pair("threshold", int(pwalletMain->nStakeSplitThreshold))); + result.pushKV("threshold", int(pwalletMain->nStakeSplitThreshold)); if (fFileBacked) { walletdb.WriteStakeSplitThreshold(nStakeSplitThreshold); - result.push_back(Pair("saved", "true")); + result.pushKV("saved", "true"); } else - result.push_back(Pair("saved", "false")); + result.pushKV("saved", "false"); return result; } @@ -2287,8 +2287,8 @@ UniValue autocombinedust(const UniValue& params, bool fHelp) throw std::runtime_error("Changed settings in wallet but failed to save to database\n"); UniValue result(UniValue::VOBJ); - result.push_back(Pair("autocombinedust", params[0].get_bool())); - result.push_back(Pair("amount", int(pwalletMain->nAutoCombineThreshold))); + result.pushKV("autocombinedust", params[0].get_bool()); + result.pushKV("amount", int(pwalletMain->nAutoCombineThreshold)); return result; } @@ -2296,14 +2296,14 @@ UniValue printMultiSend() { UniValue ret(UniValue::VARR); UniValue act(UniValue::VARR); - act.push_back(Pair("MultiSendStake Activated?", pwalletMain->fMultiSendStake)); - act.push_back(Pair("MultiSendMasternode Activated?", pwalletMain->fMultiSendMasternodeReward)); + act.pushKV("MultiSendStake Activated?", pwalletMain->fMultiSendStake); + act.pushKV("MultiSendMasternode Activated?", pwalletMain->fMultiSendMasternodeReward); ret.push_back(act); if (pwalletMain->vDisabledAddresses.size() >= 1) { UniValue disAdd(UniValue::VOBJ); for (unsigned int i = 0; i < pwalletMain->vDisabledAddresses.size(); i++) { - disAdd.push_back(Pair("Disabled From Sending", pwalletMain->vDisabledAddresses[i])); + disAdd.pushKV("Disabled From Sending", pwalletMain->vDisabledAddresses[i]); } ret.push_back(disAdd); } @@ -2312,8 +2312,8 @@ UniValue printMultiSend() UniValue vMS(UniValue::VOBJ); for (unsigned int i = 0; i < pwalletMain->vMultiSend.size(); i++) { - vMS.push_back(Pair("Address " + std::to_string(i), pwalletMain->vMultiSend[i].first)); - vMS.push_back(Pair("Percent", pwalletMain->vMultiSend[i].second)); + vMS.pushKV("Address " + std::to_string(i), pwalletMain->vMultiSend[i].first); + vMS.pushKV("Percent", pwalletMain->vMultiSend[i].second); } ret.push_back(vMS); @@ -2341,8 +2341,8 @@ UniValue printAddresses() UniValue obj(UniValue::VOBJ); const std::string* strAdd = &(*it).first; const double* nBalance = &(*it).second; - obj.push_back(Pair("Address ", *strAdd)); - obj.push_back(Pair("Balance ", *nBalance)); + obj.pushKV("Address ", *strAdd); + obj.pushKV("Balance ", *nBalance); ret.push_back(obj); } @@ -2382,8 +2382,8 @@ UniValue multisend(const UniValue& params, bool fHelp) pwalletMain->setMultiSendDisabled(); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("Erased from database", erased)); - obj.push_back(Pair("Erased from RAM", true)); + obj.pushKV("Erased from database", erased); + obj.pushKV("Erased from RAM", true); return obj; } @@ -2395,7 +2395,7 @@ UniValue multisend(const UniValue& params, bool fHelp) pwalletMain->fMultiSendStake = true; if (!walletdb.WriteMSettings(true, pwalletMain->fMultiSendMasternodeReward, pwalletMain->nLastMultiSendHeight)) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("error", "MultiSend activated but writing settings to DB failed")); + obj.pushKV("error", "MultiSend activated but writing settings to DB failed"); UniValue arr(UniValue::VARR); arr.push_back(obj); arr.push_back(printMultiSend()); @@ -2414,7 +2414,7 @@ UniValue multisend(const UniValue& params, bool fHelp) if (!walletdb.WriteMSettings(pwalletMain->fMultiSendStake, true, pwalletMain->nLastMultiSendHeight)) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("error", "MultiSend activated but writing settings to DB failed")); + obj.pushKV("error", "MultiSend activated but writing settings to DB failed"); UniValue arr(UniValue::VARR); arr.push_back(obj); arr.push_back(printMultiSend()); @@ -2593,13 +2593,13 @@ UniValue createprivacyaccount(const UniValue& params, bool fHelp) i++; continue; } - ret.push_back(Pair("viewpublickey", viewAccount.vchPubKey.GetHex())); + ret.pushKV("viewpublickey", viewAccount.vchPubKey.GetHex()); - ret.push_back(Pair("spendpublickey", spendAccount.vchPubKey.GetHex())); + ret.pushKV("spendpublickey", spendAccount.vchPubKey.GetHex()); std::string stealthAddr; if (pwalletMain->EncodeStealthPublicAddress(viewAccount.vchPubKey, spendAccount.vchPubKey, stealthAddr)) { - ret.push_back(Pair("stealthaddress", stealthAddr)); + ret.pushKV("stealthaddress", stealthAddr); } break; } @@ -2648,8 +2648,8 @@ UniValue generateintegratedaddress(const UniValue& params, bool fHelp) } else { address = pwalletMain->GenerateIntegratedAddressWithRandomPaymentID("masteraccount", paymentID); } - ret.push_back(Pair("integratedaddress", address)); - ret.push_back(Pair("paymentid", paymentID)); + ret.pushKV("integratedaddress", address); + ret.pushKV("paymentid", paymentID); return ret; } @@ -2748,13 +2748,13 @@ UniValue createprivacysubaddress(const UniValue& params, bool fHelp) UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("viewpublickey", account.viewAccount.vchPubKey.GetHex())); + ret.pushKV("viewpublickey", account.viewAccount.vchPubKey.GetHex()); - ret.push_back(Pair("spendpublickey", account.spendAccount.vchPubKey.GetHex())); + ret.pushKV("spendpublickey", account.spendAccount.vchPubKey.GetHex()); std::string stealthAddr; if (pwalletMain->EncodeStealthPublicAddress(account.viewAccount.vchPubKey, account.spendAccount.vchPubKey, stealthAddr)) { - ret.push_back(Pair("stealthaddress", stealthAddr)); + ret.pushKV("stealthaddress", stealthAddr); } return ret; } @@ -2805,10 +2805,10 @@ UniValue decodestealthaddress(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Stealth address is not correctly formatted."); } - ret.push_back(Pair("spendpublickey", spendKey.GetHex())); - ret.push_back(Pair("viewpublickey", viewKey.GetHex())); + ret.pushKV("spendpublickey", spendKey.GetHex()); + ret.pushKV("viewpublickey", viewKey.GetHex()); if (hasPaymentID) { - ret.push_back(Pair("paymentid", paymentID)); + ret.pushKV("paymentid", paymentID); } return ret; @@ -2933,7 +2933,7 @@ UniValue setdecoyconfirmation(const UniValue& params, bool fHelp) } pwalletMain->DecoyConfirmationMinimum = confirmation; UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("decoy_confirmation", confirmation)); + ret.pushKV("decoy_confirmation", confirmation); return ret; } @@ -2953,7 +2953,7 @@ UniValue getdecoyconfirmation(const UniValue& params, bool fHelp) EnsureWallet(); UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("decoy_confirmation", pwalletMain->DecoyConfirmationMinimum)); + ret.pushKV("decoy_confirmation", pwalletMain->DecoyConfirmationMinimum); return ret; } @@ -3025,7 +3025,7 @@ UniValue showtxprivatekeys(const UniValue& params, bool fHelp) { std::string key = params[0].get_str() + std::to_string(i); std::string secret; if (db.ReadTxPrivateKey(key, secret)) { - ret.push_back(Pair(std::to_string(i), secret)); + ret.pushKV(std::to_string(i), secret); } else break; } return ret; @@ -3105,9 +3105,9 @@ UniValue erasewallettransactions(const UniValue& params, bool fHelp) { removedTxes = initialCount - newCount; UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("initial_utxo_count", initialCount)); - ret.push_back(Pair("new_utxo_count", newCount)); - ret.push_back(Pair("deleted_utxo_count", removedTxes)); + ret.pushKV("initial_utxo_count", initialCount); + ret.pushKV("new_utxo_count", newCount); + ret.pushKV("deleted_utxo_count", removedTxes); return ret; } From 9d57113285352ef9e583c80dc0a7d93c982b9016 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 26 Jun 2023 17:00:21 -0400 Subject: [PATCH 272/391] refactor: rpc: Remove vector copy from listtransactions --- src/wallet/rpcwallet.cpp | 44 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 27f6912090..24458a4480 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1341,24 +1341,10 @@ UniValue listtransactions(const UniValue& params, bool fHelp) if ((nFrom + nCount) > (int)ret.size()) nCount = ret.size() - nFrom; - std::vector arrTmp = ret.getValues(); - - std::vector::iterator first = arrTmp.begin(); - std::advance(first, nFrom); - - std::vector::iterator last = arrTmp.begin(); - std::advance(last, nFrom + nCount); - - if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); - if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); - - std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest - - ret.clear(); - ret.setArray(); - ret.push_backV(arrTmp); - - return ret; + const std::vector& txs = ret.getValues(); + UniValue result{UniValue::VARR}; + result.push_backV({ txs.rend() - nFrom - nCount, txs.rend() - nFrom }); // Return oldest to newest + return result; } UniValue listtransactionsbypaymentid(const UniValue& params, bool fHelp) @@ -1453,24 +1439,10 @@ UniValue listtransactionsbypaymentid(const UniValue& params, bool fHelp) if ((nFrom + nCount) > (int)ret.size()) nCount = ret.size() - nFrom; - std::vector arrTmp = ret.getValues(); - - std::vector::iterator first = arrTmp.begin(); - std::advance(first, nFrom); - - std::vector::iterator last = arrTmp.begin(); - std::advance(last, nFrom + nCount); - - if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); - if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); - - std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest - - ret.clear(); - ret.setArray(); - ret.push_backV(arrTmp); - - return ret; + const std::vector& txs = ret.getValues(); + UniValue result{UniValue::VARR}; + result.push_backV({ txs.rend() - nFrom - nCount, txs.rend() - nFrom }); // Return oldest to newest + return result; } UniValue listaccounts(const UniValue& params, bool fHelp) From 4ce2dc1e5a092b4afc41747818b62b7e0c0a766b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 26 Jun 2023 19:02:57 -0400 Subject: [PATCH 273/391] [rpc] Reduce scope of cs_main and cs_wallet locks in listtransactions --- src/wallet/rpcwallet.cpp | 54 ++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 24458a4480..1b7fe84963 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1298,8 +1298,6 @@ UniValue listtransactions(const UniValue& params, bool fHelp) "\nList transactions 100 to 120 from the tabby account\n" + HelpExampleCli("listtransactions", "\"tabby\" 20 100") + "\nAs a json rpc call\n" + HelpExampleRpc("listtransactions", "\"tabby\", 20, 100")); - LOCK2(cs_main, pwalletMain->cs_wallet); - std::string strAccount = "*"; if (params.size() > 0) strAccount = params[0].get_str(); @@ -1321,19 +1319,24 @@ UniValue listtransactions(const UniValue& params, bool fHelp) UniValue ret(UniValue::VARR); - const CWallet::TxItems & txOrdered = pwalletMain->wtxOrdered; + { + LOCK2(cs_main, pwalletMain->cs_wallet); + + const CWallet::TxItems& txOrdered = pwalletMain->wtxOrdered; - // iterate backwards until we have nCount items to return: - for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { - CWalletTx* const pwtx = (*it).second.first; - if (pwtx != 0) - ListTransactions(*pwtx, strAccount, 0, true, ret, filter); - CAccountingEntry* const pacentry = (*it).second.second; - if (pacentry != 0) - AcentryToJSON(*pacentry, strAccount, ret); + // iterate backwards until we have nCount items to return: + for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { + CWalletTx* const pwtx = (*it).second.first; + if (pwtx != 0) + ListTransactions(*pwtx, strAccount, 0, true, ret, filter); + CAccountingEntry* const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); - if ((int)ret.size() >= (nCount + nFrom)) break; + if ((int)ret.size() >= (nCount + nFrom)) break; + } } + // ret is newest to oldest if (nFrom > (int)ret.size()) @@ -1398,8 +1401,6 @@ UniValue listtransactionsbypaymentid(const UniValue& params, bool fHelp) "\nList transactions 100 to 120 from the Payment ID\n" + HelpExampleCli("listtransactionsbypaymentid", "123456 20 100") + "\nAs a json rpc call\n" + HelpExampleRpc("listtransactionsbypaymentid", "123456, 20, 100")); - LOCK2(cs_main, pwalletMain->cs_wallet); - std::string strAccount = "*"; uint64_t paymentID = 0; if (params.size() > 0) @@ -1419,19 +1420,24 @@ UniValue listtransactionsbypaymentid(const UniValue& params, bool fHelp) UniValue ret(UniValue::VARR); - const CWallet::TxItems & txOrdered = pwalletMain->wtxOrdered; + { + LOCK2(cs_main, pwalletMain->cs_wallet); + + const CWallet::TxItems& txOrdered = pwalletMain->wtxOrdered; - // iterate backwards until we have nCount items to return: - for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { - CWalletTx* const pwtx = (*it).second.first; - if (pwtx != 0 && (pwtx->hasPaymentID && pwtx->paymentID == paymentID)) - ListTransactions(*pwtx, strAccount, 0, true, ret, filter); - CAccountingEntry* const pacentry = (*it).second.second; - if (pacentry != 0) - AcentryToJSON(*pacentry, strAccount, ret); + // iterate backwards until we have nCount items to return: + for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { + CWalletTx* const pwtx = (*it).second.first; + if (pwtx != 0 && (pwtx->hasPaymentID && pwtx->paymentID == paymentID)) + ListTransactions(*pwtx, strAccount, 0, true, ret, filter); + CAccountingEntry* const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); - if ((int)ret.size() >= (nCount + nFrom)) break; + if ((int)ret.size() >= (nCount + nFrom)) break; + } } + // ret is newest to oldest if (nFrom > (int)ret.size()) From 44f53e2556935a62fb2efd813dac755e170f41b5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 13:49:03 -0400 Subject: [PATCH 274/391] Add configure option for c++17 --- configure.ac | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/configure.ac b/configure.ac index 38a88b20e6..17e51e03ac 100644 --- a/configure.ac +++ b/configure.ac @@ -66,6 +66,19 @@ case $host in ;; esac +AC_ARG_ENABLE([c++17], + [AS_HELP_STRING([--enable-c++17], + [enable compilation in c++17 mode (disabled by default)])], + [use_cxx17=$enableval], + [use_cxx17=no]) + +dnl Require C++14 or C++17 compiler (no GNU extensions) +if test "x$use_cxx17" = xyes; then + AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory]) +else + AX_CXX_COMPILE_STDCXX([14], [noext], [mandatory]) +fi + dnl Check if -latomic is required for CHECK_ATOMIC From 7b44d42c6f4e51ed993247ef6c1a016a085a747b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 25 Jun 2023 22:37:25 -0400 Subject: [PATCH 275/391] fixes for std::random_shuffle removal in C++17 --- src/txmempool.cpp | 6 +++++- src/wallet/wallet.cpp | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index f7a29d090e..5655d65db4 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -16,6 +16,8 @@ #include +#include +#include CTxMemPoolEntry::CTxMemPoolEntry() : nFee(0), nTxSize(0), nModSize(0), nTime(0), dPriority(0.0) { @@ -226,7 +228,9 @@ class CMinerPolicyEstimator // Insert at most 10 random entries per bucket, otherwise a single block // can dominate an estimate: if (e.size() > 10) { - std::random_shuffle(e.begin(), e.end()); + std::random_device rd; + std::mt19937 g(rd()); + std::shuffle(e.begin(), e.end(), g); e.resize(10); } for (const CTxMemPoolEntry* entry : e) { diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 39ba4aca21..d98d1a0ecc 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -46,6 +46,9 @@ #include #endif +#include +#include + CWallet* pwalletMain = nullptr; /** * Settings @@ -2810,7 +2813,9 @@ bool CWallet::SelectCoinsMinConf(bool needFee, CAmount& feeNeeded, int ringSize, CAmount nTotalLower = 0; std::string s = ""; - random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); + std::random_device rd; + std::mt19937 g(rd()); + std::shuffle(vCoins.begin(), vCoins.end(), g); for (const COutput& output : vCoins) { if (!output.fSpendable) From edf60cdc4962ba8b10c7439eea177d3eb825bccd Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 23 Mar 2023 13:51:12 -0400 Subject: [PATCH 276/391] build: Require C++17 compiler --- configure.ac | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 537696d329..8846e6cd08 100644 --- a/configure.ac +++ b/configure.ac @@ -66,18 +66,8 @@ case $host in ;; esac -AC_ARG_ENABLE([c++17], - [AS_HELP_STRING([--enable-c++17], - [enable compilation in c++17 mode (disabled by default)])], - [use_cxx17=$enableval], - [use_cxx17=no]) - -dnl Require C++14 or C++17 compiler (no GNU extensions) -if test "x$use_cxx17" = xyes; then - AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory]) -else - AX_CXX_COMPILE_STDCXX([14], [noext], [mandatory]) -fi +dnl Require C++17 compiler (no GNU extensions) +AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory]) dnl Check if -latomic is required for CHECK_ATOMIC From 8116b5e27e8319307b238c4a0a435de38cb9090b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 26 Jun 2023 12:51:27 -0400 Subject: [PATCH 277/391] Add MakeUnique (substitute for C++14 std::make_unique) --- src/util.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/util.h b/src/util.h index bdc944e876..d7b07cc529 100644 --- a/src/util.h +++ b/src/util.h @@ -189,4 +189,11 @@ void TraceThread(const char* name, Callable func) fs::path AbsPathForConfigVal(const boost::filesystem::path& path, bool net_specific = true); bool PointHashingSuccessively(const CPubKey& pk, const unsigned char* tweak, unsigned char* out); +//! Substitute for C++14 std::make_unique. +template +std::unique_ptr MakeUnique(Args&&... args) +{ + return std::unique_ptr(new T(std::forward(args)...)); +} + #endif // BITCOIN_UTIL_H From 6bdbf124a6b03cc4946e1b7dec2fdaea260ce73a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 26 Jun 2023 15:23:52 -0400 Subject: [PATCH 278/391] Use std::make_unique --- src/util.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/util.h b/src/util.h index d7b07cc529..b8fd70253d 100644 --- a/src/util.h +++ b/src/util.h @@ -190,10 +190,11 @@ fs::path AbsPathForConfigVal(const boost::filesystem::path& path, bool net_speci bool PointHashingSuccessively(const CPubKey& pk, const unsigned char* tweak, unsigned char* out); //! Substitute for C++14 std::make_unique. +//! DEPRECATED use std::make_unique in new code. template std::unique_ptr MakeUnique(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); + return std::make_unique(std::forward(args)...); } #endif // BITCOIN_UTIL_H From 75567379e009686f53fbd5b2079882b9d880dddb Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 27 Jun 2023 13:39:30 -0400 Subject: [PATCH 279/391] [Startup] Decrease the amount of blocks checked for corruption in the startup. 100 blocks checked for corruption is too much, having only 10 is more than enough to verify the db consistency. --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index cab4c9e07e..a61248ceff 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1484,7 +1484,7 @@ bool AppInit2(bool isDaemon) } //Must check at level 4 - if (!CVerifyDB().VerifyDB(pcoinsdbview, 4, GetArg("-checkblocks", 100))) { + if (!CVerifyDB().VerifyDB(pcoinsdbview, 4, GetArg("-checkblocks", 10))) { strLoadError = _("Corrupted block database detected"); fVerifyingBlocks = false; break; From 090b82ac6a4e98e4de6684f5cb461141c73bddfe Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 17:03:51 -0400 Subject: [PATCH 280/391] Fix QPainter non-determinism on macOS Applies a patch to Qt that fixes the non-determinism by modifying Qt. The source of the non-determinism is how LLVM 8 optimizes qt_intersect_spans when compiling. The particular optimization that seems to be causing the problems is that a temp variable is being added for spans->y. For some reason, when it does this, it chooses different instructions to use when making that variable. We bypass this problem by patching qt_intersect_spans to always make and use this local variable. --- depends/packages/qt.mk | 3 +- .../qt/fix_qpainter_non_determinism.patch | 63 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 depends/patches/qt/fix_qpainter_non_determinism.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 2665712e92..d05eb587fe 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -12,7 +12,7 @@ $(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch $(package)_patches+= fix_rcc_determinism.patch fix_riscv64_arch.patch xkb-default.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch $(package)_patches+= freetype_back_compat.patch drop_lrelease_dependency.patch -$(package)_patches+= fix_mingw_cross_compile.patch +$(package)_patches+= fix_mingw_cross_compile.patch fix_qpainter_non_determinism.patch # Update OSX_QT_TRANSLATIONS when this is updated $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) @@ -218,6 +218,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix_riscv64_arch.patch && \ patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_mingw_cross_compile.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch && \ sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ diff --git a/depends/patches/qt/fix_qpainter_non_determinism.patch b/depends/patches/qt/fix_qpainter_non_determinism.patch new file mode 100644 index 0000000000..3cfcc22f03 --- /dev/null +++ b/depends/patches/qt/fix_qpainter_non_determinism.patch @@ -0,0 +1,63 @@ +commit 2a8f7dc6ddfc414a66491522501c1574a1343ee1 +Author: Andrew Chow +Date: Sat Nov 21 01:11:04 2020 -0500 + + build: Fix determinism issue when building with Clang 8 + + When building Qt with LLVM/Clang 8 under -O3 (the default), we run into + a determinism issue in `qt_interset_spans`. The issue has been fixed for + LLVM/Clang 9, see + https://github.com/llvm/llvm-project/commit/db101864bdc938deb1d63fe4f7da761bd38e5cae + and https://reviews.llvm.org/D64601, however this fix was not backported + to 8.x. Once LLVM/Clang 9 is used, this patch can be dropped. + + The particular issue appears to be an optimization done by -O3 which + adds a temporary variable for `spans->y` in `qt_intersect_spans`. When + it does this, sometimes it chooses to use a 32-bit movs instruction + (movswl), and other times it chooses a 64-bit movs instruction (movswq). + By patching `qt_intersect_spans` to always make a temporary variable for + `spans->y`, we are able to sidestep this problem. + +diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp +index 92ab6e8375..f018009e0b 100644 +--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp ++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp +@@ -3971,22 +3971,23 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, + const QSpan *clipEnd = clip->m_spans + clip->count; + + while (available && spans < end ) { ++ const short spans_y = spans->y; + if (clipSpans >= clipEnd) { + spans = end; + break; + } +- if (clipSpans->y > spans->y) { ++ if (clipSpans->y > spans_y) { + ++spans; + continue; + } +- if (spans->y != clipSpans->y) { +- if (spans->y < clip->count && clip->m_clipLines[spans->y].spans) +- clipSpans = clip->m_clipLines[spans->y].spans; ++ if (spans_y != clipSpans->y) { ++ if (spans_y < clip->count && clip->m_clipLines[spans_y].spans) ++ clipSpans = clip->m_clipLines[spans_y].spans; + else + ++clipSpans; + continue; + } +- Q_ASSERT(spans->y == clipSpans->y); ++ Q_ASSERT(spans_y == clipSpans->y); + + int sx1 = spans->x; + int sx2 = sx1 + spans->len; +@@ -4005,7 +4006,7 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, + if (len) { + out->x = qMax(sx1, cx1); + out->len = qMin(sx2, cx2) - out->x; +- out->y = spans->y; ++ out->y = spans_y; + out->coverage = qt_div_255(spans->coverage * clipSpans->coverage); + ++out; + --available; + From c8cabcb5633f2b598b6470428e16edbae392d401 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 17 Mar 2023 10:01:49 -0400 Subject: [PATCH 281/391] build: only pass -optimized-tools to qt in debug mode Qt's configure tells us that "-optimized-tools is not useful in -release mode.", so don't use it there. --- depends/packages/qt.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index d05eb587fe..d9b3edd429 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -29,6 +29,7 @@ $(package)_config_env = QT_MAC_SDK_NO_VERSION_CHECK=1 $(package)_config_opts_release = -release $(package)_config_opts_release += -silent $(package)_config_opts_debug = -debug +$(package)_config_opts_debug += -optimized-tools $(package)_config_opts += -bindir $(build_prefix)/bin $(package)_config_opts += -c++std c++1z $(package)_config_opts += -confirm-license From 82f84ebd037bbe144a42dca9338f2afc09725b1f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 4 Apr 2023 14:44:06 -0400 Subject: [PATCH 282/391] build: Add xkbcommon 0.8.4 --- contrib/devtools/symbol-check.py | 2 ++ contrib/gitian-descriptors/gitian-linux.yml | 1 + depends/README.md | 2 +- depends/packages/libxkbcommon.mk | 32 +++++++++++++++++++++ depends/packages/packages.mk | 2 +- depends/packages/qt.mk | 5 ++-- 6 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 depends/packages/libxkbcommon.mk diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 044b28bbbf..eb5d538f6b 100644 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -70,6 +70,8 @@ 'libX11-xcb.so.1', # part of X11 'libX11.so.6', # part of X11 'libxcb.so.1', # part of X11 +'libxkbcommon.so.0', # keyboard keymapping +'libxkbcommon-x11.so.0', # keyboard keymapping 'libfontconfig.so.1', # font support 'libfreetype.so.6', # font parsing 'libdl.so.2' # programming interface to dynamic linker diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index ac3653cd45..6ef33063e8 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -23,6 +23,7 @@ packages: - "g++-8-multilib" - "gcc-8-multilib" - "binutils-gold" +- "bison" - "git" - "pkg-config" - "autoconf" diff --git a/depends/README.md b/depends/README.md index e704649a01..62cb9d28da 100644 --- a/depends/README.md +++ b/depends/README.md @@ -59,7 +59,7 @@ For more information, see [SDK Extraction](../contrib/macdeploy/README.md#sdk-ex Common linux dependencies: - sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch + sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch bison For linux ARM cross compilation: diff --git a/depends/packages/libxkbcommon.mk b/depends/packages/libxkbcommon.mk new file mode 100644 index 0000000000..cdd5af194b --- /dev/null +++ b/depends/packages/libxkbcommon.mk @@ -0,0 +1,32 @@ +package=libxkbcommon +$(package)_version=0.8.4 +$(package)_download_path=https://xkbcommon.org/download/ +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=60ddcff932b7fd352752d51a5c4f04f3d0403230a584df9a2e0d5ed87c486c8b +$(package)_dependencies=libxcb + +define $(package)_set_vars +$(package)_config_opts = --enable-option-checking --disable-dependency-tracking +$(package)_config_opts += --disable-static --disable-docs +endef + +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf share/man share/doc lib/*.la +endef + diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 666bc9973a..aaf9faee98 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -2,7 +2,7 @@ packages:=boost openssl libevent libcurl qt_packages = qrencode zlib -qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig +qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig libxkbcommon qt_android_packages=qt qt_darwin_packages=qt diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index d9b3edd429..3006f11788 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -5,7 +5,7 @@ $(package)_suffix=opensource-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) $(package)_sha256_hash=d5a97381b9339c0fbaf13f0c05d599a5c999dcf94145044058198987183fed65 $(package)_dependencies=openssl zlib -$(package)_linux_dependencies=freetype fontconfig libxcb +$(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib concurrent $(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch @@ -108,8 +108,7 @@ endif # for macOS on Apple Silicon (ARM) see https://bugreports.qt.io/browse/QTBUG-85279 $(package)_config_opts_aarch64_darwin += -device-option QMAKE_APPLE_DEVICE_ARCHS=arm64 -$(package)_config_opts_linux = -qt-xkbcommon-x11 -$(package)_config_opts_linux += -qt-xcb +$(package)_config_opts_linux = -qt-xcb $(package)_config_opts_linux += -no-xcb-xlib $(package)_config_opts_linux += -no-feature-xlib $(package)_config_opts_linux += -system-freetype From fa2ba5b841b502bf78054519ed063920f3338eba Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 15:20:08 -0400 Subject: [PATCH 283/391] build: qt 5.12.10 remove fix_configure_mac.patch Fixed upstream: https://bugreports.qt.io/browse/QTBUG-67286 remove fix_riscv64_arch.patch Was fixed upstream in 6a39e49a6cdeb28a04a3657bb6a22f848d5dfa9d remove fix_rcc_determinism.patch Fixed upstream in https://bugreports.qt.io/browse/QTBUG-62511 remove freetype_back_compat.patch By the time we ship a release with Qt 5.12, we'll certainly no-longer be supporting Ubuntu 14.04 and Ubuntu 16.04 ships with FreeType 2.6.1, which is new enough that using the symbol is no-longer an issue. The renaming of FT_Get_X11_Font_Format() happened in FreeType 2.6 remove xkb-default.patch This was removed upstream in d5abf545971da717014d316127045fc19edbcd65 --- build-aux/m4/bitcoin_qt.m4 | 12 ++++- depends/packages/qt.mk | 38 +++++++------- .../patches/qt/fix_android_qmake_conf.patch | 24 +++------ depends/patches/qt/fix_configure_mac.patch | 50 ------------------- .../patches/qt/fix_mingw_cross_compile.patch | 25 ---------- depends/patches/qt/fix_no_printer.patch | 4 +- depends/patches/qt/fix_qt_pkgconfig.patch | 12 ++--- depends/patches/qt/fix_rcc_determinism.patch | 15 ------ depends/patches/qt/fix_riscv64_arch.patch | 14 ------ depends/patches/qt/freetype_back_compat.patch | 28 ----------- depends/patches/qt/xkb-default.patch | 26 ---------- 11 files changed, 43 insertions(+), 205 deletions(-) delete mode 100644 depends/patches/qt/fix_configure_mac.patch delete mode 100644 depends/patches/qt/fix_mingw_cross_compile.patch delete mode 100644 depends/patches/qt/fix_rcc_determinism.patch delete mode 100644 depends/patches/qt/fix_riscv64_arch.patch delete mode 100644 depends/patches/qt/freetype_back_compat.patch delete mode 100644 depends/patches/qt/xkb-default.patch diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index a1284761f0..89f17ad9cc 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -129,12 +129,21 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) fi if test "x$TARGET_OS" = xwindows; then + dnl Linking against wtsapi32 is required. See #17749 and + dnl https://bugreports.qt.io/browse/QTBUG-27097. + AX_CHECK_LINK_FLAG([-lwtsapi32], [QT_LIBS="$QT_LIBS -lwtsapi32"], [AC_MSG_ERROR([could not link against -lwtsapi32])]) _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows]) AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows]) elif test "x$TARGET_OS" = xlinux; then + dnl workaround for https://bugreports.qt.io/browse/QTBUG-74874 + AX_CHECK_LINK_FLAG([-lxcb-shm], [QT_LIBS="-lxcb-shm $QT_LIBS"], [AC_MSG_ERROR([could not link against -lxcb-shm])])sssssss _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)],[-lqxcb -lxcb-static]) AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb]) elif test "x$TARGET_OS" = xdarwin; then + AX_CHECK_LINK_FLAG([[-framework Carbon]],[QT_LIBS="$QT_LIBS -framework Carbon"],[AC_MSG_ERROR(could not link against Carbon framework)]) + AX_CHECK_LINK_FLAG([[-framework IOSurface]],[QT_LIBS="$QT_LIBS -framework IOSurface"],[AC_MSG_ERROR(could not link against IOSurface framework)]) + AX_CHECK_LINK_FLAG([[-framework Metal]],[QT_LIBS="$QT_LIBS -framework Metal"],[AC_MSG_ERROR(could not link against Metal framework)]) + AX_CHECK_LINK_FLAG([[-framework QuartzCore]],[QT_LIBS="$QT_LIBS -framework QuartzCore"],[AC_MSG_ERROR(could not link against QuartzCore framework)]) _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)],[-lqcocoa]) AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa]) elif test "x$TARGET_OS" = xandroid; then @@ -324,7 +333,8 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ elif test "x$TARGET_OS" = xdarwin; then PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ClipboardSupport${qt_lib_suffix} $QT_LIBS"]) PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport${qt_lib_suffix}], [QT_LIBS="-lQt5GraphicsSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport${qt_lib_suffix}], [QT_LIBS="-lQt5CglSupport${qt_lib_suffix} $QT_LIBS"]) + elif test "x$TARGET_OS" = xwindows; then + PKG_CHECK_MODULES([QTWINDOWSUIAUTOMATION], [Qt5WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="-lQt5WindowsUIAutomationSupport${qt_lib_suffix} $QT_LIBS"]) fi fi ]) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 3006f11788..97b1f2b85f 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,25 +1,24 @@ PACKAGE=qt -$(package)_version=5.9.9 -$(package)_download_path=https://download.qt.io/archive/qt/5.9/$($(package)_version)/submodules -$(package)_suffix=opensource-src-$($(package)_version).tar.xz +$(package)_version=5.12.10 +$(package)_download_path=https://download.qt.io/archive/qt/5.12/$($(package)_version)/submodules +$(package)_suffix=everywhere-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=d5a97381b9339c0fbaf13f0c05d599a5c999dcf94145044058198987183fed65 +$(package)_sha256_hash=8088f174e6d28e779516c083b6087b6a9e3c8322b4bc161fd1b54195e3c86940 $(package)_dependencies=openssl zlib $(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib concurrent -$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch -$(package)_patches+= fix_rcc_determinism.patch fix_riscv64_arch.patch xkb-default.patch no-xlib.patch +$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch -$(package)_patches+= freetype_back_compat.patch drop_lrelease_dependency.patch -$(package)_patches+= fix_mingw_cross_compile.patch fix_qpainter_non_determinism.patch +$(package)_patches+= drop_lrelease_dependency.patch +$(package)_patches+= fix_qpainter_non_determinism.patch # Update OSX_QT_TRANSLATIONS when this is updated $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=f7474f260a1382549720081bf2359a3d425ec3bf7d31976c512834303d30d73b +$(package)_qttranslations_sha256_hash=e1de58ed108b7e0a138815ea60fd46a2c4e1fc31396a707e5630e92de79c53de $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=fce6e0fd39a40bcef880c669080087dba94af1ec442296222210472e0852bf98 +$(package)_qttools_sha256_hash=b0cfa6e7aac41b7c61fc59acc04843d7a98f9e1840370611751bcfc1834a636c $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) @@ -49,7 +48,6 @@ $(package)_config_opts += -no-libudev $(package)_config_opts += -no-mtdev $(package)_config_opts += -no-openvg $(package)_config_opts += -no-reduce-relocations -$(package)_config_opts += -no-qml-debug $(package)_config_opts += -no-sql-db2 $(package)_config_opts += -no-sql-ibase $(package)_config_opts += -no-sql-oci @@ -60,7 +58,6 @@ $(package)_config_opts += -no-sql-psql $(package)_config_opts += -no-sql-sqlite $(package)_config_opts += -no-sql-sqlite2 $(package)_config_opts += -no-use-gold-linker -$(package)_config_opts += -no-xinput2 $(package)_config_opts += -nomake examples $(package)_config_opts += -nomake tests $(package)_config_opts += -opensource @@ -76,13 +73,16 @@ $(package)_config_opts += -system-zlib $(package)_config_opts += -static $(package)_config_opts += -v $(package)_config_opts += -no-feature-dial +$(package)_config_opts += -no-feature-dtls $(package)_config_opts += -no-feature-ftp $(package)_config_opts += -no-feature-lcdnumber $(package)_config_opts += -no-feature-pdf $(package)_config_opts += -no-feature-printer $(package)_config_opts += -no-feature-printdialog $(package)_config_opts += -feature-concurrent +$(package)_config_opts += -no-feature-securetransport $(package)_config_opts += -no-feature-sql +$(package)_config_opts += -no-feature-sqlmodel $(package)_config_opts += -no-feature-statemachine $(package)_config_opts += -no-feature-syntaxhighlighter $(package)_config_opts += -no-feature-textbrowser @@ -94,6 +94,7 @@ $(package)_config_opts += -no-feature-xml $(package)_config_opts_darwin = -no-dbus $(package)_config_opts_darwin += -no-opengl $(package)_config_opts_darwin += -pch +$(package)_config_opts_darwin += -device-option QMAKE_MACOSX_DEPLOYMENT_TARGET=$(OSX_MIN_VERSION) ifneq ($(build_os),darwin) $(package)_config_opts_darwin += -xplatform macx-clang-linux @@ -115,6 +116,7 @@ $(package)_config_opts_linux += -system-freetype $(package)_config_opts_linux += -no-feature-sessionmanager $(package)_config_opts_linux += -fontconfig $(package)_config_opts_linux += -no-opengl +$(package)_config_opts_linux += -no-feature-vulkan $(package)_config_opts_linux += -dbus-runtime ifneq ($(LTO),) $(package)_config_opts_linux += -ltcg @@ -205,19 +207,13 @@ endef # 8. Adjust a regex in toolchain.prf, to accomodate Guix's usage of # CROSS_LIBRARY_PATH. See #15277. define $(package)_preprocess_cmds - patch -p1 -i $($(package)_patch_dir)/freetype_back_compat.patch && \ patch -p1 -i $($(package)_patch_dir)/drop_lrelease_dependency.patch && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_configure_mac.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_rcc_determinism.patch && \ - patch -p1 -i $($(package)_patch_dir)/xkb-default.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_android_qmake_conf.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_riscv64_arch.patch && \ - patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_mingw_cross_compile.patch && \ + patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch && \ sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ @@ -236,8 +232,8 @@ define $(package)_preprocess_cmds sed -i.old "s|QMAKE_CFLAGS += |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ sed -i.old "s|QMAKE_CXXFLAGS += |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ sed -i.old "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s|QMAKE_CC = clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \ - sed -i.old "s|QMAKE_CXX = clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \ + sed -i.old "s|QMAKE_CC = \$$$$\$$$${CROSS_COMPILE}clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \ + sed -i.old "s|QMAKE_CXX = \$$$$\$$$${CROSS_COMPILE}clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \ sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf endef diff --git a/depends/patches/qt/fix_android_qmake_conf.patch b/depends/patches/qt/fix_android_qmake_conf.patch index 13bfff9776..3a8753fd1d 100644 --- a/depends/patches/qt/fix_android_qmake_conf.patch +++ b/depends/patches/qt/fix_android_qmake_conf.patch @@ -1,20 +1,10 @@ --- old/qtbase/mkspecs/android-clang/qmake.conf +++ new/qtbase/mkspecs/android-clang/qmake.conf -@@ -30,7 +30,7 @@ - QMAKE_CFLAGS += -target mips64el-none-linux-android +@@ -47,7 +47,7 @@ ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so + ANDROID_USE_LLVM = true - QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH --QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -+QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -nostdlib++ - QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \ - -isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX \ - -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include \ -@@ -40,7 +40,7 @@ - ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH - - ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so --ANDROID_CXX_STL_LIBS = -lc++ -+ANDROID_CXX_STL_LIBS = -lc++_shared - - QMAKE_ARM_CFLAGS_RELEASE = -Oz - QMAKE_ARM_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Oz + exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \ +- ANDROID_CXX_STL_LIBS = -lc++ ++ ANDROID_CXX_STL_LIBS = -lc++_shared + else: \ + ANDROID_CXX_STL_LIBS = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so.$$replace(ANDROID_PLATFORM, "android-", "") diff --git a/depends/patches/qt/fix_configure_mac.patch b/depends/patches/qt/fix_configure_mac.patch deleted file mode 100644 index 0d7dd647de..0000000000 --- a/depends/patches/qt/fix_configure_mac.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- old/qtbase/mkspecs/features/mac/sdk.prf 2018-02-08 10:24:48.000000000 -0800 -+++ new/qtbase/mkspecs/features/mac/sdk.prf 2018-03-23 10:38:56.000000000 -0700 -@@ -8,21 +8,21 @@ - defineReplace(xcodeSDKInfo) { - info = $$1 - equals(info, "Path"): \ -- info = --show-sdk-path -+ infoarg = --show-sdk-path - equals(info, "PlatformPath"): \ -- info = --show-sdk-platform-path -+ infoarg = --show-sdk-platform-path - equals(info, "SDKVersion"): \ -- info = --show-sdk-version -+ infoarg = --show-sdk-version - sdk = $$2 - isEmpty(sdk): \ - sdk = $$QMAKE_MAC_SDK - - isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}) { -- QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$info 2>/dev/null") -+ QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$infoarg 2>/dev/null") - # --show-sdk-platform-path won't work for Command Line Tools; this is fine - # only used by the XCTest backend to testlib -- isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(info, "--show-sdk-platform-path")): \ -- error("Could not resolve SDK $$info for \'$$sdk\'") -+ isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(infoarg, "--show-sdk-platform-path")): \ -+ error("Could not resolve SDK $$info for \'$$sdk\' using $$infoarg") - cache(QMAKE_MAC_SDK.$${sdk}.$${info}, set stash, QMAKE_MAC_SDK.$${sdk}.$${info}) - } - ---- old/qtbase/configure 2018-02-08 10:24:48.000000000 -0800 -+++ new/qtbase/configure 2018-03-23 05:42:29.000000000 -0700 -@@ -232,8 +232,13 @@ - - sdk=$(getSingleQMakeVariable "QMAKE_MAC_SDK" "$1") - if [ -z "$sdk" ]; then echo "QMAKE_MAC_SDK must be set when building on Mac" >&2; exit 1; fi -- sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null) -- if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi -+ sysroot=$(getSingleQMakeVariable "QMAKE_MAC_SDK_PATH" "$1") -+ -+ echo "sysroot pre-configured as $sysroot"; -+ if [ -z "$sysroot" ]; then -+ sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null) -+ if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi -+ fi - - case "$sdk" in - macosx*) - - diff --git a/depends/patches/qt/fix_mingw_cross_compile.patch b/depends/patches/qt/fix_mingw_cross_compile.patch deleted file mode 100644 index 67f76f1d85..0000000000 --- a/depends/patches/qt/fix_mingw_cross_compile.patch +++ /dev/null @@ -1,25 +0,0 @@ -commit 5a992a549adfe5a587bbcd6cd2b2cee47d236e27 -Author: fanquake -Date: Fri Sep 4 08:13:44 2020 +0800 - - Work around broken mingw cross-compilation - - See upstream issues: - https://bugreports.qt.io/browse/QTBUG-63637 - https://bugreports.qt.io/browse/QTBUG-63659 - https://codereview.qt-project.org/q/8bebded9 - - We should be able to drop this once we are building qt 5.10.1 or later. - - Added in #12971. - -diff --git a/qtbase/mkspecs/win32-g++/qmake.conf b/qtbase/mkspecs/win32-g++/qmake.conf -index e071a0d1..ad229b10 100644 ---- a/qtbase/mkspecs/win32-g++/qmake.conf -+++ b/qtbase/mkspecs/win32-g++/qmake.conf -@@ -87,3 +87,5 @@ QMAKE_NM = $${CROSS_COMPILE}nm -P - include(../common/angle.conf) - - load(qt_config) -+QMAKE_LINK_OBJECT_MAX = 10 -+QMAKE_LINK_OBJECT_SCRIPT = object_script diff --git a/depends/patches/qt/fix_no_printer.patch b/depends/patches/qt/fix_no_printer.patch index f868ca2577..1372356138 100644 --- a/depends/patches/qt/fix_no_printer.patch +++ b/depends/patches/qt/fix_no_printer.patch @@ -10,10 +10,10 @@ --- x/qtbase/src/plugins/plugins.pro +++ y/qtbase/src/plugins/plugins.pro -@@ -8,6 +8,3 @@ qtHaveModule(gui) { - qtConfig(imageformatplugin): SUBDIRS *= imageformats +@@ -9,6 +9,3 @@ qtHaveModule(gui) { !android:qtConfig(library): SUBDIRS *= generic } + qtHaveModule(widgets): SUBDIRS += styles - -!winrt:qtHaveModule(printsupport): \ - SUBDIRS += printsupport diff --git a/depends/patches/qt/fix_qt_pkgconfig.patch b/depends/patches/qt/fix_qt_pkgconfig.patch index 8c722ffb46..a5de2b4b9e 100644 --- a/depends/patches/qt/fix_qt_pkgconfig.patch +++ b/depends/patches/qt/fix_qt_pkgconfig.patch @@ -1,17 +1,17 @@ --- old/qtbase/mkspecs/features/qt_module.prf +++ new/qtbase/mkspecs/features/qt_module.prf -@@ -264,7 +264,7 @@ +@@ -269,7 +269,7 @@ load(qt_installs) load(qt_targets) # this builds on top of qt_common --!internal_module:!lib_bundle:if(unix|mingw) { +-!internal_module:if(unix|mingw) { +if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) { CONFIG += create_pc QMAKE_PKGCONFIG_DESTDIR = pkgconfig host_build: \ -@@ -274,9 +274,9 @@ - QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw] - QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME +@@ -284,9 +284,9 @@ load(qt_targets) + QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE -I${includedir}/$$MODULE_INCNAME + } QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$QT_MAJOR_VERSION ") - QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION) + QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)$$qtPlatformTargetSuffix() @@ -20,4 +20,4 @@ + QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$section(QT.$${i}.VERSION, ., 0, 0))$$qtPlatformTargetSuffix() isEmpty(QMAKE_PKGCONFIG_DESCRIPTION): \ QMAKE_PKGCONFIG_DESCRIPTION = $$replace(TARGET, ^Qt, "Qt ") module - pclib_replace.match = $$lib_replace.match + !isEmpty(lib_replace0.match) { diff --git a/depends/patches/qt/fix_rcc_determinism.patch b/depends/patches/qt/fix_rcc_determinism.patch deleted file mode 100644 index c1b07fe23a..0000000000 --- a/depends/patches/qt/fix_rcc_determinism.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- old/qtbase/src/tools/rcc/rcc.cpp -+++ new/qtbase/src/tools/rcc/rcc.cpp -@@ -207,7 +207,11 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib) - if (lib.formatVersion() >= 2) { - // last modified time stamp - const QDateTime lastModified = m_fileInfo.lastModified(); -- lib.writeNumber8(quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0)); -+ quint64 lastmod = quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0); -+ static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong(); -+ if (sourceDate != 0) -+ lastmod = sourceDate; -+ lib.writeNumber8(lastmod); - if (text || pass1) - lib.writeChar('\n'); - } diff --git a/depends/patches/qt/fix_riscv64_arch.patch b/depends/patches/qt/fix_riscv64_arch.patch deleted file mode 100644 index e7f29f01f9..0000000000 --- a/depends/patches/qt/fix_riscv64_arch.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -index 20bfd36..93729fa 100644 ---- a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -+++ b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -@@ -65,7 +65,8 @@ - defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ - defined(__SH4__) || defined(__alpha__) || \ - defined(_MIPS_ARCH_MIPS32R2) || \ -- defined(__AARCH64EL__) -+ defined(__AARCH64EL__) || defined(__aarch64__) || \ -+ defined(__riscv) - #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 - #elif defined(_M_IX86) || defined(__i386__) || defined(__i386) - #if defined(_WIN32) diff --git a/depends/patches/qt/freetype_back_compat.patch b/depends/patches/qt/freetype_back_compat.patch deleted file mode 100644 index b0f1c98aa6..0000000000 --- a/depends/patches/qt/freetype_back_compat.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit 14bc77db61bf9d56f9b6c8b84aa02573605c19c6 -Author: fanquake -Date: Tue Aug 18 15:15:08 2020 +0800 - - Fix backwards compatibility with older Freetype versions at runtime - - A few years ago, libfreetype introduced FT_Get_Font_Format() as an alias - for FT_Get_X11_Font_Format(), but FT_Get_X11_Font_Format() was kept for abi - backwards-compatibility. - - Qt 5.9 introduced a call to FT_Get_Font_Format(). Replace it with FT_Get_X11_Font_Format() - in order to remain compatibile with older freetype, which is still used by e.g. Ubuntu Trusty. - - See #14348. - -diff --git a/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp -index 3f543755..8ecc1c8c 100644 ---- a/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp -+++ b/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp -@@ -898,7 +898,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, - } - } - #if defined(FT_FONT_FORMATS_H) -- const char *fmt = FT_Get_Font_Format(face); -+ const char *fmt = FT_Get_X11_Font_Format(face); - if (fmt && qstrncmp(fmt, "CFF", 4) == 0) { - FT_Bool no_stem_darkening = true; - FT_Error err = FT_Property_Get(qt_getFreetype(), "cff", "no-stem-darkening", &no_stem_darkening); diff --git a/depends/patches/qt/xkb-default.patch b/depends/patches/qt/xkb-default.patch deleted file mode 100644 index 165abf3e2e..0000000000 --- a/depends/patches/qt/xkb-default.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- old/qtbase/src/gui/configure.pri 2018-06-06 17:28:10.000000000 -0400 -+++ new/qtbase/src/gui/configure.pri 2018-08-17 18:43:01.589384567 -0400 -@@ -43,18 +43,11 @@ - } - - defineTest(qtConfTest_xkbConfigRoot) { -- qtConfTest_getPkgConfigVariable($${1}): return(true) -- -- for (dir, $$list("/usr/share/X11/xkb", "/usr/local/share/X11/xkb")) { -- exists($$dir) { -- $${1}.value = $$dir -- export($${1}.value) -- $${1}.cache += value -- export($${1}.cache) -- return(true) -- } -- } -- return(false) -+ $${1}.value = "/usr/share/X11/xkb" -+ export($${1}.value) -+ $${1}.cache += value -+ export($${1}.cache) -+ return(true) - } - - defineTest(qtConfTest_qpaDefaultPlatform) { From 69896de828d0cba8e9c0defb0ef6a21bb8160a12 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 16:31:49 -0400 Subject: [PATCH 284/391] build: Add QMacStyle support --- build-aux/m4/bitcoin_qt.m4 | 3 ++- src/qt/prcycoin.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 89f17ad9cc..5516133a74 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -145,6 +145,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ AX_CHECK_LINK_FLAG([[-framework Metal]],[QT_LIBS="$QT_LIBS -framework Metal"],[AC_MSG_ERROR(could not link against Metal framework)]) AX_CHECK_LINK_FLAG([[-framework QuartzCore]],[QT_LIBS="$QT_LIBS -framework QuartzCore"],[AC_MSG_ERROR(could not link against QuartzCore framework)]) _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)],[-lqcocoa]) + _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMacStylePlugin)],[-lqmacstyle]) AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa]) elif test "x$TARGET_OS" = xandroid; then QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lqtforandroid -ljnigraphics -landroid -lqtfreetype -lQt5EglSupport $QT_LIBS" @@ -315,7 +316,7 @@ dnl Inputs: qt_plugin_path. optional. dnl Outputs: QT_LIBS is appended AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ if test "x$qt_plugin_path" != x; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms" + QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms -L$qt_plugin_path/styles" if test -d "$qt_plugin_path/accessible"; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" fi diff --git a/src/qt/prcycoin.cpp b/src/qt/prcycoin.cpp index 04e393d524..93c30a2cc6 100644 --- a/src/qt/prcycoin.cpp +++ b/src/qt/prcycoin.cpp @@ -73,6 +73,7 @@ Q_IMPORT_PLUGIN(QXcbIntegrationPlugin); Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); #elif defined(QT_QPA_PLATFORM_COCOA) Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin); +Q_IMPORT_PLUGIN(QMacStylePlugin); #endif //Q_IMPORT_PLUGIN(QGifPlugin); #endif From d753d3eb42c76e964d391b982210d8d45877afac Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 17:36:47 -0400 Subject: [PATCH 285/391] build: disable qt SDK version checking This tries to invoke xcrun, which is not available when cross-compiling. Given we are in control of the SDK versions being used, removing this check has minimal-no effect. --- depends/packages/qt.mk | 3 ++- depends/patches/qt/no_sdk_version_check.patch | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 depends/patches/qt/no_sdk_version_check.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 97b1f2b85f..abf0366868 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -10,7 +10,7 @@ $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib concurrent $(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch -$(package)_patches+= drop_lrelease_dependency.patch +$(package)_patches+= drop_lrelease_dependency.patch no_sdk_version_check.patch $(package)_patches+= fix_qpainter_non_determinism.patch # Update OSX_QT_TRANSLATIONS when this is updated @@ -215,6 +215,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \ patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch && \ + patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \ sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ diff --git a/depends/patches/qt/no_sdk_version_check.patch b/depends/patches/qt/no_sdk_version_check.patch new file mode 100644 index 0000000000..b16635b572 --- /dev/null +++ b/depends/patches/qt/no_sdk_version_check.patch @@ -0,0 +1,20 @@ +commit f5eb142cd04be2bc4ca610ed3b5b7e8ce3520ee3 +Author: fanquake +Date: Tue Jan 5 16:08:49 2021 +0800 + + Don't invoke macOS SDK version checking + + This tries to use xcrun which is not available when cross-compiling. + +diff --git a/qtbase/mkspecs/features/mac/default_post.prf b/qtbase/mkspecs/features/mac/default_post.prf +index 92a9112bca6..447e186eb26 100644 +--- a/qtbase/mkspecs/features/mac/default_post.prf ++++ b/qtbase/mkspecs/features/mac/default_post.prf +@@ -8,7 +8,6 @@ contains(TEMPLATE, .*app) { + !macx-xcode:if(isEmpty(BUILDS)|build_pass) { + # Detect changes to the platform SDK + QMAKE_EXTRA_VARIABLES += QMAKE_MAC_SDK QMAKE_MAC_SDK_VERSION QMAKE_XCODE_DEVELOPER_PATH +- QMAKE_EXTRA_INCLUDES += $$shell_quote($$PWD/sdk.mk) + } + + # Detect incompatible SDK versions From fd2b0452179bb1936c3a2537d34d916e3367523f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 17:39:57 -0400 Subject: [PATCH 286/391] build, qt: Fix lib paths in *.pc files See: - QTBUG-72903, commit 9864d2c6f3b628ca9f07a56b197e77bd43931cca - QTBUG-78873, commit e55a61a77f0c87c05661a0335dfdb12673c6a27f Could be dropped for Qt 5.14+. --- depends/packages/qt.mk | 3 +- depends/patches/qt/fix_lib_paths.patch | 193 +++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 depends/patches/qt/fix_lib_paths.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index abf0366868..58d48ecfd1 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -11,7 +11,7 @@ $(package)_qt_libs=corelib network widgets gui plugins testlib concurrent $(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch $(package)_patches+= drop_lrelease_dependency.patch no_sdk_version_check.patch -$(package)_patches+= fix_qpainter_non_determinism.patch +$(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch # Update OSX_QT_TRANSLATIONS when this is updated $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) @@ -216,6 +216,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch && \ patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ diff --git a/depends/patches/qt/fix_lib_paths.patch b/depends/patches/qt/fix_lib_paths.patch new file mode 100644 index 0000000000..d1a15373f4 --- /dev/null +++ b/depends/patches/qt/fix_lib_paths.patch @@ -0,0 +1,193 @@ +--- old/qtbase/mkspecs/common/mac.conf ++++ new/qtbase/mkspecs/common/mac.conf +@@ -14,7 +14,6 @@ + + QMAKE_RESOURCE = /Developer/Tools/Rez + QMAKE_EXTENSION_SHLIB = dylib +-QMAKE_EXTENSIONS_AUX_SHLIB = tbd + QMAKE_LIBDIR = + + # sdk.prf will prefix the proper SDK sysroot + +--- old/qtbase/mkspecs/features/qmake_use.prf ++++ new/qtbase/mkspecs/features/qmake_use.prf +@@ -22,6 +22,8 @@ + !defined(QMAKE_LIBS_$$nu, var): \ + error("Library '$$lower($$replace(nu, _, -))' is not defined.") + ++ QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu) ++ + debug: \ + LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu) + else: \ + +--- old/qtbase/mkspecs/features/qt_configure.prf ++++ new/qtbase/mkspecs/features/qt_configure.prf +@@ -526,98 +526,23 @@ + return($$sysrootified) + } + +-# libs-var, libs, in-paths, out-paths-var ++# libs-var, libs, in-paths + defineTest(qtConfResolveLibs) { +- ret = true +- paths = $$3 +- out = +- copy = false +- for (l, 2) { +- $$copy { +- copy = false +- out += $$l +- } else: equals(l, "-s") { +- # em++ flag to link libraries from emscripten-ports; passed on literally. +- copy = true +- out += $$l +- } else: contains(l, "^-L.*") { +- lp = $$replace(l, "^-L", ) +- gcc: lp = $$qtGccSysrootifiedPath($$lp) +- !exists($$lp/.) { +- qtLog("Library path $$val_escape(lp) is invalid.") +- ret = false +- } else { +- paths += $$lp +- } +- } else: contains(l, "^-l.*") { +- lib = $$replace(l, "^-l", ) +- lcan = +- integrity:contains(lib, "^.*\\.a") { +- # INTEGRITY compiler searches for exact filename +- # if -l argument has .a suffix +- lcan += $${lib} +- } else: contains(lib, "^:.*") { +- # Use exact filename when -l:filename syntax is used. +- lib ~= s/^:// +- lcan += $${lib} +- } else: unix { +- # Under UNIX, we look for actual shared libraries, in addition +- # to static ones. +- shexts = $$QMAKE_EXTENSION_SHLIB $$QMAKE_EXTENSIONS_AUX_SHLIB +- for (ext, shexts) { +- lcan += $${QMAKE_PREFIX_SHLIB}$${lib}.$${ext} +- } +- lcan += \ +- $${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB} +- } else { +- # Under Windows, we look only for static libraries, as even for DLLs +- # one actually links against a static import library. +- mingw { +- lcan += \ +- # MinGW supports UNIX-style library naming in addition to +- # the MSVC style. +- lib$${lib}.dll.a lib$${lib}.a \ +- # Fun fact: prefix-less libraries are also supported. +- $${lib}.dll.a $${lib}.a +- } +- lcan += $${lib}.lib +- } +- l = $$qtConfFindInPathList($$lcan, $$paths $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS) +- isEmpty(l) { +- qtLog("None of [$$val_escape(lcan)] found in [$$val_escape(paths)] and global paths.") +- ret = false +- } else { +- out += $$l +- } +- } else { +- out += $$l +- } +- } +- $$1 = $$out ++ for (path, 3): \ ++ pre_lflags += -L$$path ++ $$1 = $$pre_lflags $$2 + export($$1) +- !isEmpty(4) { +- $$4 = $$paths +- export($$4) +- } +- return($$ret) +-} +- +-# source-var +-defineTest(qtConfResolveAllLibs) { +- ret = true +- !qtConfResolveLibs($${1}.libs, $$eval($${1}.libs), , $${1}.libdirs): \ +- ret = false +- for (b, $${1}.builds._KEYS_): \ +- !qtConfResolveLibs($${1}.builds.$${b}, $$eval($${1}.builds.$${b}), $$eval($${1}.libdirs), ): \ +- ret = false +- return($$ret) ++ return(true) + } + + # libs-var, in-paths, libs + defineTest(qtConfResolvePathLibs) { + ret = true +- gcc: 2 = $$qtGccSysrootifiedPaths($$2) +- for (libdir, 2) { ++ gcc: \ ++ local_paths = $$qtGccSysrootifiedPaths($$2) ++ else: \ ++ local_paths = $$2 ++ for (libdir, local_paths) { + !exists($$libdir/.) { + qtLog("Library path $$val_escape(libdir) is invalid.") + ret = false +@@ -667,8 +592,11 @@ + # includes-var, in-paths, test-object-var + defineTest(qtConfResolvePathIncs) { + ret = true +- gcc: 2 = $$qtGccSysrootifiedPaths($$2) +- for (incdir, 2) { ++ gcc: \ ++ local_paths = $$qtGccSysrootifiedPaths($$2) ++ else: \ ++ local_paths = $$2 ++ for (incdir, local_paths) { + !exists($$incdir/.) { + qtLog("Include path $$val_escape(incdir) is invalid.") + ret = false +@@ -727,6 +655,7 @@ + vars += $$eval(config.commandline.rev_assignments.$${iv}) + defined(config.input.$${iv}, var) { + eval($${1}.builds.$${b} = $$eval(config.input.$${iv})) ++ export($${1}.builds.$${b}) + $${1}.builds._KEYS_ *= $${b} + any = true + } else { +@@ -741,11 +670,14 @@ + export($${1}.builds._KEYS_) + # we also reset the generic libs, to avoid surprises. + $${1}.libs = ++ export($${1}.libs) + } + + # direct libs. overwrites inline libs. +- defined(config.input.$${input}.libs, var): \ ++ defined(config.input.$${input}.libs, var) { + eval($${1}.libs = $$eval(config.input.$${input}.libs)) ++ export($${1}.libs) ++ } + + includes = $$eval(config.input.$${input}.incdir) + +@@ -754,6 +686,7 @@ + !isEmpty(prefix) { + includes += $$prefix/include + $${1}.libs = -L$$prefix/lib $$eval($${1}.libs) ++ export($${1}.libs) + } + + libdir = $$eval(config.input.$${input}.libdir) +@@ -762,11 +695,9 @@ + for (ld, libdir): \ + libs += -L$$ld + $${1}.libs = $$libs $$eval($${1}.libs) ++ export($${1}.libs) + } + +- !qtConfResolveAllLibs($$1): \ +- return(false) +- + !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \ + return(false) + From 351c83505d72a71023c3b32eb22663f5956bff69 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 17:40:24 -0400 Subject: [PATCH 287/391] build: update qt lrelease patch for 5.12.10 --- depends/patches/qt/drop_lrelease_dependency.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/patches/qt/drop_lrelease_dependency.patch b/depends/patches/qt/drop_lrelease_dependency.patch index f6b2c9fc80..9b918af77c 100644 --- a/depends/patches/qt/drop_lrelease_dependency.patch +++ b/depends/patches/qt/drop_lrelease_dependency.patch @@ -14,7 +14,7 @@ diff --git a/qttranslations/translations/translations.pro b/qttranslations/trans index 694544c..eff339d 100644 --- a/qttranslations/translations/translations.pro +++ b/qttranslations/translations/translations.pro -@@ -109,3 +109,2 @@ updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} +@@ -107,3 +107,2 @@ updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} silent:updateqm.commands = @echo lrelease ${QMAKE_FILE_IN} && $$updateqm.commands -updateqm.depends = $$LRELEASE_EXE updateqm.name = LRELEASE ${QMAKE_FILE_IN} From 6397464b885784a7d146d6030241350760962644 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 17:40:45 -0400 Subject: [PATCH 288/391] build: update qt android jni static patch for 5.12.10 --- depends/patches/qt/fix_android_jni_static.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/patches/qt/fix_android_jni_static.patch b/depends/patches/qt/fix_android_jni_static.patch index 2f6ff00f40..f891da6ddf 100644 --- a/depends/patches/qt/fix_android_jni_static.patch +++ b/depends/patches/qt/fix_android_jni_static.patch @@ -1,6 +1,6 @@ --- old/qtbase/src/plugins/platforms/android/androidjnimain.cpp +++ new/qtbase/src/plugins/platforms/android/androidjnimain.cpp -@@ -890,6 +890,14 @@ +@@ -897,6 +897,14 @@ __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; } From 0e11e68cc048639d72d1fc66b7aabdea8b97b81d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 17:41:13 -0400 Subject: [PATCH 289/391] build: update qt no-xlib patch for 5.12.10 --- depends/patches/qt/no-xlib.patch | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/depends/patches/qt/no-xlib.patch b/depends/patches/qt/no-xlib.patch index fe82c2c73c..f4a6f09ee4 100644 --- a/depends/patches/qt/no-xlib.patch +++ b/depends/patches/qt/no-xlib.patch @@ -22,15 +22,15 @@ index 7c62c2e2b3..c05c6c0a07 100644 #include #include -@@ -384,6 +386,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) - w->setCursor(c, isBitmapCursor); +@@ -391,6 +393,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *window) + xcb_flush(xcb_connection()); } +#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) static int cursorIdForShape(int cshape) { int cursorId = 0; -@@ -437,6 +440,7 @@ static int cursorIdForShape(int cshape) +@@ -444,6 +447,7 @@ static int cursorIdForShape(int cshape) } return cursorId; } @@ -38,7 +38,7 @@ index 7c62c2e2b3..c05c6c0a07 100644 xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape) { -@@ -558,7 +562,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape) +@@ -556,7 +560,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape) xcb_cursor_t QXcbCursor::createFontCursor(int cshape) { xcb_connection_t *conn = xcb_connection(); @@ -48,22 +48,23 @@ index 7c62c2e2b3..c05c6c0a07 100644 xcb_cursor_t cursor = XCB_NONE; // Try Xcursor first -@@ -589,6 +595,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) +@@ -585,7 +591,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) + // Non-standard X11 cursors are created from bitmaps cursor = createNonStandardCursor(cshape); - +- +#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) // Create a glpyh cursor if everything else failed if (!cursor && cursorId) { cursor = xcb_generate_id(conn); -@@ -596,6 +603,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) +@@ -593,6 +599,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) cursorId, cursorId + 1, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0); } +#endif if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) { - const char *name = cursorNames[cshape]; + const char *name = cursorNames[cshape].front(); -- 2.22.0 From 71757191498f1aa8b26479f015810daa65fd7f10 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 17:41:39 -0400 Subject: [PATCH 290/391] build: update qt qpaint non determinism patch for 5.12.10 --- depends/patches/qt/fix_qpainter_non_determinism.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/patches/qt/fix_qpainter_non_determinism.patch b/depends/patches/qt/fix_qpainter_non_determinism.patch index 3cfcc22f03..44c45187c5 100644 --- a/depends/patches/qt/fix_qpainter_non_determinism.patch +++ b/depends/patches/qt/fix_qpainter_non_determinism.patch @@ -22,7 +22,7 @@ diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/pa index 92ab6e8375..f018009e0b 100644 --- a/qtbase/src/gui/painting/qpaintengine_raster.cpp +++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp -@@ -3971,22 +3971,23 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, +@@ -4128,22 +4128,23 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, const QSpan *clipEnd = clip->m_spans + clip->count; while (available && spans < end ) { @@ -51,7 +51,7 @@ index 92ab6e8375..f018009e0b 100644 int sx1 = spans->x; int sx2 = sx1 + spans->len; -@@ -4005,7 +4006,7 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, +@@ -4162,7 +4163,7 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, if (len) { out->x = qMax(sx1, cx1); out->len = qMin(sx2, cx2) - out->x; From 1ba53c3213527ce6fa1db5d7798bc5361052955a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 22:53:47 -0400 Subject: [PATCH 291/391] build, qt: Fix openssl linking --- depends/packages/qt.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 58d48ecfd1..44589d01dc 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -25,6 +25,7 @@ $(package)_extra_sources += $($(package)_qttools_file_name) define $(package)_set_vars $(package)_config_env = QT_MAC_SDK_NO_VERSION_CHECK=1 +$(package)_config_env += OPENSSL_LIBS="-lssl -lcrypto -lpthread -lws2_32 -lgdi32" $(package)_config_opts_release = -release $(package)_config_opts_release += -silent $(package)_config_opts_debug = -debug From 4fbd3c80480a025cf8209fde0c79c14260c141d8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 18:27:03 -0400 Subject: [PATCH 292/391] build: Do not build unused CoreWLAN stuff in depends for macOS --- depends/packages/qt.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 44589d01dc..f10bb730fe 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -95,6 +95,7 @@ $(package)_config_opts += -no-feature-xml $(package)_config_opts_darwin = -no-dbus $(package)_config_opts_darwin += -no-opengl $(package)_config_opts_darwin += -pch +$(package)_config_opts_darwin += -no-feature-corewlan $(package)_config_opts_darwin += -device-option QMAKE_MACOSX_DEPLOYMENT_TARGET=$(OSX_MIN_VERSION) ifneq ($(build_os),darwin) From 02c231691ab48e1be89a685a5b268e06306302b0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 18:29:41 -0400 Subject: [PATCH 293/391] build, qt, refactor: Drop sed commands for win32-g++/qmake.conf --- depends/packages/qt.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index f10bb730fe..2611352633 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -138,6 +138,9 @@ $(package)_config_opts_m68k_linux += -platform linux-g++ -xplatform linux-g++-32 $(package)_config_opts_mingw32 = -no-opengl $(package)_config_opts_mingw32 += -no-dbus $(package)_config_opts_mingw32 += -xplatform win32-g++ +$(package)_config_opts_mingw32 += "QMAKE_CFLAGS = '$($(package)_cflags) $($(package)_cppflags)'" +$(package)_config_opts_mingw32 += "QMAKE_CXXFLAGS = '$($(package)_cflags) $($(package)_cppflags)'" +$(package)_config_opts_mingw32 += "QMAKE_LFLAGS = '$($(package)_ldflags)'" $(package)_config_opts_mingw32 += -device-option CROSS_COMPILE="$(host)-" $(package)_config_opts_mingw32 += -pch @@ -233,9 +236,6 @@ define $(package)_preprocess_cmds echo "!host_build: QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "!host_build: QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ - sed -i.old "s|QMAKE_CFLAGS += |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s|QMAKE_CXXFLAGS += |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \ sed -i.old "s|QMAKE_CC = \$$$$\$$$${CROSS_COMPILE}clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \ sed -i.old "s|QMAKE_CXX = \$$$$\$$$${CROSS_COMPILE}clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \ sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf From 43e3f1b9982899e32df1a44a99e9064db08a0376 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 28 Jun 2023 18:32:26 -0400 Subject: [PATCH 294/391] build, qt: No longer need to set QT_RCC_TEST=1 for determinism Since Qt 5.3.1 hash seeding is disabled for rcc. See commit 5283a6c87beac5a43f612786fefd6e43f2c70bf6. --- contrib/gitian-descriptors/gitian-linux.yml | 1 - contrib/gitian-descriptors/gitian-osx.yml | 1 - contrib/gitian-descriptors/gitian-win.yml | 1 - contrib/guix/libexec/build.sh | 1 - depends/packages/qt.mk | 1 - 5 files changed, 5 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 6ef33063e8..a0546a6e96 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -49,7 +49,6 @@ script: | HOST_CXXFLAGS="-O2 -g" HOST_LDFLAGS=-static-libstdc++ - export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" export BUILD_DIR=`pwd` diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index e9e60e960b..110bcea1e1 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -40,7 +40,6 @@ script: | FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" - export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" export BUILD_DIR=`pwd` diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index d09e95f6f3..20723c4e7f 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -37,7 +37,6 @@ script: | HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" - export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" export BUILD_DIR=`pwd` diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 508b83b958..2f617f78fc 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -109,7 +109,6 @@ case "$HOST" in esac # Environment variables for determinism -export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" export TZ="UTC" diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 2611352633..67206c8af8 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -165,7 +165,6 @@ $(package)_config_opts_armv7a_android += -android-arch armeabi-v7a $(package)_config_opts_x86_64_android += -android-arch x86_64 $(package)_config_opts_i686_android += -android-arch i686 -$(package)_build_env = QT_RCC_TEST=1 $(package)_build_env += QT_RCC_SOURCE_DATE_OVERRIDE=1 endef From 418cbd12fdd93c8595bab002dbb0985962e681b4 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 29 Jun 2023 11:59:45 -0400 Subject: [PATCH 295/391] depends: Bump Qt version to 5.12.11 --- depends/packages/qt.mk | 8 ++++---- depends/patches/qt/fix_android_jni_static.patch | 2 +- doc/dependencies.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 67206c8af8..3031d9ab44 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,9 +1,9 @@ PACKAGE=qt -$(package)_version=5.12.10 +$(package)_version=5.12.11 $(package)_download_path=https://download.qt.io/archive/qt/5.12/$($(package)_version)/submodules $(package)_suffix=everywhere-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=8088f174e6d28e779516c083b6087b6a9e3c8322b4bc161fd1b54195e3c86940 +$(package)_sha256_hash=1c1b4e33137ca77881074c140d54c3c9747e845a31338cfe8680f171f0bc3a39 $(package)_dependencies=openssl zlib $(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon $(package)_build_subdir=qtbase @@ -15,10 +15,10 @@ $(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch # Update OSX_QT_TRANSLATIONS when this is updated $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=e1de58ed108b7e0a138815ea60fd46a2c4e1fc31396a707e5630e92de79c53de +$(package)_qttranslations_sha256_hash=577b0668a777eb2b451c61e8d026d79285371597ce9df06b6dee6c814164b7c3 $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=b0cfa6e7aac41b7c61fc59acc04843d7a98f9e1840370611751bcfc1834a636c +$(package)_qttools_sha256_hash=98b2aaca230458f65996f3534fd471d2ffd038dd58ac997c0589c06dc2385b4f $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) diff --git a/depends/patches/qt/fix_android_jni_static.patch b/depends/patches/qt/fix_android_jni_static.patch index f891da6ddf..a186aeb8f6 100644 --- a/depends/patches/qt/fix_android_jni_static.patch +++ b/depends/patches/qt/fix_android_jni_static.patch @@ -1,6 +1,6 @@ --- old/qtbase/src/plugins/platforms/android/androidjnimain.cpp +++ new/qtbase/src/plugins/platforms/android/androidjnimain.cpp -@@ -897,6 +897,14 @@ +@@ -898,6 +898,14 @@ __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; } diff --git a/doc/dependencies.md b/doc/dependencies.md index 7ec83d16ec..b31c0c95ee 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -21,7 +21,7 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | PCRE | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L66) | | Python (tests) | | [3.6](https://www.python.org/downloads) | | | | | qrencode | [3.4.4](https://fukuchi.org/works/qrencode) | | No | | | -| Qt | [5.9.9](https://download.qt.io/official_releases/qt/) | [5.5.1](https://github.com/bitcoin/bitcoin/issues/13478) | No | | | +| Qt | [5.12.11](https://download.qt.io/official_releases/qt/) | [5.5.1](https://github.com/bitcoin/bitcoin/issues/13478) | No | | | | XCB | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L87) (Linux only) | | xkbcommon | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L86) (Linux only) | | ZeroMQ | [4.3.1](https://github.com/zeromq/libzmq/releases) | 4.0.0 | No | | | From 3175cf322296fa98bc810dbcbb35a155ab4da740 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 29 Jun 2023 15:18:35 -0400 Subject: [PATCH 296/391] build: Makes rcc output always deterministic The Qt Resource Compiler (rcc) has a command-line option `--format-version` which has the default value 2. The only difference from `--format-version 1` is adding a last modified timestamp to the output file. That, in turn, forces us to use `QT_RCC_SOURCE_DATE_OVERRIDE=1` to get deterministic builds. This change makes rcc output always deterministic by using `--format-version 1` option that makes usage of the `QT_RCC_SOURCE_DATE_OVERRIDE` needless. Also it improves interaction with ccache. --- contrib/gitian-descriptors/gitian-linux.yml | 1 - contrib/gitian-descriptors/gitian-osx.yml | 1 - contrib/gitian-descriptors/gitian-win.yml | 1 - contrib/guix/libexec/build.sh | 1 - depends/packages/qt.mk | 2 -- src/Makefile.qt.include | 4 ++-- 6 files changed, 2 insertions(+), 8 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index a0546a6e96..c8548d46fe 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -49,7 +49,6 @@ script: | HOST_CXXFLAGS="-O2 -g" HOST_LDFLAGS=-static-libstdc++ - export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 110bcea1e1..bdefcf0b2d 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -40,7 +40,6 @@ script: | FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" - export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 20723c4e7f..a82034718b 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -37,7 +37,6 @@ script: | HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" - export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 2f617f78fc..27d0ce8944 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -109,7 +109,6 @@ case "$HOST" in esac # Environment variables for determinism -export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" export TZ="UTC" diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 3031d9ab44..23b3319335 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -164,8 +164,6 @@ $(package)_config_opts_aarch64_android += -android-arch arm64-v8a $(package)_config_opts_armv7a_android += -android-arch armeabi-v7a $(package)_config_opts_x86_64_android += -android-arch x86_64 $(package)_config_opts_i686_android += -android-arch i686 - -$(package)_build_env += QT_RCC_SOURCE_DATE_OVERRIDE=1 endef define $(package)_fetch_cmds diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 16bbb49424..dabbea0d88 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -448,13 +448,13 @@ translate: $(srcdir)/qt/prcycoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITC $(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM) @test -f $(RCC) @cp -f $< $(@D)/temp_$( $@ @rm $(@D)/temp_$( $@ CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno qt/temp_prcycoin_locale.qrc From e1840d825d8faf0f7c7c28ba6ff5bd433c2aacba Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 29 Jun 2023 15:48:48 -0400 Subject: [PATCH 297/391] build, qt: Fix compiling qt package in depends with GCC 11 --- depends/packages/qt.mk | 2 + depends/patches/qt/fix_limits_header.patch | 44 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 depends/patches/qt/fix_limits_header.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 23b3319335..408aa668d2 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -12,6 +12,7 @@ $(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch $(package)_patches+= drop_lrelease_dependency.patch no_sdk_version_check.patch $(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch +$(package)_patches+= fix_limits_header.patch # Update OSX_QT_TRANSLATIONS when this is updated $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) @@ -219,6 +220,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch && \ patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_limits_header.patch && \ sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ diff --git a/depends/patches/qt/fix_limits_header.patch b/depends/patches/qt/fix_limits_header.patch new file mode 100644 index 0000000000..e4313770e5 --- /dev/null +++ b/depends/patches/qt/fix_limits_header.patch @@ -0,0 +1,44 @@ +Fix compiling with GCC 11 + +See: https://bugreports.qt.io/browse/QTBUG-90395. + +Upstream commits: + - Qt 5.15 -- unavailable as open source + - Qt 6.0: b2af6332ea37e45ab230a7a5d2d278f86d961b83 + - Qt 6.1: 9c56d4da2ff631a8c1c30475bd792f6c86bda53c + +--- old/qtbase/src/corelib/global/qendian.h ++++ new/qtbase/src/corelib/global/qendian.h +@@ -44,6 +44,8 @@ + #include + #include + ++#include ++ + // include stdlib.h and hope that it defines __GLIBC__ for glibc-based systems + #include + #include + +--- old/qtbase/src/corelib/tools/qbytearraymatcher.h ++++ new/qtbase/src/corelib/tools/qbytearraymatcher.h +@@ -42,6 +42,8 @@ + + #include + ++#include ++ + QT_BEGIN_NAMESPACE + + + +--- old/qtbase/src/tools/moc/generator.cpp ++++ new/qtbase/src/tools/moc/generator.cpp +@@ -40,6 +40,8 @@ + #include + #include + ++#include ++ + #include + #include + From eddc4304707270aa132090d20cb425abe53428e5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 29 Jun 2023 16:39:21 -0400 Subject: [PATCH 298/391] Set AA_EnableHighDpiScaling attribute early Qt docs: This attribute must be set before QGuiApplication is constructed. --- src/qt/prcycoin.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qt/prcycoin.cpp b/src/qt/prcycoin.cpp index 93c30a2cc6..6bead4d775 100644 --- a/src/qt/prcycoin.cpp +++ b/src/qt/prcycoin.cpp @@ -585,16 +585,17 @@ int main(int argc, char* argv[]) Q_INIT_RESOURCE(prcycoin_locale); Q_INIT_RESOURCE(prcycoin); - BitcoinApplication app(argc, argv); // Generate high-dpi pixmaps QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #if QT_VERSION >= 0x050600 - QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif #ifdef Q_OS_MAC QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); #endif + BitcoinApplication app(argc, argv); + // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType(); // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType) From 6178ecb1972338fb27a7b8e61e196b8db71c2810 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 10:06:02 -0400 Subject: [PATCH 299/391] depends: Drop workaround for a fixed bug in Qt build system The bug reports: - https://bugreports.qt.io/browse/QTBUG-35444 - https://bugreports.qt.io/browse/QTBUG-32519 Fixed in Qt 5.3.0 (the workaround was introduced for Qt 5.2.1). --- depends/packages/qt.mk | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 408aa668d2..ce50f30729 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -263,10 +263,7 @@ define $(package)_stage_cmds $(MAKE) -C src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && cd .. && \ $(MAKE) -C qttools/src/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install_target && \ $(MAKE) -C qttools/src/linguist/lupdate INSTALL_ROOT=$($(package)_staging_dir) install_target && \ - $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets && \ - if `test -f qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a`; then \ - cp qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a $($(package)_staging_prefix_dir)/lib; \ - fi + $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets endef define $(package)_postprocess_cmds From f3a6ed539ec3908f92cbd978d36867062f3d7a95 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 09:22:51 -0400 Subject: [PATCH 300/391] depends: Do not set build_subdir for qt package This change makes the next commit possible without exporting the PATH variable. --- depends/packages/qt.mk | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 408aa668d2..665ae30628 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -6,7 +6,6 @@ $(package)_file_name=qtbase-$($(package)_suffix) $(package)_sha256_hash=1c1b4e33137ca77881074c140d54c3c9747e845a31338cfe8680f171f0bc3a39 $(package)_dependencies=openssl zlib $(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon -$(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib concurrent $(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch @@ -241,6 +240,7 @@ define $(package)_preprocess_cmds endef define $(package)_config_cmds + cd qtbase && \ ./configure $($(package)_config_opts) && \ echo "host_build: QT_CONFIG ~= s/system-zlib/zlib" >> mkspecs/qconfig.pri && \ echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \ @@ -253,14 +253,14 @@ endef define $(package)_build_cmds export PATH=$(build_prefix)/bin:$(PATH) && \ - $(MAKE) -C src $(addprefix sub-,$($(package)_qt_libs)) && \ - $(MAKE) -C ../qttools/src/linguist/lrelease && \ - $(MAKE) -C ../qttools/src/linguist/lupdate && \ - $(MAKE) -C ../qttranslations + $(MAKE) -C qtbase/src $(addprefix sub-,$($(package)_qt_libs)) && \ + $(MAKE) -C qttools/src/linguist/lrelease && \ + $(MAKE) -C qttools/src/linguist/lupdate && \ + $(MAKE) -C qttranslations endef define $(package)_stage_cmds - $(MAKE) -C src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && cd .. && \ + $(MAKE) -C qtbase/src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && \ $(MAKE) -C qttools/src/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install_target && \ $(MAKE) -C qttools/src/linguist/lupdate INSTALL_ROOT=$($(package)_staging_dir) install_target && \ $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets && \ From a96deee8a8fe1cb4d5a7568310af22c9d5f963db Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 09:24:21 -0400 Subject: [PATCH 301/391] depends: Use more legible qmake commands in qt package This change gets rid of multiple `../` that makes reasoning about the script and its maintaining much easier. --- depends/packages/qt.mk | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 665ae30628..18c716d4c5 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -244,11 +244,12 @@ define $(package)_config_cmds ./configure $($(package)_config_opts) && \ echo "host_build: QT_CONFIG ~= s/system-zlib/zlib" >> mkspecs/qconfig.pri && \ echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \ - $(MAKE) sub-src-clean && \ - cd ../qttranslations && ../qtbase/bin/qmake qttranslations.pro -o Makefile && \ - cd translations && ../../qtbase/bin/qmake translations.pro -o Makefile && cd ../.. && \ - cd qttools/src/linguist/lrelease/ && ../../../../qtbase/bin/qmake lrelease.pro -o Makefile && \ - cd ../lupdate/ && ../../../../qtbase/bin/qmake lupdate.pro -o Makefile && cd ../../../.. + cd .. && \ + $(MAKE) -C qtbase sub-src-clean && \ + qtbase/bin/qmake -o qttranslations/Makefile qttranslations/qttranslations.pro && \ + qtbase/bin/qmake -o qttranslations/translations/Makefile qttranslations/translations/translations.pro && \ + qtbase/bin/qmake -o qttools/src/linguist/lrelease/Makefile qttools/src/linguist/lrelease/lrelease.pro && \ + qtbase/bin/qmake -o qttools/src/linguist/lupdate/Makefile qttools/src/linguist/lupdate/lupdate.pro endef define $(package)_build_cmds From 27c7d57fb459df90c3c0725f735e0af45a1101a1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 09:18:01 -0400 Subject: [PATCH 302/391] build: Use XLIFF file to provide more context to Transifex translators Details: https://docs.transifex.com/formats/xliff --- build-aux/m4/bitcoin_qt.m4 | 6 +++++- src/Makefile.qt.include | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 5516133a74..7e5b678f74 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -212,6 +212,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt5 rcc5 rcc], $qt_bin_path) BITCOIN_QT_PATH_PROGS([LRELEASE], [lrelease-qt5 lrelease5 lrelease], $qt_bin_path) BITCOIN_QT_PATH_PROGS([LUPDATE], [lupdate-qt5 lupdate5 lupdate],$qt_bin_path, yes) + BITCOIN_QT_PATH_PROGS([LCONVERT], [lconvert-qt5 lconvert5 lconvert], $qt_bin_path, yes) MOC_DEFS='-DHAVE_CONFIG_H -I$(srcdir)' case $host in @@ -245,7 +246,10 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ AC_MSG_ERROR([libQtDBus not found. Install libQtDBus or remove --with-qtdbus.]) fi if test "x$LUPDATE" = x; then - AC_MSG_WARN([lupdate is required to update qt translations]) + AC_MSG_WARN([lupdate tool is required to update Qt translations.]) + fi + if test "x$LCONVERT" = x; then + AC_MSG_WARN([lconvert tool is required to update Qt translations.]) fi ],[ bitcoin_enable_qt=no diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index dabbea0d88..0127fa0bf6 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -444,6 +444,8 @@ $(srcdir)/qt/prcycoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wa translate: $(srcdir)/qt/prcycoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_BASE_CPP) qt/prcycoin.cpp $(BITCOIN_QT_WINDOWS_CPP) $(BITCOIN_QT_WALLET_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts $(srcdir)/qt/locale/prcycoin_en.ts + @test -n $(LCONVERT) || echo "lconvert is required for updating translations" + $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LCONVERT) -o $(srcdir)/qt/locale/prcycoin_en.xlf -i $(srcdir)/qt/locale/prcycoin_en.ts $(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM) @test -f $(RCC) From 15b1075b9992b5a8500ce538e2212501e97ba683 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 11:28:03 -0400 Subject: [PATCH 303/391] build: Add Qt lconvert tool to depends --- depends/packages/qt.mk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index f5d5465b44..c60aa7e7f4 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -249,7 +249,8 @@ define $(package)_config_cmds qtbase/bin/qmake -o qttranslations/Makefile qttranslations/qttranslations.pro && \ qtbase/bin/qmake -o qttranslations/translations/Makefile qttranslations/translations/translations.pro && \ qtbase/bin/qmake -o qttools/src/linguist/lrelease/Makefile qttools/src/linguist/lrelease/lrelease.pro && \ - qtbase/bin/qmake -o qttools/src/linguist/lupdate/Makefile qttools/src/linguist/lupdate/lupdate.pro + qtbase/bin/qmake -o qttools/src/linguist/lupdate/Makefile qttools/src/linguist/lupdate/lupdate.pro && \ + qtbase/bin/qmake -o qttools/src/linguist/lconvert/Makefile qttools/src/linguist/lconvert/lconvert.pro endef define $(package)_build_cmds @@ -257,6 +258,7 @@ define $(package)_build_cmds $(MAKE) -C qtbase/src $(addprefix sub-,$($(package)_qt_libs)) && \ $(MAKE) -C qttools/src/linguist/lrelease && \ $(MAKE) -C qttools/src/linguist/lupdate && \ + $(MAKE) -C qttools/src/linguist/lconvert && \ $(MAKE) -C qttranslations endef @@ -264,6 +266,7 @@ define $(package)_stage_cmds $(MAKE) -C qtbase/src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && \ $(MAKE) -C qttools/src/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install_target && \ $(MAKE) -C qttools/src/linguist/lupdate INSTALL_ROOT=$($(package)_staging_dir) install_target && \ + $(MAKE) -C qttools/src/linguist/lconvert INSTALL_ROOT=$($(package)_staging_dir) install_target && \ $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets endef From 19573942e707a9cad2ff2af68240d36cd5c29653 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 11:29:24 -0400 Subject: [PATCH 304/391] qt [experimental]: Add a translation comment and a disambiguation string The goal is to see the way the Transifex presents the added items to translators using an intermediate XLIFF translation file. --- src/qt/addressbookpage.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index d72cdcfdb6..3d333b0739 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -275,7 +275,8 @@ void AddressBookPage::on_exportButton_clicked() if (!writer.write()) { QMessageBox::critical(this, tr("Exporting Failed"), - tr("There was an error trying to save the address list to %1. Please try again.").arg(filename)); + //: %1 is a name of the file (e.g., "addrbook.csv") that the bitcoin addresses were exported to. + tr("There was an error trying to save the address list to %1. Please try again.", "An error message.").arg(filename)); } } From d95ccec29c25936ad3010b0a57db9b236db6121d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 12:06:21 -0400 Subject: [PATCH 305/391] Add bitcoin_en.xlf intermediate translation file to the repo As the bitcoin_en.xlf file is created by the `make -C src translate` command, other translation-related files are also updated. --- src/qt/locale/prcycoin_en.ts | 1274 ++++-- src/qt/locale/prcycoin_en.xlf | 7591 +++++++++++++++++++++++++++++++++ src/qt/prcycoinstrings.cpp | 33 +- 3 files changed, 8527 insertions(+), 371 deletions(-) create mode 100644 src/qt/locale/prcycoin_en.xlf diff --git a/src/qt/locale/prcycoin_en.ts b/src/qt/locale/prcycoin_en.ts index 24998a3199..8baebf37df 100644 --- a/src/qt/locale/prcycoin_en.ts +++ b/src/qt/locale/prcycoin_en.ts @@ -119,9 +119,11 @@ Exporting Failed - + There was an error trying to save the address list to %1. Please try again. - There was an error trying to save the address list to %1. Please try again. + An error message. + %1 is a name of the file (e.g., "addrbook.csv") that the bitcoin addresses were exported to. + There was an error trying to save the address list to %1. Please try again. @@ -250,7 +252,58 @@ IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - + + + + + Wallet Encryption Failed + + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. Please try again. + + + + + + The supplied passphrases do not match. Please try again. + + + + + Wallet Unlock Failed + + + + + The passphrase entered for the wallet unlock was incorrect. Please try again. + + + + + Wallet Decryption Failed + + + + + + The passphrase entered for the wallet decryption was incorrect. Please try again. + + + + + Passphrase Change Successful + + + + + Wallet passphrase was successfully changed. +Please remember your passphrase as there is no way to recover it. + + + + Warning: The Caps Lock key is on! Warning: The Caps Lock key is on! @@ -519,7 +572,7 @@ Show information about Qt - + &Show / Hide &Show / Hide @@ -549,7 +602,7 @@ Backup wallet to another location - + &Change Passphrase... &Change Passphrase... @@ -723,18 +776,8 @@ PRivaCY Dex Link - - - &PRCY Checker - - - - - PRCY Checker Link - - - + %n Active Connections @@ -742,7 +785,7 @@ - + Processed %n blocks of transaction history. Processed %n block of transaction history. @@ -750,7 +793,7 @@ - + Date: %1 Amount: %2 Type: %3 @@ -760,18 +803,17 @@ Confirmations: %5 - + Staking Disabled - + Staking Enabled - Enabling Staking... @@ -781,12 +823,12 @@ Confirmations: %5 - + &File &File - + &Settings &Settings @@ -816,7 +858,7 @@ Confirmations: %5 - + &Staking @@ -826,12 +868,12 @@ Confirmations: %5 - + &Network &Network - + &Debug Console @@ -846,7 +888,7 @@ Confirmations: %5 - + &Tools &Tools @@ -856,12 +898,12 @@ Confirmations: %5 &Help - + PRCY - + &Masternodes @@ -881,7 +923,17 @@ Confirmations: %5 - + + &Show Seed Phrase + + + + + Show 24 word wallet seed phrase + + + + &MultiSend @@ -1026,7 +1078,17 @@ Confirmations: %5 - + + &PRCY Toolkit + + + + + PRCY Toolkit Link + + + + &Telegram Tech Support @@ -1066,17 +1128,36 @@ Confirmations: %5 - + Social - + PRCY client - + + No Update Available + + + + + No update available. + +Your wallet is up to date. + + + + + Error checking for updates. + + + + + + Up to date Up to date @@ -1134,18 +1215,18 @@ Confirmations: %5 Transactions after this will not yet be visible. - + Loading Blocks... - + Syncing Blocks... - + %n Blocks @@ -1153,7 +1234,8 @@ Confirmations: %5 - + + Error Error @@ -1183,7 +1265,7 @@ Confirmations: %5 - + No Active Peers @@ -1193,7 +1275,7 @@ Confirmations: %5 - + Wallet is <b>encrypted</b> and currently <b>unlocked</b> for staking only @@ -1213,7 +1295,7 @@ Confirmations: %5 Wallet is <b>encrypted</b> and currently <b>locked</b> - + A fatal error occurred. PRCY can no longer continue safely and will quit. @@ -1259,7 +1341,7 @@ Confirmations: %5 ClientModel - + Total: %1 (IPv4: %2 / IPv6: %3 / Tor: %4 / Unknown: %5) @@ -1377,7 +1459,7 @@ Confirmations: %5 Priority - + Copy address Copy address @@ -1699,6 +1781,67 @@ lowercase letters, numbers, symbols) Esc + + + + Wallet Encryption Required + + + + + + There was no passphrase entered for the wallet. + +Wallet encryption is required for the security of your funds. + +What would you like to do? + + + + + + + + + Wallet Encryption Failed + + + + + The passphrase entered for wallet encryption was empty. Please try again. + + + + + The passphrase's length has to be more than 10. Please try again. + + + + + The passphrase must contain lower, upper, digit, symbol. Please try again. + + + + + The passphrases entered for wallet encryption is too weak. Please try again. + + + + + Wallet Encryption Successful + + + + + Wallet passphrase was successfully set. +Please remember your passphrase as there is no way to recover it. + + + + + The passphrases entered for wallet encryption do not match. Please try again. + + EnterMnemonics @@ -1717,6 +1860,26 @@ lowercase letters, numbers, symbols) Next + + + Recovery Phrase Import Successful + + + + + Your mnemonics have been successfully imported into the wallet. Rescanning will be scheduled to recover all your funds. + + + + + Recovery Phrase Invalid + + + + + Recovery phrase is invalid. Please try again and double check all words. + + FreespaceChecker @@ -1795,12 +1958,12 @@ lowercase letters, numbers, symbols) - + Show splash screen on startup (default: %u) - + Set language, for example "de_DE" (default: system locale) Set language, for example "de_DE" (default: system locale) @@ -1809,11 +1972,6 @@ lowercase letters, numbers, symbols) Start minimized Start minimized - - - Set SSL root certificates for payment request (default: -system-) - Set SSL root certificates for payment request (default: -system-) - HistoryPage @@ -1824,7 +1982,7 @@ lowercase letters, numbers, symbols) - + All Types @@ -1832,50 +1990,59 @@ lowercase letters, numbers, symbols) - + Sent Sent - + - + Received Received - + - + + Mined Mined - + - + + Minted - + - + + Masternode - + - + Payment to yourself Payment to yourself + + + + Rewards + + Min Amount @@ -2275,25 +2442,10 @@ Please check the address and try again. Open URI - - Open payment request from URI or file - Open payment request from URI or file - - - + URI: URI: - - - Select payment request file - Select payment request file - - - - Select payment request file to open - Select payment request file to open - OptionsDialog @@ -2561,7 +2713,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations&Cancel - + default default @@ -2633,7 +2785,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Backup Wallet Backup Wallet @@ -2682,6 +2834,11 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsRequest authentication code before sending any transactions + + + Request passphrase before sending any transactions + + Change current passphrase @@ -2724,7 +2881,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - Enabling this will incur a minimum 1 PRCY fee each time you receive a new deposit that needs to be consolidated for staking. + Enabling this will incur a maximum 0.1 PRCY fee each time you receive a new deposit that needs to be consolidated for staking. @@ -2843,12 +3000,12 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Two Factor Authentication - + Remember my authentication code for @@ -2873,215 +3030,379 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - - Wallet Data (*.dat) - Wallet Data (*.dat) + + Reserve Balance Empty + - - Copy + + PRCY reserve amount is empty and must be a minimum of 1. +Please click Disable if you would like to turn it off. + + + + + Invalid Reserve Amount - OK + The amount you have attempted to keep as spendable is greater than the %1 (%2M) limit. Please try a smaller amount. - - - OverviewPage - - Form - Form + + Reserve Balance Set + - - Blocks + + Reserve balance of %1 PRCY is successfully set. - - - ??? + + Reserve Balance Disabled - - of + + Reserve balance disabled. - - (loading) + + + + + + + Wallet Encryption Failed - - Balance + + The passphrase entered for wallet encryption was empty or contained spaces. Please try again. - - Your current balance + + The passphrase you have entered is the same as your old passphrase. Please use a different passphrase if you would like to change it. - - Your current spendable balance - Your current spendable balance + + The passphrase's length has to be more than 10. Please try again. + - - Pending: - Pending: + + The passphrase must contain lower, upper, digit, symbol. Please try again. + - - Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance - Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + + The passphrase is too weak. You must use a minimum passphrase length of 10 characters and use uppercase letters, lowercase letters, numbers, and symbols. Please try again. + - - (syncing) + + Passphrase Change Successful - - - Recent Transactions + + Wallet passphrase was successfully changed. +Please remember your passphrase as there is no way to recover it. - - It is advised not to send or receive coins until your current sync is complete. + + The passphrases entered for wallet encryption do not match. Please try again. - - Spendable: - Spendable: + + Wallet Data (*.dat) + Wallet Data (*.dat) - - - + + Wallet has been successfully backed up to + - - - PaymentServer - - - - - - - Payment request error - Payment request error + + Wallet Backup Successful + - - - URI handling - URI handling + + Wallet Backup Failed + - - Payment request file handling - Payment request file handling + + Wallet backup failed. Please try again. + - - Invalid payment address %1 - Invalid payment address %1 + + Staking Disabled - Syncing Masternode list + - - Cannot start prcycoin: click-to-pay handler + + Enable Staking is disabled when you are still syncing the Masternode list as this is required. Please allow the wallet to fully sync this list before attempting to Enable Staking. - - URI cannot be parsed! This can be caused by an invalid PRCY address or malformed URI parameters. + + Staking Setting - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Payment request file cannot be read! This can be caused by an invalid payment request file. + + + + Please unlock the wallet with your passphrase before changing this setting. + - - - - Payment request rejected - Payment request rejected + + PoW blocks are still being mined. +Please wait until Block %1. + - - Payment request network doesn't match client network. - Payment request network doesn't match client network. + + + Information + Information - - Payment request has expired. - Payment request has expired. + + Your stakeable balance is under the threshold of %1 PRCY. Please deposit more PRCY into your account in order to enable staking. + + + + + Your balance requires a consolidation transaction which incurs a fee of between %1 to %2 PRCY. However after that transaction fee, your balance will be below the staking threshold of %3 PRCY. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking. + + + + + Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance being too high. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking. + + + + + Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance of %2 PRCY being too high. The wallet software has tried to consolidate your funds with the reserve balance but without success because of a consolidation fee of %3 PRCY. Please wait around 10 minutes for the wallet to resolve the reserve to enable staking. + - Payment request is not initialized. - Payment request is not initialized. + Warning: Staking Issue + - - Unverified payment requests to custom payment scripts are unsupported. - Unverified payment requests to custom payment scripts are unsupported. + + In order to enable staking with 100%% of your current balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY. + +Would you like to do this? + - - Requested payment amount of %1 is too small (considered dust). - Requested payment amount of %1 is too small (considered dust). + + In order to enable staking with 100%% of your current balance except the reserve balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY. + +Would you like to do this? + + + + + Staking Needs Consolidation + + + + + Consolidation transaction created! + + + + + 2FA Setting + - Refund from %1 - Refund from %1 + SUCCESS! + - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Payment request %1 is too large (%2 bytes, allowed %3 bytes). + + Two-factor authentication has been successfully enabled. + + + + + UPNP Settings + + + + + UPNP Settings successfully changed. Please restart the wallet for changes to take effect. + + + + + + 2FA Digit Settings + + + + + 2FA Digit Settings have been changed successfully. + - Payment request DoS protection - Payment request DoS protection + 2FA Digit Settings have not been changed. + - - Error communicating with %1: %2 - Error communicating with %1: %2 + + Hide Balance When Unlocked + - - Payment request cannot be parsed! - Payment request cannot be parsed! + + Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security. + - - Bad response from server %1 - Bad response from server %1 + + Lock Send Tab When Unlocked + - - Network request error - Network request error + + Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security. + - - Payment acknowledged - Payment acknowledged + + Password Locked Setting + + + + + OverviewPage + + + Form + Form + + + + Blocks + + + + + + ??? + + + + + of + + + + + (loading) + + + + + Balance + + + + + Your current balance + + + + + Your current spendable balance + Your current spendable balance + + + + Pending: + Pending: + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + + + + (syncing) + + + + + + Recent Transactions + + + + + It is advised not to send or receive coins until your current sync is complete. + + + + + Spendable: + Spendable: + + + + + + + + + PaymentServer + + + Payment request error + Payment request error + + + + + URI handling + URI handling + + + + Invalid payment address %1 + Invalid payment address %1 + + + + Cannot start prcycoin: click-to-pay handler + + + + + URI cannot be parsed! This can be caused by an invalid PRCY address or malformed URI parameters. + @@ -3125,7 +3446,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsAmount - + %1 d %1 d @@ -3196,7 +3517,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations%1 GB - + @@ -3265,35 +3586,34 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations&Information - + General General - + Name Name - + Client name Client name - - + + - - + @@ -3310,12 +3630,14 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + + + N/A N/A - + Number of connections Number of connections @@ -3350,22 +3672,17 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsDebug log file - + Using OpenSSL version Using OpenSSL version - - Build date - Build date - - - + Current number of blocks Current number of blocks - + Client version Client version @@ -3375,7 +3692,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsUsing BerkeleyDB version - + Open the PRCY debug log file from the current data directory. This can take a few seconds for large log files. @@ -3385,7 +3702,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsNumber of Masternodes - + &Console &Console @@ -3410,12 +3727,12 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsTotals - + Received Received - + Sent Sent @@ -3431,8 +3748,8 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - - + + Select a peer to view detailed information. Select a peer to view detailed information. @@ -3517,47 +3834,57 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations&Wallet Repair - - Rebuild block chain index from current blk000??.dat files. + + The buttons below will restart the wallet with command-line options to repair the wallet, fix issues with corrupt blockhain files or missing/obsolete transactions. - - The buttons below will restart the wallet with command-line options to repair the wallet, fix issues with corrupt blockchain files or missing/obsolete transactions. + + Custom Backup Path: - + + Custom Backups Threshold: + + + + + Rebuild block chain index from current blk000??.dat files. + + + + Wallet In Use: - + Salvage wallet Salvage wallet - + Attempt to recover private keys from a corrupt wallet.dat. - + Rescan blockchain files Rescan blockchain files - + Recover transactions 1 Recover transactions 1 - + Recover transactions from blockchain (keep meta-data, e.g. account owner). - + Data Directory @@ -3567,42 +3894,42 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Recover transactions 2 Recover transactions 2 - + Rescan the block chain for missing wallet transactions. - + Recover transactions from blockchain (drop meta-data). - + Upgrade wallet format Upgrade wallet format - + -resync: - + Delete local Blockchain Folders - + Deletes all local blockchain folders so the wallet synchronizes from scratch. - + Starting Block @@ -3617,22 +3944,22 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Wallet repair options. Wallet repair options. - + Upgrade wallet to latest format on startup. (Note: this is NOT an update of the wallet itself!) - + Rebuild index Rebuild index - + In: In: @@ -3647,7 +3974,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + &Disconnect Node @@ -3685,7 +4012,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + This will delete your local blockchain folders and the wallet will synchronize the complete Blockchain from scratch.<br /><br /> @@ -3863,7 +4190,17 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsCopy address - + + Invalid Amount + + + + + Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY. + + + + Enter Label @@ -3945,73 +4282,156 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsRevealTxDialog + Transaction Details - + + TXID: + + + + Copy transaction ID to clipboard - - TxId + + Address: - + + Private Key: + + + + + Amount: + Amount: + + + + Fee: + Fee: + + + + Ring Size: + + + + + Payment ID: + + + + + In Block: + + + + + Height: + + + + + Hash: + + + + + + Copy address to clipboard - - Address - Address + + Copy transaction private key to clipboard + + + + + Copy Transaction Amount to clipboard + + + + + Copy Transaction Fee to clipboard + + + + + + Copy Payment ID to clipboard + + + + + Are You Sure? + + + + + Are you sure you would like to delete this transaction from the local wallet? + +Note: They can only be restored from backup or rescan. + + + + + Potential Masternode Collateral Detected! + - - Copy transaction private key to clipboard + + Potential Masternode Collateral Detected! +Are you sure? + +Note: They can only be restored from backup or rescan. - - PrivKey + + Invalid or non-wallet transaction id - - Copy Transaction Amount to clipboard + + Invalid or non-wallet transaction id. - - Amount - Amount + + Unable to delete transaction id + - - Copy Transaction Fee to clipboard + + Unable to delete transaction id. - - Fee + + Do not show successful confirmation again - - - Copy Payment ID to clipboard + + OK - - Ring Size + + Success! - - Payment ID + + Transaction ID successfully deleted. @@ -4188,7 +4608,37 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsCopy change - + + Send Disabled - Syncing + + + + + Sending PRCY is disabled when you are still syncing the wallet. Please allow the wallet to fully sync before attempting to send a transaction. + + + + + Invalid Address + + + + + Invalid address entered. Please make sure you are sending to a Stealth Address. + + + + + Invalid Amount + + + + + Invalid amount entered. Please enter an amount less than your Spendable Balance. + + + + Destination @@ -4213,7 +4663,59 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + + Insufficient Spendable Funds! + + + + + Insufficient spendable funds. Send with smaller amount or wait for your coins become mature + + + + + Insufficient Reserve Funds! + + + + + Insufficient reserve funds. Send with smaller amount or turn off staking mode. + + + + + Information + Information + + + + Consolidation transaction created! + + + + + + Sweeping Transaction Creation Error + + + + + + Sweeping transaction creation failed due to an internal error. Please try again later. + + + + + Unable to create transaction. Please try again later. + + + + + Transaction Creation Error + + + + View on Explorer @@ -4228,7 +4730,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Warning: Invalid PIVX address @@ -4310,6 +4812,16 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsMemo: Memo: + + + Invalid Amount + + + + + Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY. + + ShutdownWindow @@ -4557,7 +5069,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations TrafficGraphWidget - + KB/s KB/s @@ -4714,12 +5226,12 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Credit Credit - + matures in %n more block(s) matures in %n more block @@ -4734,12 +5246,12 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Debit Debit - + Total debit Total debit @@ -4780,12 +5292,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - - Merchant - Merchant - - - + Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. @@ -4921,12 +5428,12 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsReceived from - + Confirmed Count. - + Sent to Sent to @@ -4951,7 +5458,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsMined - + watch-only watch-only @@ -5393,10 +5900,49 @@ Please try again. WalletModel - + Send Coins Send Coins + + + + + Mnemonic Recovery Phrase + + + + + + Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security. + + + + + Are You Sure? + + + + + Are you sure you would like to view your Mnemonic Phrase? +You will be required to enter your passphrase. Failed or canceled attempts will be logged. + + + + + Copy + + + + + OK + + + + + Below is your Mnemonic Recovery Phrase, consisting of 24 seed words. Please copy/write these words down in order. We strongly recommend keeping multiple copies in different locations. + + WalletView @@ -5479,12 +6025,12 @@ Please try again. Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup - + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. - + Enter regression test mode, which uses a special chain in which blocks can be solved instantly. Enter regression test mode, which uses a special chain in which blocks can be solved instantly. @@ -5559,12 +6105,12 @@ Please try again. Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) - + Maximum size of data in data carrier transactions we relay and mine (default: %u) Maximum size of data in data carrier transactions we relay and mine (default: %u) - + Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s) Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s) @@ -5645,16 +6191,16 @@ Please try again. - Unable to locate enough funds for this transaction that are not equal 10000 PRCY. - - - - Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + + + + Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction. Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction. @@ -5843,6 +6389,11 @@ Please try again. Done loading Done loading + + + Enable Old Transaction Deletion + + Enable publish hash transaction (locked via SwiftX) in <address> @@ -5893,11 +6444,6 @@ Please try again. Error reading from database, shutting down. Error reading from database, shutting down. - - - Error recovering public key. - Error recovering public key. - Error @@ -5919,17 +6465,17 @@ Please try again. Error: Unsupported argument -tor found, use -onion. - - Failed to listen on any port. Use -listen=0 if you want this. - Failed to listen on any port. Use -listen=0 if you want this. + + Failed to generate RingCT + - Failed to read block - Failed to read block + Failed to listen on any port. Use -listen=0 if you want this. + Failed to listen on any port. Use -listen=0 if you want this. - + Force safe mode (default: %u) Force safe mode (default: %u) @@ -6009,27 +6555,22 @@ Please try again. Invalid netmask specified in -whitelist: '%s' - - Invalid private key. - Invalid private key. - - - + Reindex the %s money supply statistics - + SwiftX options: - + This is a pre-release test build - use at your own risk - do not use for staking or merchant applications! - + Accept connections from outside (default: 1 if no -proxy or -connect/-noconnect) @@ -6039,10 +6580,20 @@ Please try again. - + + Delete transaction every <n> blocks during inital block download (default: %i) + + + + Enable SwiftX, show confirmations for locked transactions (bool, default: %s) + + + Enable or disable staking functionality for PRCY inputs (0-1, default: %u) + + Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. @@ -6064,7 +6615,17 @@ Please try again. - + + Maximum average size of an index occurrence in the block spam filter (default: %u) + + + + + Maximum size of the list of indexes in the block spam filter (default: %u) + + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect) @@ -6084,7 +6645,7 @@ Please try again. - + You have attempted to send more than 50 UTXOs in a single transaction. To work around this limitation, please either lower the total amount of the transaction or send two separate transactions with 50% of your total desired amount. @@ -6189,7 +6750,7 @@ Please try again. - + Enable publish hash block in <address> @@ -6229,7 +6790,7 @@ Please try again. - + Error: -listen must be true if -masternode is set. @@ -6244,17 +6805,7 @@ Please try again. - - Failed to generate RingCT for Sweeping transaction - - - - - Failed to generate bulletproof for Sweeping transaction - - - - + Failed to generate bulletproof @@ -6264,7 +6815,7 @@ Please try again. - + Fee (in %s/kB) to add to transactions you send (default: %s) @@ -6294,17 +6845,12 @@ Please try again. - + Keep at most <n> unconnectable transactions in memory (default: %u) Keep at most <n> unconnectable transactions in memory (default: %u) - - Limit size of signature cache to <n> entries (default: %u) - Limit size of signature cache to <n> entries (default: %u) - - - + Line: %d Line: %d @@ -6404,7 +6950,7 @@ Please try again. Number of automatic wallet backups (default: 10) - + Only accept block chain matching built-in checkpoints (default: %u) Only accept block chain matching built-in checkpoints (default: %u) @@ -6498,11 +7044,6 @@ Please try again. Send transactions as zero-fee transactions if possible (default: %u) Send transactions as zero-fee transactions if possible (default: %u) - - - Session timed out. - Session timed out. - Set database cache size in megabytes (%d to %d, default: %d) @@ -6559,17 +7100,27 @@ Please try again. Shrink debug.log file on client startup (default: 1 when no -debug) - - Signing failed. - Signing failed. + + Keep the last <n> transactions (default: %i) + - Signing timed out. - Signing timed out. + Keep transactions for at least <n> blocks (default: %i) + + Limit size of signature cache to <n> MiB (default: %u) + + + + + Number of custom location backups to retain (default: %d) + + + + Signing transaction failed Signing transaction failed @@ -6748,6 +7299,11 @@ Please try again. Use a custom max chain reorganization depth (default: %u) + + + Use block spam filter (default: %u) + + Use the test network diff --git a/src/qt/locale/prcycoin_en.xlf b/src/qt/locale/prcycoin_en.xlf new file mode 100644 index 0000000000..5fd34b9152 --- /dev/null +++ b/src/qt/locale/prcycoin_en.xlf @@ -0,0 +1,7591 @@ + + + + + + Right-click to edit address or label + Right-click to edit address or label + 67 + + + Create a new address + Create a new address + 94 + + + &New + &New + 97 + + + Copy the currently selected address to the system clipboard + Copy the currently selected address to the system clipboard + 111 + + + &Copy + &Copy + 114 + + + Delete the currently selected address from the list + Delete the currently selected address from the list + 128 + + + &Delete + &Delete + 131 + + + Export the data in the current tab to a file + Export the data in the current tab to a file + 158 + + + &Export + &Export + 161 + + + C&lose + C&lose + 181 + + + + + + + Choose the address to send coins to + Choose the address to send coins to + 44 + + + Choose the address to receive coins with + Choose the address to receive coins with + 47 + + + C&hoose + C&hoose + 53 + + + Sending addresses + Sending addresses + 59 + + + Receiving addresses + Receiving addresses + 62 + + + These are your PRCY addresses for sending payments. Always check the amount and the receiving address before sending coins. + + 69 + + + These are your PRCY addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + + 73 + + + &Copy Address + &Copy Address + 79 + + + Copy &Label + Copy &Label + 80 + + + &Edit + &Edit + 81 + + + Export Address List + Export Address List + 263 + + + Comma separated file (*.csv) + Comma separated file (*.csv) + 264 + + + Exporting Failed + Exporting Failed + 277 + + + There was an error trying to save the address list to %1. Please try again. + There was an error trying to save the address list to %1. Please try again. + 279 + An error message. + %1 is a name of the file (e.g., "addrbook.csv") that the bitcoin addresses were exported to. + + + + + + + Label + Label + 169 + + + Address + Address + 169 + + + (no label) + (no label) + 202 + + + + + + + Passphrase Dialog + Passphrase Dialog + 26 + + + Enter passphrase + Enter passphrase + 56 + + + New passphrase + New passphrase + 70 + + + Repeat new passphrase + Repeat new passphrase + 84 + + + Serves to disable the trivial sendmoney when OS account compromised. Provides no real security. + Serves to disable the trivial sendmoney when OS account compromised. Provides no real security. + 120 + + + For staking only + + 123 + + + Show passphrase + + 130 + + + + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + 46 + + + This operation needs your wallet passphrase to decrypt the wallet. + This operation needs your wallet passphrase to decrypt the wallet. + 64 + + + Enter the old and new passphrase to the wallet. + Enter the old and new passphrase to the wallet. + 73 + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR COINS</b>! + + 127 + + + PRCY will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your PRCYs from being stolen by malware infecting your computer. + + 135 + + + Are you sure you wish to encrypt your wallet? + Are you sure you wish to encrypt your wallet? + 127 + + + Encrypt Wallet + + 49 + + + This operation needs your wallet passphrase to unlock the wallet.<br/><br/>(Wallet may appear not responding as it rescans for all transactions)<br/><br/> + + 55 + + + Unlock Wallet + + 61 + + + Decrypt Wallet + + 69 + + + Change Passphrase + + 72 + + + Confirm Wallet Encryption + + 126 + + + Wallet Encrypted + + 133 + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + 139 + + + Wallet Encryption Failed + + 147 + 154 + 193 + 199 + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. Please try again. + + 148 + + + The supplied passphrases do not match. Please try again. + + 155 + 200 + + + Wallet Unlock Failed + + 166 + + + The passphrase entered for the wallet unlock was incorrect. Please try again. + + 167 + + + Wallet Decryption Failed + + 176 + + + The passphrase entered for the wallet decryption was incorrect. Please try again. + + 177 + 194 + + + Passphrase Change Successful + + 187 + + + Wallet passphrase was successfully changed. +Please remember your passphrase as there is no way to recover it. + + 188 + + + Warning: The Caps Lock key is on! + Warning: The Caps Lock key is on! + 236 + 260 + + + + + + + IP/Netmask + + 90 + + + Banned Until + + 90 + + + + + + + BIP 38 Tool + + 14 + + + &BIP 38 Encrypt + + 27 + + + Address: + + 57 + 457 + + + Enter a PRCY Address that you would like to encrypt using BIP 38. Enter a passphrase in the middle box. Press encrypt to compute the encrypted private key. + + 33 + + + The PRCY address to encrypt + + 64 + + + Choose previously used address + Choose previously used address + 71 + + + Alt+A + Alt+A + 81 + + + Paste address from clipboard + Paste address from clipboard + 88 + 308 + + + Alt+P + Alt+P + 98 + 318 + + + Passphrase: + + 118 + 338 + + + Encrypted Key: + + 145 + 294 + + + Copy the current signature to the system clipboard + Copy the current signature to the system clipboard + 167 + + + Encrypt the private key for this PRCY address + + 185 + + + Reset all fields + + 202 + 373 + + + The encrypted private key + + 301 + + + Decrypt the entered key using the passphrase + + 356 + + + Encrypt &Key + + 188 + + + Clear &All + Clear &All + 205 + 376 + + + &BIP 38 Decrypt + + 264 + + + Enter the BIP 38 encrypted private key. Enter the passphrase in the middle box. Click Decrypt Key to compute the private key. After the key is decrypted, clicking 'Import Address' will add this private key to the wallet. + + 270 + + + Decrypt &Key + + 359 + + + Decrypted Key: + + 436 + + + Import Address + + 450 + + + + + + + Click "Decrypt Key" to compute key + + 32 + + + The entered passphrase is invalid. + + 121 + + + Allowed: 0-9,a-z,A-Z, + + 121 + + + The entered address is invalid. + The entered address is invalid. + 128 + + + Please check the address and try again. + Please check the address and try again. + 128 + 136 + + + The entered address does not refer to a key. + The entered address does not refer to a key. + 136 + + + Wallet unlock was cancelled. + Wallet unlock was cancelled. + 143 + 206 + + + Private key for the entered address is not available. + Private key for the entered address is not available. + 150 + + + Failed to decrypt. + + 189 + + + Please check the key and passphrase and try again. + + 189 + + + Data Not Valid. + + 215 + + + Please try again. + + 215 + + + Please wait while key is imported + + 222 + + + Key Already Held By Wallet + + 230 + + + Error Adding Key To Wallet + + 238 + + + Successfully Added Private Key To Wallet + + 248 + + + + + + + Node + Node + 137 + + + &Overview + &Overview + 281 + + + &Send + &Send + 293 + + + &Receive + &Receive + 304 + + + E&xit + E&xit + 355 + + + Quit application + Quit application + 356 + + + About &Qt + About &Qt + 362 + + + Show information about Qt + Show information about Qt + 363 + + + &Show / Hide + &Show / Hide + 396 + + + Show or hide the main Window + Show or hide the main Window + 397 + + + &Encrypt Wallet... + &Encrypt Wallet... + 399 + + + Encrypt the private keys that belong to your wallet + Encrypt the private keys that belong to your wallet + 400 + + + &Backup Wallet... + &Backup Wallet... + 402 + + + Backup wallet to another location + Backup wallet to another location + 403 + + + &Change Passphrase... + &Change Passphrase... + 406 + + + Change the passphrase used for wallet encryption + Change the passphrase used for wallet encryption + 407 + + + &Unlock Wallet... + &Unlock Wallet... + 408 + + + Unlock wallet + Unlock wallet + 409 + + + &Lock Wallet + &Lock Wallet + 410 + + + &Information + &Information + 415 + + + Show diagnostic information + Show diagnostic information + 416 + + + Open debugging console + Open debugging console + 418 + + + &Network Monitor + &Network Monitor + 420 + + + Show network monitor + Show network monitor + 421 + + + Show peers info + Show peers info + 423 + + + Wallet &Repair + Wallet &Repair + 424 + + + Show wallet repair options + Show wallet repair options + 425 + + + Open configuration file + Open configuration file + 427 + + + Show &PRCYcoin Folder + + 432 + + + Show the PRCYcoin folder + + 433 + + + Show &Qt Folder + + 435 + + + Show the Qt folder + + 436 + + + Show Automatic &Backups + Show Automatic &Backups + 438 + + + Show automatically created wallet backups + Show automatically created wallet backups + 439 + + + &Sending addresses... + &Sending addresses... + 441 + + + Show the list of used sending addresses and labels + Show the list of used sending addresses and labels + 442 + + + &Receiving addresses... + &Receiving addresses... + 443 + + + Show the list of used receiving addresses and labels + Show the list of used receiving addresses and labels + 444 + + + Open &URI... + Open &URI... + 446 + + + &Knowledge Base + + 475 + + + Knowledge Base + + 476 + + + &GitHub Wiki + + 477 + + + GitHub Wiki + + 478 + + + &Blockchain Explorer API + + 479 + + + Blockchain Explorer API + + 480 + + + &Bridge + + 483 + + + Bridge Link + + 484 + + + &PRivaCY DEX + + 485 + + + PRivaCY Dex Link + + 486 + + + 1130 + + %n Active Connections + + + + %n Active Connections + + + + + 1149 + + Processed %n blocks of transaction history. + Processed %n block of transaction history. + + + Processed %n blocks of transaction history. + Processed %n blocks of transaction history. + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 +Confirmations: %5 + + + 1321 + + + Staking Disabled + + 1370 + + + Staking Enabled + + 1397 + + + Enabling Staking... + + 1407 + + + Disabling Staking... + + 1411 + + + &File + &File + 551 + + + &Settings + &Settings + 365 + + + PRivaCY Coin + + 126 + + + Wallet + + 135 + + + &History + + 315 + + + Masternodes + + 329 + + + Modify settings + + 367 + + + &Staking + + 379 + + + Staking Status + + 380 + + + &Network + &Network + 386 + + + &Debug Console + + 417 + + + &Peers List + + 422 + + + &Blockchain Explorer + + 448 + + + &Tools + &Tools + 579 + + + &Help + &Help + 605 + + + PRCY + + 1230 + + + &Masternodes + + 327 + + + - Lite Mode + + 140 + + + &About PRCY + + 359 + + + Show information about PRCY + + 360 + + + &Show Seed Phrase + + 404 + + + Show 24 word wallet seed phrase + + 405 + + + &MultiSend + + 411 + + + MultiSend Settings + + 412 + + + Open Wallet &Configuration File + + 426 + + + Open &Masternode Configuration File + + 429 + + + Open Masternode configuration file + + 430 + + + Open a PRCY: URI or payment request + + 447 + + + Block explorer window + + 449 + + + Facebook + + 451 + + + PRCY Facebook + + 452 + + + Twitter + + 453 + + + PRCY Twitter + + 454 + + + Discord + + 455 + + + PRCY Discord + + 456 + + + Telegram - Main + + 457 + + + PRCY Telegram - Main + + 458 + + + Telegram - Lounge + + 459 + + + PRCY Telegram - Lounge + + 460 + + + Medium + + 461 + + + PRCY Medium + + 462 + + + Steemit + + 463 + + + PRCY Steemit + + 464 + + + Instagram + + 465 + + + PRCY Instagram + + 466 + + + Reddit + + 467 + + + PRCY Reddit + + 468 + + + &Command-line Options + + 470 + + + Show the PRCY help message to get a list with possible PRCY command-line options + + 472 + + + &BootStrap + + 481 + + + BootStrap Link + + 482 + + + &PRCY Toolkit + + 487 + + + PRCY Toolkit Link + + 488 + + + &Telegram Tech Support + + 489 + + + Telegram Tech Support + + 490 + + + &Telegram Masternode Support + + 491 + + + Telegram Masternode Support + + 492 + + + &Discord Tech Support + + 493 + + + Discord Tech Support + + 494 + + + &Check For Updates + + 495 + + + Check For Updates + + 496 + + + Social + + 594 + + + PRCY client + + 794 + + + No Update Available + + 1017 + + + No update available. + +Your wallet is up to date. + + 1018 + + + Error checking for updates. + + + + 1027 + + + Up to date + Up to date + 1155 + + + 1185 + + %n hour(s) + %n hour + + + %n hour(s) + %n hours + + + + 1187 + + %n day(s) + %n day + + + %n day(s) + %n days + + + + 1189 + 1193 + + %n week(s) + %n week + + + %n week(s) + %n weeks + + + + %1 and %2 + %1 and %2 + 1193 + + + 1193 + + %n year(s) + %n year + + + %n year(s) + %n years + + + + Catching up... + Catching up... + 1196 + + + Last received block was generated %1 ago. + Last received block was generated %1 ago. + 1212 + + + Transactions after this will not yet be visible. + Transactions after this will not yet be visible. + 1214 + + + Loading Blocks... + + 1218 + + + Syncing Blocks... + + 1220 + 1384 + + + 1222 + + %n Blocks + + + + %n Blocks + + + + + Error + Error + 1026 + 1243 + + + Warning + Warning + 1246 + + + Information + Information + 1249 + + + Sent transaction + Sent transaction + 1320 + + + Incoming transaction + Incoming transaction + 1320 + + + Sent MultiSend transaction + + 1320 + + + No Active Peers + + 1377 + + + Syncing MN List... + + 1391 + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> for staking only + + 1444 + + + Tor is <b>enabled</b>: %1 + + 1474 + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + 1434 + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Wallet is <b>encrypted</b> and currently <b>locked</b> + 1454 + + + + + Unit to show amounts in. Click to select another unit. + Unit to show amounts in. Click to select another unit. + 1552 + + + + + + + A fatal error occurred. PRCY can no longer continue safely and will quit. + + 539 + + + + + PRCY + + 634 + 641 + 654 + 673 + + + Error: Specified data directory "%1" does not exist. + + 635 + + + Error: Cannot parse configuration file: %1. Only use key=value syntax. + + 642 + + + Error: Invalid combination of -regtest and -testnet. + + 654 + + + Error reading masternode configuration file: %1 + + 674 + + + PRCY didn't yet exit safely... + + 717 + + + + + + + Blockchain Explorer + + 14 + + + Back + + 32 + + + Forward + + 46 + + + Address / Block / Transaction + + 75 + + + Search + + 100 + + + TextLabel + + 139 + + + + + + + Not all transactions will be shown. To view all transactions you need to set txindex=1 in the configuration file (prcycoin.conf). + + 422 + + + + + + + Total: %1 (IPv4: %2 / IPv6: %3 / Tor: %4 / Unknown: %5) + + 81 + + + + + + + Quantity: + Quantity: + 48 + + + Bytes: + Bytes: + 77 + + + Amount: + Amount: + 122 + + + Priority: + Priority: + 151 + + + Fee: + Fee: + 196 + + + Coin Selection + Coin Selection + 14 + + + Dust: + Dust: + 228 + + + After Fee: + After Fee: + 276 + + + Change: + Change: + 308 + + + (un)select all + (un)select all + 364 + + + toggle lock state + + 380 + + + Tree mode + Tree mode + 396 + + + List mode + List mode + 409 + + + (1 locked) + (1 locked) + 419 + + + Amount + Amount + 465 + + + Received with label + Received with label + 470 + + + Received with address + Received with address + 475 + + + Type + Type + 480 + + + Date + Date + 485 + + + Confirmations + Confirmations + 490 + + + Confirmed + Confirmed + 493 + + + Priority + Priority + 498 + + + medium + medium + 164 + ../coincontroldialog.cpp461 + + + no + no + 244 + ../coincontroldialog.cpp663 + + + + + + + Copy address + Copy address + 55 + + + Copy label + Copy label + 56 + + + Copy amount + Copy amount + 57 + 83 + + + Copy transaction ID + Copy transaction ID + 58 + + + Lock unspent + Lock unspent + 59 + + + Unlock unspent + Unlock unspent + 60 + + + Copy quantity + Copy quantity + 82 + + + Copy fee + Copy fee + 84 + + + Copy after fee + Copy after fee + 85 + + + Copy bytes + Copy bytes + 86 + + + Copy priority + Copy priority + 87 + + + Copy dust + Copy dust + 88 + + + Copy change + Copy change + 89 + + + Select all + + 196 + + + Unselect all + + 198 + + + Please switch to "List mode" to use this function. + + 237 + + + highest + highest + 453 + + + higher + higher + 455 + + + high + high + 457 + + + medium-high + medium-high + 459 + + + Can vary +/- %1 duff(s) per input. + Can vary +/- %1 duff(s) per input. + 694 + + + low-medium + low-medium + 463 + + + low + low + 465 + + + lower + lower + 467 + + + lowest + lowest + 469 + + + (%1 locked) + (%1 locked) + 478 + + + none + none + 537 + + + yes + yes + 663 + + + This label turns red, if the transaction size is greater than 1000 bytes. + This label turns red, if the transaction size is greater than 1000 bytes. + 678 + + + This means a fee of at least %1 per kB is required. + This means a fee of at least %1 per kB is required. + 679 + 684 + + + Can vary +/- 1 byte per input. + Can vary +/- 1 byte per input. + 680 + + + Transactions with higher priority are more likely to get included into a block. + Transactions with higher priority are more likely to get included into a block. + 682 + + + This label turns red, if the priority is smaller than "medium". + This label turns red, if the priority is smaller than "medium". + 683 + + + This label turns red, if any recipient receives an amount smaller than %1. + This label turns red, if any recipient receives an amount smaller than %1. + 686 + + + (no label) + (no label) + 740 + 803 + + + change from %1 (%2) + change from %1 (%2) + 798 + + + (change) + (change) + 799 + + + + + + + Edit Address + Edit Address + 14 + + + &Label + &Label + 25 + + + The label associated with this address list entry + The label associated with this address list entry + 35 + + + &Address + &Address + 42 + + + The address associated with this address list entry. This can only be modified for sending addresses. + The address associated with this address list entry. This can only be modified for sending addresses. + 52 + + + + + + + New receiving address + New receiving address + 29 + + + New sending address + New sending address + 33 + + + Edit receiving address + Edit receiving address + 36 + + + Edit sending address + Edit sending address + 40 + + + The entered address "%1" is not a valid PRCY address. + + 107 + + + The entered address "%1" is already in the address book. + The entered address "%1" is already in the address book. + 112 + + + Could not unlock wallet. + Could not unlock wallet. + 117 + + + New key generation failed. + New key generation failed. + 122 + + + + + + + Transaction Details + + 20 + + + Encrypt Wallet + + 31 + + + Please enter a passphrase to encrypt your wallet. This is required. +(You must use a minimum passphrase length of 10 characters and use uppercase letters, +lowercase letters, numbers, symbols) + + 53 + + + New passphrase + New passphrase + 72 + + + Repeat new passphrase + Repeat new passphrase + 82 + + + Show passphrase + + 89 + + + Confirm + + 109 + + + Return + + 112 + + + Cancel + + 119 + + + Esc + + 122 + + + + + + + Wallet Encryption Required + + 37 + 48 + + + There was no passphrase entered for the wallet. + +Wallet encryption is required for the security of your funds. + +What would you like to do? + + 37 + 48 + + + Wallet Encryption Failed + + 67 + 76 + 84 + 94 + 111 + + + The passphrase entered for wallet encryption was empty. Please try again. + + 68 + + + The passphrase's length has to be more than 10. Please try again. + + 77 + + + The passphrase must contain lower, upper, digit, symbol. Please try again. + + 85 + + + The passphrases entered for wallet encryption is too weak. Please try again. + + 95 + + + Wallet Encryption Successful + + 104 + + + Wallet passphrase was successfully set. +Please remember your passphrase as there is no way to recover it. + + 105 + + + The passphrases entered for wallet encryption do not match. Please try again. + + 112 + + + + + + + PRivaCY Coin Wallet Recovery Wizard + + 20 + + + Enter your mnemonics recovery phrase to recover your wallet + + 32 + + + Next + + 57 + + + + + + + Recovery Phrase Import Successful + + 29 + + + Your mnemonics have been successfully imported into the wallet. Rescanning will be scheduled to recover all your funds. + + 29 + + + Recovery Phrase Invalid + + 35 + + + Recovery phrase is invalid. Please try again and double check all words. + + 35 + + + + + + + A new data directory will be created. + A new data directory will be created. + 73 + + + name + name + 92 + + + Directory already exists. Add %1 if you intend to create a new directory here. + Directory already exists. Add %1 if you intend to create a new directory here. + 94 + + + Path already exists, and is not a directory. + Path already exists, and is not a directory. + 97 + + + Cannot create data directory here. + Cannot create data directory here. + 103 + + + + + PRCY + + 186 + + + Error: Specified data directory "%1" cannot be created. + Error: Specified data directory "%1" cannot be created. + 187 + + + Error + Error + 211 + + + %1 GB of free space available + %1 GB of free space available + 219 + + + (of %1 GB needed) + (of %1 GB needed) + 221 + + + + + + + version + version + 38 + + + PRCY + + 38 + + + (%1-bit) + (%1-bit) + 43 + 45 + + + About PRCY + + 49 + + + Command-line options + Command-line options + 69 + + + Usage: + Usage: + 70 + + + command-line options + command-line options + 71 + + + UI Options: + + 79 + + + Choose data directory on startup (default: %u) + + 80 + + + Show splash screen on startup (default: %u) + + 83 + + + Set language, for example "de_DE" (default: system locale) + Set language, for example "de_DE" (default: system locale) + 81 + + + Start minimized + Start minimized + 82 + + + + + PRCY is shutting down... + + 157 + + + Do not shut down the computer until this window disappears. + Do not shut down the computer until this window disappears. + 158 + + + + + + + to + to + 57 + + + All Types + + 84 + ../historypage.cpp300 + + + Sent + Sent + 89 + ../historypage.cpp303 + ../historypage.cpp304 + ../historypage.cpp317 + + + Received + Received + 94 + ../historypage.cpp301 + ../historypage.cpp302 + ../historypage.cpp317 + + + Mined + Mined + 99 + ../historypage.cpp305 + ../historypage.cpp306 + ../historypage.cpp314 + ../historypage.cpp317 + + + Minted + + 104 + ../historypage.cpp307 + ../historypage.cpp308 + ../historypage.cpp314 + ../historypage.cpp317 + + + Masternode + + 109 + ../historypage.cpp309 + ../historypage.cpp310 + ../historypage.cpp314 + ../historypage.cpp317 + + + Payment to yourself + Payment to yourself + 114 + ../historypage.cpp311 + ../historypage.cpp312 + ../historypage.cpp317 + + + Rewards + + 119 + ../historypage.cpp313 + + + Min Amount + + 146 + + + Date + Date + 200 + + + Type + Type + 205 + + + Address/Description + + 210 + + + Amount (PRCY) + + 215 + + + Confirmations + Confirmations + 220 + + + + + + + PRivaCY Coin Wallet Wizard + + 20 + + + Do you want to create a new wallet or recover from your mnemonics? + + 32 + + + Create a new wallet + + 41 + + + Recover from a mnemonic phrase + + 51 + + + Next + + 71 + + + + + + + Copy + + 40 + + + OK + + 41 + + + + + + + Welcome + Welcome + 14 + + + Welcome to the PRivaCY Coin Wallet. + + 23 + + + As this is the first time the program is launched, you can choose where the PRivaCY Coin Wallet will store its data. + + 49 + + + The PRivaCY Coin Wallet will download and store a copy of the PRCY block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + + 59 + + + Use the default data directory + Use the default data directory + 69 + + + Use a custom data directory: + Use a custom data directory: + 76 + + + + + + + Form + Form + 14 + + + Alias + + 117 + + + Address + Address + 122 + + + Status + Status + 127 + + + Active + + 132 + + + Last Seen (UTC) + + 137 + + + Pubkey + + 142 + + + S&tart alias + + 155 + + + Start &all + + 162 + + + Start &MISSING + + 169 + + + &Update status + + 176 + + + + + + + Start alias + + 46 + + + Confirm masternode start + + 241 + + + Are you sure you want to start masternode %1? + + 242 + + + Confirm all masternodes start + + 265 + + + Are you sure you want to start ALL masternodes? + + 266 + + + Command is not available right now + + 289 + + + You can't use this command until masternode list is synced + + 290 + + + Confirm missing masternodes start + + 296 + + + Are you sure you want to start MISSING masternodes? + + 297 + + + + + + + MultiSend + + 17 + + + Enter whole numbers 1 - 100 + + 29 + + + Enter % to Give (1-100) + + 32 + + + Enter Address to Send to + + 48 + + + MultiSend allows you to automatically send up to 100% of your stake or masternode reward to a list of other PRCY addresses after it matures. +To Add: enter percentage to give and PRCY address to add to the MultiSend vector. +To Delete: Enter address to delete and press delete. +MultiSend will not be activated unless you have clicked Activate + + 64 + + + Add to MultiSend Vector + + 102 + + + Add + + 105 + + + Deactivate MultiSend + + 118 + + + Deactivate + + 121 + + + Choose an address from the address book + + 134 + + + Alt+A + Alt+A + 144 + + + Percentage of stake to send + + 157 + + + Percentage: + + 160 + + + Address to send portion of stake to + + 173 + + + Address: + + 176 + + + Delete Address From MultiSend Vector + + 192 + + + Delete + + 195 + + + Activate MultiSend + + 208 + + + Activate + + 211 + + + View MultiSend Vector + + 227 + + + View MultiSend + + 230 + + + Send For Stakes + + 246 + + + Send For Masternode Rewards + + 253 + + + + + + + The entered address: + + + 92 + + + is invalid. +Please check the address and try again. + + 92 + + + The total amount of your MultiSend vector is over 100% of your stake reward + + + 103 + + + Please Enter 1 - 100 for percent. + + 110 + + + MultiSend Vector + + + 130 + + + Removed + + 152 + + + Could not locate address + + + 154 + + + + + + + Open URI + Open URI + 14 + + + URI: + URI: + 29 + + + + + + + Options + Options + 14 + + + &Main + &Main + 27 + + + Size of &database cache + Size of &database cache + 45 + + + MB + MB + 61 + + + Number of script &verification threads + Number of script &verification threads + 88 + + + (0 = auto, <0 = leave that many cores free) + (0 = auto, <0 = leave that many cores free) + 101 + + + W&allet + W&allet + 137 + + + If you disable the spending of unconfirmed change, the change from a transaction<br/>cannot be used until that transaction has at least one confirmation.<br/>This also affects how your balance is computed. + If you disable the spending of unconfirmed change, the change from a transaction<br/>cannot be used until that transaction has at least one confirmation.<br/>This also affects how your balance is computed. + 169 + + + Automatically open the PRCY client port on the router. This only works when your router supports UPnP and it is enabled. + + 202 + + + Accept connections from outside + Accept connections from outside + 212 + + + Allow incoming connections + Allow incoming connections + 215 + + + &Connect through SOCKS5 proxy (default proxy): + &Connect through SOCKS5 proxy (default proxy): + 225 + + + Expert + Expert + 143 + + + Automatically start PRCY after logging in to the system. + + 33 + + + &Start PRCY on system login + + 36 + + + Whether to show coin control features or not. + Whether to show coin control features or not. + 149 + + + Enable coin &control features + Enable coin &control features + 152 + + + Show additional tab listing all your masternodes in first sub-tab<br/>and all masternodes on the network in second sub-tab. + + 159 + + + Show Masternodes Tab + + 162 + + + &Spend unconfirmed change + &Spend unconfirmed change + 172 + + + &Network + &Network + 196 + + + Language missing or translation incomplete? Help contributing translations here: +https://www.transifex.com/prcycoin-project/prcycoin-project-translations + + 409 + + + Map port using &UPnP + Map port using &UPnP + 205 + + + Connect to the PRCY network through a SOCKS5 proxy. + + 222 + + + Proxy &IP: + Proxy &IP: + 234 + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + 259 + + + &Port: + &Port: + 266 + + + Port of the proxy (e.g. 9050) + Port of the proxy (e.g. 9050) + 291 + + + &Window + &Window + 327 + + + Show only a tray icon after minimizing the window. + Show only a tray icon after minimizing the window. + 333 + + + &Minimize to the tray instead of the taskbar + &Minimize to the tray instead of the taskbar + 336 + + + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu. + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu. + 343 + + + M&inimize on close + M&inimize on close + 346 + + + &Display + &Display + 367 + + + User Interface &language: + User Interface &language: + 375 + + + The user interface language can be set here. This setting will take effect after restarting PRCYcoin. + + 388 + + + Interface Mode: + + 428 + + + Light + + 449 + + + Dark + + 511 + + + &Unit to show amounts in: + &Unit to show amounts in: + 537 + + + Choose the default subdivision unit to show in the interface and when sending coins. + Choose the default subdivision unit to show in the interface and when sending coins. + 550 + + + Decimal digits + Decimal digits + 561 + + + Hide empty balances + + 575 + 581 + + + Hide orphan stakes in transaction lists + + 588 + + + Hide orphan stakes + + 591 + + + Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. + Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. + 615 + 628 + + + Third party transaction URLs + Third party transaction URLs + 618 + + + Active command-line options that override above options: + Active command-line options that override above options: + 659 + + + Reset all client options to default. + Reset all client options to default. + 702 + + + &Reset Options + &Reset Options + 705 + + + &OK + &OK + 766 + + + &Cancel + &Cancel + 779 + + + + + + + default + default + 85 + + + none + none + 131 + + + Confirm options reset + Confirm options reset + 218 + + + Client restart required to activate changes. + Client restart required to activate changes. + 219 + 248 + + + Client will be shutdown, do you want to proceed? + Client will be shutdown, do you want to proceed? + 219 + + + This change would require a client restart. + This change would require a client restart. + 250 + + + The supplied proxy address is invalid. + The supplied proxy address is invalid. + 279 + + + The supplied proxy port is invalid. + + 286 + + + The supplied proxy settings are invalid. + + 294 + + + + + + + Turn staking on or off + + 70 + + + On + + 76 + 226 + + + Off + + 79 + 229 + + + Staking Mode: + + 57 + + + Backup Wallet + Backup Wallet + 105 + ../optionspage.cpp349 + + + Show Seed Phrase + + 125 + + + Theme Selection: + + 148 + + + Switch between Dark and Web Wallet theme + + 167 + + + Dark + + 173 + + + Web + + 176 + + + Number of digits to use: + + 244 + + + 6 + + 255 + + + 8 + + 260 + + + Request authentication code before sending any transactions + + 270 + + + Request passphrase before sending any transactions + + 277 + + + Change current passphrase + + 398 + + + Old passphrase + + 409 + + + New passphrase + New passphrase + 419 + + + Repeat new passphrase + Repeat new passphrase + 429 + + + Show passphrase + + 436 + + + Submit + + 457 + + + Clear All + + 470 + + + Quantity of PRCY to keep as spendable (not staking) + + 484 + + + Enabling this will incur a maximum 0.1 PRCY fee each time you receive a new deposit that needs to be consolidated for staking. + + 500 + + + Automatically add any new deposits received to your staked balance + + 503 + + + Save + + 542 + + + Disable + + 549 + + + Network Settings + + 602 + + + Automatically open the PRCY client port on the router. This only works when your router supports UPnP and it is enabled. + + 608 + + + Map port using &UPnP + Map port using &UPnP + 611 + + + Window Settings + + 621 + + + &Minimize to the tray instead of the taskbar + &Minimize to the tray instead of the taskbar + 627 + + + M&inimize on close + M&inimize on close + 634 + + + Privacy Settings + + 644 + + + Hide Balance when unlocked + + 650 + + + Lock "Send" tab when unlocked + + 657 + + + Alternative Currency Value + + 667 + + + Display alternative currency value of wallet on Overview + + 675 + + + Default Currency: + + 682 + + + USD + + 693 + + + CAD + + 698 + + + EUR + + 703 + + + GBP + + 708 + + + BTC + + 713 + + + ETH + + 718 + + + XAU + + 723 + + + XAG + + 728 + + + Two Factor Authentication + + 212 + + + Remember my authentication code for + + 284 + + + 1 Day + + 299 + + + 1 Week + + 306 + + + 1 Month + + 313 + + + Current Authentication Code + + 322 + + + + + + + Reserve Balance Empty + + 215 + + + PRCY reserve amount is empty and must be a minimum of 1. +Please click Disable if you would like to turn it off. + + 216 + + + Invalid Reserve Amount + + 224 + + + The amount you have attempted to keep as spendable is greater than the %1 (%2M) limit. Please try a smaller amount. + + 225 + + + Reserve Balance Set + + 239 + + + Reserve balance of %1 PRCY is successfully set. + + 240 + + + Reserve Balance Disabled + + 252 + + + Reserve balance disabled. + + 253 + + + Wallet Encryption Failed + + 271 + 295 + 301 + 307 + 313 + 326 + + + The passphrase entered for wallet encryption was empty or contained spaces. Please try again. + + 272 + + + The passphrase you have entered is the same as your old passphrase. Please use a different passphrase if you would like to change it. + + 296 + + + The passphrase's length has to be more than 10. Please try again. + + 302 + + + The passphrase must contain lower, upper, digit, symbol. Please try again. + + 308 + + + The passphrase is too weak. You must use a minimum passphrase length of 10 characters and use uppercase letters, lowercase letters, numbers, and symbols. Please try again. + + 314 + + + Passphrase Change Successful + + 319 + + + Wallet passphrase was successfully changed. +Please remember your passphrase as there is no way to recover it. + + 320 + + + The passphrases entered for wallet encryption do not match. Please try again. + + 327 + + + Wallet Data (*.dat) + Wallet Data (*.dat) + 350 + + + Wallet has been successfully backed up to + + 357 + + + Wallet Backup Successful + + 359 + + + Wallet Backup Failed + + 365 + + + Wallet backup failed. Please try again. + + 366 + + + Staking Disabled - Syncing Masternode list + + 417 + + + Enable Staking is disabled when you are still syncing the Masternode list as this is required. Please allow the wallet to fully sync this list before attempting to Enable Staking. + + 418 + + + Staking Setting + + 425 + + + Please unlock the wallet with your passphrase before changing this setting. + + 426 + 623 + 1005 + + + PoW blocks are still being mined. +Please wait until Block %1. + + 436 + + + Information + Information + 438 + 520 + + + Your stakeable balance is under the threshold of %1 PRCY. Please deposit more PRCY into your account in order to enable staking. + + 456 + + + Your balance requires a consolidation transaction which incurs a fee of between %1 to %2 PRCY. However after that transaction fee, your balance will be below the staking threshold of %3 PRCY. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking. + + 458 + + + Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance being too high. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking. + + 463 + + + Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance of %2 PRCY being too high. The wallet software has tried to consolidate your funds with the reserve balance but without success because of a consolidation fee of %3 PRCY. Please wait around 10 minutes for the wallet to resolve the reserve to enable staking. + + 467 + + + Warning: Staking Issue + + 473 + + + In order to enable staking with 100%% of your current balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY. + +Would you like to do this? + + 493 + + + In order to enable staking with 100%% of your current balance except the reserve balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY. + +Would you like to do this? + + 497 + + + Staking Needs Consolidation + + 502 + + + Consolidation transaction created! + + 521 + + + 2FA Setting + + 622 + + + SUCCESS! + + 670 + + + Two-factor authentication has been successfully enabled. + + 671 + + + UPNP Settings + + 839 + + + UPNP Settings successfully changed. Please restart the wallet for changes to take effect. + + 840 + + + 2FA Digit Settings + + 873 + 879 + + + 2FA Digit Settings have been changed successfully. + + 874 + + + 2FA Digit Settings have not been changed. + + 880 + + + Hide Balance When Unlocked + + 923 + + + Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security. + + 924 + + + Lock Send Tab When Unlocked + + 957 + + + Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security. + + 958 + + + Password Locked Setting + + 1004 + + + + + + + Form + Form + 20 + + + Blocks + + 91 + + + ??? + + 112 + 147 + + + of + + 128 + + + (loading) + + 159 + + + Balance + + 213 + + + Your current balance + + 236 + + + Your current spendable balance + Your current spendable balance + 362 + + + Pending: + Pending: + 384 + + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + 403 + + + (syncing) + + 422 + + + Recent Transactions + + 488 + 491 + + + It is advised not to send or receive coins until your current sync is complete. + + 551 + + + Spendable: + Spendable: + 337 + + + + + + + + + 229 + + + + + + + Payment request error + Payment request error + 163 + + + URI handling + URI handling + 219 + 224 + + + Invalid payment address %1 + Invalid payment address %1 + 219 + + + Cannot start prcycoin: click-to-pay handler + + 164 + + + URI cannot be parsed! This can be caused by an invalid PRCY address or malformed URI parameters. + + 225 + + + + + + + NodeId + + 120 + + + Node/Service + + 120 + + + Ping + + 120 + + + Sent + Sent + 120 + + + Received + Received + 120 + + + User Agent + + 120 + + + + + + + Amount + Amount + 256 + + + + + + + %1 d + %1 d + 822 + + + %1 h + %1 h + 824 + + + %1 m + %1 m + 826 + + + %1 s + %1 s + 828 + 868 + + + NETWORK + NETWORK + 843 + + + BLOOM + + 847 + + + UNKNOWN + UNKNOWN + 850 + + + None + None + 858 + + + N/A + N/A + 863 + + + %1 ms + %1 ms + 863 + + + %1 B + %1 B + 874 + + + %1 KB + %1 KB + 876 + + + %1 MB + %1 MB + 878 + + + %1 GB + %1 GB + 880 + + + + + + + &Save Image... + &Save Image... + 35 + + + &Copy Image + &Copy Image + 38 + + + Save QR Code + Save QR Code + 69 + + + PNG Image (*.png) + PNG Image (*.png) + 69 + + + + + Request payment to %1 + Request payment to %1 + 132 + + + Payment information + Payment information + 138 + + + URI + URI + 139 + + + Address + Address + 141 + + + Amount + Amount + 143 + + + Label + Label + 145 + + + Message + Message + 147 + + + Resulting URI too long, try to reduce the text for label / message. + Resulting URI too long, try to reduce the text for label / message. + 155 + + + Error encoding URI into QR Code. + Error encoding URI into QR Code. + 159 + + + + + + + Tools window + Tools window + 14 + + + &Information + &Information + 24 + + + General + General + 46 + + + Name + Name + 187 + + + Client name + Client name + 53 + + + N/A + N/A + 33 + 63 + 86 + 112 + 138 + 161 + 197 + 220 + 243 + 279 + 302 + 368 + 845 + 868 + 891 + 914 + 937 + 960 + 983 + 1006 + 1029 + 1052 + 1075 + 1098 + 1121 + 1144 + 1167 + 1193 + 1216 + 1281 + 1416 + 1535 + + + Number of connections + Number of connections + 210 + + + Block chain + + 262 + + + &Open + &Open + 344 + + + Startup time + Startup time + 151 + + + Network + Network + 180 + + + Last block time + Last block time + 292 + + + Debug log file + Debug log file + 334 + + + Using OpenSSL version + Using OpenSSL version + 99 + + + Current number of blocks + Current number of blocks + 269 + + + Client version + Client version + 76 + + + Using BerkeleyDB version + Using BerkeleyDB version + 125 + + + Open the PRCY debug log file from the current data directory. This can take a few seconds for large log files. + + 341 + + + Number of Masternodes + Number of Masternodes + 233 + + + &Console + &Console + 376 + + + Clear console + Clear console + 425 + + + &Network Traffic + &Network Traffic + 448 + + + &Clear + &Clear + 500 + + + Totals + Totals + 516 + + + Received + Received + 580 + + + Sent + Sent + 660 + + + &Peers + &Peers + 701 + + + Banned peers + + 751 + + + Select a peer to view detailed information. + Select a peer to view detailed information. + 810 + ../rpcconsole.cpp322 + ../rpcconsole.cpp1077 + + + Whitelisted + + 835 + + + Direction + Direction + 858 + + + Protocol + + 881 + + + Version + Version + 904 + + + Services + Services + 927 + + + Ban Score + Ban Score + 1019 + + + Connection Time + Connection Time + 1042 + + + Last Send + Last Send + 1065 + + + Last Receive + Last Receive + 1088 + + + Bytes Sent + Bytes Sent + 1111 + + + Bytes Received + Bytes Received + 1134 + + + Ping Time + Ping Time + 1157 + + + The duration of a currently outstanding ping. + + 1180 + + + Ping Wait + + 1183 + + + Time Offset + + 1206 + + + &Wallet Repair + &Wallet Repair + 1246 + + + The buttons below will restart the wallet with command-line options to repair the wallet, fix issues with corrupt blockhain files or missing/obsolete transactions. + + 1261 + + + Custom Backup Path: + + 1297 + + + Custom Backups Threshold: + + 1462 + + + Rebuild block chain index from current blk000??.dat files. + + 1506 + + + Wallet In Use: + + 1271 + + + Salvage wallet + Salvage wallet + 1310 + + + Attempt to recover private keys from a corrupt wallet.dat. + + 1561 + + + Rescan blockchain files + Rescan blockchain files + 1577 + + + Recover transactions 1 + Recover transactions 1 + 1343 + + + Recover transactions from blockchain (keep meta-data, e.g. account owner). + + 1357 + + + Data Directory + + 354 + + + Last block hash + + 361 + + + Recover transactions 2 + Recover transactions 2 + 1435 + + + Rescan the block chain for missing wallet transactions. + + 1591 + + + Recover transactions from blockchain (drop meta-data). + + 1449 + + + Upgrade wallet format + Upgrade wallet format + 1373 + + + -resync: + + 1469 + + + Delete local Blockchain Folders + + 1522 + + + Deletes all local blockchain folders so the wallet synchronizes from scratch. + + 1476 + + + Starting Block + + 950 + + + Synced Headers + + 973 + + + Synced Blocks + + 996 + + + Wallet repair options. + Wallet repair options. + 1330 + + + Upgrade wallet to latest format on startup. (Note: this is NOT an update of the wallet itself!) + + 1387 + + + Rebuild index + Rebuild index + 1403 + + + + + + + In: + In: + 677 + + + Out: + Out: + 678 + + + Welcome to the PRCY RPC console. + + 639 + + + &Disconnect Node + + 419 + + + Ban Node for + + 420 + 421 + 422 + 423 + + + 1 &hour + + 420 + + + 1 &day + + 421 + + + 1 &week + + 422 + + + 1 &year + + 423 + + + &Unban Node + + 470 + + + This will delete your local blockchain folders and the wallet will synchronize the complete Blockchain from scratch.<br /><br /> + + 566 + + + This needs quite some time and downloads a lot of data.<br /><br /> + + 567 + + + Your transactions and funds will be visible again after the download has completed.<br /><br /> + + 568 + + + Do you want to continue?.<br /> + + 569 + + + Confirm resync Blockchain + + 570 + + + Use up and down arrows to navigate history, and %1 to clear screen. + + 640 + + + Type <b>help</b> for an overview of available commands. + Type <b>help</b> for an overview of available commands. + 641 + + + 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. + + 643 + + + (node id: %1) + + 904 + + + via %1 + via %1 + 906 + + + never + never + 909 + 910 + + + Inbound + Inbound + 919 + + + Outbound + Outbound + 919 + + + Yes + + 921 + + + No + + 921 + + + Unknown + Unknown + 933 + 939 + + + + + + + An optional message to attach to the payment request, which will be displayed when the request is opened.<br>Note: The message will not be sent with the payment over the PRCY network. + + 69 + 79 + + + Description (optional) + + 72 + + + Description: + + 82 + + + Amount: + Amount: + 98 + + + List of addresses to receive with + + 108 + 115 + + + Address: + + 118 + + + Submit payment request for address selected above + + 136 + + + &Submit + + 139 + + + PRCY Amount (optional) + + 177 + + + Copy Master Account address to clipboard + + 227 + + + Master Account address + + 237 + + + Remove Integrated Address + + 259 + + + Generate Integrated Address + + 269 + + + An optional amount to request. Leave this empty or zero to not request a specific amount. + An optional amount to request. Leave this empty or zero to not request a specific amount. + 95 + 174 + + + + + + + Copy label + Copy label + 36 + + + Copy message + Copy message + 37 + + + Copy amount + Copy amount + 38 + + + Copy address + Copy address + 39 + + + Invalid Amount + + 196 + + + Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY. + + 197 + + + Enter Label + + 263 + + + Label (Payment ID is added by default) + + 264 + + + + + + + QR Code + QR Code + 29 + + + Copy &URI + Copy &URI + 75 + + + Copy &Address + Copy &Address + 85 + + + &Save Image... + &Save Image... + 95 + + + + + + + Transaction Details + + 14 + 20 + + + TXID: + + 34 + + + Copy transaction ID to clipboard + + 67 + + + Address: + + 87 + + + Private Key: + + 133 + + + Amount: + Amount: + 179 + + + Fee: + Fee: + 225 + + + Ring Size: + + 271 + + + Payment ID: + + 317 + + + In Block: + + 358 + + + Height: + + 372 + + + Hash: + + 425 + + + Copy address to clipboard + + 113 + 405 + 458 + + + Copy transaction private key to clipboard + + 159 + + + Copy Transaction Amount to clipboard + + 205 + + + Copy Transaction Fee to clipboard + + 251 + + + Copy Payment ID to clipboard + + 297 + 343 + + + + + + + Are You Sure? + + 200 + + + Are you sure you would like to delete this transaction from the local wallet? + +Note: They can only be restored from backup or rescan. + + 201 + + + Potential Masternode Collateral Detected! + + 207 + + + Potential Masternode Collateral Detected! +Are you sure? + +Note: They can only be restored from backup or rescan. + + 208 + + + Invalid or non-wallet transaction id + + 222 + + + Invalid or non-wallet transaction id. + + 223 + + + Unable to delete transaction id + + 230 + + + Unable to delete transaction id. + + 231 + + + Do not show successful confirmation again + + 238 + + + OK + + 239 + + + Success! + + 243 + + + Transaction ID successfully deleted. + + 245 + + + + + + + Send Coins + Send Coins + 14 + + + Confirm the send action + Confirm the send action + 828 + + + S&end + S&end + 831 + + + Send to multiple recipients at once + Send to multiple recipients at once + 751 + + + Coin Control Features + + 140 + + + Open Coin Control... + + 163 + + + Coins automatically selected + + 173 + + + Insufficient funds! + + 192 + + + Quantity: + Quantity: + 281 + + + Bytes: + Bytes: + 316 + + + Amount: + Amount: + 364 + + + Priority: + Priority: + 396 + + + medium + medium + 409 + + + Fee: + Fee: + 444 + + + Dust: + Dust: + 476 + + + no + no + 489 + + + After Fee: + After Fee: + 524 + + + Change: + Change: + 556 + + + If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. + + 600 + + + Custom change address + + 603 + + + Split UTXO + + 623 + + + # of outputs + + 636 + + + UTXO Size: + + 643 + + + 0 PRCY + + 650 + + + Add &Recipient + Add &Recipient + 754 + + + Balance: + Balance: + 43 + + + + + + + Copy quantity + Copy quantity + 60 + + + Copy amount + Copy amount + 61 + + + Copy fee + Copy fee + 62 + + + Copy after fee + Copy after fee + 63 + + + Copy bytes + Copy bytes + 64 + + + Copy priority + Copy priority + 65 + + + Copy dust + Copy dust + 66 + + + Copy change + Copy change + 67 + + + Send Disabled - Syncing + + 144 + + + Sending PRCY is disabled when you are still syncing the wallet. Please allow the wallet to fully sync before attempting to send a transaction. + + 145 + + + Invalid Address + + 168 + + + Invalid address entered. Please make sure you are sending to a Stealth Address. + + 169 + + + Invalid Amount + + 176 + + + Invalid amount entered. Please enter an amount less than your Spendable Balance. + + 177 + + + Destination + + 205 + + + Are you sure you want to send? + + 210 + + + Estimated Transaction fee + + 212 + + + <span class='h3'>Total Amount = <b>%1</b><br/></center> + + 225 + + + Confirm Send Coins + + 233 + + + Insufficient Spendable Funds! + + 249 + + + Insufficient spendable funds. Send with smaller amount or wait for your coins become mature + + 250 + + + Insufficient Reserve Funds! + + 254 + + + Insufficient reserve funds. Send with smaller amount or turn off staking mode. + + 255 + + + Information + Information + 322 + + + Consolidation transaction created! + + 323 + + + Sweeping Transaction Creation Error + + 327 + 335 + + + Sweeping transaction creation failed due to an internal error. Please try again later. + + 328 + 336 + + + Unable to create transaction. Please try again later. + + 346 + + + Transaction Creation Error + + 349 + + + View on Explorer + + 381 + + + Copy + + 382 + + + OK + + 383 + + + Warning: Invalid PIVX address + + 531 + + + Warning: Unknown change address + + 539 + + + (no label) + (no label) + 549 + + + + + + + Remove this entry + Remove this entry + 81 + 225 + 310 + + + A&mount: + A&mount: + 258 + 343 + + + PRivaCY Coin Wallet Address to send to + + 68 + + + Wallet Address + + 71 + + + An optional description to attach to the payment + + 121 + + + Description (Optional) + + 124 + + + Amount of PRCY to send to address above + + 163 + + + PRCY Amount + + 166 + + + Use Spendable Balance + + 179 + + + Clear All + + 186 + + + Pay To: + Pay To: + 207 + 288 + + + Memo: + Memo: + 241 + 326 + + + + + + + Invalid Amount + + 139 + + + Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY. + + 140 + + + + + + + Signatures - Sign / Verify a Message + Signatures - Sign / Verify a Message + 14 + + + &Sign Message + &Sign Message + 27 + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + 33 + + + The PRCY address to sign the message with + + 48 + + + Choose previously used address + Choose previously used address + 55 + 250 + + + Alt+A + Alt+A + 65 + 260 + + + Paste address from clipboard + Paste address from clipboard + 72 + + + Alt+P + Alt+P + 82 + + + Enter the message you want to sign here + Enter the message you want to sign here + 91 + + + Signature + Signature + 98 + + + Copy the current signature to the system clipboard + Copy the current signature to the system clipboard + 122 + + + Sign the message to prove you own this PRCY address + + 140 + + + The PRCY address the message was signed with + + 243 + + + Verify the message to ensure it was signed with the specified PRCY address + + 277 + + + Sign &Message + Sign &Message + 143 + + + Reset all sign message fields + Reset all sign message fields + 157 + + + Clear &All + Clear &All + 160 + 297 + + + &Verify Message + &Verify Message + 219 + + + Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. + Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. + 225 + + + Verify &Message + Verify &Message + 280 + + + Reset all verify message fields + Reset all verify message fields + 294 + + + + + + + Click "Sign Message" to generate signature + Click "Sign Message" to generate signature + 31 + + + The entered address is invalid. + The entered address is invalid. + 110 + 183 + + + Please check the address and try again. + Please check the address and try again. + 110 + 117 + 183 + 190 + + + The entered address does not refer to a key. + The entered address does not refer to a key. + 117 + 190 + + + Wallet unlock was cancelled. + Wallet unlock was cancelled. + 124 + + + Private key for the entered address is not available. + Private key for the entered address is not available. + 131 + + + Message signing failed. + Message signing failed. + 142 + + + Message signed. + Message signed. + 147 + + + The signature could not be decoded. + The signature could not be decoded. + 200 + + + Please check the signature and try again. + Please check the signature and try again. + 200 + 212 + + + The signature did not match the message digest. + The signature did not match the message digest. + 212 + + + Message verification failed. + Message verification failed. + 218 + + + Message verified. + Message verified. + 223 + + + + + + + PRivaCY Coin Wallet + + 37 + + + PRivaCY Coin Lite Mode Wallet + + 40 + + + Version %1 + Version %1 + 42 + + + The Bitcoin Core developers + The Bitcoin Core developers + 43 + + + The Dash Core developers + + 44 + + + The PIVX Core developers + + 45 + + + The DAPS Project developers + + 46 + + + The PRivaCY Coin developers + + 47 + + + + + + + [testnet] + [testnet] + 19 + + + + + + + KB/s + KB/s + 79 + + + + + + + 33 + + Open for %n more block(s) + Open for %n more block + + + Open for %n more block(s) + Open for %n more blocks + + + + Open until %1 + Open until %1 + 35 + + + conflicted + conflicted + 43 + 54 + 64 + 76 + + + %1/offline + %1/offline + 78 + + + %1/unconfirmed + %1/unconfirmed + 80 + + + %1 confirmations + %1 confirmations + 70 + 82 + + + %1/offline (verified via SwiftX) + + 45 + + + %1/confirmed (verified via SwiftX) + + 47 + + + %1 confirmations (verified via SwiftX) + + 49 + + + %1/offline (SwiftX verification in progress - %2 of %3 signatures) + + 56 + + + %1/confirmed (SwiftX verification in progress - %2 of %3 signatures ) + + 58 + + + %1 confirmations (SwiftX verification in progress - %2 of %3 signatures) + + 60 + + + %1/offline (SwiftX verification failed) + + 66 + + + %1/confirmed (SwiftX verification failed) + + 68 + + + Status + Status + 100 + + + , has not been successfully broadcast yet + , has not been successfully broadcast yet + 104 + + + 106 + + , broadcast through %n node(s) + , broadcast through %n node + + + , broadcast through %n node(s) + , broadcast through %n nodes + + + + Date + Date + 110 + + + Source + Source + 116 + + + Generated + Generated + 116 + + + From + From + 119 + 127 + 190 + + + unknown + unknown + 127 + + + To + To + 128 + 147 + 205 + + + own address + own address + 130 + + + watch-only + watch-only + 130 + 190 + + + label + label + 132 + + + Credit + Credit + 164 + 174 + 219 + 242 + 279 + + + 166 + + matures in %n more block(s) + matures in %n more block + + + matures in %n more block(s) + matures in %n more blocks + + + + not accepted + not accepted + 168 + + + Debit + Debit + 217 + 239 + 276 + + + Total debit + Total debit + 226 + + + Total credit + Total credit + 227 + + + Transaction fee + Transaction fee + 232 + + + Net amount + Net amount + 246 + + + Message + Message + 252 + 262 + + + Comment + Comment + 254 + + + Transaction ID + Transaction ID + 256 + + + Output index + + 257 + + + Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. + Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. + 266 + + + Debug information + Debug information + 273 + + + Transaction + Transaction + 281 + + + Inputs + Inputs + 284 + + + Amount + Amount + 301 + + + true + true + 302 + 303 + + + false + false + 302 + 303 + + + + + + + Transaction details + Transaction details + 14 + + + This pane shows a detailed description of the transaction + This pane shows a detailed description of the transaction + 20 + + + + + + + Date + Date + 290 + + + Type + Type + 290 + + + Address + Address + 290 + + + Confirmations + Confirmations + 290 + + + 348 + + Open for %n more block(s) + Open for %n more block + + + Open for %n more block(s) + Open for %n more blocks + + + + Open until %1 + Open until %1 + 351 + + + Offline + Offline + 354 + + + Unconfirmed + Unconfirmed + 357 + + + Confirming (%1 of %2 recommended confirmations) + Confirming (%1 of %2 recommended confirmations) + 360 + + + Confirmed (%1 confirmations) + Confirmed (%1 confirmations) + 363 + + + Conflicted + Conflicted + 366 + + + Immature (%1 confirmations, will be available after %2) + Immature (%1 confirmations, will be available after %2) + 369 + + + This block was not received by any other nodes and will probably not be accepted! + This block was not received by any other nodes and will probably not be accepted! + 372 + + + Received with + Received with + 410 + + + Masternode Reward + + 412 + + + Received from + Received from + 414 + + + Confirmed Count. + + 700 + + + Sent to + Sent to + 417 + + + Orphan Block - Generated but not accepted. This does not impact your holdings. + + 375 + + + Payment to yourself + Payment to yourself + 419 + + + Minted + + 421 + + + Mined + Mined + 423 + + + watch-only + watch-only + 457 + + + (n/a) + (n/a) + 474 + + + Transaction status. Hover over this field to show number of confirmations. + Transaction status. Hover over this field to show number of confirmations. + 688 + + + Date and time that the transaction was received. + Date and time that the transaction was received. + 690 + + + Type of transaction. + Type of transaction. + 692 + + + Whether or not a watch-only address is involved in this transaction. + Whether or not a watch-only address is involved in this transaction. + 694 + + + Destination address of transaction. + Destination address of transaction. + 696 + + + Amount removed from or added to balance. + Amount removed from or added to balance. + 698 + + + + + + + All + All + 68 + 85 + + + Today + Today + 69 + + + This week + This week + 70 + + + This month + This month + 71 + + + Last month + Last month + 72 + + + This year + This year + 73 + + + Range... + Range... + 74 + + + Most Common + Most Common + 86 + + + Received with + Received with + 87 + + + Sent to + Sent to + 88 + + + To yourself + To yourself + 89 + + + Mined + Mined + 90 + + + Minted + + 91 + + + Masternode Reward + + 92 + + + Other + Other + 93 + + + Enter address or label to search + Enter address or label to search + 99 + + + Min amount + Min amount + 103 + + + Copy address + Copy address + 138 + + + Copy label + Copy label + 139 + + + Copy amount + Copy amount + 140 + + + Copy transaction ID + Copy transaction ID + 141 + + + Edit label + Edit label + 142 + + + Show transaction details + Show transaction details + 143 + + + Hide orphan stakes + + 144 + + + Export Transaction History + Export Transaction History + 376 + + + Comma separated file (*.csv) + Comma separated file (*.csv) + 377 + + + Confirmed + Confirmed + 388 + + + Watch-only + Watch-only + 390 + + + Date + Date + 391 + + + Type + Type + 392 + + + Label + Label + 393 + + + Address + Address + 394 + + + ID + ID + 396 + + + Exporting Failed + Exporting Failed + 406 + + + There was an error trying to save the transaction history to %1. + There was an error trying to save the transaction history to %1. + 406 + + + Exporting Successful + Exporting Successful + 402 + + + The transaction history was successfully saved to %1. + The transaction history was successfully saved to %1. + 402 + + + Range: + Range: + 523 + + + to + to + 531 + + + + + + + Transaction Details + + 20 + + + Enter Code + + 31 + + + Please enter a six digit 2FA code: + + 45 + + + Confirm + + 302 + + + Return + + 305 + + + Cancel + + 312 + + + Esc + + 315 + + + + + + + Wrong 2FA Code + + 169 + + + Incorrect 2FA code entered. +Please try again. + + 170 + + + + + + + Transaction Details + + 20 + + + Enabling 2FA in your PRCY Desktop App + + 31 + + + After this step, you will need to periodically enter another 2FA code anytime you send a transaction from within this desktop app, so do not lose your 2FA code generator. + + 56 + + + Please enter a six digit 2FA code: + + 81 + + + Confirm + + 338 + + + Return + + 341 + + + Cancel + + 348 + + + Esc + + 351 + + + OPEN AUTHENTICATION APP + + 373 + + + + + + + Wrong 2FA Code + + 172 + + + Incorrect 2FA code entered. +Please try again. + + 173 + + + + + + + Below are your 2FA QR Code & Recovery Key. + + 28 + + + Please store them safely. Use them to regain access if you lose your device. + + 43 + + + QR Code + QR Code + 65 + + + Cancel + + 129 + + + Esc + + 132 + + + Next + + 142 + + + Return + + 145 + + + + + + + Resulting URI too long, try to reduce the text for label / message. + Resulting URI too long, try to reduce the text for label / message. + 89 + + + Error encoding URI into QR Code. + Error encoding URI into QR Code. + 93 + + + + + + + TxAmount + + 62 + + + lableDate + + 69 + + + TRANSACTION ID + + 168 + + + TO + + 173 + + + MM/DD/YYYY + + 178 + + + + + + + No wallet has been loaded. + No wallet has been loaded. + 25 + + + + + + + Send Coins + Send Coins + 332 + + + Mnemonic Recovery Phrase + + 367 + 392 + 419 + + + Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security. + + 368 + 393 + + + Are You Sure? + + 380 + + + Are you sure you would like to view your Mnemonic Phrase? +You will be required to enter your passphrase. Failed or canceled attempts will be logged. + + 381 + + + Copy + + 415 + + + OK + + 416 + + + Below is your Mnemonic Recovery Phrase, consisting of 24 seed words. Please copy/write these words down in order. We strongly recommend keeping multiple copies in different locations. + + 420 + + + + + + + &Export + &Export + 50 + + + Export the data in the current tab to a file + Export the data in the current tab to a file + 51 + + + Selected amount: + Selected amount: + 56 + + + Backup Wallet + Backup Wallet + 260 + + + Wallet Data (*.dat) + Wallet Data (*.dat) + 261 + + + + + + + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + 12 + + + Allow JSON-RPC connections from specified source. Valid for <ip> 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). This option can be specified multiple times + Allow JSON-RPC connections from specified source. Valid for <ip> 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). This option can be specified multiple times + 18 + + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 + Bind to given address and always listen on it. Use [host]:port notation for IPv6 + 22 + + + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + 25 + + + Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) + Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) + 28 + + + Cannot obtain a lock on data directory %s. PRCY is probably already running. + + 32 + + + Change automatic finalized budget voting behavior. mode=auto: Vote for only exact finalized budget match to my generated budget. (string, default: auto) + Change automatic finalized budget voting behavior. mode=auto: Vote for only exact finalized budget match to my generated budget. (string, default: auto) + 34 + + + Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u) + Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u) + 40 + + + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + 43 + + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup + 46 + + + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + 52 + + + Enter regression test mode, which uses a special chain in which blocks can be solved instantly. + Enter regression test mode, which uses a special chain in which blocks can be solved instantly. + 59 + + + Error: Listening for incoming connections failed (listen returned error %s) + Error: Listening for incoming connections failed (listen returned error %s) + 62 + + + Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + 68 + + + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) + 75 + + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + 78 + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Execute command when the best block changes (%s in cmd is replaced by block hash) + 81 + + + Execute command when the best block changes and its size is over (%s in cmd is replaced by block hash, %d with the block size) + + 84 + + + Flush database activity from memory pool to disk log every <n> megabytes (default: %u) + Flush database activity from memory pool to disk log every <n> megabytes (default: %u) + 93 + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + 96 + + + In this mode -genproclimit controls how many blocks are generated immediately. + In this mode -genproclimit controls how many blocks are generated immediately. + 99 + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + 102 + + + Keep the specified amount available for spending at all times (default: 0) + + 105 + + + Loading... Please do not interrupt this process as it could lead to a corrupt wallet. + + 107 + + + Log transaction priority and fee per kB when mining blocks (default: %u) + Log transaction priority and fee per kB when mining blocks (default: %u) + 110 + + + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + 112 + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + Maximum size of data in data carrier transactions we relay and mine (default: %u) + 118 + + + Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s) + Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s) + 123 + + + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + 126 + + + Output debugging information (default: %u, supplying <category> is optional) + Output debugging information (default: %u, supplying <category> is optional) + 128 + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + + 133 + + + Require high priority for relaying free or low-fee transactions (default:%u) + Require high priority for relaying free or low-fee transactions (default:%u) + 136 + + + Rescanning... Please do not interrupt this process as it could lead to a corrupt wallet. + + 138 + + + Send trace/debug info to console instead of debug.log file (default: %u) + Send trace/debug info to console instead of debug.log file (default: %u) + 141 + + + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) + 143 + + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + 145 + + + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + 148 + + + Show N confirmations for a successfully locked transaction (0-9999, default: %u) + Show N confirmations for a successfully locked transaction (0-9999, default: %u) + 151 + + + Support filtering of blocks and transaction with bloom filters (default: %u) + + 161 + + + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct + + 163 + + + There is an internal error in generating bulletproofs. Please try again later. + + 168 + + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + 174 + + + Unable to bind to %s on this computer. PRCY is probably already running. + + 181 + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + 183 + + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + + 186 + + + Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction. + Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction. + 190 + + + Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + 193 + + + Warning: Please check that your computer's date and time are correct! If your clock is wrong PRCY will not work properly. + + 196 + + + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + 199 + + + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + 202 + + + Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + 205 + + + Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. + Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. + 208 + + + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + 212 + + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + 215 + + + You have attempted to send a total value that is comprised of more than 50 smaller deposits. This is a rare occurrence, and lowering the total value sent, or sending the same total value in two separate transactions will usually work around this limitation. + + 218 + + + You must specify a masternodeprivkey in the configuration. Please see documentation for help. + You must specify a masternodeprivkey in the configuration. Please see documentation for help. + 228 + + + (default: %s) + (default: %s) + 231 + + + (default: 1) + (default: 1) + 232 + + + Accept command line and JSON-RPC commands + Accept command line and JSON-RPC commands + 235 + + + Accept public REST requests (default: %u) + Accept public REST requests (default: %u) + 236 + + + Add a node to connect to and attempt to keep the connection open + Add a node to connect to and attempt to keep the connection open + 237 + + + Allow DNS lookups for -addnode, -seednode and -connect + Allow DNS lookups for -addnode, -seednode and -connect + 239 + + + Always query for peer addresses via DNS lookup (default: %u) + Always query for peer addresses via DNS lookup (default: %u) + 240 + + + Attempt to recover private keys from a corrupt wallet.dat + Attempt to recover private keys from a corrupt wallet.dat + 243 + + + Automatically create Tor hidden service (default: %d) + + 244 + + + Block creation options: + Block creation options: + 245 + + + Cannot downgrade wallet + Cannot downgrade wallet + 250 + + + Cannot write default address + Cannot write default address + 256 + + + Connect through SOCKS5 proxy + Connect through SOCKS5 proxy + 257 + + + Connect to a node to retrieve peer addresses, and disconnect + Connect to a node to retrieve peer addresses, and disconnect + 258 + + + Connection options: + Connection options: + 259 + + + Copyright (C) 2009-%i The Bitcoin Core Developers + Copyright (C) 2009-%i The Bitcoin Core Developers + 260 + + + Copyright (C) 2014-%i The Dash Core Developers + + 261 + + + Corrupted block database detected + Corrupted block database detected + 265 + + + Could not parse masternode.conf + Could not parse masternode.conf + 266 + + + Debugging/Testing options: + Debugging/Testing options: + 268 + + + Delete blockchain folders and resync from scratch + + 269 + + + Disable OS notifications for incoming transactions (default: %u) + + 270 + + + Disable safemode, override a real safe mode event (default: %u) + Disable safemode, override a real safe mode event (default: %u) + 271 + + + Discover own IP address (default: 1 when listening and no -externalip) + Discover own IP address (default: 1 when listening and no -externalip) + 272 + + + Do not load the wallet and disable wallet RPC calls + Do not load the wallet and disable wallet RPC calls + 275 + + + Do you want to rebuild the block database now? + Do you want to rebuild the block database now? + 276 + + + Done loading + Done loading + 277 + + + Enable Old Transaction Deletion + + 278 + + + Enable publish hash transaction (locked via SwiftX) in <address> + + 280 + + + Enable publish raw transaction (locked via SwiftX) in <address> + + 283 + + + Enable the client to act as a masternode (0-1, default: %u) + Enable the client to act as a masternode (0-1, default: %u) + 286 + + + Error initializing block database + Error initializing block database + 289 + + + Error initializing wallet database environment %s! + Error initializing wallet database environment %s! + 290 + + + Error loading block database + Error loading block database + 291 + + + Error loading wallet.dat + Error loading wallet.dat + 292 + + + Error loading wallet.dat: Wallet corrupted + Error loading wallet.dat: Wallet corrupted + 293 + + + Error opening block database + Error opening block database + 295 + + + Error reading from database, shutting down. + Error reading from database, shutting down. + 296 + + + Error + Error + 297 + + + Error: A fatal internal error occured, see debug.log for details + Error: A fatal internal error occured, see debug.log for details + 299 + + + Error: Disk space is low! + Error: Disk space is low! + 301 + + + Error: Unsupported argument -tor found, use -onion. + Error: Unsupported argument -tor found, use -onion. + 303 + + + Failed to generate RingCT + + 304 + + + Failed to listen on any port. Use -listen=0 if you want this. + Failed to listen on any port. Use -listen=0 if you want this. + 306 + + + Force safe mode (default: %u) + Force safe mode (default: %u) + 309 + + + Generate coins (default: %u) + Generate coins (default: %u) + 310 + + + How many blocks to check at startup (default: %u, 0 = all) + How many blocks to check at startup (default: %u, 0 = all) + 311 + + + If <category> is not supplied, output all debugging information. + If <category> is not supplied, output all debugging information. + 312 + + + Importing... + Importing... + 313 + + + Imports blocks from external blk000??.dat file + Imports blocks from external blk000??.dat file + 314 + + + Include IP addresses in debug output (default: %u) + Include IP addresses in debug output (default: %u) + 315 + + + Incorrect or no genesis block found. Wrong datadir for network? + Incorrect or no genesis block found. Wrong datadir for network? + 316 + + + Information + Information + 317 + + + Initialization sanity check failed. PRCY is shutting down. + + 318 + + + Insufficient funds. + Insufficient funds. + 320 + + + Invalid -onion address or hostname: '%s' + + 323 + + + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + 325 + + + Invalid amount for -reservebalance=<amount> + + 326 + + + Invalid masternodeprivkey. Please see documenation. + Invalid masternodeprivkey. Please see documenation. + 327 + + + Invalid netmask specified in -whitelist: '%s' + Invalid netmask specified in -whitelist: '%s' + 328 + + + Reindex the %s money supply statistics + + 367 + + + SwiftX options: + + 397 + + + This is a pre-release test build - use at your own risk - do not use for staking or merchant applications! + + 171 + + + Accept connections from outside (default: 1 if no -proxy or -connect/-noconnect) + + 15 + + + Connect only to the specified node(s); -noconnect or -connect=0 alone to disable automatic connections + + 37 + + + Delete transaction every <n> blocks during inital block download (default: %i) + + 49 + + + Enable SwiftX, show confirmations for locked transactions (bool, default: %s) + + 55 + + + Enable or disable staking functionality for PRCY inputs (0-1, default: %u) + + 57 + + + Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + + 64 + + + Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except one or more specified categories. + + 71 + + + Fees (in %s/Kb) smaller than this are considered zero fee for relaying (default: %s) + + 87 + + + Fees (in %s/Kb) smaller than this are considered zero fee for transaction creation (default: %s) + + 90 + + + Maximum average size of an index occurrence in the block spam filter (default: %u) + + 115 + + + Maximum size of the list of indexes in the block spam filter (default: %u) + + 121 + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect) + + 130 + + + Specify custom backup path to add a copy of any wallet backup. If set as dir, every backup generates a timestamped file. If set as file, will rewrite to that file every backup. + + 154 + + + Specify location of debug log file: this can be an absolute path or a path relative to the data directory (default: %s) + + 158 + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + + 178 + + + You have attempted to send more than 50 UTXOs in a single transaction. To work around this limitation, please either lower the total amount of the transaction or send two separate transactions with 50% of your total desired amount. + + 223 + + + (must be %d for %s-net) + + 233 + + + <category> can be: + + 234 + + + All inputs should have the same number of decoys + + 238 + + + Append comment to the user agent string + + 241 + + + Attempt to force blockchain corruption recovery + + 242 + + + Cannot compute LIJ for ring signature in secp256k1_ec_pubkey_tweak_add + + 246 + + + Cannot compute LIJ for ring signature in secp256k1_ec_pubkey_tweak_mul + + 247 + + + Cannot compute RIJ for ring signature in secp256k1_ec_pubkey_tweak_mul + + 248 + + + Cannot compute two elements and serialize it to pubkey + + 249 + + + Cannot extract public key from script pubkey + + 251 + + + Cannot find corresponding private key + + 252 + + + Cannot parse the commitment for inputs + + 253 + + + Cannot parse the commitment for transaction fee + + 254 + + + Cannot resolve -%s address: '%s' + + 255 + + + Copyright (C) 2015-%i The PIVX Core Developers + + 262 + + + Copyright (C) 2018-%i The DAPS Project developers + + 263 + + + Copyright (C) 2020-%i The PRivaCY Coin Developers + + 264 + + + Currently the Number of supported recipients must be 1 + + 267 + + + Display the stake modifier calculations in the debug.log file. + + 273 + + + Display verbose coin stake messages in the debug.log file. + + 274 + + + Enable publish hash block in <address> + + 279 + + + Enable publish hash transaction in <address> + + 281 + + + Enable publish raw block in <address> + + 282 + + + Enable publish raw transaction in <address> + + 284 + + + Enable staking functionality (0-1, default: %u) + + 285 + + + Error in CreateTransaction. Please try again. + + 287 + + + Error in CreateTransactionBulletProof. Please try again. + + 288 + + + Error loading wallet.dat: Wallet requires newer version of PRCYcoin + + 294 + + + Error: -listen must be true if -masternode is set. + + 298 + + + Error: A fatal internal error occurred, see debug.log for details + + 300 + + + Error: Invalid port %d for running a masternode. + + 302 + + + Failed to generate bulletproof + + 305 + + + Failed to parse host:port string + + 307 + + + Fee (in %s/kB) to add to transactions you send (default: %s) + + 308 + + + Input commitments are not correct + + 319 + + + Invalid -masternodeaddr address: %s + + 321 + + + Invalid -masternodeaddr port %d, only %d is supported on %s-net. + + 322 + + + Invalid amount for -%s=<amount>: '%s' + + 324 + + + Invalid port %d detected in masternode.conf + + 329 + + + Keep at most <n> unconnectable transactions in memory (default: %u) + Keep at most <n> unconnectable transactions in memory (default: %u) + 330 + + + Line: %d + Line: %d + 334 + + + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + 335 + + + Listen for connections on <port> (default: %u or testnet: %u) + Listen for connections on <port> (default: %u or testnet: %u) + 336 + + + Loading addresses... + Loading addresses... + 337 + + + Loading banlist... + + 338 + + + Loading block index... + Loading block index... + 339 + + + Loading budget cache... + Loading budget cache... + 340 + + + Loading masternode cache... + Loading masternode cache... + 341 + + + Loading masternode payment cache... + Loading masternode payment cache... + 342 + + + Lock masternodes from masternode configuration file (default: %u) + Lock masternodes from masternode configuration file (default: %u) + 343 + + + Lookup(): Invalid -proxy address or hostname: '%s' + + 344 + + + Maintain at most <n> connections to peers (default: %u) + Maintain at most <n> connections to peers (default: %u) + 345 + + + Masternode options: + Masternode options: + 346 + + + Masternodes are required to run on port %d for %s-net + + 347 + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + 348 + + + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + 349 + + + Need to specify a port with -whitebind: '%s' + Need to specify a port with -whitebind: '%s' + 350 + + + Node relay options: + Node relay options: + 351 + + + Not enough file descriptors available. + Not enough file descriptors available. + 352 + + + Number of automatic wallet backups (default: 10) + Number of automatic wallet backups (default: 10) + 353 + + + Only accept block chain matching built-in checkpoints (default: %u) + Only accept block chain matching built-in checkpoints (default: %u) + 355 + + + Only connect to nodes in network <net> (ipv4, ipv6 or onion) + Only connect to nodes in network <net> (ipv4, ipv6 or onion) + 356 + + + Options: + Options: + 357 + + + Password for JSON-RPC connections + Password for JSON-RPC connections + 358 + + + Preparing for resync... + + 359 + + + Prepend debug output with timestamp (default: %u) + Prepend debug output with timestamp (default: %u) + 360 + + + Print version and exit + + 361 + + + RPC server options: + RPC server options: + 362 + + + Randomly drop 1 of every <n> network messages + Randomly drop 1 of every <n> network messages + 363 + + + Randomly fuzz 1 of every <n> network messages + Randomly fuzz 1 of every <n> network messages + 364 + + + Rebuild block chain index from current blk000??.dat files + Rebuild block chain index from current blk000??.dat files + 365 + + + Recalculating PRCY supply... + + 366 + + + Relay and mine data carrier transactions (default: %u) + Relay and mine data carrier transactions (default: %u) + 368 + + + Relay non-P2SH multisig (default: %u) + Relay non-P2SH multisig (default: %u) + 369 + + + Rescan the block chain for missing wallet transactions + Rescan the block chain for missing wallet transactions + 370 + + + Rescanning... + Rescanning... + 371 + + + Run a thread to flush wallet periodically (default: %u) + Run a thread to flush wallet periodically (default: %u) + 372 + + + Run in the background as a daemon and accept commands + Run in the background as a daemon and accept commands + 373 + + + Send transactions as zero-fee transactions if possible (default: %u) + Send transactions as zero-fee transactions if possible (default: %u) + 374 + + + Set database cache size in megabytes (%d to %d, default: %d) + Set database cache size in megabytes (%d to %d, default: %d) + 375 + + + Set external address:port to get to this masternode (example: %s) + Set external address:port to get to this masternode (example: %s) + 376 + + + Set key pool size to <n> (default: %u) + Set key pool size to <n> (default: %u) + 377 + + + Set maximum block size in bytes (default: %d) + Set maximum block size in bytes (default: %d) + 378 + + + Set minimum block size in bytes (default: %u) + Set minimum block size in bytes (default: %u) + 379 + + + Set the Maximum reorg depth (default: %u) + + 380 + + + Set the masternode private key + Set the masternode private key + 381 + + + Set the number of threads to service RPC calls (default: %d) + Set the number of threads to service RPC calls (default: %d) + 382 + + + Sets the DB_PRIVATE flag in the wallet db environment (default: %u) + Sets the DB_PRIVATE flag in the wallet db environment (default: %u) + 383 + + + Show all debugging options (usage: --help -help-debug) + Show all debugging options (usage: --help -help-debug) + 384 + + + Shrink debug.log file on client startup (default: 1 when no -debug) + Shrink debug.log file on client startup (default: 1 when no -debug) + 385 + + + Keep the last <n> transactions (default: %i) + + 331 + + + Keep transactions for at least <n> blocks (default: %i) + + 332 + + + Limit size of signature cache to <n> MiB (default: %u) + + 333 + + + Number of custom location backups to retain (default: %d) + + 354 + + + Signing transaction failed + Signing transaction failed + 386 + + + Specify configuration file (default: %s) + Specify configuration file (default: %s) + 387 + + + Specify connection timeout in milliseconds (minimum: 1, default: %d) + Specify connection timeout in milliseconds (minimum: 1, default: %d) + 388 + + + Specify data directory + Specify data directory + 389 + + + Specify masternode configuration file (default: %s) + Specify masternode configuration file (default: %s) + 390 + + + Specify pid file (default: %s) + Specify pid file (default: %s) + 391 + + + Specify wallet file (within data directory) + Specify wallet file (within data directory) + 392 + + + Specify your own public address + Specify your own public address + 393 + + + Spend unconfirmed change when sending transactions (default: %u) + Spend unconfirmed change when sending transactions (default: %u) + 394 + + + Staking options: + + 395 + + + Stop running after importing blocks from disk (default: %u) + Stop running after importing blocks from disk (default: %u) + 396 + + + Synchronization failed + Synchronization failed + 398 + + + Synchronization finished + Synchronization finished + 399 + + + Synchronization pending... + Synchronization pending... + 400 + + + Synchronizing budgets... + Synchronizing budgets... + 401 + + + Synchronizing masternode winners... + Synchronizing masternode winners... + 402 + + + Synchronizing masternodes... + Synchronizing masternodes... + 403 + + + This help message + This help message + 404 + + + This is experimental software. + This is experimental software. + 405 + + + This is intended for regression testing tools and app development. + This is intended for regression testing tools and app development. + 406 + + + Threshold for disconnecting misbehaving peers (default: %u) + Threshold for disconnecting misbehaving peers (default: %u) + 407 + + + Too many decoys + + 408 + + + Tor control port password (default: empty) + + 409 + + + Tor control port to use if onion listening enabled (default: %s) + + 410 + + + Transaction amount too small + Transaction amount too small + 411 + + + Transaction amounts must be positive + Transaction amounts must be positive + 412 + + + Transaction too large for fee policy + Transaction too large for fee policy + 413 + + + Transaction too large + Transaction too large + 414 + + + Unable to bind to %s on this computer (bind returned error %s) + Unable to bind to %s on this computer (bind returned error %s) + 415 + + + Unable to start HTTP server. See debug log for details. + + 416 + + + Unknown network specified in -onlynet: '%s' + Unknown network specified in -onlynet: '%s' + 417 + + + Unsupported logging category %s=%s. + + 418 + + + Upgrade wallet to latest format + Upgrade wallet to latest format + 419 + + + Use UPnP to map the listening port (default: %u) + Use UPnP to map the listening port (default: %u) + 420 + + + Use UPnP to map the listening port (default: 1 when listening) + Use UPnP to map the listening port (default: 1 when listening) + 421 + + + Use a custom max chain reorganization depth (default: %u) + + 422 + + + Use block spam filter (default: %u) + + 423 + + + Use the test network + Use the test network + 424 + + + User Agent comment (%s) contains unsafe characters. + + 425 + + + Username for JSON-RPC connections + Username for JSON-RPC connections + 426 + + + Verifying blocks... + Verifying blocks... + 427 + + + Verifying wallet... + Verifying wallet... + 428 + + + Wallet %s resides outside data directory %s + Wallet %s resides outside data directory %s + 429 + + + Wallet needed to be rewritten: restart PRCY to complete + + 430 + + + Wallet options: + Wallet options: + 431 + + + Wallet window title + Wallet window title + 432 + + + Warning + Warning + 433 + + + Warning: This version is obsolete, upgrade required! + Warning: This version is obsolete, upgrade required! + 434 + + + Warning: Unsupported argument -benchmark ignored, use -debug=bench. + Warning: Unsupported argument -benchmark ignored, use -debug=bench. + 435 + + + Warning: Unsupported argument -debugnet ignored, use -debug=net. + Warning: Unsupported argument -debugnet ignored, use -debug=net. + 436 + + + You need to rebuild the database using -reindex to change -txindex + You need to rebuild the database using -reindex to change -txindex + 437 + + + Zapping all transactions from wallet... + Zapping all transactions from wallet... + 438 + + + ZeroMQ notification options: + + 439 + + + isValid(): Invalid -proxy address or hostname: '%s' + + 440 + + + on startup + on startup + 441 + + + wallet.dat corrupt, salvage failed + wallet.dat corrupt, salvage failed + 442 + + + + diff --git a/src/qt/prcycoinstrings.cpp b/src/qt/prcycoinstrings.cpp index eb22f8a034..50791836c9 100644 --- a/src/qt/prcycoinstrings.cpp +++ b/src/qt/prcycoinstrings.cpp @@ -47,11 +47,16 @@ QT_TRANSLATE_NOOP("prcycoin-core", "" "Delete all wallet transactions and only recover those parts of the " "blockchain through -rescan on startup"), QT_TRANSLATE_NOOP("prcycoin-core", "" +"Delete transaction every blocks during inital block download (default: " +"%i)"), +QT_TRANSLATE_NOOP("prcycoin-core", "" "Distributed under the MIT software license, see the accompanying file " "COPYING or ."), QT_TRANSLATE_NOOP("prcycoin-core", "" "Enable SwiftX, show confirmations for locked transactions (bool, default: %s)"), QT_TRANSLATE_NOOP("prcycoin-core", "" +"Enable or disable staking functionality for PRCY inputs (0-1, default: %u)"), +QT_TRANSLATE_NOOP("prcycoin-core", "" "Enter regression test mode, which uses a special chain in which blocks can " "be solved instantly."), QT_TRANSLATE_NOOP("prcycoin-core", "" @@ -108,9 +113,14 @@ QT_TRANSLATE_NOOP("prcycoin-core", "" "Maintain a full transaction index, used by the getrawtransaction rpc call " "(default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "" +"Maximum average size of an index occurrence in the block spam filter " +"(default: %u)"), +QT_TRANSLATE_NOOP("prcycoin-core", "" "Maximum size of data in data carrier transactions we relay and mine " "(default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "" +"Maximum size of the list of indexes in the block spam filter (default: %u)"), +QT_TRANSLATE_NOOP("prcycoin-core", "" "Maximum total fees to use in a single wallet transaction, setting too low " "may abort large transactions (default: %s)"), QT_TRANSLATE_NOOP("prcycoin-core", "" @@ -171,12 +181,13 @@ QT_TRANSLATE_NOOP("prcycoin-core", "" QT_TRANSLATE_NOOP("prcycoin-core", "" "Unable to bind to %s on this computer. PRCY is probably already running."), QT_TRANSLATE_NOOP("prcycoin-core", "" -"Unable to locate enough funds for this transaction that are not equal 10000 " -"PRCY."), -QT_TRANSLATE_NOOP("prcycoin-core", "" "Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: " "%s)"), QT_TRANSLATE_NOOP("prcycoin-core", "" +"Username and hashed password for JSON-RPC connections. The field " +"comes in the format: :$. A canonical python script is " +"included in share/rpcuser. This option can be specified multiple times"), +QT_TRANSLATE_NOOP("prcycoin-core", "" "Warning: -maxtxfee is set very high! Fees this large could be paid on a " "single transaction."), QT_TRANSLATE_NOOP("prcycoin-core", "" @@ -264,6 +275,7 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Display verbose coin stake messages in the d QT_TRANSLATE_NOOP("prcycoin-core", "Do not load the wallet and disable wallet RPC calls"), QT_TRANSLATE_NOOP("prcycoin-core", "Do you want to rebuild the block database now?"), QT_TRANSLATE_NOOP("prcycoin-core", "Done loading"), +QT_TRANSLATE_NOOP("prcycoin-core", "Enable Old Transaction Deletion"), QT_TRANSLATE_NOOP("prcycoin-core", "Enable publish hash block in
"), QT_TRANSLATE_NOOP("prcycoin-core", "Enable publish hash transaction (locked via SwiftX) in
"), QT_TRANSLATE_NOOP("prcycoin-core", "Enable publish hash transaction in
"), @@ -282,7 +294,6 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Error loading wallet.dat: Wallet corrupted") QT_TRANSLATE_NOOP("prcycoin-core", "Error loading wallet.dat: Wallet requires newer version of PRCYcoin"), QT_TRANSLATE_NOOP("prcycoin-core", "Error opening block database"), QT_TRANSLATE_NOOP("prcycoin-core", "Error reading from database, shutting down."), -QT_TRANSLATE_NOOP("prcycoin-core", "Error recovering public key."), QT_TRANSLATE_NOOP("prcycoin-core", "Error"), QT_TRANSLATE_NOOP("prcycoin-core", "Error: -listen must be true if -masternode is set."), QT_TRANSLATE_NOOP("prcycoin-core", "Error: A fatal internal error occured, see debug.log for details"), @@ -290,12 +301,10 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Error: A fatal internal error occurred, see QT_TRANSLATE_NOOP("prcycoin-core", "Error: Disk space is low!"), QT_TRANSLATE_NOOP("prcycoin-core", "Error: Invalid port %d for running a masternode."), QT_TRANSLATE_NOOP("prcycoin-core", "Error: Unsupported argument -tor found, use -onion."), -QT_TRANSLATE_NOOP("prcycoin-core", "Failed to generate RingCT for Sweeping transaction"), -QT_TRANSLATE_NOOP("prcycoin-core", "Failed to generate bulletproof for Sweeping transaction"), +QT_TRANSLATE_NOOP("prcycoin-core", "Failed to generate RingCT"), QT_TRANSLATE_NOOP("prcycoin-core", "Failed to generate bulletproof"), QT_TRANSLATE_NOOP("prcycoin-core", "Failed to listen on any port. Use -listen=0 if you want this."), QT_TRANSLATE_NOOP("prcycoin-core", "Failed to parse host:port string"), -QT_TRANSLATE_NOOP("prcycoin-core", "Failed to read block"), QT_TRANSLATE_NOOP("prcycoin-core", "Fee (in %s/kB) to add to transactions you send (default: %s)"), QT_TRANSLATE_NOOP("prcycoin-core", "Force safe mode (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Generate coins (default: %u)"), @@ -318,9 +327,10 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Invalid amount for -reservebalance=" QT_TRANSLATE_NOOP("prcycoin-core", "Invalid masternodeprivkey. Please see documenation."), QT_TRANSLATE_NOOP("prcycoin-core", "Invalid netmask specified in -whitelist: '%s'"), QT_TRANSLATE_NOOP("prcycoin-core", "Invalid port %d detected in masternode.conf"), -QT_TRANSLATE_NOOP("prcycoin-core", "Invalid private key."), QT_TRANSLATE_NOOP("prcycoin-core", "Keep at most unconnectable transactions in memory (default: %u)"), -QT_TRANSLATE_NOOP("prcycoin-core", "Limit size of signature cache to entries (default: %u)"), +QT_TRANSLATE_NOOP("prcycoin-core", "Keep the last transactions (default: %i)"), +QT_TRANSLATE_NOOP("prcycoin-core", "Keep transactions for at least blocks (default: %i)"), +QT_TRANSLATE_NOOP("prcycoin-core", "Limit size of signature cache to MiB (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Line: %d"), QT_TRANSLATE_NOOP("prcycoin-core", "Listen for JSON-RPC connections on (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Listen for connections on (default: %u or testnet: %u)"), @@ -341,6 +351,7 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Need to specify a port with -whitebind: '%s' QT_TRANSLATE_NOOP("prcycoin-core", "Node relay options:"), QT_TRANSLATE_NOOP("prcycoin-core", "Not enough file descriptors available."), QT_TRANSLATE_NOOP("prcycoin-core", "Number of automatic wallet backups (default: 10)"), +QT_TRANSLATE_NOOP("prcycoin-core", "Number of custom location backups to retain (default: %d)"), QT_TRANSLATE_NOOP("prcycoin-core", "Only accept block chain matching built-in checkpoints (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Only connect to nodes in network (ipv4, ipv6 or onion)"), QT_TRANSLATE_NOOP("prcycoin-core", "Options:"), @@ -361,7 +372,6 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Rescanning..."), QT_TRANSLATE_NOOP("prcycoin-core", "Run a thread to flush wallet periodically (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Run in the background as a daemon and accept commands"), QT_TRANSLATE_NOOP("prcycoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), -QT_TRANSLATE_NOOP("prcycoin-core", "Session timed out."), QT_TRANSLATE_NOOP("prcycoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"), QT_TRANSLATE_NOOP("prcycoin-core", "Set external address:port to get to this masternode (example: %s)"), QT_TRANSLATE_NOOP("prcycoin-core", "Set key pool size to (default: %u)"), @@ -373,8 +383,6 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Set the number of threads to service RPC cal QT_TRANSLATE_NOOP("prcycoin-core", "Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Show all debugging options (usage: --help -help-debug)"), QT_TRANSLATE_NOOP("prcycoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"), -QT_TRANSLATE_NOOP("prcycoin-core", "Signing failed."), -QT_TRANSLATE_NOOP("prcycoin-core", "Signing timed out."), QT_TRANSLATE_NOOP("prcycoin-core", "Signing transaction failed"), QT_TRANSLATE_NOOP("prcycoin-core", "Specify configuration file (default: %s)"), QT_TRANSLATE_NOOP("prcycoin-core", "Specify connection timeout in milliseconds (minimum: 1, default: %d)"), @@ -412,6 +420,7 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Upgrade wallet to latest format"), QT_TRANSLATE_NOOP("prcycoin-core", "Use UPnP to map the listening port (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Use UPnP to map the listening port (default: 1 when listening)"), QT_TRANSLATE_NOOP("prcycoin-core", "Use a custom max chain reorganization depth (default: %u)"), +QT_TRANSLATE_NOOP("prcycoin-core", "Use block spam filter (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Use the test network"), QT_TRANSLATE_NOOP("prcycoin-core", "User Agent comment (%s) contains unsafe characters."), QT_TRANSLATE_NOOP("prcycoin-core", "Username for JSON-RPC connections"), From a73b7fbf780e617443d4a81ceb226476d562ac11 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 15:03:43 -0400 Subject: [PATCH 306/391] build: Use Qt top-level build facilities --- depends/packages/qt.mk | 22 ++++++---------------- depends/patches/qt/qt.pro | 12 ++++++++++++ depends/patches/qt/qttools_src.pro | 2 ++ 3 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 depends/patches/qt/qt.pro create mode 100644 depends/patches/qt/qttools_src.pro diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index c60aa7e7f4..9390a46f50 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -7,7 +7,8 @@ $(package)_sha256_hash=1c1b4e33137ca77881074c140d54c3c9747e845a31338cfe8680f171f $(package)_dependencies=openssl zlib $(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon $(package)_qt_libs=corelib network widgets gui plugins testlib concurrent -$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch +$(package)_patches = qt.pro qttools_src.pro +$(package)_patches += fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch $(package)_patches+= drop_lrelease_dependency.patch no_sdk_version_check.patch $(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch @@ -209,6 +210,8 @@ endef # 8. Adjust a regex in toolchain.prf, to accomodate Guix's usage of # CROSS_LIBRARY_PATH. See #15277. define $(package)_preprocess_cmds + cp $($(package)_patch_dir)/qt.pro qt.pro && \ + cp $($(package)_patch_dir)/qttools_src.pro qttools/src/src.pro && \ patch -p1 -i $($(package)_patch_dir)/drop_lrelease_dependency.patch && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ @@ -241,25 +244,12 @@ endef define $(package)_config_cmds cd qtbase && \ - ./configure $($(package)_config_opts) && \ - echo "host_build: QT_CONFIG ~= s/system-zlib/zlib" >> mkspecs/qconfig.pri && \ - echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \ - cd .. && \ - $(MAKE) -C qtbase sub-src-clean && \ - qtbase/bin/qmake -o qttranslations/Makefile qttranslations/qttranslations.pro && \ - qtbase/bin/qmake -o qttranslations/translations/Makefile qttranslations/translations/translations.pro && \ - qtbase/bin/qmake -o qttools/src/linguist/lrelease/Makefile qttools/src/linguist/lrelease/lrelease.pro && \ - qtbase/bin/qmake -o qttools/src/linguist/lupdate/Makefile qttools/src/linguist/lupdate/lupdate.pro && \ - qtbase/bin/qmake -o qttools/src/linguist/lconvert/Makefile qttools/src/linguist/lconvert/lconvert.pro + ./configure -top-level $($(package)_config_opts) endef define $(package)_build_cmds export PATH=$(build_prefix)/bin:$(PATH) && \ - $(MAKE) -C qtbase/src $(addprefix sub-,$($(package)_qt_libs)) && \ - $(MAKE) -C qttools/src/linguist/lrelease && \ - $(MAKE) -C qttools/src/linguist/lupdate && \ - $(MAKE) -C qttools/src/linguist/lconvert && \ - $(MAKE) -C qttranslations + $(MAKE) endef define $(package)_stage_cmds diff --git a/depends/patches/qt/qt.pro b/depends/patches/qt/qt.pro new file mode 100644 index 0000000000..6d8b7fdb6a --- /dev/null +++ b/depends/patches/qt/qt.pro @@ -0,0 +1,12 @@ +# Create the super cache so modules will add themselves to it. +cache(, super) + +!QTDIR_build: cache(CONFIG, add, $$list(QTDIR_build)) + +TEMPLATE = subdirs +SUBDIRS = qtbase qttools qttranslations + +qttools.depends = qtbase +qttranslations.depends = qttools + +load(qt_configure) diff --git a/depends/patches/qt/qttools_src.pro b/depends/patches/qt/qttools_src.pro new file mode 100644 index 0000000000..487e226e97 --- /dev/null +++ b/depends/patches/qt/qttools_src.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = linguist From 3572d3ed39bffacc60068ffa8ab83b23a8eb5aba Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 15:07:40 -0400 Subject: [PATCH 307/391] build, qt: Add linguist_tools list --- depends/packages/qt.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 9390a46f50..e4197ab904 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -7,6 +7,7 @@ $(package)_sha256_hash=1c1b4e33137ca77881074c140d54c3c9747e845a31338cfe8680f171f $(package)_dependencies=openssl zlib $(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon $(package)_qt_libs=corelib network widgets gui plugins testlib concurrent +$(package)_linguist_tools = lrelease lupdate lconvert $(package)_patches = qt.pro qttools_src.pro $(package)_patches += fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch @@ -254,9 +255,7 @@ endef define $(package)_stage_cmds $(MAKE) -C qtbase/src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && \ - $(MAKE) -C qttools/src/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install_target && \ - $(MAKE) -C qttools/src/linguist/lupdate INSTALL_ROOT=$($(package)_staging_dir) install_target && \ - $(MAKE) -C qttools/src/linguist/lconvert INSTALL_ROOT=$($(package)_staging_dir) install_target && \ + $(MAKE) -C qttools/src/linguist INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_linguist_tools))) && \ $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets endef From 2eda289f93774305ceae617e4dc8c6ef42b714cf Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 15:21:56 -0400 Subject: [PATCH 308/391] build, qt: Drop lrelease dependency patch It is no longer required after switching to Qt top-level build. --- depends/packages/qt.mk | 3 +-- .../patches/qt/drop_lrelease_dependency.patch | 20 ------------------- 2 files changed, 1 insertion(+), 22 deletions(-) delete mode 100644 depends/patches/qt/drop_lrelease_dependency.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index e4197ab904..0f24da5d7d 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -11,7 +11,7 @@ $(package)_linguist_tools = lrelease lupdate lconvert $(package)_patches = qt.pro qttools_src.pro $(package)_patches += fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch -$(package)_patches+= drop_lrelease_dependency.patch no_sdk_version_check.patch +$(package)_patches+= no_sdk_version_check.patch $(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch $(package)_patches+= fix_limits_header.patch @@ -213,7 +213,6 @@ endef define $(package)_preprocess_cmds cp $($(package)_patch_dir)/qt.pro qt.pro && \ cp $($(package)_patch_dir)/qttools_src.pro qttools/src/src.pro && \ - patch -p1 -i $($(package)_patch_dir)/drop_lrelease_dependency.patch && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \ diff --git a/depends/patches/qt/drop_lrelease_dependency.patch b/depends/patches/qt/drop_lrelease_dependency.patch deleted file mode 100644 index 9b918af77c..0000000000 --- a/depends/patches/qt/drop_lrelease_dependency.patch +++ /dev/null @@ -1,20 +0,0 @@ -commit 67b3ed7406e1d0762188dbad2c44a06824ba0778 -Author: fanquake -Date: Tue Aug 18 15:24:01 2020 +0800 - - Drop dependency on lrelease - - Qts buildsystem insists on using the installed lrelease, but gets - confused about how to find it. Since we manually control the build - order, just drop the dependency. - - See #9469 - -diff --git a/qttranslations/translations/translations.pro b/qttranslations/translations/translations.pro -index 694544c..eff339d 100644 ---- a/qttranslations/translations/translations.pro -+++ b/qttranslations/translations/translations.pro -@@ -107,3 +107,2 @@ updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} - silent:updateqm.commands = @echo lrelease ${QMAKE_FILE_IN} && $$updateqm.commands --updateqm.depends = $$LRELEASE_EXE - updateqm.name = LRELEASE ${QMAKE_FILE_IN} From 69560105a1b03e4e5de7bb1539e511704902fef8 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 15:24:07 -0400 Subject: [PATCH 309/391] build, qt: Drop translations.pro hack It is no longer required after switching to Qt top-level build. --- depends/packages/qt.mk | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 0f24da5d7d..239c4b6756 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -192,23 +192,20 @@ endef # # 1. Apply our patches to the extracted source. See each patch for more info. # -# 2. Point to lrelease in qttools/bin/lrelease; otherwise Qt will look for it in -# $(host)/native/bin/lrelease and not find it. +# 2. Create a macOS-Clang-Linux mkspec using our mac-qmake.conf. # -# 3. Create a macOS-Clang-Linux mkspec using our mac-qmake.conf. -# -# 4. After making a copy of the mkspec for the linux-arm-gnueabi host, named +# 3. After making a copy of the mkspec for the linux-arm-gnueabi host, named # bitcoin-linux-g++, replace instances of linux-arm-gnueabi with $(host). This # way we can generically support hosts like riscv64-linux-gnu, which Qt doesn't # ship a mkspec for. See it's usage in config_opts_* above. # -# 5. Put our C, CXX and LD FLAGS into gcc-base.conf. Only used for non-host builds. +# 4. Put our C, CXX and LD FLAGS into gcc-base.conf. Only used for non-host builds. # -# 6. Do similar for the win32-g++ mkspec. +# 5. Do similar for the win32-g++ mkspec. # -# 7. In clang.conf, swap out clang & clang++, for our compiler + flags. See #17466. +# 6. In clang.conf, swap out clang & clang++, for our compiler + flags. See #17466. # -# 8. Adjust a regex in toolchain.prf, to accomodate Guix's usage of +# 7. Adjust a regex in toolchain.prf, to accommodate Guix's usage of # CROSS_LIBRARY_PATH. See #15277. define $(package)_preprocess_cmds cp $($(package)_patch_dir)/qt.pro qt.pro && \ @@ -223,7 +220,6 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_limits_header.patch && \ - sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ From b0a7d4101a60ce9898525fb402efc99d4c3c07f6 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 15:27:12 -0400 Subject: [PATCH 310/391] build, qt: Force bootstrap while building linguist tools Qt lrelease tool depends on the xml module. This change guarantees that it is always available after being bootstrapped. --- depends/packages/qt.mk | 1 + depends/patches/qt/qttools_src.pro | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 239c4b6756..c05ee496d2 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -63,6 +63,7 @@ $(package)_config_opts += -no-sql-sqlite2 $(package)_config_opts += -no-use-gold-linker $(package)_config_opts += -nomake examples $(package)_config_opts += -nomake tests +$(package)_config_opts += -nomake tools $(package)_config_opts += -opensource $(package)_config_opts += -openssl-linked $(package)_config_opts += -optimized-qmake diff --git a/depends/patches/qt/qttools_src.pro b/depends/patches/qt/qttools_src.pro index 487e226e97..6ef71a0942 100644 --- a/depends/patches/qt/qttools_src.pro +++ b/depends/patches/qt/qttools_src.pro @@ -1,2 +1,6 @@ TEMPLATE = subdirs SUBDIRS = linguist + +fb = force_bootstrap +CONFIG += $$fb +cache(CONFIG, add, fb) From e3111933e8b894fe7233bf2bf902a5ada3da3b39 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 15:30:54 -0400 Subject: [PATCH 311/391] build, qt: Fix wrong cross-compiling detection on macOS --- depends/packages/qt.mk | 3 +-- depends/patches/qt/mac-qmake.conf | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index c05ee496d2..d48cf6f059 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -99,14 +99,13 @@ $(package)_config_opts_darwin = -no-dbus $(package)_config_opts_darwin += -no-opengl $(package)_config_opts_darwin += -pch $(package)_config_opts_darwin += -no-feature-corewlan -$(package)_config_opts_darwin += -device-option QMAKE_MACOSX_DEPLOYMENT_TARGET=$(OSX_MIN_VERSION) +$(package)_config_opts_darwin += QMAKE_MACOSX_DEPLOYMENT_TARGET=$(OSX_MIN_VERSION) ifneq ($(build_os),darwin) $(package)_config_opts_darwin += -xplatform macx-clang-linux $(package)_config_opts_darwin += -device-option MAC_SDK_PATH=$(OSX_SDK) $(package)_config_opts_darwin += -device-option MAC_SDK_VERSION=$(OSX_SDK_VERSION) $(package)_config_opts_darwin += -device-option CROSS_COMPILE="$(host)-" -$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) $(package)_config_opts_darwin += -device-option MAC_TARGET=$(host) $(package)_config_opts_darwin += -device-option XCODE_VERSION=$(XCODE_VERSION) endif diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf index 0142667547..190ab7a160 100644 --- a/depends/patches/qt/mac-qmake.conf +++ b/depends/patches/qt/mac-qmake.conf @@ -8,7 +8,6 @@ include(../common/clang-mac.conf) QMAKE_MAC_SDK_PATH=$${MAC_SDK_PATH} QMAKE_XCODE_VERSION = $${XCODE_VERSION} QMAKE_XCODE_DEVELOPER_PATH=/Developer -QMAKE_MACOSX_DEPLOYMENT_TARGET = $${MAC_MIN_VERSION} QMAKE_MAC_SDK=macosx QMAKE_MAC_SDK.macosx.Path = $${MAC_SDK_PATH} QMAKE_MAC_SDK.macosx.platform_name = macosx From f46dd16f4197b50fb7d451c85223661bd868372c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 15:32:52 -0400 Subject: [PATCH 312/391] build, qt: Do not install *.prl files --- depends/packages/qt.mk | 2 +- depends/patches/qt/qt.pro | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index d48cf6f059..625aed290a 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -256,5 +256,5 @@ endef define $(package)_postprocess_cmds rm -rf native/mkspecs/ native/lib/ lib/cmake/ && \ - rm -f lib/lib*.la lib/*.prl plugins/*/*.prl + rm -f lib/lib*.la endef diff --git a/depends/patches/qt/qt.pro b/depends/patches/qt/qt.pro index 6d8b7fdb6a..8f2e900a84 100644 --- a/depends/patches/qt/qt.pro +++ b/depends/patches/qt/qt.pro @@ -3,6 +3,10 @@ cache(, super) !QTDIR_build: cache(CONFIG, add, $$list(QTDIR_build)) +prl = no_install_prl +CONFIG += $$prl +cache(CONFIG, add stash, prl) + TEMPLATE = subdirs SUBDIRS = qtbase qttools qttranslations From e5a9fd05e59c2260868a978a3e02acf6323e6999 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 18:11:12 -0400 Subject: [PATCH 313/391] build: Add ability to build qt in depends with -stdlib=libc++ --- depends/packages/qt.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 625aed290a..e6c1036ac4 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -127,7 +127,11 @@ $(package)_config_opts_linux += -ltcg endif $(package)_config_opts_arm_linux += -platform linux-g++ -xplatform bitcoin-linux-g++ $(package)_config_opts_i686_linux = -xplatform linux-g++-32 +ifneq (,$(findstring -stdlib=libc++,$($(1)_cxx))) +$(package)_config_opts_x86_64_linux = -xplatform linux-clang-libc++ +else $(package)_config_opts_x86_64_linux = -xplatform linux-g++-64 +endif $(package)_config_opts_aarch64_linux = -xplatform linux-aarch64-gnu-g++ $(package)_config_opts_riscv64_linux = -platform linux-g++ -xplatform bitcoin-linux-g++ $(package)_config_opts_s390x_linux += -platform linux-g++ -xplatform linux-g++-64 From 43ac2ad4050c53407f1cd20c240bb5da46bda403 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 30 Jun 2023 18:14:26 -0400 Subject: [PATCH 314/391] build: patch qt to explicitly define previously implicit header include macOS Monterey has refactored some includes such that implicitly defined headers were no longer exposed and that in turns breaks building Qt on macOS 12. Additional Resources: - https://bugreports.qt.io/browse/QTBUG-97855 - https://codereview.qt-project.org/c/qt/qtbase/+/378706 - https://code.qt.io/cgit/qt/qtbase.git/commit/src/plugins/platforms/cocoa?id=dece6f5840463ae2ddf927d65eb1b3680e34a547 --- depends/packages/qt.mk | 2 ++ depends/patches/qt/fix_montery_include.patch | 21 ++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 depends/patches/qt/fix_montery_include.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index e6c1036ac4..85a11909b0 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -14,6 +14,7 @@ $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch d $(package)_patches+= no_sdk_version_check.patch $(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch $(package)_patches+= fix_limits_header.patch +$(package)_patches+= fix_montery_include.patch # Update OSX_QT_TRANSLATIONS when this is updated $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) @@ -224,6 +225,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_limits_header.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_montery_include.patch && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ diff --git a/depends/patches/qt/fix_montery_include.patch b/depends/patches/qt/fix_montery_include.patch new file mode 100644 index 0000000000..38b700addf --- /dev/null +++ b/depends/patches/qt/fix_montery_include.patch @@ -0,0 +1,21 @@ +From dece6f5840463ae2ddf927d65eb1b3680e34a547 +From: Øystein Heskestad +Date: Wed, 27 Oct 2021 13:07:46 +0200 +Subject: [PATCH] Add missing macOS header file that was indirectly included before + +See: https://bugreports.qt.io/browse/QTBUG-97855 + +Upstream Commits: + - Qt 6.2: c884bf138a21dd7320e35cef34d24e22e74d7ce0 + +diff --git a/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h b/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h +index e070ba97..07c75b04 100644 +--- a/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h ++++ b/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h +@@ -40,6 +40,7 @@ + #ifndef QIOSURFACEGRAPHICSBUFFER_H + #define QIOSURFACEGRAPHICSBUFFER_H + ++#include + #include + #include From 72db7d6a648255cf59f5137904c2130cffe2be6f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sat, 1 Jul 2023 08:25:59 -0400 Subject: [PATCH 315/391] build, qt: Ditch `no_sdk_version_check.patch` --- depends/packages/qt.mk | 3 +-- depends/patches/qt/no_sdk_version_check.patch | 20 ------------------- 2 files changed, 1 insertion(+), 22 deletions(-) delete mode 100644 depends/patches/qt/no_sdk_version_check.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 85a11909b0..0880a1e8e8 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -11,7 +11,6 @@ $(package)_linguist_tools = lrelease lupdate lconvert $(package)_patches = qt.pro qttools_src.pro $(package)_patches += fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch -$(package)_patches+= no_sdk_version_check.patch $(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch $(package)_patches+= fix_limits_header.patch $(package)_patches+= fix_montery_include.patch @@ -222,7 +221,6 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \ patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch && \ - patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_limits_header.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_montery_include.patch && \ @@ -245,6 +243,7 @@ define $(package)_preprocess_cmds endef define $(package)_config_cmds + export QT_MAC_SDK_NO_VERSION_CHECK=1 && \ cd qtbase && \ ./configure -top-level $($(package)_config_opts) endef diff --git a/depends/patches/qt/no_sdk_version_check.patch b/depends/patches/qt/no_sdk_version_check.patch deleted file mode 100644 index b16635b572..0000000000 --- a/depends/patches/qt/no_sdk_version_check.patch +++ /dev/null @@ -1,20 +0,0 @@ -commit f5eb142cd04be2bc4ca610ed3b5b7e8ce3520ee3 -Author: fanquake -Date: Tue Jan 5 16:08:49 2021 +0800 - - Don't invoke macOS SDK version checking - - This tries to use xcrun which is not available when cross-compiling. - -diff --git a/qtbase/mkspecs/features/mac/default_post.prf b/qtbase/mkspecs/features/mac/default_post.prf -index 92a9112bca6..447e186eb26 100644 ---- a/qtbase/mkspecs/features/mac/default_post.prf -+++ b/qtbase/mkspecs/features/mac/default_post.prf -@@ -8,7 +8,6 @@ contains(TEMPLATE, .*app) { - !macx-xcode:if(isEmpty(BUILDS)|build_pass) { - # Detect changes to the platform SDK - QMAKE_EXTRA_VARIABLES += QMAKE_MAC_SDK QMAKE_MAC_SDK_VERSION QMAKE_XCODE_DEVELOPER_PATH -- QMAKE_EXTRA_INCLUDES += $$shell_quote($$PWD/sdk.mk) - } - - # Detect incompatible SDK versions From d6dd0c6690f774e8cce9d103dbe93e4e90d7bf18 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 11:30:06 -0400 Subject: [PATCH 316/391] build, qt: Refactor internal _BITCOIN_QT_CHECK_STATIC_PLUGINS macro This change puts Q_IMPORT_PLUGIN(...) boilerplate into the macro, which now accepts only one plugin to check, and it is renamed (plural -> singular). --- build-aux/m4/bitcoin_qt.m4 | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 7e5b678f74..decf09b2c1 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -111,9 +111,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ dnl For Qt5, we can check a header to find out whether Qt is build dnl statically. When Qt is built statically, some plugins must be linked into dnl the final binary as well. - dnl With Qt5, languages moved into core and the WindowsIntegration plugin was - dnl added. - dnl _BITCOIN_QT_CHECK_STATIC_PLUGINS does a quick link-check and appends the + dnl _BITCOIN_QT_CHECK_STATIC_PLUGIN does a quick link-check and appends the dnl results to QT_LIBS. BITCOIN_QT_CHECK([ TEMP_CPPFLAGS=$CPPFLAGS @@ -125,27 +123,27 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ _BITCOIN_QT_FIND_STATIC_PLUGINS AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) if test "x$TARGET_OS" != xandroid; then - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin)],[-lqminimal]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMinimalIntegrationPlugin], [-lqminimal]) AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) fi if test "x$TARGET_OS" = xwindows; then dnl Linking against wtsapi32 is required. See #17749 and dnl https://bugreports.qt.io/browse/QTBUG-27097. AX_CHECK_LINK_FLAG([-lwtsapi32], [QT_LIBS="$QT_LIBS -lwtsapi32"], [AC_MSG_ERROR([could not link against -lwtsapi32])]) - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QWindowsIntegrationPlugin], [-lqwindows]) AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows]) elif test "x$TARGET_OS" = xlinux; then dnl workaround for https://bugreports.qt.io/browse/QTBUG-74874 AX_CHECK_LINK_FLAG([-lxcb-shm], [QT_LIBS="-lxcb-shm $QT_LIBS"], [AC_MSG_ERROR([could not link against -lxcb-shm])])sssssss - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)],[-lqxcb -lxcb-static]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QXcbIntegrationPlugin], [-lqxcb -lxcb-static]) AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb]) elif test "x$TARGET_OS" = xdarwin; then AX_CHECK_LINK_FLAG([[-framework Carbon]],[QT_LIBS="$QT_LIBS -framework Carbon"],[AC_MSG_ERROR(could not link against Carbon framework)]) AX_CHECK_LINK_FLAG([[-framework IOSurface]],[QT_LIBS="$QT_LIBS -framework IOSurface"],[AC_MSG_ERROR(could not link against IOSurface framework)]) AX_CHECK_LINK_FLAG([[-framework Metal]],[QT_LIBS="$QT_LIBS -framework Metal"],[AC_MSG_ERROR(could not link against Metal framework)]) AX_CHECK_LINK_FLAG([[-framework QuartzCore]],[QT_LIBS="$QT_LIBS -framework QuartzCore"],[AC_MSG_ERROR(could not link against QuartzCore framework)]) - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)],[-lqcocoa]) - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMacStylePlugin)],[-lqmacstyle]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QCocoaIntegrationPlugin], [-lqcocoa]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMacStylePlugin], [-lqmacstyle]) AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa]) elif test "x$TARGET_OS" = xandroid; then QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lqtforandroid -ljnigraphics -landroid -lqtfreetype -lQt5EglSupport $QT_LIBS" @@ -296,22 +294,22 @@ AC_DEFUN([_BITCOIN_QT_IS_STATIC],[ ]) ]) -dnl Internal. Check if the link-requirements for static plugins are met. +dnl Internal. Check if the link-requirements for a static plugin are met. +dnl +dnl _BITCOIN_QT_CHECK_STATIC_PLUGIN(PLUGIN, LIBRARIES) +dnl -------------------------------------------------- +dnl dnl Requires: INCLUDES and LIBS must be populated as necessary. -dnl Inputs: $1: A series of Q_IMPORT_PLUGIN(). +dnl Inputs: $1: A static plugin name. dnl Inputs: $2: The libraries that resolve $1. dnl Output: QT_LIBS is prepended or configure exits. -AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[ - AC_MSG_CHECKING(for static Qt plugins: $2) +AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGIN], [ + AC_MSG_CHECKING([for $1 ($2)]) CHECK_STATIC_PLUGINS_TEMP_LIBS="$LIBS" LIBS="$2${qt_lib_suffix} $QT_LIBS $LIBS" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #define QT_STATICPLUGIN - #include - $1]], - [[return 0;]])], - [AC_MSG_RESULT(yes); QT_LIBS="$2${qt_lib_suffix} $QT_LIBS"], - [AC_MSG_RESULT(no); BITCOIN_QT_FAIL(Could not resolve: $2)]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include Q_IMPORT_PLUGIN($1)]])], + [AC_MSG_RESULT([yes]); QT_LIBS="$2${qt_lib_suffix} $QT_LIBS"], + [AC_MSG_RESULT([no]); BITCOIN_QT_FAIL([$1 not found.])]) LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS" ]) From 45d950fcfe23a153f0594002184be66e2c44b705 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 11:42:09 -0400 Subject: [PATCH 317/391] build, refactor: Rename internal _BITCOIN_QT_FIND_STATIC_PLUGINS macro New _BITCOIN_QT_CHECK_STATIC_LIBS name describes the macro functionality more precisely. --- build-aux/m4/bitcoin_qt.m4 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index decf09b2c1..a9a3783ad1 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -120,7 +120,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ CXXFLAGS="$PIC_FLAGS $CXXFLAGS" _BITCOIN_QT_IS_STATIC if test "x$bitcoin_cv_static_qt" = xyes; then - _BITCOIN_QT_FIND_STATIC_PLUGINS + _BITCOIN_QT_CHECK_STATIC_LIBS AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) if test "x$TARGET_OS" != xandroid; then _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMinimalIntegrationPlugin], [-lqminimal]) @@ -313,10 +313,14 @@ AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGIN], [ LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS" ]) -dnl Internal. Find paths necessary for linking qt static plugins -dnl Inputs: qt_plugin_path. optional. +dnl Internal. Check Qt static libs with PKG_CHECK_MODULES. +dnl +dnl _BITCOIN_QT_CHECK_STATIC_LIBS +dnl ----------------------------- +dnl +dnl Inputs: no inputs. dnl Outputs: QT_LIBS is appended -AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ +AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ if test "x$qt_plugin_path" != x; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms -L$qt_plugin_path/styles" if test -d "$qt_plugin_path/accessible"; then From a0de98a40637cabdd8c03349c813314edd66cfee Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 11:47:38 -0400 Subject: [PATCH 318/391] build, qt: Make Qt static libs check regardless of plugindir Qt static libs reside in libdir. --- build-aux/m4/bitcoin_qt.m4 | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index a9a3783ad1..1510dc40a8 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -121,6 +121,17 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ _BITCOIN_QT_IS_STATIC if test "x$bitcoin_cv_static_qt" = xyes; then _BITCOIN_QT_CHECK_STATIC_LIBS + + if test "x$qt_plugin_path" != x; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms -L$qt_plugin_path/styles" + if test -d "$qt_plugin_path/accessible"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" + fi + if test -d "$qt_plugin_path/platforms/android"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" + fi + fi + AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) if test "x$TARGET_OS" != xandroid; then _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMinimalIntegrationPlugin], [-lqminimal]) @@ -319,16 +330,8 @@ dnl _BITCOIN_QT_CHECK_STATIC_LIBS dnl ----------------------------- dnl dnl Inputs: no inputs. -dnl Outputs: QT_LIBS is appended +dnl Outputs: QT_LIBS is prepended. AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ - if test "x$qt_plugin_path" != x; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms -L$qt_plugin_path/styles" - if test -d "$qt_plugin_path/accessible"; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" - fi - if test -d "$qt_plugin_path/platforms/android"; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" - fi PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"]) PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"]) PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"]) @@ -343,7 +346,6 @@ AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ elif test "x$TARGET_OS" = xwindows; then PKG_CHECK_MODULES([QTWINDOWSUIAUTOMATION], [Qt5WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="-lQt5WindowsUIAutomationSupport${qt_lib_suffix} $QT_LIBS"]) fi - fi ]) dnl Internal. Find Qt libraries using pkg-config. From af0906c740107fd72182815617db571fa487b58d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 11:50:24 -0400 Subject: [PATCH 319/391] build, refactor: Fix indentation --- build-aux/m4/bitcoin_qt.m4 | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 1510dc40a8..9afdb7405e 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -83,14 +83,14 @@ AC_DEFUN([BITCOIN_QT_INIT],[ [use_dbus=$withval], [use_dbus=auto]) - dnl Android doesn't support D-Bus and certainly doesn't use it for notifications - case $host in - *android*) - if test "x$use_dbus" != xyes; then - use_dbus=no - fi - ;; - esac + dnl Android doesn't support D-Bus and certainly doesn't use it for notifications + case $host in + *android*) + if test "x$use_dbus" != xyes; then + use_dbus=no + fi + ;; + esac AC_SUBST(QT_TRANSLATION_DIR,$qt_translation_path) ]) @@ -332,20 +332,20 @@ dnl dnl Inputs: no inputs. dnl Outputs: QT_LIBS is prepended. AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ - PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="-lQt5AccessibilitySupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTFB], [Qt5FbSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FbSupport${qt_lib_suffix} $QT_LIBS"]) - if test "x$TARGET_OS" = xlinux; then - PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) - elif test "x$TARGET_OS" = xdarwin; then - PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ClipboardSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport${qt_lib_suffix}], [QT_LIBS="-lQt5GraphicsSupport${qt_lib_suffix} $QT_LIBS"]) - elif test "x$TARGET_OS" = xwindows; then - PKG_CHECK_MODULES([QTWINDOWSUIAUTOMATION], [Qt5WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="-lQt5WindowsUIAutomationSupport${qt_lib_suffix} $QT_LIBS"]) - fi + PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="-lQt5AccessibilitySupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTFB], [Qt5FbSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FbSupport${qt_lib_suffix} $QT_LIBS"]) + if test "x$TARGET_OS" = xlinux; then + PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xdarwin; then + PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ClipboardSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport${qt_lib_suffix}], [QT_LIBS="-lQt5GraphicsSupport${qt_lib_suffix} $QT_LIBS"]) + elif test "x$TARGET_OS" = xwindows; then + PKG_CHECK_MODULES([QTWINDOWSUIAUTOMATION], [Qt5WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="-lQt5WindowsUIAutomationSupport${qt_lib_suffix} $QT_LIBS"]) + fi ]) dnl Internal. Find Qt libraries using pkg-config. From 2f6669d20e991eb0b66d0d47c5cfb711170577fc Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 12:46:19 -0400 Subject: [PATCH 320/391] build, qt: Fix regression introduced in previous commit Due to the ill-formed code _BITCOIN_QT_CHECK_STATIC_PLUGIN never fails. --- build-aux/m4/bitcoin_qt.m4 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 9afdb7405e..3f6652ec2a 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -318,7 +318,10 @@ AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGIN], [ AC_MSG_CHECKING([for $1 ($2)]) CHECK_STATIC_PLUGINS_TEMP_LIBS="$LIBS" LIBS="$2${qt_lib_suffix} $QT_LIBS $LIBS" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include Q_IMPORT_PLUGIN($1)]])], + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + Q_IMPORT_PLUGIN($1) + ]])], [AC_MSG_RESULT([yes]); QT_LIBS="$2${qt_lib_suffix} $QT_LIBS"], [AC_MSG_RESULT([no]); BITCOIN_QT_FAIL([$1 not found.])]) LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS" From b2a2b96faae48198d4fc3b140d1096c9b7b2ae47 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 19:08:06 -0400 Subject: [PATCH 321/391] build, qt: Always test plugins/subdir before adding to search paths The existence of each subdir is not guaranteed for all platforms. --- build-aux/m4/bitcoin_qt.m4 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 3f6652ec2a..9a08cd9051 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -123,7 +123,12 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ _BITCOIN_QT_CHECK_STATIC_LIBS if test "x$qt_plugin_path" != x; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms -L$qt_plugin_path/styles" + if test -d "$qt_plugin_path/platforms"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms" + fi + if test -d "$qt_plugin_path/styles"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/styles" + fi if test -d "$qt_plugin_path/accessible"; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" fi From 691f238daf20a22bda9762165ee3cabf13605912 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 19:08:39 -0400 Subject: [PATCH 322/391] build, qt: Drop redundant -lxcb-static flag The removed flag has been already linked with Qt5XcbQpa. --- build-aux/m4/bitcoin_qt.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 9a08cd9051..50a173763a 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -151,7 +151,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ elif test "x$TARGET_OS" = xlinux; then dnl workaround for https://bugreports.qt.io/browse/QTBUG-74874 AX_CHECK_LINK_FLAG([-lxcb-shm], [QT_LIBS="-lxcb-shm $QT_LIBS"], [AC_MSG_ERROR([could not link against -lxcb-shm])])sssssss - _BITCOIN_QT_CHECK_STATIC_PLUGIN([QXcbIntegrationPlugin], [-lqxcb -lxcb-static]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QXcbIntegrationPlugin], [-lqxcb]) AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb]) elif test "x$TARGET_OS" = xdarwin; then AX_CHECK_LINK_FLAG([[-framework Carbon]],[QT_LIBS="$QT_LIBS -framework Carbon"],[AC_MSG_ERROR(could not link against Carbon framework)]) From 9fcdf26ef65e6f7cfcf1c98a67f6d41189009041 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 19:09:27 -0400 Subject: [PATCH 323/391] build: Cleanup libxkbcommon_postprocess_cmds There is no "share" directory in the staging one. --- depends/packages/libxkbcommon.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/libxkbcommon.mk b/depends/packages/libxkbcommon.mk index cdd5af194b..8c6c56545f 100644 --- a/depends/packages/libxkbcommon.mk +++ b/depends/packages/libxkbcommon.mk @@ -27,6 +27,6 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf share/man share/doc lib/*.la + rm lib/*.la endef From 187c4f0886a818d3fc2354ea83f9beca2f681d3d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 19:31:56 -0400 Subject: [PATCH 324/391] build: reorder libs in _BITCOIN_QT_CHECK_STATIC_LIBS (move-only) --- build-aux/m4/bitcoin_qt.m4 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 50a173763a..b779d70c81 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -340,12 +340,12 @@ dnl dnl Inputs: no inputs. dnl Outputs: QT_LIBS is prepended. AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ - PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"]) PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="-lQt5AccessibilitySupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"]) PKG_CHECK_MODULES([QTFB], [Qt5FbSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FbSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"]) if test "x$TARGET_OS" = xlinux; then PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) elif test "x$TARGET_OS" = xdarwin; then From ce0c0464d60178b49f6781c73bfb55c6d9ab8dc5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 19:32:52 -0400 Subject: [PATCH 325/391] scripted-diff: replace Qt5 with ${qt_lib_prefix} in _BITCOIN_QT_CHECK_STATIC_LIBS -BEGIN VERIFY SCRIPT- sed -i -e "s/\[Qt5/\[\$\{qt_lib_prefix\}/g" build-aux/m4/bitcoin_qt.m4 sed -i -e "s/Qt5Core/\$\{qt_lib_prefix\}Core/g" build-aux/m4/bitcoin_qt.m4 -END VERIFY SCRIPT- --- build-aux/m4/bitcoin_qt.m4 | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index b779d70c81..db978bdc96 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -171,7 +171,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ ]) if test "x$qt_bin_path" = x; then - qt_bin_path="`$PKG_CONFIG --variable=host_bins Qt5Core 2>/dev/null`" + qt_bin_path="`$PKG_CONFIG --variable=host_bins ${qt_lib_prefix}Core 2>/dev/null`" fi if test "x$use_hardening" != xno; then @@ -340,19 +340,19 @@ dnl dnl Inputs: no inputs. dnl Outputs: QT_LIBS is prepended. AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ - PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="-lQt5AccessibilitySupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTFB], [Qt5FbSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FbSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTACCESSIBILITY], [${qt_lib_prefix}AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="-lQt5AccessibilitySupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [${qt_lib_prefix}DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTEVENTDISPATCHER], [${qt_lib_prefix}EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTFB], [${qt_lib_prefix}FbSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FbSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTFONTDATABASE], [${qt_lib_prefix}FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTTHEME], [${qt_lib_prefix}ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"]) if test "x$TARGET_OS" = xlinux; then - PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QTXCBQPA], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) elif test "x$TARGET_OS" = xdarwin; then - PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ClipboardSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport${qt_lib_suffix}], [QT_LIBS="-lQt5GraphicsSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTCLIPBOARD], [${qt_lib_prefix}ClipboardSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ClipboardSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTGRAPHICS], [${qt_lib_prefix}GraphicsSupport${qt_lib_suffix}], [QT_LIBS="-lQt5GraphicsSupport${qt_lib_suffix} $QT_LIBS"]) elif test "x$TARGET_OS" = xwindows; then - PKG_CHECK_MODULES([QTWINDOWSUIAUTOMATION], [Qt5WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="-lQt5WindowsUIAutomationSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QTWINDOWSUIAUTOMATION], [${qt_lib_prefix}WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="-lQt5WindowsUIAutomationSupport${qt_lib_suffix} $QT_LIBS"]) fi ]) From b71ca40062e95995766fa59b07387e64f9ca80cb Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 19:41:40 -0400 Subject: [PATCH 326/391] build: use QT_*_LIBS rather than passing lib names --- build-aux/m4/bitcoin_qt.m4 | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index db978bdc96..4954d15b7b 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -162,7 +162,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMacStylePlugin], [-lqmacstyle]) AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa]) elif test "x$TARGET_OS" = xandroid; then - QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lqtforandroid -ljnigraphics -landroid -lqtfreetype -lQt5EglSupport $QT_LIBS" + QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lqtforandroid -ljnigraphics -landroid -lqtfreetype $QT_LIBS" AC_DEFINE(QT_QPA_PLATFORM_ANDROID, 1, [Define this symbol if the qt platform is android]) fi fi @@ -340,19 +340,21 @@ dnl dnl Inputs: no inputs. dnl Outputs: QT_LIBS is prepended. AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ - PKG_CHECK_MODULES([QTACCESSIBILITY], [${qt_lib_prefix}AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="-lQt5AccessibilitySupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [${qt_lib_prefix}DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTEVENTDISPATCHER], [${qt_lib_prefix}EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTFB], [${qt_lib_prefix}FbSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FbSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTFONTDATABASE], [${qt_lib_prefix}FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTTHEME], [${qt_lib_prefix}ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QT_ACCESSIBILITY], [${qt_lib_prefix}AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="$QT_ACCESSIBILITY_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_DEVICEDISCOVERY], [${qt_lib_prefix}DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="$QT_DEVICEDISCOVERY_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_EVENTDISPATCHER], [${qt_lib_prefix}EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="$QT_EVENTDISPATCHER_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_FB], [${qt_lib_prefix}FbSupport${qt_lib_suffix}], [QT_LIBS="$QT_FB_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_FONTDATABASE], [${qt_lib_prefix}FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="$QT_FONTDATABASE_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_THEME], [${qt_lib_prefix}ThemeSupport${qt_lib_suffix}], [QT_LIBS="$QT_THEME_LIBS $QT_LIBS"]) if test "x$TARGET_OS" = xlinux; then - PKG_CHECK_MODULES([QTXCBQPA], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_XCBQPA], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QT_XCBQPA_LIBS $QT_LIBS"]) elif test "x$TARGET_OS" = xdarwin; then - PKG_CHECK_MODULES([QTCLIPBOARD], [${qt_lib_prefix}ClipboardSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ClipboardSupport${qt_lib_suffix} $QT_LIBS"]) - PKG_CHECK_MODULES([QTGRAPHICS], [${qt_lib_prefix}GraphicsSupport${qt_lib_suffix}], [QT_LIBS="-lQt5GraphicsSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QT_CLIPBOARD], [${qt_lib_prefix}ClipboardSupport${qt_lib_suffix}], [QT_LIBS="$QT_CLIPBOARD_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_GRAPHICS], [${qt_lib_prefix}GraphicsSupport${qt_lib_suffix}], [QT_LIBS="$QT_GRAPHICS_LIBS $QT_LIBS"]) elif test "x$TARGET_OS" = xwindows; then - PKG_CHECK_MODULES([QTWINDOWSUIAUTOMATION], [${qt_lib_prefix}WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="-lQt5WindowsUIAutomationSupport${qt_lib_suffix} $QT_LIBS"]) + PKG_CHECK_MODULES([QT_WINDOWSUIAUTOMATION], [${qt_lib_prefix}WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="$QT_WINDOWSUIAUTOMATION_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xandroid; then + PKG_CHECK_MODULES([QT_EGL], [${qt_lib_prefix}EglSupport], [QT_LIBS="$QT_EGL_LIBS $QT_LIBS"]) fi ]) From be429a0faecc3d6420e8a99b509a9205bebba88d Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 19:47:12 -0400 Subject: [PATCH 327/391] build: set QT_*_CFLAGS & QT_*_LIBS in PKG_CHECK_MODULES() calls --- build-aux/m4/bitcoin_qt.m4 | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 4954d15b7b..335b0129c7 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -363,27 +363,25 @@ dnl Outputs: All necessary QT_* variables are set. dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[ BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [], + PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_CORE_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_CORE_LIBS $QT_LIBS"], [BITCOIN_QT_FAIL([${qt_lib_prefix}Core${qt_lib_suffix} $qt_version not found])]) ]) BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version], [], + PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_GUI_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_GUI_LIBS $QT_LIBS"], [BITCOIN_QT_FAIL([${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version not found])]) ]) BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version], [], + PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_WIDGETS_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_WIDGETS_LIBS $QT_LIBS"], [BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version not found])]) ]) BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network${qt_lib_suffix} $qt_version], [], + PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_NETWORK_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_NETWORK_LIBS $QT_LIBS"], [BITCOIN_QT_FAIL([${qt_lib_prefix}Network${qt_lib_suffix} $qt_version not found])]) ]) BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_CONCURRENT], [${qt_lib_prefix}Concurrent${qt_lib_suffix} $qt_version], [], + PKG_CHECK_MODULES([QT_CONCURRENT], [${qt_lib_prefix}Concurrent${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_CONCURRENT_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_CONCURRENT_LIBS $QT_LIBS"], [BITCOIN_QT_FAIL([${qt_lib_prefix}Concurrent${qt_lib_suffix} $qt_version not found])]) ]) - QT_INCLUDES="$QT_CORE_CFLAGS $QT_GUI_CFLAGS $QT_WIDGETS_CFLAGS $QT_NETWORK_CFLAGS $QT_CONCURRENT_CFLAGS" - QT_LIBS="$QT_CORE_LIBS $QT_GUI_LIBS $QT_WIDGETS_LIBS $QT_NETWORK_LIBS $QT_CONCURRENT_LIBS" BITCOIN_QT_CHECK([ PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test${qt_lib_suffix} $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) From a7cc7a85dbad4c8a5232c440fe6c5493b5a52120 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 19:48:57 -0400 Subject: [PATCH 328/391] build: misc doc changes in bitcoin_qt.m4 --- build-aux/m4/bitcoin_qt.m4 | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 335b0129c7..a409a3f2e3 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -107,12 +107,10 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ qt_lib_prefix="Qt5" BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS]) - dnl This is ugly and complicated. Yuck. Works as follows: - dnl For Qt5, we can check a header to find out whether Qt is build - dnl statically. When Qt is built statically, some plugins must be linked into - dnl the final binary as well. - dnl _BITCOIN_QT_CHECK_STATIC_PLUGIN does a quick link-check and appends the - dnl results to QT_LIBS. + dnl We check a header to find out whether Qt is built statically. + dnl When Qt is built statically, some plugins must be linked into + dnl the final binary as well. _BITCOIN_QT_CHECK_STATIC_PLUGIN does + dnl a quick link-check and appends the results to QT_LIBS. BITCOIN_QT_CHECK([ TEMP_CPPFLAGS=$CPPFLAGS TEMP_CXXFLAGS=$CXXFLAGS @@ -284,12 +282,13 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ AC_SUBST(MOC_DEFS) ]) -dnl All macros below are internal and should _not_ be used from the main -dnl configure.ac. -dnl ---- +dnl All macros below are internal and should _not_ be used from configure.ac. -dnl Internal. Check if the linked version of Qt was built as static libs. -dnl Requires: Qt5. +dnl Internal. Check if the linked version of Qt was built statically. +dnl +dnl _BITCOIN_QT_IS_STATIC +dnl --------------------- +dnl dnl Requires: INCLUDES and LIBS must be populated as necessary. dnl Output: bitcoin_cv_static_qt=yes|no AC_DEFUN([_BITCOIN_QT_IS_STATIC],[ @@ -337,7 +336,6 @@ dnl dnl _BITCOIN_QT_CHECK_STATIC_LIBS dnl ----------------------------- dnl -dnl Inputs: no inputs. dnl Outputs: QT_LIBS is prepended. AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ PKG_CHECK_MODULES([QT_ACCESSIBILITY], [${qt_lib_prefix}AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="$QT_ACCESSIBILITY_LIBS $QT_LIBS"]) @@ -359,6 +357,10 @@ AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ ]) dnl Internal. Find Qt libraries using pkg-config. +dnl +dnl _BITCOIN_QT_FIND_LIBS +dnl --------------------- +dnl dnl Outputs: All necessary QT_* variables are set. dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[ From 857b5de6a7653ff47d54578071e69eed60b85730 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 19:50:03 -0400 Subject: [PATCH 329/391] build: additional PKG_CHECK_MODULES calls in bitcoin_qt.m4 Add checks for the edid, input and service support modules. --- build-aux/m4/bitcoin_qt.m4 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index a409a3f2e3..ce4f394250 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -340,15 +340,19 @@ dnl Outputs: QT_LIBS is prepended. AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ PKG_CHECK_MODULES([QT_ACCESSIBILITY], [${qt_lib_prefix}AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="$QT_ACCESSIBILITY_LIBS $QT_LIBS"]) PKG_CHECK_MODULES([QT_DEVICEDISCOVERY], [${qt_lib_prefix}DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="$QT_DEVICEDISCOVERY_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_EDID], [${qt_lib_prefix}EdidSupport${qt_lib_suffix}], [QT_LIBS="$QT_EDID_LIBS $QT_LIBS"]) PKG_CHECK_MODULES([QT_EVENTDISPATCHER], [${qt_lib_prefix}EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="$QT_EVENTDISPATCHER_LIBS $QT_LIBS"]) PKG_CHECK_MODULES([QT_FB], [${qt_lib_prefix}FbSupport${qt_lib_suffix}], [QT_LIBS="$QT_FB_LIBS $QT_LIBS"]) PKG_CHECK_MODULES([QT_FONTDATABASE], [${qt_lib_prefix}FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="$QT_FONTDATABASE_LIBS $QT_LIBS"]) PKG_CHECK_MODULES([QT_THEME], [${qt_lib_prefix}ThemeSupport${qt_lib_suffix}], [QT_LIBS="$QT_THEME_LIBS $QT_LIBS"]) if test "x$TARGET_OS" = xlinux; then + PKG_CHECK_MODULES([QT_INPUT], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QT_INPUT_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"]) PKG_CHECK_MODULES([QT_XCBQPA], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QT_XCBQPA_LIBS $QT_LIBS"]) elif test "x$TARGET_OS" = xdarwin; then PKG_CHECK_MODULES([QT_CLIPBOARD], [${qt_lib_prefix}ClipboardSupport${qt_lib_suffix}], [QT_LIBS="$QT_CLIPBOARD_LIBS $QT_LIBS"]) PKG_CHECK_MODULES([QT_GRAPHICS], [${qt_lib_prefix}GraphicsSupport${qt_lib_suffix}], [QT_LIBS="$QT_GRAPHICS_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport${qt_lib_suffix}], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"]) elif test "x$TARGET_OS" = xwindows; then PKG_CHECK_MODULES([QT_WINDOWSUIAUTOMATION], [${qt_lib_prefix}WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="$QT_WINDOWSUIAUTOMATION_LIBS $QT_LIBS"]) elif test "x$TARGET_OS" = xandroid; then From 2b6a7db8d091a815e56e41c1f187634e116ed522 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 23:51:10 -0400 Subject: [PATCH 330/391] build, qt: Make QWindowsVistaStylePlugin available again (regression) In Qt 5.12.x style plugins are separated. --- build-aux/m4/bitcoin_qt.m4 | 1 + src/qt/prcycoin.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index ce4f394250..8a40a8b1e6 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -145,6 +145,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ dnl https://bugreports.qt.io/browse/QTBUG-27097. AX_CHECK_LINK_FLAG([-lwtsapi32], [QT_LIBS="$QT_LIBS -lwtsapi32"], [AC_MSG_ERROR([could not link against -lwtsapi32])]) _BITCOIN_QT_CHECK_STATIC_PLUGIN([QWindowsIntegrationPlugin], [-lqwindows]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QWindowsVistaStylePlugin], [-lqwindowsvistastyle]) AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows]) elif test "x$TARGET_OS" = xlinux; then dnl workaround for https://bugreports.qt.io/browse/QTBUG-74874 diff --git a/src/qt/prcycoin.cpp b/src/qt/prcycoin.cpp index 6bead4d775..0a28709393 100644 --- a/src/qt/prcycoin.cpp +++ b/src/qt/prcycoin.cpp @@ -71,6 +71,7 @@ Q_IMPORT_PLUGIN(QXcbIntegrationPlugin); #elif defined(QT_QPA_PLATFORM_WINDOWS) Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); +Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin); #elif defined(QT_QPA_PLATFORM_COCOA) Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin); Q_IMPORT_PLUGIN(QMacStylePlugin); From 2434307367182b712dc32d120f63ee28f9623538 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 23:52:46 -0400 Subject: [PATCH 331/391] build, qt: Fix libraries linking order for Linux hosts This change fixes configuring with Qt on Alpine Linux. --- build-aux/m4/bitcoin_qt.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 8a40a8b1e6..5fbb47ed27 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -149,7 +149,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows]) elif test "x$TARGET_OS" = xlinux; then dnl workaround for https://bugreports.qt.io/browse/QTBUG-74874 - AX_CHECK_LINK_FLAG([-lxcb-shm], [QT_LIBS="-lxcb-shm $QT_LIBS"], [AC_MSG_ERROR([could not link against -lxcb-shm])])sssssss + AX_CHECK_LINK_FLAG([-lxcb-shm], [QT_LIBS="$QT_LIBS -lxcb-shm"], [AC_MSG_ERROR([could not link against -lxcb-shm])]) _BITCOIN_QT_CHECK_STATIC_PLUGIN([QXcbIntegrationPlugin], [-lqxcb]) AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb]) elif test "x$TARGET_OS" = xdarwin; then From 37ba37fe1060a857ed94989402438175b011006b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 7 Jul 2023 23:53:38 -0400 Subject: [PATCH 332/391] build, qt: Fix typo in QtInputSupport check --- build-aux/m4/bitcoin_qt.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 5fbb47ed27..5cc6c78552 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -347,7 +347,7 @@ AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ PKG_CHECK_MODULES([QT_FONTDATABASE], [${qt_lib_prefix}FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="$QT_FONTDATABASE_LIBS $QT_LIBS"]) PKG_CHECK_MODULES([QT_THEME], [${qt_lib_prefix}ThemeSupport${qt_lib_suffix}], [QT_LIBS="$QT_THEME_LIBS $QT_LIBS"]) if test "x$TARGET_OS" = xlinux; then - PKG_CHECK_MODULES([QT_INPUT], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QT_INPUT_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_INPUT], [${qt_lib_prefix}InputSupport], [QT_LIBS="$QT_INPUT_LIBS $QT_LIBS"]) PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"]) PKG_CHECK_MODULES([QT_XCBQPA], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QT_XCBQPA_LIBS $QT_LIBS"]) elif test "x$TARGET_OS" = xdarwin; then From 30e331aa14fa99eca4a8cdf3d7b897cec4440320 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sat, 8 Jul 2023 15:55:17 -0400 Subject: [PATCH 333/391] build: remove build stubs for external leveldb Presumably these stubs indicate to packagers that external leveldb is meant to be supported in some way. It is not. Remove the stubs to avoid sending any mixed messages. --- configure.ac | 8 -------- src/Makefile.am | 2 -- src/Makefile.leveldb.include | 5 +++-- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 8846e6cd08..2bef9cb555 100644 --- a/configure.ac +++ b/configure.ac @@ -895,14 +895,6 @@ if test x$use_reduce_exports = xyes; then [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) fi -LEVELDB_CPPFLAGS= -LIBLEVELDB= -LIBMEMENV= -AM_CONDITIONAL([EMBEDDED_LEVELDB],[true]) -AC_SUBST(LEVELDB_CPPFLAGS) -AC_SUBST(LIBLEVELDB) -AC_SUBST(LIBMEMENV) - if test x$enable_wallet != xno; then dnl Check for libdb_cxx only if wallet enabled BITCOIN_FIND_BDB48 diff --git a/src/Makefile.am b/src/Makefile.am index 115248e31e..9fb71d316a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -589,10 +589,8 @@ if HARDEN $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS) endif -if EMBEDDED_LEVELDB include Makefile.crc32c.include include Makefile.leveldb.include -endif if ENABLE_TESTS include Makefile.test.include diff --git a/src/Makefile.leveldb.include b/src/Makefile.leveldb.include index 04b53471e4..abbcb81374 100644 --- a/src/Makefile.leveldb.include +++ b/src/Makefile.leveldb.include @@ -8,9 +8,10 @@ LIBMEMENV_INT = leveldb/libmemenv.a EXTRA_LIBRARIES += $(LIBLEVELDB_INT) EXTRA_LIBRARIES += $(LIBMEMENV_INT) -LIBLEVELDB += $(LIBLEVELDB_INT) $(LIBCRC32C) -LIBMEMENV += $(LIBMEMENV_INT) +LIBLEVELDB = $(LIBLEVELDB_INT) $(LIBCRC32C) +LIBMEMENV = $(LIBMEMENV_INT) +LEVELDB_CPPFLAGS = LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/helpers/memenv From d19b587fedca5351cf55569a139186f53142d425 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 2 Jul 2023 11:06:36 -0400 Subject: [PATCH 334/391] Qt: add Android packaging support Introduce an android directory under qt and allow one to package prcycoin-qt for Android by running make apk. Add prcycoin-qt Android build instructions. --- configure.ac | 15 +++++ doc/README.md | 1 + doc/build-android.md | 12 ++++ src/Makefile.qt.include | 14 +++++ src/qt/android/AndroidManifest.xml | 38 +++++++++++++ src/qt/android/build.gradle | 52 ++++++++++++++++++ src/qt/android/gradle.properties | 4 ++ src/qt/android/res/drawable-hdpi/prcycoin.png | Bin 0 -> 9807 bytes src/qt/android/res/drawable-ldpi/prcycoin.png | Bin 0 -> 3083 bytes src/qt/android/res/drawable-mdpi/prcycoin.png | Bin 0 -> 4962 bytes .../android/res/drawable-xhdpi/prcycoin.png | Bin 0 -> 15978 bytes .../android/res/drawable-xxhdpi/prcycoin.png | Bin 0 -> 31802 bytes .../android/res/drawable-xxxhdpi/prcycoin.png | Bin 0 -> 52052 bytes .../prcycoincore/qt/PrcycoinQtActivity.java | 29 ++++++++++ src/qt/prcycoin.cpp | 6 ++ 15 files changed, 171 insertions(+) create mode 100644 doc/build-android.md create mode 100644 src/qt/android/AndroidManifest.xml create mode 100644 src/qt/android/build.gradle create mode 100644 src/qt/android/gradle.properties create mode 100644 src/qt/android/res/drawable-hdpi/prcycoin.png create mode 100644 src/qt/android/res/drawable-ldpi/prcycoin.png create mode 100644 src/qt/android/res/drawable-mdpi/prcycoin.png create mode 100644 src/qt/android/res/drawable-xhdpi/prcycoin.png create mode 100644 src/qt/android/res/drawable-xxhdpi/prcycoin.png create mode 100644 src/qt/android/res/drawable-xxxhdpi/prcycoin.png create mode 100644 src/qt/android/src/org/prcycoincore/qt/PrcycoinQtActivity.java diff --git a/configure.ac b/configure.ac index 8846e6cd08..fea60b1426 100644 --- a/configure.ac +++ b/configure.ac @@ -563,6 +563,21 @@ case $host in *android*) dnl make sure android stays above linux for hosts like *linux-android* TARGET_OS=android + case $host in + *x86_64*) + ANDROID_ARCH=x86_64 + ;; + *aarch64*) + ANDROID_ARCH=arm64-v8a + ;; + *armv7a*) + ANDROID_ARCH=armeabi-v7a + ;; + *i686*) + ANDROID_ARCH=i686 + ;; + *) AC_MSG_ERROR("Could not determine Android arch") ;; + esac ;; *linux*) TARGET_OS=linux diff --git a/doc/README.md b/doc/README.md index c6e998da63..00305941e6 100644 --- a/doc/README.md +++ b/doc/README.md @@ -42,6 +42,7 @@ The following are developer notes on how to build PRCYCoin on your native platfo - [FreeBSD Build Notes](build-freebsd.md) - [OpenBSD Build Notes](build-openbsd.md) - [NetBSD Build Notes](build-netbsd.md) +- [Android Build Notes](build-android.md) - [Gitian Building Guide](gitian-building.md) Development diff --git a/doc/build-android.md b/doc/build-android.md new file mode 100644 index 0000000000..9f8717a459 --- /dev/null +++ b/doc/build-android.md @@ -0,0 +1,12 @@ +ANDROID BUILD NOTES +====================== + +This guide describes how to build and package the `prcycoin-qt` GUI for Android on Linux and macOS. + +## Preparation + +You will need to get the Android NDK and build dependencies for Android as described in [depends/README.md](../depends/README.md). + +## Building and packaging + +After the depends are built configure with one of the resulting prefixes and run `make && make apk` in `src/qt`. \ No newline at end of file diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 0127fa0bf6..432b474405 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -468,6 +468,20 @@ prcycoin_qt_clean: FORCE prcycoin_qt : qt/prcycoin-qt$(EXEEXT) +APK_LIB_DIR = qt/android/libs/$(ANDROID_ARCH) +QT_BASE_PATH = $(shell find ../depends/sources/ -maxdepth 1 -type f -regex ".*qtbase.*\.tar.xz") +QT_BASE_TLD = $(shell tar tf $(QT_BASE_PATH) --exclude='*/*') + +prcycoin_qt_apk: FORCE + mkdir -p $(APK_LIB_DIR) + cp $(dir $(CC))../sysroot/usr/lib/$(host_alias)/libc++_shared.so $(APK_LIB_DIR) + tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/jar/src --strip-components=5 + tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/java/src --strip-components=5 + tar xf $(QT_BASE_PATH) -C qt/android/res/ $(QT_BASE_TLD)src/android/java/res --strip-components=5 + cp qt/prcycoin-qt $(APK_LIB_DIR)/libprcycoin-qt.so + cd qt/android && gradle wrapper --gradle-version=6.6.1 + cd qt/android && ./gradlew build + ui_%.h: %.ui @test -f $(UIC) @$(MKDIR_P) $(@D) diff --git a/src/qt/android/AndroidManifest.xml b/src/qt/android/AndroidManifest.xml new file mode 100644 index 0000000000..82ac5877bc --- /dev/null +++ b/src/qt/android/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/android/build.gradle b/src/qt/android/build.gradle new file mode 100644 index 0000000000..4c36e79db8 --- /dev/null +++ b/src/qt/android/build.gradle @@ -0,0 +1,52 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.1.0' + } +} + +repositories { + google() + jcenter() +} + +apply plugin: 'com.android.application' + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) +} + +android { + compileSdkVersion androidCompileSdkVersion.toInteger() + + buildToolsVersion androidBuildToolsVersion + + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java'] + aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] + res.srcDirs = [qt5AndroidDir + '/res', 'res'] + resources.srcDirs = ['src'] + renderscript.srcDirs = ['src'] + assets.srcDirs = ['assets'] + jniLibs.srcDirs = ['libs'] + } + } + + lintOptions { + abortOnError false + } + + dexOptions { + javaMaxHeapSize '4g' + } + + defaultConfig { + minSdkVersion 24 + } +} diff --git a/src/qt/android/gradle.properties b/src/qt/android/gradle.properties new file mode 100644 index 0000000000..838870f62d --- /dev/null +++ b/src/qt/android/gradle.properties @@ -0,0 +1,4 @@ +androidBuildToolsVersion=28.0.3 +androidCompileSdkVersion=28 +qt5AndroidDir=new File(".").absolutePath +org.gradle.jvmargs=-Xmx4608M diff --git a/src/qt/android/res/drawable-hdpi/prcycoin.png b/src/qt/android/res/drawable-hdpi/prcycoin.png new file mode 100644 index 0000000000000000000000000000000000000000..d0cc26044844707b2ab3d24e6fd8f2a5523156ff GIT binary patch literal 9807 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 literal 0 HcmV?d00001 diff --git a/src/qt/android/res/drawable-ldpi/prcycoin.png b/src/qt/android/res/drawable-ldpi/prcycoin.png new file mode 100644 index 0000000000000000000000000000000000000000..e60b04c554b39788b4382f987d2b835b78204b16 GIT binary patch literal 3083 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 literal 0 HcmV?d00001 diff --git a/src/qt/android/res/drawable-xhdpi/prcycoin.png b/src/qt/android/res/drawable-xhdpi/prcycoin.png new file mode 100644 index 0000000000000000000000000000000000000000..ec1b374ac2dda8cb0aed7da5c309c7fe92831fa1 GIT binary patch literal 15978 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 literal 0 HcmV?d00001 diff --git a/src/qt/android/res/drawable-xxhdpi/prcycoin.png b/src/qt/android/res/drawable-xxhdpi/prcycoin.png new file mode 100644 index 0000000000000000000000000000000000000000..dd7dfd5334b86b656e308ef787081f7aeb5e2109 GIT binary patch literal 31802 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 literal 0 HcmV?d00001 diff --git a/src/qt/android/res/drawable-xxxhdpi/prcycoin.png b/src/qt/android/res/drawable-xxxhdpi/prcycoin.png new file mode 100644 index 0000000000000000000000000000000000000000..fcdeb9301b36596ed42268a67f92462fac96e52f GIT binary patch literal 52052 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%0D)EsIC6)n<ltggYzf#!Qkz{*G9=V`&a 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 Qd;kCd07*qoM6N<$f{qyAGynhq literal 0 HcmV?d00001 diff --git a/src/qt/android/src/org/prcycoincore/qt/PrcycoinQtActivity.java b/src/qt/android/src/org/prcycoincore/qt/PrcycoinQtActivity.java new file mode 100644 index 0000000000..33dceb30e1 --- /dev/null +++ b/src/qt/android/src/org/prcycoincore/qt/PrcycoinQtActivity.java @@ -0,0 +1,29 @@ +package org.prcycoin.qt; + +import android.os.Bundle; +import android.system.ErrnoException; +import android.system.Os; + +import org.qtproject.qt5.android.bindings.QtActivity; + +import java.io.File; + +public class PrcycoinQtActivity extends QtActivity +{ + @Override + public void onCreate(Bundle savedInstanceState) + { + final File prcycoinDir = new File(getFilesDir().getAbsolutePath() + "/.prcycoin"); + if (!prcycoinDir.exists()) { + prcycoinDir.mkdir(); + } + + try { + Os.setenv("QT_QPA_PLATFORM", "android", true); + } catch (ErrnoException e) { + e.printStackTrace(); + } + + super.onCreate(savedInstanceState); + } +} diff --git a/src/qt/prcycoin.cpp b/src/qt/prcycoin.cpp index 6bead4d775..eb2a2726f1 100644 --- a/src/qt/prcycoin.cpp +++ b/src/qt/prcycoin.cpp @@ -594,6 +594,12 @@ int main(int argc, char* argv[]) QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); #endif +#if defined(QT_QPA_PLATFORM_ANDROID) + QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar); + QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); + QApplication::setAttribute(Qt::AA_DontUseNativeDialogs); +#endif + BitcoinApplication app(argc, argv); // Register meta types used for QMetaObject::invokeMethod From 22d56e04a1a18f3b8d2619e6eda28d77c3c34902 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 2 Jul 2023 11:07:38 -0400 Subject: [PATCH 335/391] depends: disable Qt Vulkan support on Android --- depends/packages/qt.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 0880a1e8e8..9cb31a9bd6 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -165,6 +165,7 @@ $(package)_config_opts_android += -no-fontconfig $(package)_config_opts_android += -L $(host_prefix)/lib $(package)_config_opts_android += -I $(host_prefix)/include $(package)_config_opts_android += -pch +$(package)_config_opts_android += -no-feature-vulkan $(package)_config_opts_aarch64_android += -android-arch arm64-v8a $(package)_config_opts_armv7a_android += -android-arch armeabi-v7a From 1e3f6a4254ffb31778d73a3ad1d6c059e4fc77c0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 2 Jul 2023 11:08:49 -0400 Subject: [PATCH 336/391] depends: fix Qt precompiled headers bug Fixed in 5.14, see QTBUG-85214 --- depends/packages/qt.mk | 3 ++- depends/patches/qt/fix_android_pch.patch | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 depends/patches/qt/fix_android_pch.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 9cb31a9bd6..3e2a0d4bb4 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -11,7 +11,7 @@ $(package)_linguist_tools = lrelease lupdate lconvert $(package)_patches = qt.pro qttools_src.pro $(package)_patches += fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch $(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch -$(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch +$(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch fix_android_pch.patch $(package)_patches+= fix_limits_header.patch $(package)_patches+= fix_montery_include.patch @@ -220,6 +220,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_android_qmake_conf.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_android_pch.patch && \ patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ diff --git a/depends/patches/qt/fix_android_pch.patch b/depends/patches/qt/fix_android_pch.patch new file mode 100644 index 0000000000..bed6e4bb63 --- /dev/null +++ b/depends/patches/qt/fix_android_pch.patch @@ -0,0 +1,10 @@ +--- old/qtbase/mkspecs/common/android-base-head.conf ++++ new/qtbase/mkspecs/common/android-base-head.conf +@@ -73,6 +73,6 @@ CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX- + QMAKE_PCH_OUTPUT_EXT = .gch + + QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +-QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE} ++QMAKE_CFLAGS_USE_PRECOMPILE = -include-pch ${QMAKE_PCH_OUTPUT} + QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} + QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE From 429cf799d57bb4ff87a9abfa6bf073ba795af076 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 3 Jul 2023 12:10:38 -0400 Subject: [PATCH 337/391] build: Add support for Android NDK r22+ --- depends/packages/qt.mk | 4 +- depends/patches/qt/fix_android_pch.patch | 2 +- .../patches/qt/fix_android_qmake_conf.patch | 10 -- .../patches/qt/support_new_android_ndks.patch | 122 ++++++++++++++++++ 4 files changed, 125 insertions(+), 13 deletions(-) delete mode 100644 depends/patches/qt/fix_android_qmake_conf.patch create mode 100644 depends/patches/qt/support_new_android_ndks.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 3e2a0d4bb4..5b89c8c482 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -10,7 +10,7 @@ $(package)_qt_libs=corelib network widgets gui plugins testlib concurrent $(package)_linguist_tools = lrelease lupdate lconvert $(package)_patches = qt.pro qttools_src.pro $(package)_patches += fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch -$(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch +$(package)_patches += support_new_android_ndks.patch fix_android_jni_static.patch dont_hardcode_pwd.patch $(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch fix_android_pch.patch $(package)_patches+= fix_limits_header.patch $(package)_patches+= fix_montery_include.patch @@ -218,7 +218,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_android_qmake_conf.patch && \ + patch -p1 -i $($(package)_patch_dir)/support_new_android_ndks.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_android_pch.patch && \ patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ diff --git a/depends/patches/qt/fix_android_pch.patch b/depends/patches/qt/fix_android_pch.patch index bed6e4bb63..195e1c5e59 100644 --- a/depends/patches/qt/fix_android_pch.patch +++ b/depends/patches/qt/fix_android_pch.patch @@ -1,6 +1,6 @@ --- old/qtbase/mkspecs/common/android-base-head.conf +++ new/qtbase/mkspecs/common/android-base-head.conf -@@ -73,6 +73,6 @@ CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX- +@@ -72,6 +72,6 @@ CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX- QMAKE_PCH_OUTPUT_EXT = .gch QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} diff --git a/depends/patches/qt/fix_android_qmake_conf.patch b/depends/patches/qt/fix_android_qmake_conf.patch deleted file mode 100644 index 3a8753fd1d..0000000000 --- a/depends/patches/qt/fix_android_qmake_conf.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- old/qtbase/mkspecs/android-clang/qmake.conf -+++ new/qtbase/mkspecs/android-clang/qmake.conf -@@ -47,7 +47,7 @@ ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so - ANDROID_USE_LLVM = true - - exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \ -- ANDROID_CXX_STL_LIBS = -lc++ -+ ANDROID_CXX_STL_LIBS = -lc++_shared - else: \ - ANDROID_CXX_STL_LIBS = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so.$$replace(ANDROID_PLATFORM, "android-", "") diff --git a/depends/patches/qt/support_new_android_ndks.patch b/depends/patches/qt/support_new_android_ndks.patch new file mode 100644 index 0000000000..85c8ae2132 --- /dev/null +++ b/depends/patches/qt/support_new_android_ndks.patch @@ -0,0 +1,122 @@ +Follow Google's BuildSystemMaintainers doc to support future NDK releases. + +Upstream commit: + - Qt 5.14: 9b14950ff600a4ce5a8698b67ab38907c50417f1 + +--- old/qtbase/mkspecs/android-clang/qmake.conf ++++ new/qtbase/mkspecs/android-clang/qmake.conf +@@ -14,43 +14,29 @@ + QMAKE_CC = $$NDK_LLVM_PATH/bin/clang + QMAKE_CXX = $$NDK_LLVM_PATH/bin/clang++ + ++# Follow https://android.googlesource.com/platform/ndk/+/ndk-release-r20/docs/BuildSystemMaintainers.md ++ + equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ +- QMAKE_CFLAGS += -target armv7-none-linux-androideabi +-else: equals(ANDROID_TARGET_ARCH, armeabi): \ +- QMAKE_CFLAGS += -target armv5te-none-linux-androideabi ++ QMAKE_CFLAGS = -target armv7a-linux-androideabi$$replace(ANDROID_PLATFORM, "android-", "") + else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \ +- QMAKE_CFLAGS += -target aarch64-none-linux-android ++ QMAKE_CFLAGS = -target aarch64-linux-android$$replace(ANDROID_PLATFORM, "android-", "") + else: equals(ANDROID_TARGET_ARCH, x86): \ +- QMAKE_CFLAGS += -target i686-none-linux-android -mstackrealign ++ QMAKE_CFLAGS = -target i686-linux-android$$replace(ANDROID_PLATFORM, "android-", "") -mstackrealign + else: equals(ANDROID_TARGET_ARCH, x86_64): \ +- QMAKE_CFLAGS += -target x86_64-none-linux-android +-else: equals(ANDROID_TARGET_ARCH, mips): \ +- QMAKE_CFLAGS += -target mipsel-none-linux-android +-else: equals(ANDROID_TARGET_ARCH, mips64): \ +- QMAKE_CFLAGS += -target mips64el-none-linux-android +- +-QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH -fno-limit-debug-info +- +-QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++ +-equals(ANDROID_TARGET_ARCH, armeabi-v7a): QMAKE_LINK += -Wl,--exclude-libs,libunwind.a +- +-QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \ +- -isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX \ +- -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include \ +- -isystem $$NDK_ROOT/sources/android/support/include \ +- -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include ++ QMAKE_CFLAGS = -target x86_64-linux-android$$replace(ANDROID_PLATFORM, "android-", "") + +-ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH ++QMAKE_CFLAGS += -fno-limit-debug-info + +-ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so ++QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS + +-ANDROID_USE_LLVM = true ++ANDROID_STDCPP_PATH = $$NDK_LLVM_PATH/sysroot/usr/lib/$$NDK_TOOLS_PREFIX/libc++_shared.so + +-exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \ +- ANDROID_CXX_STL_LIBS = -lc++ +-else: \ +- ANDROID_CXX_STL_LIBS = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so.$$replace(ANDROID_PLATFORM, "android-", "") ++ANDROID_USE_LLVM = true + +-QMAKE_CFLAGS_OPTIMIZE_SIZE = -Oz ++QMAKE_CFLAGS_OPTIMIZE_SIZE = -Oz ++QMAKE_LIBDIR_POST = ++QMAKE_LFLAGS = ++QMAKE_LIBS_PRIVATE = ++ANDROID_CXX_STL_LIBS = + + include(../common/android-base-tail.conf) + +--- old/qtbase/mkspecs/common/android-base-head.conf ++++ new/qtbase/mkspecs/common/android-base-head.conf +@@ -64,7 +58,6 @@ + } + + CONFIG += $$ANDROID_PLATFORM +-QMAKE_CFLAGS = -D__ANDROID_API__=$$replace(ANDROID_PLATFORM, "android-", "") + + ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/ + +--- old/qtbase/mkspecs/common/android-base-tail.conf ++++ new/qtbase/mkspecs/common/android-base-tail.conf +@@ -6,22 +6,17 @@ + QMAKE_CFLAGS += -fstack-protector-strong -DANDROID + + equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ +- QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove ++ QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp + else: equals(ANDROID_TARGET_ARCH, armeabi): \ +- QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float -fno-builtin-memmove +-# -fno-builtin-memmove is used to workaround https://code.google.com/p/android/issues/detail?id=81692 ++ QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float + + QMAKE_CFLAGS_WARN_ON = -Wall -W + QMAKE_CFLAGS_WARN_OFF = + equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) { + CONFIG += optimize_size + QMAKE_CFLAGS_DEBUG = -g -marm -O0 +- equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) { +- DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND +- } else { +- QMAKE_CFLAGS_RELEASE += -mthumb +- QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb +- } ++ QMAKE_CFLAGS_RELEASE += -mthumb ++ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb + } + + QMAKE_CFLAGS_SHLIB = -fPIC +@@ -61,15 +56,12 @@ + QMAKE_RANLIB = $${CROSS_COMPILE}ranlib + + QMAKE_INCDIR_POST = +-QMAKE_LIBDIR_POST = $$ANDROID_SOURCES_CXX_STL_LIBDIR + QMAKE_INCDIR_X11 = + QMAKE_LIBDIR_X11 = + QMAKE_INCDIR_OPENGL = + QMAKE_LIBDIR_OPENGL = + + QMAKE_LINK_SHLIB = $$QMAKE_LINK +-QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH +-equals(ANDROID_TARGET_ARCH, x86_64) QMAKE_LFLAGS += -L$$ANDROID_PLATFORM_ROOT_PATH/usr/lib64 + QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared + QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared + QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB From e22e6a898d13c5ad12bd1cac8b9a588c3694e05c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 5 Jul 2023 09:19:46 -0400 Subject: [PATCH 338/391] build, qt, macOS: Don't hard-code x86_64 as the arch when using qmake This change fixes qt build on M1 Apple Silicon --- depends/packages/qt.mk | 2 + depends/patches/qt/dont_hardcode_x86_64.patch | 123 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 depends/patches/qt/dont_hardcode_x86_64.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 5b89c8c482..9aa649f0af 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -11,6 +11,7 @@ $(package)_linguist_tools = lrelease lupdate lconvert $(package)_patches = qt.pro qttools_src.pro $(package)_patches += fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch $(package)_patches += support_new_android_ndks.patch fix_android_jni_static.patch dont_hardcode_pwd.patch +$(package)_patches += dont_hardcode_x86_64.patch $(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch fix_android_pch.patch $(package)_patches+= fix_limits_header.patch $(package)_patches+= fix_montery_include.patch @@ -222,6 +223,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_android_pch.patch && \ patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ + patch -p1 -i $($(package)_patch_dir)/dont_hardcode_x86_64.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_limits_header.patch && \ diff --git a/depends/patches/qt/dont_hardcode_x86_64.patch b/depends/patches/qt/dont_hardcode_x86_64.patch new file mode 100644 index 0000000000..0e1ca6acda --- /dev/null +++ b/depends/patches/qt/dont_hardcode_x86_64.patch @@ -0,0 +1,123 @@ +macOS: Don't hard-code x86_64 as the architecture when using qmake + +Upstream commit: + - Qt 6.1: 9082cc8e8d5a6441dabe5e7a95bc0cd9085b95fe + +For other Qt branches see +https://codereview.qt-project.org/q/I70db7e4c27f0d3da5d0af33cb491d72c312d3fa8 + + +--- old/qtbase/configure.json ++++ new/qtbase/configure.json +@@ -208,11 +208,18 @@ + + "testTypeDependencies": { + "linkerSupportsFlag": [ "use_gold_linker" ], +- "verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "qmakeargs", "commit" ], ++ "verifySpec": [ ++ "shared", ++ "use_gold_linker", ++ "compiler-flags", "qmakeargs", ++ "simulator_and_device", ++ "thread", ++ "commit" ], + "compile": [ "verifyspec" ], + "detectPkgConfig": [ "cross_compile", "machineTuple" ], + "library": [ "pkg-config", "compiler-flags" ], +- "getPkgConfigVariable": [ "pkg-config" ] ++ "getPkgConfigVariable": [ "pkg-config" ], ++ "architecture" : [ "verifyspec" ] + }, + + "testTypeAliases": { +@@ -653,7 +660,7 @@ + }, + "architecture": { + "label": "Architecture", +- "output": [ "architecture" ] ++ "output": [ "architecture", "commitConfig" ] + }, + "pkg-config": { + "label": "Using pkg-config", +diff --git a/configure.pri b/configure.pri +index 33c90a8c2f..71767e29d6 100644 + +--- old/qtbase/configure.pri ++++ new/qtbase/configure.pri +@@ -642,6 +642,13 @@ defineTest(qtConfOutput_commitOptions) { + write_file($$QT_BUILD_TREE/mkspecs/qdevice.pri, $${currentConfig}.output.devicePro)|error() + } + ++# Output is written after configuring each Qt module, ++# but some tests within a module might depend on the ++# configuration output of previous tests. ++defineTest(qtConfOutput_commitConfig) { ++ qtConfProcessOutput() ++} ++ + # type (empty or 'host'), option name, default value + defineTest(processQtPath) { + out_var = config.rel_input.$${2} +diff --git a/mkspecs/common/macx.conf b/mkspecs/common/macx.conf +index 7d4a406134..de96c12fc9 100644 + +--- old/qtbase/mkspecs/common/macx.conf ++++ new/qtbase/mkspecs/common/macx.conf +@@ -6,7 +6,6 @@ QMAKE_PLATFORM += macos osx macx + QMAKE_MAC_SDK = macosx + + QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12 +-QMAKE_APPLE_DEVICE_ARCHS = x86_64 + + QT_MAC_SDK_VERSION_MIN = 10.13 + QT_MAC_SDK_VERSION_MAX = 11.0 +diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf +index d052808c14..0a89effe87 100644 + +--- old/qtbase/mkspecs/features/mac/default_post.prf ++++ new/qtbase/mkspecs/features/mac/default_post.prf +@@ -89,6 +89,11 @@ app_extension_api_only { + QMAKE_LFLAGS += $$QMAKE_CFLAGS_APPLICATION_EXTENSION + } + ++# Non-universal builds do not set QMAKE_APPLE_DEVICE_ARCHS, ++# so we pick it up from what the arch test resolved instead. ++isEmpty(QMAKE_APPLE_DEVICE_ARCHS): \ ++ QMAKE_APPLE_DEVICE_ARCHS = $$QT_ARCH ++ + macx-xcode { + qmake_pkginfo_typeinfo.name = QMAKE_PKGINFO_TYPEINFO + !isEmpty(QMAKE_PKGINFO_TYPEINFO): \ +@@ -144,9 +149,6 @@ macx-xcode { + simulator: VALID_SIMULATOR_ARCHS = $$QMAKE_APPLE_SIMULATOR_ARCHS + VALID_ARCHS = $$VALID_DEVICE_ARCHS $$VALID_SIMULATOR_ARCHS + +- isEmpty(VALID_ARCHS): \ +- error("QMAKE_APPLE_DEVICE_ARCHS or QMAKE_APPLE_SIMULATOR_ARCHS must contain at least one architecture") +- + single_arch: VALID_ARCHS = $$first(VALID_ARCHS) + + ACTIVE_ARCHS = $(filter $(EXPORT_VALID_ARCHS), $(ARCHS)) +diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf +index 5003679bd0..c7c080cb07 100644 + +--- old/qtbase/mkspecs/features/toolchain.prf ++++ new/qtbase/mkspecs/features/toolchain.prf +@@ -182,9 +182,14 @@ isEmpty($${target_prefix}.INCDIRS) { + # UIKit simulator platforms will see the device SDK's sysroot in + # QMAKE_DEFAULT_*DIRS, because they're handled in a single build pass. + darwin { +- # Clang doesn't pick up the architecture from the sysroot, and will +- # default to the host architecture, so we need to manually set it. +- cxx_flags += -arch $$QMAKE_APPLE_DEVICE_ARCHS ++ uikit { ++ # Clang doesn't automatically pick up the architecture, just because ++ # we're passing the iOS sysroot below, and we will end up building the ++ # test for the host architecture, resulting in linker errors when ++ # linking against the iOS libraries. We work around this by passing ++ # the architecture explicitly. ++ cxx_flags += -arch $$first(QMAKE_APPLE_DEVICE_ARCHS) ++ } + + uikit:macx-xcode: \ + cxx_flags += -isysroot $$sdk_path_device.value From 79eb5d45a5ba7a326486b7e020baba0bc70ddede Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 5 Jul 2023 09:20:50 -0400 Subject: [PATCH 339/391] build, qt, macOS: Don't pass -device-option when building natively --- depends/packages/qt.mk | 4 +++- depends/patches/qt/mac-qmake.conf | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 9aa649f0af..7e7d50552a 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -111,8 +111,10 @@ $(package)_config_opts_darwin += -device-option MAC_TARGET=$(host) $(package)_config_opts_darwin += -device-option XCODE_VERSION=$(XCODE_VERSION) endif -# for macOS on Apple Silicon (ARM) see https://bugreports.qt.io/browse/QTBUG-85279 +ifneq ($(build_arch),$(host_arch)) $(package)_config_opts_aarch64_darwin += -device-option QMAKE_APPLE_DEVICE_ARCHS=arm64 +$(package)_config_opts_x86_64_darwin += -device-option QMAKE_APPLE_DEVICE_ARCHS=x86_64 +endif $(package)_config_opts_linux = -qt-xcb $(package)_config_opts_linux += -no-xcb-xlib diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf index 190ab7a160..e4bfaa1463 100644 --- a/depends/patches/qt/mac-qmake.conf +++ b/depends/patches/qt/mac-qmake.conf @@ -13,7 +13,6 @@ QMAKE_MAC_SDK.macosx.Path = $${MAC_SDK_PATH} QMAKE_MAC_SDK.macosx.platform_name = macosx QMAKE_MAC_SDK.macosx.SDKVersion = $${MAC_SDK_VERSION} QMAKE_MAC_SDK.macosx.PlatformPath = /phony -QMAKE_APPLE_DEVICE_ARCHS=x86_64 !host_build: QMAKE_CFLAGS += -target $${MAC_TARGET} !host_build: QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS !host_build: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS From 7d4120293e9b7923fc735409efc0c0619ccfcab3 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 9 Jul 2023 10:12:17 -0400 Subject: [PATCH 340/391] http: add missing header bootlegged by boost < 1.72 httpserver.cpp:74:10: error: no template named 'deque' in namespace 'std' std::deque> queue; ~~~~~^ --- src/httpserver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 54a4e03923..b70569122c 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -14,6 +14,7 @@ #include "sync.h" #include "guiinterface.h" +#include #include #include #include From a7ac57e1903675e16f13c14303c022a8b41d4252 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 9 Jul 2023 09:51:23 -0400 Subject: [PATCH 341/391] C++11: s/boost::scoped_ptr/std::unique_ptr/ --- src/dbwrapper.cpp | 4 +--- src/main.cpp | 2 +- src/test/dbwrapper_tests.cpp | 2 +- src/txdb.cpp | 4 ++-- src/wallet/walletdb.cpp | 3 +-- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index c180be3890..119657f3b2 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -6,8 +6,6 @@ #include "util.h" -#include - #include #include #include @@ -102,7 +100,7 @@ bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync) bool CDBWrapper::IsEmpty() { - boost::scoped_ptr it(NewIterator()); + std::unique_ptr it(NewIterator()); it->SeekToFirst(); return !(it->Valid()); } diff --git a/src/main.cpp b/src/main.cpp index 4f3363a198..a43e3cf14e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -192,7 +192,7 @@ std::map mapBlockSource; * * Memory used: 1.7MB */ -boost::scoped_ptr recentRejects; +std::unique_ptr recentRejects; uint256 hashRecentRejectsChainTip; /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */ diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 90f09379a0..c1671dfca1 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -89,7 +89,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) uint256 in2 = GetRandHash(); BOOST_CHECK(dbw.Write(key2, in2)); - boost::scoped_ptr it(const_cast(&dbw)->NewIterator()); + std::unique_ptr it(const_cast(&dbw)->NewIterator()); // Be sure to seek past any earlier key (if it exists) it->Seek(key); diff --git a/src/txdb.cpp b/src/txdb.cpp index 6cb6acf47e..6ce77cf53f 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -113,7 +113,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats& stats) const /* It seems that there are no "const iterators" for LevelDB. Since we only need read operations on it, use a const-cast to get around that restriction. */ - boost::scoped_ptr pcursor(const_cast(&db)->NewIterator()); + std::unique_ptr pcursor(const_cast(&db)->NewIterator()); pcursor->Seek(DB_COINS); CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); @@ -237,7 +237,7 @@ bool CBlockTreeDB::ReadInt(const std::string& name, int& nValue) bool CBlockTreeDB::LoadBlockIndexGuts() { - boost::scoped_ptr pcursor(NewIterator()); + std::unique_ptr pcursor(NewIterator()); pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, UINT256_ZERO)); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 8d79aae0d1..a717e3d19c 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -17,7 +17,6 @@ #include "wallet/wallet.h" #include -#include #include #include @@ -1153,7 +1152,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size()); bool fSuccess = allOK; - boost::scoped_ptr pdbCopy(new Db(dbenv.dbenv, 0)); + std::unique_ptr pdbCopy(new Db(dbenv.dbenv, 0)); int ret = pdbCopy->open(NULL, // Txn pointer filename.c_str(), // Filename "main", // Logical db name From 57c7d84064c9d35a3ad9128d9fcd9832433755bc Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 9 Jul 2023 10:57:48 -0400 Subject: [PATCH 342/391] Added std::unique_ptr<> wrappers with deleters for libevent modules. --- src/Makefile.am | 1 + src/support/events.h | 55 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/support/events.h diff --git a/src/Makefile.am b/src/Makefile.am index 9fb71d316a..5d043587d2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -176,6 +176,7 @@ BITCOIN_CORE_H = \ stakeinput.h \ streams.h \ support/cleanse.h \ + support/events.h \ sync.h \ threadsafety.h \ timedata.h \ diff --git a/src/support/events.h b/src/support/events.h new file mode 100644 index 0000000000..16378086fa --- /dev/null +++ b/src/support/events.h @@ -0,0 +1,55 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_SUPPORT_EVENTS_H +#define BITCOIN_SUPPORT_EVENTS_H + +#include + +#include +#include + +#define MAKE_RAII(type) \ +/* deleter */\ +struct type##_deleter {\ + void operator()(struct type* ob) {\ + type##_free(ob);\ + }\ +};\ +/* unique ptr typedef */\ +typedef std::unique_ptr raii_##type + +MAKE_RAII(event_base); +MAKE_RAII(event); +MAKE_RAII(evhttp); +MAKE_RAII(evhttp_request); +MAKE_RAII(evhttp_connection); + +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) { + return raii_event(event_new(base, s, events, cb, arg)); +} + +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) { + 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) { + 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"); + return result; +} + +#endif // BITCOIN_SUPPORT_EVENTS_H From 10a93fa71f8edc5443b9683383de30d8aee481f0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 9 Jul 2023 11:02:03 -0400 Subject: [PATCH 343/391] Switched prcycoin-cli.cpp to use RAII unique pointers with deleters. --- src/prcycoin-cli.cpp | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/prcycoin-cli.cpp b/src/prcycoin-cli.cpp index 599a2cd2af..485b6aa688 100644 --- a/src/prcycoin-cli.cpp +++ b/src/prcycoin-cli.cpp @@ -17,11 +17,9 @@ #include #include -#include -#include #include #include - +#include "support/events.h" #define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */ @@ -145,19 +143,15 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) std::string host = GetArg("-rpcconnect", "127.0.0.1"); int port = GetArg("-rpcport", BaseParams().RPCPort()); - // Create event base - struct event_base *base = event_base_new(); // TODO RAII - if (!base) - throw std::runtime_error("cannot create event_base"); + // Obtain event base + raii_event_base base = obtain_event_base(); // Synchronously look up hostname - struct evhttp_connection *evcon = evhttp_connection_base_new(base, NULL, host.c_str(), port); // TODO RAII - if (evcon == NULL) - throw std::runtime_error("create connection failed"); - evhttp_connection_set_timeout(evcon, GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT)); + raii_evhttp_connection evcon = obtain_evhttp_connection_base(base.get(), host, port); + evhttp_connection_set_timeout(evcon.get(), GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT)); HTTPReply response; - struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII + raii_evhttp_request req = obtain_evhttp_request(http_request_done, (void*)&response); if (req == NULL) throw std::runtime_error("create http request failed"); @@ -175,7 +169,7 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } - struct evkeyvalq *output_headers = evhttp_request_get_output_headers(req); + struct evkeyvalq* output_headers = evhttp_request_get_output_headers(req.get()); assert(output_headers); evhttp_add_header(output_headers, "Host", host.c_str()); evhttp_add_header(output_headers, "Connection", "close"); @@ -184,20 +178,17 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) // Attach request data std::string strRequest = JSONRPCRequest(strMethod, params, 1); - struct evbuffer * output_buffer = evhttp_request_get_output_buffer(req); + struct evbuffer* output_buffer = evhttp_request_get_output_buffer(req.get()); assert(output_buffer); evbuffer_add(output_buffer, strRequest.data(), strRequest.size()); - int r = evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/"); + int r = evhttp_make_request(evcon.get(), req.get(), EVHTTP_REQ_POST, "/"); + req.release(); // ownership moved to evcon in above call if (r != 0) { - evhttp_connection_free(evcon); - event_base_free(base); throw CConnectionFailed("send http request failed"); } - event_base_dispatch(base); - evhttp_connection_free(evcon); - event_base_free(base); + event_base_dispatch(base.get()); if (response.status == 0) throw CConnectionFailed("couldn't connect to server"); From 06d7e740cef979339ce23cccf7d60221fe273eaf Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 9 Jul 2023 11:04:08 -0400 Subject: [PATCH 344/391] Added some simple tests for the RAII-style events. --- src/Makefile.test.include | 1 + src/support/events.h | 1 + src/test/raii_event_tests.cpp | 88 +++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 src/test/raii_event_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index b419bcf67f..741f08c7e9 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -51,6 +51,7 @@ BITCOIN_TESTS =\ test/netbase_tests.cpp \ test/pmt_tests.cpp \ test/prevector_tests.cpp \ + test/raii_event_tests.cpp \ test/reverselock_tests.cpp \ test/rpc_tests.cpp \ test/sanity_tests.cpp \ diff --git a/src/support/events.h b/src/support/events.h index 16378086fa..4f2f3cf9ef 100644 --- a/src/support/events.h +++ b/src/support/events.h @@ -6,6 +6,7 @@ #define BITCOIN_SUPPORT_EVENTS_H #include +#include #include #include diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp new file mode 100644 index 0000000000..87d25c0e2c --- /dev/null +++ b/src/test/raii_event_tests.cpp @@ -0,0 +1,88 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include + +#include "support/events.h" + +#include "test/test_bitcoin.h" + +#include + +#include + +static std::map tags; +static std::map orders; +static uint16_t tagSequence = 0; + +static void* tag_malloc(size_t sz) { + void* mem = malloc(sz); + if (!mem) return mem; + tags[mem]++; + orders[mem] = tagSequence++; + return mem; +} + +static void tag_free(void* mem) { + tags[mem]--; + orders[mem] = tagSequence++; + free(mem); +} + +BOOST_FIXTURE_TEST_SUITE(raii_event_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(raii_event_creation) +{ + event_set_mem_functions(tag_malloc, realloc, tag_free); + + void* base_ptr = NULL; + { + auto base = obtain_event_base(); + base_ptr = (void*)base.get(); + BOOST_CHECK(tags[base_ptr] == 1); + } + BOOST_CHECK(tags[base_ptr] == 0); + + void* event_ptr = NULL; + { + auto base = obtain_event_base(); + auto event = obtain_event(base.get(), -1, 0, NULL, NULL); + + base_ptr = (void*)base.get(); + event_ptr = (void*)event.get(); + + BOOST_CHECK(tags[base_ptr] == 1); + BOOST_CHECK(tags[event_ptr] == 1); + } + BOOST_CHECK(tags[base_ptr] == 0); + BOOST_CHECK(tags[event_ptr] == 0); + + event_set_mem_functions(malloc, realloc, free); +} + +BOOST_AUTO_TEST_CASE(raii_event_order) +{ + event_set_mem_functions(tag_malloc, realloc, tag_free); + + void* base_ptr = NULL; + void* event_ptr = NULL; + { + auto base = obtain_event_base(); + auto event = obtain_event(base.get(), -1, 0, NULL, NULL); + + base_ptr = (void*)base.get(); + event_ptr = (void*)event.get(); + + // base should have allocated before event + BOOST_CHECK(orders[base_ptr] < orders[event_ptr]); + } + // base should be freed after event + BOOST_CHECK(orders[base_ptr] > orders[event_ptr]); + + event_set_mem_functions(malloc, realloc, free); +} + +BOOST_AUTO_TEST_SUITE_END() From a531e3337bb131b6723e424b35280dab2bbe4b58 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 9 Jul 2023 11:07:10 -0400 Subject: [PATCH 345/391] Added EVENT_CFLAGS to test makefile to explicitly include libevent headers --- src/Makefile.test.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 741f08c7e9..f9ef118420 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -79,7 +79,7 @@ BITCOIN_TESTS += \ endif test_test_prcycoin_SOURCES = $(BITCOIN_TEST_SUITE) $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES) -test_test_prcycoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_FLAGS) +test_test_prcycoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_CFLAGS) test_test_prcycoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \ $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(LIBSECP256K1_2) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) if ENABLE_WALLET From bdac65f88a1ef766fcf350a573574e3d2abc1d1b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 9 Jul 2023 11:22:22 -0400 Subject: [PATCH 346/391] Switched httpserver.cpp to use RAII wrapped libevents. --- src/httpserver.cpp | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index a863f607b9..70d45b8254 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -24,15 +24,14 @@ #include #include -#include -#include -#include #include #include #include #include #include +#include "support/events.h" + #ifdef EVENT__HAVE_NETINET_IN_H #include #ifdef _XOPEN_SOURCE_EXTENDED @@ -391,9 +390,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; @@ -419,17 +415,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; } @@ -440,8 +432,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; } @@ -450,8 +440,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; } From 53927a26451565b258170ae514d24caa4be7f59c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 9 Jul 2023 11:24:08 -0400 Subject: [PATCH 347/391] Changed event RAII helper functions to inline to deal with duplicate symbol linker errors. --- src/support/events.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/support/events.h b/src/support/events.h index 4f2f3cf9ef..90690876ee 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"); From c0213a6bfedc17122689ceeb5829ce2b0e863340 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 07:59:51 -0400 Subject: [PATCH 348/391] Set to nullptr after delete --- src/httpserver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 70d45b8254..d41c5a479e 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -501,6 +501,7 @@ void StopHTTPServer() LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n"); workQueue->WaitExit(); delete workQueue; + workQueue = nullptr; } MilliSleep(500); // Avoid race condition while the last HTTP-thread is exiting if (eventBase) { From ce65587c6af339d07d063fa1d513b73c9bf35f76 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 08:26:44 -0400 Subject: [PATCH 349/391] depends: qrencode 4.1.1 Upgrade to the latest qrencode, and disable some warnings that cause compile failures with newer compilers (clang-15+). Fixes part of https://github.com/bitcoin/bitcoin/issues/27299. --- depends/packages/qrencode.mk | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index d1687883bc..2afd95d7c4 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -1,15 +1,16 @@ package=qrencode -$(package)_version=3.4.4 +$(package)_version=4.1.1 $(package)_download_path=https://fukuchi.org/works/qrencode/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=efe5188b1ddbcbf98763b819b146be6a90481aac30cfc8d858ab78a19cde1fa5 +$(package)_sha256_hash=e455d9732f8041cf5b9c388e345a641fd15707860f928e94507b1961256a6923 define $(package)_set_vars -$(package)_config_opts=--disable-shared --without-tools --without-tests --disable-sdltest +$(package)_config_opts=--disable-shared --without-tools --without-tests --without-png $(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic $(package)_config_opts_android=--with-pic +$(package)_cflags += -Wno-int-conversion -Wno-implicit-function-declaration endef define $(package)_preprocess_cmds From 3d97b7ec9f997827d4d992585dfffa187a98c60f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 09:01:44 -0400 Subject: [PATCH 350/391] refactor: Move GetDifficulty out of `rpc/server.h` It has no business in `rpcserver.h`. Define it in the interface header of the implementation unit `rpcblockchain` where it is defined. Also modernize the signature to: double GetDifficulty(const CBlockIndex* blockindex = nullptr); (remove `extern`, replace `NULL` with `nullptr`) --- src/Makefile.am | 1 + src/rpc/blockchain.cpp | 2 ++ src/rpc/blockchain.h | 20 ++++++++++++++++++++ src/rpc/mining.cpp | 1 + src/rpc/misc.cpp | 1 + src/rpc/server.h | 1 - 6 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/rpc/blockchain.h diff --git a/src/Makefile.am b/src/Makefile.am index 5d043587d2..7b5a0815f9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -162,6 +162,7 @@ BITCOIN_CORE_H = \ random.h \ reverselock.h \ reverse_iterate.h \ + rpc/blockchain.h \ rpc/client.h \ rpc/protocol.h \ rpc/server.h \ diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index eae5b7cabd..c499e7b05a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -6,6 +6,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "rpc/blockchain.h" + #include "checkpoints.h" #include "main.h" #include "rpc/server.h" diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h new file mode 100644 index 0000000000..69cba8f019 --- /dev/null +++ b/src/rpc/blockchain.h @@ -0,0 +1,20 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_RPC_BLOCKCHAIN_H +#define BITCOIN_RPC_BLOCKCHAIN_H + +class CBlockIndex; + +/** + * Get the difficulty of the net wrt to the given block index, or the chain tip if + * not provided. + * + * @return A floating point number that is a multiple of the main net minimum + * difficulty (4295032833 hashes). + */ +double GetDifficulty(const CBlockIndex* blockindex = nullptr); + +#endif + diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 2d20b1b7dd..82bd7ea956 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -15,6 +15,7 @@ #include "miner.h" #include "net.h" #include "poa.h" +#include "rpc/blockchain.h" #include "rpc/server.h" #include "util.h" #ifdef ENABLE_WALLET diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index c2dbe7eebd..bd4006f5f5 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -14,6 +14,7 @@ #include "masternode-sync.h" #include "net.h" #include "netbase.h" +#include "rpc/blockchain.h" #include "rpc/server.h" #include "timedata.h" #include "util.h" diff --git a/src/rpc/server.h b/src/rpc/server.h index d880e15ba7..71e152b0fa 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -171,7 +171,6 @@ extern bool ParseBool(const UniValue& o, std::string strKey); extern int64_t nWalletUnlockTime; extern CAmount AmountFromValue(const UniValue& value); extern UniValue ValueFromAmount(const CAmount& amount); -extern double GetDifficulty(const CBlockIndex* blockindex = NULL); extern std::string HelpRequiringPassphrase(); extern std::string HelpExampleCli(std::string methodname, std::string args); extern std::string HelpExampleRpc(std::string methodname, std::string args); From 2c2b9a2dbf11750b6c54e324547031b359dae3fc Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 09:07:06 -0400 Subject: [PATCH 351/391] refactor: Move RPCNotifyBlockChange out of `rpc/server.h` --- src/init.cpp | 1 + src/rpc/blockchain.h | 3 +++ src/rpc/server.h | 1 - 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index a61248ceff..f2a3605373 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -31,6 +31,7 @@ #include "miner.h" #include "netbase.h" #include "net.h" +#include "rpc/blockchain.h" #include "rpc/server.h" #include "script/standard.h" #include "script/sigcache.h" diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h index 69cba8f019..8821f297f6 100644 --- a/src/rpc/blockchain.h +++ b/src/rpc/blockchain.h @@ -16,5 +16,8 @@ class CBlockIndex; */ double GetDifficulty(const CBlockIndex* blockindex = nullptr); +/** Callback for when block tip changed. */ +void RPCNotifyBlockChange(bool ibd, const CBlockIndex *); + #endif diff --git a/src/rpc/server.h b/src/rpc/server.h index 71e152b0fa..c30d5a56de 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -361,6 +361,5 @@ bool StartRPC(); void InterruptRPC(); void StopRPC(); std::string JSONRPCExecBatch(const UniValue& vReq); -void RPCNotifyBlockChange(bool fInitialDownload, const CBlockIndex* pindex); #endif // BITCOIN_RPCSERVER_H From 311615dbe2f7f77089b0b5f1ba0185fbdde799c5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 09:49:02 -0400 Subject: [PATCH 352/391] refactor: Make rest.cpp dependency on `*toJSON` in `blockchain.cpp` explicit --- src/rest.cpp | 16 ++++------------ src/rpc/blockchain.cpp | 4 ++-- src/rpc/blockchain.h | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index eb35962e7e..29b8972b86 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -8,6 +8,7 @@ #include "primitives/transaction.h" #include "main.h" #include "httpserver.h" +#include "rpc/blockchain.h" #include "rpc/server.h" #include "streams.h" #include "sync.h" @@ -54,18 +55,9 @@ struct CCoin { } }; - -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); - -extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); - -extern UniValue mempoolInfoToJSON(); - -extern UniValue mempoolToJSON(bool fVerbose = false); - -extern void ScriptPubKeyToJSON(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex); - -extern UniValue blockheaderToJSON(const CBlockIndex *blockindex); +/* Defined in rawtransaction.cpp */ +void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); static bool RESTERR(HTTPRequest *req, enum HTTPStatusCode status, std::string message) { req->WriteHeader("Content-Type", "text/plain"); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index c499e7b05a..c29337ea41 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -94,7 +94,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) return result; } -UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails) { UniValue result(UniValue::VOBJ); result.pushKV("hash", block.GetHash().GetHex()); @@ -379,7 +379,7 @@ UniValue getdifficulty(const UniValue& params, bool fHelp) } -UniValue mempoolToJSON(bool fVerbose = false) +UniValue mempoolToJSON(bool fVerbose) { if (fVerbose) { LOCK(mempool.cs); diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h index 8821f297f6..c021441b0a 100644 --- a/src/rpc/blockchain.h +++ b/src/rpc/blockchain.h @@ -5,7 +5,12 @@ #ifndef BITCOIN_RPC_BLOCKCHAIN_H #define BITCOIN_RPC_BLOCKCHAIN_H +class CBlock; class CBlockIndex; +class CScript; +class CTransaction; +class uint256; +class UniValue; /** * Get the difficulty of the net wrt to the given block index, or the chain tip if @@ -19,5 +24,17 @@ double GetDifficulty(const CBlockIndex* blockindex = nullptr); /** Callback for when block tip changed. */ void RPCNotifyBlockChange(bool ibd, const CBlockIndex *); +/** Block description to JSON */ +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); + +/** Mempool information to JSON */ +UniValue mempoolInfoToJSON(); + +/** Mempool to JSON */ +UniValue mempoolToJSON(bool fVerbose = false); + +/** Block header to JSON */ +UniValue blockheaderToJSON(const CBlockIndex* blockindex); + #endif From 132ec156beff4132e17ef7cd7a7fd612d51b579a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 12:40:04 -0400 Subject: [PATCH 353/391] Avoid integer overflows in scriptnum tests --- src/test/scriptnum_tests.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index 767db678d0..f75b51e202 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -12,8 +12,10 @@ BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup) -static const long values[] = \ -{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, static_castUINT_MAX, LONG_MIN, LONG_MAX }; +/** A selection of numbers that do not trigger int64_t overflow + * when added/subtracted. */ +static const int64_t values[] = { 0, 1, -2, 127, 128, -255, 256, (1LL << 15) - 1, -(1LL << 16), (1LL << 24) - 1, (1LL << 31), 1 - (1LL << 32), 1LL << 40 }; + static const long offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000}; static bool verify(const CBigNum& bignum, const CScriptNum& scriptnum) From f3cdfa6d79aa8acb67770a0f1dc44eac70325df1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 12:41:24 -0400 Subject: [PATCH 354/391] Fix memory leak in wallet tests --- src/wallet/test/wallet_tests.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index d324b111df..a917639daa 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -20,6 +20,7 @@ // we repeat those tests this many times and only complain if all iterations of the test fail #define RANDOM_REPEATS 5 +std::vector> wtxn; typedef std::set > CoinSet; extern CWallet* pwalletMain; @@ -81,21 +82,21 @@ static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = fa // so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe() tx.vin.resize(1); } - CWalletTx* wtx = new CWalletTx(&wallet, tx); + std::unique_ptr wtx(new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)))); if (fIsFromMe) { wtx->fDebitCached = true; wtx->nDebitCached = 1; } - COutput output(wtx, nInput, nAge, true); + COutput output(wtx.get(), nInput, nAge, true); vCoins.push_back(output); + wtxn.emplace_back(std::move(wtx)); } static void empty_wallet(void) { - for (COutput output : vCoins) - delete output.tx; vCoins.clear(); + wtxn.clear(); } static bool equal_sets(CoinSet a, CoinSet b) From 2d43558751251c5fa26393bd10aecb01b26ae593 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 12:41:38 -0400 Subject: [PATCH 355/391] Fix memory leak in net_tests --- src/test/net_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index e96a35ba47..ad98df60d5 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -162,12 +162,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) bool fInboundIn = false; // Test that fFeeler is false by default. - CNode* pnode1 = new CNode(hSocket, addr, pszDest, fInboundIn); + std::unique_ptr pnode1(new CNode(hSocket, addr, pszDest, fInboundIn)); BOOST_CHECK(pnode1->fInbound == false); BOOST_CHECK(pnode1->fFeeler == false); fInboundIn = true; - CNode* pnode2 = new CNode(hSocket, addr, pszDest, fInboundIn); + std::unique_ptr pnode2(new CNode(hSocket, addr, pszDest, fInboundIn)); BOOST_CHECK(pnode2->fInbound == true); BOOST_CHECK(pnode2->fFeeler == false); } From 1efaccaf494f88d03ab9b8cfd97153d32fa586db Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 12:41:54 -0400 Subject: [PATCH 356/391] Fix memory leak in multiUserAuthorized --- src/httprpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 655939c3e3..2015805d88 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -113,7 +113,7 @@ static bool multiUserAuthorized(std::string strUserPass) std::string strHash = vFields[2]; unsigned int KEY_SIZE = 32; - unsigned char *out = new unsigned char[KEY_SIZE]; + 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); From ca862b55afe0a488dc2c9cca49b1a11c4b48a622 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 12:42:12 -0400 Subject: [PATCH 357/391] Avoid boost dynamic_bitset in rest_getutxos --- src/rest.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index 29b8972b86..433c0ba363 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -18,11 +18,9 @@ #include #include -#include static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once - enum RetFormat { RF_UNDEF, RF_BINARY, @@ -477,7 +475,8 @@ static bool rest_getutxos(HTTPRequest *req, const std::string &strURIPart) { std::vector bitmap; std::vector outs; std::string bitmapStringRepresentation; - boost::dynamic_bitset hits(vOutPoints.size()); + std::vector hits; + bitmap.resize((vOutPoints.size() + 7) / 8); { LOCK2(cs_main, mempool.cs); @@ -493,12 +492,12 @@ static bool rest_getutxos(HTTPRequest *req, const std::string &strURIPart) { for (size_t i = 0; i < vOutPoints.size(); i++) { CCoins coins; uint256 hash = vOutPoints[i].hash; + bool hit = false; if (view.GetCoins(hash, coins)) { mempool.pruneSpent(hash, coins); if (coins.IsAvailable(vOutPoints[i].n)) { - hits[i] = true; + hit = true; // Safe to index into vout here because IsAvailable checked if it's off the end of the array, or if - // n is valid but points to an already spent output (IsNull). CCoin coin; coin.nTxVer = coins.nVersion; @@ -509,11 +508,12 @@ static bool rest_getutxos(HTTPRequest *req, const std::string &strURIPart) { } } - bitmapStringRepresentation.append( - hits[i] ? "1" : "0"); // form a binary string representation (human-readable for json output) + hits.push_back(hit); + bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output) + bitmap[i / 8] |= ((uint8_t)hit) << (i % 8); } } - boost::to_block_range(hits, std::back_inserter(bitmap)); + switch (rf) { case RF_BINARY: { // serialize data From 303dc598ae4b29478bfc4421207a2426baf2c18f Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 15:22:29 -0400 Subject: [PATCH 358/391] Fix includes in tests --- src/test/alert_tests.cpp | 2 +- src/test/bip32_tests.cpp | 2 +- src/test/miner_tests.cpp | 2 +- src/test/raii_event_tests.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index c43881be20..9910865f4c 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -9,7 +9,7 @@ #include "chainparams.h" #include "util.h" -#include "test/test_bitcoin.h" +#include "test/test_prcycoin.h" #include diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index c558ff99f1..1630a6ccb6 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -8,7 +8,7 @@ #include "key.h" #include "uint256.h" #include "util.h" -#include "test/test_bitcoin.h" +#include "test/test_prcycoin.h" #include #include diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 755644f5b1..f58bc30a64 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -10,7 +10,7 @@ #include "uint256.h" #include "util.h" -#include "test/test_bitcoin.h" +#include "test/test_prcycoin.h" #include diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp index 87d25c0e2c..97363dd353 100644 --- a/src/test/raii_event_tests.cpp +++ b/src/test/raii_event_tests.cpp @@ -8,7 +8,7 @@ #include "support/events.h" -#include "test/test_bitcoin.h" +#include "test/test_prcycoin.h" #include From b9dceec8d867d5459f1248567994645f917cec9a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 16:00:12 -0400 Subject: [PATCH 359/391] use std::map::erase(const_iterator, const_iterator) to get non-constant iterator --- src/limitedmap.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/limitedmap.h b/src/limitedmap.h index dda9287f16..7688edf3c5 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -63,8 +63,10 @@ class limitedmap } void update(const_iterator itIn, const mapped_type& v) { - // TODO: When we switch to C++11, use map.erase(itIn, itIn) to get the non-const iterator. - iterator itTarget = map.find(itIn->first); + // Using map::erase() with empty range instead of map::find() to get a non-const iterator, + // since it is a constant time operation in C++11. For more details, see + // https://stackoverflow.com/questions/765148/how-to-remove-constness-of-const-iterator + iterator itTarget = map.erase(itIn, itIn); if (itTarget == map.end()) return; std::pair itPair = rmap.equal_range(itTarget->second); From 980052db08ada3d11ffcfd2c129566fcb4ab50e1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 16:01:45 -0400 Subject: [PATCH 360/391] use c++11 std::unique_ptr instead of boost::shared_ptr --- src/rpc/server.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 75c2457310..0e9d14514f 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -25,13 +25,12 @@ #include #include #include -#include #include #include #include // for to_upper() #include - +#include // for unique_ptr static bool fRPCRunning = false; static bool fRPCInWarmup = true; @@ -40,9 +39,8 @@ static RecursiveMutex cs_rpcWarmup; /* Timer-creating functions */ static RPCTimerInterface* timerInterface = NULL; -/* Map of name to timer. - * @note Can be changed to std::unique_ptr when C++11 */ -static std::map > deadlineTimers; +/* Map of name to timer. */ +static std::map > deadlineTimers; static struct CRPCSignals { boost::signals2::signal Started; @@ -630,7 +628,7 @@ void RPCRunLater(const std::string &name, boost::function func, int6 deadlineTimers.erase(name); LogPrint(BCLog::RPC, "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); deadlineTimers.insert( - std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds * 1000)))); + std::make_pair(name, std::unique_ptr(timerInterface->NewTimer(func, nSeconds * 1000)))); } const CRPCTable tableRPC; From a8a7df77a6bfb24f3bb2a6a6d4c8da980ea9b2f0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 16:02:49 -0400 Subject: [PATCH 361/391] use std::map::emplace() instead of std::map::insert() --- src/rpc/server.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 0e9d14514f..b25675b245 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -627,8 +627,7 @@ void RPCRunLater(const std::string &name, boost::function func, int6 throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); deadlineTimers.erase(name); LogPrint(BCLog::RPC, "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); - deadlineTimers.insert( - std::make_pair(name, std::unique_ptr(timerInterface->NewTimer(func, nSeconds * 1000)))); + deadlineTimers.emplace(name, std::unique_ptr(timerInterface->NewTimer(func, nSeconds * 1000))); } const CRPCTable tableRPC; From 5f6a0f95b1fb8bba1c8c528f641d7f4c20af1bc7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 10 Jul 2023 16:06:49 -0400 Subject: [PATCH 362/391] Use std::shared_ptr instead of boost::shared_ptr in ScriptForMining --- src/validationinterface.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/validationinterface.h b/src/validationinterface.h index 229dc7e3ed..e241d2c4fd 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -7,7 +7,6 @@ #define BITCOIN_VALIDATIONINTERFACE_H #include -#include class CBlock; struct CBlockLocator; @@ -41,7 +40,7 @@ class CValidationInterface { // XX42 virtual void ResendWalletTransactions(int64_t nBestBlockTime) {} virtual void ResendWalletTransactions() {} virtual void BlockChecked(const CBlock&, const CValidationState&) {} -// XX42 virtual void GetScriptForMining(boost::shared_ptr&) {}; +// XX42 virtual void GetScriptForMining(std::shared_ptr&) {}; virtual void ResetRequestCount(const uint256 &hash) {}; friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*); @@ -67,7 +66,7 @@ struct CMainSignals { /** Notifies listeners of a block validation result */ boost::signals2::signal BlockChecked; /** Notifies listeners that a key for mining is required (coinbase) */ -// XX42 boost::signals2::signal&)> ScriptForMining; +// XX42 boost::signals2::signal&)> ScriptForMining; /** Notifies listeners that a block has been successfully mined */ boost::signals2::signal BlockFound; }; From a09a453f7a866047d92cc8ff431f0b95987d0477 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 11 Jul 2023 08:55:26 -0400 Subject: [PATCH 363/391] Improve shutdown process --- src/httpserver.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index d41c5a479e..99cfe45239 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -506,6 +506,8 @@ void StopHTTPServer() MilliSleep(500); // Avoid race condition while the last HTTP-thread is exiting if (eventBase) { LogPrint(BCLog::HTTP, "Waiting for HTTP event thread to exit\n"); + // Exit the event loop as soon as there are no active events. + event_base_loopexit(eventBase, nullptr); // Give event loop a few seconds to exit (to send back last RPC responses), then break it // Before this was solved with event_base_loopexit, but that didn't work as expected in // at least libevent 2.0.21 and always introduced a delay. In libevent From f24d007e4934641cf74221768c00cb6e20742ad1 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 11 Jul 2023 09:03:58 -0400 Subject: [PATCH 364/391] Access WorkQueue::running only within the cs lock. This removes a "race" between Interrupt() and Run(), though it should not effect any of our supported platforms. --- src/httpserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index d41c5a479e..2d947bf245 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -122,7 +122,7 @@ class WorkQueue void Run() { ThreadCounter count(*this); - while (running) { + while (true) { std::unique_ptr i; { std::unique_lock lock(cs); From 23caf7a958060da312ce91fd5014c3eda5fd3da5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Jul 2023 12:01:18 -0400 Subject: [PATCH 365/391] Replace boost::function with std::function (C++11) --- src/httprpc.cpp | 4 ++-- src/qt/rpcconsole.cpp | 6 +++--- src/rpc/server.cpp | 12 ++++-------- src/rpc/server.h | 14 ++++++-------- src/scheduler.h | 7 +++---- src/torcontrol.cpp | 9 ++++----- src/torcontrol.h | 1 - 7 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 2015805d88..d8c6cb5a8a 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -30,7 +30,7 @@ static const char* WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; class HTTPRPCTimer : public RPCTimerBase { public: - HTTPRPCTimer(struct event_base* eventBase, boost::function& func, int64_t millis) : + HTTPRPCTimer(struct event_base* eventBase, std::function& func, int64_t millis) : ev(eventBase, false, func) { struct timeval tv; @@ -52,7 +52,7 @@ class HTTPRPCTimerInterface : public RPCTimerInterface { return "HTTP"; } - RPCTimerBase* NewTimer(boost::function& func, int64_t millis) + RPCTimerBase* NewTimer(std::function& func, int64_t millis) { return new HTTPRPCTimer(base, func, millis); } diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 9539bb8155..dc2db159ab 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -88,7 +88,7 @@ class QtRPCTimerBase: public QObject, public RPCTimerBase { Q_OBJECT public: - QtRPCTimerBase(boost::function& func, int64_t millis): + QtRPCTimerBase(std::function& func, int64_t millis): func(func) { timer.setSingleShot(true); @@ -100,7 +100,7 @@ private Q_SLOTS: void timeout() { func(); } private: QTimer timer; - boost::function func; + std::function func; }; class QtRPCTimerInterface: public RPCTimerInterface @@ -108,7 +108,7 @@ class QtRPCTimerInterface: public RPCTimerInterface public: ~QtRPCTimerInterface() {} const char *Name() { return "Qt"; } - RPCTimerBase* NewTimer(boost::function& func, int64_t millis) + RPCTimerBase* NewTimer(std::function& func, int64_t millis) { return new QtRPCTimerBase(func, millis); } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index b25675b245..a3a5cc21b0 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -49,22 +49,18 @@ static struct CRPCSignals { boost::signals2::signal PostCommand; } g_rpcSignals; -void RPCServer::OnStarted(boost::function slot) { +void RPCServer::OnStarted(std::function slot) { g_rpcSignals.Started.connect(slot); } -void RPCServer::OnStopped(boost::function slot) { +void RPCServer::OnStopped(std::function slot) { g_rpcSignals.Stopped.connect(slot); } -void RPCServer::OnPreCommand(boost::function slot) { +void RPCServer::OnPreCommand(std::function slot) { g_rpcSignals.PreCommand.connect(boost::bind(slot, _1)); } -void RPCServer::OnPostCommand(boost::function slot) { - g_rpcSignals.PostCommand.connect(boost::bind(slot, _1)); -} - void RPCTypeCheck(const UniValue ¶ms, const std::list& typesExpected, bool fAllowNull) { unsigned int i = 0; for (UniValue::VType t : typesExpected) { @@ -622,7 +618,7 @@ void RPCUnsetTimerInterface(RPCTimerInterface *iface) { timerInterface = NULL; } -void RPCRunLater(const std::string &name, boost::function func, int64_t nSeconds) { +void RPCRunLater(const std::string &name, std::function func, int64_t nSeconds) { if (!timerInterface) throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); deadlineTimers.erase(name); diff --git a/src/rpc/server.h b/src/rpc/server.h index c30d5a56de..65ebb14997 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -17,18 +17,16 @@ #include #include -#include - #include class CRPCCommand; namespace RPCServer { - void OnStarted(boost::function slot); - void OnStopped(boost::function slot); - void OnPreCommand(boost::function slot); - void OnPostCommand(boost::function slot); + void OnStarted(std::function slot); + void OnStopped(std::function slot); + void OnPreCommand(std::function slot); + void OnPostCommand(std::function slot); } class CBlockIndex; @@ -97,7 +95,7 @@ class RPCTimerInterface * This is needed to cope with the case in which there is no HTTP server, but * only GUI RPC console, and to break the dependency of pcserver on httprpc. */ - virtual RPCTimerBase* NewTimer(boost::function& func, int64_t millis) = 0; + virtual RPCTimerBase* NewTimer(std::function& func, int64_t millis) = 0; }; /** Set factory function for timers */ @@ -111,7 +109,7 @@ void RPCUnsetTimerInterface(RPCTimerInterface *iface); * Run func nSeconds from now. * Overrides previous timer (if any). */ -void RPCRunLater(const std::string& name, boost::function func, int64_t nSeconds); +void RPCRunLater(const std::string& name, std::function func, int64_t nSeconds); typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp); diff --git a/src/scheduler.h b/src/scheduler.h index f06031715e..f322d30beb 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -9,10 +9,9 @@ // // NOTE: -// boost::thread / boost::function / boost::chrono should be ported to -// std::thread / std::function / std::chrono when we support C++11. +// boost::thread / boost::chrono should be ported to std::thread / std::chrono +// when we support C++11. // -#include #include #include #include @@ -40,7 +39,7 @@ class CScheduler { ~CScheduler(); - typedef boost::function Function; + typedef std::function Function; // Call func at/after time t void schedule(Function f, boost::chrono::system_clock::time_point t); diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 8a1a3413b0..405c9679bf 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -75,8 +74,8 @@ class TorControlReply class TorControlConnection { public: - typedef boost::function ConnectionCB; - typedef boost::function ReplyHandlerCB; + typedef std::function ConnectionCB; + typedef std::function ReplyHandlerCB; /** Create a new TorControlConnection. */ @@ -107,9 +106,9 @@ class TorControlConnection boost::signals2::signal async_handler; private: /** Callback when ready for use */ - boost::function connected; + std::function connected; /** Callback when connection lost */ - boost::function disconnected; + std::function disconnected; /** Libevent event base */ struct event_base *base; /** Connection to control socket */ diff --git a/src/torcontrol.h b/src/torcontrol.h index 977dfe3682..f0b5569caa 100644 --- a/src/torcontrol.h +++ b/src/torcontrol.h @@ -10,7 +10,6 @@ #include -#include #include #include From 075ea40e8a3802ead84a78a6fe0fdd3ffeb7e100 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Jul 2023 12:53:40 -0400 Subject: [PATCH 366/391] http: Join worker threads before deleting work queue This prevents a potential race condition if control flow ends up in `ShutdownHTTPServer` before the thread gets to `queue->Run()`, deleting the work queue while workers are still going to use it. Meant to fix https://github.com/bitcoin/bitcoin/issues/12362. --- src/httpserver.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 089e4d044d..22ce1795de 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -462,6 +462,7 @@ bool UpdateHTTPServerLogging(bool enable) { std::thread threadHTTP; std::future threadResult; +static std::vector g_thread_http_workers; bool StartHTTPServer() { @@ -473,8 +474,7 @@ bool StartHTTPServer() threadHTTP = std::thread(std::move(task), eventBase, eventHTTP); for (int i = 0; i < rpcThreads; i++) { - std::thread rpc_worker(HTTPWorkQueueRun, workQueue); - rpc_worker.detach(); + g_thread_http_workers.emplace_back(HTTPWorkQueueRun, workQueue); } return true; } @@ -500,6 +500,10 @@ void StopHTTPServer() if (workQueue) { LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n"); workQueue->WaitExit(); + for (auto& thread: g_thread_http_workers) { + thread.join(); + } + g_thread_http_workers.clear(); delete workQueue; workQueue = nullptr; } From 1cc30477da0e77af0237b9f1dbf4bc1e09ef3942 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Jul 2023 12:55:54 -0400 Subject: [PATCH 367/391] http: Remove WaitExit from WorkQueue This function, which waits for all threads to exit, is no longer needed now that threads are joined instead. --- src/httpserver.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 22ce1795de..c454999508 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -101,8 +101,7 @@ class WorkQueue numThreads(0) { } - /** Precondition: worker threads have all stopped - * (call WaitExit) + /** Precondition: worker threads have all stopped (they have been joined). */ ~WorkQueue() { @@ -143,14 +142,6 @@ class WorkQueue running = false; cond.notify_all(); } - /** Wait for worker threads to exit */ - void WaitExit() - { - std::unique_lock lock(cs); - while (numThreads > 0) - cond.wait(lock); - } - /** Return current depth of queue */ size_t Depth() { @@ -499,7 +490,6 @@ void StopHTTPServer() LogPrint(BCLog::HTTP, "Stopping HTTP server\n"); if (workQueue) { LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n"); - workQueue->WaitExit(); for (auto& thread: g_thread_http_workers) { thread.join(); } From 97bf07b3ccad9ac6cac8e88ce93de7933b3bb8ea Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 17 Jul 2023 12:57:40 -0400 Subject: [PATCH 368/391] http: Remove numThreads and ThreadCounter The HTTP worker thread counter, as well as the RAII object that was used to maintain it, is unused now, so can be removed. --- src/httpserver.cpp | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index c454999508..3eda8cd890 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -75,30 +75,10 @@ class WorkQueue std::deque> queue; bool running; size_t maxDepth; - int numThreads; - - /** RAII object to keep track of number of running worker threads */ - class ThreadCounter - { - public: - WorkQueue &wq; - ThreadCounter(WorkQueue &w): wq(w) - { - std::lock_guard lock(wq.cs); - wq.numThreads += 1; - } - ~ThreadCounter() - { - std::lock_guard lock(wq.cs); - wq.numThreads -= 1; - wq.cond.notify_all(); - } - }; public: WorkQueue(size_t _maxDepth) : running(true), - maxDepth(_maxDepth), - numThreads(0) + maxDepth(_maxDepth) { } /** Precondition: worker threads have all stopped (they have been joined). @@ -120,7 +100,6 @@ class WorkQueue /** Thread function */ void Run() { - ThreadCounter count(*this); while (true) { std::unique_ptr i; { From 86942fda0b9db93d86f64a2e0e6504d787e81628 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 20 Jul 2023 14:45:35 -0400 Subject: [PATCH 369/391] rpc: make `getwalletinfo` balances match `getbalances` format --- src/wallet/rpcwallet.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 73186509b6..75928b90c5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2075,9 +2075,14 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total PRCY balance of the wallet\n" - " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in PRCY\n" - " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in PRCY\n" + " \"balances\": (string) A json array of balances\n" + " {\n" + " \"total\": (numeric) the total balance of the wallet in PRCY\n" + " \"spendable\": (numeric) the total spendable balance of the wallet in PRCY\n" + " \"pending\": (numeric) the total pending balance of the wallet in PRCY\n" + " \"immature\": (numeric) the total immature balance of the wallet in PRCY\n" + " \"locked\": (numeric) the total locked balance of the wallet in PRCY\n" + " },\n" " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" @@ -2092,9 +2097,13 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); obj.pushKV("walletversion", pwalletMain->GetVersion()); - obj.pushKV("balance", ValueFromAmount(pwalletMain->GetBalance())); - obj.pushKV("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())); - obj.pushKV("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance())); + UniValue balances(UniValue::VOBJ); + balances.pushKV("total", ValueFromAmount(pwalletMain->GetBalance())); + balances.pushKV("spendable", ValueFromAmount(pwalletMain->GetSpendableBalance())); + balances.pushKV("pending", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())); + balances.pushKV("immature", ValueFromAmount(pwalletMain->GetImmatureBalance())); + balances.pushKV("locked", ValueFromAmount(pwalletMain->GetLockedCoins())); + obj.pushKV("balances", balances); obj.pushKV("txcount", (int)pwalletMain->mapWallet.size()); obj.pushKV("keypoololdest", pwalletMain->GetOldestKeyPoolTime()); obj.pushKV("keypoolsize", (int)pwalletMain->GetKeyPoolSize()); From 360afc8465a3b3aa47f80956db3cbc6004aef859 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sat, 22 Jul 2023 00:39:53 -0400 Subject: [PATCH 370/391] depends: libcurl 8.2.0 --- depends/packages/libcurl.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk index 4099e3972a..264cfd31d2 100644 --- a/depends/packages/libcurl.mk +++ b/depends/packages/libcurl.mk @@ -1,9 +1,9 @@ package=libcurl -$(package)_version=8.1.2 +$(package)_version=8.2.0 $(package)_dependencies=openssl $(package)_download_path=https://curl.haxx.se/download $(package)_file_name=curl-$($(package)_version).tar.xz -$(package)_sha256_hash=31b1118eb8bfd43cd95d9a3f146f814ff874f6ed3999b29d94f4d1e7dbac5ef6 +$(package)_sha256_hash=2859ec79e2cd96e976a99493547359b8001af1d1e21f3a3a3b846544ef54500f $(package)_config_opts=--disable-shared --enable-static --prefix=$(host_prefix) --host=$(HOST) --with-openssl $(package)_config_opts+=--disable-manual --disable-ntlm-wb --with-random=/dev/urandom $(package)_config_opts+=--disable-curldebug --disable-libcurl-option --disable-ldap --disable-ldaps From e232691d6b0d0f2a2fb9e58eb16f5b38501de7e5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sat, 22 Jul 2023 00:46:43 -0400 Subject: [PATCH 371/391] depends: xcb-proto 1.15.2 Resolves build failures under Python 3.12, i.e building on rawhide: ```bash make[3]: Nothing to be done for 'install-exec-am'. /usr/bin/mkdir -p '/bitcoin/depends/work/staging/aarch64-unknown-linux-gnu/xcb_proto/1.14.1-4a91ac9dc41/bitcoin/depends/aarch64-unknown-linux-gnu/lib/python3.12/site-packages/xcbgen' /usr/bin/install -c -m 644 __init__.py error.py expr.py align.py matcher.py state.py xtypes.py '/bitcoin/depends/work/staging/aarch64-unknown-linux-gnu/xcb_proto/1.14.1-4a91ac9dc41/bitcoin/depends/aarch64-unknown-linux-gnu/lib/python3.12/site-packages/xcbgen' Traceback (most recent call last): File "", line 2, in ModuleNotFoundError: No module named 'imp' make[3]: *** [Makefile:271: install-pkgpythonPYTHON] Error 1 ``` `imp` was removed in 3.12: https://docs.python.org/3/library/imp.html. --- depends/packages/xcb_proto.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk index 9be822506d..6e1c5a10a8 100644 --- a/depends/packages/xcb_proto.mk +++ b/depends/packages/xcb_proto.mk @@ -1,8 +1,8 @@ package=xcb_proto -$(package)_version=1.14.1 +$(package)_version=1.15.2 $(package)_download_path=https://xorg.freedesktop.org/archive/individual/proto $(package)_file_name=xcb-proto-$($(package)_version).tar.xz -$(package)_sha256_hash=f04add9a972ac334ea11d9d7eb4fc7f8883835da3e4859c9afa971efdf57fcc3 +$(package)_sha256_hash=7072beb1f680a2fe3f9e535b797c146d22528990c72f63ddb49d2f350a3653ed define $(package)_config_cmds $($(package)_autoconf) From 7d8743150cfd918a9d91724a341bd2f6e02ce059 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Tue, 25 Jul 2023 09:27:34 -0400 Subject: [PATCH 372/391] init: add option to manually set rescan height on startup --- src/init.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index f2a3605373..adb33edc32 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -443,6 +443,7 @@ std::string HelpMessage(HelpMessageMode mode) CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); + strUsage += HelpMessageOpt("-rescanheight", _("Rescan the block chain from the specified height when rescan=1 on startup")); strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); @@ -1685,6 +1686,15 @@ bool AppInit2(bool isDaemon) if (GetBoolArg("-rescan", false)) { pindexRescan = chainActive.Genesis(); + + int rescanHeight = GetArg("-rescanheight", 0); + if (rescanHeight > 0) { + if (rescanHeight > chainActive.Tip()->nHeight) { + pindexRescan = chainActive.Tip(); + } else { + pindexRescan = chainActive[rescanHeight]; + } + } } else { CWalletDB walletdb(strWalletFile); CBlockLocator locator; From bdd46abf2b7c4c60133e3189978ff7a0deb4e23c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 28 Jul 2023 19:55:15 -0400 Subject: [PATCH 373/391] depends: expat 2.5.0 --- depends/packages/expat.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index bb203d06f8..f2e16da315 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,8 +1,8 @@ package=expat -$(package)_version=2.4.8 +$(package)_version=2.5.0 $(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_$(subst .,_,$($(package)_version))/ $(package)_file_name=$(package)-$($(package)_version).tar.xz -$(package)_sha256_hash=f79b8f904b749e3e0d20afeadecf8249c55b2e32d4ebb089ae378df479dcaf25 +$(package)_sha256_hash=ef2420f0232c087801abf705e89ae65f6257df6b7931d37846a193ef2e8cdcbe # -D_DEFAULT_SOURCE defines __USE_MISC, which exposes additional # definitions in endian.h, which are required for a working From de68471baeb50e4a19e0ec970ab94c87fec318b5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Sun, 30 Jul 2023 23:53:32 -0400 Subject: [PATCH 374/391] depends: libcurl 8.2.1 --- depends/packages/libcurl.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk index 264cfd31d2..49b7080dd7 100644 --- a/depends/packages/libcurl.mk +++ b/depends/packages/libcurl.mk @@ -1,9 +1,9 @@ package=libcurl -$(package)_version=8.2.0 +$(package)_version=8.2.1 $(package)_dependencies=openssl $(package)_download_path=https://curl.haxx.se/download $(package)_file_name=curl-$($(package)_version).tar.xz -$(package)_sha256_hash=2859ec79e2cd96e976a99493547359b8001af1d1e21f3a3a3b846544ef54500f +$(package)_sha256_hash=dd322f6bd0a20e6cebdfd388f69e98c3d183bed792cf4713c8a7ef498cba4894 $(package)_config_opts=--disable-shared --enable-static --prefix=$(host_prefix) --host=$(HOST) --with-openssl $(package)_config_opts+=--disable-manual --disable-ntlm-wb --with-random=/dev/urandom $(package)_config_opts+=--disable-curldebug --disable-libcurl-option --disable-ldap --disable-ldaps From 27732387695f6f9d65dbd6d38aa033c3e533f3c2 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 21 Jul 2023 17:27:31 -0400 Subject: [PATCH 375/391] qt: update ` getHttpsJson` to use headers and pointers --- src/curl_json.cpp | 43 ++++++++++++++++++++++------------------- src/curl_json.h | 10 +++++++--- src/qt/overviewpage.cpp | 9 ++++----- src/qt/overviewpage.h | 5 ++--- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/src/curl_json.cpp b/src/curl_json.cpp index 3aeffbda23..0bff43737b 100644 --- a/src/curl_json.cpp +++ b/src/curl_json.cpp @@ -7,24 +7,17 @@ #include -JsonDownload downloadedJSON; - static size_t writer(char *in, size_t size, size_t nmemb, std::string *out) { out->append((char*)in, size * nmemb); return size * nmemb; } -void getHttpsJson(std::string url) +void getHttpsJson(std::string url, JsonDownload* reply, int headerType) { - { - JsonDownload newDownload; - downloadedJSON = newDownload; - } - - downloadedJSON.failed = false; - downloadedJSON.complete = false; - downloadedJSON.URL = url; + reply->failed = false; + reply->complete = false; + reply->URL = url; std::string response_string; curl_global_init(CURL_GLOBAL_ALL); @@ -32,15 +25,26 @@ void getHttpsJson(std::string url) CURLcode res; struct curl_slist *headers=NULL; // init to NULL is important + switch(headerType) { + case STANDARD_HEADERS: + headers = curl_slist_append(headers, "Accept: application/json"); + break; + case CG_HEADERS: + headers = curl_slist_append(headers, "Accept: application/json"); + break; + case GITHUB_HEADERS: + headers = curl_slist_append(headers, "Accept: application/vnd.github+json"); + headers = curl_slist_append(headers, "User-Agent: PRCYcoin"); + break; + } - headers = curl_slist_append(headers, "Accept: application/json"); headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, "charset: utf-8"); curl = curl_easy_init(); if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, downloadedJSON.URL.c_str()); + curl_easy_setopt(curl, CURLOPT_URL, reply->URL.c_str()); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); @@ -54,19 +58,18 @@ void getHttpsJson(std::string url) /* ask for the content-type */ res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct); if((CURLE_OK == res) && ct) { - downloadedJSON.response = response_string; - downloadedJSON.failed = false; - downloadedJSON.complete = true; + reply->response = std::move(response_string); + reply->failed = false; + reply->complete = true; } } else { - downloadedJSON.response = ""; - downloadedJSON.failed = false; - downloadedJSON.complete = false; + reply->response = ""; + reply->failed = false; + reply->complete = false; } } /* always cleanup */ curl_easy_cleanup(curl); curl_slist_free_all(headers); curl_global_cleanup(); - } diff --git a/src/curl_json.h b/src/curl_json.h index b92c11698b..d8f9b9c442 100644 --- a/src/curl_json.h +++ b/src/curl_json.h @@ -19,6 +19,12 @@ struct CurlProgress { CURL *curl; }; +enum JsonDownloadHeaders { + STANDARD_HEADERS, + CG_HEADERS, + GITHUB_HEADERS +}; + struct JsonDownload { std::string URL = ""; std::string response = ""; @@ -28,9 +34,7 @@ struct JsonDownload { CurlProgress prog; }; -extern JsonDownload downloadedJSON; - static size_t writer(char *in, size_t size, size_t nmemb, std::string *out); -extern void getHttpsJson(std::string url); +extern void getHttpsJson(std::string url, JsonDownload* reply, int headerType); #endif diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index bfd79d407c..be7c96e24c 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -126,8 +126,7 @@ OverviewPage::OverviewPage(QWidget* parent) : QDialog(parent, Qt::WindowSystemMe // Init getCurrencyValueInterval updateJSONtimer = new QTimer(this); updateGUItimer = new QTimer(this); - manager = new QNetworkAccessManager(this); - reply = nullptr; + cgReply = new JsonDownload; connect(updateJSONtimer, SIGNAL(timeout()), SLOT(getCurrencyValue())); connect(updateGUItimer, SIGNAL(timeout()), SLOT(setCurrencyValue())); @@ -583,7 +582,7 @@ void OverviewPage::getCurrencyValue() ui->labelCurrencyValue->setText(""); return; } - getHttpsJson("https://api.coingecko.com/api/v3/simple/price?ids=prcy-coin&vs_currencies=" + defaultCurrency.toStdString() + "&include_market_cap=false&include_24hr_vol=false&include_24hr_change=false&include_last_updated_at=false"); + getHttpsJson("https://api.coingecko.com/api/v3/simple/price?ids=prcy-coin&vs_currencies=" + defaultCurrency.toStdString() + "&include_market_cap=false&include_24hr_vol=false&include_24hr_change=false&include_last_updated_at=false", cgReply, CG_HEADERS); } void OverviewPage::setCurrencyValue() @@ -609,10 +608,10 @@ void OverviewPage::setCurrencyValue() defaultCurrencySymbol = "XAG"; } - if (downloadedJSON.failed == false && downloadedJSON.complete == true) { + if (cgReply->failed == false && cgReply->complete == true) { try { // Parse data - QJsonDocument jsonDocument(QJsonDocument::fromJson(downloadedJSON.response.c_str())); + QJsonDocument jsonDocument(QJsonDocument::fromJson(cgReply->response.c_str())); const QJsonObject item = jsonDocument.object(); const QJsonObject currency = item["prcy-coin"].toObject(); auto currencyValue = currency[defaultCurrency.toLower()].toDouble(); diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 72873df406..c17346fb00 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -6,6 +6,7 @@ #define BITCOIN_QT_OVERVIEWPAGE_H #include "amount.h" +#include "curl_json.h" #include #include @@ -13,7 +14,6 @@ #include #include #include -#include class ClientModel; class TransactionFilterProxy; @@ -94,8 +94,7 @@ public Q_SLOTS: // Check Currency Value via CoinGecko.com API QTimer* updateJSONtimer; QTimer* updateGUItimer; - QNetworkAccessManager* manager; - QNetworkReply* reply; + JsonDownload* cgReply; private Q_SLOTS: void updateDisplayUnit(); From 557a3db6cd4449845ed2db44da53f8f2de66de37 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 21 Jul 2023 17:45:44 -0400 Subject: [PATCH 376/391] qt: use libcurl for check for updates --- src/qt/bitcoingui.cpp | 30 ++++++++++++++---------------- src/qt/bitcoingui.h | 6 ++++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 88858a2bb4..5b50ec322d 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -60,8 +60,9 @@ #include #include #include -#include -#include +#include +#include +#include #define BASE_WINDOW_WIDTH 800 #define BASE_WINDOW_HEIGHT 768 @@ -254,6 +255,8 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle* networkStyle, QWidget* parent) : QMai timerStakingIcon->start(10000); setStakingStatus(); } + + gitReply = new JsonDownload; checkForUpdatesClicked(); } @@ -983,27 +986,22 @@ void BitcoinGUI::openToolkitClicked() void BitcoinGUI::checkForUpdatesClicked() { LogPrintf("Check For Updates: Checking...\n"); - QUrl serviceUrl = QUrl("https://raw.githubusercontent.com/PRCYCoin/PRCYCoin/master/version.txt"); - QNetworkAccessManager *manager = new QNetworkAccessManager(this); - connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*))); - QNetworkRequest request; - request.setUrl(serviceUrl); - QNetworkReply* reply = manager->get(request); + getHttpsJson("https://api.github.com/repos/prcycoin/prcycoin/releases/latest", gitReply, GITHUB_HEADERS); } -void BitcoinGUI::serviceRequestFinished(QNetworkReply* reply) +void BitcoinGUI::checkForUpdatesFinished() { QString currentVersion = QString::number(CLIENT_VERSION_MAJOR) + "." + QString::number(CLIENT_VERSION_MINOR)+ "." + QString::number(CLIENT_VERSION_REVISION)+ "." + QString::number(CLIENT_VERSION_BUILD); QString currentVersionStripped = currentVersion.remove(QChar('.'), Qt::CaseInsensitive); - reply->deleteLater(); - if(reply->error() == QNetworkReply::NoError) { - QByteArray data = reply->readAll(); - QString dataStream = data.trimmed(); - QString availableVersionStripped = dataStream.remove(QChar('.'), Qt::CaseInsensitive); + if(gitReply->failed == false && gitReply->complete == true) { + QJsonDocument response = QJsonDocument::fromJson(gitReply->response.c_str()); + const QJsonObject jsonObject = response.object(); + QString availableVersion = jsonObject["tag_name"].toString(); + QString availableVersionStripped = availableVersion.replace(".", ""); if (availableVersionStripped > currentVersionStripped) { LogPrintf("Check For Updates: Update Available!\n"); QMessageBox::StandardButton msgReply; - msgReply = QMessageBox::question(this, "Wallet Update Available!", "Wallet update available.\n\nWould you like to go to the GitHub Releases page to download v" + data.trimmed() + "?", QMessageBox::Yes|QMessageBox::No); + msgReply = QMessageBox::question(this, "Wallet Update Available!", "Wallet update available.\n\nWould you like to go to the GitHub Releases page to download v" + availableVersion + "?", QMessageBox::Yes|QMessageBox::No); if (msgReply == QMessageBox::Yes) { QDesktopServices::openUrl(QUrl("https://github.com/PRCYCoin/PRCYCoin/releases/latest")); } else { @@ -1021,7 +1019,7 @@ void BitcoinGUI::serviceRequestFinished(QNetworkReply* reply) } } else { LogPrintf("Check For Updates: Error!\n"); - QByteArray error = reply->readAll(); + QByteArray error = gitReply->response.c_str(); GUIUtil::showMessageBox( tr("Error"), tr("Error checking for updates.\n\n" + error), diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 98c686f2ff..b4ce01ee69 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -10,6 +10,7 @@ #endif #include "amount.h" +#include "curl_json.h" #include #include @@ -19,7 +20,6 @@ #include #include #include -#include class ClientModel; class NetworkStyle; @@ -186,6 +186,8 @@ class BitcoinGUI : public QMainWindow /** Disconnect core signals from GUI client */ void unsubscribeFromCoreSignals(); + JsonDownload* gitReply; + Q_SIGNALS: /** Signal raised when a URI was entered or dragged to the GUI */ void receivedURI(const QString& uri); @@ -282,7 +284,7 @@ private Q_SLOTS: void openDexClicked(); void openToolkitClicked(); void checkForUpdatesClicked(); - void serviceRequestFinished(QNetworkReply* reply); + void checkForUpdatesFinished(); #ifndef Q_OS_MAC /** Handle tray icon clicked */ void trayIconActivated(QSystemTrayIcon::ActivationReason reason); From 4903946b65171dac26ab91892a7d771c5721e6f5 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 21 Jul 2023 17:56:37 -0400 Subject: [PATCH 377/391] qt: improve check for updates code - add check for "Mandatory" and prepend it to MsgBox - rename isStartup to isClicked (allows more flexible usage) - split up functions - use try/catch - various other improvements --- src/qt/bitcoingui.cpp | 87 +++++++++++++++++++++++++++---------------- src/qt/bitcoingui.h | 4 +- 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 5b50ec322d..78a9cebe57 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -257,7 +257,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle* networkStyle, QWidget* parent) : QMai } gitReply = new JsonDownload; - checkForUpdatesClicked(); + checkForUpdates(); } BitcoinGUI::~BitcoinGUI() @@ -984,48 +984,71 @@ void BitcoinGUI::openToolkitClicked() } void BitcoinGUI::checkForUpdatesClicked() +{ + checkForUpdates(true); +} + +void BitcoinGUI::checkForUpdates(bool isClicked) { LogPrintf("Check For Updates: Checking...\n"); getHttpsJson("https://api.github.com/repos/prcycoin/prcycoin/releases/latest", gitReply, GITHUB_HEADERS); + checkForUpdatesFinished(isClicked); } -void BitcoinGUI::checkForUpdatesFinished() -{ - QString currentVersion = QString::number(CLIENT_VERSION_MAJOR) + "." + QString::number(CLIENT_VERSION_MINOR)+ "." + QString::number(CLIENT_VERSION_REVISION)+ "." + QString::number(CLIENT_VERSION_BUILD); - QString currentVersionStripped = currentVersion.remove(QChar('.'), Qt::CaseInsensitive); - if(gitReply->failed == false && gitReply->complete == true) { - QJsonDocument response = QJsonDocument::fromJson(gitReply->response.c_str()); - const QJsonObject jsonObject = response.object(); - QString availableVersion = jsonObject["tag_name"].toString(); - QString availableVersionStripped = availableVersion.replace(".", ""); - if (availableVersionStripped > currentVersionStripped) { - LogPrintf("Check For Updates: Update Available!\n"); - QMessageBox::StandardButton msgReply; - msgReply = QMessageBox::question(this, "Wallet Update Available!", "Wallet update available.\n\nWould you like to go to the GitHub Releases page to download v" + availableVersion + "?", QMessageBox::Yes|QMessageBox::No); - if (msgReply == QMessageBox::Yes) { - QDesktopServices::openUrl(QUrl("https://github.com/PRCYCoin/PRCYCoin/releases/latest")); +void BitcoinGUI::checkForUpdatesFinished(bool isClicked) +{ + if (!gitReply->failed && gitReply->complete) { + try { + QString currentVersion = QString("%1.%2.%3.%4").arg(CLIENT_VERSION_MAJOR).arg(CLIENT_VERSION_MINOR).arg(CLIENT_VERSION_REVISION).arg(CLIENT_VERSION_BUILD); + QString currentVersionStripped = currentVersion.replace(".", ""); + + QJsonDocument response = QJsonDocument::fromJson(gitReply->response.c_str()); + const QJsonObject jsonObject = response.object(); + QString gitStrVersion = jsonObject["tag_name"].toString(); + QString gitStrVersionStripped = gitStrVersion.replace(".", ""); + + QString gitStrName = jsonObject["name"].toString(); + bool isMandatory = gitStrName.contains("Mandatory", Qt::CaseInsensitive); + + if (gitStrVersionStripped > currentVersionStripped) { + LogPrintf("Check For Updates: Update Available!\n"); + + QString updateMessage = tr("Wallet update available.\n\nWould you like to go to the GitHub Releases page to download v") + gitStrVersion + "?"; + if (isMandatory) { + updateMessage.prepend(tr("Mandatory ")); + } + + QMessageBox::StandardButton msgReply = QMessageBox::question(this, + tr("Wallet Update Available!"), + updateMessage, + QMessageBox::Yes | QMessageBox::No); + + if (msgReply == QMessageBox::Yes) { + QDesktopServices::openUrl(QUrl("https://github.com/PRCYCoin/PRCYCoin/releases/latest")); + } else { + LogPrintf("Check For Updates: Update Available, but declined by user.\n"); + return; + } } else { - LogPrintf("Check For Updates: Update Available, but declined by user.\n"); - return; - } - } else { - LogPrintf("Check For Updates: No update available.\n"); - if (!isStartup) { - GUIUtil::showMessageBox( - tr("No Update Available"), - tr("No update available.\n\nYour wallet is up to date."), - QMessageBox::Information); + LogPrintf("Check For Updates: No update available.\n"); + if (isClicked) { + GUIUtil::showMessageBox(tr("No Update Available"), + tr("No update available.\n\nYour wallet is up to date."), + QMessageBox::Information); + } } + } catch (const std::exception& e) { + LogPrintf("Github Releases JSON Parsing error: %s\n", e.what()); } } else { LogPrintf("Check For Updates: Error!\n"); - QByteArray error = gitReply->response.c_str(); - GUIUtil::showMessageBox( - tr("Error"), - tr("Error checking for updates.\n\n" + error), - QMessageBox::Critical); + if (isClicked) { + QString error = gitReply->response.c_str(); + GUIUtil::showMessageBox(tr("Error"), + tr("Error checking for updates.\n\n") + error, + QMessageBox::Critical); + } } - isStartup = false; } #ifdef ENABLE_WALLET diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index b4ce01ee69..357f939c2f 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -71,7 +71,6 @@ class BitcoinGUI : public QMainWindow #endif // ENABLE_WALLET bool enableWallet; bool fMultiSend = false; - bool isStartup = true; protected: void changeEvent(QEvent* e); @@ -284,7 +283,8 @@ private Q_SLOTS: void openDexClicked(); void openToolkitClicked(); void checkForUpdatesClicked(); - void checkForUpdatesFinished(); + void checkForUpdates(bool isClicked = false); + void checkForUpdatesFinished(bool isClicked); #ifndef Q_OS_MAC /** Handle tray icon clicked */ void trayIconActivated(QSystemTrayIcon::ActivationReason reason); From c74484dcaf1445a9e22f71e0c0c71b9fdc772bf0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 21 Jul 2023 17:58:10 -0400 Subject: [PATCH 378/391] build: delete version.txt no longer needed for version checks as we use GitHub API --- version.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 version.txt diff --git a/version.txt b/version.txt deleted file mode 100644 index df5bd0ff56..0000000000 --- a/version.txt +++ /dev/null @@ -1 +0,0 @@ -2.0.0.6 From 50402404a46879d839402789cd6fa0e97e50f1e3 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 15 Sep 2023 00:47:54 -0400 Subject: [PATCH 379/391] depends: zlib 1.3 --- depends/packages/zlib.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/zlib.mk b/depends/packages/zlib.mk index 7d929b65f6..a6f3bc1ff0 100644 --- a/depends/packages/zlib.mk +++ b/depends/packages/zlib.mk @@ -1,8 +1,8 @@ package=zlib -$(package)_version=1.2.13 +$(package)_version=1.3 $(package)_download_path=https://www.zlib.net $(package)_file_name=$(package)-$($(package)_version).tar.xz -$(package)_sha256_hash=d14c38e313afc35a9a8760dadf26042f51ea0f5d154b0630a31da0540107fb98 +$(package)_sha256_hash=8a9ba2898e1d0d774eca6ba5b4627a11e5588ba85c8851336eb38de4683050a7 define $(package)_set_vars $(package)_config_opts= CC="$($(package)_cc)" From 021a5e869dc7b1f3bc75cdcb3db46565a9b5aee7 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Thu, 3 Aug 2023 17:06:09 -0400 Subject: [PATCH 380/391] depends: libcurl 8.3.0 --- depends/packages/libcurl.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk index 49b7080dd7..4974072e1c 100644 --- a/depends/packages/libcurl.mk +++ b/depends/packages/libcurl.mk @@ -1,9 +1,9 @@ package=libcurl -$(package)_version=8.2.1 +$(package)_version=8.3.0 $(package)_dependencies=openssl $(package)_download_path=https://curl.haxx.se/download $(package)_file_name=curl-$($(package)_version).tar.xz -$(package)_sha256_hash=dd322f6bd0a20e6cebdfd388f69e98c3d183bed792cf4713c8a7ef498cba4894 +$(package)_sha256_hash=376d627767d6c4f05105ab6d497b0d9aba7111770dd9d995225478209c37ea63 $(package)_config_opts=--disable-shared --enable-static --prefix=$(host_prefix) --host=$(HOST) --with-openssl $(package)_config_opts+=--disable-manual --disable-ntlm-wb --with-random=/dev/urandom $(package)_config_opts+=--disable-curldebug --disable-libcurl-option --disable-ldap --disable-ldaps From 90453be15462cf4835b8dca88b4b31741f1ade0c Mon Sep 17 00:00:00 2001 From: lyricidal Date: Wed, 11 Oct 2023 08:35:13 -0400 Subject: [PATCH 381/391] depends: libcurl 8.4.0 --- depends/packages/libcurl.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk index 4974072e1c..d2065ec90b 100644 --- a/depends/packages/libcurl.mk +++ b/depends/packages/libcurl.mk @@ -1,9 +1,9 @@ package=libcurl -$(package)_version=8.3.0 +$(package)_version=8.4.0 $(package)_dependencies=openssl $(package)_download_path=https://curl.haxx.se/download $(package)_file_name=curl-$($(package)_version).tar.xz -$(package)_sha256_hash=376d627767d6c4f05105ab6d497b0d9aba7111770dd9d995225478209c37ea63 +$(package)_sha256_hash=16c62a9c4af0f703d28bda6d7bbf37ba47055ad3414d70dec63e2e6336f2a82d $(package)_config_opts=--disable-shared --enable-static --prefix=$(host_prefix) --host=$(HOST) --with-openssl $(package)_config_opts+=--disable-manual --disable-ntlm-wb --with-random=/dev/urandom $(package)_config_opts+=--disable-curldebug --disable-libcurl-option --disable-ldap --disable-ldaps From 0593d5e69042e30d7fecabfe75812aea4fa9bd78 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 6 Nov 2023 12:45:22 -0500 Subject: [PATCH 382/391] build: copy config.{guess,sub} post autogen in zmq package Otherwise our config.guess and config.sub will be copied over. This problem has been masked by the fact that modern systems ship with versions that recognise all the triplets we use (namely arm64-apple-darwin). However building on ubuntu 20.04 surfaces the issue. Fixes https://github.com/bitcoin/bitcoin/issues/26420. --- depends/packages/zeromq.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index c74ae15b31..4707d172e7 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -21,12 +21,12 @@ endef define $(package)_preprocess_cmds patch -p1 < $($(package)_patch_dir)/remove_libstd_link.patch && \ - patch -p1 < $($(package)_patch_dir)/netbsd_kevent_void.patch && \ - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub config + patch -p1 < $($(package)_patch_dir)/netbsd_kevent_void.patch endef define $(package)_config_cmds ./autogen.sh && \ + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub config && \ $($(package)_autoconf) endef From eca481e52f7c604eaad55a4d41610492dfb6af38 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 6 Nov 2023 12:46:58 -0500 Subject: [PATCH 383/391] depends: zeromq 4.3.5 https://github.com/zeromq/libzmq/releases/tag/v4.3.5 --- depends/packages/zeromq.mk | 9 ++- .../patches/zeromq/netbsd_kevent_void.patch | 57 ------------------- 2 files changed, 4 insertions(+), 62 deletions(-) delete mode 100644 depends/patches/zeromq/netbsd_kevent_void.patch diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 4707d172e7..a090493b3f 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,9 +1,9 @@ package=zeromq -$(package)_version=4.3.4 +$(package)_version=4.3.5 $(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=c593001a89f5a85dd2ddf564805deb860e02471171b3f204944857336295c3e5 -$(package)_patches=remove_libstd_link.patch netbsd_kevent_void.patch +$(package)_sha256_hash=6653ef5910f17954861fe72332e68b03ca6e4d9c7160eb3a8de5a5a913bfab43 +$(package)_patches=remove_libstd_link.patch define $(package)_set_vars $(package)_config_opts = --without-docs --disable-shared --disable-valgrind @@ -20,8 +20,7 @@ define $(package)_set_vars endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/remove_libstd_link.patch && \ - patch -p1 < $($(package)_patch_dir)/netbsd_kevent_void.patch + patch -p1 < $($(package)_patch_dir)/remove_libstd_link.patch endef define $(package)_config_cmds diff --git a/depends/patches/zeromq/netbsd_kevent_void.patch b/depends/patches/zeromq/netbsd_kevent_void.patch deleted file mode 100644 index 845c6bdda6..0000000000 --- a/depends/patches/zeromq/netbsd_kevent_void.patch +++ /dev/null @@ -1,57 +0,0 @@ -commit 129137d5182967dbfcfec66bad843df2a992a78f -Author: fanquake -Date: Mon Jan 3 20:13:33 2022 +0800 - - problem: kevent udata is now void* on NetBSD Current (10) - - solution: check for the intptr_t variant in configure. - -diff --git a/configure.ac b/configure.ac -index 1a571291..402f8b86 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -307,6 +307,27 @@ case "${host_os}" in - if test "x$libzmq_netbsd_has_atomic" = "xno"; then - AC_DEFINE(ZMQ_FORCE_MUTEXES, 1, [Force to use mutexes]) - fi -+ # NetBSD Current (to become 10) has changed the type of udata in it's -+ # kevent struct from intptr_t to void * to align with darwin and other -+ # BSDs, see upstream commit: -+ # https://github.com/NetBSD/src/commit/e5ead823eb916b56589d2c6c560dbcfe4a2d0afc -+ AC_MSG_CHECKING([whether kevent udata type is intptr_t]) -+ AC_LANG_PUSH([C++]) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM( -+ [[#include -+ #include -+ #include ]], -+ [[struct kevent ev; -+ intptr_t udata; -+ EV_SET(&ev, 0, 0, EV_ADD, 0, 0, udata); -+ return 0;]])], -+ [libzmq_netbsd_kevent_udata_intptr_t=yes], -+ [libzmq_netbsd_kevent_udata_intptr_t=no]) -+ AC_LANG_POP([C++]) -+ AC_MSG_RESULT([$libzmq_netbsd_kevent_udata_intptr_t]) -+ if test "x$libzmq_netbsd_kevent_udata_intptr_t" = "xyes"; then -+ AC_DEFINE(ZMQ_NETBSD_KEVENT_UDATA_INTPTR_T, 1, [kevent udata type is intptr_t]) -+ fi - ;; - *openbsd*|*bitrig*) - # Define on OpenBSD to enable all library features -diff --git a/src/kqueue.cpp b/src/kqueue.cpp -index 53d82ac4..a6a7a7f2 100644 ---- a/src/kqueue.cpp -+++ b/src/kqueue.cpp -@@ -46,9 +46,9 @@ - #include "i_poll_events.hpp" - #include "likely.hpp" - --// NetBSD defines (struct kevent).udata as intptr_t, everyone else --// as void *. --#if defined ZMQ_HAVE_NETBSD -+// NetBSD up to version 9 defines (struct kevent).udata as intptr_t, -+// everyone else as void *. -+#if defined ZMQ_HAVE_NETBSD && defined(ZMQ_NETBSD_KEVENT_UDATA_INTPTR_T) - #define kevent_udata_t intptr_t - #else - #define kevent_udata_t void * From ea5ef7461e7696f2dadc802e96fc232cbfd3074a Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 1 Jan 2024 10:30:13 -0500 Subject: [PATCH 384/391] depends: libcurl 8.5.0 --- depends/packages/libcurl.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk index d2065ec90b..95fb6e7adf 100644 --- a/depends/packages/libcurl.mk +++ b/depends/packages/libcurl.mk @@ -1,9 +1,9 @@ package=libcurl -$(package)_version=8.4.0 +$(package)_version=8.5.0 $(package)_dependencies=openssl $(package)_download_path=https://curl.haxx.se/download $(package)_file_name=curl-$($(package)_version).tar.xz -$(package)_sha256_hash=16c62a9c4af0f703d28bda6d7bbf37ba47055ad3414d70dec63e2e6336f2a82d +$(package)_sha256_hash=42ab8db9e20d8290a3b633e7fbb3cec15db34df65fd1015ef8ac1e4723750eeb $(package)_config_opts=--disable-shared --enable-static --prefix=$(host_prefix) --host=$(HOST) --with-openssl $(package)_config_opts+=--disable-manual --disable-ntlm-wb --with-random=/dev/urandom $(package)_config_opts+=--disable-curldebug --disable-libcurl-option --disable-ldap --disable-ldaps From e5000e34901a5dd302c5891b55ede1c7661add21 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 2 Feb 2024 08:47:39 -0500 Subject: [PATCH 385/391] depends: zlib 1.3.1 --- depends/packages/zlib.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/zlib.mk b/depends/packages/zlib.mk index a6f3bc1ff0..c5361e3463 100644 --- a/depends/packages/zlib.mk +++ b/depends/packages/zlib.mk @@ -1,8 +1,8 @@ package=zlib -$(package)_version=1.3 +$(package)_version=1.3.1 $(package)_download_path=https://www.zlib.net $(package)_file_name=$(package)-$($(package)_version).tar.xz -$(package)_sha256_hash=8a9ba2898e1d0d774eca6ba5b4627a11e5588ba85c8851336eb38de4683050a7 +$(package)_sha256_hash=38ef96b8dfe510d42707d9c781877914792541133e1870841463bfa73f883e32 define $(package)_set_vars $(package)_config_opts= CC="$($(package)_cc)" From fd2f39b05cc9b5d4611c4241f41c2d391c4830f0 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Fri, 2 Feb 2024 08:49:09 -0500 Subject: [PATCH 386/391] [Trivial] Update copyright for 2024 --- COPYING | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/COPYING b/COPYING index f765ab8bf2..cc796c3b01 100644 --- a/COPYING +++ b/COPYING @@ -2,7 +2,7 @@ Copyright (c) 2009-2015 Bitcoin Developers Copyright (c) 2014-2015 Dash Developers Copyright (c) 2015-2018 PIVX Developers Copyright (c) 2018-2020 DAPScoin Developers -Copyright (c) 2020-2023 PRCYcoin Developers +Copyright (c) 2020-2024 PRCYcoin Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/configure.ac b/configure.ac index 832e7501e5..fdd5819b98 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ define(_CLIENT_VERSION_REVISION, 0) define(_CLIENT_VERSION_BUILD, 6) define(_CLIENT_VERSION_RC, 0) define(_CLIENT_VERSION_IS_RELEASE, true) -define(_COPYRIGHT_YEAR, 2023) +define(_COPYRIGHT_YEAR, 2024) AC_INIT([PRCYcoin],m4_join([.], _CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MINOR, _CLIENT_VERSION_REVISION, m4_if(_CLIENT_VERSION_BUILD, [0], [], _CLIENT_VERSION_BUILD))m4_if(_CLIENT_VERSION_RC, [0], [], [rc]_CLIENT_VERSION_RC),[https://github.com/PRCYCoin/PRCYCoin/issues],[prcycoin],[https://www.prcycoin.com]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/prcycoin-config.h]) From 279f84942c9844d0baf9a91b1f2441e9075e6c24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 21:00:37 +0000 Subject: [PATCH 387/391] Bump actions/download-artifact from 1 to 4.1.7 in /.github/workflows Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 1 to 4.1.7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v1...v4.1.7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/prcy-build-factory-debug.yml | 12 ++++++------ .github/workflows/prcy-build-factory-ubuntu20.yml | 14 +++++++------- .github/workflows/prcy-build-factory.yml | 14 +++++++------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/prcy-build-factory-debug.yml b/.github/workflows/prcy-build-factory-debug.yml index ad6add0f4c..d9d796e537 100644 --- a/.github/workflows/prcy-build-factory-debug.yml +++ b/.github/workflows/prcy-build-factory-debug.yml @@ -65,7 +65,7 @@ jobs: TEST_LOG_ARTIFACT_DIR: test-logs steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -110,7 +110,7 @@ jobs: ARTIFACT_DIR: prcycoin-win64-debug steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -160,7 +160,7 @@ jobs: SDK_URL: https://bitcoincore.org/depends-sources/sdks steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -222,7 +222,7 @@ jobs: ARTIFACT_DIR: prcycoin-aarch64-linux-debug steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -266,7 +266,7 @@ jobs: ARTIFACT_DIR: prcycoin-arm32-debug steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -310,7 +310,7 @@ jobs: ARTIFACT_DIR: prcycoin-riscv64-debug steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml index 9e173eaa8c..8791ba46a6 100644 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ b/.github/workflows/prcy-build-factory-ubuntu20.yml @@ -60,7 +60,7 @@ jobs: TEST_LOG_ARTIFACT_DIR: test-logs steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -113,7 +113,7 @@ jobs: TEST_LOG_ARTIFACT_DIR: test-logs steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -164,7 +164,7 @@ jobs: ARTIFACT_DIR: prcycoin-win64 steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -220,7 +220,7 @@ jobs: SDK_URL: https://bitcoincore.org/depends-sources/sdks steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -288,7 +288,7 @@ jobs: ARTIFACT_DIR: prcycoin-aarch64-linux steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -338,7 +338,7 @@ jobs: ARTIFACT_DIR: prcycoin-arm32 steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -388,7 +388,7 @@ jobs: ARTIFACT_DIR: prcycoin-riscv64 steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 40d5bf5765..04771eb202 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -59,7 +59,7 @@ jobs: TEST_LOG_ARTIFACT_DIR: test-logs steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -112,7 +112,7 @@ jobs: TEST_LOG_ARTIFACT_DIR: test-logs steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -163,7 +163,7 @@ jobs: ARTIFACT_DIR: prcycoin-win64 steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -219,7 +219,7 @@ jobs: SDK_URL: https://bitcoincore.org/depends-sources/sdks steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -287,7 +287,7 @@ jobs: ARTIFACT_DIR: prcycoin-aarch64-linux steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -337,7 +337,7 @@ jobs: ARTIFACT_DIR: prcycoin-arm32 steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -387,7 +387,7 @@ jobs: ARTIFACT_DIR: prcycoin-riscv64 steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives From 54a5ec4b1d59e137f46532bfbe8d2c1999640883 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 25 Aug 2025 11:11:30 -0400 Subject: [PATCH 388/391] Update Action workflows --- .../workflows/prcy-build-factory-debug.yml | 14 +- .../workflows/prcy-build-factory-ubuntu20.yml | 432 ------------------ .github/workflows/prcy-build-factory.yml | 37 +- 3 files changed, 26 insertions(+), 457 deletions(-) delete mode 100644 .github/workflows/prcy-build-factory-ubuntu20.yml diff --git a/.github/workflows/prcy-build-factory-debug.yml b/.github/workflows/prcy-build-factory-debug.yml index d9d796e537..90c99dda6a 100644 --- a/.github/workflows/prcy-build-factory-debug.yml +++ b/.github/workflows/prcy-build-factory-debug.yml @@ -10,7 +10,7 @@ env: jobs: create-source-distribution: name: Create Source Distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 if: "contains(github.event.head_commit.message, '[debug]')" env: ARTIFACT_DIR: source @@ -59,7 +59,7 @@ jobs: build-x86_64-linux: name: Build for x86 Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-x86_64-linux-debug TEST_LOG_ARTIFACT_DIR: test-logs @@ -105,7 +105,7 @@ jobs: build-win64: name: Build for Win64 needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-win64-debug steps: @@ -154,7 +154,7 @@ jobs: build-osx64: name: Build for MacOSX needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-macosx-debug SDK_URL: https://bitcoincore.org/depends-sources/sdks @@ -217,7 +217,7 @@ jobs: build-aarch64-linux: name: Build for ARM Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-aarch64-linux-debug steps: @@ -261,7 +261,7 @@ jobs: build-arm-linux-gnueabihf: name: Build for ARM Linux 32bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-arm32-debug steps: @@ -305,7 +305,7 @@ jobs: build-riscv64-linux-gnu: name: Build for RISC-V 64-bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-riscv64-debug steps: diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml deleted file mode 100644 index 8791ba46a6..0000000000 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ /dev/null @@ -1,432 +0,0 @@ -# Copyright (c) 2018-2020 The Veil developers -# Copyright (c) 2020 The DAPS Project -# Copyright (c) 2020 The PRivaCY Coin Developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -name: Github Actions CI for PRCY (Ubuntu 20) -on: [push, pull_request] -env: - SOURCE_ARTIFACT: source -jobs: - create-source-distribution: - name: Create Source Distribution - runs-on: ubuntu-20.04 - if: "contains(github.event.head_commit.message, '[focal]')" - env: - ARTIFACT_DIR: source - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Create Version Variable - run: | - export VERSION=$(cat version.txt | sed 's/[^0-9,.]//g') - export TAG=v${VERSION} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - echo "TAG=${TAG}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Print Variables - run: | - echo "VERSION=${VERSION}" - echo "TAG=${TAG}" - printenv - - name: Create Distribution Tarball - run: | - mkdir -p $ARTIFACT_DIR - touch prcycoin.tar.gz - tar -czf prcycoin.tar.gz --exclude=prcycoin.tar.gz . - - name: Download Dependencies - run: make -C depends download - - name: Create Dependencies Tarball - run: tar -czf depends.tar.gz depends - - name: Prepare Files for Artifact - run: | - mv depends.tar.gz prcycoin.tar.gz $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - path: ${{ env.ARTIFACT_DIR }} - build-linux: - name: Build for Linux - needs: create-source-distribution - runs-on: ubuntu-18.04 - env: - ARTIFACT_DIR: prcycoin-linux - TEST_LOG_ARTIFACT_DIR: test-logs - steps: - - name: Getting Source - uses: actions/download-artifact@v4.1.7 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - # May need qt and protobuf to configure qt and include prcycoin-qt.1 in distribution - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y libssl1.0-dev libevent-dev libboost-all-dev - sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode-dev - sudo add-apt-repository ppa:pivx/pivx - sudo apt-get update - sudo apt-get install -y libdb4.8-dev libdb4.8++-dev - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - strip $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-linux - path: ${{ env.ARTIFACT_DIR }} - build-x86_64-linux: - name: Build for x86 Linux 64bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-x86_64-linux - TEST_LOG_ARTIFACT_DIR: test-logs - steps: - - name: Getting Source - uses: actions/download-artifact@v4.1.7 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y python3-zmq - - name: Build Dependencies - run: make -C depends -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-pc-linux-gnu) --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - strip $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-x86_64-linux - path: ${{ env.ARTIFACT_DIR }} - build-win64: - name: Build for Win64 - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-win64 - steps: - - name: Getting Source - uses: actions/download-artifact@v4.1.7 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y g++-mingw-w64-x86-64 gcc-mingw-w64-x86-64 nsis - - name: Switch MinGW GCC and G++ to POSIX Threading - run: | - sudo update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix - sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix - - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=x86_64-w64-mingw32 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-w64-mingw32) --enable-upnp-default - make -j$(nproc) - make deploy -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - strip $SOURCE_ARTIFACT/src/{prcycoin-cli.exe,prcycoin-tx.exe,prcycoind.exe,qt/prcycoin-qt.exe} - mv $SOURCE_ARTIFACT/{prcycoin-*.exe,src/prcycoin-cli.exe,src/prcycoin-tx.exe,src/prcycoind.exe,src/qt/prcycoin-qt.exe} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-win64 - path: ${{ env.ARTIFACT_DIR }} - build-osx64: - name: Build for MacOSX - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-macosx - SDK_URL: https://bitcoincore.org/depends-sources/sdks - steps: - - name: Getting Source - uses: actions/download-artifact@v4.1.7 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - export XCODE_VERSION=11.3.1 - export XCODE_BUILD_ID=11C505 - echo "VERSION=${VERSION}" >> $GITHUB_ENV - echo "XCODE_VERSION=${XCODE_VERSION}" >> $GITHUB_ENV - echo "XCODE_BUILD_ID=${XCODE_BUILD_ID}" >> $GITHUB_ENV - export OSX_SDK_BASENAME=Xcode-$XCODE_VERSION-$XCODE_BUILD_ID-extracted-SDK-with-libcxx-headers.tar.gz - export OSX_SDK_PATH=depends/sdk-sources/$OSX_SDK_BASENAME - echo "OSX_SDK_BASENAME=${OSX_SDK_BASENAME}" >> $GITHUB_ENV - echo "OSX_SDK_PATH=${OSX_SDK_PATH}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y python3-setuptools libcap-dev librsvg2-bin libtiff-tools - - name: Get macOS SDK - run: | - mkdir -p depends/sdk-sources depends/SDKs - if [ -n "${{ env.XCODE_VERSION }}" ] && [ ! -f "${{ env.OSX_SDK_PATH }}" ]; then - curl --location --fail "${{ env.SDK_URL }}/${{ env.OSX_SDK_BASENAME }}" -o "${{ env.OSX_SDK_PATH }}" - fi - if [ -n "${{ env.XCODE_VERSION }}" ] && [ -f "${{ env.OSX_SDK_PATH }}" ]; then - tar -C "depends/SDKs" -xf "${{ env.OSX_SDK_PATH }}" - fi - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build Dependencies - run: make -C depends HOST=x86_64-apple-darwin16 -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin16) --enable-upnp-default - make -j$(nproc) - make deploy -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - mv $SOURCE_ARTIFACT/{*.dmg,src/prcycoin-cli,src/prcycoin-tx,src/prcycoind,src/qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-macosx - path: ${{ env.ARTIFACT_DIR }} - build-aarch64-linux: - name: Build for ARM Linux 64bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-aarch64-linux - steps: - - name: Getting Source - uses: actions/download-artifact@v4.1.7 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y python3-zmq g++-aarch64-linux-gnu - - name: Build Dependencies - run: make -C depends HOST=aarch64-linux-gnu -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/aarch64-linux-gnu) --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-aarch64-linux - path: ${{ env.ARTIFACT_DIR }} - build-arm-linux-gnueabihf: - name: Build for ARM Linux 32bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-arm32 - steps: - - name: Getting Source - uses: actions/download-artifact@v4.1.7 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y g++-arm-linux-gnueabihf - - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=arm-linux-gnueabihf - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/arm-linux-gnueabihf) --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-arm32 - path: ${{ env.ARTIFACT_DIR }} - build-riscv64-linux-gnu: - name: Build for RISC-V 64-bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-riscv64 - steps: - - name: Getting Source - uses: actions/download-artifact@v4.1.7 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y g++-riscv64-linux-gnu binutils-riscv64-linux-gnu - - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu NO_QT=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/riscv64-linux-gnu) --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-riscv64 - path: ${{ env.ARTIFACT_DIR }} diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 04771eb202..8791ba46a6 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -3,14 +3,15 @@ # Copyright (c) 2020 The PRivaCY Coin Developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -name: Github Actions CI for PRCY +name: Github Actions CI for PRCY (Ubuntu 20) on: [push, pull_request] env: SOURCE_ARTIFACT: source jobs: create-source-distribution: name: Create Source Distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 + if: "contains(github.event.head_commit.message, '[focal]')" env: ARTIFACT_DIR: source steps: @@ -106,7 +107,7 @@ jobs: build-x86_64-linux: name: Build for x86 Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-x86_64-linux TEST_LOG_ARTIFACT_DIR: test-logs @@ -138,10 +139,10 @@ jobs: - name: Build Dependencies run: make -C depends -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY + - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-pc-linux-gnu) --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-pc-linux-gnu) --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -158,7 +159,7 @@ jobs: build-win64: name: Build for Win64 needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-win64 steps: @@ -196,7 +197,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-w64-mingw32) --enable-upnp-default --enable-reduce-exports + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-w64-mingw32) --enable-upnp-default make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -213,7 +214,7 @@ jobs: build-osx64: name: Build for MacOSX needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-macosx SDK_URL: https://bitcoincore.org/depends-sources/sdks @@ -266,7 +267,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin16) --enable-upnp-default --enable-reduce-exports + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin16) --enable-upnp-default make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -282,7 +283,7 @@ jobs: build-aarch64-linux: name: Build for ARM Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-aarch64-linux steps: @@ -316,7 +317,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/aarch64-linux-gnu) --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/aarch64-linux-gnu) --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -332,7 +333,7 @@ jobs: build-arm-linux-gnueabihf: name: Build for ARM Linux 32bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-arm32 steps: @@ -366,7 +367,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/arm-linux-gnueabihf) --enable-glibc-back-compat --enable-reduce-exports --enable-upnp-default CXXFLAGS=-Wno-psabi + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/arm-linux-gnueabihf) --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -382,7 +383,7 @@ jobs: build-riscv64-linux-gnu: name: Build for RISC-V 64-bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-riscv64 steps: @@ -411,19 +412,19 @@ jobs: sudo apt-get update sudo apt-get install -y g++-riscv64-linux-gnu binutils-riscv64-linux-gnu - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu + run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu NO_QT=1 working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/riscv64-linux-gnu) --enable-reduce-exports --enable-upnp-default + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/riscv64-linux-gnu) --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact run: | mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR + chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} + mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} $ARTIFACT_DIR - name: Upload Artifact uses: actions/upload-artifact@v1 with: From 9f66d67fe54f2d02d9b26b50b5bb3658fc81a39b Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 25 Aug 2025 12:38:56 -0400 Subject: [PATCH 389/391] Remove focal commit message condition from workflow Eliminates the conditional check for '[focal]' in commit messages, ensuring the 'Create Source Distribution' job always runs regardless of commit message content. --- .github/workflows/prcy-build-factory.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 8791ba46a6..71ad712154 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -11,7 +11,6 @@ jobs: create-source-distribution: name: Create Source Distribution runs-on: ubuntu-20.04 - if: "contains(github.event.head_commit.message, '[focal]')" env: ARTIFACT_DIR: source steps: From 06dd42638b02fcae89154b657dd6419416b842c9 Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 25 Aug 2025 12:44:10 -0400 Subject: [PATCH 390/391] Update upload-artifact action to v4 in CI workflow Replaces deprecated actions/upload-artifact@v1 with actions/upload-artifact@v4 across all jobs in prcy-build-factory.yml for improved reliability and support. --- .github/workflows/prcy-build-factory.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 71ad712154..048330c837 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -46,7 +46,7 @@ jobs: run: | mv depends.tar.gz prcycoin.tar.gz $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: ${{ env.SOURCE_ARTIFACT }} path: ${{ env.ARTIFACT_DIR }} @@ -99,7 +99,7 @@ jobs: chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-linux path: ${{ env.ARTIFACT_DIR }} @@ -151,7 +151,7 @@ jobs: chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-x86_64-linux path: ${{ env.ARTIFACT_DIR }} @@ -206,7 +206,7 @@ jobs: strip $SOURCE_ARTIFACT/src/{prcycoin-cli.exe,prcycoin-tx.exe,prcycoind.exe,qt/prcycoin-qt.exe} mv $SOURCE_ARTIFACT/{prcycoin-*.exe,src/prcycoin-cli.exe,src/prcycoin-tx.exe,src/prcycoind.exe,src/qt/prcycoin-qt.exe} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-win64 path: ${{ env.ARTIFACT_DIR }} @@ -275,7 +275,7 @@ jobs: mkdir -p $ARTIFACT_DIR mv $SOURCE_ARTIFACT/{*.dmg,src/prcycoin-cli,src/prcycoin-tx,src/prcycoind,src/qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-macosx path: ${{ env.ARTIFACT_DIR }} @@ -325,7 +325,7 @@ jobs: chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-aarch64-linux path: ${{ env.ARTIFACT_DIR }} @@ -375,7 +375,7 @@ jobs: chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-arm32 path: ${{ env.ARTIFACT_DIR }} @@ -425,7 +425,7 @@ jobs: chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-riscv64 path: ${{ env.ARTIFACT_DIR }} From eaaf3554ae913f9d6fac0be27185b6dfe87bd41e Mon Sep 17 00:00:00 2001 From: lyricidal Date: Mon, 25 Aug 2025 13:05:55 -0400 Subject: [PATCH 391/391] Update CI workflows to use Ubuntu 22.04 Changed all GitHub Actions jobs in prcy-build-factory.yml to run on ubuntu-22.04 instead of ubuntu-20.04 for improved compatibility and support. --- .github/workflows/prcy-build-factory.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 048330c837..b7246ca25b 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -10,7 +10,7 @@ env: jobs: create-source-distribution: name: Create Source Distribution - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: source steps: @@ -106,7 +106,7 @@ jobs: build-x86_64-linux: name: Build for x86 Linux 64bit needs: create-source-distribution - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-x86_64-linux TEST_LOG_ARTIFACT_DIR: test-logs @@ -158,7 +158,7 @@ jobs: build-win64: name: Build for Win64 needs: create-source-distribution - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-win64 steps: @@ -213,7 +213,7 @@ jobs: build-osx64: name: Build for MacOSX needs: create-source-distribution - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-macosx SDK_URL: https://bitcoincore.org/depends-sources/sdks @@ -282,7 +282,7 @@ jobs: build-aarch64-linux: name: Build for ARM Linux 64bit needs: create-source-distribution - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-aarch64-linux steps: @@ -332,7 +332,7 @@ jobs: build-arm-linux-gnueabihf: name: Build for ARM Linux 32bit needs: create-source-distribution - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-arm32 steps: @@ -382,7 +382,7 @@ jobs: build-riscv64-linux-gnu: name: Build for RISC-V 64-bit needs: create-source-distribution - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-riscv64 steps: