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).
std::atomic<double> m_scanning_progress{0};
    std::mutex mutexScanning;
    friend class WalletRescanReserver;
    WalletBatch *encrypted_batch GUARDED_BY(cs_wallet) = nullptr;
    
    int nWalletVersion GUARDED_BY(cs_wallet){FEATURE_BASE};
    
    int nWalletMaxVersion GUARDED_BY(cs_wallet) = FEATURE_BASE;
    int64_t nNextResend = 0;
    int64_t nLastResend = 0;
    bool fBroadcastTransactions = false;
    
    std::atomic<int64_t> m_best_block_time {0};
    /**
     * Used to keep track of spent outpoints, and
     * detect and report conflicts (double-spends or
     * mutated transactions where the mutant gets mined).
     */
    typedef std::multimap<COutPoint, uint256> TxSpends;
    TxSpends mapTxSpends GUARDED_BY(cs_wallet);
    void AddToSpends(const COutPoint& outpoint, const uint256& wtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
    void AddToSpends(const uint256& wtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
    /**
     * Add a transaction to the wallet, or update it.  pIndex and posInBlock should
     * be set when the transaction was known to be included in a block.  When
     * pIndex == nullptr, then wallet state is not updated in AddToWallet, but
     * notifications happen and cached balances are marked dirty.
     *
     * If fUpdate is true, existing transactions will be updated.
     * TODO: One exception to this is that the abandoned state is cleared under the