mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-26 03:03:22 -03:00
Merge bitcoin/bitcoin#29011: [26.x] Backports
7b79e54474
doc: update release notes for 26.x (fanquake)ccf00b1e6e
wallet: Fix use-after-free in WalletBatch::EraseRecords (MarcoFalke)40252e184e
ci: Set `HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK` to avoid failures (Hennadii Stepanov)b06b14e68d
rpc: getwalletinfo, return wallet 'birthtime' (furszy)12834012c2
test: coverage for wallet birth time interaction with -reindex (furszy)0fa47e2569
wallet: fix legacy spkm default birth time (furszy)84f4a6c145
wallet: birth time update during tx scanning (furszy)074296dd60
refactor: rename FirstKeyTimeChanged to MaybeUpdateBirthTime (furszy)35039ac3cc
fuzz: disable BnB when SFFO is enabled (furszy)903b4623d3
test: add coverage for BnB-SFFO restriction (furszy)05d0576d3c
wallet: create tx, log resulting coin selection info (furszy)5493ebbe74
wallet: skip BnB when SFFO is active (Murch)b15e2e2cec
test: add regression test for the getrawtransaction segfault (Martin Zumsande)5097bb3389
rpc: fix getrawtransaction segfault (Martin Zumsande)81e744a9a6
ci: Use Ubuntu 24.04 Noble for asan (MarcoFalke)69e53d1e47
ci: Use Ubuntu 24.04 Noble for tsan,tidy,fuzz (MarcoFalke)d2c80b6f52
doc: Missing additions to 26.0 release notes (fanquake)8dc2c753ff
doc: add historical release notes for 26.0 (fanquake) Pull request description: Backports for `26.x`. Currently: * https://github.com/bitcoin/bitcoin/pull/28920 * https://github.com/bitcoin/bitcoin/pull/28992 * https://github.com/bitcoin/bitcoin/pull/28994 * https://github.com/bitcoin/bitcoin/pull/29003 * https://github.com/bitcoin/bitcoin/pull/29023 * https://github.com/bitcoin/bitcoin/pull/29080 * https://github.com/bitcoin/bitcoin/pull/29176 ACKs for top commit: TheCharlatan: ACK7b79e54474
glozow: ACK7b79e54474
, matches mine Tree-SHA512: 898aec76ed3ad35e0edd0980af5bcc21bd60003bbf69e0b4f473ed2aa38c4e3b360b930bc3747cf798195906a8f9fe66417524f5e5ef40fa68f1c1aaceebdeb0
This commit is contained in:
commit
04edf9f586
21 changed files with 601 additions and 319 deletions
|
@ -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"
|
||||
|
||||
|
|
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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:
|
||||
|
||||
<https://bitcoincore.org/bin/bitcoin-core-26.0/>
|
||||
<https://bitcoincore.org/bin/bitcoin-core-26.x/>
|
||||
|
||||
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 (<https://github.com/bitcoin/bitcoin/blob/master/doc/design/assumeutxo.md>).
|
||||
|
||||
`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/).
|
||||
|
|
357
doc/release-notes/release-notes-26.0.md
Normal file
357
doc/release-notes/release-notes-26.0.md
Normal file
|
@ -0,0 +1,357 @@
|
|||
26.0 Release Notes
|
||||
==================
|
||||
|
||||
Bitcoin Core version 26.0 is now available from:
|
||||
|
||||
<https://bitcoincore.org/bin/bitcoin-core-26.0/>
|
||||
|
||||
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:
|
||||
|
||||
<https://github.com/bitcoin/bitcoin/issues>
|
||||
|
||||
To receive security and update notifications, please subscribe to:
|
||||
|
||||
<https://bitcoincore.org/en/list/announcements/join/>
|
||||
|
||||
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 (<https://github.com/bitcoin/bitcoin/blob/master/doc/design/assumeutxo.md>).
|
||||
|
||||
`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 `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)
|
||||
|
||||
- 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)
|
||||
|
||||
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
|
||||
-----------
|
||||
|
||||
- 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)
|
||||
|
||||
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
|
||||
=================
|
||||
|
||||
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/).
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,9 @@ public:
|
|||
virtual bool IsLocked() const = 0;
|
||||
};
|
||||
|
||||
//! Constant representing an unknown spkm creation time
|
||||
static constexpr int64_t UNKNOWN_TIME = std::numeric_limits<int64_t>::max();
|
||||
|
||||
//! Default for -keypool
|
||||
static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
|
||||
|
||||
|
@ -286,7 +289,8 @@ private:
|
|||
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};
|
||||
|
|
|
@ -693,9 +693,12 @@ util::Result<SelectionResult> 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);
|
||||
|
@ -1260,6 +1263,7 @@ static util::Result<CreatedTransactionResult> 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,
|
||||
|
|
|
@ -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<CWallet> 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);
|
||||
|
@ -449,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<CWallet> 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{};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1763,11 +1770,11 @@ bool CWallet::ImportScriptPubKeys(const std::string& label, const std::set<CScri
|
|||
return true;
|
||||
}
|
||||
|
||||
void CWallet::FirstKeyTimeChanged(const ScriptPubKeyMan* spkm, int64_t new_birth_time)
|
||||
void CWallet::MaybeUpdateBirthTime(int64_t time)
|
||||
{
|
||||
int64_t birthtime = m_birth_time.load();
|
||||
if (new_birth_time < birthtime) {
|
||||
m_birth_time = new_birth_time;
|
||||
if (time < birthtime) {
|
||||
m_birth_time = time;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3103,7 +3110,7 @@ std::shared_ptr<CWallet> 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;
|
||||
|
@ -3494,10 +3501,12 @@ LegacyScriptPubKeyMan* CWallet::GetOrCreateLegacyScriptPubKeyMan()
|
|||
|
||||
void CWallet::AddScriptPubKeyMan(const uint256& id, std::unique_ptr<ScriptPubKeyMan> 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 +3539,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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -678,8 +678,8 @@ public:
|
|||
bool ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& 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<CScript>& 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};
|
||||
|
@ -877,6 +877,9 @@ public:
|
|||
/* 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
|
||||
|
|
|
@ -1401,13 +1401,13 @@ bool WalletBatch::EraseRecords(const std::unordered_set<std::string>& 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
|
||||
|
|
|
@ -32,6 +32,7 @@ from test_framework.script import (
|
|||
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 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
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 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
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 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
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 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
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")
|
||||
|
|
|
@ -203,6 +203,8 @@ BASE_SCRIPTS = [
|
|||
'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',
|
||||
|
|
108
test/functional/wallet_reindex.py
Executable file
108
test/functional/wallet_reindex.py
Executable file
|
@ -0,0 +1,108 @@
|
|||
#!/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, 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.
|
||||
# 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)
|
||||
|
||||
# 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)
|
||||
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')
|
||||
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()
|
||||
|
||||
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()
|
Loading…
Add table
Reference in a new issue