From 8dc2c753ff3b89c3afefdc791fff38ac590488da Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 7 Dec 2023 11:39:01 +0000 Subject: [PATCH 01/18] doc: add historical release notes for 26.0 Github-Pull: #29023 Rebased-From: 7d4e47d1849ba00c5b45995a96f2c747f1a97c71 --- doc/release-notes/release-notes-26.0.md | 335 ++++++++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 doc/release-notes/release-notes-26.0.md diff --git a/doc/release-notes/release-notes-26.0.md b/doc/release-notes/release-notes-26.0.md new file mode 100644 index 0000000000..b30dadf62b --- /dev/null +++ b/doc/release-notes/release-notes-26.0.md @@ -0,0 +1,335 @@ +26.0 Release Notes +================== + +Bitcoin Core version 26.0 is now available from: + + + +This release includes new features, various bug fixes and performance +improvements, as well as updated translations. + +Please report bugs using the issue tracker at GitHub: + + + +To receive security and update notifications, please subscribe to: + + + +How to Upgrade +============== + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes in some cases), then run the +installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on macOS) +or `bitcoind`/`bitcoin-qt` (on Linux). + +Upgrading directly from a version of Bitcoin Core that has reached its EOL is +possible, but it might take some time if the data directory needs to be migrated. Old +wallet versions of Bitcoin Core are generally supported. + +Compatibility +============== + +Bitcoin Core is supported and extensively tested on operating systems +using the Linux kernel, macOS 11.0+, and Windows 7 and newer. Bitcoin +Core should also work on most other Unix-like systems but is not as +frequently tested on them. It is not recommended to use Bitcoin Core on +unsupported systems. + +Notable changes +=============== + +P2P and network changes +----------------------- + +- Experimental support for the v2 transport protocol defined in + [BIP324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki) was added. + It is off by default, but when enabled using `-v2transport` it will be negotiated + on a per-connection basis with other peers that support it too. The existing + v1 transport protocol remains fully supported. + +- Nodes with multiple reachable networks will actively try to have at least one + outbound connection to each network. This improves individual resistance to + eclipse attacks and network level resistance to partition attacks. Users no + longer need to perform active measures to ensure being connected to multiple + enabled networks. (#27213) + +Pruning +------- + +- When using assumeutxo with `-prune`, the prune budget may be exceeded if it is set + lower than 1100MB (i.e. `MIN_DISK_SPACE_FOR_BLOCK_FILES * 2`). Prune budget is normally + split evenly across each chainstate, unless the resulting prune budget per chainstate + is beneath `MIN_DISK_SPACE_FOR_BLOCK_FILES` in which case that value will be used. (#27596) + +Updated RPCs +------------ + +- Setting `-rpcserialversion=0` is deprecated and will be removed in + a future release. It can currently still be used by also adding + the `-deprecatedrpc=serialversion` option. (#28448) + +- The `hash_serialized_2` value has been removed from `gettxoutsetinfo` since the value it + calculated contained a bug and did not take all data into account. It is superseded by + `hash_serialized_3` which provides the same functionality but serves the correctly calculated hash. (#28685) + +- New fields `transport_protocol_type` and `session_id` were added to the `getpeerinfo` RPC to indicate + whether the v2 transport protocol is in use, and if so, what the session id is. + +- A new argument `v2transport` was added to the `addnode` RPC to indicate whether a v2 transaction connection + is to be attempted with the peer. + +- [Miniscript](https://bitcoin.sipa.be/miniscript/) expressions can now be used in Taproot descriptors for all RPCs working with descriptors. (#27255) + +- `finalizepsbt` is now able to finalize a PSBT with inputs spending [Miniscript](https://bitcoin.sipa.be/miniscript/)-compatible Taproot leaves. (#27255) + +Changes to wallet related RPCs can be found in the Wallet section below. + +New RPCs +-------- + +- `loadtxoutset` has been added, which allows loading a UTXO snapshot of the format + generated by `dumptxoutset`. Once this snapshot is loaded, its contents will be + deserialized into a second chainstate data structure, which is then used to sync to + the network's tip. + + Meanwhile, the original chainstate will complete the initial block download process in + the background, eventually validating up to the block that the snapshot is based upon. + + The result is a usable bitcoind instance that is current with the network tip in a + matter of minutes rather than hours. UTXO snapshot are typically obtained via + third-party sources (HTTP, torrent, etc.) which is reasonable since their contents + are always checked by hash. + + You can find more information on this process in the `assumeutxo` design + document (). + + `getchainstates` has been added to aid in monitoring the assumeutxo sync process. + +- A new `getprioritisedtransactions` RPC has been added. It returns a map of all fee deltas created by the + user with prioritisetransaction, indexed by txid. The map also indicates whether each transaction is + present in the mempool. (#27501) + +- A new RPC, `submitpackage`, has been added. It can be used to submit a list of raw hex +transactions to the mempool to be evaluated as a package using consensus and mempool policy rules. +These policies include package CPFP, allowing a child with high fees to bump a parent below the +mempool minimum feerate (but not minimum relay feerate). (#27609) + + - Warning: successful submission does not mean the transactions will propagate throughout the + network, as package relay is not supported. + + - Not all features are available. The package is limited to a child with all of its + unconfirmed parents, and no parent may spend the output of another parent. Also, package + RBF is not supported. Refer to doc/policy/packages.md for more details on package policies + and limitations. + + - This RPC is experimental. Its interface may change. + +- A new RPC `getaddrmaninfo` has been added to view the distribution of addresses in the new and tried table of the + node's address manager across different networks(ipv4, ipv6, onion, i2p, cjdns). The RPC returns count of addresses + in new and tried table as well as their sum for all networks. (#27511) + +- A new `importmempool` RPC has been added. It loads a valid `mempool.dat` file and attempts to + add its contents to the mempool. This can be useful to import mempool data from another node + without having to modify the datadir contents and without having to restart the node. (#27460) + - Warning: Importing untrusted files is dangerous, especially if metadata from the file is taken over. + - If you want to apply fee deltas, it is recommended to use the `getprioritisedtransactions` and + `prioritisetransaction` RPCs instead of the `apply_fee_delta_priority` option to avoid + double-prioritising any already-prioritised transactions in the mempool. + +Updated settings +---------------- + +- `bitcoind` and `bitcoin-qt` will now raise an error on startup + if a datadir that is being used contains a bitcoin.conf file that + will be ignored, which can happen when a datadir= line is used in + a bitcoin.conf file. The error message is just a diagnostic intended + to prevent accidental misconfiguration, and it can be disabled to + restore the previous behavior of using the datadir while ignoring + the bitcoin.conf contained in it. (#27302) + +- Passing an invalid `-debug`, `-debugexclude`, or `-loglevel` logging configuration + option now raises an error, rather than logging an easily missed warning. (#27632) + +Changes to GUI or wallet related settings can be found in the GUI or Wallet section below. + +New settings +------------ + +Tools and Utilities +------------------- + +- A new `bitcoinconsensus_verify_script_with_spent_outputs` function is available in libconsensus which optionally accepts the spent outputs of the transaction being verified. +- A new `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT` flag is available in libconsensus that will verify scripts with the Taproot spending rules. + +Wallet +------ + +- Wallet loading has changed in this release. Wallets with some corrupted records that could be + previously loaded (with warnings) may no longer load. For example, wallets with corrupted + address book entries may no longer load. If this happens, it is recommended + load the wallet in a previous version of Bitcoin Core and import the data into a new wallet. + Please also report an issue to help improve the software and make wallet loading more robust + in these cases. (#24914) + +- The `gettransaction`, `listtransactions`, `listsinceblock` RPCs now return + the `abandoned` field for all transactions. Previously, the "abandoned" field + was only returned for sent transactions. (#25158) + +- The `listdescriptors`, `decodepsbt` and similar RPC methods now show `h` rather than apostrophe (`'`) to indicate + hardened derivation. This does not apply when using the `private` parameter, which + matches the marker used when descriptor was generated or imported. Newly created + wallets use `h`. This change makes it easier to handle descriptor strings manually. + E.g. the `importdescriptors` RPC call is easiest to use `h` as the marker: `'["desc": ".../0h/..."]'`. + With this change `listdescriptors` will use `h`, so you can copy-paste the result, + without having to add escape characters or switch `'` to 'h' manually. + Note that this changes the descriptor checksum. + For legacy wallets the `hdkeypath` field in `getaddressinfo` is unchanged, + nor is the serialization format of wallet dumps. (#26076) + +- The `getbalances` RPC now returns a `lastprocessedblock` JSON object which contains the wallet's last processed block + hash and height at the time the balances were calculated. This result shouldn't be cached because importing new keys could invalidate it. (#26094) + +- The `gettransaction` RPC now returns a `lastprocessedblock` JSON object which contains the wallet's last processed block + hash and height at the time the transaction information was generated. (#26094) + +- The `getwalletinfo` RPC now returns a `lastprocessedblock` JSON object which contains the wallet's last processed block + hash and height at the time the wallet information was generated. (#26094) + +- Coin selection and transaction building now accounts for unconfirmed low-feerate ancestor transactions. When it is necessary to spend unconfirmed outputs, the wallet will add fees to ensure that the new transaction with its ancestors will achieve a mining score equal to the feerate requested by the user. (#26152) + +- For RPC methods which accept `options` parameters ((`importmulti`, `listunspent`, + `fundrawtransaction`, `bumpfee`, `send`, `sendall`, `walletcreatefundedpsbt`, + `simulaterawtransaction`), it is now possible to pass the options as named + parameters without the need for a nested object. (#26485) + +This means it is possible make calls like: + +```sh +src/bitcoin-cli -named bumpfee txid fee_rate=100 +``` + +instead of + +```sh +src/bitcoin-cli -named bumpfee txid options='{"fee_rate": 100}' +``` + +- The `deprecatedrpc=walletwarningfield` configuration option has been removed. + The `createwallet`, `loadwallet`, `restorewallet` and `unloadwallet` RPCs no + longer return the "warning" string field. The same information is provided + through the "warnings" field added in v25.0, which returns a JSON array of + strings. The "warning" string field was deprecated also in v25.0. (#27757) + +- The `signrawtransactionwithkey`, `signrawtransactionwithwallet`, + `walletprocesspsbt` and `descriptorprocesspsbt` calls now return the more + specific RPC_INVALID_PARAMETER error instead of RPC_MISC_ERROR if their + sighashtype argument is malformed. (#28113) + +- RPC `walletprocesspsbt`, and `descriptorprocesspsbt` return + object now includes field `hex` (if the transaction + is complete) containing the serialized transaction + suitable for RPC `sendrawtransaction`. (#28414) + +- It's now possible to use [Miniscript](https://bitcoin.sipa.be/miniscript/) inside Taproot leaves for descriptor wallets. (#27255) + +GUI changes +----------- + +- The transaction list in the GUI no longer provides a special category for "payment to yourself". Now transactions that have both inputs and outputs that affect the wallet are displayed on separate lines for spending and receiving. (gui#119) + +- A new menu option allows migrating a legacy wallet based on keys and implied output script types stored in BerkeleyDB (BDB) to a modern wallet that uses descriptors stored in SQLite. (gui#738) + +- The PSBT operations dialog marks outputs paying your own wallet with "own address". (gui#740) + +- The ability to create legacy wallets is being removed. (gui#764) + +Low-level changes +================= + +Tests +----- + +- Non-standard transactions are now disabled by default on testnet + for relay and mempool acceptance. The previous behaviour can be + re-enabled by setting `-acceptnonstdtxn=1`. (#28354) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- 0xb10c +- Amiti Uttarwar +- Andrew Chow +- Andrew Toth +- Anthony Towns +- Antoine Poinsot +- Antoine Riard +- Ari +- Aurèle Oulès +- Ayush Singh +- Ben Woosley +- Brandon Odiwuor +- Brotcrunsher +- brunoerg +- Bufo +- Carl Dong +- Casey Carter +- Cory Fields +- David Álvarez Rosa +- dergoegge +- dhruv +- dimitaracev +- Erik Arvstedt +- Erik McKelvey +- Fabian Jahr +- furszy +- glozow +- Greg Sanders +- Harris +- Hennadii Stepanov +- Hernan Marino +- ishaanam +- ismaelsadeeq +- Jake Rawsthorne +- James O'Beirne +- John Moffett +- Jon Atack +- josibake +- kevkevin +- Kiminuo +- Larry Ruane +- Luke Dashjr +- MarcoFalke +- Marnix +- Martin Leitner-Ankerl +- Martin Zumsande +- Matthew Zipkin +- Michael Ford +- Michael Tidwell +- mruddy +- Murch +- ns-xvrn +- pablomartin4btc +- Pieter Wuille +- Reese Russell +- Rhythm Garg +- Ryan Ofsky +- Sebastian Falbesoner +- Sjors Provoost +- stickies-v +- stratospher +- Suhas Daftuar +- TheCharlatan +- Tim Neubauer +- Tim Ruffing +- Vasil Dimov +- virtu +- vuittont60 +- willcl-ark +- Yusuf Sahin HAMZA + +As well as to everyone that helped with translations on +[Transifex](https://www.transifex.com/bitcoin/bitcoin/). From d2c80b6f52f255c8d9237177bf0bd1b160409b81 Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 7 Dec 2023 15:35:44 +0000 Subject: [PATCH 02/18] doc: Missing additions to 26.0 release notes Github-Pull: #29023 Rebased-From: ca5937553b4b4dde53995d0b66e30150401023eb --- doc/release-notes/release-notes-26.0.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/release-notes/release-notes-26.0.md b/doc/release-notes/release-notes-26.0.md index b30dadf62b..b7c7c35f65 100644 --- a/doc/release-notes/release-notes-26.0.md +++ b/doc/release-notes/release-notes-26.0.md @@ -173,6 +173,11 @@ Wallet Please also report an issue to help improve the software and make wallet loading more robust in these cases. (#24914) +- The `createwallet` RPC will no longer create legacy (BDB) wallets when + setting `descriptors=false` without also providing the + `-deprecatedrpc=create_bdb` option. This is because the legacy wallet is + being deprecated in a future release. (#28597) + - The `gettransaction`, `listtransactions`, `listsinceblock` RPCs now return the `abandoned` field for all transactions. Previously, the "abandoned" field was only returned for sent transactions. (#25158) @@ -234,6 +239,14 @@ src/bitcoin-cli -named bumpfee txid options='{"fee_rate": 100}' - It's now possible to use [Miniscript](https://bitcoin.sipa.be/miniscript/) inside Taproot leaves for descriptor wallets. (#27255) +Descriptors +----------- + +- The usage of hybrid public keys in output descriptors has been removed. Hybrid + public keys are an exotic public key encoding not supported by output descriptors + (as specified in BIP380 and documented in doc/descriptors.md). Bitcoin Core would + previously incorrectly accept descriptors containing such hybrid keys. (#28587) + GUI changes ----------- @@ -245,6 +258,15 @@ GUI changes - The ability to create legacy wallets is being removed. (gui#764) +Contrib +------- + +- Bash completion files have been renamed from `bitcoin*.bash-completion` to + `bitcoin*.bash`. This means completions can be automatically loaded on demand + based on invoked commands' names when they are put into the completion + directory (found with `pkg-config --variable=completionsdir + bash-completion`) without requiring renaming. (#28507) + Low-level changes ================= From 69e53d1e47613efb831d01e446b790d21c35ba4b Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Mon, 4 Dec 2023 09:44:21 +0100 Subject: [PATCH 03/18] ci: Use Ubuntu 24.04 Noble for tsan,tidy,fuzz Github-Pull: #28992 Rebased-From: fa83b65ef8934b44fbac02da8dbc27fc0bc230e6 --- ci/test/00_setup_env_native_fuzz.sh | 2 +- ci/test/00_setup_env_native_tidy.sh | 2 +- ci/test/00_setup_env_native_tsan.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh index 122f044b58..c13ee0cbe9 100755 --- a/ci/test/00_setup_env_native_fuzz.sh +++ b/ci/test/00_setup_env_native_fuzz.sh @@ -6,7 +6,7 @@ export LC_ALL=C.UTF-8 -export CI_IMAGE_NAME_TAG="docker.io/ubuntu:23.10" # This version will reach EOL in Jul 2024, and can be replaced by "ubuntu:24.04" (or anything else that ships the wanted clang version). +export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" export CONTAINER_NAME=ci_native_fuzz export PACKAGES="clang-17 llvm-17 libclang-rt-17-dev libevent-dev libboost-dev libsqlite3-dev" export NO_DEPENDS=1 diff --git a/ci/test/00_setup_env_native_tidy.sh b/ci/test/00_setup_env_native_tidy.sh index 6b0c708f19..c03392af06 100755 --- a/ci/test/00_setup_env_native_tidy.sh +++ b/ci/test/00_setup_env_native_tidy.sh @@ -6,7 +6,7 @@ export LC_ALL=C.UTF-8 -export CI_IMAGE_NAME_TAG="docker.io/ubuntu:23.10" # This version will reach EOL in Jul 2024, and can be replaced by "ubuntu:24.04" (or anything else that ships the wanted clang version). +export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" export CONTAINER_NAME=ci_native_tidy export TIDY_LLVM_V="17" export PACKAGES="clang-${TIDY_LLVM_V} libclang-${TIDY_LLVM_V}-dev llvm-${TIDY_LLVM_V}-dev libomp-${TIDY_LLVM_V}-dev clang-tidy-${TIDY_LLVM_V} jq bear cmake libevent-dev libboost-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev systemtap-sdt-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode-dev libsqlite3-dev libdb++-dev" diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index 67c29d4bc8..aa23bad809 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -7,7 +7,7 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_native_tsan -export CI_IMAGE_NAME_TAG="docker.io/ubuntu:23.10" # This version will reach EOL in Jul 2024, and can be replaced by "ubuntu:24.04" (or anything else that ships the wanted clang version). +export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" export PACKAGES="clang-17 llvm-17 libclang-rt-17-dev libc++abi-17-dev libc++-17-dev python3-zmq" export DEP_OPTS="CC=clang-17 CXX='clang++-17 -stdlib=libc++'" export GOAL="install" From 81e744a9a6a55cb5c2b88cd6eeb9dd6523f3a438 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Mon, 4 Dec 2023 12:35:04 +0100 Subject: [PATCH 04/18] ci: Use Ubuntu 24.04 Noble for asan Github-Pull: #28992 Rebased-From: fad2392c5861a88a87cb8a03d2fc9773e178feb8 --- .cirrus.yml | 4 ++-- ci/test/00_setup_env_native_asan.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 3f52adde8a..3669d168c1 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -43,7 +43,7 @@ env: # Global defaults # The following specific types should exist, with the following requirements: # - small: For an x86_64 machine, recommended to have 2 CPUs and 8 GB of memory. # - medium: For an x86_64 machine, recommended to have 4 CPUs and 16 GB of memory. -# - mantic: For a machine running the Linux kernel shipped with exaclty Ubuntu Mantic 23.10. The machine is recommended to have 4 CPUs and 16 GB of memory. +# - noble: For a machine running the Linux kernel shipped with exaclty Ubuntu Noble 24.04. The machine is recommended to have 4 CPUs and 16 GB of memory. # - arm64: For an aarch64 machine, recommended to have 2 CPUs and 8 GB of memory. # https://cirrus-ci.org/guide/tips-and-tricks/#sharing-configuration-between-tasks @@ -165,7 +165,7 @@ task: << : *GLOBAL_TASK_TEMPLATE persistent_worker: labels: - type: mantic # Must use this specific worker (needed for USDT functional tests) + type: noble # Must use this specific worker (needed for USDT functional tests) env: FILE_ENV: "./ci/test/00_setup_env_native_asan.sh" diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh index 93d84bf17e..60486f8f61 100755 --- a/ci/test/00_setup_env_native_asan.sh +++ b/ci/test/00_setup_env_native_asan.sh @@ -6,6 +6,7 @@ export LC_ALL=C.UTF-8 +export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" # Only install BCC tracing packages in Cirrus CI. if [[ "${CIRRUS_CI}" == "true" ]]; then BPFCC_PACKAGE="bpfcc-tools linux-headers-$(uname --kernel-release)" @@ -17,7 +18,6 @@ fi export CONTAINER_NAME=ci_native_asan export PACKAGES="systemtap-sdt-dev clang-17 llvm-17 libclang-rt-17-dev python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev libboost-dev libdb5.3++-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev libqrencode-dev libsqlite3-dev ${BPFCC_PACKAGE}" -export CI_IMAGE_NAME_TAG="docker.io/ubuntu:23.10" # This version will reach EOL in Jul 2024, and can be replaced by "ubuntu:24.04" (or anything else that ships the wanted clang version). export NO_DEPENDS=1 export GOAL="install" export BITCOIN_CONFIG="--enable-c++20 --enable-usdt --enable-zmq --with-incompatible-bdb --with-gui=qt5 \ From 5097bb3389fe3add504851302918692b3f05db70 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Tue, 5 Dec 2023 13:07:39 -0500 Subject: [PATCH 05/18] rpc: fix getrawtransaction segfault The crash would happen when querying a mempool transaction with verbosity=2, while pruning. Github-Pull: #29003 Rebased-From: 494a926d05df44b60b3bc1145ad2a64acf96f61b --- src/rpc/rawtransaction.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 16705b3ce2..b30b0bbfeb 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -396,7 +396,7 @@ static RPCHelpMan getrawtransaction() LOCK(cs_main); blockindex = chainman.m_blockman.LookupBlockIndex(hash_block); } - if (verbosity == 1) { + if (verbosity == 1 || !blockindex) { TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate()); return result; } @@ -405,8 +405,7 @@ static RPCHelpMan getrawtransaction() CBlock block; const bool is_block_pruned{WITH_LOCK(cs_main, return chainman.m_blockman.IsBlockPruned(blockindex))}; - if (tx->IsCoinBase() || - !blockindex || is_block_pruned || + if (tx->IsCoinBase() || is_block_pruned || !(chainman.m_blockman.UndoReadFromDisk(blockUndo, *blockindex) && chainman.m_blockman.ReadBlockFromDisk(block, *blockindex))) { TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate()); return result; From b15e2e2cec596662275e790449fd250b6be75076 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Tue, 5 Dec 2023 16:36:43 -0500 Subject: [PATCH 06/18] test: add regression test for the getrawtransaction segfault This fails on master without the previous commit. Github-Pull: #29003 Rebased-From: 9075a446461ccbc446d21af778aac50b604f39b3 --- test/functional/rpc_rawtransaction.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py index 2395935620..c12865b5e3 100755 --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -32,6 +32,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, + assert_greater_than, assert_raises_rpc_error, ) from test_framework.wallet import ( @@ -70,7 +71,7 @@ def set_test_params(self): self.extra_args = [ ["-txindex"], ["-txindex"], - [], + ["-fastprune", "-prune=1"], ] # whitelist all peers to speed up tx relay / mempool sync for args in self.extra_args: @@ -85,7 +86,6 @@ def run_test(self): self.wallet = MiniWallet(self.nodes[0]) self.getrawtransaction_tests() - self.getrawtransaction_verbosity_tests() self.createrawtransaction_tests() self.sendrawtransaction_tests() self.sendrawtransaction_testmempoolaccept_tests() @@ -94,6 +94,8 @@ def run_test(self): if self.is_specified_wallet_compiled() and not self.options.descriptors: self.import_deterministic_coinbase_privkeys() self.raw_multisig_transaction_legacy_tests() + self.getrawtransaction_verbosity_tests() + def getrawtransaction_tests(self): tx = self.wallet.send_self_transfer(from_node=self.nodes[0]) @@ -243,6 +245,13 @@ def getrawtransaction_verbosity_tests(self): coin_base = self.nodes[1].getblock(block1)['tx'][0] gottx = self.nodes[1].getrawtransaction(txid=coin_base, verbosity=2, blockhash=block1) assert 'fee' not in gottx + # check that verbosity 2 for a mempool tx will fallback to verbosity 1 + # Do this with a pruned chain, as a regression test for https://github.com/bitcoin/bitcoin/pull/29003 + self.generate(self.nodes[2], 400) + assert_greater_than(self.nodes[2].pruneblockchain(250), 0) + mempool_tx = self.wallet.send_self_transfer(from_node=self.nodes[2])['txid'] + gottx = self.nodes[2].getrawtransaction(txid=mempool_tx, verbosity=2) + assert 'fee' not in gottx def createrawtransaction_tests(self): self.log.info("Test createrawtransaction") From 5493ebbe7428f95e41d5c7a64aea9e7f33190579 Mon Sep 17 00:00:00 2001 From: Murch Date: Fri, 6 Oct 2023 15:32:32 -0400 Subject: [PATCH 07/18] wallet: skip BnB when SFFO is active Co-authored-by: furszy Github-Pull: #28994 Rebased-From: 5cea25ba795d6eb9ccc721d01560783ae576af34 --- src/wallet/spend.cpp | 9 ++++-- src/wallet/test/coinselector_tests.cpp | 38 +++++++++++++++----------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index 8314a2ddfa..7cf1c34454 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -693,9 +693,12 @@ util::Result ChooseSelectionResult(interfaces::Chain& chain, co // Maximum allowed weight int max_inputs_weight = MAX_STANDARD_TX_WEIGHT - (coin_selection_params.tx_noinputs_size * WITNESS_SCALE_FACTOR); - if (auto bnb_result{SelectCoinsBnB(groups.positive_group, nTargetValue, coin_selection_params.m_cost_of_change, max_inputs_weight)}) { - results.push_back(*bnb_result); - } else append_error(bnb_result); + // SFFO frequently causes issues in the context of changeless input sets: skip BnB when SFFO is active + if (!coin_selection_params.m_subtract_fee_outputs) { + if (auto bnb_result{SelectCoinsBnB(groups.positive_group, nTargetValue, coin_selection_params.m_cost_of_change, max_inputs_weight)}) { + results.push_back(*bnb_result); + } else append_error(bnb_result); + } // As Knapsack and SRD can create change, also deduce change weight. max_inputs_weight -= (coin_selection_params.change_output_size * WITNESS_SCALE_FACTOR); diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp index 9569210ba0..3b7bd914ed 100644 --- a/src/wallet/test/coinselector_tests.cpp +++ b/src/wallet/test/coinselector_tests.cpp @@ -320,7 +320,6 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) coin_selection_params_bnb.m_change_fee = coin_selection_params_bnb.m_effective_feerate.GetFee(coin_selection_params_bnb.change_output_size); coin_selection_params_bnb.m_cost_of_change = coin_selection_params_bnb.m_effective_feerate.GetFee(coin_selection_params_bnb.change_spend_size) + coin_selection_params_bnb.m_change_fee; coin_selection_params_bnb.min_viable_change = coin_selection_params_bnb.m_effective_feerate.GetFee(coin_selection_params_bnb.change_spend_size); - coin_selection_params_bnb.m_subtract_fee_outputs = true; { std::unique_ptr wallet = NewWallet(m_node); @@ -345,6 +344,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) CoinsResult available_coins; + coin_selection_params_bnb.m_effective_feerate = CFeeRate(0); add_coin(available_coins, *wallet, 5 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); add_coin(available_coins, *wallet, 3 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); add_coin(available_coins, *wallet, 2 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); @@ -355,7 +355,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) PreSelectedInputs selected_input; selected_input.Insert(select_coin, coin_selection_params_bnb.m_subtract_fee_outputs); available_coins.Erase({available_coins.coins[OutputType::BECH32].begin()->outpoint}); - coin_selection_params_bnb.m_effective_feerate = CFeeRate(0); + LOCK(wallet->cs_wallet); const auto result10 = SelectCoins(*wallet, available_coins, selected_input, 10 * CENT, coin_control, coin_selection_params_bnb); BOOST_CHECK(result10); @@ -370,12 +370,14 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) coin_selection_params_bnb.m_effective_feerate = CFeeRate(5000); coin_selection_params_bnb.m_long_term_feerate = CFeeRate(3000); - add_coin(available_coins, *wallet, 10 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); - add_coin(available_coins, *wallet, 9 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); - add_coin(available_coins, *wallet, 1 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); + // Add selectable outputs, increasing their raw amounts by their input fee to make the effective value equal to the raw amount + CAmount input_fee = coin_selection_params_bnb.m_effective_feerate.GetFee(/*num_bytes=*/68); // bech32 input size (default test output type) + add_coin(available_coins, *wallet, 10 * CENT + input_fee, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); + add_coin(available_coins, *wallet, 9 * CENT + input_fee, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); + add_coin(available_coins, *wallet, 1 * CENT + input_fee, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); expected_result.Clear(); - add_coin(10 * CENT, 2, expected_result); + add_coin(10 * CENT + input_fee, 2, expected_result); CCoinControl coin_control; const auto result11 = SelectCoins(*wallet, available_coins, /*pre_set_inputs=*/{}, 10 * CENT, coin_control, coin_selection_params_bnb); BOOST_CHECK(EquivalentResult(expected_result, *result11)); @@ -385,13 +387,15 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) coin_selection_params_bnb.m_effective_feerate = CFeeRate(3000); coin_selection_params_bnb.m_long_term_feerate = CFeeRate(5000); - add_coin(available_coins, *wallet, 10 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); - add_coin(available_coins, *wallet, 9 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); - add_coin(available_coins, *wallet, 1 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); + // Add selectable outputs, increasing their raw amounts by their input fee to make the effective value equal to the raw amount + input_fee = coin_selection_params_bnb.m_effective_feerate.GetFee(/*num_bytes=*/68); // bech32 input size (default test output type) + add_coin(available_coins, *wallet, 10 * CENT + input_fee, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); + add_coin(available_coins, *wallet, 9 * CENT + input_fee, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); + add_coin(available_coins, *wallet, 1 * CENT + input_fee, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); expected_result.Clear(); - add_coin(9 * CENT, 2, expected_result); - add_coin(1 * CENT, 2, expected_result); + add_coin(9 * CENT + input_fee, 2, expected_result); + add_coin(1 * CENT + input_fee, 2, expected_result); const auto result12 = SelectCoins(*wallet, available_coins, /*pre_set_inputs=*/{}, 10 * CENT, coin_control, coin_selection_params_bnb); BOOST_CHECK(EquivalentResult(expected_result, *result12)); available_coins.Clear(); @@ -400,13 +404,15 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) coin_selection_params_bnb.m_effective_feerate = CFeeRate(5000); coin_selection_params_bnb.m_long_term_feerate = CFeeRate(3000); - add_coin(available_coins, *wallet, 10 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); - add_coin(available_coins, *wallet, 9 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); - add_coin(available_coins, *wallet, 1 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); + // Add selectable outputs, increasing their raw amounts by their input fee to make the effective value equal to the raw amount + input_fee = coin_selection_params_bnb.m_effective_feerate.GetFee(/*num_bytes=*/68); // bech32 input size (default test output type) + add_coin(available_coins, *wallet, 10 * CENT + input_fee, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); + add_coin(available_coins, *wallet, 9 * CENT + input_fee, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); + add_coin(available_coins, *wallet, 1 * CENT + input_fee, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true); expected_result.Clear(); - add_coin(9 * CENT, 2, expected_result); - add_coin(1 * CENT, 2, expected_result); + add_coin(9 * CENT + input_fee, 2, expected_result); + add_coin(1 * CENT + input_fee, 2, expected_result); coin_control.m_allow_other_inputs = true; COutput select_coin = available_coins.All().at(1); // pre select 9 coin coin_control.Select(select_coin.outpoint); From 05d0576d3c03ae3797c91ac51bff4e2a18d6a993 Mon Sep 17 00:00:00 2001 From: furszy Date: Fri, 29 Sep 2023 09:42:04 -0300 Subject: [PATCH 08/18] wallet: create tx, log resulting coin selection info Useful for understanding what is going on internally when the software is running. Debug issues, and provide more accurate feedback to users. Github-Pull: #28994 Rebased-From: 0c5755761c3e544547899ad096121585dffa73df --- src/wallet/spend.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index 7cf1c34454..e473c5a093 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -1263,6 +1263,7 @@ static util::Result CreateTransactionInternal( // accidental re-use. reservedest.KeepDestination(); + wallet.WalletLogPrintf("Coin Selection: Algorithm:%s, Waste Metric Score:%d\n", GetAlgorithmName(result.GetAlgo()), result.GetWaste()); wallet.WalletLogPrintf("Fee Calculation: Fee:%d Bytes:%u Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n", current_fee, nBytes, feeCalc.returnedTarget, feeCalc.desiredTarget, StringForFeeReason(feeCalc.reason), feeCalc.est.decay, feeCalc.est.pass.start, feeCalc.est.pass.end, From 903b4623d369d86925093fdce08d18019e5266e1 Mon Sep 17 00:00:00 2001 From: furszy Date: Tue, 12 Sep 2023 12:14:59 -0300 Subject: [PATCH 09/18] test: add coverage for BnB-SFFO restriction Verify the transaction creation process does not produce a BnB solution when SFFO is enabled. This is currently problematic because it could require a change output. And BnB is specialized on changeless solutions. Co-authored-by: Andrew Chow Co-authored-by: Murch Github-Pull: #28994 Rebased-From: 05e5ff194c7722b4ebc2b9309fc0bf47b3cf1df7 --- src/wallet/test/coinselector_tests.cpp | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp index 3b7bd914ed..2b7ae888d8 100644 --- a/src/wallet/test/coinselector_tests.cpp +++ b/src/wallet/test/coinselector_tests.cpp @@ -455,6 +455,44 @@ BOOST_AUTO_TEST_CASE(bnb_search_test) } } +BOOST_AUTO_TEST_CASE(bnb_sffo_restriction) +{ + // Verify the coin selection process does not produce a BnB solution when SFFO is enabled. + // This is currently problematic because it could require a change output. And BnB is specialized on changeless solutions. + std::unique_ptr wallet = NewWallet(m_node); + WITH_LOCK(wallet->cs_wallet, wallet->SetLastBlockProcessed(300, uint256{})); // set a high block so internal UTXOs are selectable + + FastRandomContext rand{}; + CoinSelectionParams params{ + rand, + /*change_output_size=*/ 31, // unused value, p2wpkh output size (wallet default change type) + /*change_spend_size=*/ 68, // unused value, p2wpkh input size (high-r signature) + /*min_change_target=*/ 0, // dummy, set later + /*effective_feerate=*/ CFeeRate(3000), + /*long_term_feerate=*/ CFeeRate(1000), + /*discard_feerate=*/ CFeeRate(1000), + /*tx_noinputs_size=*/ 0, + /*avoid_partial=*/ false, + }; + params.m_subtract_fee_outputs = true; + params.m_change_fee = params.m_effective_feerate.GetFee(params.change_output_size); + params.m_cost_of_change = params.m_discard_feerate.GetFee(params.change_spend_size) + params.m_change_fee; + params.m_min_change_target = params.m_cost_of_change + 1; + // Add spendable coin at the BnB selection upper bound + CoinsResult available_coins; + add_coin(available_coins, *wallet, COIN + params.m_cost_of_change, /*feerate=*/params.m_effective_feerate, /*nAge=*/6, /*fIsFromMe=*/true, /*nInput=*/0, /*spendable=*/true); + add_coin(available_coins, *wallet, 0.5 * COIN + params.m_cost_of_change, /*feerate=*/params.m_effective_feerate, /*nAge=*/6, /*fIsFromMe=*/true, /*nInput=*/0, /*spendable=*/true); + add_coin(available_coins, *wallet, 0.5 * COIN, /*feerate=*/params.m_effective_feerate, /*nAge=*/6, /*fIsFromMe=*/true, /*nInput=*/0, /*spendable=*/true); + // Knapsack will only find a changeless solution on an exact match to the satoshi, SRD doesn’t look for changeless + // If BnB were run, it would produce a single input solution with the best waste score + auto result = WITH_LOCK(wallet->cs_wallet, return SelectCoins(*wallet, available_coins, /*pre_set_inputs=*/{}, COIN, /*coin_control=*/{}, params)); + BOOST_CHECK(result.has_value()); + BOOST_CHECK_NE(result->GetAlgo(), SelectionAlgorithm::BNB); + BOOST_CHECK(result->GetInputSet().size() == 2); + // We have only considered BnB, SRD, and Knapsack. Test needs to be reevaluated if new algo is added + BOOST_CHECK(result->GetAlgo() == SelectionAlgorithm::SRD || result->GetAlgo() == SelectionAlgorithm::KNAPSACK); +} + BOOST_AUTO_TEST_CASE(knapsack_solver_test) { FastRandomContext rand{}; From 35039ac3cc1c2318762907961aee412a7239ce9b Mon Sep 17 00:00:00 2001 From: furszy Date: Mon, 4 Dec 2023 11:36:20 -0300 Subject: [PATCH 10/18] fuzz: disable BnB when SFFO is enabled Github-Pull: #28994 Rebased-From: 576bee88fd36e207b7288077626947a1fce0fc33 --- src/wallet/test/fuzz/coinselection.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/test/fuzz/coinselection.cpp b/src/wallet/test/fuzz/coinselection.cpp index 4caf96b18d..ade3ec3f60 100644 --- a/src/wallet/test/fuzz/coinselection.cpp +++ b/src/wallet/test/fuzz/coinselection.cpp @@ -116,7 +116,8 @@ FUZZ_TARGET(coinselection) } // Run coinselection algorithms - auto result_bnb = SelectCoinsBnB(group_pos, target, coin_params.m_cost_of_change, MAX_STANDARD_TX_WEIGHT); + auto result_bnb = coin_params.m_subtract_fee_outputs ? util::Error{Untranslated("BnB disabled when SFFO is enabled")} : + SelectCoinsBnB(group_pos, target, coin_params.m_cost_of_change, MAX_STANDARD_TX_WEIGHT); if (result_bnb) { assert(result_bnb->GetChange(coin_params.m_cost_of_change, CAmount{0}) == 0); assert(result_bnb->GetSelectedValue() >= target); From 074296dd60ef49bf6b28b191472f45ea4f995b4b Mon Sep 17 00:00:00 2001 From: furszy Date: Mon, 20 Nov 2023 18:04:57 -0300 Subject: [PATCH 11/18] refactor: rename FirstKeyTimeChanged to MaybeUpdateBirthTime In the following-up commit, the wallet birth time will also be modified by the transactions scanning process. When a tx older than all descriptor's timestamp is detected. Github-Pull: #28920 Rebased-From: b4306e3c8db6cbaedc8845c6d21c750b39f682bf --- src/wallet/wallet.cpp | 12 +++++++----- src/wallet/wallet.h | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 162d7f9ec7..2219028e3f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1763,11 +1763,11 @@ bool CWallet::ImportScriptPubKeys(const std::string& label, const std::set spkm_man) { + // Add spkm_man to m_spk_managers before calling any method + // that might access it. const auto& spkm = m_spk_managers[id] = std::move(spkm_man); // Update birth time if needed - FirstKeyTimeChanged(spkm.get(), spkm->GetTimeFirstKey()); + MaybeUpdateBirthTime(spkm->GetTimeFirstKey()); } void CWallet::SetupLegacyScriptPubKeyMan() @@ -3530,7 +3532,7 @@ void CWallet::ConnectScriptPubKeyManNotifiers() for (const auto& spk_man : GetActiveScriptPubKeyMans()) { spk_man->NotifyWatchonlyChanged.connect(NotifyWatchonlyChanged); spk_man->NotifyCanGetAddressesChanged.connect(NotifyCanGetAddressesChanged); - spk_man->NotifyFirstKeyTimeChanged.connect(std::bind(&CWallet::FirstKeyTimeChanged, this, std::placeholders::_1, std::placeholders::_2)); + spk_man->NotifyFirstKeyTimeChanged.connect(std::bind(&CWallet::MaybeUpdateBirthTime, this, std::placeholders::_2)); } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 9333493a6e..b7c64f5267 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -678,8 +678,8 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati bool ImportPubKeys(const std::vector& ordered_pubkeys, const std::map& pubkey_map, const std::map>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool ImportScriptPubKeys(const std::string& label, const std::set& script_pub_keys, const bool have_solving_data, const bool apply_label, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); - /** Updates wallet birth time if 'new_birth_time' is below it */ - void FirstKeyTimeChanged(const ScriptPubKeyMan* spkm, int64_t new_birth_time); + /** Updates wallet birth time if 'time' is below it */ + void MaybeUpdateBirthTime(int64_t time); CFeeRate m_pay_tx_fee{DEFAULT_PAY_TX_FEE}; unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET}; From 84f4a6c14587344652ef34dbf944364580417a87 Mon Sep 17 00:00:00 2001 From: furszy Date: Mon, 20 Nov 2023 12:41:50 -0300 Subject: [PATCH 12/18] wallet: birth time update during tx scanning As the user could have imported a descriptor with a newer timestamp (by blindly setting 'timestamp=now'), the wallet needs to update the birth time when it detects a transaction older than the oldest descriptor timestamp. Github-Pull: #28920 Rebased-From: 75fbf444c1e13c6ba0e79a34871534c845a13849 --- src/wallet/wallet.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2219028e3f..78febb8195 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1080,6 +1080,9 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const TxState& state, const wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx)); wtx.nTimeSmart = ComputeTimeSmart(wtx, rescanning_old_block); AddToSpends(wtx, &batch); + + // Update birth time when tx time is older than it. + MaybeUpdateBirthTime(wtx.GetTxTime()); } if (!fInsertedNew) @@ -1215,6 +1218,10 @@ bool CWallet::LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx } } } + + // Update birth time when tx time is older than it. + MaybeUpdateBirthTime(wtx.GetTxTime()); + return true; } @@ -3103,7 +3110,7 @@ std::shared_ptr CWallet::Create(WalletContext& context, const std::stri int64_t time = spk_man->GetTimeFirstKey(); if (!time_first_key || time < *time_first_key) time_first_key = time; } - if (time_first_key) walletInstance->m_birth_time = *time_first_key; + if (time_first_key) walletInstance->MaybeUpdateBirthTime(*time_first_key); if (chain && !AttachChain(walletInstance, *chain, rescan_required, error, warnings)) { return nullptr; From 0fa47e2569a40e74db701f16421b8638a486ebd3 Mon Sep 17 00:00:00 2001 From: furszy Date: Tue, 28 Nov 2023 17:31:45 -0300 Subject: [PATCH 13/18] wallet: fix legacy spkm default birth time To avoid scanning blocks, as assumed by a wallet with no generated keys or imported scripts, the default value for the birth time needs to be set to the maximum int64_t value. Once the first key is generated or the first script is imported, the legacy SPKM will update the birth time automatically. Github-Pull: #28920 Rebased-From: 6f497377aa17cb8a590fd7717fa8ededf4249999 --- src/wallet/scriptpubkeyman.cpp | 2 +- src/wallet/scriptpubkeyman.h | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index bc3327cdb2..f5f3a17ae7 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -709,7 +709,7 @@ void LegacyScriptPubKeyMan::UpdateTimeFirstKey(int64_t nCreateTime) // Cannot determine birthday information, so set the wallet birthday to // the beginning of time. nTimeFirstKey = 1; - } else if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) { + } else if (nTimeFirstKey == UNKNOWN_TIME || nCreateTime < nTimeFirstKey) { nTimeFirstKey = nCreateTime; } diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index 7c0eca1475..7231486df0 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -51,6 +51,9 @@ class WalletStorage virtual bool IsLocked() const = 0; }; +//! Constant representing an unknown spkm creation time +static constexpr int64_t UNKNOWN_TIME = std::numeric_limits::max(); + //! Default for -keypool static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000; @@ -286,7 +289,8 @@ class LegacyScriptPubKeyMan : public ScriptPubKeyMan, public FillableSigningProv WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore); WatchKeyMap mapWatchKeys GUARDED_BY(cs_KeyStore); - int64_t nTimeFirstKey GUARDED_BY(cs_KeyStore) = 0; + // By default, do not scan any block until keys/scripts are generated/imported + int64_t nTimeFirstKey GUARDED_BY(cs_KeyStore) = UNKNOWN_TIME; //! Number of pre-generated keys/scripts (part of the look-ahead process, used to detect payments) int64_t m_keypool_size GUARDED_BY(cs_KeyStore){DEFAULT_KEYPOOL_SIZE}; From 12834012c2a31f7c33e3410d67edba1eaec53ae9 Mon Sep 17 00:00:00 2001 From: furszy Date: Mon, 20 Nov 2023 12:39:57 -0300 Subject: [PATCH 14/18] test: coverage for wallet birth time interaction with -reindex Verifying the wallet updates the birth time accordingly when it detects a transaction with a time older than the oldest descriptor timestamp. This could happen when the user blindly imports a descriptor with 'timestamp=now'. Github-Pull: #28920 Rebased-From: 83c66444d0604f0a9ec3bc3f89d4f1a810b7cda0 --- test/functional/test_runner.py | 2 + test/functional/wallet_reindex.py | 87 +++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100755 test/functional/wallet_reindex.py diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index fbf48a0e4d..148902032f 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -203,6 +203,8 @@ 'wallet_createwallet.py --descriptors', 'wallet_watchonly.py --legacy-wallet', 'wallet_watchonly.py --usecli --legacy-wallet', + 'wallet_reindex.py --legacy-wallet', + 'wallet_reindex.py --descriptors', 'wallet_reorgsrestore.py', 'wallet_conflicts.py --legacy-wallet', 'wallet_conflicts.py --descriptors', diff --git a/test/functional/wallet_reindex.py b/test/functional/wallet_reindex.py new file mode 100755 index 0000000000..95d5fd85ad --- /dev/null +++ b/test/functional/wallet_reindex.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php. + +"""Test wallet-reindex interaction""" + +import time + +from test_framework.blocktools import COINBASE_MATURITY +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, +) +BLOCK_TIME = 60 * 10 + +class WalletReindexTest(BitcoinTestFramework): + def add_options(self, parser): + self.add_wallet_options(parser) + + def set_test_params(self): + self.num_nodes = 1 + self.setup_clean_chain = True + + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + + def advance_time(self, node, secs): + self.node_time += secs + node.setmocktime(self.node_time) + + # Verify the wallet updates the birth time accordingly when it detects a transaction + # with a time older than the oldest descriptor timestamp. + # This could happen when the user blindly imports a descriptor with 'timestamp=now'. + def birthtime_test(self, node, miner_wallet): + self.log.info("Test birth time update during tx scanning") + # Fund address to test + wallet_addr = miner_wallet.getnewaddress() + tx_id = miner_wallet.sendtoaddress(wallet_addr, 2) + + # Generate 50 blocks, one every 10 min to surpass the 2 hours rescan window the wallet has + for _ in range(50): + self.generate(node, 1) + self.advance_time(node, BLOCK_TIME) + + # Now create a new wallet, and import the descriptor + node.createwallet(wallet_name='watch_only', disable_private_keys=True, blank=True, load_on_startup=True) + wallet_watch_only = node.get_wallet_rpc('watch_only') + + # For a descriptors wallet: Import address with timestamp=now. + # For legacy wallet: There is no way of importing a script/address with a custom time. The wallet always imports it with birthtime=1. + # In both cases, disable rescan to not detect the transaction. + wallet_watch_only.importaddress(wallet_addr, rescan=False) + assert_equal(len(wallet_watch_only.listtransactions()), 0) + + # Rescan the wallet to detect the missing transaction + wallet_watch_only.rescanblockchain() + assert_equal(wallet_watch_only.gettransaction(tx_id)['confirmations'], 50) + assert_equal(wallet_watch_only.getbalances()['mine' if self.options.descriptors else 'watchonly']['trusted'], 2) + + # Reindex and wait for it to finish + with node.assert_debug_log(expected_msgs=["initload thread exit"]): + self.restart_node(0, extra_args=['-reindex=1', f'-mocktime={self.node_time}']) + node.syncwithvalidationinterfacequeue() + + # Verify the transaction is still 'confirmed' after reindex + wallet_watch_only = node.get_wallet_rpc('watch_only') + assert_equal(wallet_watch_only.gettransaction(tx_id)['confirmations'], 50) + + wallet_watch_only.unloadwallet() + + def run_test(self): + node = self.nodes[0] + self.node_time = int(time.time()) + node.setmocktime(self.node_time) + + # Fund miner + node.createwallet(wallet_name='miner', load_on_startup=True) + miner_wallet = node.get_wallet_rpc('miner') + self.generatetoaddress(node, COINBASE_MATURITY + 10, miner_wallet.getnewaddress()) + + # Tests + self.birthtime_test(node, miner_wallet) + + +if __name__ == '__main__': + WalletReindexTest().main() From b06b14e68d81f8be091d32db162c8d85b9d29e4c Mon Sep 17 00:00:00 2001 From: furszy Date: Tue, 21 Nov 2023 21:48:57 -0300 Subject: [PATCH 15/18] rpc: getwalletinfo, return wallet 'birthtime' And add coverage for it Github-Pull: #28920 Rebased-From: 1ce45baed7dd2da3f1cb85c9c25110e5537451ae --- src/wallet/rpc/wallet.cpp | 4 ++++ src/wallet/wallet.h | 3 +++ test/functional/wallet_reindex.py | 25 +++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp index 164ce9afed..c635093344 100644 --- a/src/wallet/rpc/wallet.cpp +++ b/src/wallet/rpc/wallet.cpp @@ -69,6 +69,7 @@ static RPCHelpMan getwalletinfo() {RPCResult::Type::BOOL, "descriptors", "whether this wallet uses descriptors for scriptPubKey management"}, {RPCResult::Type::BOOL, "external_signer", "whether this wallet is configured to use an external signer such as a hardware wallet"}, {RPCResult::Type::BOOL, "blank", "Whether this wallet intentionally does not contain any keys, scripts, or descriptors"}, + {RPCResult::Type::NUM_TIME, "birthtime", /*optional=*/true, "The start time for blocks scanning. It could be modified by (re)importing any descriptor with an earlier timestamp."}, RESULT_LAST_PROCESSED_BLOCK, }}, }, @@ -132,6 +133,9 @@ static RPCHelpMan getwalletinfo() obj.pushKV("descriptors", pwallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)); obj.pushKV("external_signer", pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER)); obj.pushKV("blank", pwallet->IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET)); + if (int64_t birthtime = pwallet->GetBirthTime(); birthtime != UNKNOWN_TIME) { + obj.pushKV("birthtime", birthtime); + } AppendLastProcessedBlock(obj, *pwallet); return obj; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b7c64f5267..c7cd3b3959 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -877,6 +877,9 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati /* Returns true if the wallet can give out new addresses. This means it has keys in the keypool or can generate new keys */ bool CanGetAddresses(bool internal = false) const; + /* Returns the time of the first created key or, in case of an import, it could be the time of the first received transaction */ + int64_t GetBirthTime() const { return m_birth_time; } + /** * Blocks until the wallet state is up-to-date to /at least/ the current * chain at the time this function is entered diff --git a/test/functional/wallet_reindex.py b/test/functional/wallet_reindex.py index 95d5fd85ad..5388de4b71 100755 --- a/test/functional/wallet_reindex.py +++ b/test/functional/wallet_reindex.py @@ -44,8 +44,10 @@ def birthtime_test(self, node, miner_wallet): self.advance_time(node, BLOCK_TIME) # Now create a new wallet, and import the descriptor - node.createwallet(wallet_name='watch_only', disable_private_keys=True, blank=True, load_on_startup=True) + node.createwallet(wallet_name='watch_only', disable_private_keys=True, load_on_startup=True) wallet_watch_only = node.get_wallet_rpc('watch_only') + # Blank wallets don't have a birth time + assert 'birthtime' not in wallet_watch_only.getwalletinfo() # For a descriptors wallet: Import address with timestamp=now. # For legacy wallet: There is no way of importing a script/address with a custom time. The wallet always imports it with birthtime=1. @@ -53,6 +55,16 @@ def birthtime_test(self, node, miner_wallet): wallet_watch_only.importaddress(wallet_addr, rescan=False) assert_equal(len(wallet_watch_only.listtransactions()), 0) + # Depending on the wallet type, the birth time changes. + wallet_birthtime = wallet_watch_only.getwalletinfo()['birthtime'] + if self.options.descriptors: + # As blocks were generated every 10 min, the chain MTP timestamp is node_time - 60 min. + assert_equal(self.node_time - BLOCK_TIME * 6, wallet_birthtime) + else: + # No way of importing scripts/addresses with a custom time on a legacy wallet. + # It's always set to the beginning of time. + assert_equal(wallet_birthtime, 1) + # Rescan the wallet to detect the missing transaction wallet_watch_only.rescanblockchain() assert_equal(wallet_watch_only.gettransaction(tx_id)['confirmations'], 50) @@ -65,7 +77,16 @@ def birthtime_test(self, node, miner_wallet): # Verify the transaction is still 'confirmed' after reindex wallet_watch_only = node.get_wallet_rpc('watch_only') - assert_equal(wallet_watch_only.gettransaction(tx_id)['confirmations'], 50) + tx_info = wallet_watch_only.gettransaction(tx_id) + assert_equal(tx_info['confirmations'], 50) + + # Depending on the wallet type, the birth time changes. + if self.options.descriptors: + # For descriptors, verify the wallet updated the birth time to the transaction time + assert_equal(tx_info['time'], wallet_watch_only.getwalletinfo()['birthtime']) + else: + # For legacy, as the birth time was set to the beginning of time, verify it did not change + assert_equal(wallet_birthtime, 1) wallet_watch_only.unloadwallet() From 40252e184eb188c4af767adb4918f729015910e8 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 14 Dec 2023 12:18:53 +0000 Subject: [PATCH 16/18] ci: Set `HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK` to avoid failures Homebrew attempts to check for outdated dependents or those with broken linkage. Such behavior might lead to failures when Homebrew updates them on old macOS images. This change prevents such behavior. Github-Pull: #29080 Rebased-From: 43c3246af774bda284111056268a814477f9b256 --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8564c3a28..07a88b2969 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,6 +92,8 @@ jobs: run: clang --version - name: Install Homebrew packages + env: + HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 run: brew install automake libtool pkg-config gnu-getopt ccache boost libevent miniupnpc libnatpmp zeromq qt@5 qrencode - name: Set Ccache directory From ccf00b1e6eb811a3af2c22518a832dd9a51f8aa4 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Thu, 4 Jan 2024 12:18:07 +0100 Subject: [PATCH 17/18] wallet: Fix use-after-free in WalletBatch::EraseRecords Github-Pull: #29176 Rebased-From: faebf1df2afe207f5d2d4f73f50ac66824fe34bb --- src/wallet/walletdb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 92eca46f05..3a40b7a34f 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1401,13 +1401,13 @@ bool WalletBatch::EraseRecords(const std::unordered_set& types) } // Make a copy of key to avoid data being deleted by the following read of the type - Span key_data{key}; + const SerializeData key_data{key.begin(), key.end()}; std::string type; key >> type; if (types.count(type) > 0) { - if (!m_batch->Erase(key_data)) { + if (!m_batch->Erase(Span{key_data})) { cursor.reset(nullptr); m_batch->TxnAbort(); return false; // erase failed From 7b79e54474b86864c81148c74824bfe4b732412d Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 6 Dec 2023 15:13:59 +0000 Subject: [PATCH 18/18] doc: update release notes for 26.x --- doc/release-notes.md | 288 ++----------------------------------------- 1 file changed, 12 insertions(+), 276 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index b30dadf62b..f55c72ab9a 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,9 +1,9 @@ -26.0 Release Notes +26.x Release Notes ================== -Bitcoin Core version 26.0 is now available from: +Bitcoin Core version 26.x is now available from: - + This release includes new features, various bug fixes and performance improvements, as well as updated translations. @@ -40,296 +40,32 @@ unsupported systems. Notable changes =============== -P2P and network changes ------------------------ +### Wallet -- Experimental support for the v2 transport protocol defined in - [BIP324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki) was added. - It is off by default, but when enabled using `-v2transport` it will be negotiated - on a per-connection basis with other peers that support it too. The existing - v1 transport protocol remains fully supported. +- #28994 wallet: skip BnB when SFFO is enabled +- #28920 wallet: birth time update during tx scanning +- #29176 wallet: Fix use-after-free in WalletBatch::EraseRecords -- Nodes with multiple reachable networks will actively try to have at least one - outbound connection to each network. This improves individual resistance to - eclipse attacks and network level resistance to partition attacks. Users no - longer need to perform active measures to ensure being connected to multiple - enabled networks. (#27213) +### RPC -Pruning -------- +- #29003 rpc: fix getrawtransaction segfault -- When using assumeutxo with `-prune`, the prune budget may be exceeded if it is set - lower than 1100MB (i.e. `MIN_DISK_SPACE_FOR_BLOCK_FILES * 2`). Prune budget is normally - split evenly across each chainstate, unless the resulting prune budget per chainstate - is beneath `MIN_DISK_SPACE_FOR_BLOCK_FILES` in which case that value will be used. (#27596) +### CI -Updated RPCs ------------- - -- Setting `-rpcserialversion=0` is deprecated and will be removed in - a future release. It can currently still be used by also adding - the `-deprecatedrpc=serialversion` option. (#28448) - -- The `hash_serialized_2` value has been removed from `gettxoutsetinfo` since the value it - calculated contained a bug and did not take all data into account. It is superseded by - `hash_serialized_3` which provides the same functionality but serves the correctly calculated hash. (#28685) - -- New fields `transport_protocol_type` and `session_id` were added to the `getpeerinfo` RPC to indicate - whether the v2 transport protocol is in use, and if so, what the session id is. - -- A new argument `v2transport` was added to the `addnode` RPC to indicate whether a v2 transaction connection - is to be attempted with the peer. - -- [Miniscript](https://bitcoin.sipa.be/miniscript/) expressions can now be used in Taproot descriptors for all RPCs working with descriptors. (#27255) - -- `finalizepsbt` is now able to finalize a PSBT with inputs spending [Miniscript](https://bitcoin.sipa.be/miniscript/)-compatible Taproot leaves. (#27255) - -Changes to wallet related RPCs can be found in the Wallet section below. - -New RPCs --------- - -- `loadtxoutset` has been added, which allows loading a UTXO snapshot of the format - generated by `dumptxoutset`. Once this snapshot is loaded, its contents will be - deserialized into a second chainstate data structure, which is then used to sync to - the network's tip. - - Meanwhile, the original chainstate will complete the initial block download process in - the background, eventually validating up to the block that the snapshot is based upon. - - The result is a usable bitcoind instance that is current with the network tip in a - matter of minutes rather than hours. UTXO snapshot are typically obtained via - third-party sources (HTTP, torrent, etc.) which is reasonable since their contents - are always checked by hash. - - You can find more information on this process in the `assumeutxo` design - document (). - - `getchainstates` has been added to aid in monitoring the assumeutxo sync process. - -- A new `getprioritisedtransactions` RPC has been added. It returns a map of all fee deltas created by the - user with prioritisetransaction, indexed by txid. The map also indicates whether each transaction is - present in the mempool. (#27501) - -- A new RPC, `submitpackage`, has been added. It can be used to submit a list of raw hex -transactions to the mempool to be evaluated as a package using consensus and mempool policy rules. -These policies include package CPFP, allowing a child with high fees to bump a parent below the -mempool minimum feerate (but not minimum relay feerate). (#27609) - - - Warning: successful submission does not mean the transactions will propagate throughout the - network, as package relay is not supported. - - - Not all features are available. The package is limited to a child with all of its - unconfirmed parents, and no parent may spend the output of another parent. Also, package - RBF is not supported. Refer to doc/policy/packages.md for more details on package policies - and limitations. - - - This RPC is experimental. Its interface may change. - -- A new RPC `getaddrmaninfo` has been added to view the distribution of addresses in the new and tried table of the - node's address manager across different networks(ipv4, ipv6, onion, i2p, cjdns). The RPC returns count of addresses - in new and tried table as well as their sum for all networks. (#27511) - -- A new `importmempool` RPC has been added. It loads a valid `mempool.dat` file and attempts to - add its contents to the mempool. This can be useful to import mempool data from another node - without having to modify the datadir contents and without having to restart the node. (#27460) - - Warning: Importing untrusted files is dangerous, especially if metadata from the file is taken over. - - If you want to apply fee deltas, it is recommended to use the `getprioritisedtransactions` and - `prioritisetransaction` RPCs instead of the `apply_fee_delta_priority` option to avoid - double-prioritising any already-prioritised transactions in the mempool. - -Updated settings ----------------- - -- `bitcoind` and `bitcoin-qt` will now raise an error on startup - if a datadir that is being used contains a bitcoin.conf file that - will be ignored, which can happen when a datadir= line is used in - a bitcoin.conf file. The error message is just a diagnostic intended - to prevent accidental misconfiguration, and it can be disabled to - restore the previous behavior of using the datadir while ignoring - the bitcoin.conf contained in it. (#27302) - -- Passing an invalid `-debug`, `-debugexclude`, or `-loglevel` logging configuration - option now raises an error, rather than logging an easily missed warning. (#27632) - -Changes to GUI or wallet related settings can be found in the GUI or Wallet section below. - -New settings ------------- - -Tools and Utilities -------------------- - -- A new `bitcoinconsensus_verify_script_with_spent_outputs` function is available in libconsensus which optionally accepts the spent outputs of the transaction being verified. -- A new `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT` flag is available in libconsensus that will verify scripts with the Taproot spending rules. - -Wallet ------- - -- Wallet loading has changed in this release. Wallets with some corrupted records that could be - previously loaded (with warnings) may no longer load. For example, wallets with corrupted - address book entries may no longer load. If this happens, it is recommended - load the wallet in a previous version of Bitcoin Core and import the data into a new wallet. - Please also report an issue to help improve the software and make wallet loading more robust - in these cases. (#24914) - -- The `gettransaction`, `listtransactions`, `listsinceblock` RPCs now return - the `abandoned` field for all transactions. Previously, the "abandoned" field - was only returned for sent transactions. (#25158) - -- The `listdescriptors`, `decodepsbt` and similar RPC methods now show `h` rather than apostrophe (`'`) to indicate - hardened derivation. This does not apply when using the `private` parameter, which - matches the marker used when descriptor was generated or imported. Newly created - wallets use `h`. This change makes it easier to handle descriptor strings manually. - E.g. the `importdescriptors` RPC call is easiest to use `h` as the marker: `'["desc": ".../0h/..."]'`. - With this change `listdescriptors` will use `h`, so you can copy-paste the result, - without having to add escape characters or switch `'` to 'h' manually. - Note that this changes the descriptor checksum. - For legacy wallets the `hdkeypath` field in `getaddressinfo` is unchanged, - nor is the serialization format of wallet dumps. (#26076) - -- The `getbalances` RPC now returns a `lastprocessedblock` JSON object which contains the wallet's last processed block - hash and height at the time the balances were calculated. This result shouldn't be cached because importing new keys could invalidate it. (#26094) - -- The `gettransaction` RPC now returns a `lastprocessedblock` JSON object which contains the wallet's last processed block - hash and height at the time the transaction information was generated. (#26094) - -- The `getwalletinfo` RPC now returns a `lastprocessedblock` JSON object which contains the wallet's last processed block - hash and height at the time the wallet information was generated. (#26094) - -- Coin selection and transaction building now accounts for unconfirmed low-feerate ancestor transactions. When it is necessary to spend unconfirmed outputs, the wallet will add fees to ensure that the new transaction with its ancestors will achieve a mining score equal to the feerate requested by the user. (#26152) - -- For RPC methods which accept `options` parameters ((`importmulti`, `listunspent`, - `fundrawtransaction`, `bumpfee`, `send`, `sendall`, `walletcreatefundedpsbt`, - `simulaterawtransaction`), it is now possible to pass the options as named - parameters without the need for a nested object. (#26485) - -This means it is possible make calls like: - -```sh -src/bitcoin-cli -named bumpfee txid fee_rate=100 -``` - -instead of - -```sh -src/bitcoin-cli -named bumpfee txid options='{"fee_rate": 100}' -``` - -- The `deprecatedrpc=walletwarningfield` configuration option has been removed. - The `createwallet`, `loadwallet`, `restorewallet` and `unloadwallet` RPCs no - longer return the "warning" string field. The same information is provided - through the "warnings" field added in v25.0, which returns a JSON array of - strings. The "warning" string field was deprecated also in v25.0. (#27757) - -- The `signrawtransactionwithkey`, `signrawtransactionwithwallet`, - `walletprocesspsbt` and `descriptorprocesspsbt` calls now return the more - specific RPC_INVALID_PARAMETER error instead of RPC_MISC_ERROR if their - sighashtype argument is malformed. (#28113) - -- RPC `walletprocesspsbt`, and `descriptorprocesspsbt` return - object now includes field `hex` (if the transaction - is complete) containing the serialized transaction - suitable for RPC `sendrawtransaction`. (#28414) - -- It's now possible to use [Miniscript](https://bitcoin.sipa.be/miniscript/) inside Taproot leaves for descriptor wallets. (#27255) - -GUI changes ------------ - -- The transaction list in the GUI no longer provides a special category for "payment to yourself". Now transactions that have both inputs and outputs that affect the wallet are displayed on separate lines for spending and receiving. (gui#119) - -- A new menu option allows migrating a legacy wallet based on keys and implied output script types stored in BerkeleyDB (BDB) to a modern wallet that uses descriptors stored in SQLite. (gui#738) - -- The PSBT operations dialog marks outputs paying your own wallet with "own address". (gui#740) - -- The ability to create legacy wallets is being removed. (gui#764) - -Low-level changes -================= - -Tests ------ - -- Non-standard transactions are now disabled by default on testnet - for relay and mempool acceptance. The previous behaviour can be - re-enabled by setting `-acceptnonstdtxn=1`. (#28354) +- #28992 ci: Use Ubuntu 24.04 Noble for asan,tsan,tidy,fuzz +- #29080 ci: Set HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK to avoid unrelated failures Credits ======= Thanks to everyone who directly contributed to this release: -- 0xb10c -- Amiti Uttarwar - Andrew Chow -- Andrew Toth -- Anthony Towns -- Antoine Poinsot -- Antoine Riard -- Ari -- Aurèle Oulès -- Ayush Singh -- Ben Woosley -- Brandon Odiwuor -- Brotcrunsher -- brunoerg -- Bufo -- Carl Dong -- Casey Carter -- Cory Fields -- David Álvarez Rosa -- dergoegge -- dhruv -- dimitaracev -- Erik Arvstedt -- Erik McKelvey -- Fabian Jahr - furszy -- glozow -- Greg Sanders -- Harris - Hennadii Stepanov -- Hernan Marino -- ishaanam -- ismaelsadeeq -- Jake Rawsthorne -- James O'Beirne -- John Moffett -- Jon Atack -- josibake -- kevkevin -- Kiminuo -- Larry Ruane -- Luke Dashjr - MarcoFalke -- Marnix -- Martin Leitner-Ankerl - Martin Zumsande -- Matthew Zipkin -- Michael Ford -- Michael Tidwell -- mruddy - Murch -- ns-xvrn -- pablomartin4btc -- Pieter Wuille -- Reese Russell -- Rhythm Garg -- Ryan Ofsky -- Sebastian Falbesoner -- Sjors Provoost -- stickies-v -- stratospher -- Suhas Daftuar -- TheCharlatan -- Tim Neubauer -- Tim Ruffing -- Vasil Dimov -- virtu -- vuittont60 -- willcl-ark -- Yusuf Sahin HAMZA As well as to everyone that helped with translations on [Transifex](https://www.transifex.com/bitcoin/bitcoin/).