diff --git a/src/carrot_impl/account.cpp b/src/carrot_impl/account.cpp index 8a3dd990f..a6dc59c8c 100644 --- a/src/carrot_impl/account.cpp +++ b/src/carrot_impl/account.cpp @@ -328,6 +328,13 @@ void carrot_and_legacy_account::set_carrot_keys(const AddressDeriveType default_ this->default_derive_type = default_derive_type; generate_subaddress_map(); } +//---------------------------------------------------------------------------------------------------------------------- +void carrot_and_legacy_account::set_cn_subaddress_map(const std::unordered_map& subaddress_map_cn) +{ + for (const auto &p : subaddress_map_cn) + subaddress_map.insert({p.first, {{p.second.major, p.second.minor}, AddressDeriveType::PreCarrot}}); +} + //---------------------------------------------------------------------------------------------------------------------- AddressDeriveType carrot_and_legacy_account::resolve_derive_type(const AddressDeriveType derive_type) const { diff --git a/src/carrot_impl/account.h b/src/carrot_impl/account.h index ac165727e..1f4cc72d7 100644 --- a/src/carrot_impl/account.h +++ b/src/carrot_impl/account.h @@ -108,6 +108,8 @@ namespace carrot void set_carrot_keys(const AddressDeriveType default_derive_type = AddressDeriveType::Carrot); + void set_cn_subaddress_map(const std::unordered_map& subaddress_map); + AddressDeriveType resolve_derive_type(const AddressDeriveType derive_type) const; }; } diff --git a/src/carrot_impl/format_utils.cpp b/src/carrot_impl/format_utils.cpp index c3c97aa4d..9acac376e 100644 --- a/src/carrot_impl/format_utils.cpp +++ b/src/carrot_impl/format_utils.cpp @@ -205,7 +205,7 @@ cryptonote::transaction store_carrot_to_transaction_v1(const std::vector view_incoming_scan_pre_car const std::optional &encrypted_payment_id, const epee::span main_derivations, const epee::span additional_derivations, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore, + carrot::carrot_and_legacy_account &account, hw::device &hwdev) { - - const std::unordered_map &subaddress_map = subaddress_keystore.get_all(); + const std::unordered_map &subaddress_map = account.subaddress_map_cn(); boost::optional receive_info; size_t main_deriv_idx; @@ -241,7 +239,7 @@ static std::optional view_incoming_scan_pre_car }; // add the entry to our temporary subaddress map via the keystore - subaddress_keystore.add(enote.onetime_address, {subaddr_index.index.major, subaddr_index.index.minor}); + account.subaddress_map.insert({enote.onetime_address, subaddr_index}); return enote_view_incoming_scan_info_t{ .sender_extension_g = sender_extension_g, @@ -338,8 +336,7 @@ static std::optional view_incoming_scan_carrot_ const mx25519_pubkey &s_sender_receiver_unctx, const crypto::public_key &main_address_spend_pubkey, const carrot::view_incoming_key_device &k_view_dev, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore) + carrot::carrot_and_legacy_account &account) { enote_view_incoming_scan_info_t res; @@ -360,7 +357,9 @@ static std::optional view_incoming_scan_carrot_ dummy_enote_type)) return std::nullopt; - const std::unordered_map &subaddress_map = subaddress_keystore.get_all(); + // Check for a Carrot + + const std::unordered_map &subaddress_map = account.subaddress_map_cn(); const auto subaddr_it = subaddress_map.find(res.address_spend_pubkey); CHECK_AND_ASSERT_MES(subaddr_it != subaddress_map.cend(), @@ -471,8 +470,7 @@ std::optional view_incoming_scan_enote( const epee::span additional_derivations, const cryptonote::account_public_address &address, const carrot::view_incoming_key_device *k_view_dev, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore, + carrot::carrot_and_legacy_account &account, hw::device &hwdev) { CHECK_AND_ASSERT_MES(!main_derivations.empty() || !additional_derivations.empty(), @@ -498,7 +496,7 @@ std::optional view_incoming_scan_enote( encrypted_payment_id, main_derivations, additional_derivations, - subaddress_keystore, + account, hwdev); // copy long plaintext payment ID, if applicable @@ -543,7 +541,7 @@ std::optional view_incoming_scan_enote( s_sender_receiver_unctx, address.m_spend_public_key, *k_view_dev, - subaddress_keystore); + account); } } @@ -554,8 +552,7 @@ std::optional view_incoming_scan_enote( const epee::span additional_derivations; const cryptonote::account_public_address &address; const carrot::view_incoming_key_device *k_view_dev; - //const std::unordered_map &subaddress_map; - tools::keystore &subaddress_keystore; + carrot::carrot_and_legacy_account &account; hw::device &hwdev; }; @@ -567,7 +564,7 @@ std::optional view_incoming_scan_enote( additional_derivations, address, k_view_dev, - subaddress_keystore, + account, hwdev }, enote); @@ -583,8 +580,7 @@ std::optional view_incoming_scan_enote( const epee::span additional_derivations, const cryptonote::account_public_address &address, const carrot::view_incoming_key_device *k_view_dev, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore, + carrot::carrot_and_legacy_account &account, hw::device &hwdev) { MoneroEnoteVariant enote; @@ -635,14 +631,14 @@ std::optional view_incoming_scan_enote( } return view_incoming_scan_enote(enote, - local_output_index, - tx_extra_nonce, - main_derivations, - additional_derivations, - address, - k_view_dev, - subaddress_keystore, - hwdev); + local_output_index, + tx_extra_nonce, + main_derivations, + additional_derivations, + address, + k_view_dev, + account, + hwdev); } //------------------------------------------------------------------------------------------------------------------- std::optional view_incoming_scan_enote_from_prefix( @@ -652,8 +648,7 @@ std::optional view_incoming_scan_enote_from_pre const std::size_t local_output_index, const cryptonote::account_public_address &address, const crypto::secret_key &k_view_incoming, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore, + carrot::carrot_and_legacy_account &account, hw::device &hwdev) { const bool is_carrot = carrot::is_carrot_transaction_v1(tx_prefix); @@ -700,13 +695,13 @@ std::optional view_incoming_scan_enote_from_pre // 4. view scan enote return view_incoming_scan_enote(enote, - local_output_index, - tx_extra_nonce, - epee::to_span(main_derivations), - epee::to_span(additional_derivations), - address, - &k_view_dev, - subaddress_keystore, + local_output_index, + tx_extra_nonce, + epee::to_span(main_derivations), + epee::to_span(additional_derivations), + address, + &k_view_dev, + account, hwdev); } //------------------------------------------------------------------------------------------------------------------- @@ -717,9 +712,7 @@ void view_incoming_scan_transaction( const cryptonote::blobdata &tx_extra_nonce, const epee::span main_derivations, const epee::span additional_derivations, - const cryptonote::account_keys &acc, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore, + carrot::carrot_and_legacy_account &account, const epee::span> enote_scan_infos_out) { const size_t n_outputs = tx.vout.size(); @@ -729,31 +722,29 @@ void view_incoming_scan_transaction( //! @TODO: HW device const bool is_carrot = carrot::is_carrot_transaction_v1(tx); - carrot::view_incoming_key_ram_borrowed_device k_view_dev(acc.m_view_secret_key); + carrot::view_incoming_key_ram_borrowed_device k_view_dev(account.get_keys().m_view_secret_key); // do view-incoming scan for each output enotes for (size_t local_output_index = 0; local_output_index < n_outputs; ++local_output_index) { auto &enote_scan_info = const_cast&>(enote_scan_infos_out[local_output_index]); enote_scan_info = view_incoming_scan_enote(tx, - local_output_index, - main_tx_ephemeral_pubkeys, - additional_tx_ephemeral_pubkeys, - tx_extra_nonce, - main_derivations, - additional_derivations, - is_carrot ? acc.m_carrot_account_address : acc.m_account_address, - &k_view_dev, - subaddress_keystore, - acc.get_device()); + local_output_index, + main_tx_ephemeral_pubkeys, + additional_tx_ephemeral_pubkeys, + tx_extra_nonce, + main_derivations, + additional_derivations, + is_carrot ? account.get_keys().m_carrot_account_address : account.get_keys().m_account_address, + &k_view_dev, + account, + account.get_keys().get_device()); } } //------------------------------------------------------------------------------------------------------------------- void view_incoming_scan_transaction( const cryptonote::transaction &tx, - const cryptonote::account_keys &acc, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore, + carrot::carrot_and_legacy_account &account, const epee::span> enote_scan_infos_out) { // 1. parse tx extra @@ -775,36 +766,33 @@ void view_incoming_scan_transaction( std::vector additional_derivations; const bool is_carrot = carrot::is_carrot_transaction_v1(tx); perform_ecdh_derivations(epee::to_span(main_tx_ephemeral_pubkeys), - epee::to_span(additional_tx_ephemeral_pubkeys), - acc.m_view_secret_key, - acc.get_device(), - is_carrot, - main_derivations, - additional_derivations); + epee::to_span(additional_tx_ephemeral_pubkeys), + account.get_keys().m_view_secret_key, + account.get_keys().get_device(), + is_carrot, + main_derivations, + additional_derivations); // 3. view-incoming scan output enotes view_incoming_scan_transaction(tx, - epee::to_span(main_tx_ephemeral_pubkeys), - epee::to_span(additional_tx_ephemeral_pubkeys), - tx_extra_nonce, - epee::to_span(main_derivations), - epee::to_span(additional_derivations), - acc, - subaddress_keystore, - enote_scan_infos_out); + epee::to_span(main_tx_ephemeral_pubkeys), + epee::to_span(additional_tx_ephemeral_pubkeys), + tx_extra_nonce, + epee::to_span(main_derivations), + epee::to_span(additional_derivations), + account, + enote_scan_infos_out); } //------------------------------------------------------------------------------------------------------------------- std::vector> view_incoming_scan_transaction( const cryptonote::transaction &tx, - const cryptonote::account_keys &acc, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore) + carrot::carrot_and_legacy_account &account) { const auto n_outputs = tx.vout.size(); std::vector> res(n_outputs); if (n_outputs > 0) { - view_incoming_scan_transaction(tx, acc, subaddress_keystore, epee::to_mut_span(res)); + view_incoming_scan_transaction(tx, account, epee::to_mut_span(res)); } return res; @@ -814,7 +802,8 @@ std::vector> view_incoming_scan_t const cryptonote::transaction &tx, const epee::span custom_main_derivations, const epee::span custom_additional_derivations, - const cryptonote::account_public_address &address) + const cryptonote::account_public_address &address, + carrot::carrot_and_legacy_account &account) { // 1. Resize output const size_t n_outputs = tx.vout.size(); @@ -831,9 +820,6 @@ std::vector> view_incoming_scan_t tx_extra_nonce)) MWARNING("Transaction extra has unsupported format: " << cryptonote::get_transaction_hash(tx)); - tools::keystore keystore; - keystore.add(address.m_spend_public_key, {}); - // 3. do view-incoming scan for each output enotes hw::device &hwdev = hw::get_device("default"); for (size_t local_output_index = 0; local_output_index < n_outputs; ++local_output_index) @@ -841,16 +827,16 @@ std::vector> view_incoming_scan_t auto &enote_scan_info = res[local_output_index]; enote_scan_info = view_incoming_scan_enote(tx, - local_output_index, - epee::to_span(main_tx_ephemeral_pubkeys), - epee::to_span(additional_tx_ephemeral_pubkeys), - tx_extra_nonce, - custom_main_derivations, - custom_additional_derivations, - address, - /*k_view_dev=*/nullptr, - keystore, - hwdev); + local_output_index, + epee::to_span(main_tx_ephemeral_pubkeys), + epee::to_span(additional_tx_ephemeral_pubkeys), + tx_extra_nonce, + custom_main_derivations, + custom_additional_derivations, + address, + /*k_view_dev=*/nullptr, + account, + hwdev); } return res; diff --git a/src/wallet/scanning_tools.h b/src/wallet/scanning_tools.h index 9cbd7cb1c..14e936810 100644 --- a/src/wallet/scanning_tools.h +++ b/src/wallet/scanning_tools.h @@ -38,7 +38,6 @@ #include "cryptonote_basic/blobdatatype.h" #include "cryptonote_basic/subaddress_index.h" #include "cryptonote_basic/tx_extra.h" -#include "common/keystore.h" #include "common/variant.h" //third party headers @@ -108,8 +107,7 @@ std::optional view_incoming_scan_enote_from_pre const std::size_t local_output_index, const cryptonote::account_public_address &address, const crypto::secret_key &k_view_incoming, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore, + carrot::carrot_and_legacy_account &account, hw::device &hwdev); void view_incoming_scan_transaction( @@ -119,27 +117,22 @@ void view_incoming_scan_transaction( const cryptonote::blobdata &tx_extra_nonce, const epee::span main_derivations, const epee::span additional_derivations, - const cryptonote::account_keys &acc, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore, + carrot::carrot_and_legacy_account &account, const epee::span> enote_scan_infos_out); void view_incoming_scan_transaction( const cryptonote::transaction &tx, - const cryptonote::account_keys &acc, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore, + carrot::carrot_and_legacy_account &account, const epee::span> enote_scan_infos_out); std::vector> view_incoming_scan_transaction( const cryptonote::transaction &tx, - const cryptonote::account_keys &acc, - //const std::unordered_map &subaddress_map, - tools::keystore &subaddress_keystore); + carrot::carrot_and_legacy_account &account); std::vector> view_incoming_scan_transaction_as_sender( const cryptonote::transaction &tx, const epee::span custom_main_derivations, const epee::span custom_additional_derivations, - const cryptonote::account_public_address &address); + const cryptonote::account_public_address &address, + carrot::carrot_and_legacy_account &account); bool is_long_payment_id(const crypto::hash &pid); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 68c254d6b..2b111214f 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2447,11 +2447,9 @@ void wallet2::process_new_transaction( const size_t n_outputs = tx.vout.size(); // view-incoming scan enotes - tools::keystore keystore(m_subaddresses); const std::vector> enote_scan_infos = wallet::view_incoming_scan_transaction(tx, - this->m_account.get_keys(), - keystore); + this->m_account); // if view-incoming scan was successful, try deriving the key image bool password_failure = false; @@ -3470,14 +3468,11 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect hw::reset_mode rst(hwdev); hwdev.set_mode(hw::device::TRANSACTION_PARSE); - // Create a thread-safe keystore instance to allow detection of `STAKE`, `AUDIT` and `RETURN_PAYMENT` TX outputs - tools::keystore keystore(m_subaddresses); - // define view-incoming scan and key image derivation job std::vector> enote_scan_infos(num_tx_outputs); std::vector> output_key_images(num_tx_outputs); bool password_failure = false; - auto tx_scan_job = [this, &enote_scan_infos, &output_key_images, &password_failure, &keystore] + auto tx_scan_job = [this, &enote_scan_infos, &output_key_images, &password_failure] (const cryptonote::transaction &tx, size_t tx_output_idx) { if (tx.vout.empty()) @@ -3494,8 +3489,7 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect } wallet::view_incoming_scan_transaction(tx, - this->m_account.get_keys(), - keystore, + this->m_account, {&enote_scan_infos[0] + tx_output_idx, tx.vout.size()}); // if view-incoming scan was successful, try deriving the key image @@ -5542,6 +5536,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st if (r) { m_account.set_carrot_keys(); + m_account.set_cn_subaddress_map(m_subaddresses); if (!m_is_background_wallet) setup_keys(password); @@ -12904,9 +12899,10 @@ void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypt received = 0; const auto enote_scan_infos = wallet::view_incoming_scan_transaction_as_sender(tx, - {&derivation, 1}, - epee::to_span(additional_derivations), - address); + {&derivation, 1}, + epee::to_span(additional_derivations), + address, + m_account); for (const auto &enote_scan_info : enote_scan_infos) if (enote_scan_info && enote_scan_info->address_spend_pubkey == address.m_spend_public_key) @@ -13907,8 +13903,6 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle error::wallet_internal_error, "get_tx_pub_key_from_received_outs is not relevant for Carrot txs"); - tools::keystore subaddress_keystore(m_subaddresses); - const auto enote_scan_info = wallet::view_incoming_scan_enote_from_prefix( td.m_tx, td.amount(), @@ -13916,7 +13910,7 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle td.m_internal_output_index, m_account_public_address, m_account.get_keys().m_view_secret_key, - subaddress_keystore, + m_account, m_account.get_device()); const size_t main_tx_pubkey_index = enote_scan_info ? enote_scan_info->main_tx_pubkey_index : 0; @@ -14237,7 +14231,6 @@ uint64_t wallet2::import_key_images(const std::vector tx_money_got_in_outs; const auto enote_scan_infos = wallet::view_incoming_scan_transaction(spent_tx, - m_account.get_keys(), - keystore); + m_account); for (const auto &enote_scan_info : enote_scan_infos) if (enote_scan_info && enote_scan_info->subaddr_index) tx_money_got_in_outs[enote_scan_info->asset_type] += enote_scan_info->amount; //! @TODO: check overflow diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index dea18874b..9efd9c51b 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -2095,7 +2095,7 @@ private: bool should_expand(const cryptonote::subaddress_index &index) const; bool spends_one_of_ours(const cryptonote::transaction &tx) const; - carrot::carrot_and_legacy_account m_account; + mutable carrot::carrot_and_legacy_account m_account; boost::optional m_daemon_login; std::string m_daemon_address; std::string m_proxy;