From 402c9eef0e25d8a295367206ea9f1aebdea7c6d7 Mon Sep 17 00:00:00 2001 From: stoffu Date: Mon, 22 Jan 2018 10:16:25 +0900 Subject: [PATCH] cryptonote_tx_utils: fixed logic bug in get_destination_view_key_pub --- src/cryptonote_core/cryptonote_tx_utils.cpp | 22 ++++++++++++--------- src/cryptonote_core/cryptonote_tx_utils.h | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 431d71556..4a10f7133 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -172,20 +172,24 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - crypto::public_key get_destination_view_key_pub(const std::vector &destinations, const account_keys &sender_keys) + crypto::public_key get_destination_view_key_pub(const std::vector &destinations, const boost::optional& change_addr) { - if (destinations.empty()) - return null_pkey; - for (size_t n = 1; n < destinations.size(); ++n) + account_public_address addr = {null_pkey, null_pkey}; + size_t count = 0; + for (const auto &i : destinations) { - if (!memcmp(&destinations[n].addr, &sender_keys.m_account_address, sizeof(destinations[0].addr))) + if (i.amount == 0) continue; - if (destinations[n].amount == 0) + if (change_addr && i.addr == *change_addr) continue; - if (memcmp(&destinations[n].addr, &destinations[0].addr, sizeof(destinations[0].addr))) + if (i.addr == addr) + continue; + if (count > 0) return null_pkey; + addr = i.addr; + ++count; } - return destinations[0].addr.m_view_public_key; + return addr.m_view_public_key; } //--------------------------------------------------------------- bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct, bool bulletproof, rct::multisig_out *msout) @@ -221,7 +225,7 @@ namespace cryptonote if (get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id)) { LOG_PRINT_L2("Encrypting payment id " << payment_id); - crypto::public_key view_key_pub = get_destination_view_key_pub(destinations, sender_account_keys); + crypto::public_key view_key_pub = get_destination_view_key_pub(destinations, change_addr); if (view_key_pub == null_pkey) { LOG_ERROR("Destinations have to have exactly one output to support encrypted payment ids"); diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h index e3b7a4f8c..1c390078d 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.h +++ b/src/cryptonote_core/cryptonote_tx_utils.h @@ -88,7 +88,7 @@ namespace cryptonote }; //--------------------------------------------------------------- - crypto::public_key get_destination_view_key_pub(const std::vector &destinations, const account_keys &sender_keys); + crypto::public_key get_destination_view_key_pub(const std::vector &destinations, const boost::optional& change_addr); bool construct_tx(const account_keys& sender_account_keys, std::vector &sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time); bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct = false, bool bulletproof = false, rct::multisig_out *msout = NULL); bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct = false, bool bulletproof = false, rct::multisig_out *msout = NULL);