_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
{
    return{{RPCResult::Type::NUM, "confirmations", "The number of confirmations for the transaction. Negative confirmations means the\n"
               "transaction conflicted that many blocks ago."},
           {RPCResult::Type::BOOL, "generated", true, "Only present if the transaction's only input is a coinbase one."},
           {RPCResult::Type::BOOL, "trusted", true, "Whether we consider the transaction to be trusted and safe to spend from.\n"
                "Only present when the transaction has 0 confirmations (or negative confirmations, if conflicted)."},
           {RPCResult::Type::STR_HEX, "blockhash", true, "The block hash containing the transaction."},
           {RPCResult::Type::NUM, "blockheight", true, "The block height containing the transaction."},
           {RPCResult::Type::NUM, "blockindex", true, "The index of the transaction in the block that includes it."},
           {RPCResult::Type::NUM_TIME, "blocktime", true, "The block time expressed in " + UNIX_EPOCH_TIME + "."},
           {RPCResult::Type::STR_HEX, "txid", "The transaction id."},
           {RPCResult::Type::STR_HEX, "wtxid", "The hash of serialized transaction, including witness data."},
           {RPCResult::Type::ARR, "walletconflicts", "Conflicting transaction ids.",
           {
               {RPCResult::Type::STR_HEX, "txid", "The transaction id."},
           }},
           {RPCResult::Type::STR_HEX, "replaced_by_txid", true, "The txid if this tx was replaced."},
           {RPCResult::Type::STR_HEX, "replaces_txid", true, "The txid if the tx replaces one."},
           {RPCResult::Type::STR, "comment", true, ""},
           {RPCResult::Type::STR, "to", true, "If a comment to is associated with the transaction."},
           {RPCResult::Type::NUM_TIME, "time", "The transaction time expressed in " + UNIX_EPOCH_TIME + "."},
           {RPCResult::Type::NUM_TIME, "timereceived", "The time received expressed in " + UNIX_EPOCH_TIME + "."},
           {RPCResult::Type::STR, "comment", true, "If a comment is associated with the transaction, only present if not empty."},
           {RPCResult::Type::STR, "bip125-replaceable", "(\"yes|no|unknown\") Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
               "may be unknown for unconfirmed transactions not in the mempool."}};
}
RPCHelpMan listtransactions()