elements/src/wallet
glozow 96d30ed4f9
Merge bitcoin/bitcoin#31495: wallet: Utilize IsMine() and CanProvide() in migration to cover edge cases
af76664b12 test: Test migration of a solvable script with no privkeys (Ava Chow)
17f01b0795 test: Test migration of taproot output scripts (Ava Chow)
1eb9a2a39f test: Test migration of miniscript in legacy wallets (Ava Chow)
e8c3efc7d8 wallet migration: Determine Solvables with CanProvide (Ava Chow)
fa1b7cd6e2 migration: Skip descriptors which do not parse (Ava Chow)
440ea1ab63 legacy spkm: use IsMine() to extract watched output scripts (Ava Chow)
b777e84cd7 legacy spkm: Move CanProvide to LegacyDataSPKM (Ava Chow)
b1ab927bbf tests: Test migration of additional P2WSH scripts (Ava Chow)
c39b3cfcd1 test: Extra verification that migratewallet migrates (Ava Chow)

Pull request description:

  The legacy wallet `IsMine()` is essentially a black box that would tell us whether the wallet is watching an output script. In order to migrate legacy wallets to descriptor wallets, we need to be able to compute all of the output scripts that a legacy wallet would watch. The original approach for this was to understand `IsMine()` and write a function which would be its inverse. This was partially done in the original migration code, and attempted to be completed in #30328. However, further analysis of `IsMine()` has continued to reveal additional edge cases which make writing an inverse function increasingly difficult to verify correctness.

  This PR instead changes migration to utilize `IsMine()` to produce the output scripts by first computing a superset of all of the output scripts that `IsMine()` would watch and testing each script against `IsMine()` to filter for the ones that actually are watched. The superset is constructed by computing all possible output scripts for the keys and scripts in the wallet - for keys, every key could be a P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH; for scripts, every script could be an output script, the redeemScript of a P2SH, the witnessScript of a P2WSH, and the witnessScript of a P2SH-P2WSH.

  Additionally, the legacy wallet can contain scripts that are redeemScripts and witnessScripts, while not watching for any output script utilizing that script. These are known as solvable scripts and are migrated to a separate "solvables" wallet. The previous approach to identifying these solvables was similar to identifying output scripts - finding known solvable conditions and computing the scripts. However, this also can miss scripts, so the solvables are now identified in a manner similar to the output scripts but using the function `CanProvide()`. Using the same superset as before, all output scripts which are `ISMINE_NO` are put through `CanProvide()` which will perform a dummy signing and then a key lookup to determine whether the legacy wallet could provide any solving data for the output script. The scripts that pass will have their descriptors inferred and the script included in the solvables wallet.

  The main downside of this approach is that `IsMine()` and `CanProvide()` can no longer be deleted. They will need to be refactored to be migration only code instead in #28710.

  Lastly, I've added 2 test cases for the edge cases that prompted this change of approach. In particular, miniscript witnessScripts and `rawtr()` output scripts are  solvable and signable in a legacy wallet, although never `ISMINE_SPENDABLE`.

ACKs for top commit:
  sipa:
    Code review ACK af76664b12; I did not review the tests in detail.
  brunoerg:
    code review ACK af76664b12
  rkrux:
    ACK af76664b12

Tree-SHA512: 7f58a90de6f38fe9801fb6c2a520627072c8d66358652ad0872ff59deb678a82664b99babcfd874288bebcb1487d099a77821f03ae063c2b4cbf2d316e77d141
2025-02-13 12:30:15 -05:00
..
rpc Merge bitcoin/bitcoin#30909: wallet, assumeutxo: Don't Assume m_chain_tx_count, Improve wallet RPC errors 2025-01-31 15:45:14 -05:00
test Merge bitcoin/bitcoin#31242: wallet, desc spkm: Return SigningProvider only if we have the privkey 2025-01-16 17:30:36 +00:00
bdb.cpp scripted-diff: LogPrint -> LogDebug 2024-08-29 13:49:57 +02:00
bdb.h wallet: introduce active db txn listeners 2024-10-21 08:29:22 -03:00
CMakeLists.txt cmake: Add systemtap-sdt optional package support 2024-08-16 19:27:41 +01:00
coincontrol.cpp wallet: Explicitly preserve scriptSig and scriptWitness in CreateTransaction 2023-12-08 17:12:19 -05:00
coincontrol.h [wallet, rpc]: add max_tx_weight to tx funding options 2024-06-27 15:31:21 +01:00
coinselection.cpp Remove unused variable assignment 2024-12-13 21:00:07 -06:00
coinselection.h Merge bitcoin/bitcoin#29523: Wallet: Add max_tx_weight to transaction funding options (take 2) 2024-07-17 18:27:59 -04:00
context.cpp
context.h interfaces: Add schedulerMockForward method so mockscheduler RPC can work across processes 2023-10-20 10:30:16 -04:00
crypter.cpp refactor: vector -> span in CCrypter 2024-08-28 19:09:51 +02:00
crypter.h refactor: vector -> span in CCrypter 2024-08-28 19:09:51 +02:00
db.cpp Merge bitcoin/bitcoin#29071: refactor: Remove Span operator==, Use std::ranges::equal 2024-08-28 10:34:47 +01:00
db.h wallet: introduce active db txn listeners 2024-10-21 08:29:22 -03:00
dump.cpp bdb: Be able to make byteswapped databases 2024-05-16 15:03:13 -04:00
dump.h wallettool: Don't create CWallet when dumping DB 2023-12-19 16:54:06 -05:00
external_signer_scriptpubkeyman.cpp util: add TransactionError includes and namespace declarations 2024-05-16 10:16:08 -05:00
external_signer_scriptpubkeyman.h common: Add PSBTError enum 2024-05-16 10:16:08 -05:00
feebumper.cpp scripted-diff: Replace strprintf(Untranslated) with Untranslated(strprintf) 2024-12-04 15:09:05 -04:00
feebumper.h rpc: bumpfee, improve doc for 'reduce_output' arg 2023-09-26 20:17:02 -03:00
fees.cpp
fees.h
init.cpp scripted-diff: drop config/ subdir for bitcoin-config.h, rename to bitcoin-build-config.h 2024-10-10 12:22:12 +02:00
interfaces.cpp gui: Use wallet name for wallet migration rather than WalletModel 2024-08-13 11:25:38 -04:00
load.cpp refactor: Delay translation of _() literals 2025-01-14 19:21:37 +01:00
load.h interfaces: Add schedulerMockForward method so mockscheduler RPC can work across processes 2023-10-20 10:30:16 -04:00
migrate.cpp refactor: Drop unused UCharCast 2025-01-14 19:01:53 +01:00
migrate.h wallet: introduce active db txn listeners 2024-10-21 08:29:22 -03:00
receive.cpp [clang-tidy] Enable the misc-no-recursion check 2024-04-07 14:04:45 +01:00
receive.h wallet: Add wallet/types.h for simple public enum and struct types 2023-04-11 15:52:25 -04:00
salvage.cpp scripted-diff: Replace strprintf(Untranslated) with Untranslated(strprintf) 2024-12-04 15:09:05 -04:00
salvage.h refactor: Move fs.* to util/fs.* 2023-03-23 12:55:18 +01:00
scriptpubkeyman.cpp Merge bitcoin/bitcoin#31495: wallet: Utilize IsMine() and CanProvide() in migration to cover edge cases 2025-02-13 12:30:15 -05:00
scriptpubkeyman.h Merge bitcoin/bitcoin#31495: wallet: Utilize IsMine() and CanProvide() in migration to cover edge cases 2025-02-13 12:30:15 -05:00
spend.cpp tracing: only prepare tracepoint args if attached 2024-10-28 14:27:47 +01:00
spend.h refactor: pass CRecipient to FundTransaction 2024-01-19 15:04:56 +01:00
sqlite.cpp scripted-diff: Rename PACKAGE_* variables to CLIENT_* 2024-10-28 12:36:19 +00:00
sqlite.h wallet: introduce active db txn listeners 2024-10-21 08:29:22 -03:00
transaction.cpp scripted-diff: wallet: s/TxStateConflicted/TxStateBlockConflicted 2024-03-14 17:38:39 -04:00
transaction.h util: Move util/string.h functions to util namespace 2024-05-16 10:16:08 -05:00
types.h util: move error.h TransactionError enum to node/types.h 2024-05-16 10:16:08 -05:00
wallet.cpp Merge bitcoin/bitcoin#31241: wallet: remove BDB dependency from wallet migration benchmark 2025-01-24 18:21:50 -05:00
wallet.h Merge bitcoin/bitcoin#31241: wallet: remove BDB dependency from wallet migration benchmark 2025-01-24 18:21:50 -05:00
walletdb.cpp Merge bitcoin/bitcoin#28724: wallet: Cleanup accidental encryption keys in watchonly wallets 2025-01-10 15:29:47 +00:00
walletdb.h Merge bitcoin/bitcoin#28724: wallet: Cleanup accidental encryption keys in watchonly wallets 2025-01-10 15:29:47 +00:00
wallettool.cpp scripted-diff: Rename PACKAGE_* variables to CLIENT_* 2024-10-28 12:36:19 +00:00
wallettool.h
walletutil.cpp descriptors: Change Parse to return vector of descriptors 2024-08-08 12:47:22 -04:00
walletutil.h Merge bitcoin/bitcoin#22838: descriptors: Be able to specify change and receiving in a single descriptor string 2024-08-28 15:56:15 +01:00