mirror of
https://github.com/monero-project/monero.git
synced 2024-12-23 12:09:54 +00:00
wallet2: fix O(n^2) behaviour in import_key_images
That takes a lot of time for even not so large wallets
This commit is contained in:
parent
702a41034d
commit
ff37bd00bc
1 changed files with 15 additions and 21 deletions
|
@ -9870,6 +9870,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::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
|
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.
|
// 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)
|
for(size_t i = 0; i < signed_key_images.size(); ++i)
|
||||||
{
|
{
|
||||||
transfer_details &td = m_transfers[i];
|
transfer_details &td = m_transfers[i];
|
||||||
|
@ -9883,28 +9894,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)
|
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;
|
const std::unordered_map<crypto::key_image, crypto::hash>::const_iterator skii = spent_key_images.find(td.m_key_image);
|
||||||
for (auto it = m_transfers.rbegin(); &(*it) != &td; ++it)
|
if (skii == spent_key_images.end())
|
||||||
{
|
|
||||||
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)
|
|
||||||
swept_transfers.push_back(i);
|
swept_transfers.push_back(i);
|
||||||
|
else
|
||||||
|
spent_txids.insert(skii->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MDEBUG("Total: " << print_money(spent) << " spent, " << print_money(unspent) << " unspent");
|
MDEBUG("Total: " << print_money(spent) << " spent, " << print_money(unspent) << " unspent");
|
||||||
|
|
Loading…
Reference in a new issue