wallet2: fix double counting outs if the tx pubkey is duplicated

This commit is contained in:
moneromooo-monero 2018-06-11 12:01:41 +01:00
parent a9b83f5a6e
commit 58cceaad71
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3
1 changed files with 24 additions and 10 deletions

View File

@ -1172,6 +1172,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;
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
@ -1192,6 +1193,13 @@ 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();
@ -1216,6 +1224,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
memcpy(&derivation, rct::identity().bytes, sizeof(derivation)); memcpy(&derivation, rct::identity().bytes, sizeof(derivation));
} }
if (pk_index == 1)
{
// additional tx pubkeys and derivations for multi-destination transfers involving one or more subaddresses // additional tx pubkeys and derivations for multi-destination transfers involving one or more subaddresses
if (find_tx_extra_field_by_type(tx_extra_fields, additional_tx_pub_keys)) if (find_tx_extra_field_by_type(tx_extra_fields, additional_tx_pub_keys))
{ {
@ -1230,18 +1240,22 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
} }
} }
} }
}
else else
{ {
THROW_WALLET_EXCEPTION_IF(pk_index - 1 >= tx_cache_data.primary.size(), THROW_WALLET_EXCEPTION_IF(pk_index - 1 >= tx_cache_data.primary.size(),
error::wallet_internal_error, "pk_index out of range of tx_cache_data"); error::wallet_internal_error, "pk_index out of range of tx_cache_data");
is_out_data_ptr = &tx_cache_data.primary[pk_index - 1]; is_out_data_ptr = &tx_cache_data.primary[pk_index - 1];
derivation = tx_cache_data.primary[pk_index - 1].derivation; derivation = tx_cache_data.primary[pk_index - 1].derivation;
if (pk_index == 1)
{
for (size_t n = 0; n < tx_cache_data.additional.size(); ++n) for (size_t n = 0; n < tx_cache_data.additional.size(); ++n)
{ {
additional_tx_pub_keys.data.push_back(tx_cache_data.additional[n].pkey); additional_tx_pub_keys.data.push_back(tx_cache_data.additional[n].pkey);
additional_derivations.push_back(tx_cache_data.additional[n].derivation); additional_derivations.push_back(tx_cache_data.additional[n].derivation);
} }
} }
}
if (miner_tx && m_refresh_type == RefreshNoCoinbase) if (miner_tx && m_refresh_type == RefreshNoCoinbase)
{ {