aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluigi1111 <luigi1111w@gmail.com>2018-08-15 17:40:55 -0500
committerluigi1111 <luigi1111w@gmail.com>2018-08-15 17:40:55 -0500
commit7aa2030cee51a65084415ea629ad2f01f92a2dd9 (patch)
tree4169ffccf1cb742ede10e1f8685aa4ab5defc4bb
parentMerge pull request #4173 (diff)
parentwallet2: fix O(n^2) behaviour in import_key_images (diff)
downloadmonero-7aa2030cee51a65084415ea629ad2f01f92a2dd9.tar.xz
Merge pull request #4174
ff37bd0 wallet2: fix O(n^2) behaviour in import_key_images (moneromooo-monero)
-rw-r--r--src/wallet/wallet2.cpp36
1 files changed, 15 insertions, 21 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 0c9580fc6..092356269 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -10000,6 +10000,17 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag
std::unordered_set<crypto::hash> spent_txids; // For each spent key image, search for a tx in m_transfers that uses it as input.
std::vector<size_t> swept_transfers; // If such a spending tx wasn't found in m_transfers, this means the spending tx
// was created by sweep_all, so we can't know the spent height and other detailed info.
+ std::unordered_map<crypto::key_image, crypto::hash> spent_key_images;
+
+ for (const transfer_details &td: m_transfers)
+ {
+ for (const cryptonote::txin_v& in : td.m_tx.vin)
+ {
+ if (in.type() == typeid(cryptonote::txin_to_key))
+ spent_key_images.insert(std::make_pair(boost::get<cryptonote::txin_to_key>(in).k_image, td.m_txid));
+ }
+ }
+
for(size_t i = 0; i < signed_key_images.size(); ++i)
{
transfer_details &td = m_transfers[i];
@@ -10013,28 +10024,11 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag
if (i < daemon_resp.spent_status.size() && daemon_resp.spent_status[i] == COMMAND_RPC_IS_KEY_IMAGE_SPENT::SPENT_IN_BLOCKCHAIN)
{
- bool is_spent_tx_found = false;
- for (auto it = m_transfers.rbegin(); &(*it) != &td; ++it)
- {
- bool is_spent_tx = false;
- for(const cryptonote::txin_v& in : it->m_tx.vin)
- {
- if(in.type() == typeid(cryptonote::txin_to_key) && td.m_key_image == boost::get<cryptonote::txin_to_key>(in).k_image)
- {
- is_spent_tx = true;
- break;
- }
- }
- if (is_spent_tx)
- {
- is_spent_tx_found = true;
- spent_txids.insert(it->m_txid);
- break;
- }
- }
-
- if (!is_spent_tx_found)
+ const std::unordered_map<crypto::key_image, crypto::hash>::const_iterator skii = spent_key_images.find(td.m_key_image);
+ if (skii == spent_key_images.end())
swept_transfers.push_back(i);
+ else
+ spent_txids.insert(skii->second);
}
}
MDEBUG("Total: " << print_money(spent) << " spent, " << print_money(unspent) << " unspent");