Skip to content

Check if the wallet already contains the descriptor GetDescriptorScriptPubKeyMan #32013

@saikiran57

Description

@saikiran57

Is there an existing issue for this?

  • I have searched the existing issues

Current behaviour

In importdescriptors rpc call when we try import descriptor address we are internally calling ProcessDescriptorImport() method which checking

// Check if the wallet already contains the descriptor auto existing_spk_manager = wallet.GetDescriptorScriptPubKeyMan(w_desc); if (existing_spk_manager) { if (!existing_spk_manager->CanUpdateToWalletDescriptor(w_desc, error)) { throw JSONRPCError(RPC_INVALID_PARAMETER, error); } }

and below we have

// Add descriptor to the wallet auto spk_manager = wallet.AddWalletDescriptor(w_desc, keys, label, desc_internal); if (spk_manager == nullptr) { throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Could not add descriptor '%s'", descriptor)); }

but in AddWalletDescriptor method again we are checking
auto spk_man = GetDescriptorScriptPubKeyMan(desc);

By calling twice we are facing lot of delay when we import address.

2025-01-24T03:26:28Z [wt_wallet] ProcessDescriptorImport: GetDescriptorScriptPubKeyMan time 619 milliseconds
2025-01-24T03:26:28Z [wt_wallet] ProcessDescriptorImport: AddWalletDescriptor time 33 milliseconds
2025-01-24T03:26:28Z [wt_wallet] operator(): ProcessDescriptorImport time 653 milliseconds

I've made some improvement like using only GetDescriptorScriptPubKeyMan method it is bit faster. Kindly verify this issue so I can create Pull request.

Expected behaviour

GetDescriptorScriptPubKeyMan method should be called only once in the importdescriptor call.

Steps to reproduce

  1. call importdescriptors()

GetDescriptor_time_1.txt

Improved_getdescriptor.txt

  1. Add debug logs
    auto startTime = std::chrono::steady_clock::now(); const UniValue result = ProcessDescriptorImport(*pwallet, request, timestamp); auto endTime = std::chrono::steady_clock::now(); auto duratioMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(endTime-startTime).count(); pwallet->WalletLogPrintf("%s: ProcessDescriptorImport time %d milliseconds \n", __func__, duratioMilliseconds);

auto startTime = std::chrono::steady_clock::now(); // Check if the wallet already contains the descriptor auto existing_spk_manager = wallet.GetDescriptorScriptPubKeyMan(w_desc); if (existing_spk_manager) { if (!existing_spk_manager->CanUpdateToWalletDescriptor(w_desc, error)) { throw JSONRPCError(RPC_INVALID_PARAMETER, error); } } auto endTime = std::chrono::steady_clock::now(); auto duratioMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(endTime-startTime).count(); pwallet->WalletLogPrintf("%s: GetDescriptorScriptPubKeyMantime %d milliseconds \n", __func__, duratioMilliseconds);
`

` auto startTime = std::chrono::steady_clock::now();
// Add descriptor to the wallet
auto spk_manager = wallet.AddWalletDescriptor(w_desc, keys, label, desc_internal);
if (spk_manager == nullptr) {
throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Could not add descriptor '%s'", descriptor));
}

        auto endTime = std::chrono::steady_clock::now();
        auto duratioMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(endTime-startTime).count();
        wallet.WalletLogPrintf("%s: AddWalletDescriptor time %d milliseconds \n", __func__, duratioMilliseconds);`

Relevant log output

No response

How did you obtain Bitcoin Core

Compiled from source

What version of Bitcoin Core are you using?

master

Operating system and version

wsl ubuntu 22.04 LTS

Machine specifications

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions