wallet2: trim stale transfer maps after output imports

(cherry picked from commit 7d7a74848780f4f42a0e1376badf62a79240a02f)
This commit is contained in:
selsta
2026-10-04 18:50:25 -04:00
committed by such-gitea
parent f607a02dae
commit d86469844e
2 changed files with 29 additions and 0 deletions
+28
View File
@@ -6614,6 +6614,24 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
}
}
//----------------------------------------------------------------------------------------------------
void wallet2::trim_transfer_maps(size_t num_transfers)
{
for (auto it = m_key_images.begin(); it != m_key_images.end(); )
{
if (it->second >= num_transfers)
it = m_key_images.erase(it);
else
++it;
}
for (auto it = m_pub_keys.begin(); it != m_pub_keys.end(); )
{
if (it->second >= num_transfers)
it = m_pub_keys.erase(it);
else
++it;
}
}
//----------------------------------------------------------------------------------------------------
void wallet2::load_wallet_cache(const bool use_fs, const std::string& cache_buf)
{
boost::system::error_code e;
@@ -6728,6 +6746,10 @@ void wallet2::load_wallet_cache(const bool use_fs, const std::string& cache_buf)
ar >> *this;
}
}
// Repair stale indices from older output imports.
if (!m_has_ever_refreshed_from_node)
trim_transfer_maps(m_transfers.size());
for (const auto &key_image : m_key_images)
THROW_WALLET_EXCEPTION_IF(key_image.second >= m_transfers.size(), error::wallet_internal_error,
std::string("Key images cache contains illegal transfer offset: ") + std::to_string(key_image.second)
@@ -15184,7 +15206,10 @@ size_t wallet2::import_outputs(const std::tuple<uint64_t, uint64_t, std::vector<
if (offset + output_array.size() > m_transfers.size())
m_transfers.resize(offset + output_array.size());
else if (num_outputs < m_transfers.size())
{
trim_transfer_maps(num_outputs);
m_transfers.resize(num_outputs);
}
for (size_t i = 0; i < output_array.size(); ++i)
{
@@ -15264,7 +15289,10 @@ size_t wallet2::import_outputs(const std::tuple<uint64_t, uint64_t, std::vector<
if (offset + output_array.size() > m_transfers.size())
m_transfers.resize(offset + output_array.size());
else if (num_outputs < m_transfers.size())
{
trim_transfer_maps(num_outputs);
m_transfers.resize(num_outputs);
}
for (size_t i = 0; i < output_array.size(); ++i)
{
+1
View File
@@ -1856,6 +1856,7 @@ private:
bool load_keys_buf(const std::string& keys_buf, const epee::wipeable_string& password);
bool load_keys_buf(const std::string& keys_buf, const epee::wipeable_string& password, boost::optional<crypto::chacha_key>& keys_to_encrypt);
void load_wallet_cache(const bool use_fs, const std::string& cache_buf = "");
void trim_transfer_maps(size_t num_transfers);
void process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector<uint64_t> &o_indices, uint64_t height, uint8_t block_version, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen, const tx_cache_data &tx_cache_data, std::map<std::pair<uint64_t, uint64_t>, size_t> *output_tracker_cache = NULL, bool ignore_callbacks = false);
bool should_skip_block(const cryptonote::block &b, uint64_t height) const;
void process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const parsed_block &parsed_block, const crypto::hash& bl_id, uint64_t height, const std::vector<tx_cache_data> &tx_cache_data, size_t tx_cache_data_offset, std::map<std::pair<uint64_t, uint64_t>, size_t> *output_tracker_cache = NULL);