From 607d6dd925819b736609a114d36ff26d85bd5941 Mon Sep 17 00:00:00 2001 From: Alexander Wiederin Date: Fri, 4 Sep 2026 11:23:53 +0200 Subject: [PATCH 1/6] Squashed 'libbitcoinkernel-sys/bitcoin/' changes from 70d9ec7f3d4..97462c683d4 97462c683d4 kernel: Add script tracer ea7d459ac08 Merge bitcoin/bitcoin#36057: build: check for SetThreadDescription() at configure time 204256c73f2 Merge bitcoin/bitcoin#35900: iwyu: Fix warnings in `src/interfaces` and treat them as errors da1cb4dd90e Merge bitcoin/bitcoin#35586: doc: note -blocknotify is not run during IBD/reindex in help text b31aae4f9af Merge bitcoin/bitcoin#36094: ci: bump riscv toolchain to tag 2026.08.25 607f220c6cf Revert "ci: use mirror for riscv submodules" 64af18f4e6d ci: bump riscv toolchain to tag 2026.08.25 fd573f6db9d Merge bitcoin/bitcoin#36044: test: cover OP_SUCCESSx bypassing the initial stack element size limit 2224e4af6ce Merge bitcoin/bitcoin#35850: fuzz: Implement `connect_block` harness 2777300c68f fuzz: Implement connect_block harness bed46bd16c2 build: check for SetThreadDescription() at configure time 40add915be5 test: Add reset to CuckooCache a24110cef7f Merge bitcoin/bitcoin#36092: fix: UB sanitizer in mempool estimator logging 8b84f917789 Merge bitcoin/bitcoin#36088: util: Set Univalue to null after read failure 576a0ebb536 fix: UB sanitizer in mempool estimator logging 5f45583e437 Merge bitcoin/bitcoin#36077: bugfix: give TxDownloadManager its own RNG fa72de78a93 util: Set Univalue to null after read failure fa7786592d7 test: Add UniValue failed read test e339043ee9e Merge bitcoin/bitcoin#35829: http: Make class fields private and make HTTPResponse a struct 031175197f1 Merge bitcoin/bitcoin#36032: rpc: avoid quadratic output lookups b91d983f66f Merge bitcoin/bitcoin#36078: qa: Reduce `-maxconnections` in the functional test framework 0f5c6d0b64a Merge bitcoin/bitcoin#35618: depends: Make tarball creation from local directory reproducible b8a8893bf2a qa: Lower `-rpcmaxconnections` in `interface_http.py` test 6f4109b4489 qa: Reduce `-maxconnections` in the functional test framework 80eaa6cabf2 bugfix: give TxDownloadManager its own RNG 5e0d7a286a4 refactor: Drastically narrow scope of http_bitcoin namespace and rename it to bitcoin_http 8f9fd8698a7 refactor: Make HTTPRemoteClient fields private d72f67fd6c9 refactor: Expose additional HTTPRemoteClient fields through accessors 10bbae302fb refactor: Expose HTTPRemoteClient fields to tests through methods 5b06d908316 refactor: Replace HTTPServer::MaybeDispatchRequestsFromClient() with HTTPRemoteClient::TryReadRequest() 794a753958a Merge bitcoin/bitcoin#35583: test: close the listeners before terminating the event loop f6b3f2ff6b1 Merge bitcoin/bitcoin#36064: qa: Minor improvement follow-ups to 35730 6a028161daf Merge bitcoin/bitcoin#36025: psbt: avoid duplicate taproot leaf script keys when merging 07d92a9d65a Merge bitcoin/bitcoin#35516: rpc: preserve global xpubs and proprietary fields in joinpsbts 4375d74d24c Merge bitcoin/bitcoin#34993: wallet: `NotifyCanGetAddressesChanged` when advancing `next_index` 290be9eafa4 qa: Minor feature_init.py improvements 6248331b295 qa: Switch to warning when skipping tests 04cf9ecee43 Merge bitcoin/bitcoin#35978: contrib/init: fix unused variables in openrc script aed80c73958 Merge bitcoin/bitcoin#36067: test: Remove `BOOST_CHECK_CLOSE` in favor of exact comparison 07ca9ba9e84 Merge bitcoin/bitcoin#36059: test: make index crash test check saved state 402f1fdae6a Merge bitcoin/bitcoin#36063: refactor: [test] Remove deprecated SetMockTime(i64) alias 135e05cfa07 Merge bitcoin/bitcoin#36046: fuzz: Use ImmediateBackgroundTaskRunner in process_messages 9e115edd39f test: Remove `BOOST_CHECK_CLOSE` in favor of exact comparison 6d570415a01 refactor(qa): Move check right below related check 7e3b60584b3 refactor(qa): Simplify through using assert_raises() fad1e6bf238 util: refactor: Remove deprecated SetMockTime(i64) alias faf87c3535c test: refactor: Use FakeNodeClock over manual/global SetMockTime 994c17d6c0a Merge bitcoin/bitcoin#34697: descriptor: fix musig() duplicate key checks and doubled PSBT origin paths a1183c02aac refactor: Extract Send() and Receive() into HTTPRemoteClient from HTTPServer 6d9b61d4f8d refactor: Extract HTTPRemoteClient::MaybeDisconnect() from HTTPServer::DisconnectClients() 6fec8d6914b refactor: Make HTTPRequest fields private b8cd77237b3 refactor: Make HTTPRequest::GetHeader() return saner optional type 1cb416397b7 psbt: avoid duplicate taproot leaf script keys when merging 32765aca5c3 Merge bitcoin/bitcoin#35730: http: limit connected HTTPRemoteClients a3335994a84 Merge bitcoin/bitcoin#35580: bugfix: compare non-adjusted chunk weight against block weight limit 0ea81904ebd Merge bitcoin/bitcoin#35933: psbt: don't abort on invalid MuSig2 derivations 7ea36e985a9 test: preserve index crash test state 5aa15df60c4 test: expose missing index crash checkpoint b3ff9c4d683 iwyu: Fix warnings in `src/interfaces` and treat them as errors d564b0255f7 iwyu: Add temporary mapping to work around upstream bug 58a7869f860 Merge bitcoin/bitcoin#36051: ci: use ruff 0.16.x f5e91c6fbae Merge bitcoin/bitcoin#35884: util: set os-level thread names on Windows a1e27162257 Merge bitcoin/bitcoin#36045: test: avoid undersized Boost.Test signal stacks 9d0c38db746 ci: use mypy 2.3.1 7a53beca06a ci: use pyzmq 27.2.0 f29f076f3c2 ci: use ruff 16 7dcb7f09ed6 Merge bitcoin/bitcoin#34075: fees: Introduce Mempool Based Fee Estimation to reduce overestimation 5e8586ec5b0 Merge bitcoin/bitcoin#36019: bench: Construct CTxOut and COutPoint in a single expression 950bdb763e1 bench: Construct CTxOut and COutPoint in a single expression bf8402c8803 Merge bitcoin/bitcoin#32958: wallet/refactor: Update SignPSBTInput to return util::Expected and remove PSBTError:Ok 02306cc915c Merge bitcoin/bitcoin#35161: consensus: document merkle mutation root invariant fae6665f013 fuzz: Use ImmediateBackgroundTaskRunner in process_messages 9eba3aafa6c test: avoid undersized Boost.Test signal stacks 747cff84248 rpc: avoid quadratic output lookups 7f9c4e29289 doc: add release notes e18d392689d test: add mempool estimator i/o fuzz test 970f02096d3 fees: persist mempool policy estimator data 7dcb37989d2 fees: move fee_estimates.dat into fees directory 0db2b69e6db rpc: add verbosity option to estimatesmartfee options 06bb65730eb fees: gate mempool estimates on recent block coverage cfe585df25c validation: emit block mempool removal signal from ConnectTip 0d88558f951 fees: return mempool estimates when it's lower than block policy 56db08d5291 Merge bitcoin/bitcoin#35877: build: ci/doc win64-cross build via nix 693b1351aff fees: add caching to MemPoolFeeRateEstimator c9bb3df29ff fees: add MemPoolFeeRateEstimator class 558e26e66e0 test: cover OP_SUCCESSx bypassing the initial stack element size limit e5be0dc35e8 refactor: Make HTTPResponse a struct since all fields are public 69c61f9f2f3 Merge bitcoin/bitcoin#36034: Release: Prepare "Translation string freeze" step 87b8a4ee506 Merge bitcoin-core/gui#944: Fix out-of-bounds read in RPCParseCommandLine on empty command f9cc0c020c2 Merge bitcoin/bitcoin#36020: doc: Correct after HTTPRequest::m_client changed to weak_ptr 5a431c957d1 qt: Update `src/qt/locale/bitcoin_en.ts` translation source file 08dfaa04f4c Merge bitcoin/bitcoin#36018: test: [refactor] Properly use BOOST_CHECK_EXCEPTION fa0fe212f52 test: [refactor] Properly use BOOST_CHECK_EXCEPTION 436921eb469 test: check joinpsbts preserves global xpubs and proprietary fields 011094b282b rpc: preserve global xpubs and proprietary fields in joinpsbts 367b2202a49 Merge bitcoin/bitcoin#35665: psbt: avoid duplicate global xpub keys when merging bab030a6feb Merge bitcoin/bitcoin#35859: wallet: use unsigned KDF iteration count 21ee7f6c00b Merge bitcoin/bitcoin#35069: Refactor keypath parser a07f1313b14 Merge bitcoin/bitcoin#35980: contrib: reject divergent verify-commits history 32dfed44a2a Merge bitcoin/bitcoin#36012: psbt: Remove unused `IsNull()` methods 8c366094b89 Merge bitcoin/bitcoin#35956: fuzz: scope fake clocks to target phases 4d86d9cc7ed Merge bitcoin/bitcoin#35968: test: sync funding block before isolating nodes 8c1d776bf2c Merge bitcoin/bitcoin#35965: test: Tighten Coin equality and add debug output fa8762da626 build: ci/doc win64-cross build via nix fafe7205cc8 doc: Clarify that cygwin/msys2 are not tested/supported 4b991d7b5fe Merge bitcoin/bitcoin#34239: depends: Hash included makefiles in package checksums fe5e2a6319b Merge bitcoin/bitcoin#32162: depends: Switch from multilib to platform-specific toolchains 4e5327bc988 fuzz: refactor: scope fake clocks to target phases 15e5c35c451 doc: Correct comments after HTTPRequest::m_client was changed from shared to weak pointer 1156ce67545 test: Tighten `Coin` equality and add debug output 59224b66aa1 Merge bitcoin/bitcoin#36008: wallet: WalletBatch->WriteVersion respect argument 2c16efbb7b5 psbt: Remove unused IsNull() methods dd669f40b98 util: set os-level thread names on Windows b88bffe550a Merge bitcoin/bitcoin#36010: test: Print os exit code on failure 0fd515bbb70 Merge bitcoin/bitcoin#36009: miniscript: remove unused context argument from ParseHexStr 15a7a4ed7c4 Merge bitcoin/bitcoin#35952: kernel: prevent dangling iterators from temporary ranges ac6b6c1f06e Merge bitcoin/bitcoin#35680: private broadcast: bound rebroadcast attempts to 1,000 d411bb02ff8 Merge bitcoin/bitcoin#35993: guix: build glibc with `--enable-kernel=3.17.0` fada80192bd test: Print os exit code on failure 381c3312191 Merge bitcoin/bitcoin#36007: http: Make HTTPRequest::m_client a weak_ptr 82b3bfe38c0 Merge bitcoin/bitcoin#35797: psbt: support output metadata updates before inputs are added 681b429393e Merge bitcoin/bitcoin#35986: p2p: reconsider orphans when missing inputs are mined 16f4bd15bc9 Merge bitcoin/bitcoin#35954: qa: Disable Qt's glib event dispatcher for GUI tests on OpenBSD 1fdd208c1ce miniscript: remove unused context argument from ParseHexStr 4ca07c2fb3d Merge bitcoin/bitcoin#35963: doc : update cjdns docs to discourage using onlynet option 4b4ae6e37c5 Merge bitcoin/bitcoin#35995: doc: fix outdated URL in hash_tests.cpp a23df4bfa87 Merge bitcoin/bitcoin#35946: rpc: Improve some type specs for openrpc 20ad7c9eab8 Merge bitcoin/bitcoin#35955: wallet: remove orphaned GetAffectedKeys and LegacyScriptPubKeyMan declarations 979a42ec173 http: Make HTTPRequest::m_client a weak_ptr cf36df070b4 Wallet: Check crypter return values 777aee77d12 refactor: deduplicate keypath element parsing 7d8fddfba25 refactor: define BIP32_HARDENED and BIP32_UNHARDENED constants e4d80e7001e test: close the loop after the network thread has completed 29fba5ddbb9 test: close the listeners before terminating the event loop bd4b1524eab init: do not count file descriptors for HTTPServer if -server=0 b08662060db init: account for maximum file descriptors needed by HTTP 158efbc723d doc: fix outdated URL in hash_tests.cpp 9cacf677a91 rpc: add fee_rate_estimator option to estimatesmartfee ba6c61bbdd3 fees: add FeeRateEstimatorManager class 2cb6b831e03 fees: add EstimateFeeRate and MaximumTarget to CBlockPolicyEstimator 5adb2ab0843 refactor: test block policy estimator directly 9c8309a8909 test: rename policy estimator tests to block policy estimator tests e3d5ef1b5fb fees: move StringForBlockPolicyEstimateReason to block policy estimator 74245c20e05 fees: split wallet and estimator fee reasons ec5d19665b8 wallet: WalletBatch->WriteVersion respect argument. cc2acebefb0 http: configure simultaneous connection limit with -rpcmaxconnections b3d6d2d1a7e http: limit connected clients to 16 86651d81971 scripted-diff: Rename nUserBind, nBind, nMaxConnections to snake_case 5548818115c guix: build glibc with --enable-kernel=3.17.0 f72537037d3 Merge bitcoin/bitcoin#35972: fuzz: Fix assertion in `txorphan` 4800cb7aea0 Merge bitcoin/bitcoin#35735: Add state to HTTPRequest e0992599a63 Merge bitcoin/bitcoin#35846: test: Use throwing config parser getters without fallback e5977f0b9e5 Merge bitcoin/bitcoin#35982: Update minisketch subtree to latest master fe7dbde52c9 Merge bitcoin/bitcoin#35976: test: Speedup fee estimation functional test with batching 9cc7dc50bdc p2p: reconsider orphans when missing inputs are mined c90c23d388f Merge bitcoin/bitcoin#35531: txindex: hash keys and pack positions to reduce disk usage 2dcb2c6df20 Update minisketch subtree to latest master 461e3be8d3d Squashed 'src/minisketch/' changes from d1bd01e189..4a179c61e3 05c36d9fadc Merge bitcoin-core/gui#957: fix: add .dat file extension automatically when exporting watchonly 75a4e6c6788 gui: fix allow restore wallets without .dat file extension a8b582ec1d2 Merge bitcoin/bitcoin#32784: wallet: derivehdkey RPC to get xpub at arbitrary path 465bca734eb contrib: reject divergent verify-commits history b3d1dca3388 contrib: fail on verify-commits ancestry errors d837bb38a44 contrib/init: fix unused variables in openrc script fe7d475d450 private broadcast: bound broadcast attempts per tx to 1k b3d77ea0275 test: Speedup fee estimation functional test with batching 683e05a265c Merge bitcoin/bitcoin#35889: rpc: avoid quadratic `gettxspendingprevout` work and preserve order 230185a5ee7 Merge bitcoin/bitcoin#35971: net_processing: remove unused code ae36e2ef798 rpc: avoid quadratic prevout resolution da1eaeb3507 rpc: preserve `gettxspendingprevout` order f98753e7621 refactor: identify prevouts by request index 221a3fe5cfb test: cover mixed `gettxspendingprevout` order 02de12b1e61 wallet: remove remaining LegacyScriptPubKeyMan references d194be69d60 wallet: remove orphaned GetAffectedKeys declaration 01dde6b2057 fuzz: Fix assertion in txorphan dec68f997e7 Merge bitcoin/bitcoin#35852: scripted-diff: Use inline const(expr) over static constexpr in headers e95bab98f03 Merge bitcoin/bitcoin#35960: common: remove `::runtime_error` from `RunCommandParseJSON` aad830ac4a6 Merge bitcoin/bitcoin#35847: test: move more tests to `baseindex_tests` and run them for all indexes b76afff2749 Wallet: Use unsigned KDF iteration count e07d826e0eb rpc: Fix type in ApplyTypeStrOverride 0cff3cc5187 net_processing: Remove redundant porphanTx in ProcessOrphanTx c7eacbd45b0 net_processing: remove Peer& from UpdatePeerStateForReceivedHeaders 8454fb2bd74 test: sync funding block before isolating nodes 8b5da677d7b common: remove ::runtime_error from RunCommandParseJSON 25bed560bed test: add forward-compat functional test for txindex 703304ed8c1 doc: add release notes for txindex disk usage and downgrading 8e5320a2d24 tests: cover txindex hash prefix collisions and legacy fallback b75efa19ba8 txindex: skip bloom filters and legacy lookups for new databases 004d7c098ca txindex: hash key prefixes and pack block positions 5a255970fd1 refactor: move txindex db constants and legacy key to txindex_key.h 327660134cb txindex: pass the full block to DB::WriteTxs 42771e79980 txindex: use a new block locator for downgrade safety 4b08baed72c txindex: return optional tx and block hash from FindTx fc0dcf950f9 kernel: keep range iterators tied to their owner 0936c55f626 test: characterize kernel range iterators ef501a63d9d consensus: document merkle mutation root invariant 11090c8bb35 Merge bitcoin/bitcoin#35951: doc: release note about I2P ElGamal sunset beefda21be3 doc : update cjdns docs to discourage using onlynet option b2c45888fde Merge bitcoin/bitcoin#35866: test: Verify unwelcome RPC clients are rejected before reading their requests c0792889673 psbt: update output metadata without inputs 4f5712476a3 test: characterize P2WSH miniscript output e24e8fa2a68 test: characterize PSBT output metadata 625f951ba2f Merge bitcoin/bitcoin#35959: Update secp256k1 subtree to latest master e9ed5e83a39 Merge bitcoin/bitcoin#35605: wallet: rpc: Deprecate `removeprunedfunds` RPC 800ad9c3c0c doc: release note I2P ElGamal sunset 2f72123f613 Merge bitcoin/bitcoin#35867: test: classify SOCKS5 peers via getpeerinfo addrbind f464f6cd67e Update secp256k1 subtree to lastest master 09cc345c3e3 Squashed 'src/secp256k1/' changes from d2d04864ef..687155df6b c94074fa1b1 rpc: Surface OBJ_USER_KEYS description for openrpc c020c21d543 rpc: Handle skip type args for openrpc e33410d8884 fuzz: document arbitrary mocktimes 4c045f1a032 Merge bitcoin/bitcoin#35945: depends, qt: Add patch for missing headers b0615672352 Merge bitcoin/bitcoin#35947: build, msvc: Update vcpkg manifest baseline 1f5c46f7ce2 Merge bitcoin/bitcoin#35931: ci: Check DLL imports of cross-built `bitcoind.exe` b42f7fade0c descriptor: don't prepend key origins twice 7b15e2cb442 descriptor: fix duplicate check for hardened keys 1bec7fa22c9 Merge bitcoin/bitcoin#35496: kernel: add `btck_set_mock_time` for testing time-dependent paths c1967c4453b Merge bitcoin/bitcoin#35950: Update leveldb subtree to latest master 512dc9af1b1 Merge bitcoin/bitcoin#35930: wallet: post-#35501 cleanups in CWalletTx b970bb34d0c Merge bitcoin/bitcoin#33585: cmake: Use builtin support for .manifest files de2adc308a4 qa: Disable Qt's glib event dispatcher for GUI tests on OpenBSD aa0e0f793fe Merge bitcoin/bitcoin#35729: refactor: test: Unroll `&&` conditions in macros 3e76d22de25 Update leveldb subtree to latest master 9f10ef5e96d Squashed 'src/leveldb/' changes from a7f9bdc611..13da2d6758 2c01832f7be Merge bitcoin/bitcoin#35493: wallet, descriptor: Fix MuSig private key completeness checks on `importdescriptors` b80cee03619 Merge bitcoin/bitcoin#35924: Wallet, refactor: Remove orphaned EraseWatchOnly function 5d051c05629 Merge bitcoin/bitcoin#35943: doc: fix dead link in txrequest.h 4ca182ca402 doc: clarify alternate_wtxids is empty when only one witness variant fa48b5d28eb test: assert listsinceblock "removed" reports current canonical wtxid 9b96ee12881 wallet, test: add unit test for variant txid validation in CWalletTx deserializer 9de6543cb55 wallet: post-#35501 cleanup in CWalletTx e2bf51543ad build, msvc: Disable default features of the `sqlite3` package a31425610af build, msvc: Update vcpkg manifest baseline 757aa573c45 Merge bitcoin/bitcoin#33186: wallet, test: Ancient Wallet Migration from v0.14.3 (no-HD and Single Chain) e8cc21c57f9 Merge bitcoin/bitcoin#35925: wallet, rpc: Exclude non-owned addresses from listreceivedby* e8500cbd19d depends, qt: Add patch for missing headers 9954aa77280 http: don't parse any new requests from a client if m_req_busy = true c7db3ae1f90 test: cover HTTPRequest state machine 90676e24ad1 Add state to HTTPRequest to avoid duplicate work over I/O cycles 99497b38f6c cmake: Unconditionally add .rc files to sources 654a4cf5e69 cmake: Use builtin support for .manifest files 8f695379f31 cmake: Unconditionally set WIN32_EXECUTABLE target property 507e528e845 http: reuse HTTPHeaders to parse chunked trailer 902d8908c94 http: only read one HTTPRequest at a time per client a7b0b5084a4 doc: fix dead link in txrequest.h 1d386c250f2 Merge bitcoin/bitcoin#35941: doc: remove mention of `::wsystem` 57246934e71 doc: remove mention of wsystem 5973e075882 Merge bitcoin/bitcoin#35937: test: Append print_suppressions=0 to LSAN_OPTIONS, and suppress bitcoin-qt b6bd573eb97 Merge bitcoin/bitcoin#34794: rest: add Cache-Control headers to REST responses d055a3ab100 test: verify disallowed RPC clients are rejected upon `accept()` 128456b62d5 Merge bitcoin/bitcoin#35260: doc: clarify test placement guidance fad9ab714b5 test: Append print_suppressions=0 to LSAN_OPTIONS, and suppress bitcoin-qt 05a7c470d28 Merge bitcoin/bitcoin#35822: fuzz: reset SOCKS5 interrupt between inputs 73a94b45459 psbt: avoid aborting on invalid MuSig2 derivations e3d1e75a519 test: characterize MuSig2 derivation aborts 1be0b46297c Merge bitcoin/bitcoin#35898: rpc: fix mempool entry vsize docs 5f4d5626e7f Merge bitcoin/bitcoin#35908: doc: Update NetBSD Build Guide 8397e09e6ba Merge bitcoin/bitcoin#35928: doc: mention -DWITH_ZMQ=ON in macOS build guide 4b4e63f2823 Merge bitcoin/bitcoin#35704: windows: remove deprecated codecvt via UTF-8 narrow APIs 67fee5bf440 ci: Check DLL imports of cross-built `bitcoind.exe` 089c883c558 test: Add coverage for listreceivedby* excluding "send" addresses 873c0548059 wallet: Exclude non-owned addresses from listreceivedby* c3945bfd2bf doc: use derivehdkey in multisig tutorial 3662e336697 test: use derivehdkey in M-of-N multisig demo d9570f08383 rpc: add derivehdkey 62da9f96145 wallet: add GetExtKey helper 222855ed112 doc: mention -DWITH_ZMQ=ON in macOS build guide aaf1548475d wallet: generalize GetActiveHDPubKeys helper 3821452c4af refactor: add hardened derivation helper 0ab61caafd1 rpc: ParsePathBIP32 helper e36c4b76e19 util: reject out-of-range BIP32 keypath indices ba78c31a00c fuzz: check ParseHDKeypath/WriteHDKeypath round-trip 8cce969085d Have ParseHDKeypath handle h derivation marker fc530777623 test: move parse_hd_keypath test to bip32_tests dab525eb771 key: add DeriveExtKey() helper 71c06c5cbcd Merge bitcoin/bitcoin#35830: fees: Return false for incompatible fee estimates 55dfc244143 Merge bitcoin/bitcoin#35915: Release: Prepare "Open Transifex translations for `v32.0`" step f11dc6170ed Merge bitcoin/bitcoin#35482: fuzz: exercise the transaction-handling path in process_message(s) 6f906106d73 Merge bitcoin/bitcoin#35879: ci: Fix $BASE_ROOT_DIR installation d36bf709f7f Merge bitcoin/bitcoin#35914: test, fuzz: Remove unused variables ed2c59ab654 Merge bitcoin/bitcoin#35896: refactor: Default uint256::operator==, add operator<=> fae7ba9abae ci: Fix $BASE_ROOT_DIR installation fabe100c2b3 test: Use throwing config parser getters without fallback fa8acd57cd1 test: Write true/false values in config.ini 6304789a18f Wallet, refactor: Remove orphaned EraseWatchOnly function 6b6d77cc84e windows: remove deprecated codecvt via UTF-8 narrow APIs b388674acf0 Merge bitcoin/bitcoin#35872: rpc: avoid descriptor range counter overflow c36ffd870e8 Merge bitcoin/bitcoin#35842: rpc: Properly make RPCResult::Type::ANY non-test-only 7cb9aaaee80 Merge bitcoin/bitcoin#35759: fuzz: check http_request body matches framing 5b008514dbe Merge bitcoin/bitcoin#35878: net_processing: process unique tx INVs only 3175d576288 test, refactor: Remove unused `error` in `wallet_tests.cpp` 422f1bd92f1 test, refactor: Remove unused `utxo_pool` in `coinselector_tests.cpp` e550945a394 test, refactor: Remove unused `removed_refs` in `txgraph_tests.cpp` a061b011b78 Merge bitcoin/bitcoin#35912: doc: fix stale bitcoin_en.xlf reference 950b1c09225 Merge bitcoin/bitcoin#34927: test: Check that RPCs do not time out, even under load bd01e66f0a7 Merge bitcoin/bitcoin#35885: ci: switch to a sourceware mirror for riscv fa2e76d397a bench: Add base_blob compare bench via uint256 97abf95f48a qt: Update the `src/qt/locale/bitcoin_en.ts` translation source file 81fcecfe452 Revert "ci: Temporarily remove riscv32 config from GHA matrix" b283e1751cc ci: use mirror for riscv submodules fa7bc26d127 test: Check that RPCs do not time out, even under load fa2bd96cc0d test: Map cli CalledProcessError on server error to JSONRPCException e50f422d25f test, refactor: Remove unused variables in `test/rbf_tests.cpp` b7ae50e2e27 fuzz, refactor: Remove unused `header` in `p2p_transport_serialization.cpp` 3df0d067ade fuzz, refactor: Remove unused `random_string` in `locale.cpp` fc28914de4e fuzz, refactor: Remove unused `linearization` in `cluster_linearize.cpp` da58e559865 test, refactor: Remove unused `warnings` in `wallet/test/util.cpp` 4df077d7cd3 Merge bitcoin/bitcoin#35910: refactor: Remove unused newFeeRate var in ReplacementChecks e98ffd4bd82 doc: fix stale bitcoin_en.xlf reference fa9a9a82acd refactor: Remove unused newFeeRate var in ReplacementChecks fa588e9e0f8 refactor: Mark assertion_fail as [[noreturn]] 1278a5970d5 net_processing: process unique tx INVs only 75f58519277 doc: add release note for REST cache-control headers bbe21ac29f5 doc: document REST cache-control defaults 862a1795563 http: add no-store to dispatcher-generated error responses f32685315c2 doc: Install `pkgconf` to find `capnproto` on NetBSD 5964c7229fc doc: Switch `pkg-config` package to modern `pkgconf` on NetBSD 9b85c9814d1 doc: Drop GCC upgrade instructions for NetBSD ea59f172209 test: cover v0.14.3 wallet migration 18b8afd0933 test: support v0.14.x in dumb_sync_blocks faec059dfe8 refactor: Add uint256::operator<=>() b9d573e4a95 fees: Return false for incompatible fee estimates a3ebf8ab607 rpc: fix mempool entry vsize docs c4fbd3c7211 Merge bitcoin/bitcoin#35895: refactor: Enable clang-tidy rule to reject anon namespace in header 465196d0154 Merge bitcoin/bitcoin#35630: test: Add importdescriptors rpc error test coverage fa6df14c236 refactor: uint256::operator==() = default c940fd75145 Merge bitcoin/bitcoin#35180: coins: group private cache helpers 3db96eb5fd7 Merge bitcoin/bitcoin#35582: rpc: reject null for optional parameters fa93132d6da refactor: Enable misc-definitions-in-headers fa5ca877b60 refactor: Enable clang-tidy rule to reject anon namespace in header fafe5042bd1 refactor: Use C++20 std::identity over IntIdentity 28257111acf Merge bitcoin/bitcoin#35737: test: Move cluster_linearize.h contents into cluster_linearize namespace fac4b06e997 refactor: Use CLIENT_NAME in buildOpenRPCDoc fa3aadbc32e refactor: Use self.Arg in getopenrpcinfo fa1871a5281 refactor: Remove stale NOLINTNEXTLINE above GetAddressInfoBaseFields fa226479149 rpc: Properly make RPCResult::Type::ANY non-test-only fa1242dcc02 refactor: Use std::visit in ApplyArgFallback 27b6b5a458f Merge bitcoin/bitcoin#35836: rpc: Remove meaningless bool fallback in FundTransaction 3ac8b806a69 test: test the result order of a multiple import request is correct e4732bf0187 test: test invalid or missing timestamp throws importdescriptors 324c231efea Merge bitcoin/bitcoin#35881: iwyu: Fix warnings in `src/consensus` and treat them as errors 6ed7e05e20d gui: fix add .dat file extension automatically when exporting watchonly 75183f4464b Merge bitcoin/bitcoin#35880: fuzz: don't connman.ReceiveMsgFrom oversized msg fab74a0e922 refactor: Use C++14 digit separator for large int literals fae759be793 scripted-diff: Use inline constexpr over plain constexpr fa74f58a262 scripted-diff: Use inline const over (static) const fab1a62c870 refactor: Use inline constexpr for string literals in headers fa08bbed8dd contrib: Adjust generate-seeds.py to write inline constexpr fad753611b5 scripted-diff: Use inline constexpr over (static) const faedb52583e refactor: Make CFeeRate(integral) ctor constexpr 5555d5dcb55 scripted-diff: Use inline constexpr over static constexpr fa6e1a1e85e refactor: Remove static from constexpr functions in headers e2ab8ae5514 wallet: spkm: Only notify CanGetAddressesChanged on change 0892f16f911 refactor: moveonly: Pair CanGetAddressesChanged notifications with desc range. e6adae3db24 wallet: `NotifyCanGetAddressesChanged` when advancing `next_index` acf45c44c01 rest: add Cache-Control headers to REST responses d3cfd02bd7f Merge bitcoin/bitcoin#35501: wallet: store all witness variants of a transaction 0b8ffd01cde Merge bitcoin/bitcoin#35790: fuzz: populate wallet TXO index in wallet_create_transaction 2f52c2e8c06 Merge bitcoin/bitcoin#35886: refactor: Remove unused #include in common/system fa7304f3a5b refactor: Remove unused #include in common/system e7eb159a868 Merge bitcoin/bitcoin#35773: test: Suppress implicit-unsigned-integer-truncation:SaltedCoinsCacheHasher::operator() c6ef42d7dbc Merge bitcoin/bitcoin#35205: kernel,node: add `dbcache` setter and clarify defaults f280f5eb474 wallet: rpc: deprecate removeprunedfunds 4e8c4bc794c test: classify SOCKS5 peers via getpeerinfo addrbind 17c5e33e9c5 Merge bitcoin/bitcoin#35216: qa: Improve functional test support on illumos and *BSD 13b53f8bf67 iwyu: Fix warnings in `src/consensus` and treat them as errors bb19f1da19c fuzz: don't connman.ReceiveMsgFrom oversized msg 8a4bab8e975 Merge bitcoin/bitcoin#35863: test: fix wrong transaction in GetP2SHSigOpCount assertion 975a314667e Merge bitcoin/bitcoin#35832: p2p: avoid block disk reads on unnecessary requests d24610fa2c7 Merge bitcoin/bitcoin#35870: guix: move `python-minimal` to Linux GUI build b33a5b5767e Merge bitcoin/bitcoin#35871: refactor: Annotate `MakeAndPushFeature` with `[[maybe_unused]]` 4b322989ac2 Merge bitcoin/bitcoin#34995: iwyu: Fix warnings in `src/common` and treat them as errors 75f024a84e0 Merge bitcoin/bitcoin#35875: ci: Fix NetBSD SDK download failure, Temp. remove riscv32 from GHA fa06ea42448 ci: Temporarily remove riscv32 config from GHA matrix 873550bea38 ci: verify cross-build SDK archives 2c87337efe8 ci: update NetBSD cross-build SDK 6a2de55a0d8 test: require `TryGetTotalRam()` detection cd086c16dd7 node, qt: inline `DEFAULT_DB_CACHE` 8bd9f46082d kernel: allow setting chainstate `dbcache` 8aa21e119b0 kernel, node: colocate dbcache bounds 7cfa21d60a5 scripted-diff: use `MIN_DBCACHE_BYTES` ab634325768 common: cache total RAM as `uint64_t` 031fa402c8a scripted-diff: use `TryGetTotalRam` 264555af3cc rpc: avoid descriptor range counter overflow 143a13fb2bd test: characterize descriptor range endpoint 41c44f55885 node, qt: use `1_MiB` for dbcache conversions 0238aebf619 refactor: Annotate `MakeAndPushFeature` with `[[maybe_unused]]` 1ed14c61222 Merge bitcoin-core/gui#872: Menu action to export a watchonly wallet b75eb938a04 guix: move python-minimal to GUI build 101400b28f7 guix: remove -Werror=dev e27c179db2f Merge bitcoin/bitcoin#35869: lint: (re-)add contrib/guix for Python linting 50145f62c92 ci, iwyu: Enforce warning-free `src/common` 30f6b05857f Merge bitcoin/bitcoin#35860: fuzz: Rework rpc fuzz target dcc2ed52b84 Merge bitcoin/bitcoin#35856: fuzz: cover the mempool interface for transaction announcement 8221d714c78 lint: document CI lief version requirement 594a02c3ae0 lint: re-add guix scripts to mypy linting e8691056c01 test: Unroll `&&` conditions in macros ddddffda3af doc: Add doc/release-notes-35836.md 756afe14b5c test: give each ValidateInputsStandardness case its own scope 5559fa464b3 test: fix wrong transaction in GetP2SHSigOpCount assertion 556988790a7 Merge bitcoin/bitcoin#35592: http: check rpcallowip immediately after accepting connection fa895bb77a8 fuzz: Rework rpc fuzz target 28641fd195d p2p: reject empty getblocktxn requests dd2561003dd fuzz: cover the mempool interface for transaction announcement 9871fb726cb p2p: reject filtered block inv early when bloom is disabled aaf94120266 refactor: split p2p_getdata.py in sub-cases 34c03075a5a test: run generic baseindex tests against every index type 11b3e251c48 test: make baseindex flush test chain-length agnostic 8b959f4c6ab test: move unclean_shutdown test to baseindex_tests 2232d6afbe2 test: move index_reorg_crash to baseindex_tests a3597e26837 test: move BuildChain helper into test mining util 954985e6a38 test: simplify blockfilter test's BuildChain helper 67efced1fc8 Merge bitcoin/bitcoin#35838: qa: Enable `interface_gui.py` on macOS 45f5609f2ed qa: Enable `interface_gui.py` on macOS fa7fe798c61 wallet: Remove meaningless bool fallback in FundTransaction 9611a356035 Merge bitcoin/bitcoin#35828: util: Make LineReader consistently use string_view 6e2962e48cb Merge bitcoin/bitcoin#35753: kernel: handle null mempool on chainstate deletion 87bc4c74c4d Merge bitcoin/bitcoin#35787: init, rpc: ignore empty addnode values 67998e15c8d Merge bitcoin/bitcoin#35553: test: Add missing test case for getdata requests from blocks-only peers 9b38d077f89 Merge bitcoin-core/gui#953: Adds option to not load the wallet after migration 146988ef6c5 Merge bitcoin/bitcoin#35551: test: add interface_gui.py to test bitcoin-qt startup 7e5952b0aa0 Merge bitcoin/bitcoin#35821: guix: followups to #35537 683ae4c520b guix: consolidate config flags 665f11d04ac guix: consolidate gcc toolchain setup 288f76ed0fc guix: consolidate mingw-w64 toolchain setup cc9b0f2266d guix: consolidate LLVM toolchain setup b12a70f330d guix: turn linux/win linker warnings into errors fd7d4f29704 Merge bitcoin/bitcoin#35795: build: set CMAKE_VISIBILITY_INLINES_HIDDEN in REDUCE_EXPORTS 8ecbe270f0d Merge bitcoin/bitcoin#35606: script: qa: Improve `Key::Fingerprint` type safety a9d181f2d35 Merge bitcoin/bitcoin#35084: ipc: Add nonunix platform support 6573196e63b doc: Release note for export watchonly wallet gui action cb51f97f6c5 gui: Menu action for exporting a watchonly wallet 4cea59573c8 add release notes 492a715d784 gui: Adds option to not load the wallet after migration dff44e4c8f3 util: LineReader - Drop support for raw std::byte spans 5d5cdcd79d4 util: Make LineReader consistently use string_views e8eaa80ce29 util: LineReader - Don't include newline and acknowledge single-char \r 5907a5c7dc2 gui: Add ExceptionSafeConnect that takes a lambda 7dea464d6b5 Merge bitcoin/bitcoin#35692: addrman: remove unreachable tried-collision branch a2aab6df97d Merge bitcoin/bitcoin#35810: guix: Drop unused `(guix licenses)` import from `manifest_build.scm` 77440814bf2 fuzz: reset SOCKS5 interrupt between inputs 90ce21e21d0 rpc: reject empty node argument in addnode 69465de4470 init: ignore empty addnode values e75b76b12c5 Merge bitcoin/bitcoin#35261: guix: disable LTO in GCC a92e93429ee guix: Drop unused `(guix licenses)` import from `manifest_build.scm` 5be248341a8 bugfix: compare real chunk weight against block weight limit fc987908699 test: `TestChunkBlockLimits` uses incorrect weight for comparison e34b8d5a7dc Merge bitcoin/bitcoin#35794: doc: Discourage adding AI agents as commit (co)-authors b33a7fcd7bd Merge bitcoin/bitcoin#34628: p2p: Replace per-peer transaction rate-limiting with global rate limits 6b059d9dbdb Merge bitcoin/bitcoin#32800: rpc: Distinguish between vsize and sigop adjusted mempool vsize 11ebbd90721 Merge bitcoin/bitcoin#28463: p2p: Increase inbound capacity for block-relay only connections 3f313a774be build: set CMAKE_VISIBILITY_INLINES_HIDDEN in REDUCE_EXPORTS 3a2c52f9d70 Merge bitcoin/bitcoin#35792: refactor: Make all `const static` class members `constexpr` f5d7cc66ecb doc: Discourage adding AI agents as commit authors 05c35c402cc refactor: Make all `const static` class members `constexpr` c11508406e6 doc: Update docs that refer to -maxconnections 69ce0dba2ae test: add test that EvictTxPeerIfFull only evicts tx-relaying peers 3ed7f064180 p2p: trigger possible eviction if we support bloom filters and change a peer to tx relay 0bd3d3dfa56 init: make inbound tx relay percentage configurable cc59aee196e test: add functional test for inbound maxconnection limits 1b76e047364 net: increase inbound capacity for block-relay-only connections baa5a2ce43a guix: pass --disable-tm-clone-registry to base GCC 9c2589630f0 guix: mirror some arguments from linux-gcc to mingw-w64-gcc e0b8fbde897 guix: disable-nls in *-base-gcc 7dc87f8e1e2 guix: disable-lto in *-base-gcc 9ed3d6ef2a2 guix: modernise style in *-base-gcc 1eac6a728bf fuzz: populate wallet TXO index in wallet_create_transaction 610dd320d1a Merge bitcoin/bitcoin#35783: chainparams: remove my testnet3 seed afa5e46bbc6 Merge bitcoin/bitcoin#35076: doc: clarify pruning impact on wallet sync 26b730cdbf2 Merge bitcoin/bitcoin#35320: key: validate BIP32 seed length in CExtKey::SetSeed edf4b807f05 Merge bitcoin/bitcoin#35781: Update secp256k1 subtree to latest master 774d11c58f2 Merge bitcoin/bitcoin#35664: test: add CLTV and CHECK(MULTI)SIGVERIFY failure-path vectors to script_tests.json 526673487ce Merge bitcoin/bitcoin#34683: rpc: support a formal description of our JSON-RPC interface 290cb2f17ef Merge bitcoin/bitcoin#35775: scripted-diff: Use C.UTF-8 locale in Guix scripts d472a7798ac Merge bitcoin/bitcoin#32764: guix: Build for macOS using LLVM toolchain only 9755d33390d Merge bitcoin/bitcoin#34808: cmake, translation: Use native Qt TS file as source for translations on Transifex 51143291a6c Merge bitcoin/bitcoin#35782: doc: fix outdated i2p URLs in comments 2cb3bfa8df7 scripted-diff: Use long form of shell options in Guix scripts 711eb10f08b guix: Add copyright headers to Guix scripts 7295b8be704 chainparams: remove my testnet3 seed 419f7427eee doc: fix outdated i2p URLs in comments a33f240524d Squashed 'src/secp256k1/' changes from bd0287d650..d2d04864ef c26d4e2d6f0 Update secp256k1 subtree to latest master 22a03ca6944 Merge bitcoin/bitcoin#35694: clusterlin: minor SFL optimizations 7b6f9ba7bad Merge bitcoin/bitcoin#34672: mining: add reason/debug to `submitSolution` and unify with `submitBlock` 5311b15727f Merge bitcoin/bitcoin#33014: rpc: Fix internal bug in descriptorprocesspsbt when encountering invalid signatures c9cedebfffb coins: group private cache helpers 8a90c7cd973 guix: Build for macOS using LLVM toolchain only db74d3390a3 doc: clarify test placement guidance d3d74e701f7 ipc, refactor: Update mp::g_thread_context references 80f831494e5 guix: Fix `glibc` version in comment 8916f7967e1 scripted-diff: Use C.UTF-8 locale in Guix scripts a2e074d66ac Merge bitcoin-core/gui#951: test: Nudge toward QT_STYLE_OVERRIDE=fusion on macOS 6ced9ad782b Merge bitcoin/bitcoin#35770: net: Simplify `AddressPosition` comparitor b8844d3df75 Merge bitcoin/bitcoin#35766: p2p: Assume v2transport for addresses from seeds fa7f5537817 test: Suppress implicit-unsigned-integer-truncation:SaltedCoinsCacheHasher::operator() 075e7f42187 net: Simplify `AddressPosition` comparitor fa0c8337a8d test: Nudge toward QT_STYLE_OVERRIDE=fusion on macOS faa50c08b17 refactor: Run clang-format on qt test_main.cpp bc49bd154a3 Merge bitcoin/bitcoin#35709: depends: Update Qt to 6.8.4 efa1800a885 Merge bitcoin/bitcoin#35769: depends, zeromq: Apply upstream patch fc4ceda8b61 Merge bitcoin-core/gui#949: Fix `-Wsfinae-incomplete` warnings when building with GCC 16.x 559d042ba25 Merge bitcoin/bitcoin#35736: bitcoin-util: replace netmagic command with getchainparams command 8f2ed31f702 Merge bitcoin/bitcoin#35767: fuzz: Avoid dangling prevoutfetch threads after AFL fork a31c30290d4 Merge bitcoin/bitcoin#35746: ci: Test build directory path with spaces e446ea09c4d depends, zeromq: Apply upstream patch 87b080fe2b6 fuzz: reset the reused mempool in process_message(s) d522fd31963 fuzz: prepare deterministic mempool rebuilds b11456386b2 fuzz: let the test input toggle IBD in the p2p fuzz targets 2a29cee6843 test: add helper to reset chainman and mempool 2a4ef42d34e fuzz: share a single FakeNodeClock in the chainman-resetting fuzz targets 32eb5210029 Merge bitcoin/bitcoin#35215: coins: use SipHash-1-3-UJ for CCoinsMap keys 883ef1d85d7 Merge bitcoin/bitcoin#35727: blockencodings: fix extra transaction count f3f302150b5 ci: Put space and non-ASCII char in `BASE_BUILD_DIR` a7e980af31b build: Quote host paths in NSIS installer template faada35f9c0 fuzz: [refactor] Use 100'000 digit separator in __AFL_LOOP cf0f2aeae00 p2p: Assume v2transport for addresses from seeds fae067ec4a4 fuzz: Avoid dangling prevoutfetch threads after AFL fork 7e1a750d45d guix, refactor: Use `target` variable instead of hardcoded value de9b436ba36 depends: Switch from multilib to platform-specific toolchains d673ca765a5 Merge bitcoin/bitcoin#35537: guix: split builds into Linux, Linux GUI and macOS/Windows b36c2d78a3a Merge bitcoin/bitcoin#35490: test: cover unused mempool space in coins cache limit 7502b9ddba7 fuzz: check http_request body matches framing d1d85263f8e Merge bitcoin/bitcoin#35681: test: cover disconnect on private broadcast peer with relay=false 4906594a384 Merge bitcoin-core/gui#950: qt, test: Run GUI tests on macOS with `minimal` QPA plugin e0c196f9c11 Merge bitcoin/bitcoin#35721: lint: drop most remaining default Ruff rule ignores fd59d68c262 qt, test: Enable tests on macOS with `minimal` QPA plugin c8b2aeb2263 qt: Avoid implicit `NSApplication` instantiation 006f8f7d49a Merge bitcoin/bitcoin#35090: fuzz: add p2p_private_broadcast harness 51d36dfd076 qt: Fix `-Wsfinae-incomplete` warnings when building with GCC 16.x 0b0785daa00 guix: split macOS and win builds 008a3e29c88 guix: split builds into Linux(gui) and macOS/Windows a99b27f1920 validation: handle null mempool on delete a3b5dc05723 cmake: Add `GenerateWindowsInstaller` script 3bfdcbd7ee4 coins: reuse cache hasher for txid set 2beab94896a coins: use SipHash-1-3-UJ for `CCoinsMap` 7ff55cc6500 bench: add fixed-width SipHash benchmarks 3aea85411f6 test: add SipHash-1-3-UJ coverage a0ccd4ad171 crypto: add fixed-width SipHash-1-3-UJ c2d7931b5c8 crypto: add generic SipHash-1-3-UJ 25bfca06d66 refactor: simplify adding SipHash-1-3-UJ af50ba8500a test: add shared SipHash vectors fa5cbb89097 uint256: Workaround GCC-14 stringop-overread bug in Compare 18c05d93016 Merge bitcoin/bitcoin#35590: test: wallet: BnB incomplete result on attempt-limit success 21b4b790e48 test: Move cluster_linearize.h contents into cluster_linearize namespace b56b66fc64b Merge bitcoin/bitcoin#35679: fuzz: Remove unused `DeserializeFromFuzzingInput` params overload 6ee05c4b188 test: wallet: BnB incomplete result on attempt-limit success 6aa5d8d9481 blockencodings: fix extra transaction count be4e64d9e40 test: characterize extra transaction miscount 2d3f72fd3fa ipc, refactor: Update mp::SpawnProcess call 7298281ba8d bitcoin-util: replace netmagic command with getchainparams command 9d6ba4b3b57 Merge bitcoin/bitcoin#34514: refactor: remove unnecessary `std::move` for a few trivially copyable types ca9ffb8e123 rpc: add OpenRPC discovery alias 6c9d76d5894 doc: release note for alternate_wtxids in gettransaction 99bdcb064c2 test: compat, ensure downgrade preserves tx witness variants ef2afc6a0a3 test: Test for wallet txs with alternate wtxids 2d55c7a74dd wallet: Show alternate wtxids in gettransaction 0b1af01bd44 wallet: Replace CWalletTx::SetTx with Update 56cf27db4dc wallet: Store all witness variants of a transaction 798ba6d04fa wallet: Make CWalletTx::tx private and use CWalletTx::GetTx to access 72ebdd6364c wallet: Remove unused CWalletTx CopyFrom and copy constructor 19af439bdf3 wallet: Deserialize directly in CWalletTx's ctor afab8d4225c fuzz, refactor: Remove `Serialize` overload efa7f8c1437 fuzz: Remove unused `DeserializeFromFuzzingInput` params overload 6eca11175be lint: remove E731 Ruff ignore b52454538b0 lint: remove E712 Ruff ignore e9f19815caa ipc, refactor: Add Stream type alias and use it 3859805f05e ipc, refactor: Add SocketId type alias and use it 2ee9b69c7a1 ipc, refactor: Add ProcessId type alias and use it 34497971418 ipc: Avoid 'unistd.h' error with MSVC dbcc192dce6 ipc, refactor: fix include order 7c86d4834ed ipc, refactor: use native path separators in test 00287b9a340 ipc, refactor: Change Protocol class field order 33d37f3c35e ipc, refactor: Drop connect/listen/serve exe_name parameters 794940469e7 ipc, moveonly: combine ipc_test.cpp and ipc_tests.cpp efb4eae3386 clusterlin: avoid recomputing intersections in MergeChunks 4b91ad149f0 clusterlin: reserve the suboptimal-chunk queue up front e6ca996255b clusterlin: avoid heap allocations in GetLinearization 226e6388b7f depends: Update Qt to 6.8.4 fef99e6563a qt: fix out-of-bounds read in RPCParseCommandLine on empty command 349c72ee00a net_processing: Drop unnecessary txid arg from InitiateTxBroadcastToAll 12b0dc33c4a doc: Add release note for -txsendrate etc 5cde66341a6 tests: basic functional test for tx rate limiting 4842903ac12 rpc: report -txsendrate and bucket info via getnetworkinfo 74a47a52071 init: add -txsendrate configuration parameter 6307bd034bf net_processing: Provide a 30bpm heartbeat log while inv backlog is in use df31ee57aaf net_processing: add a global delay queue for sending txs 7927650e56d util/tokenbucket.h: Provide a generic TokenBucket class 749bb447f81 txmempool: Drop CompareMiningScoreWithTopology e1b7490fbc9 net_processing: Replace CompareInvMempoolOrder 6cfc65d2103 txmempool: Add ExtractBestByMiningScoreWithTopology 026f70e05f9 net_processing: Remove per-peer rate-limiting 46c8c471dcf net_processing: bump last_inv_sequence for bip35 messages explicitly 5d57f2cefee test: cover unused mempool space in coins cache 1fc9277a1c1 test: cover disconnect on private broadcast peer with relay=false bc7d9050467 addrman: remove unreachable tried-collision branch 0390338692a test: check MuSig import private key warnings 5e62fbf09c0 wallet: check descriptor private key completeness on import cd8d01bf47a descriptors: require complete MuSig private keys 55d3cd51a48 doc: add release note describing change for forbidden clients d1ed2a6e25d http: check rpcallowip immediately after accepting connection d24d3cbad01 fuzz: add p2p_private_broadcast harness c4068cf37b6 test: add negative zero CSV failure script test vector 37edf0e2338 test: add CHECKLOCKTIMEVERIFY failure-path script test vectors 29b124416e4 doc: add release notes for 32800 5d25a0c28d1 rpc: add `vsize_adjusted` field to getrawtransaction output for mempool transactions eaef8d31118 rpc: add `vsize_adjusted` and `vsize_bip141` field to mempool-related RPCs 6d387af562f psbt: remove write-only global xpub tracking set 3b7051c7e33 test: check combinepsbt with conflicting global xpub origins 7c632c0e2a2 psbt: avoid duplicate global xpub keys when merging a86a96d17b3 test: add CHECKSIGVERIFY/CHECKMULTISIGVERIFY failure script test vectors 07fb58b9ef2 test: Test a locked wallet rejects an empty importdescriptors request aeca0610865 rpc: reject null for optional parameters f4a6d079c42 qa: Support `get_bind_addrs` and `feature_bind_extra` on illumos 5e96a8fd5ac doc: Add `lsof` to Test Suite Dependencies on NetBSD 5d01aa4772a qa: Ignore `lsof` warnings on NetBSD 70352fda038 qa: Strip prefix length from NetBSD `ifconfig` output 1c1735567e2 doc: Add `lsof` to Test Suite Dependencies on FreeBSD 4cb7f39c2ce qa: Drop OpenBSD from supported platforms in `get_bind_addrs` function 8a982eea854 qa: Add `skip_if_no_lsof_on_nonlinux` helper and use it where needed 7e973cce52c depends: Make tarball creation from local directory reproducible e5b7785447f test: wallet: resend: avoid internal behavior via removeprunedfunds c9a70f93387 script: qa: Improve Key::Fingerprint type safety aa01721c899 test: add interface_gui.py to test bitcoin-gui startup via RPC ef0676f4007 rpc: factor getaddressinfo embedded field docs 1fb6b605609 test: add functional test for getopenrpcinfo 672dd42d140 rpc: add getopenrpcinfo command d5e64b01e1b doc: note -blocknotify is not run during IBD/reindex in help text f5116c587f7 rpc: add placeholder annotation for deprecated params 26c221a980d rpc: expose RPC metadata for introspection 6a1a66c180c rpc: render Type::ANY in help text instead of aborting 06de34a0333 rpc: erase empty map entry in removeCommand d4d64ae7393 rpc: add missing string_view include to server.h 278710a88d8 test: Add missing test case for getdata requests from blocks-only peers 156f2c6c49d kernel: add `btck_set_mock_time` for testing time-dependent paths 75929b11edb doc: add release note for submitSolution IPC changes ed75d70fdb8 refactor: centralize SubmitBlock result handling cbaa1696f37 mining: add reason and debug output to submitSolution 83f3bc002d0 mining: clarify SubmitBlock result handling 87bca1c2adb net: add options to AttemptToEvictConnection 2cf9d79d84c key: validate BIP32 seed length in CExtKey::SetSeed 3e8e21b2efc txgraph: avoid moving primitive members d9f94aa882a rpc: avoid moving RPC enum types b67baed4e7e coins: avoid moving `COutPoint` values 7e19ce200b2 rpc: Fix descriptorprocesspsbt internal bug on invalid signatures 51ee8ca1683 doc: clarify pruning impact on wallet sync 6cca38e2b92 refactor: remove unused PSBTError::Ok 3660678b953 refactor: SignPSBTInput now uses util:Expected ec61a1af621 depends: Hash included makefiles in package checksums a434d660250 cmake, translation: Specify English as target language explicitly 4097d6d968e cmake, translation: Sort messages within contexts alphabetically 312ab8ab0a8 cmake, translation: Skip source locations in TS files 4f553bd0da2 cmake, translation: Remove TS to XLIFF conversion 8c30055458b translation: Switch to Qt TS source file git-subtree-dir: libbitcoinkernel-sys/bitcoin git-subtree-split: 97462c683d49792a58ba954723a205cda86a5e0b --- .../actions/configure-environment/action.yml | 4 +- .github/ci-windows-cross.py | 52 +- .github/workflows/ci.yml | 5 + .tx/config | 6 +- CMakeLists.txt | 6 +- CONTRIBUTING.md | 3 +- ci/lint/requirements.txt | 5 +- ci/lint_imagefile | 2 +- ci/test/00_setup_env.sh | 4 +- ci/test/00_setup_env_freebsd_cross.sh | 1 + ci/test/00_setup_env_i686_no_ipc.sh | 5 +- ci/test/00_setup_env_mac_cross.sh | 1 + ci/test/00_setup_env_mac_cross_intel.sh | 1 + ci/test/00_setup_env_netbsd_cross.sh | 5 +- ci/test/00_setup_env_openbsd_cross.sh | 3 + ci/test/00_setup_env_win64.sh | 4 +- ci/test/00_setup_env_win64_msvcrt.sh | 4 +- ci/test/01_base_install.sh | 45 +- ci/test/02_run_container.py | 13 +- ci/test/03_test_script.sh | 9 +- ci/test_imagefile | 7 +- cmake/bitcoin-build-config.h.in | 5 +- cmake/introspection.cmake | 7 +- cmake/module/AddWindowsResources.cmake | 16 +- cmake/module/GenerateSetupNsi.cmake | 19 - cmake/module/Maintenance.cmake | 35 +- .../script/GenerateWindowsInstaller.cmake.in | 40 + contrib/devtools/iwyu/bitcoin.core.imp | 4 + contrib/devtools/shell-win64-cross.nix | 45 + contrib/guix/guix-attest | 7 +- contrib/guix/guix-build | 111 +- contrib/guix/guix-clean | 7 +- contrib/guix/guix-codesign | 7 +- contrib/guix/guix-verify | 7 +- contrib/guix/libexec/build.sh | 207 - contrib/guix/libexec/build_linux.sh | 74 + contrib/guix/libexec/build_linux_gui.sh | 74 + contrib/guix/libexec/build_macos.sh | 58 + contrib/guix/libexec/build_macos_gui.sh | 64 + contrib/guix/libexec/build_win.sh | 63 + contrib/guix/libexec/build_win_gui.sh | 68 + contrib/guix/libexec/codesign.sh | 8 +- contrib/guix/libexec/package.sh | 17 +- contrib/guix/libexec/prelude.bash | 7 +- contrib/guix/libexec/setup.sh | 107 +- contrib/guix/manifest_build.scm | 94 +- contrib/guix/manifest_gui.scm | 30 + contrib/guix/security-check.py | 4 +- contrib/guix/symbol-check.py | 12 +- contrib/init/bitcoind.openrc | 3 +- contrib/seeds/generate-seeds.py | 8 +- contrib/verify-commits/verify-commits.py | 39 +- depends/README.md | 53 +- depends/funcs.mk | 8 +- depends/hosts/linux.mk | 21 - depends/packages/native_qt.mk | 5 +- depends/packages/qt.mk | 13 +- depends/packages/qt_details.mk | 12 +- depends/packages/zeromq.mk | 4 +- depends/patches/qt/fix-gcc16-qcompare.patch | 10 +- .../qt/fix-gcc16-sfinae-qanystringview.patch | 2 +- .../patches/qt/fix-gcc16-sfinae-qchar.patch | 2 +- depends/patches/qt/fix_missed_headers.patch | 32 + .../patches/qt/qtbase_platformsupport.patch | 34 - depends/patches/qt/qtbase_plugins_cocoa.patch | 2 +- depends/patches/qt/qtbase_skip_tools.patch | 4 +- depends/patches/zeromq/add_new_include.patch | 123 + doc/AI_POLICY.md | 1 + doc/REST-interface.md | 29 +- doc/build-freebsd.md | 2 +- doc/build-netbsd.md | 29 +- doc/build-osx.md | 2 +- doc/build-windows.md | 2 +- doc/cjdns.md | 6 +- doc/developer-notes.md | 29 + doc/files.md | 2 +- doc/i2p.md | 14 +- doc/multisig-tutorial.md | 58 +- doc/reduce-memory.md | 2 +- doc/reduce-traffic.md | 5 +- doc/release-notes-32784.md | 9 + doc/release-notes-32800.md | 9 + doc/release-notes-34075.md | 52 + doc/release-notes-34628.md | 13 + doc/release-notes-34672.md | 11 + doc/release-notes-34794.md | 8 + doc/release-notes-35182.md | 5 + doc/release-notes-35501.md | 4 + doc/release-notes-35531.md | 12 + doc/release-notes-35592.md | 6 + doc/release-notes-35610.md | 4 +- doc/release-notes-35680.md | 13 + doc/release-notes-35696.md | 8 + doc/release-notes-35836.md | 5 + doc/release-notes-953.md | 5 + doc/release-notes-gui-872.md | 7 + doc/release-notes-removeprunedfunds.md | 6 + doc/release-process.md | 6 +- ruff.toml | 2 - share/qt/translate.cmake | 22 +- share/setup.nsi.in | 22 +- src/.clang-tidy | 4 +- src/CMakeLists.txt | 34 +- src/addresstype.h | 2 +- src/addrman.cpp | 9 +- src/addrman.h | 28 +- src/addrman_impl.h | 12 +- src/banman.h | 4 +- src/bech32.h | 4 +- src/bench/CMakeLists.txt | 1 + src/bench/blockencodings.cpp | 4 +- src/bench/coin_selection.cpp | 2 +- src/bench/crypto_hash.cpp | 52 +- src/bench/mempool_ephemeral_spends.cpp | 8 +- src/bench/mempool_stress.cpp | 2 +- src/bench/nanobench.h | 2 + src/bench/uint256_blob.cpp | 91 + src/bip324.h | 2 +- src/bitcoin-util.cpp | 59 +- src/blockencodings.cpp | 33 +- src/blockfilter.h | 4 +- src/chain.h | 8 +- src/chainparamsseeds.h | 8 +- src/clientversion.h | 2 +- src/cluster_linearize.h | 62 +- src/coins.cpp | 17 +- src/coins.h | 70 +- src/common/args.cpp | 2 - src/common/args.h | 1 - src/common/bloom.cpp | 3 +- src/common/bloom.h | 7 +- src/common/config.cpp | 9 +- src/common/init.cpp | 4 +- src/common/interfaces.cpp | 5 +- src/common/messages.cpp | 21 +- src/common/messages.h | 3 +- src/common/netif.cpp | 12 +- src/common/netif.h | 1 + src/common/pcp.cpp | 23 +- src/common/pcp.h | 10 +- src/common/run_command.cpp | 13 +- src/common/settings.cpp | 5 +- src/common/settings.h | 4 +- src/common/signmessage.cpp | 5 +- src/common/system.cpp | 29 +- src/common/system.h | 4 +- src/common/types.h | 1 - src/common/url.cpp | 1 + src/compressor.h | 2 +- src/consensus/amount.h | 4 +- src/consensus/consensus.h | 20 +- src/consensus/merkle.cpp | 15 +- src/consensus/merkle.h | 11 +- src/consensus/params.h | 1 + src/consensus/tx_check.cpp | 10 +- src/consensus/tx_verify.cpp | 6 + src/consensus/tx_verify.h | 1 + src/consensus/validation.h | 16 +- src/crypto/aes.h | 4 +- src/crypto/hkdf_sha256_32.h | 2 +- src/crypto/hmac_sha256.h | 2 +- src/crypto/hmac_sha512.h | 2 +- src/crypto/ripemd160.h | 2 +- src/crypto/sha1.h | 2 +- src/crypto/sha256.h | 2 +- src/crypto/siphash.cpp | 149 +- src/crypto/siphash.h | 167 +- src/cuckoocache.h | 10 +- src/dbwrapper.cpp | 24 + src/dbwrapper.h | 11 +- src/hash.h | 4 +- src/httprpc.cpp | 7 +- src/httpserver.cpp | 613 +- src/httpserver.h | 230 +- src/i2p.cpp | 4 +- src/i2p.h | 8 +- src/index/base.h | 5 +- src/index/blockfilterindex.h | 4 +- src/index/coinstatsindex.h | 2 +- src/index/db_key.h | 4 +- src/index/txindex.cpp | 189 +- src/index/txindex.h | 28 +- src/index/txindex_key.h | 128 + src/index/txospenderindex.h | 2 +- src/init.cpp | 155 +- src/init.h | 4 +- src/interfaces/chain.h | 17 +- src/interfaces/mining.h | 18 +- src/interfaces/node.h | 11 +- src/interfaces/wallet.h | 31 +- src/ipc/CMakeLists.txt | 4 +- src/ipc/capnp/common-types.h | 5 +- src/ipc/capnp/mining.capnp | 5 +- src/ipc/capnp/protocol.cpp | 34 +- src/ipc/capnp/protocol.h | 2 +- src/ipc/interfaces.cpp | 26 +- src/ipc/process.cpp | 39 +- src/ipc/process.h | 20 +- src/ipc/protocol.h | 45 +- src/ipc/test/CMakeLists.txt | 9 +- src/ipc/test/fuzz/ipc.cpp | 9 +- src/ipc/test/ipc_test.cpp | 193 - src/ipc/test/ipc_test.h | 4 - src/ipc/test/ipc_tests.cpp | 202 +- src/ipc/util.h | 64 + src/kernel/CMakeLists.txt | 6 + src/kernel/bitcoinkernel.cpp | 174 +- src/kernel/bitcoinkernel.h | 172 + src/kernel/bitcoinkernel_wrapper.h | 115 +- src/kernel/blockmanager_opts.h | 2 +- src/kernel/caches.h | 13 +- src/kernel/chainparams.cpp | 1 - src/kernel/chainstatemanager_opts.h | 4 +- src/kernel/disconnected_transactions.h | 2 +- src/kernel/mempool_options.h | 10 +- src/key.cpp | 28 +- src/key.h | 25 +- src/leveldb/.github/workflows/ci.yml | 12 + src/leveldb/benchmarks/db_bench_sqlite3.cc | 1 + src/leveldb/util/env_posix.cc | 4 +- src/leveldb/util/env_windows.cc | 4 +- src/logging.h | 12 +- src/mapport.h | 2 +- src/minisketch/src/fields/clmul_common_impl.h | 5 +- src/minisketch/src/util.h | 14 + src/musig.cpp | 2 +- src/musig.h | 2 +- src/net.cpp | 33 +- src/net.h | 73 +- src/net_permissions.h | 6 +- src/net_processing.cpp | 421 +- src/net_processing.h | 33 +- src/netaddress.h | 22 +- src/netbase.h | 6 +- src/node/blockstorage.h | 10 +- src/node/caches.cpp | 14 +- src/node/caches.h | 8 +- src/node/chainstatemanager_args.h | 2 +- src/node/context.cpp | 2 +- src/node/context.h | 4 +- src/node/interfaces.cpp | 30 +- src/node/kernel_notifications.h | 2 +- src/node/mempool_persist_args.h | 2 +- src/node/miner.cpp | 37 +- src/node/miner.h | 6 +- src/node/mining_args.h | 2 +- src/node/peerman_args.cpp | 4 + src/node/protocol_version.h | 20 +- src/node/psbt.cpp | 6 +- src/node/transaction.cpp | 12 +- src/node/transaction.h | 4 +- src/node/txdownloadman.h | 16 +- src/node/txdownloadman_impl.cpp | 9 +- src/node/txdownloadman_impl.h | 11 +- src/node/txorphanage.cpp | 2 + src/node/txorphanage.h | 4 +- src/node/txreconciliation.h | 2 +- src/node/utxo_snapshot.h | 8 +- src/outputtype.h | 2 +- src/policy/feerate.h | 15 +- src/policy/fees/block_policy_estimator.cpp | 175 +- src/policy/fees/block_policy_estimator.h | 40 +- .../fees/block_policy_estimator_args.cpp | 16 - src/policy/fees/block_policy_estimator_args.h | 15 - src/policy/fees/estimator_args.cpp | 60 + src/policy/fees/estimator_args.h | 21 + src/policy/fees/estimator_man.cpp | 105 + src/policy/fees/estimator_man.h | 102 + src/policy/fees/mempool_estimator.cpp | 407 ++ src/policy/fees/mempool_estimator.h | 157 + src/policy/packages.h | 4 +- src/policy/policy.h | 68 +- src/policy/rbf.h | 2 +- src/policy/truc_policy.h | 14 +- src/primitives/transaction.h | 18 +- src/primitives/transaction_identifier.h | 15 +- src/private_broadcast.cpp | 27 +- src/private_broadcast.h | 39 +- src/protocol.h | 16 +- src/psbt.cpp | 85 +- src/psbt.h | 115 +- src/pubkey.cpp | 9 +- src/pubkey.h | 21 +- src/qt/CMakeLists.txt | 13 +- src/qt/bitcoingui.cpp | 27 +- src/qt/bitcoingui.h | 9 +- src/qt/bitcoinstrings.cpp | 23 +- src/qt/forms/optionsdialog.ui | 2 +- src/qt/guiconstants.h | 16 +- src/qt/guiutil.cpp | 8 +- src/qt/guiutil.h | 32 + src/qt/intro.h | 2 +- src/qt/locale/bitcoin_en.ts | 4774 +++++--------- src/qt/locale/bitcoin_en.xlf | 5626 ---------------- src/qt/macdockiconhandler.mm | 6 +- src/qt/modaloverlay.h | 2 +- src/qt/optionsdialog.cpp | 2 +- src/qt/optionsmodel.cpp | 4 +- src/qt/optionsmodel.h | 2 +- src/qt/qrimagewidget.h | 8 +- src/qt/qvalidatedlineedit.cpp | 2 + src/qt/recentrequeststablemodel.h | 2 +- src/qt/rpcconsole.cpp | 9 +- src/qt/sendcoinsdialog.cpp | 10 +- src/qt/sendcoinsentry.cpp | 2 + src/qt/sendcoinsrecipient.h | 2 +- src/qt/test/addressbooktests.cpp | 11 - src/qt/test/apptests.cpp | 12 - src/qt/test/rpcnestedtests.cpp | 5 + src/qt/test/test_main.cpp | 16 +- src/qt/test/wallettests.cpp | 11 - src/qt/transactionfilterproxy.h | 2 +- src/qt/transactionrecord.h | 2 +- src/qt/walletcontroller.cpp | 22 +- src/qt/walletcontroller.h | 2 +- src/rest.cpp | 42 +- src/rpc/blockchain.cpp | 11 +- src/rpc/blockchain.h | 2 +- src/rpc/client.cpp | 4 + src/rpc/fees.cpp | 91 +- src/rpc/mempool.cpp | 78 +- src/rpc/mining.cpp | 6 +- src/rpc/mining.h | 2 +- src/rpc/net.cpp | 28 + src/rpc/node.cpp | 2 +- src/rpc/output_script.cpp | 9 +- src/rpc/rawtransaction.cpp | 67 +- src/rpc/rawtransaction_util.cpp | 10 +- src/rpc/server.cpp | 486 +- src/rpc/server.h | 5 + src/rpc/server_util.cpp | 12 +- src/rpc/server_util.h | 6 +- src/rpc/util.cpp | 23 +- src/rpc/util.h | 19 +- src/script/descriptor.cpp | 127 +- src/script/interpreter.cpp | 9 +- src/script/interpreter.h | 26 +- src/script/keyorigin.h | 19 +- src/script/miniscript.h | 34 +- src/script/script.h | 26 +- src/script/sigcache.h | 6 +- src/script/sign.cpp | 10 +- src/script/signingprovider.cpp | 1 + src/script/signingprovider.h | 3 +- src/script/trace.cpp | 40 + src/script/trace.h | 118 + .../install-homebrew-valgrind/action.yml | 1 + src/secp256k1/.github/workflows/ci.yml | 41 +- src/secp256k1/.gitignore | 1 + src/secp256k1/CHANGELOG.md | 31 +- src/secp256k1/CMakeLists.txt | 8 +- src/secp256k1/Makefile.am | 25 + src/secp256k1/README.md | 19 +- src/secp256k1/SECURITY.md | 10 +- src/secp256k1/ci/ci.sh | 3 +- src/secp256k1/configure.ac | 22 +- src/secp256k1/doc/release-process.md | 45 +- src/secp256k1/examples/CMakeLists.txt | 4 + src/secp256k1/examples/silentpayments.c | 465 ++ src/secp256k1/include/secp256k1.h | 34 +- src/secp256k1/include/secp256k1_schnorrsig.h | 13 +- .../include/secp256k1_silentpayments.h | 396 ++ src/secp256k1/src/CMakeLists.txt | 9 + src/secp256k1/src/bench.c | 64 +- src/secp256k1/src/bench.h | 6 +- src/secp256k1/src/ctime_tests.c | 78 + src/secp256k1/src/field.h | 2 +- src/secp256k1/src/field_10x26_impl.h | 40 +- src/secp256k1/src/field_5x52_impl.h | 36 +- src/secp256k1/src/field_impl.h | 2 +- src/secp256k1/src/hash.h | 2 + src/secp256k1/src/hash_impl.h | 65 + src/secp256k1/src/modules/ecdh/main_impl.h | 2 +- .../src/modules/ellswift/main_impl.h | 6 +- .../modules/ellswift/tests_exhaustive_impl.h | 4 +- .../src/modules/ellswift/tests_impl.h | 16 +- .../src/modules/extrakeys/main_impl.h | 7 + .../src/modules/extrakeys/tests_impl.h | 4 +- src/secp256k1/src/modules/musig/tests_impl.h | 4 +- .../modules/recovery/tests_exhaustive_impl.h | 6 +- .../src/modules/schnorrsig/main_impl.h | 4 - .../src/modules/schnorrsig/tests_impl.h | 3 - .../silentpayments/Makefile.am.include | 5 + .../src/modules/silentpayments/bench_impl.h | 227 + .../bip352_send_and_receive_test_vectors.json | 5729 +++++++++++++++++ .../src/modules/silentpayments/main_impl.h | 805 +++ .../src/modules/silentpayments/tests_impl.h | 933 +++ .../src/modules/silentpayments/vectors.h | 4747 ++++++++++++++ src/secp256k1/src/scalar.h | 4 +- src/secp256k1/src/scalar_4x64_impl.h | 8 +- src/secp256k1/src/scalar_8x32_impl.h | 3 +- src/secp256k1/src/scalar_low_impl.h | 12 +- src/secp256k1/src/secp256k1.c | 10 +- src/secp256k1/src/selftest.h | 8 +- src/secp256k1/src/tests.c | 128 +- src/secp256k1/src/tests_exhaustive.c | 2 +- src/secp256k1/src/util.h | 17 +- .../tools/tests_silentpayments_generate.py | 324 + src/serialize.h | 6 +- src/support/lockedpool.h | 4 +- src/test/CMakeLists.txt | 22 +- src/test/addrman_tests.cpp | 19 +- src/test/allocator_tests.cpp | 21 +- src/test/amount_tests.cpp | 12 +- src/test/argsman_tests.cpp | 52 +- src/test/arith_uint256_tests.cpp | 10 +- src/test/base58_tests.cpp | 2 +- src/test/baseindex_tests.cpp | 235 +- src/test/bip32_tests.cpp | 156 +- src/test/blockencodings_tests.cpp | 53 +- src/test/blockfilter_index_tests.cpp | 148 +- ...sts.cpp => blockpolicyestimator_tests.cpp} | 175 +- src/test/caches_tests.cpp | 7 +- src/test/checkqueue_tests.cpp | 3 +- src/test/coins_tests.cpp | 47 +- src/test/coinscachepair_tests.cpp | 36 +- src/test/coinstatsindex_tests.cpp | 48 - src/test/coinsviewoverlay_tests.cpp | 9 +- src/test/data/script_tests.json | 18 + src/test/data/siphash.json | 732 +++ src/test/descriptor_tests.cpp | 46 +- src/test/fees_util_tests.cpp | 26 + src/test/fuzz/CMakeLists.txt | 4 +- ...timator.cpp => block_policy_estimator.cpp} | 11 +- src/test/fuzz/cluster_linearize.cpp | 1 - src/test/fuzz/cmpctblock.cpp | 53 +- src/test/fuzz/coins_view.cpp | 19 +- src/test/fuzz/connect_block.cpp | 480 ++ src/test/fuzz/deserialize.cpp | 21 +- src/test/fuzz/fees.cpp | 8 +- src/test/fuzz/fuzz.cpp | 4 +- src/test/fuzz/http_request.cpp | 25 +- src/test/fuzz/integer.cpp | 45 +- src/test/fuzz/locale.cpp | 1 - src/test/fuzz/p2p_handshake.cpp | 9 +- src/test/fuzz/p2p_private_broadcast.cpp | 258 + src/test/fuzz/p2p_transport_serialization.cpp | 1 - src/test/fuzz/parse_hd_keypath.cpp | 11 +- src/test/fuzz/policy_estimator_io.cpp | 36 +- src/test/fuzz/private_broadcast.cpp | 59 +- src/test/fuzz/process_message.cpp | 37 +- src/test/fuzz/process_messages.cpp | 42 +- src/test/fuzz/psbt.cpp | 3 - src/test/fuzz/rpc.cpp | 114 +- src/test/fuzz/socks5.cpp | 1 + src/test/fuzz/tx_pool.cpp | 50 +- src/test/fuzz/txdownloadman.cpp | 6 +- src/test/fuzz/txorphan.cpp | 12 +- src/test/fuzz/util/descriptor.h | 10 +- src/test/fuzz/utxo_snapshot.cpp | 4 +- src/test/hash_tests.cpp | 94 +- src/test/httpserver_tests.cpp | 433 +- src/test/i2p_tests.cpp | 2 +- src/test/kernel/CMakeLists.txt | 4 + src/test/kernel/test_kernel.cpp | 134 + src/test/key_tests.cpp | 12 +- src/test/main.cpp | 2 + src/test/mempool_fee_estimator_tests.cpp | 343 + src/test/mempool_tests.cpp | 2 +- src/test/merkle_tests.cpp | 20 + src/test/miner_tests.cpp | 70 +- src/test/miniscript_tests.cpp | 37 +- src/test/net_tests.cpp | 77 +- src/test/pcp_tests.cpp | 5 +- src/test/pow_tests.cpp | 3 +- src/test/private_broadcast_tests.cpp | 80 + src/test/psbt_tests.cpp | 98 +- src/test/rbf_tests.cpp | 7 +- src/test/reverselock_tests.cpp | 12 +- src/test/rpc_tests.cpp | 33 + src/test/scheduler_tests.cpp | 3 +- src/test/script_p2sh_tests.cpp | 232 +- src/test/script_standard_tests.cpp | 24 +- src/test/script_tests.cpp | 3 +- src/test/scriptnum10.h | 2 +- src/test/skiplist_tests.cpp | 6 +- src/test/streams_tests.cpp | 34 +- src/test/sync_tests.cpp | 15 +- src/test/system_ram_tests.cpp | 15 +- src/test/system_tests.cpp | 7 - src/test/threadpool_tests.cpp | 6 +- src/test/transaction_tests.cpp | 3 +- src/test/txdownload_tests.cpp | 6 +- src/test/txgraph_tests.cpp | 2 +- src/test/txindex_tests.cpp | 318 +- src/test/txpackage_tests.cpp | 3 +- src/test/util/chainstate.h | 2 +- src/test/util/cluster_linearize.h | 10 +- src/test/util/coins.h | 18 + src/test/util/mining.cpp | 41 + src/test/util/mining.h | 9 + src/test/util/net.h | 8 +- src/test/util/script.h | 12 +- src/test/util/setup_common.cpp | 10 +- src/test/util/setup_common.h | 2 +- src/test/util/validation.cpp | 41 + src/test/util/validation.h | 22 + src/test/util/versionbits.h | 2 +- src/test/util_tests.cpp | 133 + .../validation_chainstatemanager_tests.cpp | 17 +- src/test/validation_flush_tests.cpp | 17 +- src/test/versionbits_tests.cpp | 6 +- src/tinyformat.h | 2 +- src/torcontrol.cpp | 5 +- src/torcontrol.h | 14 +- src/txgraph.cpp | 6 +- src/txgraph.h | 2 +- src/txmempool.cpp | 79 +- src/txmempool.h | 24 +- src/txrequest.h | 2 +- src/uint256.h | 8 +- src/univalue/include/univalue.h | 7 +- src/univalue/include/univalue_escapes.h | 2 +- src/univalue/lib/univalue_read.cpp | 16 +- src/univalue/test/object.cpp | 7 + src/util/CMakeLists.txt | 1 + src/util/bip32.cpp | 60 +- src/util/bip32.h | 23 + src/util/check.h | 8 +- src/util/exec.cpp | 11 +- src/util/fees.cpp | 32 + src/util/fees.h | 84 +- src/util/hasher.cpp | 6 +- src/util/hasher.h | 2 +- src/util/rbf.h | 2 +- src/util/sock.h | 2 +- src/util/strencodings.h | 15 +- src/util/string.cpp | 39 +- src/util/string.h | 16 +- src/util/subprocess.h | 62 +- src/util/threadnames.cpp | 11 + src/util/time.cpp | 1 - src/util/time.h | 8 - src/util/tokenbucket.h | 69 + src/validation.cpp | 15 +- src/validation.h | 12 +- src/validationinterface.cpp | 15 +- src/validationinterface.h | 7 +- src/versionbits.h | 8 +- src/wallet/coincontrol.h | 11 +- src/wallet/coinselection.h | 4 +- src/wallet/crypter.cpp | 6 +- src/wallet/crypter.h | 22 +- src/wallet/export.cpp | 14 +- src/wallet/feebumper.cpp | 32 +- src/wallet/fees.cpp | 89 +- src/wallet/fees.h | 9 +- src/wallet/interfaces.cpp | 46 +- src/wallet/receive.cpp | 32 +- src/wallet/rpc/addresses.cpp | 21 +- src/wallet/rpc/backup.cpp | 29 +- src/wallet/rpc/coins.cpp | 7 +- src/wallet/rpc/spend.cpp | 150 +- src/wallet/rpc/transactions.cpp | 33 +- src/wallet/rpc/util.h | 3 +- src/wallet/rpc/wallet.cpp | 153 +- src/wallet/scriptpubkeyman.cpp | 90 +- src/wallet/scriptpubkeyman.h | 28 +- src/wallet/spend.cpp | 48 +- src/wallet/spend.h | 1 - src/wallet/test/coinselection_tests.cpp | 20 + src/wallet/test/coinselector_tests.cpp | 3 +- src/wallet/test/fuzz/crypter.cpp | 8 +- src/wallet/test/fuzz/fees.cpp | 67 +- src/wallet/test/fuzz/spend.cpp | 1 + src/wallet/test/group_outputs_tests.cpp | 2 +- src/wallet/test/psbt_wallet_tests.cpp | 81 +- src/wallet/test/spend_tests.cpp | 1 - src/wallet/test/util.cpp | 2 - src/wallet/test/util.h | 4 +- src/wallet/test/wallet_crypto_tests.cpp | 20 +- src/wallet/test/wallet_tests.cpp | 11 +- src/wallet/test/wallet_transaction_tests.cpp | 27 + src/wallet/transaction.cpp | 56 +- src/wallet/transaction.h | 87 +- src/wallet/types.h | 23 +- src/wallet/wallet.cpp | 161 +- src/wallet/wallet.h | 73 +- src/wallet/walletdb.cpp | 100 +- src/wallet/walletdb.h | 30 +- src/wallet/walletutil.h | 40 +- src/zmq/zmqabstractnotifier.cpp | 2 - src/zmq/zmqabstractnotifier.h | 2 +- src/zmq/zmqutil.h | 2 +- test/CMakeLists.txt | 7 +- test/config.ini.in | 31 +- .../data/util/bitcoin-util-test.json | 42 +- .../data/util/getchainparams-mainnet.json | 28 + .../data/util/getchainparams-regtest.json | 19 + .../util/getchainparams-signet-custom.json | 24 + .../data/util/getchainparams-signet.json | 26 + .../data/util/getchainparams-testnet.json | 25 + .../data/util/getchainparams-testnet4.json | 23 + .../functional/data/util/netmagic-mainnet.hex | 1 - .../functional/data/util/netmagic-regtest.hex | 1 - .../data/util/netmagic-signet-custom.hex | 1 - test/functional/data/util/netmagic-signet.hex | 1 - .../functional/data/util/netmagic-testnet.hex | 1 - .../data/util/netmagic-testnet4.hex | 1 - test/functional/feature_addrman.py | 13 +- test/functional/feature_bind_extra.py | 1 + test/functional/feature_config_args.py | 20 +- test/functional/feature_fee_estimation.py | 324 +- .../feature_framework_unit_tests.py | 1 + test/functional/feature_init.py | 63 +- test/functional/feature_pruning.py | 4 +- test/functional/feature_reindex_readonly.py | 16 +- test/functional/feature_taproot.py | 17 +- .../feature_txindex_compatibility.py | 72 + test/functional/interface_gui.py | 38 + test/functional/interface_http.py | 232 +- test/functional/interface_ipc_mining.py | 89 +- test/functional/interface_rest.py | 126 +- test/functional/interface_rpc.py | 7 +- test/functional/interface_usdt_net.py | 4 +- test/functional/mempool_accept.py | 20 +- test/functional/mempool_limit.py | 3 + test/functional/mempool_sigoplimit.py | 22 +- test/functional/mempool_spend_coinbase.py | 3 +- .../mining_template_verification.py | 9 +- test/functional/p2p_blocksonly.py | 12 +- test/functional/p2p_compactblocks.py | 12 + test/functional/p2p_connection_limits.py | 107 + test/functional/p2p_eviction.py | 8 +- test/functional/p2p_getdata.py | 6 +- test/functional/p2p_nobloomfilter_messages.py | 6 +- test/functional/p2p_opportunistic_1p1c.py | 2 +- test/functional/p2p_orphan_handling.py | 26 + test/functional/p2p_private_broadcast.py | 68 +- .../p2p_private_broadcast_retry_v1.py | 4 +- test/functional/p2p_segwit.py | 4 + test/functional/p2p_sendheaders.py | 12 +- test/functional/p2p_tx_download.py | 68 + test/functional/p2p_tx_relay_rate_limit.py | 114 + test/functional/rpc_bind.py | 19 +- test/functional/rpc_deprecated.py | 14 +- test/functional/rpc_deriveaddresses.py | 1 + test/functional/rpc_echo_payload.py | 50 + test/functional/rpc_estimatefee.py | 13 +- test/functional/rpc_generate.py | 4 +- test/functional/rpc_gettxspendingprevout.py | 8 + test/functional/rpc_net.py | 9 +- test/functional/rpc_openrpc.py | 110 + test/functional/rpc_packages.py | 5 + test/functional/rpc_psbt.py | 209 +- test/functional/rpc_scanblocks.py | 3 + test/functional/rpc_scantxoutset.py | 3 + .../test_framework/crypto/siphash.py | 14 + test/functional/test_framework/netutil.py | 22 +- test/functional/test_framework/p2p.py | 27 +- test/functional/test_framework/socks5.py | 10 +- .../test_framework/test_framework.py | 39 +- test/functional/test_framework/test_node.py | 41 +- test/functional/test_framework/util.py | 41 +- test/functional/test_runner.py | 18 +- test/functional/wallet_ancient_migration.py | 229 + .../wallet_backwards_compatibility.py | 74 + test/functional/wallet_basic.py | 3 +- test/functional/wallet_bumpfee.py | 21 +- test/functional/wallet_derivehdkey.py | 235 + test/functional/wallet_fundrawtransaction.py | 4 +- test/functional/wallet_importdescriptors.py | 125 +- test/functional/wallet_importprunedfunds.py | 1 + test/functional/wallet_listreceivedby.py | 11 + test/functional/wallet_listtransactions.py | 125 + test/functional/wallet_migration.py | 12 +- .../wallet_multisig_descriptor_psbt.py | 22 +- test/functional/wallet_musig.py | 15 +- .../wallet_resendwallettransactions.py | 107 +- test/functional/wallet_taproot.py | 10 +- test/fuzz/test_runner.py | 2 +- test/lint/lint-includes.py | 6 +- test/lint/lint-python.py | 4 +- test/sanitizer_suppressions/lsan | 5 +- test/sanitizer_suppressions/ubsan | 1 + vcpkg.json | 9 +- 676 files changed, 32173 insertions(+), 14154 deletions(-) delete mode 100644 cmake/module/GenerateSetupNsi.cmake create mode 100644 cmake/script/GenerateWindowsInstaller.cmake.in create mode 100644 contrib/devtools/shell-win64-cross.nix delete mode 100755 contrib/guix/libexec/build.sh create mode 100755 contrib/guix/libexec/build_linux.sh create mode 100755 contrib/guix/libexec/build_linux_gui.sh create mode 100755 contrib/guix/libexec/build_macos.sh create mode 100755 contrib/guix/libexec/build_macos_gui.sh create mode 100755 contrib/guix/libexec/build_win.sh create mode 100755 contrib/guix/libexec/build_win_gui.sh create mode 100644 contrib/guix/manifest_gui.scm create mode 100644 depends/patches/qt/fix_missed_headers.patch delete mode 100644 depends/patches/qt/qtbase_platformsupport.patch create mode 100644 depends/patches/zeromq/add_new_include.patch create mode 100644 doc/release-notes-32784.md create mode 100644 doc/release-notes-32800.md create mode 100644 doc/release-notes-34075.md create mode 100644 doc/release-notes-34628.md create mode 100644 doc/release-notes-34672.md create mode 100644 doc/release-notes-34794.md create mode 100644 doc/release-notes-35501.md create mode 100644 doc/release-notes-35531.md create mode 100644 doc/release-notes-35592.md create mode 100644 doc/release-notes-35680.md create mode 100644 doc/release-notes-35696.md create mode 100644 doc/release-notes-35836.md create mode 100644 doc/release-notes-953.md create mode 100644 doc/release-notes-gui-872.md create mode 100644 doc/release-notes-removeprunedfunds.md create mode 100644 src/bench/uint256_blob.cpp create mode 100644 src/index/txindex_key.h delete mode 100644 src/ipc/test/ipc_test.cpp create mode 100644 src/ipc/util.h create mode 100644 src/leveldb/.github/workflows/ci.yml delete mode 100644 src/policy/fees/block_policy_estimator_args.cpp delete mode 100644 src/policy/fees/block_policy_estimator_args.h create mode 100644 src/policy/fees/estimator_args.cpp create mode 100644 src/policy/fees/estimator_args.h create mode 100644 src/policy/fees/estimator_man.cpp create mode 100644 src/policy/fees/estimator_man.h create mode 100644 src/policy/fees/mempool_estimator.cpp create mode 100644 src/policy/fees/mempool_estimator.h delete mode 100644 src/qt/locale/bitcoin_en.xlf create mode 100644 src/script/trace.cpp create mode 100644 src/script/trace.h create mode 100644 src/secp256k1/examples/silentpayments.c create mode 100644 src/secp256k1/include/secp256k1_silentpayments.h create mode 100644 src/secp256k1/src/modules/silentpayments/Makefile.am.include create mode 100644 src/secp256k1/src/modules/silentpayments/bench_impl.h create mode 100644 src/secp256k1/src/modules/silentpayments/bip352_send_and_receive_test_vectors.json create mode 100644 src/secp256k1/src/modules/silentpayments/main_impl.h create mode 100644 src/secp256k1/src/modules/silentpayments/tests_impl.h create mode 100644 src/secp256k1/src/modules/silentpayments/vectors.h create mode 100755 src/secp256k1/tools/tests_silentpayments_generate.py rename src/test/{policyestimator_tests.cpp => blockpolicyestimator_tests.cpp} (57%) create mode 100644 src/test/data/siphash.json create mode 100644 src/test/fees_util_tests.cpp rename src/test/fuzz/{policy_estimator.cpp => block_policy_estimator.cpp} (94%) create mode 100644 src/test/fuzz/connect_block.cpp create mode 100644 src/test/fuzz/p2p_private_broadcast.cpp create mode 100644 src/test/mempool_fee_estimator_tests.cpp create mode 100644 src/util/fees.cpp create mode 100644 src/util/tokenbucket.h create mode 100644 test/functional/data/util/getchainparams-mainnet.json create mode 100644 test/functional/data/util/getchainparams-regtest.json create mode 100644 test/functional/data/util/getchainparams-signet-custom.json create mode 100644 test/functional/data/util/getchainparams-signet.json create mode 100644 test/functional/data/util/getchainparams-testnet.json create mode 100644 test/functional/data/util/getchainparams-testnet4.json delete mode 100644 test/functional/data/util/netmagic-mainnet.hex delete mode 100644 test/functional/data/util/netmagic-regtest.hex delete mode 100644 test/functional/data/util/netmagic-signet-custom.hex delete mode 100644 test/functional/data/util/netmagic-signet.hex delete mode 100644 test/functional/data/util/netmagic-testnet.hex delete mode 100644 test/functional/data/util/netmagic-testnet4.hex create mode 100755 test/functional/feature_txindex_compatibility.py create mode 100755 test/functional/interface_gui.py create mode 100755 test/functional/p2p_connection_limits.py create mode 100755 test/functional/p2p_tx_relay_rate_limit.py create mode 100755 test/functional/rpc_echo_payload.py create mode 100755 test/functional/rpc_openrpc.py create mode 100755 test/functional/wallet_ancient_migration.py create mode 100755 test/functional/wallet_derivehdkey.py diff --git a/.github/actions/configure-environment/action.yml b/.github/actions/configure-environment/action.yml index e2a26b71..d3c928cf 100644 --- a/.github/actions/configure-environment/action.yml +++ b/.github/actions/configure-environment/action.yml @@ -7,7 +7,9 @@ runs: shell: bash run: | echo "BASE_ROOT_DIR=${{ runner.temp }}" >> "$GITHUB_ENV" - echo "BASE_BUILD_DIR=${{ runner.temp }}/build" >> "$GITHUB_ENV" + # Space and non-ASCII symbols mimic BASE_SCRATCH_DIR in ci/test/00_setup_env.sh, + # to test word-splitting and UTF-8 path handling on CI. + echo "BASE_BUILD_DIR=${{ runner.temp }}/build_ ₿🧪_" >> "$GITHUB_ENV" echo "CCACHE_DIR=${{ runner.temp }}/ccache_dir" >> $GITHUB_ENV echo "DEPENDS_DIR=${{ runner.temp }}/depends" >> "$GITHUB_ENV" echo "BASE_CACHE=${{ runner.temp }}/depends/built" >> $GITHUB_ENV diff --git a/.github/ci-windows-cross.py b/.github/ci-windows-cross.py index bf13f81a..355d8fb7 100755 --- a/.github/ci-windows-cross.py +++ b/.github/ci-windows-cross.py @@ -5,6 +5,7 @@ import argparse import os +import re import shlex import subprocess import sys @@ -28,6 +29,31 @@ def print_version(): run([str(bitcoind), "-version"]) +def check_imports(): + bitcoind = Path.cwd() / "bin" / "bitcoind.exe" + output = run( + ["dumpbin.exe", "/imports", str(bitcoind)], + capture_output=True, + text=True, + ).stdout + dlls = re.findall(r"^\s*(\S+\.dll)\s*$", output, re.IGNORECASE | re.MULTILINE) + print("\n".join(dlls)) + + # Ensure the executable is linked against the expected C runtime. + dlls = {name.lower() for name in dlls} + uses_msvcrt = "msvcrt.dll" in dlls + uses_ucrt = any(name.startswith("api-ms-win-crt-") for name in dlls) + crt = os.environ["CRT"] + if crt == "msvcrt": + crt_ok = uses_msvcrt and not uses_ucrt + elif crt == "ucrt": + crt_ok = uses_ucrt and not uses_msvcrt + else: + sys.exit(f"Unexpected CRT value: {crt!r}") + if not crt_ok: + sys.exit(f"Imported DLLs do not match the expected {crt!r} C runtime.") + + def check_manifests(): release_dir = Path.cwd() / "bin" manifest_path = release_dir / "bitcoind.manifest" @@ -99,23 +125,26 @@ def run_functional_tests(): f"--tmpdirprefix={workspace / '_ _'}", "--combinedlogslen=99999999", *shlex.split(os.environ.get("TEST_RUNNER_EXTRA", "").strip()), - # feature_unsupported_utxo_db.py fails on Windows because of emojis in the test data directory. + # Tests using ancient releases fail on Windows because of emojis in the test data directory. "--exclude", "feature_unsupported_utxo_db.py", + "--exclude", + "wallet_ancient_migration.py", ] run(test_runner_cmd) - # Run feature_unsupported_utxo_db sequentially in ASCII-only tmp dir, - # because it is excluded above due to lack of UTF-8 support in the + # Run ancient release tests sequentially in ASCII-only tmp dir, + # because they are excluded above due to lack of UTF-8 support in the # ancient release. - cmd_feature_unsupported_db = [ - sys.executable, - str(workspace / "test" / "functional" / "feature_unsupported_utxo_db.py"), - "--previous-releases", - "--tmpdir", - str(Path(workspace) / "test_feature_unsupported_utxo_db"), - ] - run(cmd_feature_unsupported_db) + for test_name in ["feature_unsupported_utxo_db", "wallet_ancient_migration"]: + cmd = [ + sys.executable, + str(workspace / "test" / "functional" / f"{test_name}.py"), + "--previous-releases", + "--tmpdir", + str(workspace / f"test_{test_name}"), + ] + run(cmd) def run_unit_tests(): @@ -140,6 +169,7 @@ def main(): parser = argparse.ArgumentParser(description="Utility to run Windows CI steps.") steps = list(map(lambda f: f.__name__, [ print_version, + check_imports, check_manifests, prepare_tests, run_unit_tests, diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bce9c603..d8d48eec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -403,6 +403,11 @@ jobs: - *IMPORT_VS_ENV + - name: Check imported DLLs + env: + CRT: ${{ matrix.crt }} + run: py -3 .github/ci-windows-cross.py check_imports + - name: Check executable manifests run: py -3 .github/ci-windows-cross.py check_manifests diff --git a/.tx/config b/.tx/config index 41051254..a43890a3 100644 --- a/.tx/config +++ b/.tx/config @@ -1,7 +1,7 @@ [main] host = https://www.transifex.com -[o:bitcoin:p:bitcoin:r:qt-translation-031x] -file_filter = src/qt/locale/bitcoin_.xlf -source_file = src/qt/locale/bitcoin_en.xlf +[o:bitcoin:p:bitcoin:r:qt-translation-032x] +file_filter = src/qt/locale/bitcoin_.ts +source_file = src/qt/locale/bitcoin_en.ts source_lang = en diff --git a/CMakeLists.txt b/CMakeLists.txt index ffd2da14..f36c4cd4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -330,10 +330,6 @@ if(WIN32) /Zc:__cplusplus /sdl ) - target_link_options(core_interface INTERFACE - # We embed our own manifests. - /MANIFEST:NO - ) # Improve parallelism in MSBuild. # See: https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/. list(APPEND CMAKE_VS_GLOBALS "UseMultiToolTask=true") @@ -471,7 +467,6 @@ if(MSVC) try_append_cxx_flags("/wd4805" TARGET warn_interface SKIP_LINK) target_compile_definitions(warn_interface INTERFACE _CRT_SECURE_NO_WARNINGS - _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING ) else() try_append_cxx_flags("-Wall" TARGET warn_interface SKIP_LINK) @@ -601,6 +596,7 @@ endif() if(REDUCE_EXPORTS) set(CMAKE_CXX_VISIBILITY_PRESET hidden) + set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) try_append_linker_flag("-Wl,--exclude-libs,ALL" TARGET core_interface) try_append_linker_flag("-Wl,-no_exported_symbols" VAR CMAKE_EXE_LINKER_FLAGS) endif() diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bcf0815d..93be1099 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -106,7 +106,8 @@ fixes or code moves with actual code changes. Make sure each individual commit is hygienic: that it builds successfully on its own without warnings, errors, regressions, or test failures. -This means tests must be updated in the same commit that changes the behavior. +See the [developer notes](doc/developer-notes.md#commit-structure-for-tests) +for guidance on where test coverage belongs in a commit stack. Commit messages should be verbose by default consisting of a short subject line (50 chars max), a blank line and detailed explanatory text as separate diff --git a/ci/lint/requirements.txt b/ci/lint/requirements.txt index e9459225..5a6b7624 100644 --- a/ci/lint/requirements.txt +++ b/ci/lint/requirements.txt @@ -1,3 +1,4 @@ +# lief version should match the version used in Guix lief==0.17.5 -mypy==2.3.0 -pyzmq==27.1.0 +mypy==2.3.1 +pyzmq==27.2.0 diff --git a/ci/lint_imagefile b/ci/lint_imagefile index cc4986a7..45bfe11e 100644 --- a/ci/lint_imagefile +++ b/ci/lint_imagefile @@ -10,7 +10,7 @@ FROM mirror.gcr.io/ubuntu:26.04 # https://docs.astral.sh/uv/reference/policies/versioning/ # https://docs.astral.sh/ruff/versioning/ COPY --from=ghcr.io/astral-sh/uv:0.11 /uv /uvx /bin/ -COPY --from=ghcr.io/astral-sh/ruff:0.15 /ruff /bin/ +COPY --from=ghcr.io/astral-sh/ruff:0.16 /ruff /bin/ COPY ./ci/retry/retry /ci_retry COPY ./.python-version /.python-version diff --git a/ci/test/00_setup_env.sh b/ci/test/00_setup_env.sh index 4ca660a5..fc8f2d98 100755 --- a/ci/test/00_setup_env.sh +++ b/ci/test/00_setup_env.sh @@ -14,7 +14,9 @@ BASE_READ_ONLY_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../../ >/dev/null 2> export BASE_READ_ONLY_DIR # The destination root dir inside the container. # This folder will also hold any SDKs. -# This folder only exists on the ci guest and will be a copy of BASE_READ_ONLY_DIR +# This folder only exists on the ci guest and will be a copy of BASE_READ_ONLY_DIR. +# This value is embedded in the CI image at build time; changing it requires +# rebuilding the image. export BASE_ROOT_DIR="${BASE_ROOT_DIR:-/ci_container_base}" # The depends dir. # This folder exists only on the ci guest, and on the ci host as a volume. diff --git a/ci/test/00_setup_env_freebsd_cross.sh b/ci/test/00_setup_env_freebsd_cross.sh index 29602ae2..9a22cb6f 100755 --- a/ci/test/00_setup_env_freebsd_cross.sh +++ b/ci/test/00_setup_env_freebsd_cross.sh @@ -12,6 +12,7 @@ export APT_LLVM_V="22" export HOST=x86_64-unknown-freebsd export FREEBSD_VERSION=15.1 export FREEBSD_SDK_BASENAME="freebsd-${HOST}-${FREEBSD_VERSION}" +export FREEBSD_SDK_SHA256=3768988b151c20f965679062b065c63a977d6bbb9f47fd83695ec2c40790c18f export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} lld-${APT_LLVM_V}" export SYSROOT="--sysroot=${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" export DEP_OPTS="build_CC=clang build_CXX=clang++ \ diff --git a/ci/test/00_setup_env_i686_no_ipc.sh b/ci/test/00_setup_env_i686_no_ipc.sh index d8df8100..f8943a00 100755 --- a/ci/test/00_setup_env_i686_no_ipc.sh +++ b/ci/test/00_setup_env_i686_no_ipc.sh @@ -6,12 +6,13 @@ export LC_ALL=C.UTF-8 -export HOST=i686-pc-linux-gnu +export HOST=i686-linux-gnu +export DPKG_ADD_ARCH="i386" export CONTAINER_NAME=ci_i686_no_multiprocess export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export CI_IMAGE_PLATFORM="linux/amd64" export CI_CONTAINER_CAP="--security-opt seccomp=unconfined" -export PACKAGES="g++-multilib" +export PACKAGES="g++-i686-linux-gnu binutils-i686-linux-gnu libstdc++6:i386 libatomic1:i386" export DEP_OPTS="DEBUG=1 NO_IPC=1" export GOAL="install" export CI_LIMIT_STACK_SIZE=1 diff --git a/ci/test/00_setup_env_mac_cross.sh b/ci/test/00_setup_env_mac_cross.sh index 63d89fb9..80c6f878 100755 --- a/ci/test/00_setup_env_mac_cross.sh +++ b/ci/test/00_setup_env_mac_cross.sh @@ -14,6 +14,7 @@ export HOST=arm64-apple-darwin export PACKAGES="clang lld llvm zip" export XCODE_VERSION=26.1.1 export XCODE_BUILD_ID=17B100 +export OSX_SDK_SHA256=9600fa93644df674ee916b5e2c8a6ba8dacf631996a65dc922d003b98b5ea3b1 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/ci/test/00_setup_env_mac_cross_intel.sh b/ci/test/00_setup_env_mac_cross_intel.sh index 4b07e14b..e679c957 100755 --- a/ci/test/00_setup_env_mac_cross_intel.sh +++ b/ci/test/00_setup_env_mac_cross_intel.sh @@ -14,6 +14,7 @@ export HOST=x86_64-apple-darwin export PACKAGES="clang lld llvm zip" export XCODE_VERSION=26.1.1 export XCODE_BUILD_ID=17B100 +export OSX_SDK_SHA256=9600fa93644df674ee916b5e2c8a6ba8dacf631996a65dc922d003b98b5ea3b1 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/ci/test/00_setup_env_netbsd_cross.sh b/ci/test/00_setup_env_netbsd_cross.sh index 9fb4c18a..e817473f 100755 --- a/ci/test/00_setup_env_netbsd_cross.sh +++ b/ci/test/00_setup_env_netbsd_cross.sh @@ -10,8 +10,11 @@ export CONTAINER_NAME=ci_netbsd_cross export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export APT_LLVM_V="22" export HOST=x86_64-unknown-netbsd -export NETBSD_VERSION=11.0_RC6 +export NETBSD_VERSION=11.0 export NETBSD_SDK_BASENAME="netbsd-${HOST}-${NETBSD_VERSION}" +export NETBSD_SDK_SHA512SUMS="\ +e8871bbedb8c3e0f696cc2596ced0c1e6497939f725fb3495b8d2c168430325907550f5f840f4dd0e3c73e6090394747c5e54762f2737de81177b984403522a8 base.tar.xz\n\ +d8df6c07e9142dd8189292b769ac312f86185a6a278a752c18c840f7cd3a8dd3c535f9b0c8e06b62d556b2c75b97a01d786184e8a18f5e080ccd213591c8628f comp.tar.xz" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} lld-${APT_LLVM_V}" export SYSROOT="--sysroot=${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" export DEP_OPTS="build_CC=clang build_CXX=clang++ \ diff --git a/ci/test/00_setup_env_openbsd_cross.sh b/ci/test/00_setup_env_openbsd_cross.sh index 1732aef3..f9d75e47 100755 --- a/ci/test/00_setup_env_openbsd_cross.sh +++ b/ci/test/00_setup_env_openbsd_cross.sh @@ -12,6 +12,9 @@ export APT_LLVM_V="22" export HOST=x86_64-unknown-openbsd export OPENBSD_VERSION=7.9 export OPENBSD_SDK_BASENAME="openbsd-${HOST}-${OPENBSD_VERSION}" +export OPENBSD_SDK_SHA256SUMS="\ +923d2e03f06408d50d4848334398c6d04b5514dcac7917badfc178a0eef248de base79.tgz\n\ +21a67af20aebcabf85b09f4206fc95b4cae0a35d42b154b976f0159f457724f9 comp79.tgz" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} lld-${APT_LLVM_V}" export SYSROOT="--sysroot=${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" export DEP_OPTS="NO_QT=1 build_CC=clang build_CXX=clang++ \ diff --git a/ci/test/00_setup_env_win64.sh b/ci/test/00_setup_env_win64.sh index dbbf55c1..74891889 100755 --- a/ci/test/00_setup_env_win64.sh +++ b/ci/test/00_setup_env_win64.sh @@ -7,9 +7,9 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_win64 -export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" # Check that https://packages.debian.org/trixie/g++-mingw-w64-ucrt64 can cross-compile +export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export HOST=x86_64-w64-mingw32ucrt -export PACKAGES="g++-mingw-w64-ucrt64 nsis" +export PACKAGES="nix-bin nix-setup-systemd" export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/ci/test/00_setup_env_win64_msvcrt.sh b/ci/test/00_setup_env_win64_msvcrt.sh index 6c948aeb..d1c1aa8a 100755 --- a/ci/test/00_setup_env_win64_msvcrt.sh +++ b/ci/test/00_setup_env_win64_msvcrt.sh @@ -7,9 +7,9 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_win64_msvcrt -export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" # Check that https://packages.debian.org/trixie/g++-mingw-w64-x86-64-posix (version 14.x, similar to guix) can cross-compile +export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export HOST=x86_64-w64-mingw32 -export PACKAGES="g++-mingw-w64-x86-64-posix nsis" +export PACKAGES="nix-bin nix-setup-systemd" export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index f619a088..057916e2 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -50,6 +50,11 @@ elif [ "$CI_OS_NAME" != "macos" ]; then ${CI_RETRY_EXE} apt-get install --no-install-recommends --no-upgrade -y $PACKAGES $CI_BASE_PACKAGES fi +if [[ ${HOST:-} == x86_64-w64-mingw32* ]]; then + # Install Nix packages. + NIX_BUILD_SHELL=bash nix-shell "${BASE_ROOT_DIR}/contrib/devtools/shell-win64-cross.nix" --run true +fi + if [ -n "${APT_LLVM_V}" ]; then update-alternatives --install /usr/bin/clang++ clang++ "/usr/bin/clang++-${APT_LLVM_V}" 100 update-alternatives --install /usr/bin/clang clang "/usr/bin/clang-${APT_LLVM_V}" 100 @@ -88,18 +93,18 @@ if [[ -n "${USE_INSTRUMENTED_LIBCPP}" ]]; then fi if [[ ${BARE_METAL_RISCV} == "true" ]]; then - ${CI_RETRY_EXE} git clone --depth=1 https://github.com/riscv-collab/riscv-gnu-toolchain -b 2026.06.06 /riscv/gcc - ( cd /riscv/gcc; - ./configure --prefix=/opt/riscv-ilp32 --with-arch=rv32gc --with-abi=ilp32 --disable-gdb; - make "$MAKEJOBS"; ) + ${CI_RETRY_EXE} git clone --depth=1 https://github.com/riscv-collab/riscv-gnu-toolchain -b 2026.08.25 /riscv/gcc + ( cd /riscv/gcc + ./configure --prefix=/opt/riscv-ilp32 --with-arch=rv32gc --with-abi=ilp32 --disable-gdb + make "$MAKEJOBS" ) rm -rf /riscv/gcc fi if [[ "${RUN_IWYU}" == true ]]; then ${CI_RETRY_EXE} git clone --depth=1 https://github.com/include-what-you-use/include-what-you-use -b clang_"${IWYU_LLVM_V}" /include-what-you-use pushd /include-what-you-use - patch -p1 < /ci_container_base/ci/test/01_iwyu.patch - patch -p1 < /ci_container_base/ci/test/02_iwyu_hash.patch + patch -p1 < "${BASE_ROOT_DIR}/ci/test/01_iwyu.patch" + patch -p1 < "${BASE_ROOT_DIR}/ci/test/02_iwyu_hash.patch" popd cmake -B /iwyu-build/ -G 'Unix Makefiles' -DCMAKE_PREFIX_PATH=/usr/lib/llvm-"${IWYU_LLVM_V}" -S /include-what-you-use make -C /iwyu-build/ install "$MAKEJOBS" @@ -115,18 +120,20 @@ if [ -n "$XCODE_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${OSX_SDK_BASENAME}" ] if [ ! -f "$OSX_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "${SDK_URL}/${OSX_SDK_FILENAME}" -o "$OSX_SDK_PATH" fi + sha256sum -c <<<"${OSX_SDK_SHA256} ${OSX_SDK_PATH}" tar -C "${DEPENDS_DIR}/SDKs" -xf "$OSX_SDK_PATH" fi if [ -n "$NETBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" ]; then mkdir -p "${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" - for NETBSD_SDK_FILENAME in base.tar.xz comp.tar.xz; do + while read -r NETBSD_SDK_SHA512 NETBSD_SDK_FILENAME; do NETBSD_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${NETBSD_SDK_FILENAME}" if [ ! -f "$NETBSD_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "https://cdn.netbsd.org/pub/NetBSD/NetBSD-${NETBSD_VERSION}/amd64/binary/sets/${NETBSD_SDK_FILENAME}" -o "$NETBSD_SDK_PATH" fi + sha512sum -c <<<"${NETBSD_SDK_SHA512} ${NETBSD_SDK_PATH}" tar -C "${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" -xf "$NETBSD_SDK_PATH" - done + done < <(printf '%b\n' "${NETBSD_SDK_SHA512SUMS}") fi if [ -n "$FREEBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" ]; then @@ -135,27 +142,29 @@ if [ -n "$FREEBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENA if [ ! -f "$FREEBSD_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "https://download.freebsd.org/releases/amd64/${FREEBSD_VERSION}-RELEASE/base.txz" -o "$FREEBSD_SDK_PATH" fi + sha256sum -c <<<"${FREEBSD_SDK_SHA256} ${FREEBSD_SDK_PATH}" mkdir -p "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" tar -C "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" -xf "$FREEBSD_SDK_PATH" fi if [ -n "$OPENBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" ]; then mkdir -p "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" - for OPENBSD_SDK_FILENAME in base79.tgz comp79.tgz; do + while read -r OPENBSD_SDK_SHA256 OPENBSD_SDK_FILENAME; do OPENBSD_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${OPENBSD_SDK_FILENAME}" if [ ! -f "$OPENBSD_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "https://cdn.openbsd.org/pub/OpenBSD/${OPENBSD_VERSION}/amd64/${OPENBSD_SDK_FILENAME}" -o "$OPENBSD_SDK_PATH" fi + sha256sum -c <<<"${OPENBSD_SDK_SHA256} ${OPENBSD_SDK_PATH}" tar -C "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" -xf "$OPENBSD_SDK_PATH" - ( - # The SDK has versioned shared libs, but no unversioned libfoo.so symlink, - # which breaks linking the kernel with lld. Create the symlinks. - cd "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}/usr/lib" - ln -sf libc++abi.so.*.* libc++abi.so - ln -sf libc++.so.*.* libc++.so - ln -sf libpthread.so.*.* libpthread.so - ) - done + done < <(printf '%b\n' "${OPENBSD_SDK_SHA256SUMS}") + ( + # The SDK has versioned shared libs, but no unversioned libfoo.so symlink, + # which breaks linking the kernel with lld. Create the symlinks. + cd "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}/usr/lib" + ln -sf libc++abi.so.*.* libc++abi.so + ln -sf libc++.so.*.* libc++.so + ln -sf libpthread.so.*.* libpthread.so + ) fi echo -n "done" > "${CFG_DONE}" diff --git a/ci/test/02_run_container.py b/ci/test/02_run_container.py index 05887000..d726b36a 100755 --- a/ci/test/02_run_container.py +++ b/ci/test/02_run_container.py @@ -183,7 +183,18 @@ def ci_exec(cmd_inner, **kwargs): f"{os.environ['BASE_ROOT_DIR']}", ]) ci_exec([f"{os.environ['BASE_ROOT_DIR']}/ci/test/01_base_install.sh"]) - ci_exec([f"{os.environ['BASE_ROOT_DIR']}/ci/test/03_test_script.sh"]) + test_script = f"{os.environ['BASE_ROOT_DIR']}/ci/test/03_test_script.sh" + if os.environ.get("HOST", "").startswith("x86_64-w64-mingw32"): + ci_exec([ + "env", + "NIX_BUILD_SHELL=bash", + "nix-shell", + f"{os.environ['BASE_ROOT_DIR']}/contrib/devtools/shell-win64-cross.nix", + "--run", + f"exec bash {shlex.quote(test_script)}", + ]) + else: + ci_exec([test_script]) if not os.getenv("DANGER_RUN_CI_ON_HOST"): print("Stop and remove CI container by ID") diff --git a/ci/test/03_test_script.sh b/ci/test/03_test_script.sh index 7650ab7d..cffd87af 100755 --- a/ci/test/03_test_script.sh +++ b/ci/test/03_test_script.sh @@ -17,7 +17,7 @@ cd "${BASE_ROOT_DIR}" export PATH="/path_with space:${PATH}" export ASAN_OPTIONS="detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1" -export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan" +export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan:print_suppressions=0" export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1:second_deadlock_stack=1" export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" @@ -234,7 +234,7 @@ fi if [[ "${RUN_IWYU}" == true ]]; then # TODO: Consider enforcing IWYU across the entire codebase. - FILES_WITH_ENFORCED_IWYU="/src/(((bench|crypto|index|kernel|primitives|script|univalue/(lib|test)|util|zmq)/.*|common/license_info|node/(blockstorage|interfaces|miner|mining_args|utxo_snapshot)|rpc/mining|clientversion|core_io|signet|init)\\.cpp)" + FILES_WITH_ENFORCED_IWYU='/src/((bench|common|consensus|crypto|index|kernel|primitives|script|univalue/(lib|test)|util|zmq)/.*|node/(blockstorage|interfaces|miner|mining_args|utxo_snapshot)|rpc/mining|clientversion|core_io|signet|init)\.cpp' jq --arg patterns "$FILES_WITH_ENFORCED_IWYU" 'map(select(.file | test($patterns)))' "${BASE_BUILD_DIR}/compile_commands.json" > "${BASE_BUILD_DIR}/compile_commands_iwyu_errors.json" jq --arg patterns "$FILES_WITH_ENFORCED_IWYU" 'map(select(.file | test($patterns) | not))' "${BASE_BUILD_DIR}/compile_commands.json" > "${BASE_BUILD_DIR}/compile_commands_iwyu_warnings.json" @@ -247,7 +247,10 @@ if [[ "${RUN_IWYU}" == true ]]; then -p "${BASE_BUILD_DIR}" "${MAKEJOBS}" \ -- -Xiwyu --cxx17ns -Xiwyu --mapping_file="${BASE_ROOT_DIR}/contrib/devtools/iwyu/bitcoin.core.imp" \ -Xiwyu --max_line_length=160 \ - -Xiwyu --check_also="*/primitives/*.h" \ + -Xiwyu --check_also='*/common/types\.h' \ + -Xiwyu --check_also='*/consensus/*\.h' \ + -Xiwyu --check_also='*/interfaces/*\.h' \ + -Xiwyu --check_also='*/primitives/transaction_identifier\.h' \ 2>&1 || true } | tee /tmp/iwyu_ci.out python3 "/include-what-you-use/fix_includes.py" --nosafe_headers < /tmp/iwyu_ci.out diff --git a/ci/test_imagefile b/ci/test_imagefile index dac6b553..7cb88ddb 100644 --- a/ci/test_imagefile +++ b/ci/test_imagefile @@ -16,10 +16,11 @@ ENV BASE_ROOT_DIR=${BASE_ROOT_DIR} # Make retry available in PATH, needed for CI_RETRY_EXE COPY ./ci/retry/retry /usr/bin/retry -COPY ./ci/test/00_setup_env.sh ./${FILE_ENV} ./ci/test/01_base_install.sh /ci_container_base/ci/test/ -COPY ./ci/test/*.patch /ci_container_base/ci/test/ +COPY ./ci/test/00_setup_env.sh ./${FILE_ENV} ./ci/test/01_base_install.sh ${BASE_ROOT_DIR}/ci/test/ +COPY ./contrib/devtools/shell-win64-cross.nix ${BASE_ROOT_DIR}/contrib/devtools/ +COPY ./ci/test/*.patch ${BASE_ROOT_DIR}/ci/test/ # Bash is required, so install it when missing RUN sh -c "bash -c 'true' || ( apk update && apk add --no-cache bash )" -RUN ["bash", "-c", "cd /ci_container_base/ && set -o errexit && source ./ci/test/00_setup_env.sh && DANGER_RUN_CI_ON_HOST=1 ./ci/test/01_base_install.sh"] +RUN ["bash", "-c", "cd ${BASE_ROOT_DIR}/ && set -o errexit && source ./ci/test/00_setup_env.sh && DANGER_RUN_CI_ON_HOST=1 ./ci/test/01_base_install.sh"] diff --git a/cmake/bitcoin-build-config.h.in b/cmake/bitcoin-build-config.h.in index bf3ddcd7..5e1c1008 100644 --- a/cmake/bitcoin-build-config.h.in +++ b/cmake/bitcoin-build-config.h.in @@ -76,6 +76,9 @@ /* Define this symbol if you have posix_fallocate */ #cmakedefine HAVE_POSIX_FALLOCATE 1 +/* Define this symbol if you have SetThreadDescription */ +#cmakedefine HAVE_SETTHREADDESCRIPTION 1 + /* Define this symbol if platform supports unix domain sockets */ #cmakedefine HAVE_SOCKADDR_UN 1 @@ -88,7 +91,7 @@ /* Define this symbol if the BSD sysctl(KERN_ARND) is available */ #cmakedefine HAVE_SYSCTL_ARND 1 -/* Define to 1 if std::system or ::wsystem is available. */ +/* Define to 1 if std::system is available. */ #cmakedefine HAVE_SYSTEM 1 /* Define to the address where bug reports for this package should be sent. */ diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake index d6083f52..a99a7660 100644 --- a/cmake/introspection.cmake +++ b/cmake/introspection.cmake @@ -24,8 +24,7 @@ endif() # Even though ::system is part of the standard library, we still check # for it, to support building targets that don't have it, such as iOS. check_cxx_symbol_exists(std::system "cstdlib" HAVE_STD_SYSTEM) -check_cxx_symbol_exists(::_wsystem "stdlib.h" HAVE__WSYSTEM) -if(HAVE_STD_SYSTEM OR HAVE__WSYSTEM) +if(HAVE_STD_SYSTEM) set(HAVE_SYSTEM 1) endif() @@ -77,6 +76,10 @@ check_cxx_source_compiles(" " HAVE_STRONG_GETAUXVAL ) +# Check for SetThreadDescription(), which is missing from mingw-w64 headers +# before 12.0.0. +check_cxx_symbol_exists(SetThreadDescription "windows.h" HAVE_SETTHREADDESCRIPTION) + # Check for UNIX sockets. check_cxx_source_compiles(" #include diff --git a/cmake/module/AddWindowsResources.cmake b/cmake/module/AddWindowsResources.cmake index 84c1ba85..8fad425a 100644 --- a/cmake/module/AddWindowsResources.cmake +++ b/cmake/module/AddWindowsResources.cmake @@ -4,21 +4,19 @@ include_guard(GLOBAL) -function(add_windows_resources target rc_file) - if(WIN32) - target_sources(${target} PRIVATE ${rc_file}) - endif() -endfunction() - # Add a fusion manifest to Windows executables. # See: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests function(add_windows_application_manifest target) - if(WIN32) - configure_file(${PROJECT_SOURCE_DIR}/cmake/windows-app.manifest.in ${target}.manifest USE_SOURCE_PERMISSIONS) + configure_file(${PROJECT_SOURCE_DIR}/cmake/windows-app.manifest.in ${target}.manifest USE_SOURCE_PERMISSIONS) + if(MSVC) + target_sources(${target} PRIVATE ${target}.manifest) + else() + # TODO: Remove when upstream issue is fixed: + # https://gitlab.kitware.com/cmake/cmake/-/issues/23244 file(CONFIGURE OUTPUT ${target}-manifest.rc CONTENT "1 /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 24 /* RT_MANIFEST */ \"${target}.manifest\"" ) - add_windows_resources(${target} ${CMAKE_CURRENT_BINARY_DIR}/${target}-manifest.rc) + target_sources(${target} PRIVATE ${target}-manifest.rc) endif() endfunction() diff --git a/cmake/module/GenerateSetupNsi.cmake b/cmake/module/GenerateSetupNsi.cmake deleted file mode 100644 index c8d5bd67..00000000 --- a/cmake/module/GenerateSetupNsi.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2023-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit/. - -function(generate_setup_nsi) - set(abs_top_srcdir ${PROJECT_SOURCE_DIR}) - set(abs_top_builddir ${PROJECT_BINARY_DIR}) - set(CLIENT_URL ${PROJECT_HOMEPAGE_URL}) - set(CLIENT_TARNAME "bitcoin") - set(BITCOIN_WRAPPER_NAME "bitcoin") - set(BITCOIN_GUI_NAME "bitcoin-qt") - set(BITCOIN_DAEMON_NAME "bitcoind") - set(BITCOIN_CLI_NAME "bitcoin-cli") - set(BITCOIN_TX_NAME "bitcoin-tx") - set(BITCOIN_WALLET_TOOL_NAME "bitcoin-wallet") - set(BITCOIN_TEST_NAME "test_bitcoin") - set(EXEEXT ${CMAKE_EXECUTABLE_SUFFIX}) - configure_file(${PROJECT_SOURCE_DIR}/share/setup.nsi.in ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.nsi USE_SOURCE_PERMISSIONS @ONLY) -endfunction() diff --git a/cmake/module/Maintenance.cmake b/cmake/module/Maintenance.cmake index 15fbf2be..43e145d6 100644 --- a/cmake/module/Maintenance.cmake +++ b/cmake/module/Maintenance.cmake @@ -19,32 +19,21 @@ function(setup_split_debug_script) endfunction() function(add_windows_deploy_target) + configure_file(${PROJECT_SOURCE_DIR}/cmake/script/GenerateWindowsInstaller.cmake.in ${PROJECT_BINARY_DIR}/GenerateWindowsInstaller.cmake USE_SOURCE_PERMISSIONS @ONLY) if(MINGW AND TARGET bitcoin AND TARGET bitcoin-qt AND TARGET bitcoind AND TARGET bitcoin-cli AND TARGET bitcoin-tx AND TARGET bitcoin-wallet AND TARGET bitcoin-util AND TARGET test_bitcoin) - find_program(MAKENSIS_EXECUTABLE makensis) - if(NOT MAKENSIS_EXECUTABLE) - add_custom_target(deploy - COMMAND ${CMAKE_COMMAND} -E echo "Error: NSIS not found" - ) - return() - endif() - - # TODO: Consider replacing this code with the CPack NSIS Generator. - # See https://cmake.org/cmake/help/latest/cpack_gen/nsis.html - include(GenerateSetupNsi) - generate_setup_nsi() add_custom_command( OUTPUT ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.exe - COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/release - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${MAKENSIS_EXECUTABLE} -V2 ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.nsi - VERBATIM + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory release + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_COMMAND} -D BIN_DIR=release -D LIBEXEC_DIR=release -P GenerateWindowsInstaller.cmake ) add_custom_target(deploy DEPENDS ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.exe) endif() diff --git a/cmake/script/GenerateWindowsInstaller.cmake.in b/cmake/script/GenerateWindowsInstaller.cmake.in new file mode 100644 index 00000000..16ebdd49 --- /dev/null +++ b/cmake/script/GenerateWindowsInstaller.cmake.in @@ -0,0 +1,40 @@ +# Copyright (c) 2026-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +find_program(MAKENSIS_EXECUTABLE makensis REQUIRED) + +# Project variables. +set(CLIENT_NAME "@CLIENT_NAME@") +set(CLIENT_VERSION_MAJOR @CLIENT_VERSION_MAJOR@) +set(CLIENT_VERSION_MINOR @CLIENT_VERSION_MINOR@) +set(CLIENT_VERSION_BUILD @CLIENT_VERSION_BUILD@) +set(CLIENT_VERSION_STRING "@CLIENT_VERSION_STRING@") +set(CLIENT_URL "@PROJECT_HOMEPAGE_URL@") +set(COPYRIGHT_YEAR "@COPYRIGHT_YEAR@") +set(COPYRIGHT_HOLDERS_FINAL "@COPYRIGHT_HOLDERS_FINAL@") +set(abs_top_srcdir @PROJECT_SOURCE_DIR@) +set(EXEEXT @CMAKE_EXECUTABLE_SUFFIX@) + +# Script variables. +cmake_path(ABSOLUTE_PATH BIN_DIR NORMALIZE) +cmake_path(ABSOLUTE_PATH LIBEXEC_DIR NORMALIZE) + +# Other variables required by the `setup.nsi.in` template. +set(CLIENT_TARNAME "bitcoin") +set(BITCOIN_WRAPPER_NAME "bitcoin") +set(BITCOIN_GUI_NAME "bitcoin-qt") +set(BITCOIN_DAEMON_NAME "bitcoind") +set(BITCOIN_CLI_NAME "bitcoin-cli") +set(BITCOIN_TX_NAME "bitcoin-tx") +set(BITCOIN_WALLET_TOOL_NAME "bitcoin-wallet") +set(BITCOIN_TEST_NAME "test_bitcoin") +configure_file(@PROJECT_SOURCE_DIR@/share/setup.nsi.in ${CMAKE_CURRENT_LIST_DIR}/bitcoin-win64-setup.nsi + USE_SOURCE_PERMISSIONS @ONLY +) + +execute_process( + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + COMMAND ${MAKENSIS_EXECUTABLE} -V2 bitcoin-win64-setup.nsi + COMMAND_ERROR_IS_FATAL ANY +) diff --git a/contrib/devtools/iwyu/bitcoin.core.imp b/contrib/devtools/iwyu/bitcoin.core.imp index 9b471cb8..ca7e2750 100644 --- a/contrib/devtools/iwyu/bitcoin.core.imp +++ b/contrib/devtools/iwyu/bitcoin.core.imp @@ -5,4 +5,8 @@ { "include": [ "", "private", "", "public" ] }, { "include": [ "", "private", "", "public" ] }, { "include": [ "", "private", "", "public" ] }, + + # Workaround for IWYU issue. + # See: https://github.com/include-what-you-use/include-what-you-use/issues/2084. + { "symbol": ["std::tuple", "private", "", "public"] }, ] diff --git a/contrib/devtools/shell-win64-cross.nix b/contrib/devtools/shell-win64-cross.nix new file mode 100644 index 00000000..4fd83b0d --- /dev/null +++ b/contrib/devtools/shell-win64-cross.nix @@ -0,0 +1,45 @@ +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +{ pkgs ? import (builtins.fetchTarball { + # Pin, to keep the versions of the toolchain aligned with the versions used by Guix. + url = "https://github.com/NixOS/nixpkgs/archive/531670d871c0e29724a02f3cbcac170adc65b58c.tar.gz"; + }) {} }: + +let + host = builtins.getEnv "HOST"; + crossPkgs = if host == "x86_64-w64-mingw32ucrt" + then pkgs.pkgsCross.ucrt64 + else if host == "x86_64-w64-mingw32" + then pkgs.pkgsCross.mingwW64 + else throw "Unsupported HOST: ${host}"; + toolchain = crossPkgs.stdenv.cc.targetPrefix; + pthreads = crossPkgs.windows.pthreads; +in + +pkgs.mkShellNoCC { + packages = [ + crossPkgs.gcc14 + pkgs.nsis + ]; + + shellHook = '' + export NIX_CFLAGS_COMPILE="-isystem ${pthreads}/include $NIX_CFLAGS_COMPILE" + export NIX_LDFLAGS="-L${pthreads}/lib $NIX_LDFLAGS" + export CC=$(command -v ${toolchain}gcc) + export CXX=$(command -v ${toolchain}g++) + export LD=$(command -v ${toolchain}ld) + export AR=$(command -v ${toolchain}ar) + export AS=$(command -v ${toolchain}as) + export RANLIB=$(command -v ${toolchain}ranlib) + export NM=$(command -v ${toolchain}nm) + export STRIP=$(command -v ${toolchain}strip) + export OBJCOPY=$(command -v ${toolchain}objcopy) + export OBJDUMP=$(command -v ${toolchain}objdump) + export READELF=$(command -v ${toolchain}readelf) + export SIZE=$(command -v ${toolchain}size) + export WINDRES=$(command -v ${toolchain}windres) + export RC=$(command -v ${toolchain}windres) + ''; +} diff --git a/contrib/guix/guix-attest b/contrib/guix/guix-attest index 3d70731c..06925ffb 100755 --- a/contrib/guix/guix-attest +++ b/contrib/guix/guix-attest @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build index 1ab9cc7e..9afe00a0 100755 --- a/contrib/guix/guix-build +++ b/contrib/guix/guix-build @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository @@ -337,8 +340,8 @@ INFO: Building ${VERSION:?not set} for platform triple ${HOST:?not set}: ADDITIONAL_GUIX_TIMEMACHINE_FLAGS: ${ADDITIONAL_GUIX_TIMEMACHINE_FLAGS} EOF - # Run the build script 'contrib/guix/libexec/build.sh' in the build - # container specified by 'contrib/guix/manifest.scm'. + # Run the build scripts 'contrib/guix/libexec/*.sh' in the build + # containers specified by 'contrib/guix/manifest*.scm'. # # Explanation of `guix shell` flags: # @@ -403,39 +406,73 @@ EOF # substitutes (pre-built packages) from servers that the user trusts. # Please read the README.md in the same directory as this file for # more information. - # - # shellcheck disable=SC2086 - time-machine shell --manifest="${PWD}/contrib/guix/manifest_build.scm" \ - --container \ - --writable-root \ - --pure \ - --no-cwd \ - --share="$PWD"=/bitcoin \ - --share="$DISTSRC_BASE"=/distsrc-base \ - --share="$OUTDIR_BASE"=/outdir-base \ - --expose="$(git rev-parse --git-common-dir)" \ - ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ - ${BASE_CACHE:+--share="$BASE_CACHE"} \ - ${SDK_PATH:+--share="$SDK_PATH"} \ - --cores="$JOBS" \ - --keep-failed \ - --fallback \ - --link-profile \ - --root="$(profiledir_for_host "${HOST}")" \ - ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} \ - ${ADDITIONAL_GUIX_COMMON_FLAGS} ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ - -- env HOST="$host" \ - DISTNAME="$DISTNAME" \ - JOBS="$JOBS" \ - SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ - ${V:+V=1} \ - ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ - ${BASE_CACHE:+BASE_CACHE="$BASE_CACHE"} \ - ${SDK_PATH:+SDK_PATH="$SDK_PATH"} \ - DISTSRC="$(distsrc_for_host "$HOST" "" /distsrc-base)" \ - OUTDIR="$(outdir_for_host "$HOST" "" /outdir-base)" \ - DIST_ARCHIVE_BASE=/outdir-base/dist-archive \ - bash -c "cd /bitcoin && bash contrib/guix/libexec/build.sh" + read -ra _guix_common_flags <<< "$ADDITIONAL_GUIX_COMMON_FLAGS" + read -ra _guix_env_flags <<< "$ADDITIONAL_GUIX_ENVIRONMENT_FLAGS" + + shell_opts=( + --manifest="${PWD}/contrib/guix/manifest_build.scm" + --container + --writable-root + --pure + --no-cwd + --share="$PWD=/bitcoin" + --share="$DISTSRC_BASE=/distsrc-base" + --share="$OUTDIR_BASE=/outdir-base" + --expose="$(git rev-parse --git-common-dir)" + ${SOURCES_PATH:+--share="$SOURCES_PATH"} + ${BASE_CACHE:+--share="$BASE_CACHE"} + ${SDK_PATH:+--share="$SDK_PATH"} + --cores="$JOBS" + --keep-failed + --fallback + --link-profile + ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} + "${_guix_common_flags[@]}" "${_guix_env_flags[@]}" + -- env HOST="$host" \ + DISTNAME="$DISTNAME" + JOBS="$JOBS" + SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" + ${V:+V=1} + ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} + ${BASE_CACHE:+BASE_CACHE="$BASE_CACHE"} + ${SDK_PATH:+SDK_PATH="$SDK_PATH"} + DISTSRC="$(distsrc_for_host "$HOST" "" /distsrc-base)" + OUTDIR="$(outdir_for_host "$HOST" "" /outdir-base)" + DIST_ARCHIVE_BASE=/outdir-base/dist-archive + ) + + case "$HOST" in + *linux*) + time-machine shell --root="$(profiledir_for_host "${HOST}")" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_linux.sh" + + time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \ + --root="$(profiledir_for_host "${HOST}"_gui)" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_linux_gui.sh" + ;; + *darwin*) + time-machine shell --root="$(profiledir_for_host "${HOST}")" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_macos.sh" + + time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \ + --root="$(profiledir_for_host "${HOST}"_gui)" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_macos_gui.sh" + ;; + *mingw*) + time-machine shell --root="$(profiledir_for_host "${HOST}")" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_win.sh" + + time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \ + --root="$(profiledir_for_host "${HOST}"_gui)" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_win_gui.sh" + ;; + esac ) done diff --git a/contrib/guix/guix-clean b/contrib/guix/guix-clean index 32258cd7..a72a2644 100755 --- a/contrib/guix/guix-clean +++ b/contrib/guix/guix-clean @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/contrib/guix/guix-codesign b/contrib/guix/guix-codesign index 8cc6993b..179041c1 100755 --- a/contrib/guix/guix-codesign +++ b/contrib/guix/guix-codesign @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/contrib/guix/guix-verify b/contrib/guix/guix-verify index 02ae0227..82e74003 100755 --- a/contrib/guix/guix-verify +++ b/contrib/guix/guix-verify @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh deleted file mode 100755 index 0ec058b8..00000000 --- a/contrib/guix/libexec/build.sh +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2019-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. -export LC_ALL=C -set -e -o pipefail - -# shellcheck source=setup.sh -source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" - -# Set environment variables to point the NATIVE toolchain to the right -# includes/libs -NATIVE_GCC="$(store_path gcc-toolchain)" - -# Set native toolchain -build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include" -build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include" - -case "$HOST" in - *darwin*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;; # Required for native packages - *mingw*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;; - *) - NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)" - export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib" - ;; -esac - -# Set environment variables to point the CROSS toolchain to the right -# includes/libs for $HOST -case "$HOST" in - *mingw*) - # Determine output paths to use in CROSS_* environment variables - CROSS_GLIBC="$(store_path "mingw-w64-x86_64-winpthreads")" - CROSS_GCC="$(store_path "gcc-cross-${HOST}")" - CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" - CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... - CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) - - # The search path ordering is generally: - # 1. gcc-related search paths - # 2. libc-related search paths - # 2. kernel-header-related search paths (not applicable to mingw-w64 hosts) - export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include" - export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" - export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" - ;; - *darwin*) - # The CROSS toolchain for darwin uses the SDK and ignores environment variables. - # See depends/hosts/darwin.mk for more details. - ;; - *linux*) - CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")" - CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)" - CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")" - CROSS_GCC="$(store_path "gcc-cross-${HOST}")" - CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" - CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... - CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) - - export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" - export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" - export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" - ;; - *) - exit 1 ;; -esac - -# Sanity check CROSS_*_PATH directories -IFS=':' read -ra PATHS <<< "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" -for p in "${PATHS[@]}"; do - if [ -n "$p" ] && [ ! -d "$p" ]; then - echo "'$p' doesn't exist or isn't a directory... Aborting..." - exit 1 - fi -done - -# Determine the correct value for -Wl,--dynamic-linker for the current $HOST -case "$HOST" in - *linux*) - glibc_dynamic_linker=$( - case "$HOST" in - x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; - arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; - aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; - riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; - powerpc64-linux-gnu) echo /lib64/ld64.so.1;; - powerpc64le-linux-gnu) echo /lib64/ld64.so.2;; - *) exit 1 ;; - esac - ) - ;; -esac - -#################### -# Depends Building # -#################### - -# Build the depends tree, overriding variables that assume multilib gcc -make -C depends --jobs="$JOBS" HOST="$HOST" \ - ${V:+V=1} \ - ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ - ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ - ${SDK_PATH+SDK_PATH="$SDK_PATH"} \ - ${build_CC+build_CC="$build_CC"} \ - ${build_CXX+build_CXX="$build_CXX"} \ - x86_64_linux_CC=x86_64-linux-gnu-gcc \ - x86_64_linux_CXX=x86_64-linux-gnu-g++ \ - x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \ - x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \ - x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \ - x86_64_linux_STRIP=x86_64-linux-gnu-strip - -case "$HOST" in - *darwin*) - # Unset now that Qt is built - unset LIBRARY_PATH - ;; -esac - -########################### -# Binary Tarball Building # -########################### - -# CONFIGFLAGS -CONFIGFLAGS="-DREDUCE_EXPORTS=ON -DBUILD_BENCH=OFF -DBUILD_GUI_TESTS=OFF -DBUILD_FUZZ_BINARY=OFF -DCMAKE_SKIP_RPATH=TRUE" - -# CFLAGS -HOST_CFLAGS="-O2 -g" -HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) -HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." -case "$HOST" in - *mingw*) HOST_CFLAGS+=" -fno-ident" ;; - *darwin*) unset HOST_CFLAGS ;; -esac - -# CXXFLAGS -HOST_CXXFLAGS="$HOST_CFLAGS" - -case "$HOST" in - arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;; -esac - -# LDFLAGS -case "$HOST" in - *linux*) HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -Wl,-O2" ;; - *mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;; -esac - -# EXE FLAGS -case "$HOST" in - *linux*) CMAKE_EXE_LINKER_FLAGS="-DCMAKE_EXE_LINKER_FLAGS=${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" ;; -esac - -mkdir -p "$DISTSRC" -( - cd "$DISTSRC" - - # Extract the source tarball - tar --strip-components=1 -xf "${GIT_ARCHIVE}" - - # Configure this DISTSRC for $HOST - # shellcheck disable=SC2086 - env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ - cmake -S . -B build \ - --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ - -DWITH_CCACHE=OFF \ - -Werror=dev \ - ${CONFIGFLAGS} \ - ${CMAKE_EXE_LINKER_FLAGS+"$CMAKE_EXE_LINKER_FLAGS"} - - # Build Bitcoin Core - cmake --build build -j "$JOBS" - - mkdir -p "$OUTDIR" - - # Make the os-specific installers - case "$HOST" in - *mingw*) - cmake --build build -j "$JOBS" -t deploy - mv build/bitcoin-win64-setup.exe "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" - ;; - esac - - # Setup the directory where our Bitcoin Core build for HOST will be - # installed. This directory will also later serve as the input for our - # binary tarballs. - mkdir -p "${INSTALLPATH}" - # Install built Bitcoin Core to $INSTALLPATH - case "$HOST" in - *darwin*) - cmake --install build --strip --prefix "${INSTALLPATH}" - ;; - *) - cmake --install build --prefix "${INSTALLPATH}" - ;; - esac - - # Perform basic security checks on installed executables. - echo "Checking binary security on installed executables..." - python3 "${DISTSRC}/contrib/guix/security-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* - # Check that executables only contain allowed version symbols. - echo "Running symbol and dynamic library checks on installed executables..." - python3 "${DISTSRC}/contrib/guix/symbol-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* -) # $DISTSRC - -# shellcheck source=package.sh -source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/contrib/guix/libexec/build_linux.sh b/contrib/guix/libexec/build_linux.sh new file mode 100755 index 00000000..bf3296a5 --- /dev/null +++ b/contrib/guix/libexec/build_linux.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup gcc toolchain +gcc_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + NO_QT=1 + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +case "$HOST" in + arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;; +esac + +# LDFLAGS +HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$(glibc_dynamic_linker "$HOST") -Wl,-O2" + +# Use LINK_WARNING_AS_ERROR when using CMake 4.x +case "$HOST" in + riscv64-linux-gnu) ;; # https://github.com/boostorg/test/issues/345 + *) HOST_LDFLAGS="${HOST_LDFLAGS} -Wl,--fatal-warnings" ;; +esac + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DCMAKE_EXE_LINKER_FLAGS="${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF + + # Build Bitcoin Core + cmake --build build -j "$JOBS" + + # Install built Bitcoin Core + cmake --install build +) + +rm -rf "$DISTSRC"/build + +exit 0 diff --git a/contrib/guix/libexec/build_linux_gui.sh b/contrib/guix/libexec/build_linux_gui.sh new file mode 100755 index 00000000..b9665c25 --- /dev/null +++ b/contrib/guix/libexec/build_linux_gui.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup gcc toolchain +gcc_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +case "$HOST" in + arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;; +esac + +# LDFLAGS +HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$(glibc_dynamic_linker "$HOST") -Wl,-O2" + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_BITCOIN_BIN=OFF \ + -DBUILD_CLI=OFF \ + -DBUILD_DAEMON=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TX=OFF \ + -DBUILD_UTIL=OFF \ + -DBUILD_WALLET_TOOL=OFF \ + -DCMAKE_EXE_LINKER_FLAGS="${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF \ + -Werror=dev + + # Build Bitcoin Core + cmake --build build -j "$JOBS" --target bitcoin-gui bitcoin-qt + + # Install built Bitcoin Core + cmake --install build --component bitcoin-gui + cmake --install build --component bitcoin-qt +) # $DISTSRC + +# shellcheck source=package.sh +source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/contrib/guix/libexec/build_macos.sh b/contrib/guix/libexec/build_macos.sh new file mode 100755 index 00000000..a782d80e --- /dev/null +++ b/contrib/guix/libexec/build_macos.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# Setup toolchain +llvm_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${SDK_PATH+SDK_PATH="$SDK_PATH"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + ${build_LDFLAGS+build_LDFLAGS="$build_LDFLAGS"} \ + ${build_AR+build_AR="$build_AR"} \ + ${build_RANLIB+build_RANLIB="$build_RANLIB"} \ + ${build_OBJDUMP+build_OBJDUMP="$build_OBJDUMP"} \ + ${build_NM+build_NM="$build_NM"} \ + ${build_STRIP+build_STRIP="$build_STRIP"} \ + NO_QT=1 + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF + + # Build Bitcoin Core + cmake --build build -j "$JOBS" + + # Install built Bitcoin Core + cmake --install build --strip +) + +rm -rf "$DISTSRC"/build + +exit 0 diff --git a/contrib/guix/libexec/build_macos_gui.sh b/contrib/guix/libexec/build_macos_gui.sh new file mode 100755 index 00000000..1f2dbc64 --- /dev/null +++ b/contrib/guix/libexec/build_macos_gui.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# Setup toolchain +llvm_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${SDK_PATH+SDK_PATH="$SDK_PATH"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + ${build_LDFLAGS+build_LDFLAGS="$build_LDFLAGS"} \ + ${build_AR+build_AR="$build_AR"} \ + ${build_RANLIB+build_RANLIB="$build_RANLIB"} \ + ${build_OBJDUMP+build_OBJDUMP="$build_OBJDUMP"} \ + ${build_NM+build_NM="$build_NM"} \ + ${build_STRIP+build_STRIP="$build_STRIP"} + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_BITCOIN_BIN=OFF \ + -DBUILD_CLI=OFF \ + -DBUILD_DAEMON=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TX=OFF \ + -DBUILD_UTIL=OFF \ + -DBUILD_WALLET_TOOL=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF \ + -Werror=dev + + # Build Bitcoin Core + cmake --build build -j "$JOBS" --target bitcoin-gui bitcoin-qt + + # Install built Bitcoin Core + cmake --install build --strip --component bitcoin-gui + cmake --install build --strip --component bitcoin-qt +) + +# shellcheck source=package.sh +source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/contrib/guix/libexec/build_win.sh b/contrib/guix/libexec/build_win.sh new file mode 100755 index 00000000..7dd6e9fc --- /dev/null +++ b/contrib/guix/libexec/build_win.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup mingw-w64 toolchain +mingw_w64_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + NO_QT=1 + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." +HOST_CFLAGS+=" -fno-ident" + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +# LDFLAGS +HOST_LDFLAGS="-Wl,--no-insert-timestamp -Wl,--fatal-warnings" + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF + + # Build Bitcoin Core + cmake --build build -j "$JOBS" + + # Install built Bitcoin Core + cmake --install build +) + +rm -rf "$DISTSRC"/build + +exit 0 diff --git a/contrib/guix/libexec/build_win_gui.sh b/contrib/guix/libexec/build_win_gui.sh new file mode 100755 index 00000000..65696a2f --- /dev/null +++ b/contrib/guix/libexec/build_win_gui.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup mingw-w64 toolchain +mingw_w64_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." +HOST_CFLAGS+=" -fno-ident" + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +# LDFLAGS +HOST_LDFLAGS="-Wl,--no-insert-timestamp -Wl,--fatal-warnings" + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_BITCOIN_BIN=OFF \ + -DBUILD_CLI=OFF \ + -DBUILD_DAEMON=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TX=OFF \ + -DBUILD_UTIL=OFF \ + -DBUILD_WALLET_TOOL=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF \ + -Werror=dev + + # Build Bitcoin Core + cmake --build build -j "$JOBS" --target bitcoin-qt + + # Install built Bitcoin Core + cmake --install build --component bitcoin-qt +) + +# shellcheck source=package.sh +source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/contrib/guix/libexec/codesign.sh b/contrib/guix/libexec/codesign.sh index 9b7f085d..21f4c110 100755 --- a/contrib/guix/libexec/codesign.sh +++ b/contrib/guix/libexec/codesign.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Copyright (c) 2021-present The Bitcoin Core developers +# Copyright (c) The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -export LC_ALL=C -set -e -o pipefail +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Environment variables for determinism export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" diff --git a/contrib/guix/libexec/package.sh b/contrib/guix/libexec/package.sh index 7228346a..05f5e61f 100755 --- a/contrib/guix/libexec/package.sh +++ b/contrib/guix/libexec/package.sh @@ -2,12 +2,19 @@ # Copyright (c) The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/license/mit. -export LC_ALL=C -set -e -o pipefail +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail ( cd "$DISTSRC" + # Perform basic security checks on installed executables. + echo "Checking binary security on installed executables..." + python3 "${DISTSRC}/contrib/guix/security-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* + # Check that executables only contain allowed version symbols. + echo "Running symbol and dynamic library checks on installed executables..." + python3 "${DISTSRC}/contrib/guix/symbol-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* + ( cd installed @@ -32,7 +39,7 @@ set -e -o pipefail esac # copy over the example bitcoin.conf file. if contrib/devtools/gen-bitcoin-conf.sh - # has not been run before buildling, this file will be a stub + # has not been run before building, this file will be a stub cp "${DISTSRC}/share/examples/bitcoin.conf" "${DISTNAME}/" cp -r "${DISTSRC}/share/rpcauth" "${DISTNAME}/share/" @@ -79,6 +86,10 @@ set -e -o pipefail # Finally make tarballs for codesigning case "$HOST" in *mingw*) + # Make the installer + cmake -D BIN_DIR="${INSTALLPATH}/bin" -D LIBEXEC_DIR="${INSTALLPATH}/libexec" -P build/GenerateWindowsInstaller.cmake + mv build/bitcoin-win64-setup.exe "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" + cp -rf --target-directory=. contrib/windeploy ( cd ./windeploy diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash index 23852767..2fe5c738 100644 --- a/contrib/guix/libexec/prelude.bash +++ b/contrib/guix/libexec/prelude.bash @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail source contrib/shell/realpath.bash source contrib/shell/git-utils.bash diff --git a/contrib/guix/libexec/setup.sh b/contrib/guix/libexec/setup.sh index 37388f98..2e3eb159 100755 --- a/contrib/guix/libexec/setup.sh +++ b/contrib/guix/libexec/setup.sh @@ -2,8 +2,8 @@ # Copyright (c) The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/license/mit. -export LC_ALL=C -set -e -o pipefail +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Environment variables for determinism export TAR_OPTIONS="--no-same-owner --owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" @@ -61,6 +61,109 @@ store_path() { --expression='s|"[[:space:]]*$||' } +# Sanity check CROSS_*_PATH directories +check_cross_paths() { + local p paths + IFS=':' read -ra paths <<< "$1" + for p in "${paths[@]}"; do + if [ -n "$p" ] && [ ! -d "$p" ]; then + echo "'$p' doesn't exist or isn't a directory... Aborting..." >&2 + return 1 + fi + done +} + +# Given a hostname, determine the correct value for -Wl,--dynamic-linker. +glibc_dynamic_linker() { + case "$1" in + x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; + arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; + aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; + riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; + powerpc64-linux-gnu) echo /lib64/ld64.so.1 ;; + powerpc64le-linux-gnu) echo /lib64/ld64.so.2 ;; + *) exit 1 ;; + esac +} + +gcc_toolchain() { + # Set environment variables to point the NATIVE toolchain to the right + # includes/libs + local NATIVE_GCC NATIVE_GCC_STATIC CROSS_GLIBC CROSS_GLIBC_STATIC CROSS_KERNEL CROSS_GCC CROSS_GCC_LIB_STORE CROSS_GCC_LIBS CROSS_GCC_LIB + + NATIVE_GCC="$(store_path gcc-toolchain)" + + # Set native toolchain + export build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include" + export build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include" + + NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)" + export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib" + + # Set environment variables to point the CROSS toolchain to the right + # includes/libs for $HOST + CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")" + CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)" + CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" + CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" + + check_cross_paths "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" +} + +llvm_toolchain() { + local CLANG_TOOLCHAIN LIB_CXX + + CLANG_TOOLCHAIN="$(store_path clang-toolchain)" + LIB_CXX="$(store_path libcxx)" + + export build_CC="${CLANG_TOOLCHAIN}/bin/clang -isystem ${CLANG_TOOLCHAIN}/include" + export build_CXX="${CLANG_TOOLCHAIN}/bin/clang++ -stdlib=libc++ -isystem ${LIB_CXX}/include/c++/v1 -isystem ${CLANG_TOOLCHAIN}/include" + export build_LDFLAGS="-fuse-ld=lld -rtlib=compiler-rt -unwindlib=libunwind -L${LIB_CXX}/lib -Wl,-rpath,${LIB_CXX}/lib" + export build_AR="${CLANG_TOOLCHAIN}/bin/llvm-ar" + export build_RANLIB="${CLANG_TOOLCHAIN}/bin/llvm-ranlib" + export build_OBJDUMP="${CLANG_TOOLCHAIN}/bin/llvm-objdump" + export build_NM="${CLANG_TOOLCHAIN}/bin/llvm-nm" + export build_STRIP="${CLANG_TOOLCHAIN}/bin/llvm-strip" +} + +mingw_w64_toolchain() { + # Set environment variables to point the NATIVE toolchain to the right + # includes/libs + local NATIVE_GCC CROSS_GLIBC CROSS_GCC CROSS_GCC_LIB_STORE CROSS_GCC_LIBS CROSS_GCC_LIB + + NATIVE_GCC="$(store_path gcc-toolchain)" + + # Set native toolchain + export build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include" + export build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include" + + # Set environment variables to point the CROSS toolchain to the right + # includes/libs for $HOST + # Determine output paths to use in CROSS_* environment variables + CROSS_GLIBC="$(store_path "mingw-w64-x86_64-winpthreads")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" + CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + # The search path ordering is generally: + # 1. gcc-related search paths + # 2. libc-related search paths + # 2. kernel-header-related search paths (not applicable to mingw-w64 hosts) + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" + + check_cross_paths "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" +} + # Disable Guix ld auto-rpath behavior export GUIX_LD_WRAPPER_DISABLE_RPATH=yes diff --git a/contrib/guix/manifest_build.scm b/contrib/guix/manifest_build.scm index 576021e6..8e8df90a 100644 --- a/contrib/guix/manifest_build.scm +++ b/contrib/guix/manifest_build.scm @@ -1,26 +1,18 @@ (use-modules (gnu packages) ((gnu packages bash) #:select (bash-minimal)) - (gnu packages bison) ((gnu packages cmake) #:select (cmake-minimal)) (gnu packages commencement) - ((gnu packages compression) #:select (gzip xz zip)) + ((gnu packages compression) #:select (gzip)) (gnu packages cross-base) - (gnu packages gawk) (gnu packages gcc) - ((gnu packages installers) #:select (nsis-x86_64)) ((gnu packages linux) #:select (linux-libre-headers-6.1)) (gnu packages llvm) (gnu packages mingw) - (gnu packages ninja) - (gnu packages pkg-config) - ((gnu packages python) #:select (python-minimal)) - ((gnu packages python-xyz) #:select (python-lief)) ((gnu packages version-control) #:select (git-minimal)) (guix build-system trivial) (guix download) (guix gexp) (guix git-download) - ((guix licenses) #:prefix license:) (guix packages) ((guix utils) #:select (substitute-keyword-arguments))) @@ -171,14 +163,18 @@ chain for " target " development.")) (arguments (substitute-keyword-arguments (package-arguments base-gcc) ((#:configure-flags flags) - `(append ,flags + #~(append #$flags ;; https://gcc.gnu.org/install/configure.html - (list "--enable-threads=posix", - "--enable-default-ssp=yes", - "--enable-host-bind-now=yes", - "--disable-gcov", - "--disable-libgomp", - building-on))))))) + (list "--enable-default-ssp=yes" + "--enable-gprofng=no" + "--enable-host-bind-now=yes" + "--enable-threads=posix" + "--disable-gcov" + "--disable-libgomp" + "--disable-libsanitizer" + "--disable-lto" + "--disable-nls" + #$building-on))))))) (define-public linux-base-gcc (package @@ -186,22 +182,25 @@ chain for " target " development.")) (arguments (substitute-keyword-arguments (package-arguments base-gcc) ((#:configure-flags flags) - `(append ,flags + #~(append #$flags ;; https://gcc.gnu.org/install/configure.html - (list "--enable-initfini-array=yes", - "--enable-default-ssp=yes", - "--enable-default-pie=yes", - "--enable-host-bind-now=yes", - "--enable-standard-branch-protection=yes", - "--enable-cet=yes", - "--enable-gprofng=no", - "--disable-gcov", - "--disable-libgomp", - "--disable-libquadmath", - "--disable-libsanitizer", - building-on))) + (list "--enable-cet=yes" + "--enable-default-ssp=yes" + "--enable-default-pie=yes" + "--enable-gprofng=no" + "--enable-host-bind-now=yes" + "--enable-initfini-array=yes" + "--enable-standard-branch-protection=yes" + "--disable-gcov" + "--disable-libgomp" + "--disable-libquadmath" + "--disable-libsanitizer" + "--disable-lto" + "--disable-nls" + "--disable-tm-clone-registry" + #$building-on))) ((#:phases phases) - `(modify-phases ,phases + #~(modify-phases #$phases ;; Given a XGCC package, return a modified package that replace each instance of ;; -rpath in the default system spec that's inserted by Guix with -rpath-link (add-after 'pre-configure 'replace-rpath-with-rpath-link @@ -215,7 +214,7 @@ chain for " target " development.")) (define-public glibc-2.31 (let ((commit "28eb5caf895ced5d895cb02757e109004a2d33e5")) (package - (inherit glibc) ;; 2.39 + (inherit glibc) ;; 2.41 (version "2.31") (source (origin (method git-fetch) @@ -233,12 +232,13 @@ chain for " target " development.")) ((#:configure-flags flags) `(append ,flags ;; https://www.gnu.org/software/libc/manual/html_node/Configuring-and-compiling.html - (list "--enable-stack-protector=all", + (list "--enable-bind-now", "--enable-cet", - "--enable-bind-now", - "--disable-werror", - "--disable-timezone-tools", + "--enable-kernel=3.17.0", + "--enable-stack-protector=all", "--disable-profile", + "--disable-timezone-tools", + "--disable-werror", building-on))) ((#:phases phases) `(modify-phases ,phases @@ -262,40 +262,28 @@ chain for " target " development.")) coreutils-minimal ;; File(system) inspection grep - diffutils findutils ;; File transformation patch - gawk sed ;; Compression and archiving tar gzip - xz ;; Build tools - gcc-toolchain-14 cmake-minimal gnu-make - ninja - ;; Scripting - python-minimal ;; (3.11) ;; Git - git-minimal - ;; Tests - python-lief) + git-minimal) (let ((target (getenv "HOST"))) (cond ((string-suffix? "-mingw32" target) - (list (make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32") - nsis-x86_64 - zip)) + (list gcc-toolchain-14 + (make-mingw-pthreads-cross-toolchain target))) ((string-contains target "-linux-") - (list bison - pkg-config + (list gcc-toolchain-14 (list gcc-toolchain-14 "static") (make-bitcoin-cross-toolchain target))) ((string-contains target "darwin") (list clang-toolchain-19 - lld-19 - (make-lld-wrapper lld-19 #:lld-as-ld? #t) - zip)) + libcxx ;; 19.1.7 + lld-19)) (else '()))))) diff --git a/contrib/guix/manifest_gui.scm b/contrib/guix/manifest_gui.scm new file mode 100644 index 00000000..1754af90 --- /dev/null +++ b/contrib/guix/manifest_gui.scm @@ -0,0 +1,30 @@ +(use-modules (gnu packages bison) + ((gnu packages compression) #:select (xz zip)) + (gnu packages gawk) + ((gnu packages installers) #:select (nsis-x86_64)) + (gnu packages ninja) + (gnu packages pkg-config) + ((gnu packages python) #:select (python-minimal)) + ((gnu packages python-xyz) #:select (python-lief))) + +(packages->manifest + (append + (list ;; Compression and archiving + xz + ;; Build tools + ninja + ;; Packaging scripts + python-minimal ;; (3.11) + ;; Tests + python-lief) + (let ((target (getenv "HOST"))) + (cond ((string-suffix? "-mingw32" target) + (list zip + nsis-x86_64)) + ((string-contains target "-linux-") + (list bison + gawk + pkg-config)) + ((string-contains target "darwin") + (list zip)) + (else '()))))) diff --git a/contrib/guix/security-check.py b/contrib/guix/security-check.py index 2a6e26b6..87aafcb9 100755 --- a/contrib/guix/security-check.py +++ b/contrib/guix/security-check.py @@ -280,8 +280,8 @@ def check_MACHO_BRANCH_PROTECTION(binary) -> bool: for filename in sys.argv[1:]: binary = lief.parse(filename) - etype = binary.format - arch = binary.abstract.header.architecture + etype = binary.format # type: ignore[union-attr] + arch = binary.abstract.header.architecture # type: ignore[union-attr] failed: list[str] = [] for (name, func) in CHECKS[etype][arch]: diff --git a/contrib/guix/symbol-check.py b/contrib/guix/symbol-check.py index 86b79652..b1f326d3 100755 --- a/contrib/guix/symbol-check.py +++ b/contrib/guix/symbol-check.py @@ -72,17 +72,17 @@ ELF_ABIS: dict[lief.ELF.ARCH, dict[lief.Header.ENDIANNESS, list[int]]] = { lief.ELF.ARCH.X86_64: { - lief.Header.ENDIANNESS.LITTLE: [3,2,0], + lief.Header.ENDIANNESS.LITTLE: [3,17,0], }, lief.ELF.ARCH.ARM: { - lief.Header.ENDIANNESS.LITTLE: [3,2,0], + lief.Header.ENDIANNESS.LITTLE: [3,17,0], }, lief.ELF.ARCH.AARCH64: { - lief.Header.ENDIANNESS.LITTLE: [3,7,0], + lief.Header.ENDIANNESS.LITTLE: [3,17,0], }, lief.ELF.ARCH.PPC64: { - lief.Header.ENDIANNESS.LITTLE: [3,10,0], - lief.Header.ENDIANNESS.BIG: [3,2,0], + lief.Header.ENDIANNESS.LITTLE: [3,17,0], + lief.Header.ENDIANNESS.BIG: [3,17,0], }, lief.ELF.ARCH.RISCV: { lief.Header.ENDIANNESS.LITTLE: [4,15,0], @@ -306,7 +306,7 @@ def check_ELF_ABI(binary) -> bool: for filename in sys.argv[1:]: binary = lief.parse(filename) - etype = binary.format + etype = binary.format # type: ignore[union-attr] failed: list[str] = [] for (name, func) in CHECKS[etype]: diff --git a/contrib/init/bitcoind.openrc b/contrib/init/bitcoind.openrc index 30e7be36..ae9dbf46 100644 --- a/contrib/init/bitcoind.openrc +++ b/contrib/init/bitcoind.openrc @@ -21,7 +21,7 @@ BITCOIND_OPTS="${BITCOIND_OPTS:-${BITCOIN_OPTS}}" name="Bitcoin Core Daemon" description="Bitcoin cryptocurrency P2P network daemon" -command="/usr/bin/bitcoind" +command="${BITCOIND_BIN}" command_args="-pid=\"${BITCOIND_PIDFILE}\" \ -conf=\"${BITCOIND_CONFIGFILE}\" \ -datadir=\"${BITCOIND_DATADIR}\" \ @@ -30,6 +30,7 @@ command_args="-pid=\"${BITCOIND_PIDFILE}\" \ required_files="${BITCOIND_CONFIGFILE}" start_stop_daemon_args="-u ${BITCOIND_USER} \ + -g ${BITCOIND_GROUP} \ -N ${BITCOIND_NICE} -w 2000" pidfile="${BITCOIND_PIDFILE}" diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index 2dfad0c7..ff2b4028 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -22,9 +22,9 @@ The output will be several data structures with the peers in binary format: - static const uint8_t chainparams_seed_{main,signet,test,testnet4}[]={ - ... - } + inline constexpr uint8_t chainparams_seed_{main,signet,test,testnet4}[]{ + ... + }; These should be pasted into `src/chainparamsseeds.h`. ''' @@ -137,7 +137,7 @@ def bip155_serialize(spec): return r def process_nodes(g, f, structname): - g.write('static const uint8_t %s[] = {\n' % structname) + g.write("inline constexpr uint8_t %s[]{\n" % structname) for line in f: comment = line.find('#') if comment != -1: diff --git a/contrib/verify-commits/verify-commits.py b/contrib/verify-commits/verify-commits.py index b053fbd1..12c01019 100755 --- a/contrib/verify-commits/verify-commits.py +++ b/contrib/verify-commits/verify-commits.py @@ -14,6 +14,23 @@ GIT = os.getenv('GIT', 'git') +def is_ancestor(older, newer, root_name): + """Return whether older is an ancestor of newer, rejecting Git errors.""" + result = subprocess.run([GIT, "merge-base", "--is-ancestor", older, newer]) + if result.returncode not in (0, 1): + print(f'Failed to determine ancestry between "{older}" and "{newer}" for the {root_name} (git merge-base exited with {result.returncode}).', file=sys.stderr) + sys.exit(1) + return result.returncode == 0 + +def predates(commit, root, root_name): + """Return whether commit is provably older than root, rejecting divergent history.""" + if is_ancestor(root, commit, root_name): + return False + elif is_ancestor(commit, root, root_name): + return True + print(f'"{commit}" diverges from the {root_name} "{root}", refusing to verify.', file=sys.stderr) + sys.exit(1) + def tree_sha512sum(commit='HEAD'): """Calculate the Tree-sha512 for the commit. @@ -107,27 +124,23 @@ def main(): logging.debug("verify-commits: [in-progress] processing commit {}".format(current_commit[:8])) if current_commit == verified_root: + # Ensure the trusted root identifies an existing commit. + is_ancestor(verified_root, current_commit, "trusted Git root") print('There is a valid path from "{}" to {} where all commits are signed!'.format(initial_commit, verified_root)) sys.exit(0) - else: - # Make sure this commit isn't older than trusted roots - check_root_older_res = subprocess.run([GIT, "merge-base", "--is-ancestor", verified_root, current_commit]) - if check_root_older_res.returncode != 0: - print(f"\"{current_commit}\" predates the trusted root, stopping!") - sys.exit(0) + elif predates(current_commit, verified_root, "trusted Git root"): + print(f"\"{current_commit}\" predates the trusted root, stopping!") + sys.exit(0) if verify_tree: if current_commit == verified_sha512_root: print("All Tree-SHA512s matched up to {}".format(verified_sha512_root), file=sys.stderr) verify_tree = False no_sha1 = False - else: - # Skip the tree check if we are older than the trusted root - check_root_older_res = subprocess.run([GIT, "merge-base", "--is-ancestor", verified_sha512_root, current_commit]) - if check_root_older_res.returncode != 0: - print(f"\"{current_commit}\" predates the trusted SHA512 root, disabling tree verification.") - verify_tree = False - no_sha1 = False + elif predates(current_commit, verified_sha512_root, "trusted Tree-SHA512 root"): + print(f"\"{current_commit}\" predates the trusted SHA512 root, disabling tree verification.") + verify_tree = False + no_sha1 = False os.environ['BITCOIN_VERIFY_COMMITS_ALLOW_SHA1'] = "0" if no_sha1 else "1" diff --git a/depends/README.md b/depends/README.md index 83ebf8e2..9018fc12 100644 --- a/depends/README.md +++ b/depends/README.md @@ -125,7 +125,7 @@ without gcc/g++), you could use the following to build all packages using clang: ## Cross compilation -To build for another arch/OS: +To build for another arch+OS: make HOST=host-platform-triplet @@ -135,18 +135,18 @@ For example: Common `host-platform-triplet`s for cross compilation are: -- `i686-pc-linux-gnu` for Linux x86 32 bit -- `x86_64-pc-linux-gnu` for Linux x86 64 bit +- `i686-linux-gnu` for Linux x86 32-bit +- `x86_64-linux-gnu` for Linux x86 64-bit - `x86_64-w64-mingw32` for Windows using MSVCRT - `x86_64-w64-mingw32ucrt` for Windows using UCRT - `x86_64-apple-darwin` for Intel macOS - `arm64-apple-darwin` for ARM macOS -- `arm-linux-gnueabihf` for Linux ARM 32 bit -- `aarch64-linux-gnu` for Linux ARM 64 bit -- `powerpc64-linux-gnu` for Linux POWER 64 bit (big endian) -- `powerpc64le-linux-gnu` for Linux POWER 64 bit (little endian) -- `riscv32-linux-gnu` for Linux RISC-V 32 bit -- `riscv64-linux-gnu` for Linux RISC-V 64 bit +- `arm-linux-gnueabihf` for Linux ARM 32-bit +- `aarch64-linux-gnu` for Linux ARM 64-bit +- `powerpc64-linux-gnu` for Linux POWER 64-bit (big endian) +- `powerpc64le-linux-gnu` for Linux POWER 64-bit (little endian) +- `riscv32-linux-gnu` for Linux RISC-V 32-bit +- `riscv64-linux-gnu` for Linux RISC-V 64-bit - `s390x-linux-gnu` for Linux S390X The paths are automatically configured and no other options are needed. @@ -160,37 +160,52 @@ proceeding with a cross-compile. Under the depends directory, create a subdirectory named `SDKs`. Then, place the extracted SDK under this new directory. For more information, see [SDK Extraction](../contrib/macdeploy/README.md#sdk-extraction). -#### For Windows cross compilation using MSVCRT +#### For Windows cross compilation + +Using MSVCRT: apt install g++-mingw-w64-x86-64-posix -#### For Windows cross compilation using UCRT +Using UCRT: apt install g++-mingw-w64-ucrt64 -#### For linux (including i386, ARM) cross compilation +Some Ubuntu or Debian versions may not offer a working package. In this case, +you may install `nix-bin` and use the Nix shell from the repository root: + + apt install nix-bin + NIX_BUILD_SHELL=bash HOST=x86_64-w64-mingw32 nix-shell contrib/devtools/shell-win64-cross.nix # MSVCRT + NIX_BUILD_SHELL=bash HOST=x86_64-w64-mingw32ucrt nix-shell contrib/devtools/shell-win64-cross.nix # UCRT + +#### For Linux cross compilation + +Please note that package availability might depend on the arch+OS you are building on. + +For Linux x86 32-bit cross compilation: + + sudo apt-get install g++-i686-linux-gnu binutils-i686-linux-gnu -Common linux dependencies: +For Linux x86 64-bit cross compilation: - sudo apt-get install g++-multilib binutils + sudo apt-get install g++-x86-64-linux-gnu binutils-x86-64-linux-gnu -For linux ARM cross compilation: +For Linux ARM 32-bit cross compilation: sudo apt-get install g++-arm-linux-gnueabihf binutils-arm-linux-gnueabihf -For linux AARCH64 cross compilation: +For Linux ARM 64-bit cross compilation: sudo apt-get install g++-aarch64-linux-gnu binutils-aarch64-linux-gnu -For linux POWER 64-bit cross compilation (there are no packages for 32-bit): +For Linux POWER 64-bit cross compilation (there are no packages for 32-bit): sudo apt-get install g++-powerpc64-linux-gnu binutils-powerpc64-linux-gnu g++-powerpc64le-linux-gnu binutils-powerpc64le-linux-gnu -For linux RISC-V 64-bit cross compilation (there are no packages for 32-bit): +For Linux RISC-V 64-bit cross compilation (there are no packages for 32-bit): sudo apt-get install g++-riscv64-linux-gnu binutils-riscv64-linux-gnu -For linux S390X cross compilation: +For Linux S390X cross compilation: sudo apt-get install g++-s390x-linux-gnu binutils-s390x-linux-gnu diff --git a/depends/funcs.mk b/depends/funcs.mk index f6221ef1..11b6337d 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -47,7 +47,11 @@ endef define fetch_local_dir_sha256 if ! [ -f $($(1)_source) ] || [ -n "$$(find $($(1)_local_dir) -newer $($(1)_source) | head -n1)" ]; then \ mkdir -p $(dir $($(1)_source)) && \ - $(build_TAR) -c -f $($(1)_source) -C $($(1)_local_dir) . && \ + ( \ + cd $($(1)_local_dir) && \ + find . -print0 | TZ=UTC xargs -0r $(build_TOUCH) && \ + find . | LC_ALL=C sort | $(build_TAR) --no-recursion -c -f $($(1)_source) -T - \ + ) && \ rm -f $($(1)_fetched); \ fi && \ if ! [ -f $($(1)_fetched) ] || [ -n "$$(find $($(1)_source) -newer $($(1)_fetched))" ]; then \ @@ -60,7 +64,7 @@ endef define int_get_build_recipe_hash $(eval $(1)_patches_path?=$(PATCHES_PATH)/$(1)) -$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $($(1)_patches_path)/,$($(1)_patches)) | cut -d" " -f1)) +$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $$(grep "^include " packages/$(1).mk | cut -d' ' -f2 | xargs) $(addprefix $($(1)_patches_path)/,$($(1)_patches)) | cut -d" " -f1)) # If $(1)_local_dir is set, create a tarball of the local directory contents to # use as the source of the package, and include a hash of the tarball in the # package id, so if directory contents change, the package and packages diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk index 41958f99..be899507 100644 --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -19,27 +19,6 @@ linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC # https://libcxx.llvm.org/Hardening.html linux_debug_CPPFLAGS+=-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG -ifeq (86,$(findstring 86,$(build_arch))) -i686_linux_CC=gcc -m32 -i686_linux_CXX=g++ -m32 -i686_linux_AR=ar -i686_linux_RANLIB=ranlib -i686_linux_NM=nm -i686_linux_STRIP=strip - -x86_64_linux_CC=gcc -m64 -x86_64_linux_CXX=g++ -m64 -x86_64_linux_AR=ar -x86_64_linux_RANLIB=ranlib -x86_64_linux_NM=nm -x86_64_linux_STRIP=strip -else -i686_linux_CC=$(default_host_CC) -m32 -i686_linux_CXX=$(default_host_CXX) -m32 -x86_64_linux_CC=$(default_host_CC) -m64 -x86_64_linux_CXX=$(default_host_CXX) -m64 -endif - linux_cmake_system_name=Linux # Refer to doc/dependencies.md for the minimum required kernel. linux_cmake_system_version=3.17.0 diff --git a/depends/packages/native_qt.mk b/depends/packages/native_qt.mk index 2bf088c1..913d0fc4 100644 --- a/depends/packages/native_qt.mk +++ b/depends/packages/native_qt.mk @@ -10,6 +10,7 @@ $(package)_patches += qtbase_skip_tools.patch $(package)_patches += rcc_hardcode_timestamp.patch $(package)_patches += qttools_skip_dependencies.patch $(package)_patches += fix-macos26-qyield.patch +$(package)_patches += fix_missed_headers.patch $(package)_qttranslations_file_name=$(qt_details_qttranslations_file_name) $(package)_qttranslations_sha256_hash=$(qt_details_qttranslations_sha256_hash) @@ -94,6 +95,7 @@ $(package)_config_env += OBJCXX="$$(build_CXX)" endif $(package)_cmake_opts := -DCMAKE_EXE_LINKER_FLAGS="$$(build_LDFLAGS)" +$(package)_cmake_opts += -DCMAKE_AR="$$(build_AR)" ifneq ($(V),) $(package)_cmake_opts += --log-level=STATUS endif @@ -139,7 +141,8 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/qtbase_skip_tools.patch && \ patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch && \ patch -p1 -i $($(package)_patch_dir)/qttools_skip_dependencies.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix-macos26-qyield.patch + patch -p1 -i $($(package)_patch_dir)/fix-macos26-qyield.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_missed_headers.patch endef define $(package)_config_cmds diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 500a2729..cd4c3cc7 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -14,7 +14,6 @@ $(package)_patches_path := $(qt_details_patches_path) $(package)_patches := cocoa_compat.patch $(package)_patches += dont_hardcode_pwd.patch $(package)_patches += qtbase_avoid_qmain.patch -$(package)_patches += qtbase_platformsupport.patch $(package)_patches += qtbase_plugins_cocoa.patch $(package)_patches += qtbase_skip_tools.patch $(package)_patches += rcc_hardcode_timestamp.patch @@ -29,6 +28,7 @@ $(package)_patches += fix-macos26-qyield.patch $(package)_patches += fix-qbytearray-include.patch $(package)_patches += fix_openbsd_network_kernel.patch $(package)_patches += fix_openbsd_plugin_qelfparser.patch +$(package)_patches += fix_missed_headers.patch $(package)_qttranslations_file_name=$(qt_details_qttranslations_file_name) $(package)_qttranslations_sha256_hash=$(qt_details_qttranslations_sha256_hash) @@ -181,7 +181,11 @@ $(package)_cmake_opts += --log-level=STATUS endif $(package)_cmake_opts += -DQT_USE_DEFAULT_CMAKE_OPTIMIZATION_FLAGS=ON -$(package)_cmake_opts += -DCMAKE_C_FLAGS="$$($(package)_cppflags) $$($$($(package)_type)_CFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" +# The bundled libpng 1.6.49 in Qt 6.8.4 introduced support for +# the RISC-V Vector Extension (RVV). However, the resulting library +# fails to link when cross-compiling for riscv64-linux-gnu. +# Disable this feature for now. +$(package)_cmake_opts += -DCMAKE_C_FLAGS="$$($(package)_cppflags) -DPNG_RISCV_RVV_OPT=0 $$($$($(package)_type)_CFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" $(package)_cmake_opts += -DCMAKE_C_FLAGS_RELEASE="$$($$($(package)_type)_release_CFLAGS)" $(package)_cmake_opts += -DCMAKE_C_FLAGS_DEBUG="$$($$($(package)_type)_debug_CFLAGS)" $(package)_cmake_opts += -DCMAKE_CXX_FLAGS="$$($(package)_cppflags) $$($$($(package)_type)_CXXFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" @@ -198,6 +202,7 @@ endif $(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS="$$($$($(package)_type)_LDFLAGS)" $(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS_RELEASE="$$($$($(package)_type)_release_LDFLAGS)" $(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS_DEBUG="$$($$($(package)_type)_debug_LDFLAGS)" +$(package)_cmake_opts += -DCMAKE_AR="$$($(package)_ar)" ifneq ($(host),$(build)) $(package)_cmake_opts += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system_name) @@ -277,7 +282,6 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/cocoa_compat.patch && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase_avoid_qmain.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase_platformsupport.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase_plugins_cocoa.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase_skip_tools.patch && \ patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch && \ @@ -290,7 +294,8 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix-macos26-qyield.patch && \ patch -p1 -i $($(package)_patch_dir)/fix-qbytearray-include.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_openbsd_network_kernel.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_openbsd_plugin_qelfparser.patch + patch -p1 -i $($(package)_patch_dir)/fix_openbsd_plugin_qelfparser.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_missed_headers.patch endef ifeq ($(host),$(build)) $(package)_preprocess_cmds += && patch -p1 -i $($(package)_patch_dir)/qttools_skip_dependencies.patch diff --git a/depends/packages/qt_details.mk b/depends/packages/qt_details.mk index e49ac6a2..1808f342 100644 --- a/depends/packages/qt_details.mk +++ b/depends/packages/qt_details.mk @@ -1,19 +1,19 @@ -qt_details_version := 6.8.3 +qt_details_version := 6.8.4 qt_details_download_path := https://download.qt.io/archive/qt/6.8/$(qt_details_version)/submodules -qt_details_suffix := everywhere-src-$(qt_details_version).tar.xz +qt_details_suffix := everywhere-opensource-src-$(qt_details_version).tar.xz qt_details_qtbase_file_name := qtbase-$(qt_details_suffix) -qt_details_qtbase_sha256_hash := 56001b905601bb9023d399f3ba780d7fa940f3e4861e496a7c490331f49e0b80 +qt_details_qtbase_sha256_hash := 532dfbf3fa3cbc68fa37441ea9e81c5009da044eaecda78ffaeafd8bd125532f qt_details_qttranslations_file_name := qttranslations-$(qt_details_suffix) -qt_details_qttranslations_sha256_hash := c3c61d79c3d8fe316a20b3617c64673ce5b5519b2e45535f49bee313152fa531 +qt_details_qttranslations_sha256_hash := 33b1fd1d75598cbf54da12263957f18292c9fb01e42fcc3ab9bd2f8ac79763b7 qt_details_qttools_file_name := qttools-$(qt_details_suffix) -qt_details_qttools_sha256_hash := 02a4e219248b94f1333df843d25763f35251c1074cdc4fb5bda67d340f8c8b3a +qt_details_qttools_sha256_hash := c6030ea66d7be1ca7e3b40578beb35b0f4ff4014277d8e051d3219759f6ab399 qt_details_patches_path := $(PATCHES_PATH)/qt -qt_details_top_download_path := https://raw.githubusercontent.com/qt/qt5/refs/heads/$(qt_details_version) +qt_details_top_download_path := https://raw.githubusercontent.com/qt/qt5/refs/tags/v$(qt_details_version)-lts-lgpl qt_details_top_cmakelists_file_name := CMakeLists.txt qt_details_top_cmakelists_download_file := $(qt_details_top_cmakelists_file_name) qt_details_top_cmakelists_sha256_hash := 54e9a4e554da37792446dda4f52bc308407b01a34bcc3afbad58e4e0f71fac9b diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 8bf84b1f..ab10e6c2 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -11,6 +11,7 @@ $(package)_patches += openbsd_kqueue_headers.patch $(package)_patches += cmake_minimum.patch $(package)_patches += cacheline_undefined.patch $(package)_patches += no_librt.patch +$(package)_patches += add_new_include.patch define $(package)_set_vars $(package)_config_opts := -DCMAKE_BUILD_TYPE=None -DWITH_DOCS=OFF -DWITH_LIBSODIUM=OFF @@ -28,7 +29,8 @@ define $(package)_preprocess_cmds patch -p1 < $($(package)_patch_dir)/fix_have_windows.patch && \ patch -p1 < $($(package)_patch_dir)/openbsd_kqueue_headers.patch && \ patch -p1 < $($(package)_patch_dir)/cmake_minimum.patch && \ - patch -p1 < $($(package)_patch_dir)/no_librt.patch + patch -p1 < $($(package)_patch_dir)/no_librt.patch && \ + patch -p1 < $($(package)_patch_dir)/add_new_include.patch endef define $(package)_config_cmds diff --git a/depends/patches/qt/fix-gcc16-qcompare.patch b/depends/patches/qt/fix-gcc16-qcompare.patch index e56f610a..c2c1100a 100644 --- a/depends/patches/qt/fix-gcc16-qcompare.patch +++ b/depends/patches/qt/fix-gcc16-qcompare.patch @@ -105,7 +105,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 namespace Qt { class weak_ordering; -@@ -157,12 +183,18 @@ public: +@@ -156,12 +182,18 @@ public: constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept { static_assert(sizeof(*this) == sizeof(std::partial_ordering)); @@ -127,7 +127,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 switch (m_order) { case qToUnderlying(O::Less): return R::less; case qToUnderlying(O::Greater): return R::greater; -@@ -170,7 +202,6 @@ public: +@@ -169,7 +201,6 @@ public: case qToUnderlying(U::Unordered): return R::unordered; } Q_UNREACHABLE_RETURN(R::unordered); @@ -135,7 +135,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 } friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept -@@ -349,18 +380,18 @@ public: +@@ -347,18 +378,18 @@ public: constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept { static_assert(sizeof(*this) == sizeof(std::weak_ordering)); @@ -158,7 +158,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 } friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept -@@ -547,18 +578,18 @@ public: +@@ -542,18 +573,18 @@ public: constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept { static_assert(sizeof(*this) == sizeof(std::strong_ordering)); @@ -181,7 +181,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 } friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept -@@ -625,6 +656,8 @@ inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::G +@@ -620,6 +651,8 @@ inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::G } // namespace Qt diff --git a/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch b/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch index 11c27949..42f13ebb 100644 --- a/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch +++ b/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch @@ -19,7 +19,7 @@ diff --git a/qtbase/src/corelib/text/qanystringview.cpp b/qtbase/src/corelib/tex index 7bf8a3fa1fd..3c993ff1da0 100644 --- a/qtbase/src/corelib/text/qanystringview.cpp +++ b/qtbase/src/corelib/text/qanystringview.cpp -@@ -243,6 +243,10 @@ QT_BEGIN_NAMESPACE +@@ -355,6 +355,10 @@ QT_BEGIN_NAMESPACE \sa isNull(), isEmpty() */ diff --git a/depends/patches/qt/fix-gcc16-sfinae-qchar.patch b/depends/patches/qt/fix-gcc16-sfinae-qchar.patch index 888e128c..e8afea81 100644 --- a/depends/patches/qt/fix-gcc16-sfinae-qchar.patch +++ b/depends/patches/qt/fix-gcc16-sfinae-qchar.patch @@ -37,7 +37,7 @@ diff --git a/qtbase/src/corelib/kernel/qmetatype.cpp b/qtbase/src/corelib/kernel index e70583404a46..54a0fe671fe0 100644 --- a/qtbase/src/corelib/kernel/qmetatype.cpp +++ b/qtbase/src/corelib/kernel/qmetatype.cpp -@@ -1212,7 +1212,7 @@ QT_WARNING_DISABLE_CLANG("-Wtautological-compare") +@@ -1230,7 +1230,7 @@ QT_WARNING_DISABLE_CLANG("-Wtautological-compare") return true; ); QMETATYPE_CONVERTER(QString, Char32, diff --git a/depends/patches/qt/fix_missed_headers.patch b/depends/patches/qt/fix_missed_headers.patch new file mode 100644 index 00000000..1fda902c --- /dev/null +++ b/depends/patches/qt/fix_missed_headers.patch @@ -0,0 +1,32 @@ +QXcbAtom: add missing #include + +Clang 21 complained about free() being an undefined identifier. + +See: https://codereview.qt-project.org/c/qt/qtbase/+/686891 + +--- a/qtbase/src/plugins/platforms/xcb/qxcbatom.cpp ++++ b/qtbase/src/plugins/platforms/xcb/qxcbatom.cpp +@@ -7,6 +7,7 @@ + #include + + #include ++#include + + static const char *xcb_atomnames = { + // window-manager <-> client protocols + + +syncqt.cpp: Include for std::transform + +See: https://codereview.qt-project.org/c/qt/qtbase/+/673183 + +--- a/qtbase/src/tools/syncqt/main.cpp ++++ b/qtbase/src/tools/syncqt/main.cpp +@@ -15,6 +15,7 @@ + * pre-defined list of header files. + */ + ++#include + #include + #include + #include diff --git a/depends/patches/qt/qtbase_platformsupport.patch b/depends/patches/qt/qtbase_platformsupport.patch deleted file mode 100644 index 45ccaea5..00000000 --- a/depends/patches/qt/qtbase_platformsupport.patch +++ /dev/null @@ -1,34 +0,0 @@ -CMake: Prevent creation of empty InputSupportPrivate module - -The combination of - -no-feature-evdev - -no-feature-tslib - -no-feature-libinput -led to the creation of the InputSupportPrivate module without source -files. - -This triggered CMake upstream issue 23464 when using CMake < 3.25. - -Fix this by adjusting the inexact condition that decides whether to -build InputSupportPrivate. - - -See: https://codereview.qt-project.org/c/qt/qtbase/+/633612 - - ---- a/qtbase/src/platformsupport/CMakeLists.txt -+++ b/qtbase/src/platformsupport/CMakeLists.txt -@@ -3,7 +3,12 @@ - - add_subdirectory(devicediscovery) - add_subdirectory(fbconvenience) --if(QT_FEATURE_evdev OR QT_FEATURE_integrityhid OR QT_FEATURE_libinput OR QT_FEATURE_tslib OR QT_FEATURE_xkbcommon) -+if(QT_FEATURE_evdev -+ OR QT_FEATURE_vxworksevdev -+ OR QT_FEATURE_integrityhid -+ OR QT_FEATURE_libinput -+ OR QT_FEATURE_tslib -+ OR (QT_FEATURE_libinput AND QT_FEATURE_xkbcommon)) - add_subdirectory(input) - endif() - if(QT_FEATURE_kms) diff --git a/depends/patches/qt/qtbase_plugins_cocoa.patch b/depends/patches/qt/qtbase_plugins_cocoa.patch index 2b0cc509..1f055353 100644 --- a/depends/patches/qt/qtbase_plugins_cocoa.patch +++ b/depends/patches/qt/qtbase_plugins_cocoa.patch @@ -8,7 +8,7 @@ See: https://codereview.qt-project.org/c/qt/qtbase/+/634002 --- a/qtbase/src/plugins/platforms/cocoa/CMakeLists.txt +++ b/qtbase/src/plugins/platforms/cocoa/CMakeLists.txt -@@ -107,3 +107,10 @@ qt_internal_extend_target(QCocoaIntegrationPlugin CONDITION QT_FEATURE_sessionma +@@ -108,3 +108,10 @@ qt_internal_extend_target(QCocoaIntegrationPlugin CONDITION QT_FEATURE_sessionma SOURCES qcocoasessionmanager.cpp qcocoasessionmanager.h ) diff --git a/depends/patches/qt/qtbase_skip_tools.patch b/depends/patches/qt/qtbase_skip_tools.patch index eef65425..77cb3e3f 100644 --- a/depends/patches/qt/qtbase_skip_tools.patch +++ b/depends/patches/qt/qtbase_skip_tools.patch @@ -9,7 +9,7 @@ Skip building/installing unneeded tools: --- a/qtbase/cmake/QtBaseGlobalTargets.cmake +++ b/qtbase/cmake/QtBaseGlobalTargets.cmake -@@ -118,9 +118,6 @@ qt_generate_global_module_pri_file() +@@ -128,9 +128,6 @@ qt_generate_global_module_pri_file() qt_generate_global_device_pri_file() qt_generate_qmake_and_qtpaths_wrapper_for_target() @@ -19,7 +19,7 @@ Skip building/installing unneeded tools: qt_internal_add_platform_internal_target(GlobalConfigPrivate) target_link_libraries(GlobalConfigPrivate INTERFACE GlobalConfig) -@@ -390,12 +387,3 @@ elseif(WASM) +@@ -400,12 +397,3 @@ elseif(WASM) qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py" DESTINATION "${INSTALL_LIBEXECDIR}") endif() diff --git a/depends/patches/zeromq/add_new_include.patch b/depends/patches/zeromq/add_new_include.patch new file mode 100644 index 00000000..0bf987f6 --- /dev/null +++ b/depends/patches/zeromq/add_new_include.patch @@ -0,0 +1,123 @@ +commit 2e8a6ccb414ca79636392604893c79c3b0d00dc4 +Author: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> +Date: Sat Jul 4 09:11:11 2026 +0200 + + Add missing includes for std::nothrow + + Without the include, compilation may fail: + + ``` + src/polling_util.hpp:28:30: error: no member named 'nothrow' in namespace 'std' + 28 | _buf = new (std::nothrow) T[nitems_]; + | ^~~~~~~ + ``` + +diff --git a/src/norm_engine.cpp b/src/norm_engine.cpp +index 1e3ae179..02483f0b 100644 +--- a/src/norm_engine.cpp ++++ b/src/norm_engine.cpp +@@ -1,6 +1,7 @@ + + #include "precompiled.hpp" + ++#include + #include "platform.hpp" + + #if defined ZMQ_HAVE_NORM +diff --git a/src/polling_util.hpp b/src/polling_util.hpp +index 13a4911f..3536be9a 100644 +--- a/src/polling_util.hpp ++++ b/src/polling_util.hpp +@@ -4,6 +4,7 @@ + #define __ZMQ_SOCKET_POLLING_UTIL_HPP_INCLUDED__ + + #include ++#include + #include + + #if defined ZMQ_HAVE_WINDOWS +diff --git a/src/proxy.cpp b/src/proxy.cpp +index 78d6ba61..85e4db4a 100644 +--- a/src/proxy.cpp ++++ b/src/proxy.cpp +@@ -3,6 +3,7 @@ + #include "precompiled.hpp" + + #include ++#include + #include "poller.hpp" + #include "proxy.hpp" + #include "likely.hpp" +diff --git a/src/reaper.cpp b/src/reaper.cpp +index 4361a7e9..1484a926 100644 +--- a/src/reaper.cpp ++++ b/src/reaper.cpp +@@ -2,6 +2,7 @@ + + #include "precompiled.hpp" + #include "macros.hpp" ++#include + #include "reaper.hpp" + #include "socket_base.hpp" + #include "err.hpp" +diff --git a/src/session_base.cpp b/src/session_base.cpp +index 5a81b076..618443d5 100644 +--- a/src/session_base.cpp ++++ b/src/session_base.cpp +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: MPL-2.0 */ + + #include "precompiled.hpp" ++#include + #include "macros.hpp" + #include "session_base.hpp" + #include "i_engine.hpp" +diff --git a/src/socket_poller.cpp b/src/socket_poller.cpp +index b5c330e8..3feb452e 100644 +--- a/src/socket_poller.cpp ++++ b/src/socket_poller.cpp +@@ -7,6 +7,7 @@ + #include "macros.hpp" + + #include ++#include + + static bool is_thread_safe (const zmq::socket_base_t &socket_) + { +diff --git a/src/stream_connecter_base.cpp b/src/stream_connecter_base.cpp +index 8dd9a6d6..6b733b4d 100644 +--- a/src/stream_connecter_base.cpp ++++ b/src/stream_connecter_base.cpp +@@ -15,6 +15,7 @@ + #endif + + #include ++#include + + zmq::stream_connecter_base_t::stream_connecter_base_t ( + zmq::io_thread_t *io_thread_, +diff --git a/src/stream_listener_base.cpp b/src/stream_listener_base.cpp +index 350093ad..b4e02027 100644 +--- a/src/stream_listener_base.cpp ++++ b/src/stream_listener_base.cpp +@@ -13,6 +13,8 @@ + #include + #endif + ++#include ++ + zmq::stream_listener_base_t::stream_listener_base_t ( + zmq::io_thread_t *io_thread_, + zmq::socket_base_t *socket_, +diff --git a/src/ws_engine.cpp b/src/ws_engine.cpp +index 9eec0d92..55590cdc 100644 +--- a/src/ws_engine.cpp ++++ b/src/ws_engine.cpp +@@ -26,6 +26,7 @@ + #endif + + #include ++#include + + #include "compat.hpp" + #include "tcp.hpp" diff --git a/doc/AI_POLICY.md b/doc/AI_POLICY.md index 6238c790..fde44c48 100644 --- a/doc/AI_POLICY.md +++ b/doc/AI_POLICY.md @@ -23,6 +23,7 @@ This includes the pull request body and responses to questions. This project requires a human author in the loop who understands the work produced by AI. **Pull requests should not be opened or driven by autonomous agents**. A human author must choose the work, understand the change, and be responsible for the contribution. +Do not include agents as authors or co-authors of your commits for these reasons. Pull requests that appear in violation of this can be closed without notice. If you wish to include context from an interaction with AI in your comments, it must be disclosed as such. diff --git a/doc/REST-interface.md b/doc/REST-interface.md index ed46e222..91fa0399 100644 --- a/doc/REST-interface.md +++ b/doc/REST-interface.md @@ -12,17 +12,24 @@ REST Interface consistency guarantees The [same guarantees as for the RPC Interface](/doc/JSON-RPC-interface.md#rpc-consistency-guarantees) apply. -Limitations ------------ - -There is a known issue in the REST interface that can cause a node to crash if -too many http connections are being opened at the same time because the system runs -out of available file descriptors. To prevent this from happening you might -want to increase the number of maximum allowed file descriptors in your system -and try to prevent opening too many connections to your rest interface at the -same time if this is under your control. It is hard to give general advice -since this depends on your system but if you make several hundred requests at -once you are definitely at risk of encountering this issue. +Default HTTP caching +-------------------- + +REST responses include `Cache-Control` headers by default: + +* `public, immutable, max-age=86400` for `/block` and `/block/notxdetails` + binary and hex responses, `/blockpart`, `/blockfilter` and `/spenttxouts` in + all formats, and `/deploymentinfo/.json`. The TTL is deliberately + short so caches do not hold older response shapes across software upgrades. +* `no-store` for `/block` and `/block/notxdetails` JSON, `/tx`, `/headers`, + `/blockfilterheaders`, `/blockhashbyheight`, `/chaininfo`, `/mempool`, + `/getutxos`, `/deploymentinfo.json`, and all error responses. These responses + can change with active chain or node state and do not currently provide cache + validators such as `ETag` or `Last-Modified`. + +If you front `bitcoind` with a reverse proxy or CDN such as Caddy or nginx with +the headers-more module, you can override these defaults there. Keep overrides +scoped to responses you know are safe to cache more aggressively. Supported API ------------- diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index ffb8ecfe..8189fe0b 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -74,7 +74,7 @@ There is an included test suite that is useful for testing code changes when dev To run the test suite (recommended), you will need to have Python 3 installed: ```bash -pkg install python3 databases/py-sqlite3 net/py-pyzmq +pkg install python3 databases/py-sqlite3 net/py-pyzmq lsof ``` --- diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md index d4d031d3..fc3096bb 100644 --- a/doc/build-netbsd.md +++ b/doc/build-netbsd.md @@ -15,22 +15,6 @@ The example commands below use `pkgin`. pkgin install git cmake boost ``` -NetBSD currently ships with an older version of `gcc` than is needed to build. You should upgrade your `gcc` and then pass this new version to the CMake configuration. - -For example, grab `gcc12`: -``` -pkgin install gcc12 -``` - -Then, when configuring, pass the following: -```bash -cmake -B build - ... - -DCMAKE_C_COMPILER="/usr/pkg/gcc12/bin/gcc" \ - -DCMAKE_CXX_COMPILER="/usr/pkg/gcc12/bin/g++" \ - ... -``` - SQLite is required for the wallet: ```bash @@ -42,7 +26,7 @@ To build Bitcoin Core without the wallet, use `-DENABLE_WALLET=OFF`. Cap'n Proto is needed for IPC functionality (see [multiprocess.md](multiprocess.md)): ```bash -pkgin install capnproto +pkgin install capnproto pkgconf ``` Compile with `-DENABLE_IPC=OFF` if you do not need IPC functionality. @@ -84,7 +68,7 @@ Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` Bitcoin Core can provide notifications via ZeroMQ. To compile ZMQ support, install the following dependency and pass `-DWITH_ZMQ=ON` when configuring. ```bash -pkgin install zeromq pkg-config +pkgin install zeromq pkgconf ``` #### Test Suite Dependencies @@ -93,7 +77,14 @@ There is an included test suite that is useful for testing code changes when dev To run the test suite (recommended), you will need to have Python 3 installed: ```bash -pkgin install python313 py313-zmq +pkgin install python313 py313-zmq lsof +``` + +When the `lsof` binary package was built for a different point release, it might be necessary to force its installation as follows: + +```bash +echo "CHECK_OSABI=no" >> /etc/pkg_install.conf +pkgin install lsof ``` ## Building Bitcoin Core diff --git a/doc/build-osx.md b/doc/build-osx.md index bf55fda3..4cdb4834 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -106,7 +106,7 @@ Otherwise, if you don't need QR encoding support, you can pass `-DWITH_QRENCODE= #### ZMQ Dependencies -Support for ZMQ notifications requires the following dependency. +Bitcoin Core can provide notifications via ZeroMQ. To compile ZMQ support, install the following dependency and pass `-DWITH_ZMQ=ON` when configuring. Skip if you do not need ZMQ functionality. ``` bash diff --git a/doc/build-windows.md b/doc/build-windows.md index 449dd4be..0af73681 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -9,7 +9,7 @@ The options known to work for building Bitcoin Core on Windows are: * On Windows, using [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/about) and Mingw-w64. * On Windows, using [Microsoft Visual Studio](https://visualstudio.microsoft.com). See [`build-windows-msvc.md`](./build-windows-msvc.md). -Other options which may work, but which have not been extensively tested are (please contribute instructions): +Other options may work, but are not officially tested: * On Windows, using a POSIX compatibility layer application such as [cygwin](https://www.cygwin.com/) or [msys2](https://www.msys2.org/). diff --git a/doc/cjdns.md b/doc/cjdns.md index 9bdcec73..22849282 100644 --- a/doc/cjdns.md +++ b/doc/cjdns.md @@ -73,7 +73,11 @@ connections are not affected by this option. It can be specified multiple times to allow multiple networks, e.g. onlynet=cjdns, onlynet=i2p, onlynet=onion. CJDNS support was added to Bitcoin Core in version 23.0 and there may be fewer -CJDNS peers than Tor or IP ones. You can use `bitcoin-cli -addrinfo` to see the +CJDNS peers than Tor or IP ones. Therefore, using CJDNS alone without other +networks is discouraged: a node may be unable to fill its outbound connection slots +but will repeatedly try the few addresses it knows and is more susceptible to +[Sybil attacks](https://en.bitcoin.it/wiki/Weaknesses#Sybil_attack). +You can use `bitcoin-cli -addrinfo` to see the number of CJDNS addresses known to your node. In general, a node can be run with both an onion service and CJDNS (or any/all diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 0bc1bd25..b31d42a1 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -673,6 +673,35 @@ Additional resources: A few non-style-related recommendations for developers, as well as points to pay attention to for reviewers of Bitcoin Core code. +## General Testing + +As a rule of thumb, an externally observable change (new feature, bug fix, or +changed default) should be accompanied by an automated test. +New tests are usually not needed for behavior-preserving work that is easy to +validate, such as moving code, renaming, or mechanical refactors. +When an automated test would be brittle or have limited long-term value, +a manual testing guide in the commit message or PR description is an +acceptable alternative. + +### Commit Structure for Tests + +Test placement depends on existing coverage and the type of change: + +* When existing tests already cover the behavior being changed, update them in + the same commit as the change. The diff records the old and new expectations + together and shows the change was intentional. +* For a simple feature or bug fix without existing coverage, the change and its + test can often be in the same commit. +* For a non-trivial refactor, if the relevant invariant is not already covered + by automated tests, first add that coverage in a separate test commit. The + refactor commit should not need to update test expectations. +* For a non-trivial change to existing behavior without coverage, consider + adding a preceding commit with a [characterization test](https://en.wikipedia.org/wiki/Characterization_test) + to document the current behavior. Mark assertions whose expected values will + change with `TODO` comments so they are not mistaken for intended behavior. + Remove the comments when updating those assertions in the behavior-changing + commit. + ## Locking/mutex usage notes The code is multi-threaded and uses mutexes and the diff --git a/doc/files.md b/doc/files.md index e8f28692..7176b5c6 100644 --- a/doc/files.md +++ b/doc/files.md @@ -54,6 +54,7 @@ Subdirectory | File(s) | Description `blocks/` | `revNNNNN.dat`[\[2\]](#note2) | Block undo data (custom format) `blocks/` | `xor.dat` | Rolling XOR pattern for block and undo data files `chainstate/` | LevelDB database | Blockchain state (a compact representation of all currently unspent transaction outputs (UTXOs) and metadata about the transactions they are from) +`fees/` | `block_policy_estimates.dat` and `mempool_policy_estimator.dat` | Stores block policy and mempool policy estimator data `indexes/txindex/` | LevelDB database | Transaction index; *optional*, used if `-txindex=1` `indexes/txospenderindex/` | LevelDB database | Transaction spender index; *optional*, used if `-txospenderindex=1` `indexes/blockfilter/basic/db/` | LevelDB database | Blockfilter index LevelDB database for the basic filtertype; *optional*, used if `-blockfilterindex=basic` @@ -65,7 +66,6 @@ Subdirectory | File(s) | Description `./` | `bitcoin.conf` | User-defined [configuration settings](bitcoin-conf.md) for `bitcoind` or `bitcoin-qt`. File is not written to by the software and must be created manually. Path can be specified by `-conf` option `./` | `bitcoind.pid` | Stores the process ID (PID) of `bitcoind` or `bitcoin-qt` while running; created at start and deleted on shutdown; can be specified by `-pid` option `./` | `debug.log` | Contains debug information and general logging generated by `bitcoind` or `bitcoin-qt`; can be specified by `-debuglogfile` option -`./` | `fee_estimates.dat` | Stores statistics used to estimate minimum transaction fees required for confirmation `./` | `guisettings.ini.bak` | Backup of former [GUI settings](#gui-settings) after `-resetguisettings` option is used `./` | `mempool.dat` | Dump of the mempool's transactions `./` | `onion_v3_private_key` | Cached Tor onion service private key for `-listenonion` option diff --git a/doc/i2p.md b/doc/i2p.md index 2877c1e5..6bf427ea 100644 --- a/doc/i2p.md +++ b/doc/i2p.md @@ -4,20 +4,20 @@ It is possible to run Bitcoin Core as an [I2P (Invisible Internet Project)](https://en.wikipedia.org/wiki/I2P) service and connect to such services. -This [glossary](https://geti2p.net/en/about/glossary) may be useful to get +This [glossary](https://i2p.net/en/docs/overview/glossary) may be useful to get started with I2P terminology. ## Run Bitcoin Core with an I2P router (proxy) -A running I2P router (proxy) is required with the [SAM](https://geti2p.net/en/docs/api/samv3) +A running I2P router (proxy) is required with the [SAM](https://i2p.net/en/docs/api/samv3) application bridge enabled. The following routers are recommended for use with Bitcoin Core: -- [i2prouter (I2P Router)](https://geti2p.net), the official implementation in +- [i2prouter (I2P Router)](https://i2p.net), the official implementation in Java. The SAM bridge is not enabled by default; it must be started manually, or configured to start automatically, in the Clients page in the router console (`http://127.0.0.1:7657/configclients`) or in the `clients.config` file. - [i2pd (I2P Daemon)](https://github.com/PurpleI2P/i2pd) - ([documentation](https://i2pd.readthedocs.io/en/latest)), a lighter + ([documentation](https://docs.i2pd.website/en/latest)), a lighter alternative in C++. It enables the SAM bridge by default. Note the IP address and port the SAM proxy is listening to; usually, it is @@ -113,7 +113,7 @@ You can use the `getnodeaddresses` RPC to fetch a number of I2P peers known to y ## Compatibility -Bitcoin Core uses the [SAM v3.1](https://geti2p.net/en/docs/api/samv3) protocol +Bitcoin Core uses the [SAM v3.1](https://i2p.net/en/docs/api/samv3) protocol to connect to the I2P network. Any I2P router that supports it can be used. ## Ports in I2P and Bitcoin Core @@ -158,13 +158,13 @@ Similar bandwidth configuration options for the Java I2P router can be found in `http://127.0.0.1:7657/config` under the "Bandwidth" tab. Before doing this, please see the "Participating Traffic Considerations" section -in [Embedding I2P in your Application](https://geti2p.net/en/docs/applications/embedding). +in [Embedding I2P in your Application](https://i2p.net/en/docs/applications/embedding). In most cases, the default router settings should work fine. ## Bundling I2P in a Bitcoin application -Please see the "General Guidance for Developers" section in https://geti2p.net/en/docs/api/samv3 +Please see the "General Guidance for Developers" section in https://i2p.net/en/docs/api/samv3 if you are developing a downstream application that may be bundling I2P with Bitcoin. ## Privacy recommendations diff --git a/doc/multisig-tutorial.md b/doc/multisig-tutorial.md index b6f496a3..fd74e62e 100644 --- a/doc/multisig-tutorial.md +++ b/doc/multisig-tutorial.md @@ -9,18 +9,16 @@ This tutorial uses [jq](https://github.com/stedolan/jq) JSON processor to proces Before starting this tutorial, start the bitcoin node on the signet network. ```bash -./build/bin/bitcoind -signet -daemon +./build/bin/bitcoin node -signet -daemon ``` -This tutorial also uses the default WPKH derivation path to get the xpubs and does not conform to [BIP 45](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) or [BIP 87](https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki). - -At the time of writing, there is no way to extract a specific path from wallets in Bitcoin Core. For this, an external signer/xpub can be used. +This tutorial also uses the default PKH derivation path to get the xpubs and does not conform to [BIP 45](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) or [BIP 87](https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki). ## 1.1 Basic Multisig Workflow ### 1.1 Create the Descriptor Wallets -For a 2-of-3 multisig, create 3 descriptor wallets. It is important that they are of the descriptor type in order to retrieve the wallet descriptors. These wallets contain HD seed and private keys, which will be used to sign the PSBTs and derive the xpub. +For a 2-of-3 multisig, create 3 wallets. These wallets contain HD seed and private keys, which will be used to sign the PSBTs and derive the xpub. These three wallets should not be used directly for privacy reasons (public key reuse). They should only be used to sign transactions for the (watch-only) multisig wallet. @@ -31,16 +29,7 @@ do done ``` -Extract the xpub of each wallet. To do this, the `listdescriptors` RPC is used. By default, Bitcoin Core single-sig wallets are created using path `m/44'/1'/0'` for PKH, `m/84'/1'/0'` for WPKH, `m/49'/1'/0'` for P2WPKH-nested-in-P2SH and `m/86'/1'/0'` for P2TR based accounts. Each of them uses the chain 0 for external addresses and chain 1 for internal ones, as shown in the example below. - -``` -wpkh([1004658e/84'/1'/0']tpubDCBEcmVKbfC9KfdydyLbJ2gfNL88grZu1XcWSW9ytTM6fitvaRmVyr8Ddf7SjZ2ZfMx9RicjYAXhuh3fmLiVLPodPEqnQQURUfrBKiiVZc8/0/*)#g8l47ngv - -wpkh([1004658e/84'/1'/0']tpubDCBEcmVKbfC9KfdydyLbJ2gfNL88grZu1XcWSW9ytTM6fitvaRmVyr8Ddf7SjZ2ZfMx9RicjYAXhuh3fmLiVLPodPEqnQQURUfrBKiiVZc8/1/*)#en65rxc5 -``` - -The suffix (after #) is the checksum. Descriptors can optionally be suffixed with a checksum to protect against typos or copy-paste errors. -All RPCs in Bitcoin Core will include the checksum in their output. +Extract the xpub of each wallet. To do this, the `derivehdkey` RPC is used. Note that previously at least two descriptors were usually used, one for external derivation paths and one for internal ones. Since https://github.com/bitcoin/bitcoin/pull/22838 this redundancy has been eliminated by a multipath descriptor with <0;1> at the [BIP-44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#change) change level expanding to external and internal descriptors when imported. @@ -49,49 +38,44 @@ declare -A xpubs for ((n=1;n<=3;n++)) do - xpubs["xpub_${n}"]=$(./build/bin/bitcoin rpc -signet -rpcwallet="participant_${n}" listdescriptors | jq '.descriptors | [.[] | select(.desc | startswith("wpkh") and contains("/0/*") )][0] | .desc' | grep -Po '(?<=\().*(?=\))' | sed 's /0/\* /<0;1>/* ') + xpubs["xpub_${n}"]=$(./build/bin/bitcoin rpc -signet -rpcwallet="participant_${n}" derivehdkey "m/44h/1h/0h" | jq -r '.origin + .xpub') done ``` -`jq` is used to extract the xpub from the `wpkh` descriptor. - -The following command can be used to verify if the xpub was generated correctly. +The following command can be used to verify if the xpubs were obtained successfully: ```bash for x in "${!xpubs[@]}"; do printf "[%s]=%s\n" "$x" "${xpubs[$x]}" ; done ``` -As previously mentioned, this step extracts the `m/84'/1'/0'` account instead of the path defined in [BIP 45](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) or [BIP 87](https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki), since there is no way to extract a specific path in Bitcoin Core at the time of writing. +As previously mentioned, this step extracts the `m/44'/1'/0'` account instead of the path defined in [BIP 45](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) or [BIP 87](https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki), because the wallet currently can't sign for a derivation path that's not used in one of its descriptors. ### 1.2 Define the Multisig Descriptor -Define the multisig descriptor, add the checksum and then, wrap it in a JSON array. +Define the multisig descriptors. + +All RPCs in Bitcoin Core will include the checksum in their output. ```bash -desc="wsh(sortedmulti(2,${xpubs["xpub_1"]},${xpubs["xpub_2"]},${xpubs["xpub_3"]}))" +desc="wsh(sortedmulti(2,${xpubs["xpub_1"]}/<0;1>/*,${xpubs["xpub_2"]}/<0;1>/*,${xpubs["xpub_3"]}/<0;1>/*))" -checksum=$(./build/bin/bitcoin rpc -signet getdescriptorinfo $desc | jq -r '.checksum') +desc_sum=$(./build/bin/bitcoin rpc -signet getdescriptorinfo $desc | jq -r '.checksum') -multisig_desc="[{\"desc\": \"${desc}#${checksum}\", \"active\": true, \"timestamp\": \"now\"}]" +multisig_desc="[{\"desc\": \"$desc#$desc_sum\", \"active\": true, \"timestamp\": \"now\"}]" ``` `desc` specifies the output type (`wsh`, in this case) and the xpubs involved. It also uses 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)]. -After creating the descriptor, it is necessary to add the checksum, which is required by the `importdescriptors` RPC. +The checksum for a descriptor without one can be computed using the `getdescriptorinfo` RPC. The response has a `checksum` field, which is appended to the descriptor after `#` to protect against typos or copy-paste errors. -The checksum for a descriptor without one can be computed using the `getdescriptorinfo` RPC. The response has the `checksum` field, which is the checksum for the input descriptor, append "#" and this checksum to the input descriptor. - -There are other fields that can be added to the descriptor: +There are other fields that can be added to the descriptors: * `active`: Sets the descriptor to be the active one for the corresponding output type (`wsh`, in this case). -* `internal`: Indicates whether matching outputs should be treated as something other than incoming payments (e.g. change). * `timestamp`: Sets the time from which to start rescanning the blockchain for the descriptor, in UNIX epoch time. -Note: when a multipath descriptor is imported, it is expanded into two descriptors which are imported separately, with the second implicitly used for internal (change) addresses. - Documentation for these and other parameters can be found by typing `./build/bin/bitcoin rpc -signet help importdescriptors`. -`multisig_desc` wraps the descriptor in a JSON array and will be used to create the multisig wallet. +`multisig_desc` concatenates the descriptor in a JSON array and then it will be used to create the multisig wallet. ### 1.3 Create the Multisig Wallet @@ -99,16 +83,18 @@ To create the multisig wallet, first create an empty one (no keys, HD seed and p Then import the descriptor created in the previous step using the `importdescriptors` RPC. -After that, `getwalletinfo` can be used to check if the wallet was created successfully. +After that, `listdescriptors` can be used to check if the wallet was created successfully. ```bash -./build/bin/bitcoin rpc -signet createwallet "multisig_wallet_01" disable_private_keys=true blank=true +./build/bin/bitcoin rpc -signet -named createwallet wallet_name="multisig_wallet_01" disable_private_keys=true blank=true ./build/bin/bitcoin rpc -signet -rpcwallet="multisig_wallet_01" importdescriptors "$multisig_desc" -./build/bin/bitcoin rpc -signet -rpcwallet="multisig_wallet_01" getwalletinfo +./build/bin/bitcoin rpc -signet -rpcwallet="multisig_wallet_01" listdescriptors ``` +The `<0;1>` notation in `desc` caused the creation of two descriptors. One uses the chain 0 for external addresses, and the other uses chain 1 for internal ones (change). + Once the wallets have already been created and this tutorial needs to be repeated or resumed, it is not necessary to recreate them, just load them with the command below: ```bash @@ -199,7 +185,7 @@ psbt_2=$(./build/bin/bitcoin rpc -signet -rpcwallet="participant_2" walletproces The PSBT, if signed separately by the co-signers, must be combined into one transaction before being finalized. This is done by `combinepsbt` RPC. ```bash -combined_psbt=$(./build/bin/bitcoin rpc -signet combinepsbt "[$psbt_1, $psbt_2]") +combined_psbt=$(./build/bin/bitcoin rpc -signet combinepsbt txs="[$psbt_1, $psbt_2]") ``` There is an RPC called `joinpsbts`, but it has a different purpose than `combinepsbt`. `joinpsbts` joins the inputs from multiple distinct PSBTs into one PSBT. diff --git a/doc/reduce-memory.md b/doc/reduce-memory.md index 348d98bd..6729ab66 100644 --- a/doc/reduce-memory.md +++ b/doc/reduce-memory.md @@ -33,7 +33,7 @@ The size of some in-memory caches can be reduced. As caches trade off memory usa ## Number of peers -- `-maxconnections=` - the maximum number of connections, which defaults to 125. Each active connection takes up some +- `-maxconnections=` - the maximum number of connections, which defaults to 200. Each active connection takes up some memory. This option applies only if inbound connections are enabled; otherwise, the number of connections will not be more than 11. Of the 11 outbound peers, there can be 8 full-relay connections, 2 block-relay-only ones, and occasionally 1 short-lived feeler or extra outbound block-relay-only connection. diff --git a/doc/reduce-traffic.md b/doc/reduce-traffic.md index 8926a836..315de214 100644 --- a/doc/reduce-traffic.md +++ b/doc/reduce-traffic.md @@ -3,8 +3,9 @@ Reduce Traffic Some node operators need to deal with bandwidth caps imposed by their ISPs. -By default, Bitcoin Core allows up to 125 connections to different peers, 11 of -which are outbound. You can therefore, have at most 114 inbound connections. +By default, Bitcoin Core allows up to 200 connections to different peers, 11 of +which are outbound. You can therefore, have at most 189 inbound connections, half of +which can only be taken up by low-traffic block-relay-only peers. Of the 11 outbound peers, there can be 8 full-relay connections, 2 block-relay-only ones and occasionally 1 short-lived feeler or an extra block-relay-only connection. diff --git a/doc/release-notes-32784.md b/doc/release-notes-32784.md new file mode 100644 index 00000000..6312165f --- /dev/null +++ b/doc/release-notes-32784.md @@ -0,0 +1,9 @@ +Wallet +------ + +- A new `derivehdkey` RPC is available to obtain an xpub or xprv for a + derivation path with at least one hardened step from an HD key known to the + wallet. This can be used to coordinate a multisig setup, where each signer + shares an xpub using a + different derivation path than the default single-signature descriptors. The + example in `doc/multisig-tutorial.md` is updated to use this RPC. (#32784) diff --git a/doc/release-notes-32800.md b/doc/release-notes-32800.md new file mode 100644 index 00000000..de7a427e --- /dev/null +++ b/doc/release-notes-32800.md @@ -0,0 +1,9 @@ +- Mempool RPCs (`getrawmempool`, `getmempoolentry`, `testmempoolaccept`, `submitpackage`) +now include an additional field `vsize_adjusted` (which is the sigop-adjusted virtual size +used for policy) and `vsize_bip141` (which represents the raw BIP141 virtual size). +While `vsize` is marked as DEPRECATED, it was previously erroneously described as the BIP 141 +vsize, but is actually sigops-adjusted vsize. Use `vsize_bip141` to actually get that behavior +or switch to the explicit `vsize_adjusted` for retained behavior. + +- `getrawtransaction` RPC now includes an additional field `vsize_adjusted`, which is the +sigop-adjusted virtual size if the transaction is in the mempool. diff --git a/doc/release-notes-34075.md b/doc/release-notes-34075.md new file mode 100644 index 00000000..3d42b0de --- /dev/null +++ b/doc/release-notes-34075.md @@ -0,0 +1,52 @@ +Updated RPCs +------------ + +- The `estimatesmartfee` RPC now combines two fee rate estimators: the existing + block policy fee rate estimator and a new mempool fee rate estimator. + +- The new mempool fee rate estimator produces conservative and economical fee + rate estimates from the current contents of the mempool. It only produces a + fee rate estimate when recent blocks indicate a healthy mempool, and falls + back to the higher of the minimum relay fee rate and the current mempool + minimum fee rate when the mempool is too sparse. Its statistics are persisted + to `fees/mempool_policy_estimator.dat` and reloaded on startup. + + `estimatesmartfee` returns the lower of the two fee rate estimators' results, + so the mempool fee rate estimator can only lower the block policy fee rate + estimate. + +- The combined estimate requires both estimators to succeed. If the mempool fee + rate estimator cannot produce an estimate, for example, while the mempool is + still loading, when too few recent blocks have been observed, or when the + mempool is suspected to be unhealthy, an error is returned. + +- `estimatesmartfee` accepts an `options` object with `fee_rate_estimator`. + Recognized values are `"none"` (the default, combined behavior described + above), `"block_policy"` (use only the block policy fee rate estimator), + and `"mempool_policy"` (use only the mempool fee rate estimator). + All unknown values are treated as `"none"`. + Users who want the previous behavior can select the block policy fee rate + estimator explicitly. + +- The options object also accepts `verbosity`. A verbosity of `2` or higher + also returns `mempool_health_statistics`. + +- When `fee_rate_estimator` is `"none"` and the estimate succeeds, the response + also includes an `estimator` field identifying which fee rate estimator produced + the result. + +- Block policy fee estimator data is now stored in + `fees/block_policy_estimates.dat`. If the new file does not exist, the + legacy `fee_estimates.dat` file is moved to the new path during startup. If + both files exist, the legacy file is removed. + +- Wallet fee rate estimation uses the default combined estimate. + +Wallet +------ + +- The `fee_reason` field returned by wallet transaction creation RPCs now + reports the reason the wallet selected the fee rate (fee rate estimator, + mempool minimum, fallback, or minimum required) instead of the block policy + fee rate estimator's internal threshold details. Those details remain + available in the block policy fee rate estimator debug log. diff --git a/doc/release-notes-34628.md b/doc/release-notes-34628.md new file mode 100644 index 00000000..884ac073 --- /dev/null +++ b/doc/release-notes-34628.md @@ -0,0 +1,13 @@ +P2P and network changes +----------------------- + +- To reduce memory and CPU usage during periods of high transaction + volume, rate-limiting of outgoing transaction relay has been changed + to use a global backlog instead of being done on a per-peer basis. The + default rate-limit remains as 14 tx/s (boosted by 2.5x for outbound + peers), though this can be changed via the `-txsendrate` configuration + option. An additional bandwidth rate-limit has also been introduced + at 12MB of transactions per 10 minutes, with a high burst rate. The + size of the global backlog and the token bucket values for the rate + limits can be queried via the `getnetworkinfo` RPC. (#34628) + diff --git a/doc/release-notes-34672.md b/doc/release-notes-34672.md new file mode 100644 index 00000000..060d9142 --- /dev/null +++ b/doc/release-notes-34672.md @@ -0,0 +1,11 @@ +IPC Interface +------------- + +- `BlockTemplate.submitSolution` now returns `reason` and `debug` rejection + details in addition to the boolean result. Clients must regenerate IPC + bindings from the updated `mining.capnp` schema to use the new method. The + previous `@7` method now returns an error directing clients to update. (#34672) + +- `BlockTemplate.submitSolution` now reports duplicate blocks as failures with + `reason="duplicate"`, matching `Mining.submitBlock`, instead of returning + success for duplicate submissions. (#34672) diff --git a/doc/release-notes-34794.md b/doc/release-notes-34794.md new file mode 100644 index 00000000..befafa94 --- /dev/null +++ b/doc/release-notes-34794.md @@ -0,0 +1,8 @@ +REST API +-------- + +- REST responses now include `Cache-Control` headers to guide intermediary + caches. Immutable responses such as block binary and hex data, block parts, + block filters, spent transaction outputs, and block-specific deployment info + are marked cacheable for one day. Responses that can change with active chain + or node state, as well as errors, are marked `no-store`. (#34794) diff --git a/doc/release-notes-35182.md b/doc/release-notes-35182.md index 8d2b6918..d095d2fb 100644 --- a/doc/release-notes-35182.md +++ b/doc/release-notes-35182.md @@ -14,3 +14,8 @@ Certain HTTP edge cases will observe different behavior to be more RFC-compliant - "Line Folding" is rejected (whitespace at start of a header line) - Tolerate `%` at the end of requested URLs - Multiple "Content-Length" headers with different values are rejected + +A new configuration option `-rpcmaxconnections` (default `16`) limits the +number of simultaneously connected HTTP clients to the server. The application +will now attempt to reserve file descriptors for the HTTP server sockets. If your +system has limited resources, consider using a lower setting. diff --git a/doc/release-notes-35501.md b/doc/release-notes-35501.md new file mode 100644 index 00000000..2399ca1e --- /dev/null +++ b/doc/release-notes-35501.md @@ -0,0 +1,4 @@ +RPC +--- + +- `gettransaction`, `listtransactions`, and `listsinceblock` now have an `alternate_wtxids` field which lists the wtxids of all transactions that have the same txid. When there is only one known witness variant the field is an empty array, analogous to `walletconflicts` and `mempoolconflicts`. diff --git a/doc/release-notes-35531.md b/doc/release-notes-35531.md new file mode 100644 index 00000000..90e6014c --- /dev/null +++ b/doc/release-notes-35531.md @@ -0,0 +1,12 @@ +## Index + +- The transaction index (`-txindex`) now stores less data on disk; a fully + rebuilt index takes less than half the space. The index is backwards compatible, + so existing users will not see the space saving unless the index is recreated. + To do so, stop the node, delete the `/indexes/txindex` directory, and + restart; rebuilding can take up to a few hours depending on hardware. Progress + can be monitored using the `getindexinfo` RPC. Once rebuilt, the index can no + longer be read by previous releases, so downgrading will rebuild it again in + the old format. When downgrading permanently, delete the + `/indexes/txindex` directory first, since previous releases do not + reclaim the space used by entries in the new format. (#35531) diff --git a/doc/release-notes-35592.md b/doc/release-notes-35592.md new file mode 100644 index 00000000..e24eec31 --- /dev/null +++ b/doc/release-notes-35592.md @@ -0,0 +1,6 @@ +HTTP: RPC / REST +---------------- + +Clients attempting to connect from addresses not allowed by the `-rpcallowip` +option (or its default, `localhost`) will now be immediately disconnected +instead of receiving a `403 Forbidden`. diff --git a/doc/release-notes-35610.md b/doc/release-notes-35610.md index 8e0dd208..1f80677e 100644 --- a/doc/release-notes-35610.md +++ b/doc/release-notes-35610.md @@ -1,6 +1,6 @@ Tools and Utilities ------------------- -- A new `bitcoin-util netmagic` command returns the network magic of the - selected chain. +- A new `bitcoin-util getchainparams` command returns hardcoded details + about the selected chain. diff --git a/doc/release-notes-35680.md b/doc/release-notes-35680.md new file mode 100644 index 00000000..c5d19b15 --- /dev/null +++ b/doc/release-notes-35680.md @@ -0,0 +1,13 @@ +P2P and network changes +----------------------- + +- Each transaction sent via private broadcast (`-privatebroadcast`) is limited + to 1,000 send attempts. After reaching the limit, broadcasting stops; call + `sendrawtransaction` again to retry. Transactions that reach the limit remain + available through `getprivatebroadcastinfo` and `abortprivatebroadcast`. (#35680) + +Updated RPCs +------------ + +- `getprivatebroadcastinfo` now reports an `attempts_remaining` field for each + transaction. (#35680) diff --git a/doc/release-notes-35696.md b/doc/release-notes-35696.md new file mode 100644 index 00000000..393c2b05 --- /dev/null +++ b/doc/release-notes-35696.md @@ -0,0 +1,8 @@ +### P2P and Network Changes + +Support for the legacy ElGamal (type 0) encryption type when creating I2P +sessions is being sunset by the I2P network and will be removed from bitcoind on +or before v34. Nodes using I2P with versions of Bitcoin Core earlier than v26.1 +(PRs #29200, #29209) will soon only be able to connect to other legacy ElGamal +I2P peers and will be increasingly isolated from the rest of the network, with a +reduced anonymity set. See #35696 for details. diff --git a/doc/release-notes-35836.md b/doc/release-notes-35836.md new file mode 100644 index 00000000..851e48d4 --- /dev/null +++ b/doc/release-notes-35836.md @@ -0,0 +1,5 @@ +# RPC (wallet) + +* The `fundrawtransaction` RPC no longer accepts a boolean as the second + positional argument. This silent no-op fallback was removed and the argument + is now fully type checked. Passing a boolean will raise an error. (#35836) diff --git a/doc/release-notes-953.md b/doc/release-notes-953.md new file mode 100644 index 00000000..a4d03975 --- /dev/null +++ b/doc/release-notes-953.md @@ -0,0 +1,5 @@ +GUI Changes +--- + +The migrate wallet option now allows to disable wallet loading after migrating. +It is useful in case the node is pruned and the wallet was created before the pruned height. diff --git a/doc/release-notes-gui-872.md b/doc/release-notes-gui-872.md new file mode 100644 index 00000000..5ea70345 --- /dev/null +++ b/doc/release-notes-gui-872.md @@ -0,0 +1,7 @@ +GUI +--- + +* A menu action has been added to allow creating a watchonly wallet file from + an existing descriptor wallet. This option mirrors the `exportwatchonlywallet` + RPC - the exported file can be imported to another node using the Restore + Wallet menu action. diff --git a/doc/release-notes-removeprunedfunds.md b/doc/release-notes-removeprunedfunds.md new file mode 100644 index 00000000..0e0d0ceb --- /dev/null +++ b/doc/release-notes-removeprunedfunds.md @@ -0,0 +1,6 @@ +Updated RPCs +------------ + +- The `removeprunedfunds` RPC has been deprecated and will be removed in the +next major release. In order to continue using it, `bitcoind` must be started +with the `-deprecatedrpc=removeprunedfunds` option. diff --git a/doc/release-process.md b/doc/release-process.md index 28bcfe83..c02ada5a 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -59,11 +59,11 @@ Release Process - Clear the release notes and move them to the wiki (see "Write the release notes" below). - Translations on Transifex: - Pull translations from Transifex into the master branch. - - Create [a new resource](https://app.transifex.com/bitcoin/bitcoin/content/) named after the major version with the slug `qt-translation-x`, where `RRR` is the major branch number padded with zeros. Use `src/qt/locale/bitcoin_en.xlf` to create it. + - Create [a new resource](https://app.transifex.com/bitcoin/bitcoin/content/) named after the major version with the slug `qt-translation-x`, where `RRR` is the major branch number padded with zeros. Use `src/qt/locale/bitcoin_en.ts` to create it. - In the project workflow settings, ensure that [Translation Memory Fill-up](https://help.transifex.com/en/articles/6224817-setting-up-translation-memory-fill-up) is enabled and that [Translation Memory Context Matching](https://help.transifex.com/en/articles/6224753-translation-memory-with-context) is disabled. - Update the Transifex slug in [`.tx/config`](/.tx/config) to the slug of the resource created in the first step. This identifies which resource the translations will be synchronized from. - Make an announcement that translators can start translating for the new version. You can use one of the [previous announcements](https://app.transifex.com/bitcoin/communication/) as a template. - - Change the auto-update URL for the resource to `master`, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin/master/src/qt/locale/bitcoin_en.xlf`. (Do this only after the previous steps, to prevent an auto-update from interfering.) + - Change the auto-update URL for the resource to `master`, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin/master/src/qt/locale/bitcoin_en.ts`. (Do this only after the previous steps, to prevent an auto-update from interfering.) #### After branch-off (on the major release branch) @@ -72,7 +72,7 @@ Release Process - Clear the release notes: `cp doc/release-notes-empty-template.md doc/release-notes.md` - Create a pinned meta-issue for testing the release candidate (see [this issue](https://github.com/bitcoin/bitcoin/issues/27621) for an example) and provide a link to it in the release announcements where useful. - Translations on Transifex - - Change the auto-update URL for the new major version's resource away from `master` and to the branch, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin//src/qt/locale/bitcoin_en.xlf`. Do not forget this or it will keep tracking the translations on master instead, drifting away from the specific major release. + - Change the auto-update URL for the new major version's resource away from `master` and to the branch, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin//src/qt/locale/bitcoin_en.ts`. Do not forget this or it will keep tracking the translations on master instead, drifting away from the specific major release. - Prune inputs from the qa-assets repo (See [pruning inputs](https://github.com/bitcoin-core/qa-assets#pruning-inputs)). diff --git a/ruff.toml b/ruff.toml index d379dde1..61cf6d24 100644 --- a/ruff.toml +++ b/ruff.toml @@ -12,7 +12,5 @@ select = [ ] ignore = [ "E501", # line too long - "E712", # true-false comparison - "E731", # lambda assignment "E741", # ambiguous-variable-name ] diff --git a/share/qt/translate.cmake b/share/qt/translate.cmake index 2ac8c7f0..a8f54a91 100644 --- a/share/qt/translate.cmake +++ b/share/qt/translate.cmake @@ -7,7 +7,6 @@ cmake_minimum_required(VERSION 3.22) set(input_variables PROJECT_SOURCE_DIR COPYRIGHT_HOLDERS - LCONVERT_EXECUTABLE LUPDATE_EXECUTABLE XGETTEXT_EXECUTABLE ) @@ -103,28 +102,13 @@ extract_strings("${PROJECT_SOURCE_DIR}/src/qt/bitcoinstrings.cpp" execute_process( COMMAND ${LUPDATE_EXECUTABLE} -no-obsolete + -sort-messages -I ${PROJECT_SOURCE_DIR}/src - -locations relative + -locations none + -target-language en ${ui_files} ${qt_translatable_sources} ${PROJECT_SOURCE_DIR}/src/qt/bitcoinstrings.cpp -ts ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.ts COMMAND_ERROR_IS_FATAL ANY ) - -execute_process( - COMMAND ${LCONVERT_EXECUTABLE} - -drop-translations - -o ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf - -i ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.ts - COMMAND_ERROR_IS_FATAL ANY -) - -file(READ "${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf" bitcoin_en) -string(REPLACE "source-language=\"en\" target-language=\"en\"" - "source-language=\"en\"" bitcoin_en "${bitcoin_en}" -) -string(REGEX REPLACE " *\n" - "" bitcoin_en "${bitcoin_en}" -) -file(WRITE "${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf" "${bitcoin_en}") diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 387d7811..33baa477 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -72,19 +72,19 @@ ShowUninstDetails show Section -Main SEC0000 SetOutPath $INSTDIR SetOverwrite on - File @abs_top_builddir@/release/@BITCOIN_GUI_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_WRAPPER_NAME@@EXEEXT@ - File /oname=COPYING.txt @abs_top_srcdir@/COPYING - File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt - File @abs_top_srcdir@/share/examples/bitcoin.conf + File "@BIN_DIR@/@BITCOIN_GUI_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_WRAPPER_NAME@@EXEEXT@" + File /oname=COPYING.txt "@abs_top_srcdir@/COPYING" + File /oname=readme.txt "@abs_top_srcdir@/doc/README_windows.txt" + File "@abs_top_srcdir@/share/examples/bitcoin.conf" SetOutPath $INSTDIR\share\rpcauth - File @abs_top_srcdir@/share/rpcauth/*.* + File "@abs_top_srcdir@/share/rpcauth/*.*" SetOutPath $INSTDIR\daemon - File @abs_top_builddir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_TX_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_WALLET_TOOL_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_TEST_NAME@@EXEEXT@ + File "@BIN_DIR@/@BITCOIN_DAEMON_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_CLI_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_TX_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_WALLET_TOOL_NAME@@EXEEXT@" + File "@LIBEXEC_DIR@/@BITCOIN_TEST_NAME@@EXEEXT@" SetOutPath $INSTDIR WriteRegStr HKCU "${REGKEY}\Components" Main 1 SectionEnd diff --git a/src/.clang-tidy b/src/.clang-tidy index 9bdcc03f..4e0af3f3 100644 --- a/src/.clang-tidy +++ b/src/.clang-tidy @@ -8,8 +8,10 @@ bugprone-use-after-move, bugprone-lambda-function-name, bugprone-unhandled-self-assignment, bugprone-unused-return-value, -misc-unused-using-decls, +fuchsia-header-anon-namespaces, +misc-definitions-in-headers, misc-no-recursion, +misc-unused-using-decls, modernize-avoid-bind, modernize-deprecated-headers, modernize-use-default-member-init, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47266dcf..15b60ef9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -164,10 +164,10 @@ if(ENABLE_WALLET) if(BUILD_WALLET_TOOL) add_executable(bitcoin-wallet bitcoin-wallet.cpp + bitcoin-wallet-res.rc init/bitcoin-wallet.cpp wallet/wallettool.cpp ) - add_windows_resources(bitcoin-wallet bitcoin-wallet-res.rc) add_windows_application_manifest(bitcoin-wallet) target_link_libraries(bitcoin-wallet core_interface @@ -247,7 +247,9 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL noui.cpp policy/ephemeral_policy.cpp policy/fees/block_policy_estimator.cpp - policy/fees/block_policy_estimator_args.cpp + policy/fees/estimator_args.cpp + policy/fees/estimator_man.cpp + policy/fees/mempool_estimator.cpp policy/packages.cpp policy/rbf.cpp policy/settings.cpp @@ -302,8 +304,10 @@ endif() # Bitcoin wrapper executable that can call other executables. if(BUILD_BITCOIN_BIN) - add_executable(bitcoin bitcoin.cpp) - add_windows_resources(bitcoin bitcoin-res.rc) + add_executable(bitcoin + bitcoin.cpp + bitcoin-res.rc + ) add_windows_application_manifest(bitcoin) target_link_libraries(bitcoin core_interface bitcoin_common bitcoin_util) install_binary_component(bitcoin HAS_MANPAGE) @@ -313,9 +317,9 @@ endif() if(BUILD_DAEMON) add_executable(bitcoind bitcoind.cpp + bitcoind-res.rc init/bitcoind.cpp ) - add_windows_resources(bitcoind bitcoind-res.rc) add_windows_application_manifest(bitcoind) target_link_libraries(bitcoind core_interface @@ -352,8 +356,11 @@ target_link_libraries(bitcoin_cli # Bitcoin Core RPC client if(BUILD_CLI) - add_executable(bitcoin-cli bitcoin-cli.cpp init/basic.cpp) - add_windows_resources(bitcoin-cli bitcoin-cli-res.rc) + add_executable(bitcoin-cli + bitcoin-cli.cpp + bitcoin-cli-res.rc + init/basic.cpp + ) add_windows_application_manifest(bitcoin-cli) target_link_libraries(bitcoin-cli core_interface @@ -367,8 +374,10 @@ endif() if(BUILD_TX) - add_executable(bitcoin-tx bitcoin-tx.cpp) - add_windows_resources(bitcoin-tx bitcoin-tx-res.rc) + add_executable(bitcoin-tx + bitcoin-tx.cpp + bitcoin-tx-res.rc + ) add_windows_application_manifest(bitcoin-tx) target_link_libraries(bitcoin-tx core_interface @@ -381,13 +390,16 @@ endif() if(BUILD_UTIL) - add_executable(bitcoin-util bitcoin-util.cpp) - add_windows_resources(bitcoin-util bitcoin-util-res.rc) + add_executable(bitcoin-util + bitcoin-util.cpp + bitcoin-util-res.rc + ) add_windows_application_manifest(bitcoin-util) target_link_libraries(bitcoin-util core_interface bitcoin_common bitcoin_util + univalue ) install_binary_component(bitcoin-util HAS_MANPAGE) endif() diff --git a/src/addresstype.h b/src/addresstype.h index 862049de..79fcf3d1 100644 --- a/src/addresstype.h +++ b/src/addresstype.h @@ -118,7 +118,7 @@ struct WitnessUnknown }; /** Witness program for Pay-to-Anchor output script type */ -static const std::vector ANCHOR_BYTES{0x4e, 0x73}; +inline const std::vector ANCHOR_BYTES{0x4e, 0x73}; struct PayToAnchor : public WitnessUnknown { diff --git a/src/addrman.cpp b/src/addrman.cpp index 3050beb7..554e5ad0 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -910,7 +910,10 @@ void AddrManImpl::ResolveCollisions_() int tried_bucket_pos = info_new.GetBucketPosition(nKey, false, tried_bucket); if (!info_new.IsValid()) { // id_new may no longer map to a valid address erase_collision = true; - } else if (vvTried[tried_bucket][tried_bucket_pos] != -1) { // The position in the tried bucket is not empty + } else { + // A pending tried collision implies that the destination tried slot + // remains occupied until we resolve it. + Assume(vvTried[tried_bucket][tried_bucket_pos] != -1); // Get the to-be-evicted address that is being tested nid_type id_old = vvTried[tried_bucket][tried_bucket_pos]; @@ -939,9 +942,6 @@ void AddrManImpl::ResolveCollisions_() Good_(info_new, false, current_time); erase_collision = true; } - } else { // Collision is not actually a collision anymore - Good_(info_new, false, Now()); - erase_collision = true; } } @@ -977,6 +977,7 @@ std::pair AddrManImpl::SelectTriedCollision_() int tried_bucket = newInfo.GetTriedBucket(nKey, m_netgroupman); int tried_bucket_pos = newInfo.GetBucketPosition(nKey, false, tried_bucket); + Assume(vvTried[tried_bucket][tried_bucket_pos] != -1); const AddrInfo& info_old = mapInfo[vvTried[tried_bucket][tried_bucket_pos]]; return {info_old, info_old.m_last_try}; } diff --git a/src/addrman.h b/src/addrman.h index f7143386..70697f76 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -24,25 +23,25 @@ class NetGroupManager; /** Over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread */ -static constexpr uint32_t ADDRMAN_TRIED_BUCKETS_PER_GROUP{8}; +inline constexpr uint32_t ADDRMAN_TRIED_BUCKETS_PER_GROUP{8}; /** Over how many buckets entries with new addresses originating from a single group are spread */ -static constexpr uint32_t ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP{64}; +inline constexpr uint32_t ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP{64}; /** Maximum number of times an address can occur in the new table */ -static constexpr int32_t ADDRMAN_NEW_BUCKETS_PER_ADDRESS{8}; +inline constexpr int32_t ADDRMAN_NEW_BUCKETS_PER_ADDRESS{8}; /** How old addresses can maximally be */ -static constexpr auto ADDRMAN_HORIZON{30 * 24h}; +inline constexpr auto ADDRMAN_HORIZON{30 * 24h}; /** After how many failed attempts we give up on a new node */ -static constexpr int32_t ADDRMAN_RETRIES{3}; +inline constexpr int32_t ADDRMAN_RETRIES{3}; /** How many successive failures are allowed ... */ -static constexpr int32_t ADDRMAN_MAX_FAILURES{10}; +inline constexpr int32_t ADDRMAN_MAX_FAILURES{10}; /** ... in at least this duration */ -static constexpr auto ADDRMAN_MIN_FAIL{7 * 24h}; +inline constexpr auto ADDRMAN_MIN_FAIL{7 * 24h}; /** How recent a successful connection should be before we allow an address to be evicted from tried */ -static constexpr auto ADDRMAN_REPLACEMENT{4h}; +inline constexpr auto ADDRMAN_REPLACEMENT{4h}; /** The maximum number of tried addr collisions to store */ -static constexpr size_t ADDRMAN_SET_TRIED_COLLISION_SIZE{10}; +inline constexpr size_t ADDRMAN_SET_TRIED_COLLISION_SIZE{10}; /** The maximum time we'll spend trying to resolve a tried table collision */ -static constexpr auto ADDRMAN_TEST_WINDOW{40min}; +inline constexpr auto ADDRMAN_TEST_WINDOW{40min}; class InvalidAddrManVersionError : public std::ios_base::failure { @@ -54,7 +53,7 @@ class AddrManImpl; class AddrInfo; /** Default for -checkaddrman */ -static constexpr int32_t DEFAULT_ADDRMAN_CONSISTENCY_CHECKS{0}; +inline constexpr int32_t DEFAULT_ADDRMAN_CONSISTENCY_CHECKS{0}; /** Location information for an address in AddrMan */ struct AddressPosition { @@ -73,10 +72,7 @@ struct AddressPosition { const int bucket; const int position; - bool operator==(AddressPosition other) { - return std::tie(tried, multiplicity, bucket, position) == - std::tie(other.tried, other.multiplicity, other.bucket, other.position); - } + bool operator==(const AddressPosition&) const = default; explicit AddressPosition(bool tried_in, int multiplicity_in, int bucket_in, int position_in) : tried{tried_in}, multiplicity{multiplicity_in}, bucket{bucket_in}, position{position_in} {} }; diff --git a/src/addrman_impl.h b/src/addrman_impl.h index 88ee92e1..e6e2cab8 100644 --- a/src/addrman_impl.h +++ b/src/addrman_impl.h @@ -23,14 +23,14 @@ #include /** Total number of buckets for tried addresses */ -static constexpr int32_t ADDRMAN_TRIED_BUCKET_COUNT_LOG2{8}; -static constexpr int ADDRMAN_TRIED_BUCKET_COUNT{1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2}; +inline constexpr int32_t ADDRMAN_TRIED_BUCKET_COUNT_LOG2{8}; +inline constexpr int ADDRMAN_TRIED_BUCKET_COUNT{1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2}; /** Total number of buckets for new addresses */ -static constexpr int32_t ADDRMAN_NEW_BUCKET_COUNT_LOG2{10}; -static constexpr int ADDRMAN_NEW_BUCKET_COUNT{1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2}; +inline constexpr int32_t ADDRMAN_NEW_BUCKET_COUNT_LOG2{10}; +inline constexpr int ADDRMAN_NEW_BUCKET_COUNT{1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2}; /** Maximum allowed number of entries in buckets for new and tried addresses */ -static constexpr int32_t ADDRMAN_BUCKET_SIZE_LOG2{6}; -static constexpr int ADDRMAN_BUCKET_SIZE{1 << ADDRMAN_BUCKET_SIZE_LOG2}; +inline constexpr int32_t ADDRMAN_BUCKET_SIZE_LOG2{6}; +inline constexpr int ADDRMAN_BUCKET_SIZE{1 << ADDRMAN_BUCKET_SIZE_LOG2}; /** * User-defined type for the internally used nIds diff --git a/src/banman.h b/src/banman.h index 93149e63..815e2438 100644 --- a/src/banman.h +++ b/src/banman.h @@ -16,10 +16,10 @@ #include // NOTE: When adjusting this, update rpcnet:setban's help ("24h") -static constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban +inline constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban /// How often to dump banned addresses/subnets to disk. -static constexpr std::chrono::minutes DUMP_BANS_INTERVAL{15}; +inline constexpr std::chrono::minutes DUMP_BANS_INTERVAL{15}; class CClientUIInterface; class CNetAddr; diff --git a/src/bech32.h b/src/bech32.h index 9a43a58f..f16aa855 100644 --- a/src/bech32.h +++ b/src/bech32.h @@ -23,8 +23,8 @@ namespace bech32 { -static constexpr size_t CHECKSUM_SIZE = 6; -static constexpr char SEPARATOR = '1'; +inline constexpr size_t CHECKSUM_SIZE = 6; +inline constexpr char SEPARATOR = '1'; enum class Encoding { INVALID, //!< Failed decoding diff --git a/src/bench/CMakeLists.txt b/src/bench/CMakeLists.txt index 3c81e798..45ba7c40 100644 --- a/src/bench/CMakeLists.txt +++ b/src/bench/CMakeLists.txt @@ -52,6 +52,7 @@ add_executable(bench_bitcoin strencodings.cpp txgraph.cpp txorphanage.cpp + uint256_blob.cpp util_time.cpp verify_script.cpp ) diff --git a/src/bench/blockencodings.cpp b/src/bench/blockencodings.cpp index 274474d4..9759dd58 100644 --- a/src/bench/blockencodings.cpp +++ b/src/bench/blockencodings.cpp @@ -88,9 +88,7 @@ static void BlockEncodingBench(benchmark::Bench& bench, size_t n_pool, size_t n_ tx.vin.resize(1); tx.vin[0].scriptSig = CScript() << sigspam; tx.vin[0].scriptWitness.stack.push_back({1}); - tx.vout.resize(1); - tx.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; - tx.vout[0].nValue = i; + tx.vout = {CTxOut{CAmount(i), CScript() << OP_1 << OP_EQUAL}}; refs.push_back(MakeTransactionRef(tx)); } diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 5c54cafc..396d21d4 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -76,7 +76,7 @@ static void CoinSelection(benchmark::Bench& bench) // Create coins from the amounts assigning them various output types wallet::CoinsResult available_coins; for (const auto& wtx : wtxs) { - const auto txout = wtx->tx->vout.at(0); + const auto txout = wtx->GetTx()->vout.at(0); OutputType outtype; int input_bytes; int y{det_rand.randrange(100)}; diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp index 4d0660db..82744897 100644 --- a/src/bench/crypto_hash.cpp +++ b/src/bench/crypto_hash.cpp @@ -190,10 +190,10 @@ static void SHA512(benchmark::Bench& bench) }); } -static void SipHash_32b(benchmark::Bench& bench) +static void SipHash24_32b(benchmark::Bench& bench) { FastRandomContext rng{/*fDeterministic=*/true}; - PresaltedSipHasher presalted_sip_hasher(rng.rand64(), rng.rand64()); + PresaltedSipHasher presalted_sip_hasher{rng.rand64(), rng.rand64()}; auto val{rng.rand256()}; auto i{0U}; bench.run([&] { @@ -203,6 +203,49 @@ static void SipHash_32b(benchmark::Bench& bench) }); } +static void SipHash24_36b(benchmark::Bench& bench) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + PresaltedSipHasher presalted_sip_hasher{rng.rand64(), rng.rand64()}; + auto val{rng.rand256()}; + uint32_t extra{rng.rand32()}; + auto i{0U}; + bench.run([&] { + ankerl::nanobench::doNotOptimizeAway(presalted_sip_hasher(val, extra)); + ++i; + val.data()[i % uint256::size()] ^= i & 0xFF; + extra += i; + }); +} + +static void SipHash13UJ_32b(benchmark::Bench& bench) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + SipHasher13UJ sip_hasher{rng.rand64(), rng.rand64()}; + auto val{rng.rand256()}; + auto i{0U}; + bench.run([&] { + ankerl::nanobench::doNotOptimizeAway(sip_hasher.Hash(val)); + ++i; + val.data()[i % uint256::size()] ^= i & 0xFF; + }); +} + +static void SipHash13UJ_36b(benchmark::Bench& bench) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + SipHasher13UJ sip_hasher{rng.rand64(), rng.rand64()}; + auto val{rng.rand256()}; + uint32_t extra{rng.rand32()}; + auto i{0U}; + bench.run([&] { + ankerl::nanobench::doNotOptimizeAway(sip_hasher.Hash(val, uint64_t{extra})); + ++i; + val.data()[i % uint256::size()] ^= i & 0xFF; + extra += i; + }); +} + static void MuHash(benchmark::Bench& bench) { MuHash3072 acc; @@ -273,7 +316,10 @@ BENCHMARK(SHA256_32b_STANDARD); BENCHMARK(SHA256_32b_SSE4); BENCHMARK(SHA256_32b_AVX2); BENCHMARK(SHA256_32b_SHANI); -BENCHMARK(SipHash_32b); +BENCHMARK(SipHash24_32b); +BENCHMARK(SipHash24_36b); +BENCHMARK(SipHash13UJ_32b); +BENCHMARK(SipHash13UJ_36b); BENCHMARK(SHA256D64_1024_STANDARD); BENCHMARK(SHA256D64_1024_SSE4); BENCHMARK(SHA256D64_1024_AVX2); diff --git a/src/bench/mempool_ephemeral_spends.cpp b/src/bench/mempool_ephemeral_spends.cpp index f88643c5..d7c08724 100644 --- a/src/bench/mempool_ephemeral_spends.cpp +++ b/src/bench/mempool_ephemeral_spends.cpp @@ -50,9 +50,8 @@ static void MempoolCheckEphemeralSpends(benchmark::Bench& bench) tx1.vin.resize(1); tx1.vout.resize(number_outputs); for (size_t i = 0; i < tx1.vout.size(); i++) { - tx1.vout[i].scriptPubKey = CScript(); // Each output progressively larger - tx1.vout[i].nValue = i * CENT; + tx1.vout[i] = CTxOut{CAmount(i) * CENT, CScript()}; } const auto& parent_txid = tx1.GetHash(); @@ -60,9 +59,8 @@ static void MempoolCheckEphemeralSpends(benchmark::Bench& bench) // Spends all outputs of tx1, other details don't matter CMutableTransaction tx2; tx2.vin.resize(tx1.vout.size()); - for (size_t i = 0; i < tx2.vin.size(); i++) { - tx2.vin[i].prevout.hash = parent_txid; - tx2.vin[i].prevout.n = i; + for (uint32_t i{0}; i < tx2.vin.size(); ++i) { + tx2.vin[i].prevout = COutPoint{parent_txid, i}; } tx2.vout.resize(1); diff --git a/src/bench/mempool_stress.cpp b/src/bench/mempool_stress.cpp index ab1146e1..1d227070 100644 --- a/src/bench/mempool_stress.cpp +++ b/src/bench/mempool_stress.cpp @@ -156,7 +156,7 @@ static void ComplexMemPool(benchmark::Bench& bench) // in the same state at the end of the function, so we benchmark both // mining a block and reorging the block's contents back into the mempool. bench.run([&]() NO_THREAD_SAFETY_ANALYSIS { - pool.removeForBlock(tx_remove_for_block, /*nBlockHeight=*/100); + pool.removeForBlock(tx_remove_for_block); for (auto& tx: tx_remove_for_block) { AddTx(tx, pool, det_rand); } diff --git a/src/bench/nanobench.h b/src/bench/nanobench.h index a66e92a4..ffcc4802 100644 --- a/src/bench/nanobench.h +++ b/src/bench/nanobench.h @@ -1369,6 +1369,7 @@ void doNotOptimizeAway(T const& val) { } // namespace ankerl #if defined(ANKERL_NANOBENCH_IMPLEMENT) +// NOLINTBEGIN(misc-definitions-in-headers) /////////////////////////////////////////////////////////////////////////////////////////////////// // implementation part - only visible in .cpp @@ -3563,5 +3564,6 @@ std::ostream& operator<<(std::ostream& os, std::vector } // namespace nanobench } // namespace ankerl +// NOLINTEND(misc-definitions-in-headers) #endif // ANKERL_NANOBENCH_IMPLEMENT #endif // ANKERL_NANOBENCH_H_INCLUDED diff --git a/src/bench/uint256_blob.cpp b/src/bench/uint256_blob.cpp new file mode 100644 index 00000000..fba0a0e8 --- /dev/null +++ b/src/bench/uint256_blob.cpp @@ -0,0 +1,91 @@ +// Copyright (c) The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://opensource.org/license/mit. + +#include +#include +#include + +#include +#include +#include +#include + +namespace { + +enum class Difference { + NONE, + FIRST_BYTE, + LAST_BYTE, +}; + +constexpr size_t NUM_PAIRS{4'096}; + +std::vector> MakePairs(Difference difference) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + std::vector> pairs; + pairs.reserve(NUM_PAIRS); + + for (size_t i{0}; i < NUM_PAIRS; ++i) { + uint256 lhs{rng.rand256()}; + uint256 rhs{lhs}; + if (difference != Difference::NONE) { + const size_t position{difference == Difference::FIRST_BYTE ? 0 : uint256::size() - 1}; + lhs.begin()[position] = i % 2 == 0 ? 0 : 255; + rhs.begin()[position] = i % 2 == 0 ? 255 : 0; + } + pairs.emplace_back(lhs, rhs); + } + return pairs; +} + +template +void Comparison(benchmark::Bench& bench, Difference difference, Comparator comparator) +{ + const auto pairs{MakePairs(difference)}; + bench.batch(pairs.size()).unit("comparison").run([&] { + for (const auto& [lhs, rhs] : pairs) { + ankerl::nanobench::doNotOptimizeAway(comparator(lhs, rhs)); + } + }); +} + +void Uint256EqualIdentical(benchmark::Bench& bench) +{ + Comparison(bench, Difference::NONE, [](const uint256& lhs, const uint256& rhs) { return lhs == rhs; }); +} + +void Uint256EqualFirstByteDifferent(benchmark::Bench& bench) +{ + Comparison(bench, Difference::FIRST_BYTE, [](const uint256& lhs, const uint256& rhs) { return lhs == rhs; }); +} + +void Uint256EqualLastByteDifferent(benchmark::Bench& bench) +{ + Comparison(bench, Difference::LAST_BYTE, [](const uint256& lhs, const uint256& rhs) { return lhs == rhs; }); +} + +void Uint256LessIdentical(benchmark::Bench& bench) +{ + Comparison(bench, Difference::NONE, [](const uint256& lhs, const uint256& rhs) { return lhs < rhs; }); +} + +void Uint256LessFirstByteDifferent(benchmark::Bench& bench) +{ + Comparison(bench, Difference::FIRST_BYTE, [](const uint256& lhs, const uint256& rhs) { return lhs < rhs; }); +} + +void Uint256LessLastByteDifferent(benchmark::Bench& bench) +{ + Comparison(bench, Difference::LAST_BYTE, [](const uint256& lhs, const uint256& rhs) { return lhs < rhs; }); +} + +} // namespace + +BENCHMARK(Uint256EqualIdentical); +BENCHMARK(Uint256EqualFirstByteDifferent); +BENCHMARK(Uint256EqualLastByteDifferent); +BENCHMARK(Uint256LessIdentical); +BENCHMARK(Uint256LessFirstByteDifferent); +BENCHMARK(Uint256LessLastByteDifferent); diff --git a/src/bip324.h b/src/bip324.h index 821cc3f7..276f71e4 100644 --- a/src/bip324.h +++ b/src/bip324.h @@ -15,7 +15,7 @@ #include #include -static constexpr unsigned BIP324_SHORTIDS_IMPLEMENTED{38}; +inline constexpr unsigned BIP324_SHORTIDS_IMPLEMENTED{38}; /** The BIP324 packet cipher, encapsulating its key derivation, stream cipher, and AEAD. */ class BIP324Cipher diff --git a/src/bitcoin-util.cpp b/src/bitcoin-util.cpp index f17c7a0d..7e774685 100644 --- a/src/bitcoin-util.cpp +++ b/src/bitcoin-util.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,7 @@ static void SetupBitcoinUtilArgs(ArgsManager &argsman) argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddCommand("grind", "Perform proof of work on hex header string"); - argsman.AddCommand("netmagic", "Get the network magic bytes of the selected chain"); + argsman.AddCommand("getchainparams", "Get hardcoded parameters for the selected chain"); SetupChainParamsBaseOptions(argsman); } @@ -151,14 +152,60 @@ static int Grind(const std::vector& args, std::string& strPrint) return EXIT_SUCCESS; } -static int NetMagic(const std::vector& args, std::string& strPrint) +static int GetChainParams(const std::vector& args, std::string& strPrint) { if (!args.empty()) { - strPrint = "netmagic does not take arguments"; + strPrint = "getchainparams does not take arguments"; return EXIT_FAILURE; } - strPrint = HexStr(Params().MessageStart()); + const auto& params = Params(); + const auto& consensus = params.GetConsensus(); + + UniValue result{UniValue::VOBJ}; + result.pushKV("chain", params.GetChainTypeString()); + result.pushKV("test_chain", params.IsTestChain()); + result.pushKV("genesis", HexStr(consensus.hashGenesisBlock)); + result.pushKV("subsidy_halving_interval", consensus.nSubsidyHalvingInterval); + + if (consensus.signet_blocks) { + UniValue signet{UniValue::VOBJ}; + signet.pushKV("challenge", HexStr(consensus.signet_challenge)); + result.pushKV("signet", signet); + } + + { + UniValue pow{UniValue::VOBJ}; + pow.pushKV("limit", consensus.powLimit.ToString()); + if (!consensus.fPowNoRetargeting) { + pow.pushKV("target_spacing", TicksSeconds(consensus.PowTargetSpacing())); + pow.pushKV("difficulty_retarget_interval", consensus.DifficultyAdjustmentInterval()); + std::string mindiff_blocks = (consensus.fPowAllowMinDifficultyBlocks ? + (consensus.enforce_BIP94 ? "bip94" : "yes") : "no"); + pow.pushKV("mindiff_blocks", mindiff_blocks); + } + result.pushKV("pow", pow); + } + + { + UniValue net{UniValue::VOBJ}; + net.pushKV("default_port", params.GetDefaultPort()); + net.pushKV("magic", HexStr(params.MessageStart())); + UniValue dns{UniValue::VARR}; + for (const auto& seed : params.DNSSeeds()) { + dns.push_back(seed); + } + net.pushKV("dns_seeds", dns); + result.pushKV("net", net); + } + + { + UniValue addr{UniValue::VOBJ}; + addr.pushKV("bech32_hrp", params.Bech32HRP()); + result.pushKV("addresses", addr); + } + + strPrint = result.write(/*prettyIndent=*/2); return EXIT_SUCCESS; } @@ -191,8 +238,8 @@ MAIN_FUNCTION try { if (cmd->command == "grind") { ret = Grind(cmd->args, strPrint); - } else if (cmd->command == "netmagic") { - ret = NetMagic(cmd->args, strPrint); + } else if (cmd->command == "getchainparams") { + ret = GetChainParams(cmd->args, strPrint); } else { assert(false); // unknown command should be caught earlier } diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index c2846539..afa9df4f 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -113,25 +113,25 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c if (shorttxids.size() != cmpctblock.shorttxids.size()) return READ_STATUS_FAILED; // Short ID collision - std::vector have_txn(txn_available.size()); + enum class TxSource : uint8_t { NONE, MEMPOOL, EXTRA, COLLIDED }; + std::vector tx_source(txn_available.size(), TxSource::NONE); { LOCK(pool->cs); for (const auto& [wtxid, txit] : pool->txns_randomized) { uint64_t shortid = cmpctblock.GetShortID(wtxid); std::unordered_map::iterator idit = shorttxids.find(shortid); if (idit != shorttxids.end()) { - if (!have_txn[idit->second]) { + if (tx_source[idit->second] == TxSource::NONE) { txn_available[idit->second] = txit->GetSharedTx(); - have_txn[idit->second] = true; + tx_source[idit->second] = TxSource::MEMPOOL; mempool_count++; - } else { + } else if (tx_source[idit->second] != TxSource::COLLIDED) { // If we find two mempool txn that match the short id, just request it. // This should be rare enough that the extra bandwidth doesn't matter, // but eating a round-trip due to FillBlock failure would be annoying - if (txn_available[idit->second]) { - txn_available[idit->second].reset(); - mempool_count--; - } + txn_available[idit->second].reset(); + mempool_count--; + tx_source[idit->second] = TxSource::COLLIDED; } } // Though ideally we'd continue scanning for the two-txn-match-shortid case, @@ -146,24 +146,23 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c uint64_t shortid = cmpctblock.GetShortID(extra_txn[i].first); std::unordered_map::iterator idit = shorttxids.find(shortid); if (idit != shorttxids.end()) { - if (!have_txn[idit->second]) { + if (tx_source[idit->second] == TxSource::NONE) { txn_available[idit->second] = extra_txn[i].second; - have_txn[idit->second] = true; + tx_source[idit->second] = TxSource::EXTRA; mempool_count++; extra_count++; - } else { + } else if (tx_source[idit->second] != TxSource::COLLIDED && + txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) { // If we find two mempool/extra txn that match the short id, just // request it. // This should be rare enough that the extra bandwidth doesn't matter, // but eating a round-trip due to FillBlock failure would be annoying // Note that we don't want duplication between extra_txn and mempool to // trigger this case, so we compare witness hashes first - if (txn_available[idit->second] && - txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) { - txn_available[idit->second].reset(); - mempool_count--; - extra_count--; - } + txn_available[idit->second].reset(); + mempool_count--; + extra_count -= (tx_source[idit->second] == TxSource::EXTRA); + tx_source[idit->second] = TxSource::COLLIDED; } } // Though ideally we'd continue scanning for the two-txn-match-shortid case, diff --git a/src/blockfilter.h b/src/blockfilter.h index 225d3b16..26ddfb61 100644 --- a/src/blockfilter.h +++ b/src/blockfilter.h @@ -87,8 +87,8 @@ class GCSFilter bool MatchAny(const ElementSet& elements) const; }; -constexpr uint8_t BASIC_FILTER_P = 19; -constexpr uint32_t BASIC_FILTER_M = 784931; +inline constexpr uint8_t BASIC_FILTER_P = 19; +inline constexpr uint32_t BASIC_FILTER_M = 784931; enum class BlockFilterType : uint8_t { diff --git a/src/chain.h b/src/chain.h index 7701e926..1ca21845 100644 --- a/src/chain.h +++ b/src/chain.h @@ -26,7 +26,7 @@ * Maximum amount of time that a block timestamp is allowed to exceed the * current time before the block will be accepted. */ -static constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; +inline constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; /** * Timestamp window used as a grace period by code that compares external @@ -34,10 +34,10 @@ static constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; * to block timestamps. This should be set at least as high as * MAX_FUTURE_BLOCK_TIME. */ -static constexpr int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME; +inline constexpr int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME; //! Init values for CBlockIndex nSequenceId when loaded from disk -static constexpr int32_t SEQ_ID_BEST_CHAIN_FROM_DISK = 0; -static constexpr int32_t SEQ_ID_INIT_FROM_DISK = 1; +inline constexpr int32_t SEQ_ID_BEST_CHAIN_FROM_DISK = 0; +inline constexpr int32_t SEQ_ID_INIT_FROM_DISK = 1; enum BlockStatus : uint32_t { //! Unused. diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 5cf8d6ba..729d7050 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -10,7 +10,7 @@ * * Each line contains a BIP155 serialized (networkID, addr, port) tuple. */ -static const uint8_t chainparams_seed_main[] = { +inline constexpr uint8_t chainparams_seed_main[] = { 0x06,0x10,0xfc,0x11,0xf7,0x69,0x16,0xe6,0x36,0x11,0x58,0xae,0x1d,0x4a,0xfc,0xf7,0x57,0xa4,0x20,0x8d, 0x06,0x10,0xfc,0x17,0x43,0x69,0x54,0x14,0x4b,0x1f,0x56,0x89,0xd3,0xed,0x40,0x39,0x33,0x5c,0x20,0x8d, 0x06,0x10,0xfc,0x1f,0x22,0xc3,0x95,0xdc,0xa3,0xaf,0x4a,0x93,0x82,0x51,0xbe,0xb9,0x18,0x58,0x20,0x8d, @@ -2072,7 +2072,7 @@ static const uint8_t chainparams_seed_main[] = { 0x04,0x20,0xce,0x07,0x95,0xf3,0xa5,0xc1,0x90,0xc4,0x50,0xd5,0x22,0x86,0xa7,0x26,0x37,0x08,0xa2,0x31,0x1e,0x0d,0x77,0x48,0x0d,0x46,0xe0,0xfb,0x3d,0x71,0x60,0xe7,0x1d,0xce,0x20,0x8d, }; -static const uint8_t chainparams_seed_signet[] = { +inline constexpr uint8_t chainparams_seed_signet[] = { 0x06,0x10,0xfc,0x1f,0x22,0xc3,0x95,0xdc,0xa3,0xaf,0x4a,0x93,0x82,0x51,0xbe,0xb9,0x18,0x58,0x95,0xbd, 0x05,0x20,0xd7,0x4d,0xd9,0xc4,0x7c,0x80,0x24,0x1d,0x48,0x2f,0x52,0xba,0x2a,0xaf,0x5d,0xf2,0xfc,0x04,0x58,0x56,0x4a,0x61,0x0f,0xde,0x4e,0xd8,0x13,0x55,0x98,0x55,0x53,0xc1,0x00,0x00, 0x05,0x20,0xd8,0xaf,0x32,0x40,0x0d,0x25,0x72,0x91,0xf5,0x14,0x2a,0xa7,0x7b,0x9f,0x6b,0xe8,0x02,0x9f,0x16,0x5e,0xa0,0xe0,0x6d,0x85,0xcc,0x79,0xf2,0xe2,0xc1,0x2b,0xe0,0x20,0x00,0x00, @@ -2245,7 +2245,7 @@ static const uint8_t chainparams_seed_signet[] = { 0x04,0x20,0xc9,0x95,0x5a,0xf7,0x9a,0x27,0x09,0x6a,0xa2,0x24,0x65,0xb7,0x07,0xf0,0x28,0xee,0x8b,0xa9,0x5e,0x7c,0x37,0x19,0x14,0xc4,0x36,0x73,0x42,0xd2,0x87,0xae,0xa2,0x47,0x95,0xbd, }; -static const uint8_t chainparams_seed_test[] = { +inline constexpr uint8_t chainparams_seed_test[] = { 0x06,0x10,0xfc,0x1f,0x22,0xc3,0x95,0xdc,0xa3,0xaf,0x4a,0x93,0x82,0x51,0xbe,0xb9,0x18,0x58,0x47,0x9d, 0x05,0x20,0x39,0x06,0xc0,0x95,0x12,0xe1,0xf8,0x86,0xc2,0x36,0x76,0xa9,0x96,0x2a,0x9d,0xbd,0x3d,0x70,0x43,0xfc,0x99,0xbf,0x27,0x15,0xa4,0x9c,0x10,0xa1,0xd5,0xa3,0x9d,0x52,0x00,0x00, 0x05,0x20,0x40,0x81,0xae,0x55,0xb2,0x9d,0xd0,0xff,0x99,0x51,0xd8,0xbc,0x35,0xb2,0x06,0xb7,0x1c,0xf6,0x16,0x35,0xae,0xc6,0xf7,0xa4,0x72,0xf8,0x37,0x41,0x8e,0x91,0x7b,0x2e,0x00,0x00, @@ -2429,7 +2429,7 @@ static const uint8_t chainparams_seed_test[] = { 0x04,0x20,0xcc,0x99,0x76,0x52,0x43,0xcc,0x45,0x0a,0x49,0x5d,0x3f,0xa5,0x82,0xc3,0xc0,0xdb,0xcf,0xe5,0xda,0xfb,0xb3,0xd0,0xb9,0xd1,0xbc,0x1b,0x15,0x19,0xed,0xe0,0xd1,0x5f,0x47,0x9d, }; -static const uint8_t chainparams_seed_testnet4[] = { +inline constexpr uint8_t chainparams_seed_testnet4[] = { 0x06,0x10,0xfc,0x1f,0x22,0xc3,0x95,0xdc,0xa3,0xaf,0x4a,0x93,0x82,0x51,0xbe,0xb9,0x18,0x58,0xbc,0xcd, 0x05,0x20,0xd3,0xbc,0x25,0x95,0x63,0x7f,0x34,0x02,0x18,0x69,0x91,0x9a,0x79,0x57,0x10,0xc0,0xe0,0xf5,0xcd,0x84,0x56,0x95,0xec,0x43,0xa4,0x9d,0xba,0x1b,0xb3,0xea,0x34,0x60,0x00,0x00, 0x05,0x20,0xd8,0xee,0x64,0x35,0x6c,0x53,0xe7,0x40,0xb8,0xc3,0x15,0x60,0x5b,0x9c,0x66,0x3d,0xbb,0xd9,0x7c,0x99,0xcc,0x3a,0x3a,0xf6,0xcb,0xd5,0xd4,0x51,0x98,0x04,0x68,0xad,0x00,0x00, diff --git a/src/clientversion.h b/src/clientversion.h index f4822a12..cbdb62b2 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -23,7 +23,7 @@ #include #include -static const int CLIENT_VERSION = +inline constexpr int CLIENT_VERSION = 10000 * CLIENT_VERSION_MAJOR + 100 * CLIENT_VERSION_MINOR + 1 * CLIENT_VERSION_BUILD; diff --git a/src/cluster_linearize.h b/src/cluster_linearize.h index 23cb98f4..7b262edb 100644 --- a/src/cluster_linearize.h +++ b/src/cluster_linearize.h @@ -954,11 +954,16 @@ class SpanningForestState Assume(m_chunk_idxs[bottom_idx]); auto& top_chunk_info = m_set_info[top_idx]; auto& bottom_chunk_info = m_set_info[bottom_idx]; - // Count the number of dependencies between bottom_chunk and top_chunk. + // Count the number of dependencies between bottom_chunk and top_chunk, remembering the + // per-transaction counts so the picking loop below does not need to recompute the + // intersections. unsigned num_deps{0}; + std::array counts; for (auto tx_idx : top_chunk_info.transactions) { auto& tx_data = m_tx_data[tx_idx]; - num_deps += (tx_data.children & bottom_chunk_info.transactions).Count(); + auto count = (tx_data.children & bottom_chunk_info.transactions).Count(); + counts[tx_idx] = count; + num_deps += count; } m_cost.MergeChunksMid(/*num_txns=*/top_chunk_info.transactions.Count()); Assume(num_deps > 0); @@ -967,10 +972,10 @@ class SpanningForestState unsigned num_steps = 0; for (auto tx_idx : top_chunk_info.transactions) { ++num_steps; - auto& tx_data = m_tx_data[tx_idx]; - auto intersect = tx_data.children & bottom_chunk_info.transactions; - auto count = intersect.Count(); + auto count = counts[tx_idx]; if (pick < count) { + auto& tx_data = m_tx_data[tx_idx]; + auto intersect = tx_data.children & bottom_chunk_info.transactions; for (auto child_idx : intersect) { if (pick == 0) { m_cost.MergeChunksEnd(/*num_steps=*/num_steps); @@ -1183,6 +1188,7 @@ class SpanningForestState m_tx_data.resize(depgraph.PositionRange()); m_set_info.resize(num_transactions); m_reachable.resize(num_transactions); + m_suboptimal_chunks.reserve(num_transactions); size_t num_chunks = 0; size_t num_deps = 0; for (auto tx_idx : m_transaction_idxs) { @@ -1471,16 +1477,22 @@ class SpanningForestState /** A heap with all chunks (by set index) that can currently be included, sorted by * chunk feerate (high to low), chunk size (small to large), and by least maximum element * according to the fallback order (which is the second pair element). */ - std::vector> ready_chunks; + std::array, SetType::Size()> ready_chunks; + /** The number of entries of ready_chunks in use. */ + unsigned num_ready_chunks{0}; /** For every chunk, indexed by SetIdx, the number of unmet dependencies the chunk has on * other chunks (not including dependencies within the chunk itself). */ - std::vector chunk_deps(m_set_info.size(), 0); + std::array chunk_deps; + std::fill_n(chunk_deps.begin(), m_set_info.size(), TxIdx{0}); /** For every transaction, indexed by TxIdx, the number of unmet dependencies the * transaction has. */ - std::vector tx_deps(m_tx_data.size(), 0); + std::array tx_deps; + std::fill_n(tx_deps.begin(), m_tx_data.size(), TxIdx{0}); /** A heap with all transactions within the current chunk that can be included, sorted by * tx feerate (high to low), tx size (small to large), and fallback order. */ - std::vector ready_tx; + std::array ready_tx; + /** The number of entries of ready_tx in use. */ + unsigned num_ready_tx{0}; // Populate chunk_deps and tx_deps. unsigned num_deps{0}; for (TxIdx chl_idx : m_transaction_idxs) { @@ -1549,31 +1561,31 @@ class SpanningForestState // Construct a heap with all chunks that have no out-of-chunk dependencies. for (SetIdx chunk_idx : m_chunk_idxs) { if (chunk_deps[chunk_idx] == 0) { - ready_chunks.emplace_back(chunk_idx, max_fallback_fn(chunk_idx)); + ready_chunks[num_ready_chunks++] = {chunk_idx, max_fallback_fn(chunk_idx)}; } } - std::make_heap(ready_chunks.begin(), ready_chunks.end(), chunk_cmp_fn); + std::make_heap(ready_chunks.begin(), ready_chunks.begin() + num_ready_chunks, chunk_cmp_fn); // Pop chunks off the heap. - while (!ready_chunks.empty()) { + while (num_ready_chunks > 0) { auto [chunk_idx, _rnd] = ready_chunks.front(); - std::pop_heap(ready_chunks.begin(), ready_chunks.end(), chunk_cmp_fn); - ready_chunks.pop_back(); + std::pop_heap(ready_chunks.begin(), ready_chunks.begin() + num_ready_chunks, chunk_cmp_fn); + --num_ready_chunks; Assume(chunk_deps[chunk_idx] == 0); const auto& chunk_txn = m_set_info[chunk_idx].transactions; // Build heap of all includable transactions in chunk. - Assume(ready_tx.empty()); + Assume(num_ready_tx == 0); for (TxIdx tx_idx : chunk_txn) { - if (tx_deps[tx_idx] == 0) ready_tx.push_back(tx_idx); + if (tx_deps[tx_idx] == 0) ready_tx[num_ready_tx++] = tx_idx; } - Assume(!ready_tx.empty()); - std::make_heap(ready_tx.begin(), ready_tx.end(), tx_cmp_fn); + Assume(num_ready_tx > 0); + std::make_heap(ready_tx.begin(), ready_tx.begin() + num_ready_tx, tx_cmp_fn); // Pick transactions from the ready heap, append them to linearization, and decrement // dependency counts. - while (!ready_tx.empty()) { + while (num_ready_tx > 0) { // Pop an element from the tx_ready heap. auto tx_idx = ready_tx.front(); - std::pop_heap(ready_tx.begin(), ready_tx.end(), tx_cmp_fn); - ready_tx.pop_back(); + std::pop_heap(ready_tx.begin(), ready_tx.begin() + num_ready_tx, tx_cmp_fn); + --num_ready_tx; // Append to linearization. ret.push_back(tx_idx); // Decrement dependency counts. @@ -1584,16 +1596,16 @@ class SpanningForestState Assume(tx_deps[chl_idx] > 0); if (--tx_deps[chl_idx] == 0 && chunk_txn[chl_idx]) { // Child tx has no dependencies left, and is in this chunk. Add it to the tx heap. - ready_tx.push_back(chl_idx); - std::push_heap(ready_tx.begin(), ready_tx.end(), tx_cmp_fn); + ready_tx[num_ready_tx++] = chl_idx; + std::push_heap(ready_tx.begin(), ready_tx.begin() + num_ready_tx, tx_cmp_fn); } // Decrement chunk dependency count if this is out-of-chunk dependency. if (chl_data.chunk_idx != chunk_idx) { Assume(chunk_deps[chl_data.chunk_idx] > 0); if (--chunk_deps[chl_data.chunk_idx] == 0) { // Child chunk has no dependencies left. Add it to the chunk heap. - ready_chunks.emplace_back(chl_data.chunk_idx, max_fallback_fn(chl_data.chunk_idx)); - std::push_heap(ready_chunks.begin(), ready_chunks.end(), chunk_cmp_fn); + ready_chunks[num_ready_chunks++] = {chl_data.chunk_idx, max_fallback_fn(chl_data.chunk_idx)}; + std::push_heap(ready_chunks.begin(), ready_chunks.begin() + num_ready_chunks, chunk_cmp_fn); } } } diff --git a/src/coins.cpp b/src/coins.cpp index 7bb05f68..3d3e63fa 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -19,6 +19,13 @@ TRACEPOINT_SEMAPHORE(utxocache, add); TRACEPOINT_SEMAPHORE(utxocache, spent); TRACEPOINT_SEMAPHORE(utxocache, uncache); +SaltedCoinsCacheHasher::SaltedCoinsCacheHasher(bool deterministic) + : m_hasher{ + deterministic ? 0x8e819f2607a18de6 : FastRandomContext().rand64(), + deterministic ? 0xf4020d2e3983b0eb : FastRandomContext().rand64()} +{ +} + CoinsViewEmpty& CoinsViewEmpty::Get() { static CoinsViewEmpty instance; @@ -35,7 +42,7 @@ std::optional CCoinsViewCache::PeekCoin(const COutPoint& outpoint) const CCoinsViewCache::CCoinsViewCache(CCoinsView* in_base, bool deterministic) : CCoinsViewBacked(in_base), m_deterministic(deterministic), - cacheCoins(0, SaltedOutpointHasher(/*deterministic=*/deterministic), CCoinsMap::key_equal{}, &m_cache_coins_memory_resource) + cacheCoins(0, SaltedCoinsCacheHasher{/*deterministic=*/deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource) { m_sentinel.second.SelfRef(m_sentinel); } @@ -113,9 +120,9 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi (bool)it->second.coin.IsCoinBase()); } -void CCoinsViewCache::EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coin) { +void CCoinsViewCache::EmplaceCoinInternalDANGER(const COutPoint& outpoint, Coin&& coin) { const auto mem_usage{coin.DynamicMemoryUsage()}; - auto [it, inserted] = cacheCoins.try_emplace(std::move(outpoint), std::move(coin)); + auto [it, inserted] = cacheCoins.try_emplace(outpoint, std::move(coin)); if (inserted) { CCoinsCacheEntry::SetDirty(*it, m_sentinel); ++m_dirty_count; @@ -331,7 +338,7 @@ void CCoinsViewCache::ReallocateCache() cacheCoins.~CCoinsMap(); m_cache_coins_memory_resource.~CCoinsMapMemoryResource(); ::new (&m_cache_coins_memory_resource) CCoinsMapMemoryResource{}; - ::new (&cacheCoins) CCoinsMap{0, SaltedOutpointHasher{/*deterministic=*/m_deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource}; + ::new (&cacheCoins) CCoinsMap{0, SaltedCoinsCacheHasher{/*deterministic=*/m_deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource}; } void CCoinsViewCache::SanityCheck() const @@ -376,7 +383,7 @@ CCoinsViewCache::ResetGuard CoinsViewOverlay::StartFetching(const CBlock& block // Loop through the block inputs and set their prevouts in the queue. // Filter inputs that spend outputs created earlier in the same block. These outputs will be created // directly in the cache from the tx that creates them, so they will not be requested from a base view. - std::unordered_set earlier_txids; + std::unordered_set earlier_txids; earlier_txids.reserve(block.vtx.size()); for (const auto& tx : block.vtx | std::views::drop(1)) { for (const auto& input : tx->vin) { diff --git a/src/coins.h b/src/coins.h index 6e8643cc..6fcf1092 100644 --- a/src/coins.h +++ b/src/coins.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,6 @@ #include #include #include -#include #include #include @@ -219,6 +219,43 @@ struct CCoinsCacheEntry } }; +/** + * SipHash-1-3-UJ based hasher for the coins cache and related coins containers. + * + * Retained entries identify real transaction outputs, so their keys contain computed txids. + * Missing-input lookups may contain arbitrary claimed prevouts, but FetchCoin() immediately + * erases their temporary entries when the backend lookup fails, so non-hash keys cannot + * accumulate. + * + * The assumeutxo loader assumes snapshot txids are valid while loading and verifies the + * complete snapshot's content hash before activation. + * + * Hash values are process-local and must not be persisted, serialized, or compared across + * processes. + * + * Having the hash noexcept lets libstdc++ recalculate it during rehash instead of storing it in + * each node. + */ +class SaltedCoinsCacheHasher +{ + const SipHasher13UJ m_hasher; + +public: + SaltedCoinsCacheHasher(bool deterministic = false); + + /** Hash a transaction ID, itself a cryptographic hash, as one jumbo block. */ + size_t operator()(const Txid& id) const noexcept + { + return m_hasher.Hash(id.ToUint256()); + } + + /** Hash an outpoint as its txid jumbo block followed by the zero-extended index as one normal block. */ + size_t operator()(const COutPoint& id) const noexcept + { + return m_hasher.Hash(id.hash.ToUint256(), uint64_t{id.n}); + } +}; + /** * PoolAllocator's MAX_BLOCK_SIZE_BYTES parameter here uses sizeof the data, and adds the size * of 4 pointers. We do not know the exact node size used in the std::unordered_node implementation @@ -229,7 +266,7 @@ struct CCoinsCacheEntry */ using CCoinsMap = std::unordered_map, PoolAllocator>; @@ -401,6 +438,19 @@ class CCoinsViewCache : public CCoinsViewBacked private: const bool m_deterministic; + //! Force a reallocation of the cache map. This is required when downsizing + //! the cache because the map's allocator may be hanging onto a lot of + //! memory despite having called .clear(). + //! + //! See: https://stackoverflow.com/questions/42114044/how-to-release-unordered-map-memory + void ReallocateCache(); + + /** + * @note this is marked const, but may actually append to `cacheCoins`, increasing + * memory usage. + */ + CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const; + protected: /** * Make mutable so that we can "fill the cache" even from Get-methods @@ -474,7 +524,7 @@ class CCoinsViewCache : public CCoinsViewBacked * NOT FOR GENERAL USE. Used only when loading coins from a UTXO snapshot. * @sa ChainstateManager::PopulateAndValidateSnapshot() */ - void EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coin); + void EmplaceCoinInternalDANGER(const COutPoint& outpoint, Coin&& coin); /** * Spend a coin. Pass moveto in order to get the deleted data. @@ -518,13 +568,6 @@ class CCoinsViewCache : public CCoinsViewBacked //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view bool HaveInputs(const CTransaction& tx) const; - //! Force a reallocation of the cache map. This is required when downsizing - //! the cache because the map's allocator may be hanging onto a lot of - //! memory despite having called .clear(). - //! - //! See: https://stackoverflow.com/questions/42114044/how-to-release-unordered-map-memory - void ReallocateCache(); - //! Run an internal sanity check on the cache data structure. */ void SanityCheck() const; @@ -546,13 +589,6 @@ class CCoinsViewCache : public CCoinsViewBacked //! Create a scoped guard that will call `Reset()` on this cache when it goes out of scope. [[nodiscard]] ResetGuard CreateResetGuard() noexcept { return ResetGuard{*this}; } - -private: - /** - * @note this is marked const, but may actually append to `cacheCoins`, increasing - * memory usage. - */ - CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const; }; /** diff --git a/src/common/args.cpp b/src/common/args.cpp index cfd36e1f..97b37eb4 100644 --- a/src/common/args.cpp +++ b/src/common/args.cpp @@ -23,8 +23,6 @@ #endif #include -#include -#include #include #include #include diff --git a/src/common/args.h b/src/common/args.h index 0a3195f8..0a83e143 100644 --- a/src/common/args.h +++ b/src/common/args.h @@ -6,7 +6,6 @@ #define BITCOIN_COMMON_ARGS_H #include -#include #include #include #include diff --git a/src/common/bloom.cpp b/src/common/bloom.cpp index 3ee78994..c15c8f78 100644 --- a/src/common/bloom.cpp +++ b/src/common/bloom.cpp @@ -16,8 +16,7 @@ #include #include -#include -#include +#include #include static constexpr double LN2SQUARED = 0.4804530139182014246671025263266649717305529515945455; diff --git a/src/common/bloom.h b/src/common/bloom.h index 97007e1f..18399bd8 100644 --- a/src/common/bloom.h +++ b/src/common/bloom.h @@ -6,16 +6,17 @@ #define BITCOIN_COMMON_BLOOM_H #include -#include +#include +#include #include class COutPoint; class CTransaction; //! 20,000 items with fp rate < 0.1% or 10,000 items and <0.0001% -static constexpr unsigned int MAX_BLOOM_FILTER_SIZE = 36000; // bytes -static constexpr unsigned int MAX_HASH_FUNCS = 50; +inline constexpr unsigned int MAX_BLOOM_FILTER_SIZE{36'000}; // bytes +inline constexpr unsigned int MAX_HASH_FUNCS = 50; /** * First two bits of nFlags control how much IsRelevantAndUpdate actually updates diff --git a/src/common/config.cpp b/src/common/config.cpp index cc7ffd59..8cf324ca 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -2,28 +2,25 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include // IWYU pragma: associated #include #include #include #include -#include +#include #include #include #include #include -#include #include -#include #include #include -#include #include #include -#include #include +#include #include #include #include diff --git a/src/common/init.cpp b/src/common/init.cpp index 5c9742be..091b8d81 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -2,15 +2,15 @@ // 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 #include -#include #include #include diff --git a/src/common/interfaces.cpp b/src/common/interfaces.cpp index b501493d..3873ca2e 100644 --- a/src/common/interfaces.cpp +++ b/src/common/interfaces.cpp @@ -2,8 +2,9 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include -#include +#include // IWYU pragma: associated +#include // IWYU pragma: associated + #include #include diff --git a/src/common/messages.cpp b/src/common/messages.cpp index 82ad310b..716512be 100644 --- a/src/common/messages.cpp +++ b/src/common/messages.cpp @@ -4,16 +4,16 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include + #include #include -#include #include +#include #include #include #include #include -#include #include #include #include @@ -27,12 +27,9 @@ namespace common { std::string StringForFeeReason(FeeReason reason) { static const std::map fee_reason_strings = { - {FeeReason::NONE, "None"}, - {FeeReason::HALF_ESTIMATE, "Half Target 60% Threshold"}, - {FeeReason::FULL_ESTIMATE, "Target 85% Threshold"}, - {FeeReason::DOUBLE_ESTIMATE, "Double Target 95% Threshold"}, - {FeeReason::CONSERVATIVE, "Conservative Double Target longer horizon"}, + {FeeReason::FEE_RATE_ESTIMATOR, "Fee Rate Estimator"}, {FeeReason::MEMPOOL_MIN, "Mempool Min Fee"}, + {FeeReason::USER_SPECIFIED, "User Specified Fee"}, {FeeReason::FALLBACK, "Fallback fee"}, {FeeReason::REQUIRED, "Minimum Required Fee"}, }; @@ -59,13 +56,9 @@ std::string FeeModeInfo(const std::pair& mode, std case FeeEstimateMode::UNSET: return strprintf("%s means no mode set (%s). \n", mode.first, default_info); case FeeEstimateMode::ECONOMICAL: - return strprintf("%s estimates use a shorter time horizon, making them more\n" - "responsive to short-term drops in the prevailing fee market. This mode\n" - "potentially returns a lower fee rate estimate.\n", mode.first); + return strprintf("%s mode potentially returns a lower fee rate estimate.\n", mode.first); case FeeEstimateMode::CONSERVATIVE: - return strprintf("%s estimates use a longer time horizon, making them\n" - "less responsive to short-term drops in the prevailing fee market. This mode\n" - "potentially returns a higher fee rate estimate.\n", mode.first); + return strprintf("%s potentially returns a higher fee rate estimate.\n", mode.first); } // no default case, so the compiler can warn about missing cases assert(false); } @@ -118,8 +111,6 @@ bilingual_str PSBTErrorString(PSBTError err) return Untranslated("Input needs additional signatures or other data"); case PSBTError::INVALID_TX: return Untranslated("The transaction cannot be valid"); - case PSBTError::OK: - return Untranslated("No errors"); } // no default case, so the compiler can warn about missing cases assert(false); } diff --git a/src/common/messages.h b/src/common/messages.h index 60fdaa18..d6f26ccd 100644 --- a/src/common/messages.h +++ b/src/common/messages.h @@ -13,9 +13,9 @@ #include #include +#include struct bilingual_str; - enum class FeeEstimateMode; enum class FeeReason; namespace node { @@ -24,6 +24,7 @@ enum class TransactionError; namespace common { enum class PSBTError; + bool FeeModeFromString(std::string_view mode_string, FeeEstimateMode& fee_estimate_mode); std::string StringForFeeReason(FeeReason reason); std::string FeeModes(const std::string& delimiter); diff --git a/src/common/netif.cpp b/src/common/netif.cpp index 997db7d5..1120ee60 100644 --- a/src/common/netif.cpp +++ b/src/common/netif.cpp @@ -6,12 +6,22 @@ #include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include + #if defined(__linux__) +#include #include #elif defined(__FreeBSD__) #include @@ -27,8 +37,6 @@ #include #endif -#include - namespace { //! Return CNetAddr for the specified OS-level network address. diff --git a/src/common/netif.h b/src/common/netif.h index 769bcbcc..84df00a2 100644 --- a/src/common/netif.h +++ b/src/common/netif.h @@ -8,6 +8,7 @@ #include #include +#include //! Query the OS for the default gateway for `network`. This only makes sense for NET_IPV4 and NET_IPV6. //! Returns std::nullopt if it cannot be found, or there is no support for this OS. diff --git a/src/common/pcp.cpp b/src/common/pcp.cpp index 7b22e82e..96a85821 100644 --- a/src/common/pcp.cpp +++ b/src/common/pcp.cpp @@ -4,19 +4,30 @@ #include -#include -#include +#include #include +#include #include #include -#include -#include +#include #include #include -#include #include -#include +#include #include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace { diff --git a/src/common/pcp.h b/src/common/pcp.h index 121349b0..2c6b776f 100644 --- a/src/common/pcp.h +++ b/src/common/pcp.h @@ -6,15 +6,21 @@ #define BITCOIN_COMMON_PCP_H #include -#include +#include +#include +#include +#include +#include #include +class CThreadInterrupt; + // RFC6886 NAT-PMP and RFC6887 Port Control Protocol (PCP) implementation. // NAT-PMP and PCP use network byte order (big-endian). //! Mapping nonce size in bytes (see RFC6887 section 11.1). -constexpr size_t PCP_MAP_NONCE_SIZE = 12; +inline constexpr size_t PCP_MAP_NONCE_SIZE = 12; //! PCP mapping nonce. Arbitrary data chosen by the client to identify a mapping. typedef std::array PCPMappingNonce; diff --git a/src/common/run_command.cpp b/src/common/run_command.cpp index 86f89e17..b4e81c40 100644 --- a/src/common/run_command.cpp +++ b/src/common/run_command.cpp @@ -2,21 +2,19 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include // IWYU pragma: keep - #include #include #include #include - -#ifdef ENABLE_EXTERNAL_SIGNER #include -#endif // ENABLE_EXTERNAL_SIGNER + +#include +#include +#include UniValue RunCommandParseJSON(const std::vector& cmd_args, const std::string& str_std_in) { -#ifdef ENABLE_EXTERNAL_SIGNER namespace sp = subprocess; UniValue result_json; @@ -43,7 +41,4 @@ UniValue RunCommandParseJSON(const std::vector& cmd_args, const std if (!result_json.read(result)) throw std::runtime_error("Unable to parse JSON: " + result); return result_json; -#else - throw std::runtime_error("Compiled without external signing support (required for external signing)."); -#endif // ENABLE_EXTERNAL_SIGNER } diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 7d511b57..eca29bec 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -2,15 +2,14 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include - #include // IWYU pragma: keep +#include + #include #include #include -#include #include #include #include diff --git a/src/common/settings.h b/src/common/settings.h index bc7b89a9..6f2579b1 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -12,7 +12,9 @@ #include #include -class UniValue; +// Users of this header need to explicitly #include +// IWYU pragma: no_include +class UniValue; // IWYU pragma: keep namespace common { diff --git a/src/common/signmessage.cpp b/src/common/signmessage.cpp index 0f9e1f5e..b45951f6 100644 --- a/src/common/signmessage.cpp +++ b/src/common/signmessage.cpp @@ -4,15 +4,18 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include + +#include #include #include #include #include #include +#include #include -#include #include +#include #include #include #include diff --git a/src/common/system.cpp b/src/common/system.cpp index ca7b857d..33918dd8 100644 --- a/src/common/system.cpp +++ b/src/common/system.cpp @@ -12,12 +12,12 @@ #include #ifdef WIN32 -#include -#include #include +#include #include #else #include +#include #include #endif @@ -25,8 +25,6 @@ #include #endif -#include -#include #include #include #include @@ -50,11 +48,7 @@ std::string ShellEscape(const std::string& arg) void runCommand(const std::string& strCommand) { if (strCommand.empty()) return; -#ifndef WIN32 int nErr = ::system(strCommand.c_str()); -#else - int nErr = ::_wsystem(std::wstring_convert,wchar_t>().from_bytes(strCommand).c_str()); -#endif if (nErr) { LogWarning("runCommand error: system(%s) returned %d", strCommand, nErr); } @@ -111,20 +105,17 @@ int GetNumCores() return std::thread::hardware_concurrency(); } -std::optional GetTotalRAM() +std::optional TryGetTotalRam() { - [[maybe_unused]] auto clamp{[](uint64_t v) { return size_t(std::min(v, uint64_t{std::numeric_limits::max()})); }}; + static const auto total_ram{[]() -> std::optional { #ifdef WIN32 - if (MEMORYSTATUSEX m{}; (m.dwLength = sizeof(m), GlobalMemoryStatusEx(&m))) return clamp(m.ullTotalPhys); -#elif defined(__APPLE__) || \ - defined(__FreeBSD__) || \ - defined(__NetBSD__) || \ - defined(__OpenBSD__) || \ - defined(__illumos__) || \ - defined(__linux__) - if (long p{sysconf(_SC_PHYS_PAGES)}, s{sysconf(_SC_PAGESIZE)}; p > 0 && s > 0) return clamp(1ULL * p * s); + if (MEMORYSTATUSEX m{}; (m.dwLength = sizeof(m), GlobalMemoryStatusEx(&m))) return m.ullTotalPhys; +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__illumos__) || defined(__linux__) + if (long p{sysconf(_SC_PHYS_PAGES)}, s{sysconf(_SC_PAGESIZE)}; p > 0 && s > 0) return 1ULL * p * s; #endif - return std::nullopt; + return std::nullopt; + }()}; + return total_ram; } namespace { diff --git a/src/common/system.h b/src/common/system.h index a3100fec..ad217e0d 100644 --- a/src/common/system.h +++ b/src/common/system.h @@ -7,9 +7,9 @@ #define BITCOIN_COMMON_SYSTEM_H #include // IWYU pragma: keep + #include -#include #include #include #include @@ -35,6 +35,6 @@ int GetNumCores(); /** * Return the total RAM available on the current system, if detectable. */ -std::optional GetTotalRAM(); +std::optional TryGetTotalRam(); #endif // BITCOIN_COMMON_SYSTEM_H diff --git a/src/common/types.h b/src/common/types.h index b9ebca15..1ffcd392 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -24,7 +24,6 @@ enum class PSBTError { UNSUPPORTED, INCOMPLETE, INVALID_TX, - OK, }; /** * Instructions for how a PSBT should be signed or filled with information. diff --git a/src/common/url.cpp b/src/common/url.cpp index 19db4e99..a186c512 100644 --- a/src/common/url.cpp +++ b/src/common/url.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/src/compressor.h b/src/compressor.h index 95490b7b..b6b738f6 100644 --- a/src/compressor.h +++ b/src/compressor.h @@ -59,7 +59,7 @@ struct ScriptCompression * transactions, in which case this value becomes dependent on version * and nHeight of the enclosing transaction. */ - static const unsigned int nSpecialScripts = 6; + static constexpr unsigned int nSpecialScripts{6}; template void Ser(Stream &s, const CScript& script) { diff --git a/src/consensus/amount.h b/src/consensus/amount.h index 2a65a831..a2a383cc 100644 --- a/src/consensus/amount.h +++ b/src/consensus/amount.h @@ -12,7 +12,7 @@ typedef int64_t CAmount; /** The amount of satoshis in one BTC. */ -static constexpr CAmount COIN = 100000000; +inline constexpr CAmount COIN{100'000'000}; /** No amount larger than this (in satoshi) is valid. * @@ -23,7 +23,7 @@ static constexpr CAmount COIN = 100000000; * critical; in unusual circumstances like a(nother) overflow bug that allowed * for the creation of coins out of thin air modification could lead to a fork. * */ -static constexpr CAmount MAX_MONEY = 21000000 * COIN; +inline constexpr CAmount MAX_MONEY{21'000'000 * COIN}; inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } #endif // BITCOIN_CONSENSUS_AMOUNT_H diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 71b5fe24..96195e28 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -6,32 +6,32 @@ #ifndef BITCOIN_CONSENSUS_CONSENSUS_H #define BITCOIN_CONSENSUS_CONSENSUS_H +#include #include -#include /** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */ -static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000; +inline constexpr unsigned int MAX_BLOCK_SERIALIZED_SIZE{4'000'000}; /** The maximum allowed weight for a block, see BIP 141 (network rule) */ -static const unsigned int MAX_BLOCK_WEIGHT = 4000000; +inline constexpr unsigned int MAX_BLOCK_WEIGHT{4'000'000}; /** The maximum allowed number of signature check operations in a block (network rule) */ -static const int64_t MAX_BLOCK_SIGOPS_COST = 80000; +inline constexpr int64_t MAX_BLOCK_SIGOPS_COST{80'000}; /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ -static const int COINBASE_MATURITY = 100; +inline constexpr int COINBASE_MATURITY = 100; -static const int WITNESS_SCALE_FACTOR = 4; +inline constexpr int WITNESS_SCALE_FACTOR = 4; -static const size_t MIN_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 60; // 60 is the lower bound for the size of a valid serialized CTransaction -static const size_t MIN_SERIALIZABLE_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 10; // 10 is the lower bound for the size of a serialized CTransaction +inline constexpr size_t MIN_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 60; // 60 is the lower bound for the size of a valid serialized CTransaction +inline constexpr size_t MIN_SERIALIZABLE_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 10; // 10 is the lower bound for the size of a serialized CTransaction /** Flags for nSequence and nLockTime locks */ /** Interpret sequence numbers as relative lock-time constraints. */ -static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE = (1 << 0); +inline constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE = (1 << 0); /** * Maximum number of seconds that the timestamp of the first * block of a difficulty adjustment period is allowed to * be earlier than the last block of the previous period (BIP94). */ -static constexpr int64_t MAX_TIMEWARP = 600; +inline constexpr int64_t MAX_TIMEWARP = 600; #endif // BITCOIN_CONSENSUS_CONSENSUS_H diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp index c6ae81c6..df5f95e7 100644 --- a/src/consensus/merkle.cpp +++ b/src/consensus/merkle.cpp @@ -3,9 +3,17 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include + +#include #include +#include +#include #include +#include +#include +#include + /* WARNING! If you're reading this because you're learning about crypto and/or designing a new system that will use merkle trees, keep in mind that the following merkle tree algorithm has a serious flaw related to @@ -41,12 +49,15 @@ known ways of changing the transactions without affecting the merkle root. */ - - uint256 ComputeMerkleRoot(std::vector hashes, bool* mutated) { bool mutation = false; while (hashes.size() > 1) { if (mutated) { + // Check every level because equal pairs can appear above the leaves, + // as in the [1,2,3,4,5,6,5,6] construction described above. + // Continuing after finding one is redundant, but mutated blocks should + // not propagate through the network anyway, and the total number of + // comparisons is the same as for an unmutated input of the same length. for (size_t pos = 0; pos + 1 < hashes.size(); pos += 2) { if (hashes[pos] == hashes[pos + 1]) mutation = true; } diff --git a/src/consensus/merkle.h b/src/consensus/merkle.h index 03b5a1b5..dc8866bb 100644 --- a/src/consensus/merkle.h +++ b/src/consensus/merkle.h @@ -5,11 +5,18 @@ #ifndef BITCOIN_CONSENSUS_MERKLE_H #define BITCOIN_CONSENSUS_MERKLE_H +#include + +#include #include -#include -#include +class CBlock; +/** + * Compute a Merkle root from the provided leaf hashes. + * If non-null, `*mutated` is set to true if two identical hashes are paired at + * any tree level before the odd-count hash duplication step, and false otherwise. + */ uint256 ComputeMerkleRoot(std::vector hashes, bool* mutated = nullptr); /* diff --git a/src/consensus/params.h b/src/consensus/params.h index 7f567294..99096e06 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/src/consensus/tx_check.cpp b/src/consensus/tx_check.cpp index 251417c8..473538e4 100644 --- a/src/consensus/tx_check.cpp +++ b/src/consensus/tx_check.cpp @@ -5,8 +5,16 @@ #include #include -#include +#include #include +#include +#include