diff options
Diffstat (limited to 'src/simplewallet/simplewallet.cpp')
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 119 |
1 files changed, 92 insertions, 27 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 52d880d2c..91a8f6348 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018, The Monero Project +// Copyright (c) 2014-2019, The Monero Project // // All rights reserved. // @@ -192,7 +192,7 @@ namespace const char* USAGE_CHECK_RESERVE_PROOF("check_reserve_proof <address> <signature_file> [<message>]"); const char* USAGE_SHOW_TRANSFERS("show_transfers [in|out|pending|failed|pool|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]"); const char* USAGE_UNSPENT_OUTPUTS("unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]"); - const char* USAGE_RESCAN_BC("rescan_bc [hard]"); + const char* USAGE_RESCAN_BC("rescan_bc [hard|soft|keep_ki] [start_height=0]"); const char* USAGE_SET_TX_NOTE("set_tx_note <txid> [free text note]"); const char* USAGE_GET_TX_NOTE("get_tx_note <txid>"); const char* USAGE_GET_DESCRIPTION("get_description"); @@ -2051,7 +2051,7 @@ bool simple_wallet::cold_sign_tx(const std::vector<tools::wallet2::pending_tx>& m_wallet->cold_tx_aux_import(exported_txs.ptx, tx_aux); // import key images - return m_wallet->import_key_images(exported_txs.key_images); + return m_wallet->import_key_images(exported_txs, 0, true); } bool simple_wallet::set_always_confirm_transfers(const std::vector<std::string> &args/* = std::vector<std::string>()*/) @@ -4688,12 +4688,12 @@ boost::optional<epee::wipeable_string> simple_wallet::on_get_password(const char return pwd_container->password(); } //---------------------------------------------------------------------------------------------------- -void simple_wallet::on_button_request() +void simple_wallet::on_device_button_request(uint64_t code) { message_writer(console_color_white, false) << tr("Device requires attention"); } //---------------------------------------------------------------------------------------------------- -void simple_wallet::on_pin_request(epee::wipeable_string & pin) +boost::optional<epee::wipeable_string> simple_wallet::on_device_pin_request() { #ifdef HAVE_READLINE rdln::suspend_readline pause_readline; @@ -4701,14 +4701,14 @@ void simple_wallet::on_pin_request(epee::wipeable_string & pin) std::string msg = tr("Enter device PIN"); auto pwd_container = tools::password_container::prompt(false, msg.c_str()); THROW_WALLET_EXCEPTION_IF(!pwd_container, tools::error::password_entry_failed, tr("Failed to read device PIN")); - pin = pwd_container->password(); + return pwd_container->password(); } //---------------------------------------------------------------------------------------------------- -void simple_wallet::on_passphrase_request(bool on_device, epee::wipeable_string & passphrase) +boost::optional<epee::wipeable_string> simple_wallet::on_device_passphrase_request(bool on_device) { if (on_device){ message_writer(console_color_white, true) << tr("Please enter the device passphrase on the device"); - return; + return boost::none; } #ifdef HAVE_READLINE @@ -4717,13 +4717,13 @@ void simple_wallet::on_passphrase_request(bool on_device, epee::wipeable_string std::string msg = tr("Enter device passphrase"); auto pwd_container = tools::password_container::prompt(false, msg.c_str()); THROW_WALLET_EXCEPTION_IF(!pwd_container, tools::error::password_entry_failed, tr("Failed to read device passphrase")); - passphrase = pwd_container->password(); + return pwd_container->password(); } //---------------------------------------------------------------------------------------------------- void simple_wallet::on_refresh_finished(uint64_t start_height, uint64_t fetched_blocks, bool is_init, bool received_money) { // Key image sync after the first refresh - if (!m_wallet->get_account().get_device().has_tx_cold_sign()) { + if (!m_wallet->get_account().get_device().has_tx_cold_sign() || m_wallet->get_account().get_device().has_ki_live_refresh()) { return; } @@ -4750,8 +4750,16 @@ bool simple_wallet::refresh_main(uint64_t start_height, enum ResetType reset, bo LOCK_IDLE_SCOPE(); + crypto::hash transfer_hash_pre{}; + uint64_t height_pre, height_post; + if (reset != ResetNone) - m_wallet->rescan_blockchain(reset == ResetHard, false); + { + if (reset == ResetSoftKeepKI) + height_pre = m_wallet->hash_m_transfers(-1, transfer_hash_pre); + + m_wallet->rescan_blockchain(reset == ResetHard, false, reset == ResetSoftKeepKI); + } #ifdef HAVE_READLINE rdln::suspend_readline pause_readline; @@ -4768,6 +4776,18 @@ bool simple_wallet::refresh_main(uint64_t start_height, enum ResetType reset, bo m_in_manual_refresh.store(true, std::memory_order_relaxed); epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){m_in_manual_refresh.store(false, std::memory_order_relaxed);}); m_wallet->refresh(m_wallet->is_trusted_daemon(), start_height, fetched_blocks, received_money); + + if (reset == ResetSoftKeepKI) + { + m_wallet->finish_rescan_bc_keep_key_images(height_pre, transfer_hash_pre); + + height_post = m_wallet->get_num_transfer_details(); + if (height_pre != height_post) + { + message_writer() << tr("New transfer received since rescan was started. Key images are incomplete."); + } + } + ok = true; // Clear line "Height xxx of xxx" std::cout << "\r \r"; @@ -4963,7 +4983,7 @@ bool simple_wallet::show_incoming_transfers(const std::vector<std::string>& args std::vector<uint64_t> heights; for (const auto &e: td.m_uses) heights.push_back(e.first); const std::pair<std::string, std::string> line = show_outputs_line(heights, blockchain_height, td.m_spent_height); - extra_string += tr("Heights: ") + line.first + "\n" + line.second; + extra_string += std::string("\n ") + tr("Used at heights: ") + line.first + "\n " + line.second; } message_writer(td.m_spent ? console_color_magenta : console_color_green, false) << boost::format("%21s%8s%12s%8s%16u%68s%16u%s") % @@ -6754,7 +6774,7 @@ bool simple_wallet::get_tx_key(const std::vector<std::string> &args_) { std::vector<std::string> local_args = args_; - if (m_wallet->key_on_device()) + if (m_wallet->key_on_device() && m_wallet->get_account().get_device().get_type() != hw::device::TREZOR) { fail_msg_writer() << tr("command not supported by HW wallet"); return true; @@ -6775,7 +6795,9 @@ bool simple_wallet::get_tx_key(const std::vector<std::string> &args_) crypto::secret_key tx_key; std::vector<crypto::secret_key> additional_tx_keys; - if (m_wallet->get_tx_key(txid, tx_key, additional_tx_keys)) + + bool found_tx_key = m_wallet->get_tx_key(txid, tx_key, additional_tx_keys); + if (found_tx_key) { ostringstream oss; oss << epee::string_tools::pod_to_hex(tx_key); @@ -6851,7 +6873,7 @@ bool simple_wallet::set_tx_key(const std::vector<std::string> &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::get_tx_proof(const std::vector<std::string> &args) { - if (m_wallet->key_on_device()) + if (m_wallet->key_on_device() && m_wallet->get_account().get_device().get_type() != hw::device::TREZOR) { fail_msg_writer() << tr("command not supported by HW wallet"); return true; @@ -7775,18 +7797,43 @@ bool simple_wallet::unspent_outputs(const std::vector<std::string> &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::rescan_blockchain(const std::vector<std::string> &args_) { - bool hard = false; + uint64_t start_height = 0; + ResetType reset_type = ResetSoft; + if (!args_.empty()) { - if (args_[0] != "hard") + if (args_[0] == "hard") + { + reset_type = ResetHard; + } + else if (args_[0] == "soft") + { + reset_type = ResetSoft; + } + else if (args_[0] == "keep_ki") + { + reset_type = ResetSoftKeepKI; + } + else { PRINT_USAGE(USAGE_RESCAN_BC); return true; } - hard = true; + + if (args_.size() > 1) + { + try + { + start_height = boost::lexical_cast<uint64_t>( args_[1] ); + } + catch(const boost::bad_lexical_cast &) + { + start_height = 0; + } + } } - if (hard) + if (reset_type == ResetHard) { message_writer() << tr("Warning: this will lose any information which can not be recovered from the blockchain."); message_writer() << tr("This includes destination addresses, tx secret keys, tx notes, etc"); @@ -7797,7 +7844,20 @@ bool simple_wallet::rescan_blockchain(const std::vector<std::string> &args_) return true; } } - return refresh_main(0, hard ? ResetHard : ResetSoft, true); + + const uint64_t wallet_from_height = m_wallet->get_refresh_from_block_height(); + if (start_height > wallet_from_height) + { + message_writer() << tr("Warning: your restore height is higher than wallet restore height: ") << wallet_from_height; + std::string confirm = input_line(tr("Rescan anyway ? (Y/Yes/N/No): ")); + if(!std::cin.eof()) + { + if (!command_line::is_yes(confirm)) + return true; + } + } + + return refresh_main(start_height, reset_type, true); } //---------------------------------------------------------------------------------------------------- void simple_wallet::check_for_messages() @@ -8599,13 +8659,8 @@ bool simple_wallet::import_key_images(const std::vector<std::string> &args) { uint64_t spent = 0, unspent = 0; uint64_t height = m_wallet->import_key_images(filename, spent, unspent); - if (height > 0) - { - success_msg_writer() << "Signed key images imported to height " << height << ", " - << print_money(spent) << " spent, " << print_money(unspent) << " unspent"; - } else { - fail_msg_writer() << "Failed to import key images"; - } + success_msg_writer() << "Signed key images imported to height " << height << ", " + << print_money(spent) << " spent, " << print_money(unspent) << " unspent"; } catch (const std::exception &e) { @@ -9956,6 +10011,16 @@ bool simple_wallet::mms(const std::vector<std::string> &args) { try { + m_wallet->get_multisig_wallet_state(); + } + catch(const std::exception &e) + { + fail_msg_writer() << tr("MMS not available in this wallet"); + return true; + } + + try + { mms::message_store& ms = m_wallet->get_message_store(); if (args.size() == 0) { |