diff --git a/CMakeLists.txt b/CMakeLists.txt index 9381c90dcd1..d54b9faa0e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,9 +28,9 @@ get_directory_property(precious_variables CACHE_VARIABLES) #============================= set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 30) -set(CLIENT_VERSION_MINOR 0) +set(CLIENT_VERSION_MINOR 1) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 0) +set(CLIENT_VERSION_RC 1) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index ce460987901..d26bda3d23b 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -89,7 +89,7 @@ mkdir -p "${DEPENDS_DIR}/SDKs" "${DEPENDS_DIR}/sdk-sources" OSX_SDK_BASENAME="Xcode-${XCODE_VERSION}-${XCODE_BUILD_ID}-extracted-SDK-with-libcxx-headers" if [ -n "$XCODE_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${OSX_SDK_BASENAME}" ]; then - OSX_SDK_FILENAME="${OSX_SDK_BASENAME}.tar.gz" + OSX_SDK_FILENAME="${OSX_SDK_BASENAME}.tar" OSX_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${OSX_SDK_FILENAME}" if [ ! -f "$OSX_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "${SDK_URL}/${OSX_SDK_FILENAME}" -o "$OSX_SDK_PATH" diff --git a/contrib/devtools/gen-manpages.py b/contrib/devtools/gen-manpages.py index 12d16157df5..02e5f839ba1 100755 --- a/contrib/devtools/gen-manpages.py +++ b/contrib/devtools/gen-manpages.py @@ -3,6 +3,7 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import os +import re import subprocess import sys import tempfile @@ -59,10 +60,11 @@ for relpath in BINARIES: print(f'{abspath} not found or not an executable', file=sys.stderr) sys.exit(1) # take first line (which must contain version) - verstr = r.stdout.splitlines()[0] - # last word of line is the actual version e.g. v22.99.0-5c6b3d5b3508 - verstr = verstr.split()[-1] - assert verstr.startswith('v') + output = r.stdout.splitlines()[0] + # find the version e.g. v30.99.0-ce771726f3e7 + search = re.search(r"v[0-9]\S+", output) + assert search + verstr = search.group(0) # remaining lines are copyright copyright = r.stdout.split('\n')[1:] assert copyright[0].startswith('Copyright (C)') diff --git a/contrib/guix/README.md b/contrib/guix/README.md index 7f6b8232bba..aadc231e3be 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -37,7 +37,7 @@ You can then either point to the SDK using the `SDK_PATH` environment variable: ```sh # Extract the SDK tarball to /path/to/parent/dir/of/extracted/SDK/Xcode---extracted-SDK-with-libcxx-headers -tar -C /path/to/parent/dir/of/extracted/SDK -xaf /path/to/Xcode---extracted-SDK-with-libcxx-headers.tar.gz +tar -C /path/to/parent/dir/of/extracted/SDK -xaf /path/to/Xcode---extracted-SDK-with-libcxx-headers.tar # Indicate where to locate the SDK tarball export SDK_PATH=/path/to/parent/dir/of/extracted/SDK diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md index d47ee6774e0..1763c6cb513 100644 --- a/contrib/macdeploy/README.md +++ b/contrib/macdeploy/README.md @@ -44,15 +44,15 @@ xip -x Xcode_15.xip ### Step 2: Generating the SDK tarball from `Xcode.app` -To generate the SDK, run the script [`gen-sdk`](./gen-sdk) with the +To generate the SDK, run the script [`gen-sdk.py`](./gen-sdk.py) with the path to `Xcode.app` (extracted in the previous stage) as the first argument. ```bash -./contrib/macdeploy/gen-sdk '/path/to/Xcode.app' +./contrib/macdeploy/gen-sdk.py '/path/to/Xcode.app' ``` -The generated archive should be: `Xcode-15.0-15A240d-extracted-SDK-with-libcxx-headers.tar.gz`. -The `sha256sum` should be `c0c2e7bb92c1fee0c4e9f3a485e4530786732d6c6dd9e9f418c282aa6892f55d`. +The generated archive should be: `Xcode-15.0-15A240d-extracted-SDK-with-libcxx-headers.tar`. +The `sha256sum` should be `95b00dc41fa090747dc0a7907a5031a2fcb2d7f95c9584ba6bccdb99b6e3d498`. ## Deterministic macOS App Notes diff --git a/contrib/macdeploy/gen-sdk b/contrib/macdeploy/gen-sdk.py similarity index 74% rename from contrib/macdeploy/gen-sdk rename to contrib/macdeploy/gen-sdk.py index f0bbabf81f9..cf37929287e 100755 --- a/contrib/macdeploy/gen-sdk +++ b/contrib/macdeploy/gen-sdk.py @@ -2,9 +2,7 @@ import argparse import plistlib import pathlib -import sys import tarfile -import gzip import os import contextlib @@ -22,12 +20,12 @@ def run(): parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawTextHelpFormatter) - parser.add_argument('xcode_app', metavar='XCODEAPP', nargs=1) - parser.add_argument("-o", metavar='OUTSDKTGZ', nargs=1, dest='out_sdktgz', required=False) + parser.add_argument('xcode_app', metavar='XCODEAPP', type=pathlib.Path) + parser.add_argument("-o", metavar='OUTSDKTAR', dest='out_sdkt', type=pathlib.Path, required=False) args = parser.parse_args() - xcode_app = pathlib.Path(args.xcode_app[0]).resolve() + xcode_app = args.xcode_app.resolve() assert xcode_app.is_dir(), "The supplied Xcode.app path '{}' either does not exist or is not a directory".format(xcode_app) xcode_app_plist = xcode_app.joinpath("Contents/version.plist") @@ -47,11 +45,7 @@ def run(): out_name = "Xcode-{xcode_version}-{xcode_build_id}-extracted-SDK-with-libcxx-headers".format(xcode_version=xcode_version, xcode_build_id=xcode_build_id) - if args.out_sdktgz: - out_sdktgz_path = pathlib.Path(args.out_sdktgz_path) - else: - # Construct our own out_sdktgz if not specified on the command line - out_sdktgz_path = pathlib.Path("./{}.tar.gz".format(out_name)) + out_sdkt_path = args.out_sdkt or pathlib.Path("./{}.tar".format(out_name)) def tarfp_add_with_base_change(tarfp, dir_to_add, alt_base_dir): """Add all files in dir_to_add to tarfp, but prepend alt_base_dir to the files' @@ -68,6 +62,8 @@ def run(): """ def change_tarinfo_base(tarinfo): + if tarinfo.name and tarinfo.name.endswith((".swiftmodule", ".modulemap")): + return None if tarinfo.name and tarinfo.name.startswith("./"): tarinfo.name = str(pathlib.Path(alt_base_dir, tarinfo.name)) if tarinfo.linkname and tarinfo.linkname.startswith("./"): @@ -81,16 +77,17 @@ def run(): return tarinfo with cd(dir_to_add): # recursion already adds entries in sorted order - tarfp.add(".", recursive=True, filter=change_tarinfo_base) + tarfp.add("./usr/include", recursive=True, filter=change_tarinfo_base) + tarfp.add("./usr/lib", recursive=True, filter=change_tarinfo_base) + tarfp.add("./System/Library/Frameworks", recursive=True, filter=change_tarinfo_base) - print("Creating output .tar.gz file...") - with out_sdktgz_path.open("wb") as fp: - with gzip.GzipFile(fileobj=fp, mode='wb', compresslevel=9, mtime=0) as gzf: - with tarfile.open(mode="w", fileobj=gzf, format=tarfile.GNU_FORMAT) as tarfp: - print("Adding MacOSX SDK {} files...".format(sdk_version)) - tarfp_add_with_base_change(tarfp, sdk_dir, out_name) - print("Done! Find the resulting gzipped tarball at:") - print(out_sdktgz_path.resolve()) + print("Creating output .tar file...") + with out_sdkt_path.open("wb") as fp: + with tarfile.open(mode="w", fileobj=fp, format=tarfile.PAX_FORMAT) as tarfp: + print("Adding MacOSX SDK {} files...".format(sdk_version)) + tarfp_add_with_base_change(tarfp, sdk_dir, out_name) + print("Done! Find the resulting tarball at:") + print(out_sdkt_path.resolve()) if __name__ == '__main__': run() diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md index 63a51b5a692..2eb6846747a 100644 --- a/contrib/seeds/README.md +++ b/contrib/seeds/README.md @@ -10,14 +10,13 @@ to addrman with). Update `MIN_BLOCKS` in `makeseeds.py` and the `-m`/`--minblocks` arguments below, as needed. -The seeds compiled into the release are created from sipa's, achow101's and luke-jr's +The seeds compiled into the release are created from sipa's and achow101's DNS seed, virtu's crawler, and asmap community AS map data. Run the following commands from the `/contrib/seeds` directory: ``` curl https://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt curl https://21.ninja/seeds.txt.gz | gzip -dc >> seeds_main.txt -curl https://luke.dashjr.org/programs/bitcoin/files/charts/seeds.txt >> seeds_main.txt curl https://mainnet.achownodes.xyz/seeds.txt.gz | gzip -dc >> seeds_main.txt curl https://signet.achownodes.xyz/seeds.txt.gz | gzip -dc > seeds_signet.txt curl https://testnet.achownodes.xyz/seeds.txt.gz | gzip -dc > seeds_test.txt diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 642ac3fc12e..b7c7dba4d04 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "October 2025" "bitcoin-cli v30.0.0" "User Commands" +.TH BITCOIN-CLI "1" "December 2025" "bitcoin-cli v30.1.0rc1" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v30.0.0 +bitcoin-cli \- manual page for bitcoin-cli v30.1.0rc1 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v30.0.0 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v30.0.0 +Bitcoin Core RPC client version v30.1.0rc1 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index e8d9eb6d95a..b9e81f76717 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "October 2025" "bitcoin-qt v30.0.0" "User Commands" +.TH BITCOIN-QT "1" "December 2025" "bitcoin-qt v30.1.0rc1" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v30.0.0 +bitcoin-qt \- manual page for bitcoin-qt v30.1.0rc1 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v30.0.0 +Bitcoin Core version v30.1.0rc1 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 2b02bda8bee..ff728ccc9b0 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "October 2025" "bitcoin-tx v30.0.0" "User Commands" +.TH BITCOIN-TX "1" "December 2025" "bitcoin-tx v30.1.0rc1" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v30.0.0 +bitcoin-tx \- manual page for bitcoin-tx v30.1.0rc1 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v30.0.0 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v30.0.0 +Bitcoin Core bitcoin\-tx utility version v30.1.0rc1 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index 7367fcb1b4d..9d1c5b82213 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "October 2025" "bitcoin-util v30.0.0" "User Commands" +.TH BITCOIN-UTIL "1" "December 2025" "bitcoin-util v30.1.0rc1" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v30.0.0 +bitcoin-util \- manual page for bitcoin-util v30.1.0rc1 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v30.0.0 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v30.0.0 +Bitcoin Core bitcoin\-util utility version v30.1.0rc1 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index 51723b05479..d69941dc5ba 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "October 2025" "bitcoin-wallet v30.0.0" "User Commands" +.TH BITCOIN-WALLET "1" "December 2025" "bitcoin-wallet v30.1.0rc1" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v30.0.0 +bitcoin-wallet \- manual page for bitcoin-wallet v30.1.0rc1 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v30.0.0 +Bitcoin Core bitcoin\-wallet utility version v30.1.0rc1 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoin.1 b/doc/man/bitcoin.1 index 90c2683c5fd..5d9dfa5ff0d 100644 --- a/doc/man/bitcoin.1 +++ b/doc/man/bitcoin.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN "1" "October 2025" "bitcoin v30.0.0" "User Commands" +.TH BITCOIN "1" "December 2025" "bitcoin v30.1.0rc1" "User Commands" .SH NAME -bitcoin \- manual page for bitcoin v30.0.0 +bitcoin \- manual page for bitcoin v30.1.0rc1 .SH SYNOPSIS .B bitcoin [\fI\,OPTIONS\/\fR] \fI\,COMMAND\/\fR... diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 3cc0fb53d58..9b2d22cd8ea 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "October 2025" "bitcoind v30.0.0" "User Commands" +.TH BITCOIND "1" "December 2025" "bitcoind v30.1.0rc1" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v30.0.0 +bitcoind \- manual page for bitcoind v30.1.0rc1 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v30.0.0 +Bitcoin Core daemon version v30.1.0rc1 bitcoind .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP diff --git a/doc/release-notes.md b/doc/release-notes.md index 43aff7ec531..2a02a0db957 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,9 +1,9 @@ v30.x Release Notes =================== -Bitcoin Core version v30.x is now available from: +Bitcoin Core version v30.1rc1 is now available from: - + This release includes new features, various bug fixes and performance improvements, as well as updated translations. @@ -40,10 +40,15 @@ unsupported systems. Notable changes =============== +### Wallet + +- #33528 wallet: don't consider unconfirmed TRUC coins with ancestors + ### Build - #33580 depends: Use `$(package)_file_name` when downloading from the fallback - #33906 depends: Add patch for Windows11Style plugin +- #32009 contrib: turn off compression of macOS SDK to fix determinism ### IPC @@ -53,6 +58,10 @@ Notable changes - #33566 miner: fix empty mempool case for waitNext() - #33676 interfaces: enable cancelling running waitNext calls +### P2P + +- #33723 chainparams: remove dnsseed.bitcoin.dashjr-list-of-p2p-nodes.us + ### GUI - gui#899 qt: Modernize custom filtering @@ -74,6 +83,7 @@ Notable changes - #33558 ci: Use native platform for win-cross task - #33581 ci: Properly include $FILE_ENV in DEPENDS_HASH - #33744 ci: Fix lint runner selection (and docker cache) +- #33996 contrib: fix manpage generation Credits ======= @@ -83,11 +93,13 @@ Thanks to everyone who directly contributed to this release: - Ava Chow - Cory Fields - Eugene Siegel +- fanquake - glozow - Hennadii Stepanov - ismaelsadeeq - MarcoFalke - Ryan Ofsky +- SatsAndSports - Sjors Provoost - WakeTrainDev - willcl-ark diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp index 3955794f896..2cbce2c56c7 100644 --- a/src/kernel/chainparams.cpp +++ b/src/kernel/chainparams.cpp @@ -147,7 +147,6 @@ public: // release ASAP to avoid it where possible. vSeeds.emplace_back("seed.bitcoin.sipa.be."); // Pieter Wuille, only supports x1, x5, x9, and xd vSeeds.emplace_back("dnsseed.bluematt.me."); // Matt Corallo, only supports x9 - vSeeds.emplace_back("dnsseed.bitcoin.dashjr-list-of-p2p-nodes.us."); // Luke Dashjr vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch."); // Jonas Schnelli, only supports x1, x5, x9, and xd vSeeds.emplace_back("seed.btc.petertodd.net."); // Peter Todd, only supports x1, x5, x9, and xd vSeeds.emplace_back("seed.bitcoin.sprovoost.nl."); // Sjors Provoost diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index 146fb49ea78..5654c8f3d49 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -403,6 +403,11 @@ CoinsResult AvailableCoins(const CWallet& wallet, if (wtx.tx->version != TRUC_VERSION) continue; // this unconfirmed v3 transaction already has a child if (wtx.truc_child_in_mempool.has_value()) continue; + + // this unconfirmed v3 transaction has a parent: spending would create a third generation + size_t ancestors, descendants; + wallet.chain().getTransactionAncestry(wtx.tx->GetHash(), ancestors, descendants); + if (ancestors > 1) continue; } else { if (wtx.tx->version == TRUC_VERSION) continue; Assume(!wtx.truc_child_in_mempool.has_value()); diff --git a/test/functional/wallet_v3_txs.py b/test/functional/wallet_v3_txs.py index db9f1483aba..a037c1bc124 100755 --- a/test/functional/wallet_v3_txs.py +++ b/test/functional/wallet_v3_txs.py @@ -119,6 +119,7 @@ class WalletV3Test(BitcoinTestFramework): self.sendall_truc_child_weight_limit() self.mix_non_truc_versions() self.cant_spend_multiple_unconfirmed_truc_outputs() + self.test_spend_third_generation() @cleanup def tx_spends_unconfirmed_tx_with_wrong_version(self, version_a, version_b): @@ -585,5 +586,49 @@ class WalletV3Test(BitcoinTestFramework): {'include_unsafe' : True} ) + @cleanup + def test_spend_third_generation(self): + self.log.info("Test that we can't spend an unconfirmed TRUC output that already has an unconfirmed parent") + + # Generation 1: Consolidate all UTXOs into one output using sendall + self.charlie.sendall([self.charlie.getnewaddress()], version=3) + outputs1 = self.charlie.listunspent(minconf=0) + assert_equal(len(outputs1), 1) + + # Generation 2: to ensure no change address is created, do another sendall + self.charlie.sendall([self.charlie.getnewaddress()], version=3) + outputs2 = self.charlie.listunspent(minconf=0) + assert_equal(len(outputs2), 1) + total_amount = sum([utxo['amount'] for utxo in outputs2]) + + # Generation 3: try to send half of total amount to Alice + outputs = {self.alice.getnewaddress(): total_amount / 2} + assert_raises_rpc_error( + -4, + "Insufficient funds", + self.charlie.send, + outputs, + version=3 + ) + + # Also doesn't work with fundrawtransaction + raw_tx = self.charlie.createrawtransaction(inputs=[], outputs=outputs, version=3) + assert_raises_rpc_error( + -4, + "Insufficient funds", + self.charlie.fundrawtransaction, + raw_tx, + {'include_unsafe' : True} + ) + + # Also doesn't work with sendall + assert_raises_rpc_error( + -6, + "Total value of UTXO pool too low to pay for transaction", + self.charlie.sendall, + [self.alice.getnewaddress()], + version=3 + ) + if __name__ == '__main__': WalletV3Test(__file__).main()