From 9e59047a7e5a6d23520fce156dea2ae6b32415ca Mon Sep 17 00:00:00 2001 From: furszy Date: Wed, 7 Jan 2026 16:29:30 -0500 Subject: [PATCH 1/6] test: migration, avoid backup name mismatch in default_wallet_failure The test calls migrate_and_get_rpc(), which sets mock time internally. The caller caches a mock time value and later relies on it to predict the backup filename, so setting the mock time again could cause a naming mismatch. Fix this by calling the migration RPC directly. Since the test expects the migration to fail, migrate_and_get_rpc() is unnecessary here. Github-Pull: #34221 Rebased-From: cbf0bd35bbf312f3b13d92d281d7112e4b43b9c3 --- test/functional/wallet_migration.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py index 0912f99a2c6..34c0f3cc646 100755 --- a/test/functional/wallet_migration.py +++ b/test/functional/wallet_migration.py @@ -690,6 +690,7 @@ class WalletMigrationTest(BitcoinTestFramework): master_wallet = self.master_node.get_wallet_rpc(self.default_wallet_name) wallet = self.create_legacy_wallet("", blank=True) wallet.importaddress(master_wallet.getnewaddress(address_type="legacy")) + wallet.unloadwallet() # Create wallet directory with the watch-only name and a wallet file. # Because the wallet dir exists, this will cause migration to fail. @@ -699,7 +700,8 @@ class WalletMigrationTest(BitcoinTestFramework): mocked_time = int(time.time()) self.master_node.setmocktime(mocked_time) - assert_raises_rpc_error(-4, "Failed to create database", self.migrate_and_get_rpc, "") + shutil.copyfile(self.old_node.wallets_path / "wallet.dat", self.master_node.wallets_path / "wallet.dat") + assert_raises_rpc_error(-4, "Failed to create database", self.master_node.migratewallet, wallet_name="") self.master_node.setmocktime(0) # Verify the /wallets/ path exists From 1dae0027cd43583302c1950492568198f2dcf3a9 Mon Sep 17 00:00:00 2001 From: David Gumberg Date: Wed, 7 Jan 2026 16:02:58 -0800 Subject: [PATCH 2/6] wallet: test: Failed migration cleanup Refactor a common way to perform the failed migration test that exists for default wallets, and add relative-path wallets and absolute-path wallets. Github-Pull: #34226 Rebased-From: eeaf28dbe0e09819ab0e95bb7762b29536bdeef6 --- test/functional/wallet_migration.py | 73 +++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py index 34c0f3cc646..302bd892089 100755 --- a/test/functional/wallet_migration.py +++ b/test/functional/wallet_migration.py @@ -685,37 +685,61 @@ class WalletMigrationTest(BitcoinTestFramework): wallet.unloadwallet() self.clear_default_wallet(backup_file=Path(res["backup_path"])) - def test_default_wallet_failure(self): - self.log.info("Test failure during unnamed (default) wallet migration") + def test_migration_failure(self, wallet_name): + is_default = wallet_name == "" + wallet_pretty_name = "unnamed (default)" if is_default else f'"{wallet_name}"' + self.log.info(f"Test failure during migration of wallet named: {wallet_pretty_name}") + # Preface, set up legacy wallet and unload it master_wallet = self.master_node.get_wallet_rpc(self.default_wallet_name) - wallet = self.create_legacy_wallet("", blank=True) + wallet = self.create_legacy_wallet(wallet_name, blank=True) wallet.importaddress(master_wallet.getnewaddress(address_type="legacy")) wallet.unloadwallet() - # Create wallet directory with the watch-only name and a wallet file. - # Because the wallet dir exists, this will cause migration to fail. - watch_only_dir = self.master_node.wallets_path / "default_wallet_watchonly" + if os.path.isabs(wallet_name): + old_path = master_path = Path(wallet_name) + else: + old_path = self.old_node.wallets_path / wallet_name + master_path = self.master_node.wallets_path / wallet_name + os.makedirs(master_path, exist_ok=True) + shutil.copyfile(old_path / "wallet.dat", master_path / "wallet.dat") + + # This will be the watch-only directory the migration tries to create, + # we make migration fail by placing a wallet.dat file there. + wo_prefix = wallet_name or "default_wallet" + # wo_prefix might have path characters in it, this corresponds with + # DoMigration(). + wo_dirname = f"{wo_prefix}_watchonly" + watch_only_dir = self.master_node.wallets_path / wo_dirname os.mkdir(watch_only_dir) - shutil.copyfile(self.old_node.wallets_path / "wallet.dat", watch_only_dir / "wallet.dat") + shutil.copyfile(old_path / "wallet.dat", watch_only_dir / "wallet.dat") mocked_time = int(time.time()) self.master_node.setmocktime(mocked_time) - shutil.copyfile(self.old_node.wallets_path / "wallet.dat", self.master_node.wallets_path / "wallet.dat") - assert_raises_rpc_error(-4, "Failed to create database", self.master_node.migratewallet, wallet_name="") + assert_raises_rpc_error(-4, "Failed to create database", self.master_node.migratewallet, wallet_name) self.master_node.setmocktime(0) - # Verify the /wallets/ path exists + # Verify the /wallets/ path exists. assert self.master_node.wallets_path.exists() - # Check backup file exists. Because the wallet has no name, the backup is prefixed with 'default_wallet' - backup_path = self.master_node.wallets_path / f"default_wallet_{mocked_time}.legacy.bak" - assert backup_path.exists() - # Verify the original unnamed wallet was restored - assert (self.master_node.wallets_path / "wallet.dat").exists() - # And verify it is still a BDB wallet - self.assert_is_bdb("") - # Test cleanup: clear default wallet for next test - self.clear_default_wallet(backup_path) + # Verify both wallet paths exist. + assert Path(old_path / "wallet.dat").exists() + assert Path(master_path / "wallet.dat").exists() + + backup_prefix = "default_wallet" if is_default else os.path.basename(os.path.abspath(master_path)) + backup_path = self.master_node.wallets_path / f"{backup_prefix}_{mocked_time}.legacy.bak" + assert backup_path.exists() + + self.assert_is_bdb(wallet_name) + + # Cleanup + if is_default: + self.clear_default_wallet(backup_path) + else: + backup_path.unlink() + Path(watch_only_dir / "wallet.dat").unlink() + Path(watch_only_dir).rmdir() + Path(master_path / "wallet.dat").unlink() + Path(old_path / "wallet.dat").unlink(missing_ok=True) def test_direct_file(self): self.log.info("Test migration of a wallet that is not in a wallet directory") @@ -1633,7 +1657,16 @@ class WalletMigrationTest(BitcoinTestFramework): self.test_wallet_with_relative_path() self.test_wallet_with_path("path/to/mywallet/") self.test_wallet_with_path("path/that/ends/in/..") - self.test_default_wallet_failure() + + migration_failure_cases = [ + "", + "../", + os.path.abspath(self.master_node.datadir_path / "absolute_path"), + "normallynamedwallet" + ] + for wallet_name in migration_failure_cases: + self.test_migration_failure(wallet_name=wallet_name) + self.test_default_wallet() self.test_default_wallet_watch_only() self.test_direct_file() From 6d86b32e780e3df5bcc163ed5c288144aa234b78 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 8 Jan 2026 12:45:14 +0000 Subject: [PATCH 3/6] guix: Fix `osslsigncode` tests Github-Pull: #34227 Rebased-From: 194114daf385a5db50e1507fda79a1a93240d494 --- contrib/guix/manifest.scm | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index a230eea991b..59a6366984a 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -2,6 +2,7 @@ ((gnu packages bash) #:select (bash-minimal)) (gnu packages bison) ((gnu packages certs) #:select (nss-certs)) + ((gnu packages check) #:select (libfaketime)) ((gnu packages cmake) #:select (cmake-minimal)) (gnu packages commencement) (gnu packages compression) @@ -209,7 +210,17 @@ and abstract ELF, PE and MachO formats.") (base32 "1j47vwq4caxfv0xw68kw5yh00qcpbd56d7rq6c483ma3y7s96yyz")))) (build-system cmake-build-system) - (inputs (list openssl)) + (arguments + (list + #:phases + #~(modify-phases %standard-phases + (replace 'check + (lambda* (#:key tests? #:allow-other-keys) + (if tests? + (invoke "faketime" "-f" "@2025-01-01 00:00:00" ;; Tests fail after 2025. + "ctest" "--output-on-failure" "--no-tests=error") + (format #t "test suite not run~%"))))))) + (inputs (list libfaketime openssl)) (home-page "https://github.com/mtrojnar/osslsigncode") (synopsis "Authenticode signing and timestamping tool") (description "osslsigncode is a small tool that implements part of the From 6c98d68be1478e3420a8e3b093f355ac038fe87c Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 8 Jan 2026 10:23:00 +0000 Subject: [PATCH 4/6] doc: update release notes for v30.2 --- doc/release-notes.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 920b26b2bdd..888b3f919c3 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,9 +1,9 @@ -v30.2rc1 Release Notes +v30.2 Release Notes =================== -Bitcoin Core version v30.2rc1 is now available from: +Bitcoin Core version v30.2 is now available from: - + This release includes new features, various bug fixes and performance improvements, as well as updated translations. @@ -44,6 +44,7 @@ Notable changes - #34156 wallet: fix unnamed legacy wallet migration failure - #34215 wallettool: fix unnamed createfromdump failure walletsdir deletion +- #34221 test: migration, avoid backup name mismatch in default_wallet_failure ### IPC @@ -53,10 +54,12 @@ Notable changes - #33950 guix: reduce allowed exported symbols - #34107 build: Update minimum required Boost version +- #34227 guix: Fix osslsigncode tests ### Test - #34137 test: Avoid hard time.sleep(1) in feature_init.py +- #34226 wallet: test: Relative wallet failed migration cleanup ### Fuzz @@ -77,6 +80,7 @@ Thanks to everyone who directly contributed to this release: - Ava Chow - brunoerg +- davidgumberg - fanquake - furszy - Hennadii Stepanov From ed355b8f57920714b7cc1775d60f3c4b0098ad04 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 9 Jan 2026 11:17:00 +0000 Subject: [PATCH 5/6] build: bump version to v30.2 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a345c5f1dd..4f832625170 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 30) set(CLIENT_VERSION_MINOR 2) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 1) +set(CLIENT_VERSION_RC 0) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2026") From 04a996b1a77b5e4c73df27540eca0e1f6587c56e Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 9 Jan 2026 11:23:01 +0000 Subject: [PATCH 6/6] doc: update manual pages for v30.2 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 6 +++--- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoin.1 | 4 ++-- doc/man/bitcoind.1 | 6 +++--- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 3124c13995b..ba53687c871 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" "January 2026" "bitcoin-cli v30.2.0rc1" "User Commands" +.TH BITCOIN-CLI "1" "January 2026" "bitcoin-cli v30.2.0" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v30.2.0rc1 +bitcoin-cli \- manual page for bitcoin-cli v30.2.0 .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.2.0rc1 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v30.2.0rc1 +Bitcoin Core RPC client version v30.2.0 .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 7daba3a885a..304e9f55299 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" "January 2026" "bitcoin-qt v30.2.0rc1" "User Commands" +.TH BITCOIN-QT "1" "January 2026" "bitcoin-qt v30.2.0" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v30.2.0rc1 +bitcoin-qt \- manual page for bitcoin-qt v30.2.0 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v30.2.0rc1 +Bitcoin Core version v30.2.0 .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 e1b49f617d2..e40d67cc02d 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" "January 2026" "bitcoin-tx v30.2.0rc1" "User Commands" +.TH BITCOIN-TX "1" "January 2026" "bitcoin-tx v30.2.0" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v30.2.0rc1 +bitcoin-tx \- manual page for bitcoin-tx v30.2.0 .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.2.0rc1 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v30.2.0rc1 +Bitcoin Core bitcoin\-tx utility version v30.2.0 .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 7635ed1a981..514444cc8da 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" "January 2026" "bitcoin-util v30.2.0rc1" "User Commands" +.TH BITCOIN-UTIL "1" "January 2026" "bitcoin-util v30.2.0" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v30.2.0rc1 +bitcoin-util \- manual page for bitcoin-util v30.2.0 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v30.2.0rc1 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v30.2.0rc1 +Bitcoin Core bitcoin\-util utility version v30.2.0 .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 3064467bbc6..feaf98679ad 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" "January 2026" "bitcoin-wallet v30.2.0rc1" "User Commands" +.TH BITCOIN-WALLET "1" "January 2026" "bitcoin-wallet v30.2.0" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v30.2.0rc1 +bitcoin-wallet \- manual page for bitcoin-wallet v30.2.0 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v30.2.0rc1 +Bitcoin Core bitcoin\-wallet utility version v30.2.0 .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 a04b51f9064..09448f6151d 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" "January 2026" "bitcoin v30.2.0rc1" "User Commands" +.TH BITCOIN "1" "January 2026" "bitcoin v30.2.0" "User Commands" .SH NAME -bitcoin \- manual page for bitcoin v30.2.0rc1 +bitcoin \- manual page for bitcoin v30.2.0 .SH SYNOPSIS .B bitcoin [\fI\,OPTIONS\/\fR] \fI\,COMMAND\/\fR... diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index cb4fb805382..9778da72ead 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" "January 2026" "bitcoind v30.2.0rc1" "User Commands" +.TH BITCOIND "1" "January 2026" "bitcoind v30.2.0" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v30.2.0rc1 +bitcoind \- manual page for bitcoind v30.2.0 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v30.2.0rc1 bitcoind +Bitcoin Core daemon version v30.2.0 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