Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wallet2: fix double counting outs if more than one pubkey #3985

Merged
merged 1 commit into from
Jul 3, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions src/wallet/wallet2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
size_t pk_index = 0;
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())
{
// if tx.vout is not empty, we loop through all tx pubkeys
Expand All @@ -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");
}

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;
tx_pub_key = pub_key_field.pub_key;
tools::threadpool& tpool = tools::threadpool::getInstance();
Expand All @@ -1216,16 +1224,19 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
memcpy(&derivation, rct::identity().bytes, sizeof(derivation));
}

// 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 (pk_index == 1)
{
for (size_t i = 0; i < additional_tx_pub_keys.data.size(); ++i)
// 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))
{
additional_derivations.push_back({});
if (!hwdev.generate_key_derivation(additional_tx_pub_keys.data[i], keys.m_view_secret_key, additional_derivations.back()))
for (size_t i = 0; i < additional_tx_pub_keys.data.size(); ++i)
{
MWARNING("Failed to generate key derivation from additional tx pubkey in " << txid << ", skipping");
memcpy(&additional_derivations.back(), rct::identity().bytes, sizeof(crypto::key_derivation));
additional_derivations.push_back({});
if (!hwdev.generate_key_derivation(additional_tx_pub_keys.data[i], keys.m_view_secret_key, additional_derivations.back()))
{
MWARNING("Failed to generate key derivation from additional tx pubkey in " << txid << ", skipping");
memcpy(&additional_derivations.back(), rct::identity().bytes, sizeof(crypto::key_derivation));
}
}
}
}
Expand All @@ -1236,10 +1247,13 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
error::wallet_internal_error, "pk_index out of range of tx_cache_data");
is_out_data_ptr = &tx_cache_data.primary[pk_index - 1];
derivation = tx_cache_data.primary[pk_index - 1].derivation;
for (size_t n = 0; n < tx_cache_data.additional.size(); ++n)
if (pk_index == 1)
{
additional_tx_pub_keys.data.push_back(tx_cache_data.additional[n].pkey);
additional_derivations.push_back(tx_cache_data.additional[n].derivation);
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_derivations.push_back(tx_cache_data.additional[n].derivation);
}
}
}

Expand Down