When running walletpassphrase on a large wallet.dat (ie about 300,000 segwit P2SH addresses) the command sometimes takes a very long time, and if command is run multiple times at once (while running slow) it causes bitcoin core to freeze (stops syncing and requires kill -9 to stop/restart)

During the locked up walletpassphrase commands being run the following messages start to appear in the debug.log:

`018-01-24 01:01:04 socket sending timeout: 1201s`

Note that this problem is intermittent, so sometimes the command runs instantly, other times it takes a few minutes, and other times it completely freezes the node.
{
    LOCK(cs_KeyStore);
    
    for (const auto& keyid : GetAffectedKeys(script, *this)) {
        std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
        if (mi != m_pool_key_to_index.end()) {
            WalletLogPrintf("%s: Detected a used keypool key, mark all keypool key up to this key as used\n", __func__);
            MarkReserveKeysAsUsed(mi->second);
            if (!TopUp()) {
                WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
            }
        }
    }
}
void LegacyScriptPubKeyMan::UpgradeKeyMetadata()
{
    LOCK(cs_KeyStore);
    if (m_storage.IsLocked() || m_storage.IsWalletFlagSet(WALLET_FLAG_KEY_ORIGIN_METADATA)) {
        return;
    }
    std::unique_ptr<WalletBatch> batch = MakeUnique<WalletBatch>(m_storage.GetDatabase());
    for (auto& meta_pair : mapKeyMetadata) {
        CKeyMetadata& meta = meta_pair.second;
        if (!meta.hd_seed_id.IsNull() && !meta.has_key_origin && meta.hdKeypath != "s") { 
            CKey key;
            GetKey(meta.hd_seed_id, key);
            CExtKey masterKey;
            masterKey.SetSeed(key.begin(), key.size());