The new `getrpcinfo` shows a list of the active commands and the duration each command has been running. This sounds like a good place to report a completion percentage for any command doing a blockchain rescan, to solve [this problem](https://bitcoin.stackexchange.com/q/83236/90721).
for (const COutput& out : vecOutputs) {
        CTxDestination address;
        const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
        bool fValidAddress = ExtractDestination(scriptPubKey, address);
        if (destinations.size() && (!fValidAddress || !destinations.count(address)))
            continue;
        UniValue entry(UniValue::VOBJ);
        entry.pushKV("txid", out.tx->GetHash().GetHex());
        entry.pushKV("vout", out.i);
        if (fValidAddress) {
            entry.pushKV("address", EncodeDestination(address));
            auto i = pwallet->mapAddressBook.find(address);
            if (i != pwallet->mapAddressBook.end()) {
                entry.pushKV("label", i->second.name);
            }
            if (scriptPubKey.IsPayToScriptHash()) {
                const CScriptID& hash = boost::get<CScriptID>(address);
                CScript redeemScript;
                if (pwallet->GetCScript(hash, redeemScript)) {
                    entry.pushKV("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()));
                    
                    CTxDestination witness_destination;
                    if (redeemScript.IsPayToWitnessScriptHash()) {
                        bool extracted = ExtractDestination(redeemScript, witness_destination);
                        assert(extracted);
                        
                        const WitnessV0ScriptHash& whash = boost::get<WitnessV0ScriptHash>(witness_destination);
                        CScriptID id;
                        CRIPEMD160().Write(whash.begin(), whash.size()).Finalize(id.begin());
                        CScript witnessScript;