aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xci/test/00_setup_env_win64.sh2
-rw-r--r--configure.ac18
-rw-r--r--depends/Makefile2
-rw-r--r--depends/packages/packages.mk6
-rw-r--r--depends/packages/zeromq.mk8
-rw-r--r--depends/patches/zeromq/netbsd_kevent_void.patch57
-rw-r--r--src/fs.h2
-rw-r--r--src/txmempool.h22
-rw-r--r--src/util/system.cpp5
-rw-r--r--src/validation.cpp42
-rw-r--r--src/wallet/load.cpp2
-rwxr-xr-xtest/functional/wallet_multiwallet.py2
12 files changed, 123 insertions, 45 deletions
diff --git a/ci/test/00_setup_env_win64.sh b/ci/test/00_setup_env_win64.sh
index 44b6eb7ae3..6619852423 100755
--- a/ci/test/00_setup_env_win64.sh
+++ b/ci/test/00_setup_env_win64.sh
@@ -13,4 +13,4 @@ export DPKG_ADD_ARCH="i386"
export PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64 wine32 file"
export RUN_FUNCTIONAL_TESTS=false
export GOAL="deploy"
-export BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests --disable-external-signer"
+export BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests"
diff --git a/configure.ac b/configure.ac
index 5a6b54a1ae..bef3973996 100644
--- a/configure.ac
+++ b/configure.ac
@@ -321,7 +321,7 @@ AC_ARG_ENABLE([werror],
AC_ARG_ENABLE([external-signer],
[AS_HELP_STRING([--enable-external-signer],[compile external signer support (default is yes, requires Boost::Process)])],
[use_external_signer=$enableval],
- [use_external_signer=yes])
+ [use_external_signer=auto])
AC_ARG_ENABLE([lto],
[AS_HELP_STRING([--enable-lto],[build using LTO (default is no)])],
@@ -1415,7 +1415,21 @@ if test "$use_boost" = "yes"; then
fi
if test "$use_external_signer" != "no"; then
- AC_DEFINE([ENABLE_EXTERNAL_SIGNER], [], [Define if external signer support is enabled])
+ case $host in
+ *mingw*)
+ dnl Boost Process uses Boost Filesystem when targeting Windows. Also,
+ dnl since Boost 1.71.0, Process does not work with mingw-w64 without
+ dnl workarounds. See 67669ab425b52a2b6be3d2f3b3b7e3939b676a2c.
+ if test "$use_external_signer" = "yes"; then
+ AC_MSG_ERROR([External signing is not supported on Windows])
+ fi
+ use_external_signer="no";
+ ;;
+ *)
+ use_external_signer="yes"
+ AC_DEFINE([ENABLE_EXTERNAL_SIGNER], [1], [Define if external signer support is enabled])
+ ;;
+ esac
fi
AM_CONDITIONAL([ENABLE_EXTERNAL_SIGNER], [test "$use_external_signer" = "yes"])
diff --git a/depends/Makefile b/depends/Makefile
index d2a3c35f1e..73e2af5501 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -137,7 +137,7 @@ include packages/packages.mk
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)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
$(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)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
-qrencode_packages_$(NO_QR) = $(qrencode_packages)
+qrencode_packages_$(NO_QR) = $(qrencode_$(host_os)_packages)
qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) $(qrencode_packages_)
diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk
index 77866c8e7a..4c66b3bdb9 100644
--- a/depends/packages/packages.mk
+++ b/depends/packages/packages.mk
@@ -1,10 +1,12 @@
packages:=boost libevent
-qrencode_packages = qrencode
+qrencode_linux_packages = qrencode
+qrencode_android_packages = qrencode
+qrencode_darwin_packages = qrencode
+qrencode_mingw32_packages = qrencode
qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig libxkbcommon libxcb_util libxcb_util_render libxcb_util_keysyms libxcb_util_image libxcb_util_wm
qt_android_packages=qt
-
qt_darwin_packages=qt
qt_mingw32_packages=qt
diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk
index 9798248c61..94e92431a2 100644
--- a/depends/packages/zeromq.mk
+++ b/depends/packages/zeromq.mk
@@ -1,9 +1,9 @@
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)_patches=remove_libstd_link.patch
+$(package)_sha256_hash=c593001a89f5a85dd2ddf564805deb860e02471171b3f204944857336295c3e5
+$(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
@@ -17,10 +17,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 <fanquake@gmail.com>
+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 <sys/types.h>
++ #include <sys/event.h>
++ #include <sys/time.h>]],
++ [[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 *
diff --git a/src/fs.h b/src/fs.h
index 9f18794539..bc36636084 100644
--- a/src/fs.h
+++ b/src/fs.h
@@ -88,7 +88,7 @@ static inline auto quoted(const std::string& s)
// Allow safe path append operations.
static inline path operator+(path p1, path p2)
{
- p1 += std::move(p2);
+ p1 += static_cast<boost::filesystem::path&&>(p2);
return p1;
}
diff --git a/src/txmempool.h b/src/txmempool.h
index b8c508fd90..e025dafd91 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -312,16 +312,6 @@ public:
}
};
-struct update_lock_points
-{
- explicit update_lock_points(const LockPoints& _lp) : lp(_lp) { }
-
- void operator() (CTxMemPoolEntry &e) { e.UpdateLockPoints(lp); }
-
-private:
- const LockPoints& lp;
-};
-
// Multi_index tag names
struct descendant_score {};
struct entry_time {};
@@ -599,10 +589,14 @@ public:
void addUnchecked(const CTxMemPoolEntry& entry, setEntries& setAncestors, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
void removeRecursive(const CTransaction& tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs);
- /** After reorg, check if mempool entries are now non-final, premature coinbase spends, or have
- * invalid lockpoints. Update lockpoints and remove entries (and descendants of entries) that
- * are no longer valid. */
- void removeForReorg(CChain& chain, std::function<bool(txiter)> check_final_and_mature) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
+ /** After reorg, filter the entries that would no longer be valid in the next block, and update
+ * the entries' cached LockPoints if needed. The mempool does not have any knowledge of
+ * consensus rules. It just appplies the callable function and removes the ones for which it
+ * returns true.
+ * @param[in] filter_final_and_mature Predicate that checks the relevant validation rules
+ * and updates an entry's LockPoints.
+ * */
+ void removeForReorg(CChain& chain, std::function<bool(txiter)> filter_final_and_mature) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
void removeConflicts(const CTransaction& tx) EXCLUSIVE_LOCKS_REQUIRED(cs);
void removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs);
diff --git a/src/util/system.cpp b/src/util/system.cpp
index 8f35b7b6c6..e34cdc7fb9 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -6,11 +6,6 @@
#include <util/system.h>
#ifdef ENABLE_EXTERNAL_SIGNER
-#if defined(WIN32) && !defined(__kernel_entry)
-// A workaround for boost 1.71 incompatibility with mingw-w64 compiler.
-// For details see https://github.com/bitcoin/bitcoin/pull/22348.
-#define __kernel_entry
-#endif
#include <boost/process.hpp>
#endif // ENABLE_EXTERNAL_SIGNER
diff --git a/src/validation.cpp b/src/validation.cpp
index d34ba1d635..fff7cfc07b 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -349,21 +349,37 @@ void CChainState::MaybeUpdateMempoolForReorg(
// the disconnectpool that were added back and cleans up the mempool state.
m_mempool->UpdateTransactionsFromBlock(vHashUpdate);
- const auto check_final_and_mature = [this, flags=STANDARD_LOCKTIME_VERIFY_FLAGS](CTxMemPool::txiter it)
+ // Predicate to use for filtering transactions in removeForReorg.
+ // Checks whether the transaction is still final and, if it spends a coinbase output, mature.
+ // Also updates valid entries' cached LockPoints if needed.
+ // If false, the tx is still valid and its lockpoints are updated.
+ // If true, the tx would be invalid in the next block; remove this entry and all of its descendants.
+ const auto filter_final_and_mature = [this, flags=STANDARD_LOCKTIME_VERIFY_FLAGS](CTxMemPool::txiter it)
EXCLUSIVE_LOCKS_REQUIRED(m_mempool->cs, ::cs_main) {
- bool should_remove = false;
AssertLockHeld(m_mempool->cs);
AssertLockHeld(::cs_main);
const CTransaction& tx = it->GetTx();
+
+ // The transaction must be final.
+ if (!CheckFinalTx(m_chain.Tip(), tx, flags)) return true;
LockPoints lp = it->GetLockPoints();
const bool validLP{TestLockPointValidity(m_chain, lp)};
CCoinsViewMemPool view_mempool(&CoinsTip(), *m_mempool);
- if (!CheckFinalTx(m_chain.Tip(), tx, flags)
- || !CheckSequenceLocks(m_chain.Tip(), view_mempool, tx, flags, &lp, validLP)) {
- // Note if CheckSequenceLocks fails the LockPoints may still be invalid
- // So it's critical that we remove the tx and not depend on the LockPoints.
- should_remove = true;
- } else if (it->GetSpendsCoinbase()) {
+ // CheckSequenceLocks checks if the transaction will be final in the next block to be
+ // created on top of the new chain. We use useExistingLockPoints=false so that, instead of
+ // using the information in lp (which might now refer to a block that no longer exists in
+ // the chain), it will update lp to contain LockPoints relevant to the new chain.
+ if (!CheckSequenceLocks(m_chain.Tip(), view_mempool, tx, flags, &lp, validLP)) {
+ // If CheckSequenceLocks fails, remove the tx and don't depend on the LockPoints.
+ return true;
+ } else if (!validLP) {
+ // If CheckSequenceLocks succeeded, it also updated the LockPoints.
+ // Now update the mempool entry lockpoints as well.
+ m_mempool->mapTx.modify(it, [&lp](CTxMemPoolEntry& e) { e.UpdateLockPoints(lp); });
+ }
+
+ // If the transaction spends any coinbase outputs, it must be mature.
+ if (it->GetSpendsCoinbase()) {
for (const CTxIn& txin : tx.vin) {
auto it2 = m_mempool->mapTx.find(txin.prevout.hash);
if (it2 != m_mempool->mapTx.end())
@@ -372,18 +388,16 @@ void CChainState::MaybeUpdateMempoolForReorg(
assert(!coin.IsSpent());
const auto mempool_spend_height{m_chain.Tip()->nHeight + 1};
if (coin.IsSpent() || (coin.IsCoinBase() && mempool_spend_height - coin.nHeight < COINBASE_MATURITY)) {
- should_remove = true;
- break;
+ return true;
}
}
}
- // CheckSequenceLocks updates lp. Update the mempool entry LockPoints.
- if (!validLP) m_mempool->mapTx.modify(it, update_lock_points(lp));
- return should_remove;
+ // Transaction is still valid and cached LockPoints are updated.
+ return false;
};
// We also need to remove any now-immature transactions
- m_mempool->removeForReorg(m_chain, check_final_and_mature);
+ m_mempool->removeForReorg(m_chain, filter_final_and_mature);
// Re-limit mempool size, in case we added any transactions
LimitMempoolSize(
*m_mempool,
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
index 2d47673705..e6f96074d5 100644
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -29,7 +29,7 @@ bool VerifyWallets(WalletContext& context)
fs::path wallet_dir = fs::PathFromString(args.GetArg("-walletdir", ""));
boost::system::error_code error;
// The canonical path cleans the path, preventing >1 Berkeley environment instances for the same directory
- fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error);
+ fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error).remove_trailing_separator();
if (error || !fs::exists(wallet_dir)) {
chain.initError(strprintf(_("Specified -walletdir \"%s\" does not exist"), fs::PathToString(wallet_dir)));
return false;
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index 0b868dde6c..317121eb68 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -141,7 +141,7 @@ class MultiWalletTest(BitcoinTestFramework):
# should raise rpc error if wallet path can't be created
err_code = -4 if self.options.descriptors else -1
- assert_raises_rpc_error(err_code, "boost::filesystem::create_directory:", self.nodes[0].createwallet, "w8/bad")
+ assert_raises_rpc_error(err_code, "boost::filesystem::create_director", self.nodes[0].createwallet, "w8/bad")
# check that all requested wallets were created
self.stop_node(0)