Loading a descriptor wallet currently leads to a segfault if a legacy key type entry is present that can be deserialized successfully and needs SPKman-interaction. To reproduce with a “cscript” entry (see second commit for details):
0$ ./src/bitcoin-cli createwallet crashme
1$ ./src/bitcoin-cli unloadwallet crashme
2$ sqlite3 ~/.bitcoin/wallets/crashme/wallet.dat
3SQLite version 3.38.2 2022-03-26 13:51:10
4Enter ".help" for usage hints.
5sqlite> INSERT INTO main VALUES(x'07637363726970740000000000000000000000000000000000000000', x'00');
6$ ./src/bitcoin-cli loadwallet crashme
7
8--- bitcoind output: ---
92022-11-06T13:51:01Z Using SQLite Version 3.38.2
102022-11-06T13:51:01Z Using wallet /home/honey/.bitcoin/wallets/crashme
112022-11-06T13:51:01Z init message: Loading wallet…
122022-11-06T13:51:01Z [crashme] Wallet file version = 10500, last client version = 249900
13
14Segmentation fault (core dumped)
Background: In the wallet key-value-loading routine, most legacy type entries require a LegacyScriptPubKeyMan
instance after successful deserialization. On a descriptor wallet, creating that (via method GetOrCreateLegacyScriptPubKeyMan
) fails and then leads to a null-pointer dereference crash. E.g. for CSCRIPT: https://github.com/bitcoin/bitcoin/blob/50422b770a40f5fa964201d1e99fd6b5dc1653ca/src/wallet/walletdb.cpp#L589-L594
This PR fixes this by simply ignoring legacy entries if the wallet flags indicate that we have a descriptor wallet. The second commits adds a regression test to the descriptor wallet’s functional test (fortunately Python includes sqlite3 support in the standard library).
Probably it would be even better to throw a warning to the user if unexpected legacy entries are found in descriptor wallets, but I think as a first mitigation everything is obvisouly better than crashing. As far as I’m aware, descriptor wallets created/migrated by Bitcoin Core should never end up in a state containing legacy type entries though.
This PR fixes this by throwing an error if legacy entries are found in descriptor wallets on loading.