mirror of
https://codeberg.org/anoncontributorxmr/monero.git
synced 2024-11-25 08:52:26 +00:00
Merge pull request #4117
fc39d3b2
wallet2: ensure outputs are processed only once (moneromooo-monero)
This commit is contained in:
commit
7d2d8055ac
2 changed files with 18 additions and 14 deletions
|
@ -1057,6 +1057,16 @@ void wallet2::check_acc_out_precomp(const tx_out &o, const crypto::key_derivatio
|
||||||
tx_scan_info.error = false;
|
tx_scan_info.error = false;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
void wallet2::check_acc_out_precomp_once(const tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, const is_out_data *is_out_data, tx_scan_info_t &tx_scan_info, bool &already_seen) const
|
||||||
|
{
|
||||||
|
tx_scan_info.received = boost::none;
|
||||||
|
if (already_seen)
|
||||||
|
return;
|
||||||
|
check_acc_out_precomp(o, derivation, additional_derivations, i, is_out_data, tx_scan_info);
|
||||||
|
if (tx_scan_info.received)
|
||||||
|
already_seen = true;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
static uint64_t decodeRct(const rct::rctSig & rv, const crypto::key_derivation &derivation, unsigned int i, rct::key & mask, hw::device &hwdev)
|
static uint64_t decodeRct(const rct::rctSig & rv, const crypto::key_derivation &derivation, unsigned int i, rct::key & mask, hw::device &hwdev)
|
||||||
{
|
{
|
||||||
crypto::secret_key scalar1;
|
crypto::secret_key scalar1;
|
||||||
|
@ -1173,7 +1183,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||||
// Don't try to extract tx public key if tx has no ouputs
|
// Don't try to extract tx public key if tx has no ouputs
|
||||||
size_t pk_index = 0;
|
size_t pk_index = 0;
|
||||||
std::vector<tx_scan_info_t> tx_scan_info(tx.vout.size());
|
std::vector<tx_scan_info_t> tx_scan_info(tx.vout.size());
|
||||||
std::unordered_set<crypto::public_key> public_keys_seen;
|
std::deque<bool> output_found(tx.vout.size(), false);
|
||||||
while (!tx.vout.empty())
|
while (!tx.vout.empty())
|
||||||
{
|
{
|
||||||
// if tx.vout is not empty, we loop through all tx pubkeys
|
// if tx.vout is not empty, we loop through all tx pubkeys
|
||||||
|
@ -1194,13 +1204,6 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||||
error::wallet_internal_error, "tx_cache_data is out of sync");
|
error::wallet_internal_error, "tx_cache_data is out of sync");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (public_keys_seen.find(pub_key_field.pub_key) != public_keys_seen.end())
|
|
||||||
{
|
|
||||||
MWARNING("The same transaction pubkey is present more than once, ignoring extra instance");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
public_keys_seen.insert(pub_key_field.pub_key);
|
|
||||||
|
|
||||||
int num_vouts_received = 0;
|
int num_vouts_received = 0;
|
||||||
tx_pub_key = pub_key_field.pub_key;
|
tx_pub_key = pub_key_field.pub_key;
|
||||||
tools::threadpool& tpool = tools::threadpool::getInstance();
|
tools::threadpool& tpool = tools::threadpool::getInstance();
|
||||||
|
@ -1264,7 +1267,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||||
}
|
}
|
||||||
else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase)
|
else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase)
|
||||||
{
|
{
|
||||||
check_acc_out_precomp(tx.vout[0], derivation, additional_derivations, 0, is_out_data_ptr, tx_scan_info[0]);
|
check_acc_out_precomp_once(tx.vout[0], derivation, additional_derivations, 0, is_out_data_ptr, tx_scan_info[0], output_found[0]);
|
||||||
THROW_WALLET_EXCEPTION_IF(tx_scan_info[0].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
THROW_WALLET_EXCEPTION_IF(tx_scan_info[0].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
||||||
|
|
||||||
// this assumes that the miner tx pays a single address
|
// this assumes that the miner tx pays a single address
|
||||||
|
@ -1274,8 +1277,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||||
// the first one was already checked
|
// the first one was already checked
|
||||||
for (size_t i = 1; i < tx.vout.size(); ++i)
|
for (size_t i = 1; i < tx.vout.size(); ++i)
|
||||||
{
|
{
|
||||||
tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i,
|
tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp_once, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i,
|
||||||
std::cref(is_out_data_ptr), std::ref(tx_scan_info[i])), true);
|
std::cref(is_out_data_ptr), std::ref(tx_scan_info[i]), std::ref(output_found[i])), true);
|
||||||
}
|
}
|
||||||
waiter.wait(&tpool);
|
waiter.wait(&tpool);
|
||||||
// then scan all outputs from 0
|
// then scan all outputs from 0
|
||||||
|
@ -1297,8 +1300,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < tx.vout.size(); ++i)
|
for (size_t i = 0; i < tx.vout.size(); ++i)
|
||||||
{
|
{
|
||||||
tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i,
|
tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp_once, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i,
|
||||||
std::cref(is_out_data_ptr), std::ref(tx_scan_info[i])), true);
|
std::cref(is_out_data_ptr), std::ref(tx_scan_info[i]), std::ref(output_found[i])), true);
|
||||||
}
|
}
|
||||||
waiter.wait(&tpool);
|
waiter.wait(&tpool);
|
||||||
|
|
||||||
|
@ -1319,7 +1322,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < tx.vout.size(); ++i)
|
for (size_t i = 0; i < tx.vout.size(); ++i)
|
||||||
{
|
{
|
||||||
check_acc_out_precomp(tx.vout[i], derivation, additional_derivations, i, is_out_data_ptr, tx_scan_info[i]);
|
check_acc_out_precomp_once(tx.vout[i], derivation, additional_derivations, i, is_out_data_ptr, tx_scan_info[i], output_found[i]);
|
||||||
THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
||||||
if (tx_scan_info[i].received)
|
if (tx_scan_info[i].received)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1181,6 +1181,7 @@ namespace tools
|
||||||
crypto::hash get_payment_id(const pending_tx &ptx) const;
|
crypto::hash get_payment_id(const pending_tx &ptx) const;
|
||||||
void check_acc_out_precomp(const cryptonote::tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, tx_scan_info_t &tx_scan_info) const;
|
void check_acc_out_precomp(const cryptonote::tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, tx_scan_info_t &tx_scan_info) const;
|
||||||
void check_acc_out_precomp(const cryptonote::tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, const is_out_data *is_out_data, tx_scan_info_t &tx_scan_info) const;
|
void check_acc_out_precomp(const cryptonote::tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, const is_out_data *is_out_data, tx_scan_info_t &tx_scan_info) const;
|
||||||
|
void check_acc_out_precomp_once(const cryptonote::tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, const is_out_data *is_out_data, tx_scan_info_t &tx_scan_info, bool &already_seen) const;
|
||||||
void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const;
|
void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const;
|
||||||
uint64_t get_upper_transaction_size_limit() const;
|
uint64_t get_upper_transaction_size_limit() const;
|
||||||
std::vector<uint64_t> get_unspent_amounts_vector() const;
|
std::vector<uint64_t> get_unspent_amounts_vector() const;
|
||||||
|
|
Loading…
Reference in a new issue