From afdfb7af4745e83b6805b844c2b72c125e8a15e3 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 4 Jun 2019 14:35:07 +0300 Subject: [PATCH] wallet: backup outkeys2ki for offline wallet on sign_tranfer --- src/simplewallet/simplewallet.cpp | 1 + src/wallet/wallet2.cpp | 49 +++++++++++++++++++++---------- src/wallet/wallet2.h | 7 ++++- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index e9ad2169..0fcdd4e9 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -397,6 +397,7 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa m_wallet_file = wallet_file; m_wallet.reset(new tools::wallet2()); m_wallet->callback(shared_from_this()); + m_wallet->set_force_keep_outkey2ki_file(m_offline_mode); // enfoce a wallet opened in offline mode to keep outkey2ki file for a backup purpose while (true) { diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 44a78c5a..bbd63baa 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1984,7 +1984,7 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password) bool need_to_resync = !tools::portable_unserialize_obj_from_stream(*this, data_file); - if (m_watch_only) + if (m_watch_only || m_force_keep_outkey2ki_file) load_keys2ki(true, need_to_resync); if (need_to_resync) @@ -2214,6 +2214,8 @@ void wallet2::sign_transfer(const std::string& tx_sources_blob, std::string& sig finalize_transaction(ft.ftp, ft.tx, ft.one_time_key, false); + crypto::hash tx_hash = get_transaction_hash(ft.tx); + // calculate key images for each change output crypto::key_derivation derivation = AUTO_VAL_INIT(derivation); WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX( @@ -2248,6 +2250,9 @@ void wallet2::sign_transfer(const std::string& tx_sources_blob, std::string& sig crypto::generate_key_image(ephemeral_pub, ephemeral_sec, ki); ft.outs_key_images.push_back(make_serializable_pair(static_cast(i), ki)); + + if (m_force_keep_outkey2ki_file) + add_pending_pub_key_2_key_image_pair(otk.key, ki, tx_hash); } } @@ -2331,19 +2336,7 @@ void wallet2::submit_transfer(const std::string& signed_tx_blob, currency::trans } for (auto& p : pk_ki_to_be_added) - { - auto it = m_pending_key_images.find(p.first); - if (it != m_pending_key_images.end()) - { - LOG_PRINT_YELLOW("warning: for tx " << tx_hash << " out pub key " << p.first << " already exist in m_pending_key_images, ki: " << it->second << ", proposed new ki: " << p.second, LOG_LEVEL_0); - } - else - { - m_pending_key_images[p.first] = p.second; - m_pending_key_images_file_container.push_back(tools::out_key_to_ki(p.first, p.second)); - LOG_PRINT_L2("for tx " << tx_hash << " pending key image added (" << p.first << ", " << p.second << ")"); - } - } + add_pending_pub_key_2_key_image_pair(p.first, p.second, tx_hash); for (auto& p : tri_ki_to_be_added) { @@ -2372,6 +2365,27 @@ void wallet2::submit_transfer_files(const std::string& signed_tx_file, currency: submit_transfer(signed_tx_blob, tx); } //---------------------------------------------------------------------------------------------------- +void wallet2::add_pending_pub_key_2_key_image_pair(const crypto::public_key& pub_key, const crypto::key_image& ki, const crypto::hash& tx_hash) +{ + auto it = m_pending_key_images.find(pub_key); + if (it != m_pending_key_images.end()) + { + LOG_PRINT_YELLOW("warning: for tx " << tx_hash << " out pub key " << pub_key << " already exist in m_pending_key_images, ki: " << it->second << ", proposed new ki: " << ki, LOG_LEVEL_0); + } + else + { + m_pending_key_images[pub_key] = ki; + if (m_pending_key_images_file_container.push_back(tools::out_key_to_ki(pub_key, ki))) + { + LOG_PRINT_L1("for tx " << tx_hash << " pending key image added (" << pub_key << ", " << ki << ")"); + } + else + { + LOG_ERROR("for tx " << tx_hash << " pending key image WAS NOT added (" << pub_key << ", " << ki << ")"); + } + } +} +//---------------------------------------------------------------------------------------------------- uint64_t wallet2::get_recent_transfers_total_count() { return m_transfer_history.size(); @@ -4084,6 +4098,11 @@ void wallet2::transfer(const std::vector& dsts, print_tx_sent_message(tx, std::string() + "(transfer)", fee); } - +//---------------------------------------------------------------------------------------------------- +void wallet2::set_force_keep_outkey2ki_file(bool value) +{ + m_force_keep_outkey2ki_file = value; +} +//---------------------------------------------------------------------------------------------------- } // namespace tools diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index ee92ebac..d3691dab 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -322,7 +322,8 @@ namespace tools m_fake_outputs_count(0), m_do_rise_transfer(false), m_log_prefix("???"), - m_watch_only(false) + m_watch_only(false), + m_force_keep_outkey2ki_file(false) { m_core_runtime_config = currency::get_default_core_runtime_config(); }; @@ -461,6 +462,8 @@ namespace tools void init(const std::string& daemon_address = "http://localhost:8080"); bool deinit(); + void set_force_keep_outkey2ki_file(bool value); // enfoce a wallet to keep outkey2ki file for a backup purpose + void stop() { m_stop.store(true, std::memory_order_relaxed); } void reset_creation_time(uint64_t timestamp); @@ -829,6 +832,7 @@ private: void exception_handler() const; uint64_t get_minimum_allowed_fee_for_contract(const crypto::hash& ms_id); + void add_pending_pub_key_2_key_image_pair(const crypto::public_key& pub_key, const crypto::key_image& ki, const crypto::hash& tx_hash); @@ -842,6 +846,7 @@ private: std::atomic m_local_bc_height; //temporary workaround std::atomic m_last_bc_timestamp; bool m_do_rise_transfer; + bool m_force_keep_outkey2ki_file; transfer_container m_transfers; multisig_transfer_container m_multisig_transfers;