diff --git a/.tx/config b/.tx/config index 02d80379d1cb6..b5a9abaae383f 100644 --- a/.tx/config +++ b/.tx/config @@ -1,7 +1,7 @@ [main] host = https://www.transifex.com -[o:bitcoin:p:bitcoin:r:qt-translation-028x] +[o:bitcoin:p:bitcoin:r:qt-translation-029x] file_filter = src/qt/locale/bitcoin_.xlf source_file = src/qt/locale/bitcoin_en.xlf source_lang = en diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh index 4dcf8e3d21be4..ce02a90215cb8 100755 --- a/ci/test/00_setup_env_native_asan.sh +++ b/ci/test/00_setup_env_native_asan.sh @@ -19,7 +19,7 @@ else fi export CONTAINER_NAME=ci_native_asan -export APT_LLVM_V="19" +export APT_LLVM_V="20" export PACKAGES="systemtap-sdt-dev clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev python3-zmq qtbase5-dev qttools5-dev qttools5-dev-tools libevent-dev libboost-dev libdb5.3++-dev libzmq3-dev libqrencode-dev libsqlite3-dev ${BPFCC_PACKAGE}" export NO_DEPENDS=1 export GOAL="install" diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh index 526e72a25fe19..7c58a4a677071 100755 --- a/ci/test/00_setup_env_native_fuzz.sh +++ b/ci/test/00_setup_env_native_fuzz.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" export CONTAINER_NAME=ci_native_fuzz -export APT_LLVM_V="19" +export APT_LLVM_V="20" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev libevent-dev libboost-dev libsqlite3-dev" export NO_DEPENDS=1 export GOAL="install" diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index 9b8c7ed1dff53..d09f11f6e8e7f 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_native_tsan export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" -export APT_LLVM_V="19" +export APT_LLVM_V="20" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev libc++abi-${APT_LLVM_V}-dev libc++-${APT_LLVM_V}-dev python3-zmq" export DEP_OPTS="CC=clang-${APT_LLVM_V} CXX='clang++-${APT_LLVM_V} -stdlib=libc++'" export GOAL="install" diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index a46f9ffabbef4..e1acc40708c49 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -49,7 +49,7 @@ if [ -n "$PIP_PACKAGES" ]; then fi if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then - ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-19.1.6" /msan/llvm-project + ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-20.1.0-rc1" /msan/llvm-project cmake -G Ninja -B /msan/clang_build/ \ -DLLVM_ENABLE_PROJECTS="clang" \ diff --git a/depends/packages/capnp.mk b/depends/packages/capnp.mk index 0c211cbc455df..7f41d3b5a4ed3 100644 --- a/depends/packages/capnp.mk +++ b/depends/packages/capnp.mk @@ -9,7 +9,7 @@ define $(package)_set_vars := $(package)_config_opts := -DBUILD_TESTING=OFF $(package)_config_opts += -DWITH_OPENSSL=OFF $(package)_config_opts += -DWITH_ZLIB=OFF - $(package)_cxxflags += -ffile-prefix-map=$$($(package)_extract_dir)=/usr + $(package)_cxxflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr endef define $(package)_config_cmds diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index 14ad24a1ded42..a55684ae1175f 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -13,7 +13,7 @@ define $(package)_set_vars $(package)_config_opts=-DCMAKE_BUILD_TYPE=None -DEVENT__DISABLE_BENCHMARK=ON -DEVENT__DISABLE_OPENSSL=ON $(package)_config_opts+=-DEVENT__DISABLE_SAMPLES=ON -DEVENT__DISABLE_REGRESS=ON $(package)_config_opts+=-DEVENT__DISABLE_TESTS=ON -DEVENT__LIBRARY_TYPE=STATIC - $(package)_cflags += -ffile-prefix-map=$($(package)_extract_dir)=/usr + $(package)_cflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr $(package)_cppflags += -D_GNU_SOURCE $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0A00 diff --git a/depends/packages/libmultiprocess.mk b/depends/packages/libmultiprocess.mk index a181e05100bba..afbd315e38806 100644 --- a/depends/packages/libmultiprocess.mk +++ b/depends/packages/libmultiprocess.mk @@ -13,7 +13,7 @@ ifneq ($(host),$(build)) $(package)_config_opts := -DCAPNP_EXECUTABLE="$$(native_capnp_prefixbin)/capnp" $(package)_config_opts += -DCAPNPC_CXX_EXECUTABLE="$$(native_capnp_prefixbin)/capnpc-c++" endif -$(package)_cxxflags += -ffile-prefix-map=$$($(package)_extract_dir)=/usr +$(package)_cxxflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr endef define $(package)_config_cmds diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 89e10d15efdd0..8bf84b1f1cbab 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -17,7 +17,7 @@ define $(package)_set_vars $(package)_config_opts += -DWITH_LIBBSD=OFF -DENABLE_CURVE=OFF -DENABLE_CPACK=OFF $(package)_config_opts += -DBUILD_SHARED=OFF -DBUILD_TESTS=OFF -DZMQ_BUILD_TESTS=OFF $(package)_config_opts += -DENABLE_DRAFTS=OFF -DZMQ_BUILD_TESTS=OFF - $(package)_cxxflags += -ffile-prefix-map=$($(package)_extract_dir)=/usr + $(package)_cxxflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr $(package)_config_opts_mingw32 += -DZMQ_WIN32_WINNT=0x0A00 -DZMQ_HAVE_IPC=OFF endef diff --git a/doc/developer-notes.md b/doc/developer-notes.md index f763225f6a9a8..aa2c720cf33da 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -400,8 +400,8 @@ If the code is behaving strangely, take a look in the `debug.log` file in the da error and debugging messages are written there. Debug logging can be enabled on startup with the `-debug` and `-loglevel` -configuration options and toggled while bitcoind is running with the `logging` -RPC. For instance, launching bitcoind with `-debug` or `-debug=1` will turn on +configuration options and toggled while groestlcoind is running with the `logging` +RPC. For instance, launching groestlcoind with `-debug` or `-debug=1` will turn on all log categories and `-loglevel=trace` will turn on all log severity levels. The Qt code routes `qDebug()` output to `debug.log` under category "qt": run with `-debug=qt` @@ -432,8 +432,8 @@ RPC that, when enabled, logs the location and duration of each lock contention to the `debug.log` file. The `-DCMAKE_BUILD_TYPE=Debug` build option adds `-DDEBUG_LOCKCONTENTION` to the -compiler flags. You may also enable it manually by building with `-DDEBUG_LOCKCONTENTION` added to your CPPFLAGS, -i.e. `CPPFLAGS="-DDEBUG_LOCKCONTENTION"`, then build and run groestlcoind. +compiler flags. You may also enable it manually by building with `-DDEBUG_LOCKCONTENTION` +added to your CPPFLAGS, i.e. `-DAPPEND_CPPFLAGS="-DDEBUG_LOCKCONTENTION"`. You can then use the `-debug=lock` configuration option at groestlcoind startup or `groestlcoin-cli logging '["lock"]'` at runtime to turn on lock contention logging. diff --git a/doc/release-notes-31384.md b/doc/release-notes-31384.md new file mode 100644 index 0000000000000..9256ec16f4621 --- /dev/null +++ b/doc/release-notes-31384.md @@ -0,0 +1,34 @@ +- Node and Mining + +--- + +- **PR #31384** fixed an issue where block reserved weight for fixed-size block header, transactions count, + and coinbase transaction was done in two separate places. + Before this pull request, the policy default for the maximum block weight was `3,996,000` WU, calculated by + subtracting `4,000 WU` from the `4,000,000 WU` consensus limit to account for the fixed-size block header, + transactions count, and coinbase transaction. During block assembly, Bitcoin Core clamped custom `-blockmaxweight` + value to not be more than the policy default. + + Additionally, the mining code added another `4,000 WU` to the initial reservation, reducing the effective block template + size to `3,992,000 WU`. + + Due to this issue, the total reserved weight was always `8,000 WU`, meaning that even when specifying a `-blockmaxweight` + higher than the policy default, the actual block size never exceeded `3,992,000 WU`. + + The fix consolidates the reservation into a single place and introduces a new startup option, + `-blockreservedweight` (default: `8,000 WU`). This startup option specifies the reserved weight for + the fixed-size block header, transactions count, and coinbase transaction. + The default value of `-blockreservedweight` was chosen to preserve the previous behavior. + + **Upgrade Note:** The default `-blockreservedweight` ensures backward compatibility for users who relied on the previous behavior. + + Users who manually set `-blockmaxweight` to its maximum value of `4,000,000 WU` should be aware that this + value previously had no effect since it was clamped to `3,996,000 WU`. + + Users lowering `-blockreservedweight` should ensure that the total weight (for the block header, transaction count, and coinbase transaction) + does not exceed the reduced value. + + As a safety check, Bitcoin core will **fail to start** when `-blockreservedweight` init parameter value is lower than `2000` weight units. + + Bitcoin Core will also **fail to start** if the `-blockmaxweight` or `-blockreservedweight` init parameter exceeds + consensus limit of `4,000,000` weight units. diff --git a/libgroestlcoinkernel.pc.in b/libgroestlcoinkernel.pc.in index 83e01761a48e5..bd129b4c221d1 100644 --- a/libgroestlcoinkernel.pc.in +++ b/libgroestlcoinkernel.pc.in @@ -4,7 +4,7 @@ libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: @CLIENT_NAME@ kernel library -Description: Experimental library for the Groestlcoin Core validation engine. +Description: Experimental library for the @CLIENT_NAME@ validation engine. Version: @CLIENT_VERSION_STRING@ Libs: -L${libdir} -lgroestlcoinkernel Libs.private: -L${libdir} @LIBS_PRIVATE@ diff --git a/src/bech32.cpp b/src/bech32.cpp index 5694ad54c8f9c..81695acebaae4 100644 --- a/src/bech32.cpp +++ b/src/bech32.cpp @@ -364,7 +364,7 @@ std::string Encode(Encoding encoding, const std::string& hrp, const data& values std::string ret; ret.reserve(hrp.size() + 1 + values.size() + CHECKSUM_SIZE); ret += hrp; - ret += '1'; + ret += SEPARATOR; for (const uint8_t& i : values) ret += CHARSET[i]; for (const uint8_t& i : CreateChecksum(encoding, hrp, values)) ret += CHARSET[i]; return ret; @@ -374,7 +374,7 @@ std::string Encode(Encoding encoding, const std::string& hrp, const data& values DecodeResult Decode(const std::string& str, CharLimit limit) { std::vector errors; if (!CheckCharacters(str, errors)) return {}; - size_t pos = str.rfind('1'); + size_t pos = str.rfind(SEPARATOR); if (str.size() > limit) return {}; if (pos == str.npos || pos == 0 || pos + CHECKSUM_SIZE >= str.size()) { return {}; @@ -413,7 +413,7 @@ std::pair> LocateErrors(const std::string& str, Ch return std::make_pair("Invalid character or mixed case", std::move(error_locations)); } - size_t pos = str.rfind('1'); + size_t pos = str.rfind(SEPARATOR); if (pos == str.npos) { return std::make_pair("Missing separator", std::vector{}); } diff --git a/src/bech32.h b/src/bech32.h index 33d1ca1935ca7..6d5a68ec5a10f 100644 --- a/src/bech32.h +++ b/src/bech32.h @@ -21,8 +21,8 @@ namespace bech32 { -/** The Bech32 and Bech32m checksum size */ -constexpr size_t CHECKSUM_SIZE = 6; +static constexpr size_t CHECKSUM_SIZE = 6; +static constexpr char SEPARATOR = '1'; enum class Encoding { INVALID, //!< Failed decoding diff --git a/src/init.cpp b/src/init.cpp index ed60c5f79dae7..84eea5a827155 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -648,6 +649,7 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc) argsman.AddArg("-blockmaxweight=", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_BLOCK_MAX_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION); + argsman.AddArg("-blockreservedweight=", strprintf("Reserve space for the fixed-size block header plus the largest coinbase transaction the mining software may add to the block. (default: %d).", DEFAULT_BLOCK_RESERVED_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION); argsman.AddArg("-blockmintxfee=", strprintf("Set lowest fee rate (in %s/kvB) for transactions to be included in block creation. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION); argsman.AddArg("-blockversion=", "Override block version to test forking scenarios", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::BLOCK_CREATION); @@ -1015,6 +1017,23 @@ bool AppInitParameterInteraction(const ArgsManager& args) } } + if (args.IsArgSet("-blockmaxweight")) { + const auto max_block_weight = args.GetIntArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT); + if (max_block_weight > MAX_BLOCK_WEIGHT) { + return InitError(strprintf(_("Specified -blockmaxweight (%d) exceeds consensus maximum block weight (%d)"), max_block_weight, MAX_BLOCK_WEIGHT)); + } + } + + if (args.IsArgSet("-blockreservedweight")) { + const auto block_reserved_weight = args.GetIntArg("-blockreservedweight", DEFAULT_BLOCK_RESERVED_WEIGHT); + if (block_reserved_weight > MAX_BLOCK_WEIGHT) { + return InitError(strprintf(_("Specified -blockreservedweight (%d) exceeds consensus maximum block weight (%d)"), block_reserved_weight, MAX_BLOCK_WEIGHT)); + } + if (block_reserved_weight < MINIMUM_BLOCK_RESERVED_WEIGHT) { + return InitError(strprintf(_("Specified -blockreservedweight (%d) is lower than minimum safety value of (%d)"), block_reserved_weight, MINIMUM_BLOCK_RESERVED_WEIGHT)); + } + } + nBytesPerSigOp = args.GetIntArg("-bytespersigop", nBytesPerSigOp); if (!g_wallet_init_interface.ParameterInteraction()) return false; diff --git a/src/ipc/capnp/mining.capnp b/src/ipc/capnp/mining.capnp index 50b07bda708b7..e57d6679e184a 100644 --- a/src/ipc/capnp/mining.capnp +++ b/src/ipc/capnp/mining.capnp @@ -35,7 +35,7 @@ interface BlockTemplate $Proxy.wrap("interfaces::BlockTemplate") { struct BlockCreateOptions $Proxy.wrap("node::BlockCreateOptions") { useMempool @0 :Bool $Proxy.name("use_mempool"); - coinbaseMaxAdditionalWeight @1 :UInt64 $Proxy.name("coinbase_max_additional_weight"); + blockReservedWeight @1 :UInt64 $Proxy.name("block_reserved_weight"); coinbaseOutputMaxAdditionalSigops @2 :UInt64 $Proxy.name("coinbase_output_max_additional_sigops"); } diff --git a/src/node/miner.cpp b/src/node/miner.cpp index d49e981229f08..d54b87928b733 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -75,11 +75,12 @@ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman) static BlockAssembler::Options ClampOptions(BlockAssembler::Options options) { - Assert(options.coinbase_max_additional_weight <= DEFAULT_BLOCK_MAX_WEIGHT); + Assert(options.block_reserved_weight <= MAX_BLOCK_WEIGHT); + Assert(options.block_reserved_weight >= MINIMUM_BLOCK_RESERVED_WEIGHT); Assert(options.coinbase_output_max_additional_sigops <= MAX_BLOCK_SIGOPS_COST); - // Limit weight to between coinbase_max_additional_weight and DEFAULT_BLOCK_MAX_WEIGHT for sanity: - // Coinbase (reserved) outputs can safely exceed -blockmaxweight, but the rest of the block template will be empty. - options.nBlockMaxWeight = std::clamp(options.nBlockMaxWeight, options.coinbase_max_additional_weight, DEFAULT_BLOCK_MAX_WEIGHT); + // Limit weight to between block_reserved_weight and MAX_BLOCK_WEIGHT for sanity: + // block_reserved_weight can safely exceed -blockmaxweight, but the rest of the block template will be empty. + options.nBlockMaxWeight = std::clamp(options.nBlockMaxWeight, options.block_reserved_weight, MAX_BLOCK_WEIGHT); return options; } @@ -99,14 +100,15 @@ void ApplyArgsManOptions(const ArgsManager& args, BlockAssembler::Options& optio if (const auto parsed{ParseMoney(*blockmintxfee)}) options.blockMinFeeRate = CFeeRate{*parsed}; } options.print_modified_fee = args.GetBoolArg("-printpriority", options.print_modified_fee); + options.block_reserved_weight = args.GetIntArg("-blockreservedweight", options.block_reserved_weight); } void BlockAssembler::resetBlock() { inBlock.clear(); - // Reserve space for coinbase tx - nBlockWeight = m_options.coinbase_max_additional_weight; + // Reserve space for fixed-size block header, txs count, and coinbase tx. + nBlockWeight = m_options.block_reserved_weight; nBlockSigOpsCost = m_options.coinbase_output_max_additional_sigops; // These counters do not include coinbase tx @@ -394,7 +396,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda ++nConsecutiveFailed; if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight > - m_options.nBlockMaxWeight - m_options.coinbase_max_additional_weight) { + m_options.nBlockMaxWeight - m_options.block_reserved_weight) { // Give up if we're close to full and haven't succeeded in a while break; } diff --git a/src/node/miner.h b/src/node/miner.h index 5e5d0b25f30d3..56101561b1102 100644 --- a/src/node/miner.h +++ b/src/node/miner.h @@ -176,7 +176,9 @@ class BlockAssembler /** Construct a new block template */ std::unique_ptr CreateNewBlock(); + /** The number of transactions in the last assembled block (excluding coinbase transaction) */ inline static std::optional m_last_block_num_txs{}; + /** The weight of the last assembled block (including reserved weight for block header, txs count and coinbase tx) */ inline static std::optional m_last_block_weight{}; private: diff --git a/src/node/txdownloadman_impl.cpp b/src/node/txdownloadman_impl.cpp index 8933e88a87fbc..452c75da05df3 100644 --- a/src/node/txdownloadman_impl.cpp +++ b/src/node/txdownloadman_impl.cpp @@ -578,9 +578,11 @@ CTransactionRef TxDownloadManagerImpl::GetTxToReconsider(NodeId nodeid) void TxDownloadManagerImpl::CheckIsEmpty(NodeId nodeid) { assert(m_txrequest.Count(nodeid) == 0); + assert(m_orphanage.UsageByPeer(nodeid) == 0); } void TxDownloadManagerImpl::CheckIsEmpty() { + assert(m_orphanage.TotalOrphanUsage() == 0); assert(m_orphanage.Size() == 0); assert(m_txrequest.Size() == 0); assert(m_num_wtxid_peers == 0); diff --git a/src/node/types.h b/src/node/types.h index 4b0de084ab3d0..290bbc23f1401 100644 --- a/src/node/types.h +++ b/src/node/types.h @@ -14,6 +14,7 @@ #define BITCOIN_NODE_TYPES_H #include +#include #include