diff options
Diffstat (limited to 'src/simplewallet')
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 166 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.h | 1 |
2 files changed, 77 insertions, 90 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 30cfe3ab2..1811eeb3c 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -48,6 +48,7 @@ #include "common/util.h" #include "common/dns_utils.h" #include "common/base58.h" +#include "common/scoped_message_writer.h" #include "p2p/net_node.h" #include "cryptonote_protocol/cryptonote_protocol_handler.h" #include "simplewallet.h" @@ -62,14 +63,6 @@ #include "wallet/wallet_args.h" #include <stdexcept> -#ifdef HAVE_READLINE - #include "readline_buffer.h" - #define PAUSE_READLINE() \ - rdln::suspend_readline pause_readline; -#else - #define PAUSE_READLINE() -#endif - using namespace std; using namespace epee; using namespace cryptonote; @@ -148,84 +141,19 @@ namespace return err; } - class message_writer + tools::scoped_message_writer success_msg_writer(bool color = false) { - public: - message_writer(console_colors color = console_color_default, bool bright = false, - std::string&& prefix = std::string(), el::Level log_level = el::Level::Info) - : m_flush(true) - , m_color(color) - , m_bright(bright) - , m_log_level(log_level) - { - m_oss << prefix; - } - - message_writer(message_writer&& rhs) - : m_flush(std::move(rhs.m_flush)) -#if defined(_MSC_VER) - , m_oss(std::move(rhs.m_oss)) -#else - // GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316 - , m_oss(rhs.m_oss.str(), ios_base::out | ios_base::ate) -#endif - , m_color(std::move(rhs.m_color)) - , m_log_level(std::move(rhs.m_log_level)) - { - rhs.m_flush = false; - } - - template<typename T> - std::ostream& operator<<(const T& val) - { - m_oss << val; - return m_oss; - } - - ~message_writer() - { - if (m_flush) - { - m_flush = false; - - MCLOG(m_log_level, "global", m_oss.str()); - - if (console_color_default == m_color) - { - std::cout << m_oss.str(); - } - else - { - PAUSE_READLINE(); - set_console_color(m_color, m_bright); - std::cout << m_oss.str(); - reset_console_color(); - } - std::cout << std::endl; - } - } - - private: - message_writer(message_writer& rhs); - message_writer& operator=(message_writer& rhs); - message_writer& operator=(message_writer&& rhs); - - private: - bool m_flush; - std::stringstream m_oss; - console_colors m_color; - bool m_bright; - el::Level m_log_level; - }; + return tools::scoped_message_writer(color ? console_color_green : console_color_default, false, std::string(), el::Level::Info); + } - message_writer success_msg_writer(bool color = false) + tools::scoped_message_writer message_writer(epee::console_colors color = epee::console_color_default, bool bright = false) { - return message_writer(color ? console_color_green : console_color_default, false, std::string(), el::Level::Info); + return tools::scoped_message_writer(color, bright); } - message_writer fail_msg_writer() + tools::scoped_message_writer fail_msg_writer() { - return message_writer(console_color_red, true, sw::tr("Error: "), el::Level::Error); + return tools::scoped_message_writer(console_color_red, true, sw::tr("Error: "), el::Level::Error); } bool is_it_true(const std::string& s) @@ -920,14 +848,19 @@ bool simple_wallet::ask_wallet_create_if_needed() } else if(!wallet_file_exists && !keys_file_exists) //No wallet, no keys { - message_writer() << tr(m_restoring ? "Confirm wallet name: " : "No wallet found with that name. Confirm creation of new wallet named: ") << wallet_path; - confirm_creation = command_line::input_line(tr("(Y/Yes/N/No): ")); - if(std::cin.eof()) + bool ok = true; + if (!m_restoring) { - LOG_ERROR("Unexpected std::cin.eof() - Exited simple_wallet::ask_wallet_create_if_needed()"); - return false; + message_writer() << tr("No wallet found with that name. Confirm creation of new wallet named: ") << wallet_path; + confirm_creation = command_line::input_line(tr("(Y/Yes/N/No): ")); + if(std::cin.eof()) + { + LOG_ERROR("Unexpected std::cin.eof() - Exited simple_wallet::ask_wallet_create_if_needed()"); + return false; + } + ok = command_line::is_yes(confirm_creation); } - if(command_line::is_yes(confirm_creation)) + if (ok) { success_msg_writer() << tr("Generating new wallet..."); m_generate_new = wallet_path; @@ -1094,7 +1027,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } // parse spend secret key - std::string spendkey_string = command_line::input_line("Spend key: "); + std::string spendkey_string = command_line::input_line("Secret spend key: "); if (std::cin.eof()) return false; if (spendkey_string.empty()) { @@ -1110,7 +1043,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) crypto::secret_key spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data()); // parse view secret key - std::string viewkey_string = command_line::input_line("View key: "); + std::string viewkey_string = command_line::input_line("Secret view key: "); if (std::cin.eof()) return false; if (viewkey_string.empty()) { @@ -3878,6 +3811,22 @@ static std::string get_human_readable_timestamp(uint64_t ts) return std::string(buffer); } //---------------------------------------------------------------------------------------------------- +static std::string get_human_readable_timespan(std::chrono::seconds seconds) +{ + uint64_t ts = seconds.count(); + if (ts < 60) + return std::to_string(ts) + tr(" seconds"); + if (ts < 3600) + return std::to_string((uint64_t)(ts / 60)) + tr(" minutes"); + if (ts < 3600 * 24) + return std::to_string((uint64_t)(ts / 3600)) + tr(" hours"); + if (ts < 3600 * 24 * 30.5) + return std::to_string((uint64_t)(ts / (3600 * 24))) + tr(" days"); + if (ts < 3600 * 24 * 365.25) + return std::to_string((uint64_t)(ts / (3600 * 24 * 365.25))) + tr(" months"); + return tr("a long time"); +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::show_transfers(const std::vector<std::string> &args_) { std::vector<std::string> local_args = args_; @@ -4186,6 +4135,19 @@ void simple_wallet::wallet_idle_thread() } } //---------------------------------------------------------------------------------------------------- +std::string simple_wallet::get_prompt() const +{ + std::string addr_start = m_wallet->get_account().get_public_address_str(m_wallet->testnet()).substr(0, 6); + std::string prompt = std::string("[") + tr("wallet") + " " + addr_start; + uint32_t version; + if (!m_wallet->check_connection(&version)) + prompt += tr(" (no daemon)"); + else if (!m_wallet->is_synced()) + prompt += tr(" (out of sync)"); + prompt += "]: "; + return prompt; +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::run() { // check and display warning, but go on anyway @@ -4196,9 +4158,8 @@ bool simple_wallet::run() m_auto_refresh_enabled = m_wallet->auto_refresh(); m_idle_thread = boost::thread([&]{wallet_idle_thread();}); - std::string addr_start = m_wallet->get_account().get_public_address_str(m_wallet->testnet()).substr(0, 6); message_writer(console_color_green, false) << "Background refresh thread started"; - return m_cmd_binder.run_handling(std::string("[") + tr("wallet") + " " + addr_start + "]: ", ""); + return m_cmd_binder.run_handling([this](){return get_prompt();}, ""); } //---------------------------------------------------------------------------------------------------- void simple_wallet::stop() @@ -4520,6 +4481,12 @@ bool simple_wallet::export_key_images(const std::vector<std::string> &args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::import_key_images(const std::vector<std::string> &args) { + if (!m_trusted_daemon) + { + fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon"); + return true; + } + if (args.size() != 1) { fail_msg_writer() << tr("usage: import_key_images <filename>"); @@ -4684,6 +4651,8 @@ bool simple_wallet::show_transfer(const std::vector<std::string> &args) } crypto::hash txid = *reinterpret_cast<const crypto::hash*>(txid_data.data()); + const uint64_t last_block_height = m_wallet->get_blockchain_current_height(); + std::list<std::pair<crypto::hash, tools::wallet2::payment_details>> payments; m_wallet->get_payments(payments, 0); for (std::list<std::pair<crypto::hash, tools::wallet2::payment_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) { @@ -4698,6 +4667,23 @@ bool simple_wallet::show_transfer(const std::vector<std::string> &args) success_msg_writer() << "Timestamp: " << get_human_readable_timestamp(pd.m_timestamp); success_msg_writer() << "Amount: " << print_money(pd.m_amount); success_msg_writer() << "Payment ID: " << payment_id; + if (pd.m_unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER) + { + uint64_t bh = std::max(pd.m_unlock_time, pd.m_block_height + CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE); + if (bh >= last_block_height) + success_msg_writer() << "Locked: " << (bh - last_block_height) << " blocks to unlock"; + else + success_msg_writer() << std::to_string(last_block_height - bh) << " confirmations"; + } + else + { + uint64_t current_time = static_cast<uint64_t>(time(NULL)); + uint64_t threshold = current_time + (m_wallet->use_fork_rules(2, 0) ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1); + if (threshold >= pd.m_unlock_time) + success_msg_writer() << "unlocked for " << get_human_readable_timespan(std::chrono::seconds(threshold - pd.m_unlock_time)); + else + success_msg_writer() << "locked for " << get_human_readable_timespan(std::chrono::seconds(pd.m_unlock_time - threshold)); + } success_msg_writer() << "Note: " << m_wallet->get_tx_note(txid); return true; } diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 3cfe08082..8022c9bb2 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -182,6 +182,7 @@ namespace cryptonote bool accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs); bool accept_loaded_tx(const tools::wallet2::signed_tx_set &txs); bool print_ring_members(const std::vector<tools::wallet2::pending_tx>& ptx_vector, std::ostream& ostr); + std::string get_prompt() const; /*! * \brief Prints the seed with a nice message |