wallet2: speedup large tx construction: batch ringdb updates
5.2 seconds -> 4.1 seconds on a test case
This commit is contained in:
parent
c9cf0b78f8
commit
2b95178897
|
@ -387,20 +387,24 @@ bool ringdb::get_ring(const crypto::chacha_key &chacha_key, const crypto::key_im
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ringdb::set_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, const std::vector<uint64_t> &outs, bool relative)
|
bool ringdb::set_rings(const crypto::chacha_key &chacha_key, const std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> &rings, bool relative)
|
||||||
{
|
{
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
int dbr;
|
int dbr;
|
||||||
bool tx_active = false;
|
bool tx_active = false;
|
||||||
|
|
||||||
dbr = resize_env(env, filename.c_str(), outs.size() * 64);
|
size_t n_outs = 0;
|
||||||
|
for (const auto &e: rings)
|
||||||
|
n_outs += e.second.size();
|
||||||
|
dbr = resize_env(env, filename.c_str(), n_outs * 64);
|
||||||
THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size: " + std::string(mdb_strerror(dbr)));
|
THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size: " + std::string(mdb_strerror(dbr)));
|
||||||
dbr = mdb_txn_begin(env, NULL, 0, &txn);
|
dbr = mdb_txn_begin(env, NULL, 0, &txn);
|
||||||
THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
|
THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
|
||||||
epee::misc_utils::auto_scope_leave_caller txn_dtor = epee::misc_utils::create_scope_leave_handler([&](){if (tx_active) mdb_txn_abort(txn);});
|
epee::misc_utils::auto_scope_leave_caller txn_dtor = epee::misc_utils::create_scope_leave_handler([&](){if (tx_active) mdb_txn_abort(txn);});
|
||||||
tx_active = true;
|
tx_active = true;
|
||||||
|
|
||||||
store_relative_ring(txn, dbi_rings, key_image, relative ? outs : cryptonote::absolute_output_offsets_to_relative(outs), chacha_key);
|
for (const auto &e: rings)
|
||||||
|
store_relative_ring(txn, dbi_rings, e.first, relative ? e.second : cryptonote::absolute_output_offsets_to_relative(e.second), chacha_key);
|
||||||
|
|
||||||
dbr = mdb_txn_commit(txn);
|
dbr = mdb_txn_commit(txn);
|
||||||
THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to commit txn setting ring to database: " + std::string(mdb_strerror(dbr)));
|
THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to commit txn setting ring to database: " + std::string(mdb_strerror(dbr)));
|
||||||
|
@ -408,6 +412,13 @@ bool ringdb::set_ring(const crypto::chacha_key &chacha_key, const crypto::key_im
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ringdb::set_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, const std::vector<uint64_t> &outs, bool relative)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> rings;
|
||||||
|
rings.push_back(std::make_pair(key_image, outs));
|
||||||
|
return set_rings(chacha_key, rings, relative);
|
||||||
|
}
|
||||||
|
|
||||||
bool ringdb::blackball_worker(const std::vector<std::pair<uint64_t, uint64_t>> &outputs, int op)
|
bool ringdb::blackball_worker(const std::vector<std::pair<uint64_t, uint64_t>> &outputs, int op)
|
||||||
{
|
{
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
|
|
|
@ -50,6 +50,7 @@ namespace tools
|
||||||
bool remove_rings(const crypto::chacha_key &chacha_key, const cryptonote::transaction_prefix &tx);
|
bool remove_rings(const crypto::chacha_key &chacha_key, const cryptonote::transaction_prefix &tx);
|
||||||
bool get_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, std::vector<uint64_t> &outs);
|
bool get_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, std::vector<uint64_t> &outs);
|
||||||
bool set_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, const std::vector<uint64_t> &outs, bool relative);
|
bool set_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, const std::vector<uint64_t> &outs, bool relative);
|
||||||
|
bool set_rings(const crypto::chacha_key &chacha_key, const std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> &rings, bool relative);
|
||||||
|
|
||||||
bool blackball(const std::pair<uint64_t, uint64_t> &output);
|
bool blackball(const std::pair<uint64_t, uint64_t> &output);
|
||||||
bool blackball(const std::vector<std::pair<uint64_t, uint64_t>> &outputs);
|
bool blackball(const std::vector<std::pair<uint64_t, uint64_t>> &outputs);
|
||||||
|
|
|
@ -7644,6 +7644,15 @@ bool wallet2::set_ring(const crypto::key_image &key_image, const std::vector<uin
|
||||||
catch (const std::exception &e) { return false; }
|
catch (const std::exception &e) { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wallet2::set_rings(const std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> &rings, bool relative)
|
||||||
|
{
|
||||||
|
if (!m_ringdb)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try { return m_ringdb->set_rings(get_ringdb_key(), rings, relative); }
|
||||||
|
catch (const std::exception &e) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
bool wallet2::unset_ring(const std::vector<crypto::key_image> &key_images)
|
bool wallet2::unset_ring(const std::vector<crypto::key_image> &key_images)
|
||||||
{
|
{
|
||||||
if (!m_ringdb)
|
if (!m_ringdb)
|
||||||
|
@ -8580,6 +8589,8 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
|
||||||
}
|
}
|
||||||
|
|
||||||
// save those outs in the ringdb for reuse
|
// save those outs in the ringdb for reuse
|
||||||
|
std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> rings;
|
||||||
|
rings.reserve(selected_transfers.size());
|
||||||
for (size_t i = 0; i < selected_transfers.size(); ++i)
|
for (size_t i = 0; i < selected_transfers.size(); ++i)
|
||||||
{
|
{
|
||||||
const size_t idx = selected_transfers[i];
|
const size_t idx = selected_transfers[i];
|
||||||
|
@ -8589,9 +8600,10 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
|
||||||
ring.reserve(outs[i].size());
|
ring.reserve(outs[i].size());
|
||||||
for (const auto &e: outs[i])
|
for (const auto &e: outs[i])
|
||||||
ring.push_back(std::get<0>(e));
|
ring.push_back(std::get<0>(e));
|
||||||
if (!set_ring(td.m_key_image, ring, false))
|
rings.push_back(std::make_pair(td.m_key_image, std::move(ring)));
|
||||||
MERROR("Failed to set ring for " << td.m_key_image);
|
|
||||||
}
|
}
|
||||||
|
if (!set_rings(rings, false))
|
||||||
|
MERROR("Failed to set rings");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -1559,6 +1559,7 @@ private:
|
||||||
bool get_ring(const crypto::key_image &key_image, std::vector<uint64_t> &outs);
|
bool get_ring(const crypto::key_image &key_image, std::vector<uint64_t> &outs);
|
||||||
bool get_rings(const crypto::hash &txid, std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> &outs);
|
bool get_rings(const crypto::hash &txid, std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> &outs);
|
||||||
bool set_ring(const crypto::key_image &key_image, const std::vector<uint64_t> &outs, bool relative);
|
bool set_ring(const crypto::key_image &key_image, const std::vector<uint64_t> &outs, bool relative);
|
||||||
|
bool set_rings(const std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> &rings, bool relative);
|
||||||
bool unset_ring(const std::vector<crypto::key_image> &key_images);
|
bool unset_ring(const std::vector<crypto::key_image> &key_images);
|
||||||
bool unset_ring(const crypto::hash &txid);
|
bool unset_ring(const crypto::hash &txid);
|
||||||
bool find_and_save_rings(bool force = true);
|
bool find_and_save_rings(bool force = true);
|
||||||
|
|
Loading…
Reference in New Issue