diff --git a/ci/test/00_setup_env_mac.sh b/ci/test/00_setup_env_mac.sh index 1651c5ec26..9e71da7b82 100755 --- a/ci/test/00_setup_env_mac.sh +++ b/ci/test/00_setup_env_mac.sh @@ -17,7 +17,4 @@ export XCODE_BUILD_ID=15A240d export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" - -# False-positive warning is fixed with clang 17, remove this when that version -# can be used. -export BITCOIN_CONFIG="--with-gui --enable-reduce-exports LDFLAGS=-Wno-error=unused-command-line-argument" +export BITCOIN_CONFIG="--with-gui --enable-reduce-exports" diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index ff1678116d..b3e73bb2b9 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -32,7 +32,7 @@ # See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html for more info. MAX_VERSIONS = { -'GCC': (4,8,0), +'GCC': (4,3,0), 'GLIBC': { lief.ELF.ARCH.x86_64: (2,27), lief.ELF.ARCH.ARM: (2,27), diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash index 28ca23098d..6c912ca748 100644 --- a/contrib/guix/libexec/prelude.bash +++ b/contrib/guix/libexec/prelude.bash @@ -51,7 +51,7 @@ fi time-machine() { # shellcheck disable=SC2086 guix time-machine --url=https://git.savannah.gnu.org/git/guix.git \ - --commit=77386bdbfe6b0c649c05ab37f08051d1ab3e5074 \ + --commit=d5ca4d4fd713a9f7e17e074a1e37dda99bbb09fc \ --cores="$JOBS" \ --keep-failed \ --fallback \ diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 9206973953..7335596107 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -525,5 +525,5 @@ inspecting signatures in Mach-O binaries.") ((string-contains target "-linux-") (list (make-bitcoin-cross-toolchain target))) ((string-contains target "darwin") - (list clang-toolchain-15 binutils cmake-minimal python-signapple zip)) + (list clang-toolchain-17 binutils cmake-minimal python-signapple zip)) (else '()))))) diff --git a/depends/packages/native_libtapi.mk b/depends/packages/native_libtapi.mk index a855c393c6..fb5ab0b4dc 100644 --- a/depends/packages/native_libtapi.mk +++ b/depends/packages/native_libtapi.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=d4d46c64622f13d6938cecf989046d9561011bb59e8ee835f8f39825d $(package)_patches=disable_zlib.patch ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -$(package)_dependencies=native_clang +$(package)_dependencies=native_llvm endif define $(package)_preprocess_cmds diff --git a/depends/packages/native_clang.mk b/depends/packages/native_llvm.mk similarity index 67% rename from depends/packages/native_clang.mk rename to depends/packages/native_llvm.mk index 661b9c2c1c..09994eb012 100644 --- a/depends/packages/native_clang.mk +++ b/depends/packages/native_llvm.mk @@ -1,16 +1,17 @@ -package=native_clang -$(package)_version=15.0.6 +package=native_llvm +$(package)_version=17.0.6 +$(package)_major_version=$(firstword $(subst ., ,$($(package)_version))) $(package)_download_path=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) ifneq (,$(findstring aarch64,$(BUILD))) $(package)_file_name=clang+llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz -$(package)_sha256_hash=8ca4d68cf103da8331ca3f35fe23d940c1b78fb7f0d4763c1c059e352f5d1bec +$(package)_sha256_hash=6dd62762285326f223f40b8e4f2864b5c372de3f7de0731cb7cd55ca5287b75a else -$(package)_file_name=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-18.04.tar.xz -$(package)_sha256_hash=38bc7f5563642e73e69ac5626724e206d6d539fbef653541b34cae0ba9c3f036 +$(package)_file_name=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-22.04.tar.xz +$(package)_sha256_hash=884ee67d647d77e58740c1e645649e29ae9e8a6fe87c1376be0f3a30f3cc9ab3 endif define $(package)_stage_cmds - mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_version)/include && \ + mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_major_version)/include && \ mkdir -p $($(package)_staging_prefix_dir)/bin && \ mkdir -p $($(package)_staging_prefix_dir)/include/llvm-c && \ cp bin/clang $($(package)_staging_prefix_dir)/bin/ && \ @@ -20,5 +21,5 @@ define $(package)_stage_cmds cp include/llvm-c/ExternC.h $($(package)_staging_prefix_dir)/include/llvm-c && \ cp include/llvm-c/lto.h $($(package)_staging_prefix_dir)/include/llvm-c && \ cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ - cp -r lib/clang/$($(package)_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_version)/include/ + cp -r lib/clang/$($(package)_major_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_major_version)/include/ endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index dd55c939cb..fb52fd4499 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -33,7 +33,7 @@ ifneq ($(build_os),darwin) darwin_native_packages += native_cctools native_libtapi ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -darwin_native_packages+= native_clang +darwin_native_packages+= native_llvm endif endif diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index ecf3334aa5..5608e5f073 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -22,8 +22,8 @@ $(package)_patches += fast_fixed_dtoa_no_optimize.patch $(package)_patches += guix_cross_lib_path.patch $(package)_patches += fix-macos-linker.patch $(package)_patches += memory_resource.patch +$(package)_patches += utc_from_string_no_optimize.patch $(package)_patches += windows_lto.patch -$(package)_patches += fix-minimum-macos.patch $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) $(package)_qttranslations_sha256_hash=a31785948c640b7c66d9fe2db4993728ca07f64e41c560b3625ad191b276ff20 @@ -240,7 +240,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)/fix-minimum-macos.patch && \ patch -p1 -i $($(package)_patch_dir)/fix-macos-linker.patch && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ @@ -251,6 +250,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/memory_resource.patch && \ patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch && \ patch -p1 -i $($(package)_patch_dir)/duplicate_lcqpafonts.patch && \ + patch -p1 -i $($(package)_patch_dir)/utc_from_string_no_optimize.patch && \ patch -p1 -i $($(package)_patch_dir)/fast_fixed_dtoa_no_optimize.patch && \ patch -p1 -i $($(package)_patch_dir)/guix_cross_lib_path.patch && \ patch -p1 -i $($(package)_patch_dir)/windows_lto.patch && \ diff --git a/depends/patches/qt/fix-minimum-macos.patch b/depends/patches/qt/fix-minimum-macos.patch deleted file mode 100644 index ecaa2ca308..0000000000 --- a/depends/patches/qt/fix-minimum-macos.patch +++ /dev/null @@ -1,18 +0,0 @@ -Ensure that Qt handles the minimum macOS version properly - -This patch can be dropped for LLVM Clang 17+, after commit -https://github.com/llvm/llvm-project/commit/c8e2dd8c6f490b68e41fe663b44535a8a21dfeab - - ---- a/qtbase/src/corelib/global/qsystemdetection.h -+++ b/qtbase/src/corelib/global/qsystemdetection.h -@@ -220,6 +220,9 @@ - # include - # include - # -+# undef __MAC_OS_X_VERSION_MIN_REQUIRED -+# define __MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_MIN_REQUIRED -+# - # ifdef Q_OS_MACOS - # if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6 - # undef __MAC_OS_X_VERSION_MIN_REQUIRED diff --git a/depends/patches/qt/utc_from_string_no_optimize.patch b/depends/patches/qt/utc_from_string_no_optimize.patch new file mode 100644 index 0000000000..533ef59b37 --- /dev/null +++ b/depends/patches/qt/utc_from_string_no_optimize.patch @@ -0,0 +1,84 @@ +Modify optimisation flags for various functions. +This fixes non-determinism issues in the asm produced for +these function when cross-compiling on x86_64 and aarch64 for +the arm64-apple-darwin HOST. + +--- a/qtbase/src/corelib/itemmodels/qitemselectionmodel.cpp ++++ b/qtbase/src/corelib/itemmodels/qitemselectionmodel.cpp +@@ -1078,9 +1078,9 @@ void QItemSelectionModelPrivate::_q_layoutChanged(const QList &parents = QList(), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint); +- void _q_layoutChanged(const QList &parents = QList(), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint); ++ __attribute__ ((optnone)) void _q_layoutChanged(const QList &parents = QList(), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint); + + inline void remove(QList &r) + { + +--- a/qtbase/src/corelib/time/qdatetimeparser_p.h ++++ b/qtbase/src/corelib/time/qdatetimeparser_p.h +@@ -215,7 +215,7 @@ private: + : value(ok == Invalid ? -1 : val), used(read), zeroes(zs), state(ok) + {} + }; +- ParsedSection parseSection(const QDateTime ¤tValue, int sectionIndex, ++ __attribute__ ((optnone)) ParsedSection parseSection(const QDateTime ¤tValue, int sectionIndex, + int offset, QString *text) const; + int findMonth(const QString &str1, int monthstart, int sectionIndex, + int year, QString *monthName = nullptr, int *used = nullptr) const; + +--- a/qtbase/src/corelib/time/qtimezoneprivate_p.h ++++ b/qtbase/src/corelib/time/qtimezoneprivate_p.h +@@ -191,7 +191,7 @@ public: + virtual ~QUtcTimeZonePrivate(); + + // Fall-back for UTC[+-]\d+(:\d+){,2} IDs. +- static qint64 offsetFromUtcString(const QByteArray &id); ++ static __attribute__ ((optnone)) qint64 offsetFromUtcString(const QByteArray &id); + + QUtcTimeZonePrivate *clone() const override; + +--- a/qtbase/src/widgets/widgets/qcalendarwidget.cpp ++++ b/qtbase/src/widgets/widgets/qcalendarwidget.cpp +@@ -329,13 +329,13 @@ class QCalendarYearValidator : public QCalendarDateSectionValidator + + public: + QCalendarYearValidator(); +- virtual Section handleKey(int key) override; ++ __attribute__ ((optnone)) virtual Section handleKey(int key) override; + virtual QDate applyToDate(QDate date, QCalendar cal) const override; + virtual void setDate(QDate date, QCalendar cal) override; + virtual QString text() const override; + virtual QString text(QDate date, QCalendar cal, int repeat) const override; + private: +- int pow10(int n); ++ __attribute__ ((optnone)) int pow10(int n); + int m_pos; + int m_year; + int m_oldYear; diff --git a/src/.clang-format b/src/.clang-format index 2e5d5c6449..f20e5ee2d4 100644 --- a/src/.clang-format +++ b/src/.clang-format @@ -43,5 +43,7 @@ SpacesInAngles: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false +BreakBeforeConceptDeclarations: Always +RequiresExpressionIndentation: OuterScope Standard: c++20 UseTab: Never diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index aeb3797392..328399c4ad 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -8,6 +8,7 @@ #include #include #include // For CTransactionRef +#include #include #include @@ -260,7 +261,7 @@ class Chain virtual void getPackageLimits(unsigned int& limit_ancestor_count, unsigned int& limit_descendant_count) = 0; //! Check if transaction will pass the mempool's chain limits. - virtual bool checkChainLimits(const CTransactionRef& tx) = 0; + virtual util::Result checkChainLimits(const CTransactionRef& tx) = 0; //! Estimate smart fee. virtual CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc = nullptr) = 0; diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 2e547e8e2c..6963e928fe 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -702,14 +703,13 @@ class ChainImpl : public Chain limit_ancestor_count = limits.ancestor_count; limit_descendant_count = limits.descendant_count; } - bool checkChainLimits(const CTransactionRef& tx) override + util::Result checkChainLimits(const CTransactionRef& tx) override { - if (!m_node.mempool) return true; + if (!m_node.mempool) return {}; LockPoints lp; CTxMemPoolEntry entry(tx, 0, 0, 0, 0, false, 0, lp); LOCK(m_node.mempool->cs); - std::string err_string; - return m_node.mempool->CheckPackageLimits({tx}, entry.GetTxSize(), err_string); + return m_node.mempool->CheckPackageLimits({tx}, entry.GetTxSize()); } CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc) override { diff --git a/src/policy/feerate.h b/src/policy/feerate.h index 41f4a4d06b..2e50172914 100644 --- a/src/policy/feerate.h +++ b/src/policy/feerate.h @@ -71,6 +71,8 @@ class CFeeRate friend bool operator!=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK != b.nSatoshisPerK; } CFeeRate& operator+=(const CFeeRate& a) { nSatoshisPerK += a.nSatoshisPerK; return *this; } std::string ToString(const FeeEstimateMode& fee_estimate_mode = FeeEstimateMode::BTC_KVB) const; + friend CFeeRate operator*(const CFeeRate& f, int a) { return CFeeRate(a * f.nSatoshisPerK); } + friend CFeeRate operator*(int a, const CFeeRate& f) { return CFeeRate(a * f.nSatoshisPerK); } SERIALIZE_METHODS(CFeeRate, obj) { READWRITE(obj.nSatoshisPerK); } }; diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 7e62d75583..c6bc5f8f1d 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -1777,15 +1777,15 @@ std::unique_ptr ParseScript(uint32_t& key_exp_index, SpanIsSane() || node->IsNotSatisfiable()) { // Try to find the first insane sub for better error reporting. auto insane_node = node.get(); diff --git a/src/serialize.h b/src/serialize.h index 263b781f21..19585c630a 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -271,10 +271,9 @@ template inline void Serialize(Stream& s, int32_t a ) { ser_wri template inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); } template inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); } template inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); } -template inline void Serialize(Stream& s, const char (&a)[N]) { s.write(MakeByteSpan(a)); } -template inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(MakeByteSpan(a)); } -template void Serialize(Stream& s, const std::array& a) { (void)/* force byte-type */UCharCast(a.data()); s.write(MakeByteSpan(a)); } -template void Serialize(Stream& s, Span span) { (void)/* force byte-type */UCharCast(span.data()); s.write(AsBytes(span)); } +template void Serialize(Stream& s, const B (&a)[N]) { s.write(MakeByteSpan(a)); } +template void Serialize(Stream& s, const std::array& a) { s.write(MakeByteSpan(a)); } +template void Serialize(Stream& s, Span span) { s.write(AsBytes(span)); } #ifndef CHAR_EQUALS_INT8 template void Unserialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t @@ -288,10 +287,9 @@ template inline void Unserialize(Stream& s, int32_t& a ) { a = template inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); } template inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); } template inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); } -template inline void Unserialize(Stream& s, char (&a)[N]) { s.read(MakeWritableByteSpan(a)); } -template inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(MakeWritableByteSpan(a)); } -template void Unserialize(Stream& s, std::array& a) { (void)/* force byte-type */UCharCast(a.data()); s.read(MakeWritableByteSpan(a)); } -template void Unserialize(Stream& s, Span span) { (void)/* force byte-type */UCharCast(span.data()); s.read(AsWritableBytes(span)); } +template void Unserialize(Stream& s, B (&a)[N]) { s.read(MakeWritableByteSpan(a)); } +template void Unserialize(Stream& s, std::array& a) { s.read(MakeWritableByteSpan(a)); } +template void Unserialize(Stream& s, Span span) { s.read(AsWritableBytes(span)); } template inline void Serialize(Stream& s, bool a) { uint8_t f = a; ser_writedata8(s, f); } template inline void Unserialize(Stream& s, bool& a) { uint8_t f = ser_readdata8(s); a = f; } @@ -755,18 +753,23 @@ template void Serialize(Stream& os, const std::uniq template void Unserialize(Stream& os, std::unique_ptr& p); - /** * If none of the specialized versions above matched, default to calling member function. */ -template -inline void Serialize(Stream& os, const T& a) +template +concept Serializable = requires(T a, Stream s) { a.Serialize(s); }; +template + requires Serializable +void Serialize(Stream& os, const T& a) { a.Serialize(os); } -template -inline void Unserialize(Stream& is, T&& a) +template +concept Unserializable = requires(T a, Stream s) { a.Unserialize(s); }; +template + requires Unserializable +void Unserialize(Stream& is, T&& a) { a.Unserialize(is); } diff --git a/src/span.h b/src/span.h index 2e8da27cde..2c27a54fc7 100644 --- a/src/span.h +++ b/src/span.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #ifdef DEBUG @@ -283,13 +284,16 @@ Span MakeWritableByteSpan(V&& v) noexcept return AsWritableBytes(Span{std::forward(v)}); } -// Helper functions to safely cast to unsigned char pointers. +// Helper functions to safely cast basic byte pointers to unsigned char pointers. inline unsigned char* UCharCast(char* c) { return reinterpret_cast(c); } inline unsigned char* UCharCast(unsigned char* c) { return c; } inline unsigned char* UCharCast(std::byte* c) { return reinterpret_cast(c); } inline const unsigned char* UCharCast(const char* c) { return reinterpret_cast(c); } inline const unsigned char* UCharCast(const unsigned char* c) { return c; } inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_cast(c); } +// Helper concept for the basic byte types. +template +concept BasicByte = requires { UCharCast(std::span{}.data()); }; // Helper function to safely convert a Span to a Span<[const] unsigned char>. template constexpr auto UCharSpanCast(Span s) -> Span::type> { return {UCharCast(s.data()), s.size()}; } diff --git a/src/test/amount_tests.cpp b/src/test/amount_tests.cpp index 3815a5bba6..e5ab1cfb90 100644 --- a/src/test/amount_tests.cpp +++ b/src/test/amount_tests.cpp @@ -85,6 +85,32 @@ BOOST_AUTO_TEST_CASE(GetFeeTest) BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34)); // Maximum size in bytes, should not crash CFeeRate(MAX_MONEY, std::numeric_limits::max()).GetFeePerK(); + + // check multiplication operator + // check multiplying by zero + feeRate = CFeeRate(1000); + BOOST_CHECK(0 * feeRate == CFeeRate(0)); + BOOST_CHECK(feeRate * 0 == CFeeRate(0)); + // check multiplying by a positive integer + BOOST_CHECK(3 * feeRate == CFeeRate(3000)); + BOOST_CHECK(feeRate * 3 == CFeeRate(3000)); + // check multiplying by a negative integer + BOOST_CHECK(-3 * feeRate == CFeeRate(-3000)); + BOOST_CHECK(feeRate * -3 == CFeeRate(-3000)); + // check commutativity + BOOST_CHECK(2 * feeRate == feeRate * 2); + // check with large numbers + int largeNumber = 1000000; + BOOST_CHECK(largeNumber * feeRate == feeRate * largeNumber); + // check boundary values + int maxInt = std::numeric_limits::max(); + feeRate = CFeeRate(maxInt); + BOOST_CHECK(feeRate * 2 == CFeeRate(static_cast(maxInt) * 2)); + BOOST_CHECK(2 * feeRate == CFeeRate(static_cast(maxInt) * 2)); + // check with zero fee rate + feeRate = CFeeRate(0); + BOOST_CHECK(feeRate * 5 == CFeeRate(0)); + BOOST_CHECK(5 * feeRate == CFeeRate(0)); } BOOST_AUTO_TEST_CASE(BinaryOperatorTest) diff --git a/src/test/descriptor_tests.cpp b/src/test/descriptor_tests.cpp index f4f4e39f40..c779bf6f73 100644 --- a/src/test/descriptor_tests.cpp +++ b/src/test/descriptor_tests.cpp @@ -592,9 +592,9 @@ BOOST_AUTO_TEST_CASE(descriptor_test) CheckUnparsable("raw(and_v(vc:andor(pk(L4gM1FBdyHNpkzsFh9ipnofLhpZRp2mwobpeULy1a6dBTvw8Ywtd),pk_k(Kx9HCDjGiwFcgVNhTrS5z5NeZdD6veeam61eDxLDCkGWujvL4Gnn),and_v(v:older(1),pk_k(L4o2kDvXXDRH2VS9uBnouScLduWt4dZnM25se7kvEjJeQ285en2A))),after(10)))", "sh(and_v(vc:andor(pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204),pk_k(032707170c71d8f75e4ca4e3fce870b9409dcaf12b051d3bcadff74747fa7619c0),and_v(v:older(1),pk_k(02aa27e5eb2c185e87cd1dbc3e0efc9cb1175235e0259df1713424941c3cb40402))),after(10)))", "Miniscript expressions can only be used in wsh or tr."); CheckUnparsable("", "tr(034D2224bbbbbbbbbbcbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb40,{{{{{{{{{{{{{{{{{{{{{{multi(1,xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/967808'/9,xprvA1RpRA33e1JQ7ifknakTFNpgXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/968/2/5/8/5/2/5/58/58/2/5/5/5/58/588/2/6/8/5/2/8/2/5/8/2/58/2/5/8/5/2/8/5/8/3/4/5/58/55/2/5/58/58/2/5/5/5/8/5/2/8/5/85/2/8/2/5/8/5/2/5/58/58/2/5/58/58/588/2/58/2/8/5/8/5/4/5/585/2/5/58/58/2/5/5/58/588/2/58/2/5/8/5/2/8/2/5/8/5/5/58/588/2/6/8/5/2/8/2/5/8/5/2/5/58/58/2/5/58/58/2/0/8/5/2/8/5/8/5/4/5/58/588/2/6/8/5/2/8/2/5/8/5/2/5/58/58/2/5/58/58/588/2/58/2/5/8/5/8/24/5/58/52/5/8/5/2/8/24/5/58/588/246/8/5/2/8/2/5/8/5/2/5/58/58/2/5/5/5/58/588/2/6/8/5/2/8/2/5/8/2/58/2/5/8/5/2/8/5/8/5/4/5/58/55/58/2/5/8/55/2/5/8/58/555/58/2/5/8/4//2/5/58/5w/2/5/8/5/2/4/5/58/5558'/2/5/58/58/2/5/5/58/588/2/58/2/5/8/5/2/8/2/5/8/5/5/8/58/2/5/58/58/2/5/8/9/588/2/58/2/5/8/5/2/8/5/8/5/4/5/58/588/2/6/8/5/2/8/2/5/8/5/2/5/58/58/2/5/5/58/588/2/58/2/5/8/5/2/82/5/8/5/5/58/52/6/8/5/2/8/{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}{{{{{{{{{DDD2/5/8/5/2/5/58/58/2/5/58/58/588/2/58/2/8/5/8/5/4/5/58/588/2/6/8/5/2/8/2/5/8588/246/8/5/2DLDDDDDDDbbD3DDDD/8/2/5/8/5/2/5/58/58/2/5/5/5/58/588/2/6/8/5/2/8/2/5/8/2/58/2/5/8/5/2/8/5/8/3/4/5/58/55/2/5/58/58/2/5/5/5/8/5/2/8/5/85/2/8/2/5/8D)/5/2/5/58/58/2/5/58/58/58/588/2/58/2/5/8/5/25/58/58/2/5/58/58/2/5/8/9/588/2/58/2/6780,xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFW/8/5/2/5/58678008')", "'multi(1,xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/967808'/9,xprvA1RpRA33e1JQ7ifknakTFNpgXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/968/2/5/8/5/2/5/58/58/2/5/5/5/58/588/2/6/8/5/2/8/2/5/8/2/58/2/5/8/5/2/8/5/8/3/4/5/58/55/2/5/58/58/2/5/5/5/8/5/2/8/5/85/2/8/2/5/8/5/2/5/58/58/2/5/58/58/588/2/58/2/8/5/8/5/4/5/585/2/5/58/58/2/5/5/58/588/2/58/2/5/8/5/2/8/2/5/8/5/5/58/588/2/6/8/5/2/8/2/5/8/5/2/5/58/58/2/5/58/58/2/0/8/5/2/8/5/8/5/4/5/58/588/2/6/8/5/2/8/2/5/8/5/2/5/58/58/2/5/58/58/588/2/58/2/5/8/5/8/24/5/58/52/5/8/5/2/8/24/5/58/588/246/8/5/2/8/2/5/8/5/2/5/58/58/2/5/5/5/58/588/2/6/8/5/2/8/2/5/8/2/58/2/5/8/5/2/8/5/8/5/4/5/58/55/58/2/5/8/55/2/5/8/58/555/58/2/5/8/4//2/5/58/5w/2/5/8/5/2/4/5/58/5558'/2/5/58/58/2/5/5/58/588/2/58/2/5/8/5/2/8/2/5/8/5/5/8/58/2/5/58/58/2/5/8/9/588/2/58/2/5/8/5/2/8/5/8/5/4/5/58/588/2/6/8/5/2/8/2/5/8/5/2/5/58/58/2/5/5/58/588/2/58/2/5/8/5/2/82/5/8/5/5/58/52/6/8/5/2/8/{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}{{{{{{{{{DDD2/5/8/5/2/5/58/58/2/5/58/58/588/2/58/2/8/5/8/5/4/5/58/588/2/6/8/5/2/8/2/5/8588/246/8/5/2DLDDDDDDDbbD3DDDD/8/2/5/8/5/2/5/58/58/2/5/5/5/58/588/2/6/8/5/2/8/2/5/8/2/58/2/5/8/5/2/8/5/8/3/4/5/58/55/2/5/58/58/2/5/5/5/8/5/2/8/5/85/2/8/2/5/8D)/5/2/5/58/58/2/5/58/58/58/588/2/58/2/5/8/5/25/58/58/2/5/58/58/2/5/8/9/588/2/58/2/6780,xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFW/8/5/2/5/58678008'' is not a valid descriptor function"); // No uncompressed keys allowed - CheckUnparsable("", "wsh(and_v(vc:andor(pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204),pk_k(032707170c71d8f75e4ca4e3fce870b9409dcaf12b051d3bcadff74747fa7619c0),and_v(v:older(1),pk_k(049228de6902abb4f541791f6d7f925b10e2078ccb1298856e5ea5cc5fd667f930eac37a00cc07f9a91ef3c2d17bf7a17db04552ff90ac312a5b8b4caca6c97aa4))),after(10)))", "A function is needed within P2WSH"); + CheckUnparsable("", "wsh(and_v(vc:andor(pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204),pk_k(032707170c71d8f75e4ca4e3fce870b9409dcaf12b051d3bcadff74747fa7619c0),and_v(v:older(1),pk_k(049228de6902abb4f541791f6d7f925b10e2078ccb1298856e5ea5cc5fd667f930eac37a00cc07f9a91ef3c2d17bf7a17db04552ff90ac312a5b8b4caca6c97aa4))),after(10)))", "Uncompressed keys are not allowed"); // No hybrid keys allowed - CheckUnparsable("", "wsh(and_v(vc:andor(pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204),pk_k(032707170c71d8f75e4ca4e3fce870b9409dcaf12b051d3bcadff74747fa7619c0),and_v(v:older(1),pk_k(069228de6902abb4f541791f6d7f925b10e2078ccb1298856e5ea5cc5fd667f930eac37a00cc07f9a91ef3c2d17bf7a17db04552ff90ac312a5b8b4caca6c97aa4))),after(10)))", "A function is needed within P2WSH"); + CheckUnparsable("", "wsh(and_v(vc:andor(pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204),pk_k(032707170c71d8f75e4ca4e3fce870b9409dcaf12b051d3bcadff74747fa7619c0),and_v(v:older(1),pk_k(069228de6902abb4f541791f6d7f925b10e2078ccb1298856e5ea5cc5fd667f930eac37a00cc07f9a91ef3c2d17bf7a17db04552ff90ac312a5b8b4caca6c97aa4))),after(10)))", "Hybrid public keys are not allowed"); // Insane at top level CheckUnparsable("wsh(and_b(vc:andor(pk(L4gM1FBdyHNpkzsFh9ipnofLhpZRp2mwobpeULy1a6dBTvw8Ywtd),pk_k(Kx9HCDjGiwFcgVNhTrS5z5NeZdD6veeam61eDxLDCkGWujvL4Gnn),and_v(v:older(1),pk_k(L4o2kDvXXDRH2VS9uBnouScLduWt4dZnM25se7kvEjJeQ285en2A))),after(10)))", "wsh(and_b(vc:andor(pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204),pk_k(032707170c71d8f75e4ca4e3fce870b9409dcaf12b051d3bcadff74747fa7619c0),and_v(v:older(1),pk_k(02aa27e5eb2c185e87cd1dbc3e0efc9cb1175235e0259df1713424941c3cb40402))),after(10)))", "and_b(vc:andor(pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204),pk_k(032707170c71d8f75e4ca4e3fce870b9409dcaf12b051d3bcadff74747fa7619c0),and_v(v:older(1),pk_k(02aa27e5eb2c185e87cd1dbc3e0efc9cb1175235e0259df1713424941c3cb40402))),after(10)) is invalid"); // Invalid sub diff --git a/src/test/fuzz/minisketch.cpp b/src/test/fuzz/minisketch.cpp index a17be73f6c..698cb15fc9 100644 --- a/src/test/fuzz/minisketch.cpp +++ b/src/test/fuzz/minisketch.cpp @@ -12,14 +12,27 @@ #include #include -using node::MakeMinisketch32; +namespace { + +Minisketch MakeFuzzMinisketch32(size_t capacity, uint32_t impl) +{ + return Assert(Minisketch(32, impl, capacity)); +} + +} // namespace FUZZ_TARGET(minisketch) { FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + const auto capacity{fuzzed_data_provider.ConsumeIntegralInRange(1, 200)}; - Minisketch sketch_a{Assert(MakeMinisketch32(capacity))}; - Minisketch sketch_b{Assert(MakeMinisketch32(capacity))}; + const uint32_t impl{fuzzed_data_provider.ConsumeIntegralInRange(0, Minisketch::MaxImplementation())}; + if (!Minisketch::ImplementationSupported(32, impl)) return; + + Minisketch sketch_a{MakeFuzzMinisketch32(capacity, impl)}; + Minisketch sketch_b{MakeFuzzMinisketch32(capacity, impl)}; + sketch_a.SetSeed(fuzzed_data_provider.ConsumeIntegral()); + sketch_b.SetSeed(fuzzed_data_provider.ConsumeIntegral()); // Fill two sets and keep the difference in a map std::map diff; @@ -47,8 +60,11 @@ FUZZ_TARGET(minisketch) } const auto num_diff{std::accumulate(diff.begin(), diff.end(), size_t{0}, [](auto n, const auto& e) { return n + e.second; })}; - Minisketch sketch_ar{MakeMinisketch32(capacity)}; - Minisketch sketch_br{MakeMinisketch32(capacity)}; + Minisketch sketch_ar{MakeFuzzMinisketch32(capacity, impl)}; + Minisketch sketch_br{MakeFuzzMinisketch32(capacity, impl)}; + sketch_ar.SetSeed(fuzzed_data_provider.ConsumeIntegral()); + sketch_br.SetSeed(fuzzed_data_provider.ConsumeIntegral()); + sketch_ar.Deserialize(sketch_a.Serialize()); sketch_br.Deserialize(sketch_b.Serialize()); diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index acb03ac5fc..56b391ed5c 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022 The Bitcoin Core developers +// Copyright (c) 2020-present The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -8,9 +8,6 @@ #include #include #include