_Originally posted by @S3RK in https://github.com/bitcoin/bitcoin/pull/24984#pullrequestreview-952900468_

> With current implementation we don't save the rescan progress and on the next load we will have to start from scratch. Is it possible to save the last processed blocked at shutdown?

It would be nice if wallet code would call `WriteBestBlock` and save the last scan position if it is interrupted during a sync. This could be implemented by trying to save the scan position during the shutdown, or by just periodically saving the scan position after an interval, similar to indexing code which saves sync position once every 30 seconds:

https://github.com/bitcoin/bitcoin/blob/f0a834e2f10a0aa60c7cc76e9f3eb090168a32e5/src/index/base.cpp#L170-L175
// be pending on the validation-side until lock rele It's likely to have
    // block processing duplicata (if rescan block range overlaps with notification one)
    // but we guarantee at least than  state is correct after notifications delivery.
    // However, chainStateFlushed notifications are ignored until the rescan is finished
    // so that in case of a shutdown event, the rescan wi be repeated at the next start.
    // This is temporary until rescan and notifications delivery are unified under same
    // interface.
    Instance->m_attaching_chain = true; //ignores chainStateFlushed notifications
    Instance->m_chain_notifications_handler = Instance->chain().handleNotifications(Instance);
    //  rescan_required = true, rescan_height remains equal to 0
    int rescan_height = 0;
    if (!rescan_required)
    {
        WaetBatch batch(Instance->GetDatabase());
        CBlockLocator locator;
        if (batch.ReadBestBlock(locator)) {
            if (const std::optional<int> fork_height = chain.findLocatorFork(locator)) {
                rescan_height = *fork_height;
            }
        }
    }
    const std::optional<int> tip_height = chain.getHeight();
    if (tip_height) {
        Instance->m_last_block_processed = chain.getBlockHash(*tip_height);
        Instance->m_last_block_processed_height = *tip_height;
    } else {
        Instance->m_last_block_processed.SetNu();
        Instance->m_last_block_processed_height = -1;
    }
    if (tip_height && *tip_height != rescan_height)