aboutsummaryrefslogtreecommitdiff
path: root/src/simplewallet/simplewallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/simplewallet/simplewallet.cpp')
-rw-r--r--src/simplewallet/simplewallet.cpp543
1 files changed, 173 insertions, 370 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index ca99edeb3..19a0614ec 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -125,6 +125,37 @@ namespace
const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""};
+ std::string input_line(const std::string& prompt)
+ {
+#ifdef HAVE_READLINE
+ rdln::suspend_readline pause_readline;
+#endif
+ std::cout << prompt;
+
+ std::string buf;
+ std::getline(std::cin, buf);
+
+ return epee::string_tools::trim(buf);
+ }
+
+ boost::optional<tools::password_container> password_prompter(const char *prompt, bool verify)
+ {
+#ifdef HAVE_READLINE
+ rdln::suspend_readline pause_readline;
+#endif
+ auto pwd_container = tools::password_container::prompt(verify, prompt);
+ if (!pwd_container)
+ {
+ tools::fail_msg_writer() << tr("failed to read wallet password");
+ }
+ return pwd_container;
+ }
+
+ boost::optional<tools::password_container> default_password_prompter(bool verify)
+ {
+ return password_prompter(verify ? tr("Enter new wallet password") : tr("Wallet password"), verify);
+ }
+
inline std::string interpret_rpc_response(bool ok, const std::string& status)
{
std::string err;
@@ -270,7 +301,7 @@ namespace
<< tr("Is this OK? (Y/n) ")
;
// prompt the user for confirmation given the dns query and dnssec status
- std::string confirm_dns_ok = command_line::input_line(prompt.str());
+ std::string confirm_dns_ok = input_line(prompt.str());
if (std::cin.eof())
{
return {};
@@ -448,7 +479,7 @@ bool simple_wallet::change_password(const std::vector<std::string> &args)
}
// prompts for a new password, pass true to verify the password
- const auto pwd_container = tools::wallet2::password_prompt(true);
+ const auto pwd_container = default_password_prompter(true);
try
{
@@ -1020,7 +1051,7 @@ bool simple_wallet::ask_wallet_create_if_needed()
do{
LOG_PRINT_L3("User asked to specify wallet file name.");
- wallet_path = command_line::input_line(
+ wallet_path = input_line(
tr(m_restoring ? "Specify a new wallet file name for your restored wallet (e.g., MyWallet).\n"
"Wallet file name (or Ctrl-C to quit): " :
"Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created.\n"
@@ -1071,7 +1102,7 @@ bool simple_wallet::ask_wallet_create_if_needed()
if (!m_restoring)
{
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): "));
+ confirm_creation = 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()");
@@ -1155,7 +1186,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
do
{
const char *prompt = m_electrum_seed.empty() ? "Specify Electrum seed: " : "Electrum seed continued: ";
- std::string electrum_seed = command_line::input_line(prompt);
+ std::string electrum_seed = input_line(prompt);
if (std::cin.eof())
return false;
if (electrum_seed.empty())
@@ -1184,7 +1215,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
{
m_wallet_file = m_generate_from_view_key;
// parse address
- std::string address_string = command_line::input_line("Standard address: ");
+ std::string address_string = input_line("Standard address: ");
if (std::cin.eof())
return false;
if (address_string.empty()) {
@@ -1204,7 +1235,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
}
// parse view secret key
- std::string viewkey_string = command_line::input_line("View key: ");
+ std::string viewkey_string = input_line("View key: ");
if (std::cin.eof())
return false;
if (viewkey_string.empty()) {
@@ -1258,7 +1289,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
{
m_wallet_file = m_generate_from_keys;
// parse address
- std::string address_string = command_line::input_line("Standard address: ");
+ std::string address_string = input_line("Standard address: ");
if (std::cin.eof())
return false;
if (address_string.empty()) {
@@ -1278,7 +1309,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
}
// parse spend secret key
- std::string spendkey_string = command_line::input_line("Secret spend key: ");
+ std::string spendkey_string = input_line("Secret spend key: ");
if (std::cin.eof())
return false;
if (spendkey_string.empty()) {
@@ -1294,7 +1325,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("Secret view key: ");
+ std::string viewkey_string = input_line("Secret view key: ");
if (std::cin.eof())
return false;
if (viewkey_string.empty()) {
@@ -1341,7 +1372,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
unsigned int multisig_n;
// parse multisig type
- std::string multisig_type_string = command_line::input_line("Multisig type (input as M/N with M <= N and M > 1): ");
+ std::string multisig_type_string = input_line("Multisig type (input as M/N with M <= N and M > 1): ");
if (std::cin.eof())
return false;
if (multisig_type_string.empty())
@@ -1367,7 +1398,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
message_writer() << boost::format(tr("Generating master wallet from %u of %u multisig wallet keys")) % multisig_m % multisig_n;
// parse multisig address
- std::string address_string = command_line::input_line("Multisig wallet address: ");
+ std::string address_string = input_line("Multisig wallet address: ");
if (std::cin.eof())
return false;
if (address_string.empty()) {
@@ -1382,7 +1413,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
}
// parse secret view key
- std::string viewkey_string = command_line::input_line("Secret view key: ");
+ std::string viewkey_string = input_line("Secret view key: ");
if (std::cin.eof())
return false;
if (viewkey_string.empty())
@@ -1422,7 +1453,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
// get N secret spend keys from user
for(unsigned int i=0; i<multisig_n; ++i)
{
- spendkey_string = command_line::input_line(tr((boost::format(tr("Secret spend key (%u of %u):")) % (i+i) % multisig_m).str().c_str()));
+ spendkey_string = input_line(tr((boost::format(tr("Secret spend key (%u of %u):")) % (i+i) % multisig_m).str().c_str()));
if (std::cin.eof())
return false;
if (spendkey_string.empty())
@@ -1470,7 +1501,15 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
else if (!m_generate_from_json.empty())
{
m_wallet_file = m_generate_from_json;
- m_wallet = tools::wallet2::make_from_json(vm, m_wallet_file);
+ try
+ {
+ m_wallet = tools::wallet2::make_from_json(vm, m_wallet_file, password_prompter);
+ }
+ catch (const std::exception &e)
+ {
+ fail_msg_writer() << e.what();
+ return false;
+ }
if (!m_wallet)
return false;
}
@@ -1492,9 +1531,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
{
std::string heightstr;
if (!connected || version < MAKE_CORE_RPC_VERSION(1, 6))
- heightstr = command_line::input_line("Restore from specific blockchain height (optional, default 0): ");
+ heightstr = input_line("Restore from specific blockchain height (optional, default 0): ");
else
- heightstr = command_line::input_line("Restore from specific blockchain height (optional, default 0),\nor alternatively from specific date (YYYY-MM-DD): ");
+ heightstr = input_line("Restore from specific blockchain height (optional, default 0),\nor alternatively from specific date (YYYY-MM-DD): ");
if (std::cin.eof())
return false;
if (heightstr.empty())
@@ -1530,7 +1569,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
day = boost::lexical_cast<uint16_t>(heightstr.substr(8,2));
m_restore_height = m_wallet->get_blockchain_height_by_date(year, month, day);
success_msg_writer() << tr("Restore height is: ") << m_restore_height;
- std::string confirm = command_line::input_line(tr("Is this okay? (Y/Yes/N/No): "));
+ std::string confirm = input_line(tr("Is this okay? (Y/Yes/N/No): "));
if (std::cin.eof())
return false;
if(command_line::is_yes(confirm))
@@ -1661,7 +1700,7 @@ std::string simple_wallet::get_mnemonic_language()
}
while (language_number < 0)
{
- language_choice = command_line::input_line(tr("Enter the number corresponding to the language of your choice: "));
+ language_choice = input_line(tr("Enter the number corresponding to the language of your choice: "));
if (std::cin.eof())
return std::string();
try
@@ -1683,7 +1722,7 @@ std::string simple_wallet::get_mnemonic_language()
//----------------------------------------------------------------------------------------------------
boost::optional<tools::password_container> simple_wallet::get_and_verify_password() const
{
- auto pwd_container = tools::wallet2::password_prompt(m_wallet_file.empty());
+ auto pwd_container = default_password_prompter(m_wallet_file.empty());
if (!pwd_container)
return boost::none;
@@ -1698,7 +1737,7 @@ boost::optional<tools::password_container> simple_wallet::get_and_verify_passwor
bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm,
const crypto::secret_key& recovery_key, bool recover, bool two_random, const std::string &old_language)
{
- auto rc = tools::wallet2::make_new(vm);
+ auto rc = tools::wallet2::make_new(vm, password_prompter);
m_wallet = std::move(rc.first);
if (!m_wallet)
{
@@ -1779,7 +1818,7 @@ bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm,
const cryptonote::account_public_address& address, const boost::optional<crypto::secret_key>& spendkey,
const crypto::secret_key& viewkey)
{
- auto rc = tools::wallet2::make_new(vm);
+ auto rc = tools::wallet2::make_new(vm, password_prompter);
m_wallet = std::move(rc.first);
if (!m_wallet)
{
@@ -1821,7 +1860,7 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
std::string password;
try
{
- auto rc = tools::wallet2::make_from_file(vm, m_wallet_file);
+ auto rc = tools::wallet2::make_from_file(vm, m_wallet_file, password_prompter);
m_wallet = std::move(rc.first);
password = std::move(rc.second).password();
if (!m_wallet)
@@ -2552,6 +2591,101 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending
return true;
}
//----------------------------------------------------------------------------------------------------
+static void handle_transfer_exception(const std::exception_ptr &e)
+{
+ try
+ {
+ std::rethrow_exception(e);
+ }
+ catch (const tools::error::daemon_busy&)
+ {
+ fail_msg_writer() << tr("daemon is busy. Please try again later.");
+ }
+ catch (const tools::error::no_connection_to_daemon&)
+ {
+ fail_msg_writer() << tr("no connection to daemon. Please make sure daemon is running.");
+ }
+ catch (const tools::error::wallet_rpc_error& e)
+ {
+ LOG_ERROR("RPC error: " << e.to_string());
+ fail_msg_writer() << tr("RPC error: ") << e.what();
+ }
+ catch (const tools::error::get_random_outs_error &e)
+ {
+ fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
+ }
+ catch (const tools::error::not_enough_unlocked_money& e)
+ {
+ LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
+ print_money(e.available()) %
+ print_money(e.tx_amount()));
+ fail_msg_writer() << tr("Not enough money in unlocked balance");
+ }
+ catch (const tools::error::not_enough_money& e)
+ {
+ LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
+ print_money(e.available()) %
+ print_money(e.tx_amount()));
+ fail_msg_writer() << tr("Not enough money in unlocked balance");
+ }
+ catch (const tools::error::tx_not_possible& e)
+ {
+ LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
+ print_money(e.available()) %
+ print_money(e.tx_amount() + e.fee()) %
+ print_money(e.tx_amount()) %
+ print_money(e.fee()));
+ fail_msg_writer() << tr("Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees");
+ }
+ catch (const tools::error::not_enough_outs_to_mix& e)
+ {
+ auto writer = fail_msg_writer();
+ writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":";
+ for (std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs())
+ {
+ writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second;
+ }
+ }
+ catch (const tools::error::tx_not_constructed&)
+ {
+ fail_msg_writer() << tr("transaction was not constructed");
+ }
+ catch (const tools::error::tx_rejected& e)
+ {
+ fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status();
+ std::string reason = e.reason();
+ if (!reason.empty())
+ fail_msg_writer() << tr("Reason: ") << reason;
+ }
+ catch (const tools::error::tx_sum_overflow& e)
+ {
+ fail_msg_writer() << e.what();
+ }
+ catch (const tools::error::zero_destination&)
+ {
+ fail_msg_writer() << tr("one of destinations is zero");
+ }
+ catch (const tools::error::tx_too_big& e)
+ {
+ fail_msg_writer() << tr("failed to find a suitable way to split transactions");
+ }
+ catch (const tools::error::transfer_error& e)
+ {
+ LOG_ERROR("unknown transfer error: " << e.to_string());
+ fail_msg_writer() << tr("unknown transfer error: ") << e.what();
+ }
+ catch (const tools::error::wallet_internal_error& e)
+ {
+ LOG_ERROR("internal error: " << e.to_string());
+ fail_msg_writer() << tr("internal error: ") << e.what();
+ }
+ catch (const std::exception& e)
+ {
+ LOG_ERROR("unexpected error: " << e.what());
+ fail_msg_writer() << tr("unexpected error: ") << e.what();
+ }
+}
+//----------------------------------------------------------------------------------------------------
bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::string> &args_)
{
// "transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]"
@@ -2711,7 +2845,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
// prompt is there is no payment id and confirmation is required
if (!payment_id_seen && m_wallet->confirm_missing_payment_id())
{
- std::string accepted = command_line::input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): "));
+ std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): "));
if (std::cin.eof())
return true;
if (!command_line::is_yes(accepted))
@@ -2795,7 +2929,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
std::string prompt_str = prompt.str();
if (!prompt_str.empty())
{
- std::string accepted = command_line::input_line(prompt_str);
+ std::string accepted = input_line(prompt_str);
if (std::cin.eof())
return true;
if (!command_line::is_yes(accepted))
@@ -2866,7 +3000,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
}
prompt << ENDL << tr("Is this okay? (Y/Yes/N/No): ");
- std::string accepted = command_line::input_line(prompt.str());
+ std::string accepted = input_line(prompt.str());
if (std::cin.eof())
return true;
if (!command_line::is_yes(accepted))
@@ -2895,92 +3029,9 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
commit_or_save(ptx_vector, m_do_not_relay);
}
}
- catch (const tools::error::daemon_busy&)
- {
- fail_msg_writer() << tr("daemon is busy. Please try again later.");
- }
- catch (const tools::error::no_connection_to_daemon&)
- {
- fail_msg_writer() << tr("no connection to daemon. Please make sure daemon is running.");
- }
- catch (const tools::error::wallet_rpc_error& e)
- {
- LOG_ERROR("RPC error: " << e.to_string());
- fail_msg_writer() << tr("RPC error: ") << e.what();
- }
- catch (const tools::error::get_random_outs_error &e)
- {
- fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
- }
- catch (const tools::error::not_enough_unlocked_money& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
- print_money(e.available()) %
- print_money(e.tx_amount()));
- fail_msg_writer() << tr("Not enough money in unlocked balance");
- }
- catch (const tools::error::not_enough_money& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") %
- print_money(e.available()) %
- print_money(e.tx_amount()));
- fail_msg_writer() << tr("Not enough money in overall balance");
- }
- catch (const tools::error::tx_not_possible& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
- print_money(e.available()) %
- print_money(e.tx_amount() + e.fee()) %
- print_money(e.tx_amount()) %
- print_money(e.fee()));
- fail_msg_writer() << tr("Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees");
- }
- catch (const tools::error::not_enough_outs_to_mix& e)
- {
- auto writer = fail_msg_writer();
- writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":";
- for (std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs())
- {
- writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second;
- }
- }
- catch (const tools::error::tx_not_constructed&)
- {
- fail_msg_writer() << tr("transaction was not constructed");
- }
- catch (const tools::error::tx_rejected& e)
- {
- fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status();
- std::string reason = e.reason();
- if (!reason.empty())
- fail_msg_writer() << tr("Reason: ") << reason;
- }
- catch (const tools::error::tx_sum_overflow& e)
- {
- fail_msg_writer() << e.what();
- }
- catch (const tools::error::zero_destination&)
- {
- fail_msg_writer() << tr("one of destinations is zero");
- }
- catch (const tools::error::tx_too_big& e)
- {
- fail_msg_writer() << tr("failed to find a suitable way to split transactions");
- }
- catch (const tools::error::transfer_error& e)
- {
- LOG_ERROR("unknown transfer error: " << e.to_string());
- fail_msg_writer() << tr("unknown transfer error: ") << e.what();
- }
- catch (const tools::error::wallet_internal_error& e)
- {
- LOG_ERROR("internal error: " << e.to_string());
- fail_msg_writer() << tr("internal error: ") << e.what();
- }
- catch (const std::exception& e)
+ catch (const std::exception &e)
{
- LOG_ERROR("unexpected error: " << e.what());
- fail_msg_writer() << tr("unexpected error: ") << e.what();
+ handle_transfer_exception(std::current_exception());
}
catch (...)
{
@@ -3046,7 +3097,7 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
print_money(total_unmixable) %
print_money(total_fee)).str();
}
- std::string accepted = command_line::input_line(prompt_str);
+ std::string accepted = input_line(prompt_str);
if (std::cin.eof())
return true;
if (!command_line::is_yes(accepted))
@@ -3074,92 +3125,9 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
commit_or_save(ptx_vector, m_do_not_relay);
}
}
- catch (const tools::error::daemon_busy&)
- {
- fail_msg_writer() << tr("daemon is busy. Please try again later.");
- }
- catch (const tools::error::no_connection_to_daemon&)
- {
- fail_msg_writer() << tr("no connection to daemon. Please make sure daemon is running.");
- }
- catch (const tools::error::wallet_rpc_error& e)
- {
- LOG_ERROR("RPC error: " << e.to_string());
- fail_msg_writer() << tr("RPC error: ") << e.what();
- }
- catch (const tools::error::get_random_outs_error &e)
- {
- fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
- }
- catch (const tools::error::not_enough_unlocked_money& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
- print_money(e.available()) %
- print_money(e.tx_amount()));
- fail_msg_writer() << tr("Not enough money in unlocked balance");
- }
- catch (const tools::error::not_enough_money& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") %
- print_money(e.available()) %
- print_money(e.tx_amount()));
- fail_msg_writer() << tr("Not enough money in overall balance");
- }
- catch (const tools::error::tx_not_possible& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
- print_money(e.available()) %
- print_money(e.tx_amount() + e.fee()) %
- print_money(e.tx_amount()) %
- print_money(e.fee()));
- fail_msg_writer() << tr("Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees");
- }
- catch (const tools::error::not_enough_outs_to_mix& e)
- {
- auto writer = fail_msg_writer();
- writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":";
- for (std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs())
- {
- writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second;
- }
- }
- catch (const tools::error::tx_not_constructed&)
- {
- fail_msg_writer() << tr("transaction was not constructed");
- }
- catch (const tools::error::tx_rejected& e)
- {
- fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status();
- std::string reason = e.reason();
- if (!reason.empty())
- fail_msg_writer() << tr("Reason: ") << reason;
- }
- catch (const tools::error::tx_sum_overflow& e)
- {
- fail_msg_writer() << e.what();
- }
- catch (const tools::error::zero_destination&)
- {
- fail_msg_writer() << tr("one of destinations is zero");
- }
- catch (const tools::error::tx_too_big& e)
- {
- fail_msg_writer() << tr("failed to find a suitable way to split transactions");
- }
- catch (const tools::error::transfer_error& e)
- {
- LOG_ERROR("unknown transfer error: " << e.to_string());
- fail_msg_writer() << tr("unknown transfer error: ") << e.what();
- }
- catch (const tools::error::wallet_internal_error& e)
- {
- LOG_ERROR("internal error: " << e.to_string());
- fail_msg_writer() << tr("internal error: ") << e.what();
- }
- catch (const std::exception& e)
+ catch (const std::exception &e)
{
- LOG_ERROR("unexpected error: " << e.what());
- fail_msg_writer() << tr("unexpected error: ") << e.what();
+ handle_transfer_exception(std::current_exception());
}
catch (...)
{
@@ -3290,7 +3258,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a
// prompt is there is no payment id and confirmation is required
if (!payment_id_seen && m_wallet->confirm_missing_payment_id())
{
- std::string accepted = command_line::input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): "));
+ std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): "));
if (std::cin.eof())
return true;
if (!command_line::is_yes(accepted))
@@ -3348,7 +3316,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a
print_money(total_sent) %
print_money(total_fee);
}
- std::string accepted = command_line::input_line(prompt.str());
+ std::string accepted = input_line(prompt.str());
if (std::cin.eof())
return true;
if (!command_line::is_yes(accepted))
@@ -3376,92 +3344,9 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a
commit_or_save(ptx_vector, m_do_not_relay);
}
}
- catch (const tools::error::daemon_busy&)
- {
- fail_msg_writer() << tr("daemon is busy. Please try again later.");
- }
- catch (const tools::error::no_connection_to_daemon&)
- {
- fail_msg_writer() << tr("no connection to daemon. Please make sure daemon is running.");
- }
- catch (const tools::error::wallet_rpc_error& e)
- {
- LOG_ERROR("RPC error: " << e.to_string());
- fail_msg_writer() << tr("RPC error: ") << e.what();
- }
- catch (const tools::error::get_random_outs_error &e)
- {
- fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
- }
- catch (const tools::error::not_enough_unlocked_money& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
- print_money(e.available()) %
- print_money(e.tx_amount()));
- fail_msg_writer() << tr("Not enough money in unlocked balance");
- }
- catch (const tools::error::not_enough_money& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") %
- print_money(e.available()) %
- print_money(e.tx_amount()));
- fail_msg_writer() << tr("Not enough money in overall balance");
- }
- catch (const tools::error::tx_not_possible& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
- print_money(e.available()) %
- print_money(e.tx_amount() + e.fee()) %
- print_money(e.tx_amount()) %
- print_money(e.fee()));
- fail_msg_writer() << tr("Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees");
- }
- catch (const tools::error::not_enough_outs_to_mix& e)
- {
- auto writer = fail_msg_writer();
- writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":";
- for (std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs())
- {
- writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second;
- }
- }
- catch (const tools::error::tx_not_constructed&)
- {
- fail_msg_writer() << tr("transaction was not constructed");
- }
- catch (const tools::error::tx_rejected& e)
- {
- fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status();
- std::string reason = e.reason();
- if (!reason.empty())
- fail_msg_writer() << tr("Reason: ") << reason;
- }
- catch (const tools::error::tx_sum_overflow& e)
- {
- fail_msg_writer() << e.what();
- }
- catch (const tools::error::zero_destination&)
- {
- fail_msg_writer() << tr("one of destinations is zero");
- }
- catch (const tools::error::tx_too_big& e)
- {
- fail_msg_writer() << tr("failed to find a suitable way to split transactions");
- }
- catch (const tools::error::transfer_error& e)
- {
- LOG_ERROR("unknown transfer error: " << e.to_string());
- fail_msg_writer() << tr("unknown transfer error: ") << e.what();
- }
- catch (const tools::error::wallet_internal_error& e)
- {
- LOG_ERROR("internal error: " << e.to_string());
- fail_msg_writer() << tr("internal error: ") << e.what();
- }
catch (const std::exception& e)
{
- LOG_ERROR("unexpected error: " << e.what());
- fail_msg_writer() << tr("unexpected error: ") << e.what();
+ handle_transfer_exception(std::current_exception());
}
catch (...)
{
@@ -3644,7 +3529,7 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes,
uint64_t fee = amount - amount_to_dests;
std::string prompt_str = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): ")) % (unsigned long)get_num_txes() % print_money(amount) % print_money(fee) % dest_string % change_string % (unsigned long)min_ring_size % payment_id_string % extra_message).str();
- return command_line::is_yes(command_line::input_line(prompt_str));
+ return command_line::is_yes(input_line(prompt_str));
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs)
@@ -3733,92 +3618,9 @@ bool simple_wallet::submit_transfer(const std::vector<std::string> &args_)
commit_or_save(ptx_vector, false);
}
- catch (const tools::error::daemon_busy&)
- {
- fail_msg_writer() << tr("daemon is busy. Please try later");
- }
- catch (const tools::error::no_connection_to_daemon&)
- {
- fail_msg_writer() << tr("no connection to daemon. Please, make sure daemon is running.");
- }
- catch (const tools::error::wallet_rpc_error& e)
- {
- LOG_ERROR("Unknown RPC error: " << e.to_string());
- fail_msg_writer() << tr("RPC error: ") << e.what();
- }
- catch (const tools::error::get_random_outs_error &e)
- {
- fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
- }
- catch (const tools::error::not_enough_unlocked_money& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
- print_money(e.available()) %
- print_money(e.tx_amount()));
- fail_msg_writer() << tr("Not enough money in unlocked balance");
- }
- catch (const tools::error::not_enough_money& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") %
- print_money(e.available()) %
- print_money(e.tx_amount()));
- fail_msg_writer() << tr("Not enough money in overall balance");
- }
- catch (const tools::error::tx_not_possible& e)
- {
- LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
- print_money(e.available()) %
- print_money(e.tx_amount() + e.fee()) %
- print_money(e.tx_amount()) %
- print_money(e.fee()));
- fail_msg_writer() << tr("Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees");
- }
- catch (const tools::error::not_enough_outs_to_mix& e)
- {
- auto writer = fail_msg_writer();
- writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":";
- for (std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs())
- {
- writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second;
- }
- }
- catch (const tools::error::tx_not_constructed&)
- {
- fail_msg_writer() << tr("transaction was not constructed");
- }
- catch (const tools::error::tx_rejected& e)
- {
- fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status();
- std::string reason = e.reason();
- if (!reason.empty())
- fail_msg_writer() << tr("Reason: ") << reason;
- }
- catch (const tools::error::tx_sum_overflow& e)
- {
- fail_msg_writer() << e.what();
- }
- catch (const tools::error::zero_destination&)
- {
- fail_msg_writer() << tr("one of destinations is zero");
- }
- catch (const tools::error::tx_too_big& e)
- {
- fail_msg_writer() << tr("Failed to find a suitable way to split transactions");
- }
- catch (const tools::error::transfer_error& e)
- {
- LOG_ERROR("unknown transfer error: " << e.to_string());
- fail_msg_writer() << tr("unknown transfer error: ") << e.what();
- }
- catch (const tools::error::wallet_internal_error& e)
- {
- LOG_ERROR("internal error: " << e.to_string());
- fail_msg_writer() << tr("internal error: ") << e.what();
- }
catch (const std::exception& e)
{
- LOG_ERROR("unexpected error: " << e.what());
- fail_msg_writer() << tr("unexpected error: ") << e.what();
+ handle_transfer_exception(std::current_exception());
}
catch (...)
{
@@ -4287,7 +4089,7 @@ bool simple_wallet::check_tx_proof(const std::vector<std::string> &args)
return true;
}
crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
- if (tx_pub_key == null_pkey)
+ if (tx_pub_key == crypto::null_pkey)
{
fail_msg_writer() << tr("Tx pubkey was not found");
return true;
@@ -5015,7 +4817,7 @@ bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::v
fail_msg_writer() << tr("failed to parse address");
return true;
}
- crypto::hash payment_id = null_hash;
+ crypto::hash payment_id = crypto::null_hash;
size_t description_start = 2;
if (info.has_payment_id)
{
@@ -5671,6 +5473,7 @@ int main(int argc, char* argv[])
"monero-wallet-cli [--wallet-file=<file>|--generate-new-wallet=<file>] [<COMMAND>]",
desc_params,
positional_options,
+ [](const std::string &s, bool emphasis){ tools::scoped_message_writer(emphasis ? epee::console_color_white : epee::console_color_default, true) << s; },
"monero-wallet-cli.log"
);