wallet2: key image import fixes
- return the right output data when offset is not zero - do not consider import failed if result height is zero (it can be 0 if unknown) - select the right tx pubkey when using subaddresses (it's faster, and we might select the wrong one if we got an output using one of the additional tx keys) - account for skipped outputs for spent/unspent balance info "spent" is arguably wrong, since it will count spent change multiple times as it goes through receive/spend cycles.
This commit is contained in:
parent
e65221d690
commit
c6a70af86a
|
@ -8597,13 +8597,8 @@ bool simple_wallet::import_key_images(const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
uint64_t spent = 0, unspent = 0;
|
uint64_t spent = 0, unspent = 0;
|
||||||
uint64_t height = m_wallet->import_key_images(filename, spent, unspent);
|
uint64_t height = m_wallet->import_key_images(filename, spent, unspent);
|
||||||
if (height > 0)
|
|
||||||
{
|
|
||||||
success_msg_writer() << "Signed key images imported to height " << height << ", "
|
success_msg_writer() << "Signed key images imported to height " << height << ", "
|
||||||
<< print_money(spent) << " spent, " << print_money(unspent) << " unspent";
|
<< print_money(spent) << " spent, " << print_money(unspent) << " unspent";
|
||||||
} else {
|
|
||||||
fail_msg_writer() << "Failed to import key images";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11002,15 +11002,6 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle
|
||||||
size_t pk_index = 0;
|
size_t pk_index = 0;
|
||||||
hw::device &hwdev = m_account.get_device();
|
hw::device &hwdev = m_account.get_device();
|
||||||
|
|
||||||
const std::vector<crypto::public_key> additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(td.m_tx);
|
|
||||||
std::vector<crypto::key_derivation> additional_derivations;
|
|
||||||
for (size_t i = 0; i < additional_tx_pub_keys.size(); ++i)
|
|
||||||
{
|
|
||||||
additional_derivations.push_back({});
|
|
||||||
bool r = hwdev.generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back());
|
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key derivation");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (find_tx_extra_field_by_type(tx_extra_fields, pub_key_field, pk_index++)) {
|
while (find_tx_extra_field_by_type(tx_extra_fields, pub_key_field, pk_index++)) {
|
||||||
const crypto::public_key tx_pub_key = pub_key_field.pub_key;
|
const crypto::public_key tx_pub_key = pub_key_field.pub_key;
|
||||||
crypto::key_derivation derivation;
|
crypto::key_derivation derivation;
|
||||||
|
@ -11020,16 +11011,15 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle
|
||||||
for (size_t i = 0; i < td.m_tx.vout.size(); ++i)
|
for (size_t i = 0; i < td.m_tx.vout.size(); ++i)
|
||||||
{
|
{
|
||||||
tx_scan_info_t tx_scan_info;
|
tx_scan_info_t tx_scan_info;
|
||||||
check_acc_out_precomp(td.m_tx.vout[i], derivation, additional_derivations, i, tx_scan_info);
|
check_acc_out_precomp(td.m_tx.vout[i], derivation, {}, i, tx_scan_info);
|
||||||
if (!tx_scan_info.error && tx_scan_info.received)
|
if (!tx_scan_info.error && tx_scan_info.received)
|
||||||
return tx_pub_key;
|
return tx_pub_key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we found no key yielding an output
|
// we found no key yielding an output, but it might be in the additional
|
||||||
THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error,
|
// tx pub keys only, which we do not need to check, so return the first one
|
||||||
"Public key yielding at least one output wasn't found in the transaction extra");
|
return tx_pub_key;
|
||||||
return crypto::null_pkey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wallet2::export_key_images(const std::string &filename) const
|
bool wallet2::export_key_images(const std::string &filename) const
|
||||||
|
@ -11271,6 +11261,17 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag
|
||||||
}
|
}
|
||||||
PERF_TIMER_STOP(import_key_images_C);
|
PERF_TIMER_STOP(import_key_images_C);
|
||||||
|
|
||||||
|
// accumulate outputs before the updated data
|
||||||
|
for(size_t i = 0; i < offset; ++i)
|
||||||
|
{
|
||||||
|
const transfer_details &td = m_transfers[i];
|
||||||
|
uint64_t amount = td.amount();
|
||||||
|
if (td.m_spent)
|
||||||
|
spent += amount;
|
||||||
|
else
|
||||||
|
unspent += amount;
|
||||||
|
}
|
||||||
|
|
||||||
PERF_TIMER_START(import_key_images_D);
|
PERF_TIMER_START(import_key_images_D);
|
||||||
for(size_t i = 0; i < signed_key_images.size(); ++i)
|
for(size_t i = 0; i < signed_key_images.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -11433,7 +11434,8 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag
|
||||||
PERF_TIMER_STOP(import_key_images_G);
|
PERF_TIMER_STOP(import_key_images_G);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_transfers[signed_key_images.size() - 1].m_block_height;
|
// this can be 0 if we do not know the height
|
||||||
|
return m_transfers[signed_key_images.size() + offset - 1].m_block_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wallet2::import_key_images(std::vector<crypto::key_image> key_images)
|
bool wallet2::import_key_images(std::vector<crypto::key_image> key_images)
|
||||||
|
|
Loading…
Reference in New Issue