diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6cb046126f5aa..64517817f625d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,8 +77,6 @@ jobs: asan-lsan-ubsan-integer-no-depends-usdt: name: 'ASan + LSan + UBSan + integer, no depends, USDT' runs-on: ubuntu-24.04 # has to match container in ci/test/00_setup_env_native_asan.sh for tracing tools - # No need to run on the read-only mirror, unless it is a PR. - # if: github.event_name == 'pull_request' timeout-minutes: 120 env: FILE_ENV: "./ci/test/00_setup_env_native_asan.sh" diff --git a/ci/test/00_setup_env_i686_centos.sh b/ci/test/00_setup_env_i686_centos.sh index be7a33cdfe244..85750b1ecb8c2 100755 --- a/ci/test/00_setup_env_i686_centos.sh +++ b/ci/test/00_setup_env_i686_centos.sh @@ -9,7 +9,7 @@ export LC_ALL=C.UTF-8 export HOST=i686-pc-linux-gnu export CONTAINER_NAME=ci_i686_centos export CI_IMAGE_NAME_TAG="quay.io/centos/amd64:stream9" -export CI_BASE_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 ccache make git python3 python3-pip which patch lbzip2 xz procps-ng dash rsync coreutils bison util-linux e2fsprogs cmake" +export CI_BASE_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 ccache make git python3 python3-pip which patch lbzip2 xz procps-ng dash rsync coreutils bison e2fsprogs cmake" export PIP_PACKAGES="pyzmq" export GOAL="install" export NO_WERROR=1 # Suppress error: #warning _FORTIFY_SOURCE > 2 is treated like 2 on this platform [-Werror=cpp] diff --git a/cmake/bitcoin-build-config.h.in b/cmake/bitcoin-build-config.h.in index dce9261da2a35..56e0519fac1f9 100644 --- a/cmake/bitcoin-build-config.h.in +++ b/cmake/bitcoin-build-config.h.in @@ -71,9 +71,6 @@ */ #cmakedefine01 HAVE_DECL_SETSID -/* Define this symbol if evhttp_connection_get_peer expects const char** */ -#cmakedefine HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR 1 - /* Define to 1 if fdatasync is available. */ #cmakedefine HAVE_FDATASYNC 1 diff --git a/cmake/module/FindLibevent.cmake b/cmake/module/FindLibevent.cmake index 901a4f3bd41ec..c006b43d60408 100644 --- a/cmake/module/FindLibevent.cmake +++ b/cmake/module/FindLibevent.cmake @@ -35,46 +35,52 @@ function(check_evhttp_connection_get_peer target) " HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR ) cmake_pop_check_state() - set(HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR ${HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR} PARENT_SCOPE) + target_compile_definitions(${target} INTERFACE + $<$:HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR> + ) endfunction() +set(_libevent_components core extra) +if(NOT WIN32) + list(APPEND _libevent_components pthreads) +endif() + +find_package(Libevent ${Libevent_FIND_VERSION} QUIET + NO_MODULE +) include(FindPackageHandleStandardArgs) -if(VCPKG_TARGET_TRIPLET) - find_package(Libevent ${Libevent_FIND_VERSION} NO_MODULE QUIET - COMPONENTS extra +if(Libevent_FOUND) + find_package(Libevent ${Libevent_FIND_VERSION} QUIET + REQUIRED COMPONENTS ${_libevent_components} + NO_MODULE ) find_package_handle_standard_args(Libevent REQUIRED_VARS Libevent_DIR VERSION_VAR Libevent_VERSION ) check_evhttp_connection_get_peer(libevent::extra) - add_library(libevent::libevent ALIAS libevent::extra) - mark_as_advanced(Libevent_DIR) - mark_as_advanced(_event_h) - mark_as_advanced(_event_lib) else() find_package(PkgConfig REQUIRED) - pkg_check_modules(libevent QUIET - IMPORTED_TARGET - libevent>=${Libevent_FIND_VERSION} - ) - set(_libevent_required_vars libevent_LIBRARY_DIRS libevent_FOUND) - if(NOT WIN32) - pkg_check_modules(libevent_pthreads QUIET - IMPORTED_TARGET - libevent_pthreads>=${Libevent_FIND_VERSION} + foreach(component IN LISTS _libevent_components) + pkg_check_modules(libevent_${component} + REQUIRED QUIET + IMPORTED_TARGET GLOBAL + libevent_${component}>=${Libevent_FIND_VERSION} ) - list(APPEND _libevent_required_vars libevent_pthreads_FOUND) - endif() + if(TARGET PkgConfig::libevent_${component} AND NOT TARGET libevent::${component}) + add_library(libevent::${component} ALIAS PkgConfig::libevent_${component}) + endif() + endforeach() find_package_handle_standard_args(Libevent - REQUIRED_VARS ${_libevent_required_vars} - VERSION_VAR libevent_VERSION + REQUIRED_VARS libevent_core_LIBRARY_DIRS + VERSION_VAR libevent_core_VERSION ) - unset(_libevent_required_vars) - check_evhttp_connection_get_peer(PkgConfig::libevent) - add_library(libevent::libevent ALIAS PkgConfig::libevent) - if(NOT WIN32) - add_library(libevent::pthreads ALIAS PkgConfig::libevent_pthreads) - endif() + check_evhttp_connection_get_peer(PkgConfig::libevent_extra) endif() + +unset(_libevent_components) + +mark_as_advanced(Libevent_DIR) +mark_as_advanced(_event_h) +mark_as_advanced(_event_lib) diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 22e4487d7fd92..b9f0334552d42 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -10,7 +10,7 @@ (gnu packages gawk) (gnu packages gcc) ((gnu packages installers) #:select (nsis-x86_64)) - ((gnu packages linux) #:select (linux-libre-headers-6.1 util-linux)) + ((gnu packages linux) #:select (linux-libre-headers-6.1)) (gnu packages llvm) (gnu packages mingw) (gnu packages moreutils) @@ -493,7 +493,6 @@ inspecting signatures in Mach-O binaries.") bash-minimal which coreutils-minimal - util-linux ;; File(system) inspection file grep diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index 4c05e8a0a7425..91bc75c1d30d3 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -4,7 +4,6 @@ $(package)_download_path=https://github.com/libevent/libevent/releases/download/ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb $(package)_patches=cmake_fixups.patch -$(package)_patches+=fix_mingw_link.patch $(package)_build_subdir=build # When building for Windows, we set _WIN32_WINNT to target the same Windows @@ -23,8 +22,7 @@ define $(package)_set_vars endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/cmake_fixups.patch && \ - patch -p1 < $($(package)_patch_dir)/fix_mingw_link.patch + patch -p1 < $($(package)_patch_dir)/cmake_fixups.patch endef define $(package)_config_cmds @@ -40,7 +38,8 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf bin && \ + rm -rf bin lib/pkgconfig && \ rm include/ev*.h && \ - rm include/event2/*_compat.h + rm include/event2/*_compat.h && \ + rm lib/libevent.a endef diff --git a/depends/patches/libevent/cmake_fixups.patch b/depends/patches/libevent/cmake_fixups.patch index d80c1a94898c5..a8812afd1e1ba 100644 --- a/depends/patches/libevent/cmake_fixups.patch +++ b/depends/patches/libevent/cmake_fixups.patch @@ -1,8 +1,5 @@ cmake: set minimum version to 3.5 -Fix generated pkg-config files, see -https://github.com/libevent/libevent/pull/1165. - --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ @@ -14,22 +11,3 @@ https://github.com/libevent/libevent/pull/1165. if (POLICY CMP0054) cmake_policy(SET CMP0054 NEW) -diff --git a/cmake/AddEventLibrary.cmake b/cmake/AddEventLibrary.cmake -index 04f5837e..d8ea42c4 100644 ---- a/cmake/AddEventLibrary.cmake -+++ b/cmake/AddEventLibrary.cmake -@@ -20,12 +20,12 @@ macro(generate_pkgconfig LIB_NAME) - - set(LIBS "") - foreach (LIB ${LIB_PLATFORM}) -- set(LIBS "${LIBS} -L${LIB}") -+ set(LIBS "${LIBS} -l${LIB}") - endforeach() - - set(OPENSSL_LIBS "") - foreach(LIB ${OPENSSL_LIBRARIES}) -- set(OPENSSL_LIBS "${OPENSSL_LIBS} -L${LIB}") -+ set(OPENSSL_LIBS "${OPENSSL_LIBS} -l${LIB}") - endforeach() - - configure_file("lib${LIB_NAME}.pc.in" "lib${LIB_NAME}.pc" @ONLY) diff --git a/depends/patches/libevent/fix_mingw_link.patch b/depends/patches/libevent/fix_mingw_link.patch deleted file mode 100644 index 41cbd463c9122..0000000000000 --- a/depends/patches/libevent/fix_mingw_link.patch +++ /dev/null @@ -1,25 +0,0 @@ -commit d108099913c5fdbe518f3f4d711f248f8522bd10 -Author: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> -Date: Mon Apr 22 06:39:35 2024 +0100 - - build: Add `Iphlpapi` to `Libs.private` in `*.pc` files on Windows - - It has been required since https://github.com/libevent/libevent/pull/923 - at least for the `if_nametoindex` call. - - See https://github.com/libevent/libevent/pull/1622. - - -diff --git a/configure.ac b/configure.ac -index d00e063a..cd1fce37 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -906,7 +906,7 @@ if(WIN32) - list(APPEND HDR_PRIVATE WIN32-Code/getopt.h) - - set(EVENT__DNS_USE_FTIME_FOR_ID 1) -- set(LIB_PLATFORM ws2_32 shell32 advapi32) -+ set(LIB_PLATFORM ws2_32 shell32 advapi32 iphlpapi) - add_definitions( - -D_CRT_SECURE_NO_WARNINGS - -D_CRT_NONSTDC_NO_DEPRECATE) diff --git a/doc/build-unix.md b/doc/build-unix.md index d416fb5095e12..42eba7b522f88 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -181,7 +181,7 @@ Setup and Build Example: Arch Linux ----------------------------------- This example lists the steps necessary to setup and build a command line only distribution of the latest changes on Arch Linux: - pacman --sync --needed cmake boost gcc git libevent make pkgconf python sqlite + pacman --sync --needed cmake boost gcc git libevent make python sqlite git clone https://github.com/groestlcoin/groestlcoin.git cd groestlcoin/ cmake -B build diff --git a/doc/multisig-tutorial.md b/doc/multisig-tutorial.md index 34b389106dd59..94472ddaaaa6b 100644 --- a/doc/multisig-tutorial.md +++ b/doc/multisig-tutorial.md @@ -82,7 +82,7 @@ multisig_desc="[$multisig_ext_desc, $multisig_int_desc]" `external_desc` and `internal_desc` specify the output type (`wsh`, in this case) and the xpubs involved. They also use BIP 67 (`sortedmulti`), so the wallet can be recreated without worrying about the order of xpubs. Conceptually, descriptors describe a list of scriptPubKey (along with information for spending from it) [[source](https://github.com/bitcoin/bitcoin/issues/21199#issuecomment-780772418)]. -Note that at least two descriptors are usually used, one for internal derivation paths and external ones. There are discussions about eliminating this redundancy, as can been seen in the issue [#17190](https://github.com/bitcoin/bitcoin/issues/17190). +Note that at least two descriptors are usually used, one for internal derivation paths and one for external ones. There are discussions about eliminating this redundancy, as can be seen in the issue [#17190](https://github.com/bitcoin/bitcoin/issues/17190). After creating the descriptors, it is necessary to add the checksum, which is required by the `importdescriptors` RPC. diff --git a/doc/offline-signing-tutorial.md b/doc/offline-signing-tutorial.md index fec515f356d4f..dd38a6a18e9d3 100644 --- a/doc/offline-signing-tutorial.md +++ b/doc/offline-signing-tutorial.md @@ -60,7 +60,8 @@ The `watch_only_wallet` wallet will be used to track and validate incoming trans ```sh [online]$ ./build/src/groestlcoin-cli -signet -named createwallet \ wallet_name="watch_only_wallet" \ - disable_private_keys=true + disable_private_keys=true \ + blank=true { "name": "watch_only_wallet" diff --git a/doc/psbt.md b/doc/psbt.md index 2a51481486265..ff52938e73d3f 100644 --- a/doc/psbt.md +++ b/doc/psbt.md @@ -67,6 +67,10 @@ hardware implementations will typically implement multiple roles simultaneously. input a PSBT, adds UTXO, key, and script data to inputs and outputs that miss it, and optionally signs inputs. Where possible it also finalizes the partial signatures. +- **`descriptorprocesspsbt` (Updater, Signer, Finalizer)** is a node RPC that takes + as input a PSBT and a list of descriptors. It updates SegWit inputs with + information available from the UTXO set and the mempool and signs the inputs using + the provided descriptors. Where possible it also finalizes the partial signatures. - **`utxoupdatepsbt` (Updater)** is a node RPC that takes a PSBT and updates it to include information available from the UTXO set (works only for SegWit inputs). diff --git a/doc/release-notes-30239.md b/doc/release-notes-30239.md new file mode 100644 index 0000000000000..9380bddb1cb88 --- /dev/null +++ b/doc/release-notes-30239.md @@ -0,0 +1,12 @@ +P2P and network changes +----------------------- + +Ephemeral dust is a new concept that allows a single +dust output in a transaction, provided the transaction +is zero fee. In order to spend any unconfirmed outputs +from this transaction, the spender must also spend +this dust in addition to any other outputs. + +In other words, this type of transaction +should be created in a transaction package where +the dust is both created and spent simultaneously. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 881aba6314475..2b5e32b9d41e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -260,6 +260,7 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL node/utxo_snapshot.cpp node/warnings.cpp noui.cpp + policy/ephemeral_policy.cpp policy/fees.cpp policy/fees_args.cpp policy/packages.cpp @@ -299,13 +300,14 @@ target_link_libraries(bitcoin_node core_interface bitcoin_common bitcoin_util + $ leveldb minisketch univalue Boost::headers - $ + libevent::core + libevent::extra $ - $ $ ) @@ -375,7 +377,8 @@ if(BUILD_CLI) bitcoin_cli bitcoin_common bitcoin_util - $ + libevent::core + libevent::extra ) list(APPEND installable_targets groestlcoin-cli) endif() diff --git a/src/addrman.cpp b/src/addrman.cpp index 7e086f68e10ae..59860aeea3b6a 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -813,9 +813,11 @@ nid_type AddrManImpl::GetEntry(bool use_tried, size_t bucket, size_t position) c std::vector AddrManImpl::GetAddr_(size_t max_addresses, size_t max_pct, std::optional network, const bool filtered) const { AssertLockHeld(cs); + Assume(max_pct <= 100); size_t nNodes = vRandom.size(); if (max_pct != 0) { + max_pct = std::min(max_pct, size_t{100}); nNodes = max_pct * nNodes / 100; } if (max_addresses != 0) { diff --git a/src/addrman.h b/src/addrman.h index ba6e13bf97ead..2ddf1468624c4 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -166,7 +166,7 @@ class AddrMan * Return all or many randomly selected addresses, optionally by network. * * @param[in] max_addresses Maximum number of addresses to return (0 = all). - * @param[in] max_pct Maximum percentage of addresses to return (0 = all). + * @param[in] max_pct Maximum percentage of addresses to return (0 = all). Value must be from 0 to 100. * @param[in] network Select only addresses of this network (nullopt = all). * @param[in] filtered Select only addresses that are considered good quality (false = all). * diff --git a/src/bench/CMakeLists.txt b/src/bench/CMakeLists.txt index 45b6510044635..4589ef177c331 100644 --- a/src/bench/CMakeLists.txt +++ b/src/bench/CMakeLists.txt @@ -34,6 +34,7 @@ add_executable(bench_bitcoin load_external.cpp lockedpool.cpp logging.cpp + mempool_ephemeral_spends.cpp mempool_eviction.cpp mempool_stress.cpp merkle_root.cpp diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index a2dbb11888591..26daff5070518 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -27,9 +27,26 @@ using util::Join; const std::function G_TEST_LOG_FUN{}; -const std::function()> G_TEST_COMMAND_LINE_ARGUMENTS{}; +/** + * Retrieves the available test setup command line arguments that may be used + * in the benchmark. They will be used only if the benchmark utilizes a + * 'BasicTestingSetup' or any child of it. + */ +static std::function()> g_bench_command_line_args{}; +const std::function()> G_TEST_COMMAND_LINE_ARGUMENTS = []() { + return g_bench_command_line_args(); +}; -const std::function G_TEST_GET_FULL_NAME{}; +/** + * Retrieve the name of the currently in-use benchmark. + * This is applicable only to benchmarks that utilize the unit test + * framework context setup (e.g. ones using 'MakeNoLogFileContext()'). + * It places the datadir of each benchmark run within their respective benchmark name. + */ +static std::string g_running_benchmark_name; +const std::function G_TEST_GET_FULL_NAME = []() { + return g_running_benchmark_name; +}; namespace { @@ -94,6 +111,14 @@ void BenchRunner::RunAll(const Args& args) std::cout << "Running with -sanity-check option, output is being suppressed as benchmark results will be useless." << std::endl; } + // Load inner test setup args + g_bench_command_line_args = [&args]() { + std::vector ret; + ret.reserve(args.setup_args.size()); + for (const auto& arg : args.setup_args) ret.emplace_back(arg.c_str()); + return ret; + }; + std::vector benchmarkResults; for (const auto& [name, bench_func] : benchmarks()) { const auto& [func, priority_level] = bench_func; @@ -117,6 +142,7 @@ void BenchRunner::RunAll(const Args& args) bench.output(nullptr); } bench.name(name); + g_running_benchmark_name = name; if (args.min_time > 0ms) { // convert to nanos before dividing to reduce rounding errors std::chrono::nanoseconds min_time_ns = args.min_time; diff --git a/src/bench/bench.h b/src/bench/bench.h index f0705f4fed88f..2df203ce236ea 100644 --- a/src/bench/bench.h +++ b/src/bench/bench.h @@ -61,6 +61,7 @@ struct Args { fs::path output_json; std::string regex_filter; uint8_t priority; + std::vector setup_args; }; class BenchRunner diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp index 555dca7d5982f..88afe68a1a992 100644 --- a/src/bench/bench_bitcoin.cpp +++ b/src/bench/bench_bitcoin.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,7 @@ static const std::string DEFAULT_PRIORITY{"all"}; static void SetupBenchArgs(ArgsManager& argsman) { SetupHelpOptions(argsman); + SetupCommonTestArgs(argsman); argsman.AddArg("-asymptote=", "Test asymptotic growth of the runtime of an algorithm, if supported by the benchmark", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-filter=", strprintf("Regular expression filter to select benchmark by name (default: %s)", DEFAULT_BENCH_FILTER), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); @@ -60,6 +62,18 @@ static uint8_t parsePriorityLevel(const std::string& str) { return levels; } +static std::vector parseTestSetupArgs(const ArgsManager& argsman) +{ + // Parses unit test framework arguments supported by the benchmark framework. + std::vector args; + static std::vector AVAILABLE_ARGS = {"-testdatadir"}; + for (const std::string& arg_name : AVAILABLE_ARGS) { + auto op_arg = argsman.GetArg(arg_name); + if (op_arg) args.emplace_back(strprintf("%s=%s", arg_name, *op_arg)); + } + return args; +} + int main(int argc, char** argv) { ArgsManager argsman; @@ -131,6 +145,7 @@ int main(int argc, char** argv) args.regex_filter = argsman.GetArg("-filter", DEFAULT_BENCH_FILTER); args.sanity_check = argsman.GetBoolArg("-sanity-check", false); args.priority = parsePriorityLevel(argsman.GetArg("-priority-level", DEFAULT_PRIORITY)); + args.setup_args = parseTestSetupArgs(argsman); benchmark::BenchRunner::RunAll(args); diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp index 65da942ad7c3b..a0799aea7adf2 100644 --- a/src/bench/crypto_hash.cpp +++ b/src/bench/crypto_hash.cpp @@ -192,10 +192,16 @@ static void SHA512(benchmark::Bench& bench) static void SipHash_32b(benchmark::Bench& bench) { - uint256 x; - uint64_t k1 = 0; + FastRandomContext rng{/*fDeterministic=*/true}; + auto k0{rng.rand64()}, k1{rng.rand64()}; + auto val{rng.rand256()}; + auto i{0U}; bench.run([&] { - *((uint64_t*)x.begin()) = SipHashUint256(0, ++k1, x); + ankerl::nanobench::doNotOptimizeAway(SipHashUint256(k0, k1, val)); + ++k0; + ++k1; + ++i; + val.data()[i % uint256::size()] ^= i & 0xFF; }); } diff --git a/src/bench/mempool_ephemeral_spends.cpp b/src/bench/mempool_ephemeral_spends.cpp new file mode 100644 index 0000000000000..e867c61752c1e --- /dev/null +++ b/src/bench/mempool_ephemeral_spends.cpp @@ -0,0 +1,83 @@ +// Copyright (c) 2011-2022 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 +#include +#include +#include