diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md index 2eb6846747a..388ddd5453e 100644 --- a/contrib/seeds/README.md +++ b/contrib/seeds/README.md @@ -15,8 +15,7 @@ DNS seed, virtu's crawler, and asmap community AS map data. Run the following co from the `/contrib/seeds` directory: ``` -curl https://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt -curl https://21.ninja/seeds.txt.gz | gzip -dc >> seeds_main.txt +curl https://21.ninja/seeds.txt.gz | gzip -dc > seeds_main.txt curl https://mainnet.achownodes.xyz/seeds.txt.gz | gzip -dc >> seeds_main.txt curl https://signet.achownodes.xyz/seeds.txt.gz | gzip -dc > seeds_signet.txt curl https://testnet.achownodes.xyz/seeds.txt.gz | gzip -dc > seeds_test.txt diff --git a/doc/bips.md b/doc/bips.md index c814717a09f..1dd84c1a746 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -49,6 +49,7 @@ BIPs that are implemented by Bitcoin Core: * [`BIP 173`](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki): Bech32 addresses for native Segregated Witness outputs are supported as of **v0.16.0** ([PR 11167](https://github.com/bitcoin/bitcoin/pull/11167)). Bech32 addresses are generated by default as of **v0.20.0** ([PR 16884](https://github.com/bitcoin/bitcoin/pull/16884)). * [`BIP 174`](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki): RPCs to operate on Partially Signed Bitcoin Transactions (PSBT) are present as of **v0.17.0** ([PR 13557](https://github.com/bitcoin/bitcoin/pull/13557)). * [`BIP 176`](https://github.com/bitcoin/bips/blob/master/bip-0176.mediawiki): Bits Denomination [QT only] is supported as of **v0.16.0** ([PR 12035](https://github.com/bitcoin/bitcoin/pull/12035)). +* [`BIP 323`](https://github.com/bitcoin/bips/blob/master/bip-0323.mediawiki): BIP 9 bits 5 to 28 (inclusive) are ignored for soft-fork signalling and unknown soft fork warnings as of **v30.4**. * [`BIP 324`](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki): The v2 transport protocol specified by BIP324 and the associated `NODE_P2P_V2` service bit are supported as of **v26.0**, but off by default ([PR 28331](https://github.com/bitcoin/bitcoin/pull/28331)). On by default as of **v27.0** ([PR 29347](https://github.com/bitcoin/bitcoin/pull/29347)). * [`BIP 325`](https://github.com/bitcoin/bips/blob/master/bip-0325.mediawiki): Signet test network is supported as of **v0.21.0** ([PR 18267](https://github.com/bitcoin/bitcoin/pull/18267)). * [`BIP 339`](https://github.com/bitcoin/bips/blob/master/bip-0339.mediawiki): Relay of transactions by wtxid is supported as of **v0.21.0** ([PR 18044](https://github.com/bitcoin/bitcoin/pull/18044)). diff --git a/doc/release-notes.md b/doc/release-notes.md index f8ccd6615c1..854c7e44a5a 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,11 +1,11 @@ -v30.3 Release Notes +v30.x Release Notes =================== -Bitcoin Core version v30.3 is now available from: +Bitcoin Core version v30.x is now available from: - + -This release includes new features, various bug fixes and performance +This release includes various bug fixes and performance improvements, as well as updated translations. Please report bugs using the issue tracker at GitHub: @@ -40,128 +40,33 @@ unsupported systems. Notable changes =============== -This release fixes an issue where the chainstate database would repeatedly -rewrite large portions of itself, causing excessive disk reads and writes -during normal operation. +- BIP 9 bits 5 to 28 inclusive are now ignored for soft fork signaling, as per + BIP 323. We won't warn about unknown deployments when receiving blocks that + set any of those bits in their version. (#34779) -### Validation +### Versionbits -- #35209 validation: correct lifetime of precomputed tx data -- #35465 coins: compact chainstate regularly +- #34779 BIP 323: reserve version bits 5-28 as extra nonce space -### Leveldb +### P2P -- #61(bitcoin-core/leveldb): Disable seek compaction +- #35691 chainparams: delete my DNS seed +- #35766 p2p: Assume v2transport for addresses from seeds -### Wallet +### Fuzz -- #34358 wallet: fix removeprunedfunds bug with conflicting transactions -- #34870 wallet: feebumper, fix crash when combined bump fee is unavailable -- #34888 wallet: fix amount computed as boolean in coin selection -- #35228 wallet: use outpoint when estimating input size - -### Net - -- #34093 netif: fix compilation warning in QueryDefaultGatewayImpl() -- #34549 net: reduce log level for PCP/NAT-PMP NOT_AUTHORIZED failures - -### PSBT - -- #34272 psbt: Fix PSBTInputSignedAndVerified bounds assert -- #34219 psbt: validate pubkeys in MuSig2 pubnonce/partial sig deserialization - -### Miniscript - -- #34434 miniscript: correct and_v() properties - -### Build - -- #34228 depends: Unset SOURCE_DATE_EPOCH in gen_id script -- #34281 build: Temporarily remove confusing and brittle -fdebug-prefix-map -- #34554 build: avoid exporting secp256k1 symbols -- #34627 guix: use a temporary file over sponge, drop moreutils -- #34713 depends: Allow building Qt packages after interruption -- #34754 depends: Qt fixes for GCC 16 compatibility -- #34787 build: fix native macOS deployment -- #34848 cmake: Migrate away from deprecated SQLite3 target -- #34956 depends, qt: Fix build on aarch64 macOS 26.4 - -### Test - -- #34185 test: fix feature_pruning when built without wallet -- #34282 qa: Fix Windows logging bug -- #34390 test: allow overriding tar in get_previous_releases.py -- #34409 test: use ModuleNotFoundError in interface_ipc.py -- #34445 fuzz: Use AFL_SHM_ID for naming test directories -- #34608 test: Fix broken --valgrind handling after bitcoin wrapper -- #34690 test: Add missing timeout_factor to zmq socket -- #34869 tests: applied PYTHON_GIL to the env for every test -- #34918 fuzz: [refactor] Remove unused g_setup pointers -- #35080 test: Add missing self.options.timeout_factor scale in tool_bitcoin_chainstate.py - -### Util - -- #34597 util: Fix UB in SetStdinEcho when ENOTTY - -### Doc - -- #34252 doc: add 433 (Pay to Anchor) to bips.md -- #34413 doc: Remove outdated -fdebug-prefix-map section in dev notes -- #34510 doc: fix broken bpftrace installation link -- #34561 wallet: rpc: manpage: fix example missing `fee_rate` argument -- #34671 doc: Update Guix install for Debian/Ubuntu -- #34702 doc: Fix fee field in getblock RPC result -- #34706 doc: Improve dependencies.md IPC documentation -- #34789 doc: update build guides pre v31 -- #35283 doc: mention -DWITH_ZMQ=ON in BSD build guides - -### CI - -- #32513 ci: remove 3rd party js from windows dll gha job -- #34344 ci: update GitHub Actions versions -- #34453 ci: Always print low ccache hit rate notice -- #34461 ci: Print verbose build error message in test-each-commit -- #34802 ci: Bump GHA actions versions -- #34815 ci: bump cirruslabs actions versions -- #35202 ci: restore sockets in i686, no IPC job -- #35378 ci: switch runners from cirrus to warpbuild -- #35408 ci: 35378 followups - -### Misc - -- #35175 multi_index: fix compilation failure with boost >= 1.91 +- #35679 fuzz: Remove unused DeserializeFromFuzzingInput params overload Credits ======= Thanks to everyone who directly contributed to this release: -- ANAVHEOBA -- andrewtoth -- brunoerg -- Cory Fields -- Daniel Pfeifer +- ajtowns - darosior -- fanquake -- furszy - Hennadii Stepanov -- jayvaliya -- junbyjun1238 -- kevkevinpal -- Lőrinc -- m3dwards -- marcofleon -- MarcoFalke -- mzumsande -- nervana21 -- Padraic Slattery -- ryanofsky -- Sebastian Falbesoner -- SomberNight -- tboy1337 -- theuni -- ToRyVand -- willcl-ark +- Martin Zumsande +- sipa As well as to everyone that helped with translations on [Transifex](https://explore.transifex.com/bitcoin/bitcoin/). diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp index 2cbce2c56c7..25484254d2a 100644 --- a/src/kernel/chainparams.cpp +++ b/src/kernel/chainparams.cpp @@ -145,7 +145,6 @@ public: // This is fine at runtime as we'll fall back to using them as an addrfetch if they don't support the // service bits we want, but we should get them updated to support all service bits wanted by any // release ASAP to avoid it where possible. - vSeeds.emplace_back("seed.bitcoin.sipa.be."); // Pieter Wuille, only supports x1, x5, x9, and xd vSeeds.emplace_back("dnsseed.bluematt.me."); // Matt Corallo, only supports x9 vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch."); // Jonas Schnelli, only supports x1, x5, x9, and xd vSeeds.emplace_back("seed.btc.petertodd.net."); // Peter Todd, only supports x1, x5, x9, and xd diff --git a/src/net.cpp b/src/net.cpp index 50988114d0b..7fbcd24b743 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -204,7 +204,7 @@ static std::vector ConvertSeeds(const std::vector &vSeedsIn) while (!s.eof()) { CService endpoint; s >> endpoint; - CAddress addr{endpoint, SeedsServiceFlags()}; + CAddress addr{endpoint, SeedsAssumedServiceFlags()}; addr.nTime = rng.rand_uniform_delay(Now() - one_week, -one_week); LogDebug(BCLog::NET, "Added hardcoded seed: %s\n", addr.ToStringAddrPort()); vSeedsOut.push_back(addr); @@ -2365,7 +2365,7 @@ void CConnman::ThreadDNSAddressSeed() const auto addresses{LookupHost(host, nMaxIPs, true)}; if (!addresses.empty()) { for (const CNetAddr& ip : addresses) { - CAddress addr = CAddress(CService(ip, m_params.GetDefaultPort()), requiredServiceBits); + CAddress addr = CAddress(CService(ip, m_params.GetDefaultPort()), SeedsAssumedServiceFlags()); addr.nTime = rng.rand_uniform_delay(Now() - 3 * 24h, -4 * 24h); // use a random age between 3 and 7 days old vAdd.push_back(addr); found++; diff --git a/src/protocol.h b/src/protocol.h index 804597b86d8..ca968ab0020 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -353,6 +353,14 @@ std::vector serviceFlagsToStr(uint64_t flags); */ constexpr ServiceFlags SeedsServiceFlags() { return ServiceFlags(NODE_NETWORK | NODE_WITNESS); } +/** + * Service flags we assume for addresses obtained from the DNS seeds and the + * fixed seeds, which don't come with service flags attached. + * BIP324 support can be safely assumed because the vast majority of listening nodes signals NODE_P2P_V2, and if the + * assumption is wrong for a given peer we simply reconnect using v1 transport. + */ +constexpr ServiceFlags SeedsAssumedServiceFlags() { return ServiceFlags(SeedsServiceFlags() | NODE_P2P_V2); } + /** * Checks if a peer with the given service flags may be capable of having a * robust address-storage DB. diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp index b7dea44b0b2..0b7c2d63072 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -55,14 +55,6 @@ namespace { struct invalid_fuzzing_input_exception : public std::exception { }; -template -DataStream Serialize(const T& obj, const P& params) -{ - DataStream ds{}; - ds << params(obj); - return ds; -} - template T Deserialize(DataStream&& ds, const P& params) { @@ -71,18 +63,6 @@ T Deserialize(DataStream&& ds, const P& params) return obj; } -template -void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj, const P& params) -{ - DataStream ds{buffer}; - try { - ds >> params(obj); - } catch (const std::ios_base::failure&) { - throw invalid_fuzzing_input_exception(); - } - assert(buffer.empty() || !Serialize(obj, params).empty()); -} - template DataStream Serialize(const T& obj) { @@ -114,7 +94,7 @@ void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj) template void AssertEqualAfterSerializeDeserialize(const T& obj, const P& params) { - assert(Deserialize(Serialize(obj, params), params) == obj); + assert(Deserialize(Serialize(params(obj)), params) == obj); } template void AssertEqualAfterSerializeDeserialize(const T& obj) diff --git a/src/test/fuzz/versionbits.cpp b/src/test/fuzz/versionbits.cpp index 5a7722d8708..1b15cb8c57a 100644 --- a/src/test/fuzz/versionbits.cpp +++ b/src/test/fuzz/versionbits.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -31,7 +32,7 @@ public: { assert(dep.period > 0); assert(dep.threshold <= dep.period); - assert(0 <= dep.bit && dep.bit < 32 && dep.bit < VERSIONBITS_NUM_BITS); + assert(0 <= dep.bit && dep.bit < 32 && dep.bit < VERSIONBITS_MAX_NUM_BITS); assert(0 <= dep.min_activation_height); } @@ -126,7 +127,7 @@ FUZZ_TARGET(versionbits, .init = initialize) assert(0 < dep.threshold && dep.threshold <= dep.period); // must be able to both pass and fail threshold! // select deployment parameters: bit, start time, timeout - dep.bit = fuzzed_data_provider.ConsumeIntegralInRange(0, VERSIONBITS_NUM_BITS - 1); + dep.bit = fuzzed_data_provider.ConsumeIntegralInRange(0, VERSIONBITS_MAX_NUM_BITS - 1); if (always_active_test) { dep.nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; diff --git a/src/test/util/versionbits.h b/src/test/util/versionbits.h new file mode 100644 index 00000000000..478b7882fab --- /dev/null +++ b/src/test/util/versionbits.h @@ -0,0 +1,13 @@ +// Copyright (c) 2026-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. + +#ifndef BITCOIN_TEST_UTIL_VERSIONBITS_H +#define BITCOIN_TEST_UTIL_VERSIONBITS_H + +#include + +/** Total possible bits available for versionbits per original BIP 9 specification */ +static constexpr int VERSIONBITS_MAX_NUM_BITS{29}; + +#endif // BITCOIN_TEST_UTIL_VERSIONBITS_H diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 9de57393282..df00b08e6fd 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -453,9 +454,19 @@ BOOST_FIXTURE_TEST_CASE(versionbits_computeblockversion, BlockVersionTest) // not take precedence over STARTED/LOCKED_IN. So all softforks on // the same bit might overlap, even when non-overlapping start-end // times are picked. - const uint32_t dep_mask{uint32_t{1} << chainParams->GetConsensus().vDeployments[dep].bit}; + const auto& dep_info = chainParams->GetConsensus().vDeployments[dep]; + const uint32_t dep_mask{uint32_t{1} << dep_info.bit}; BOOST_CHECK(!(chain_all_vbits & dep_mask)); chain_all_vbits |= dep_mask; + BOOST_CHECK(0 <= dep_info.bit && dep_info.bit < VERSIONBITS_MAX_NUM_BITS); + if (chain_type != ChainType::REGTEST) { + if (dep == Consensus::DEPLOYMENT_TESTDUMMY) { + BOOST_CHECK_EQUAL(dep_info.nStartTime, Consensus::BIP9Deployment::NEVER_ACTIVE); + BOOST_CHECK_EQUAL(dep_info.nTimeout, Consensus::BIP9Deployment::NO_TIMEOUT); + } else { + BOOST_CHECK(dep_info.bit < VERSIONBITS_NUM_BITS); + } + } check_computeblockversion(vbcache, chainParams->GetConsensus(), dep); } } diff --git a/src/versionbits.h b/src/versionbits.h index abd671b4efd..767e9e65fc8 100644 --- a/src/versionbits.h +++ b/src/versionbits.h @@ -21,8 +21,8 @@ static const int32_t VERSIONBITS_LAST_OLD_BLOCK_VERSION = 4; static const int32_t VERSIONBITS_TOP_BITS = 0x20000000UL; /** What bitmask determines whether versionbits is in use */ static const int32_t VERSIONBITS_TOP_MASK = 0xE0000000UL; -/** Total bits available for versionbits */ -static const int32_t VERSIONBITS_NUM_BITS = 29; +/** Total bits available for versionbits (BIP 323) */ +static const int32_t VERSIONBITS_NUM_BITS = 5; /** Opaque type for BIP9 state. See versionbits_impl.h for details. */ enum class ThresholdState : uint8_t; @@ -72,7 +72,8 @@ struct BIP9GBTStatus { }; /** BIP 9 allows multiple softforks to be deployed in parallel. We cache - * per-period state for every one of them. */ + * per-period state for every one we implement and warning state for each + * BIP 323 allowed bit. */ class VersionBitsCache { private: diff --git a/test/functional/feature_versionbits_warning.py b/test/functional/feature_versionbits_warning.py index 96ec7c570fa..4e8049dd3a9 100755 --- a/test/functional/feature_versionbits_warning.py +++ b/test/functional/feature_versionbits_warning.py @@ -18,8 +18,13 @@ from test_framework.test_framework import BitcoinTestFramework VB_PERIOD = 144 # versionbits period length for regtest VB_THRESHOLD = 108 # versionbits activation threshold for regtest VB_TOP_BITS = 0x20000000 -VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment + +# Choose a bit unassigned to any deployment, or start the +# node with the deployment matching this bit disabled. +VB_UNKNOWN_BIT = 3 VB_UNKNOWN_VERSION = VB_TOP_BITS | (1 << VB_UNKNOWN_BIT) +VB_IGNORED_BIT = 5 +VB_IGNORED_VERSION = VB_TOP_BITS | (1 << VB_IGNORED_BIT) WARN_UNKNOWN_RULES_ACTIVE = f"Unknown new rules activated (versionbit {VB_UNKNOWN_BIT})" VB_PATTERN = re.compile("Unknown new rules activated.*versionbit") @@ -76,11 +81,24 @@ class VersionBitsWarningTest(BitcoinTestFramework): assert not VB_PATTERN.match(",".join(node.getmininginfo()["warnings"])) assert not VB_PATTERN.match(",".join(node.getnetworkinfo()["warnings"])) + self.log.info("Check that there is no warning if previous VB_BLOCKS have VB_PERIOD blocks with ignored versionbits version.") + # Build one period of blocks with VB_THRESHOLD blocks signaling some unknown bit + self.send_blocks_with_version(peer, VB_THRESHOLD, VB_IGNORED_VERSION) + self.generatetoaddress(node, VB_PERIOD - VB_THRESHOLD, node_deterministic_address) + + # Move the ignored deployment state to ACTIVE and make sure we're out of IBD. + self.generatetoaddress(node, VB_PERIOD, node_deterministic_address) + self.wait_until(lambda: not node.getblockchaininfo()['initialblockdownload']) + + # Check that we're not getting any versionbit-related warnings in get*info() + assert not VB_PATTERN.match(", ".join(node.getmininginfo()["warnings"])) + assert not VB_PATTERN.match(", ".join(node.getnetworkinfo()["warnings"])) + + self.log.info("Check that there is a warning if previous VB_BLOCKS have >=VB_THRESHOLD blocks with unknown versionbits version.") # Build one period of blocks with VB_THRESHOLD blocks signaling some unknown bit self.send_blocks_with_version(peer, VB_THRESHOLD, VB_UNKNOWN_VERSION) self.generatetoaddress(node, VB_PERIOD - VB_THRESHOLD, node_deterministic_address) - self.log.info("Check that there is a warning if previous VB_BLOCKS have >=VB_THRESHOLD blocks with unknown versionbits version.") # Mine a period worth of expected blocks so the generic block-version warning # is cleared. This will move the versionbit state to ACTIVE. self.generatetoaddress(node, VB_PERIOD, node_deterministic_address)