wallet: fix another facet of "did I get some monero" information leak
We get new pool txes before processing any tx, pool or not. This ensures that if we're asked for a password, this does not cause a measurable delay in the txpool query after the last block query.
This commit is contained in:
parent
d5472bd87b
commit
fd35e2304a
|
@ -8356,7 +8356,11 @@ bool simple_wallet::get_transfers(std::vector<std::string>& local_args, std::vec
|
||||||
m_in_manual_refresh.store(true, std::memory_order_relaxed);
|
m_in_manual_refresh.store(true, std::memory_order_relaxed);
|
||||||
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){m_in_manual_refresh.store(false, std::memory_order_relaxed);});
|
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){m_in_manual_refresh.store(false, std::memory_order_relaxed);});
|
||||||
|
|
||||||
m_wallet->update_pool_state();
|
std::vector<std::pair<cryptonote::transaction, bool>> process_txs;
|
||||||
|
m_wallet->update_pool_state(process_txs);
|
||||||
|
if (!process_txs.empty())
|
||||||
|
m_wallet->process_pool_state(process_txs);
|
||||||
|
|
||||||
std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>> payments;
|
std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>> payments;
|
||||||
m_wallet->get_unconfirmed_payments(payments, m_current_subaddress_account, subaddr_indices);
|
m_wallet->get_unconfirmed_payments(payments, m_current_subaddress_account, subaddr_indices);
|
||||||
for (std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) {
|
for (std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) {
|
||||||
|
@ -10002,7 +10006,11 @@ bool simple_wallet::show_transfer(const std::vector<std::string> &args)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_wallet->update_pool_state();
|
std::vector<std::pair<cryptonote::transaction, bool>> process_txs;
|
||||||
|
m_wallet->update_pool_state(process_txs);
|
||||||
|
if (!process_txs.empty())
|
||||||
|
m_wallet->process_pool_state(process_txs);
|
||||||
|
|
||||||
std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>> pool_payments;
|
std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>> pool_payments;
|
||||||
m_wallet->get_unconfirmed_payments(pool_payments, m_current_subaddress_account);
|
m_wallet->get_unconfirmed_payments(pool_payments, m_current_subaddress_account);
|
||||||
for (std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>>::const_iterator i = pool_payments.begin(); i != pool_payments.end(); ++i) {
|
for (std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>>::const_iterator i = pool_payments.begin(); i != pool_payments.end(); ++i) {
|
||||||
|
|
|
@ -2829,7 +2829,7 @@ void wallet2::remove_obsolete_pool_txs(const std::vector<crypto::hash> &tx_hashe
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::update_pool_state(bool refreshed)
|
void wallet2::update_pool_state(std::vector<std::pair<cryptonote::transaction, bool>> &process_txs, bool refreshed)
|
||||||
{
|
{
|
||||||
MTRACE("update_pool_state start");
|
MTRACE("update_pool_state start");
|
||||||
|
|
||||||
|
@ -3019,13 +3019,7 @@ void wallet2::update_pool_state(bool refreshed)
|
||||||
[tx_hash](const std::pair<crypto::hash, bool> &e) { return e.first == tx_hash; });
|
[tx_hash](const std::pair<crypto::hash, bool> &e) { return e.first == tx_hash; });
|
||||||
if (i != txids.end())
|
if (i != txids.end())
|
||||||
{
|
{
|
||||||
process_new_transaction(tx_hash, tx, std::vector<uint64_t>(), 0, 0, time(NULL), false, true, tx_entry.double_spend_seen, {});
|
process_txs.push_back(std::make_pair(tx, tx_entry.double_spend_seen));
|
||||||
m_scanned_pool_txs[0].insert(tx_hash);
|
|
||||||
if (m_scanned_pool_txs[0].size() > 5000)
|
|
||||||
{
|
|
||||||
std::swap(m_scanned_pool_txs[0], m_scanned_pool_txs[1]);
|
|
||||||
m_scanned_pool_txs[0].clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3056,6 +3050,24 @@ void wallet2::update_pool_state(bool refreshed)
|
||||||
MTRACE("update_pool_state end");
|
MTRACE("update_pool_state end");
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
void wallet2::process_pool_state(const std::vector<std::pair<cryptonote::transaction, bool>> &txs)
|
||||||
|
{
|
||||||
|
const time_t now = time(NULL);
|
||||||
|
for (const auto &e: txs)
|
||||||
|
{
|
||||||
|
const cryptonote::transaction &tx = e.first;
|
||||||
|
const bool double_spend_seen = e.second;
|
||||||
|
const crypto::hash tx_hash = get_transaction_hash(tx);
|
||||||
|
process_new_transaction(tx_hash, tx, std::vector<uint64_t>(), 0, 0, now, false, true, double_spend_seen, {});
|
||||||
|
m_scanned_pool_txs[0].insert(tx_hash);
|
||||||
|
if (m_scanned_pool_txs[0].size() > 5000)
|
||||||
|
{
|
||||||
|
std::swap(m_scanned_pool_txs[0], m_scanned_pool_txs[1]);
|
||||||
|
m_scanned_pool_txs[0].clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, bool force)
|
void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, bool force)
|
||||||
{
|
{
|
||||||
std::vector<crypto::hash> hashes;
|
std::vector<crypto::hash> hashes;
|
||||||
|
@ -3259,6 +3271,14 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
|
||||||
});
|
});
|
||||||
|
|
||||||
auto scope_exit_handler_hwdev = epee::misc_utils::create_scope_leave_handler([&](){hwdev.computing_key_images(false);});
|
auto scope_exit_handler_hwdev = epee::misc_utils::create_scope_leave_handler([&](){hwdev.computing_key_images(false);});
|
||||||
|
|
||||||
|
// get updated pool state first, but do not process those txes just yet,
|
||||||
|
// since that might cause a password prompt, which would introduce a data
|
||||||
|
// leak allowing a passive adversary with traffic analysis capability to
|
||||||
|
// infer when we get an incoming output
|
||||||
|
std::vector<std::pair<cryptonote::transaction, bool>> process_pool_txs;
|
||||||
|
update_pool_state(process_pool_txs, refreshed);
|
||||||
|
|
||||||
bool first = true, last = false;
|
bool first = true, last = false;
|
||||||
while(m_run.load(std::memory_order_relaxed))
|
while(m_run.load(std::memory_order_relaxed))
|
||||||
{
|
{
|
||||||
|
@ -3389,8 +3409,8 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// If stop() is called we don't need to check pending transactions
|
// If stop() is called we don't need to check pending transactions
|
||||||
if (check_pool && m_run.load(std::memory_order_relaxed))
|
if (check_pool && m_run.load(std::memory_order_relaxed) && !process_pool_txs.empty())
|
||||||
update_pool_state(refreshed);
|
process_pool_state(process_pool_txs);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1219,7 +1219,8 @@ private:
|
||||||
bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false);
|
bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false);
|
||||||
crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const;
|
crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const;
|
||||||
|
|
||||||
void update_pool_state(bool refreshed = false);
|
void update_pool_state(std::vector<std::pair<cryptonote::transaction, bool>> &process_txs, bool refreshed = false);
|
||||||
|
void process_pool_state(const std::vector<std::pair<cryptonote::transaction, bool>> &txs);
|
||||||
void remove_obsolete_pool_txs(const std::vector<crypto::hash> &tx_hashes);
|
void remove_obsolete_pool_txs(const std::vector<crypto::hash> &tx_hashes);
|
||||||
|
|
||||||
std::string encrypt(const char *plaintext, size_t len, const crypto::secret_key &skey, bool authenticated = true) const;
|
std::string encrypt(const char *plaintext, size_t len, const crypto::secret_key &skey, bool authenticated = true) const;
|
||||||
|
|
|
@ -2438,7 +2438,10 @@ namespace tools
|
||||||
|
|
||||||
if (req.pool)
|
if (req.pool)
|
||||||
{
|
{
|
||||||
m_wallet->update_pool_state();
|
std::vector<std::pair<cryptonote::transaction, bool>> process_txs;
|
||||||
|
m_wallet->update_pool_state(process_txs);
|
||||||
|
if (!process_txs.empty())
|
||||||
|
m_wallet->process_pool_state(process_txs);
|
||||||
|
|
||||||
std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>> payments;
|
std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>> payments;
|
||||||
m_wallet->get_unconfirmed_payments(payments, account_index, subaddr_indices);
|
m_wallet->get_unconfirmed_payments(payments, account_index, subaddr_indices);
|
||||||
|
@ -2518,7 +2521,10 @@ namespace tools
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_wallet->update_pool_state();
|
std::vector<std::pair<cryptonote::transaction, bool>> process_txs;
|
||||||
|
m_wallet->update_pool_state(process_txs);
|
||||||
|
if (!process_txs.empty())
|
||||||
|
m_wallet->process_pool_state(process_txs);
|
||||||
|
|
||||||
std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>> pool_payments;
|
std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>> pool_payments;
|
||||||
m_wallet->get_unconfirmed_payments(pool_payments, req.account_index);
|
m_wallet->get_unconfirmed_payments(pool_payments, req.account_index);
|
||||||
|
|
Loading…
Reference in New Issue