Right now a wallet descriptor is converted to its string representation (via Descriptor::ToString
) repeatedly at different instances:
- on finding a
DescriptorScriptPubKeyMan
for a given descriptor (CWallet::GetDescriptorScriptPubKeyMan
, e.g. used by theimportdescriptors
RPC); the string representation is created once for each spkm in the wallet and at each iteration again for the searched descriptor (DescriptorScriptPubKeyMan::HasWalletDescriptor
) - whenever
DescriptorScriptPubKeyMan::GetID()
is called, e.g. inTopUp
or any instances where a descriptor is written to the DB to determine the database key, also at less obvious places likeFastWalletRescanFilter
etc.
As there is no good reason to calculate a fixed descriptor’s string/ID more than once, add the ID as a field to WalletDescriptor
and calculate it immediately at initialization (or deserialization). HasWalletDescriptor
is changed to compare the spkm’s and searched descriptor’s ID instead of the string to take use of that.
This speeds up the functional test wallet_miniscript.py
by a factor of 5-6x on my machine (3m30.95s on master vs. 0m38.02s on PR). The recently introduced “max-size TapMiniscript” test-case introduced a descriptor that takes 2-3 seconds to create a string representation, so the repeated calls to that were significantly hurting the performance.
Fixes #28800.