aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2017-11-14 21:31:50 +0200
committerRiccardo Spagni <ric@spagni.net>2017-11-14 21:31:51 +0200
commitedebe4e3b603fc391c698bf4d291336ba9376665 (patch)
tree53d687f5767f456284607ffa8e2808b251f2d7a0 /src/wallet
parentMerge pull request #2644 (diff)
parentDo not build against epee_readline if it was not built (diff)
downloadmonero-edebe4e3b603fc391c698bf4d291336ba9376665.tar.xz
Merge pull request #2736
0d9c0db9 Do not build against epee_readline if it was not built (Howard Chu) 178014c9 split off readline code into epee_readline (moneromooo-monero) a9e14a19 link against readline only for monerod and wallet-wallet-{rpc,cli} (moneromooo-monero) 437421ce wallet: move some scoped_message_writer calls from the libs (moneromooo-monero) e89994e9 wallet: rejig to avoid prompting in wallet2 (moneromooo-monero) ec5135e5 move input_line from command_line to simplewallet (moneromooo-monero) 082db75f move cryptonote command line options to cryptonote_core (moneromooo-monero)
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/CMakeLists.txt1
-rw-r--r--src/wallet/wallet2.cpp155
-rw-r--r--src/wallet/wallet2.h11
-rw-r--r--src/wallet/wallet_args.cpp33
-rw-r--r--src/wallet/wallet_args.h1
-rw-r--r--src/wallet/wallet_errors.h6
-rw-r--r--src/wallet/wallet_rpc_server.cpp30
7 files changed, 113 insertions, 124 deletions
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
index 4c00a4d51..7e061f480 100644
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
@@ -108,6 +108,7 @@ if (NOT BUILD_GUI_DEPS)
PRIVATE
wallet
epee
+ ${EPEE_READLINE}
rpc
cryptonote_core
cncrypto
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 50d07536c..9ed8e7cc3 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -137,7 +137,7 @@ uint64_t calculate_fee(uint64_t fee_per_kb, const cryptonote::blobdata &blob, ui
return calculate_fee(fee_per_kb, blob.size(), fee_multiplier);
}
-std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variables_map& vm, const options& opts)
+std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variables_map& vm, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
{
const bool testnet = command_line::get_arg(vm, opts.testnet);
const bool restricted = command_line::get_arg(vm, opts.restricted);
@@ -146,17 +146,16 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
auto daemon_host = command_line::get_arg(vm, opts.daemon_host);
auto daemon_port = command_line::get_arg(vm, opts.daemon_port);
- if (!daemon_address.empty() && !daemon_host.empty() && 0 != daemon_port)
- {
- tools::fail_msg_writer() << tools::wallet2::tr("can't specify daemon host or port more than once");
- return nullptr;
- }
+ THROW_WALLET_EXCEPTION_IF(!daemon_address.empty() && !daemon_host.empty() && 0 != daemon_port,
+ tools::error::wallet_internal_error, tools::wallet2::tr("can't specify daemon host or port more than once"));
boost::optional<epee::net_utils::http::login> login{};
if (command_line::has_arg(vm, opts.daemon_login))
{
auto parsed = tools::login::parse(
- command_line::get_arg(vm, opts.daemon_login), false, "Daemon client password"
+ command_line::get_arg(vm, opts.daemon_login), false, [password_prompter](bool verify) {
+ return password_prompter("Daemon client password", verify);
+ }
);
if (!parsed)
return nullptr;
@@ -180,12 +179,11 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
return wallet;
}
-boost::optional<tools::password_container> get_password(const boost::program_options::variables_map& vm, const options& opts, const bool verify)
+boost::optional<tools::password_container> get_password(const boost::program_options::variables_map& vm, const options& opts, const std::function<boost::optional<tools::password_container>(const char*, bool)> &password_prompter, const bool verify)
{
if (command_line::has_arg(vm, opts.password) && command_line::has_arg(vm, opts.password_file))
{
- tools::fail_msg_writer() << tools::wallet2::tr("can't specify more than one of --password and --password-file");
- return boost::none;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("can't specify more than one of --password and --password-file"));
}
if (command_line::has_arg(vm, opts.password))
@@ -198,21 +196,17 @@ boost::optional<tools::password_container> get_password(const boost::program_opt
std::string password;
bool r = epee::file_io_utils::load_file_to_string(command_line::get_arg(vm, opts.password_file),
password);
- if (!r)
- {
- tools::fail_msg_writer() << tools::wallet2::tr("the password file specified could not be read");
- return boost::none;
- }
+ THROW_WALLET_EXCEPTION_IF(!r, tools::error::wallet_internal_error, tools::wallet2::tr("the password file specified could not be read"));
// Remove line breaks the user might have inserted
boost::trim_right_if(password, boost::is_any_of("\r\n"));
return {tools::password_container{std::move(password)}};
}
- return tools::wallet2::password_prompt(verify);
+ return password_prompter(verify ? tr("Enter new wallet password") : tr("Wallet password"), verify);
}
-std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, const options& opts)
+std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
{
const bool testnet = command_line::get_arg(vm, opts.testnet);
@@ -223,22 +217,20 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
const auto do_generate = [&]() -> bool {
std::string buf;
if (!epee::file_io_utils::load_file_to_string(json_file, buf)) {
- tools::fail_msg_writer() << tools::wallet2::tr("Failed to load file ") << json_file;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("Failed to load file ")) + json_file);
return false;
}
rapidjson::Document json;
if (json.Parse(buf.c_str()).HasParseError()) {
- tools::fail_msg_writer() << tools::wallet2::tr("Failed to parse JSON");
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Failed to parse JSON"));
return false;
}
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, version, unsigned, Uint, true, 0);
const int current_version = 1;
- if (field_version > current_version) {
- tools::fail_msg_writer() << boost::format(tools::wallet2::tr("Version %u too new, we can only grok up to %u")) % field_version % current_version;
- return false;
- }
+ THROW_WALLET_EXCEPTION_IF(field_version > current_version, tools::error::wallet_internal_error,
+ ((boost::format(tools::wallet2::tr("Version %u too new, we can only grok up to %u")) % field_version % current_version)).str());
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, filename, std::string, String, true, std::string());
@@ -254,14 +246,12 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
cryptonote::blobdata viewkey_data;
if(!epee::string_tools::parse_hexstr_to_binbuff(field_viewkey, viewkey_data) || viewkey_data.size() != sizeof(crypto::secret_key))
{
- tools::fail_msg_writer() << tools::wallet2::tr("failed to parse view key secret key");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to parse view key secret key"));
}
viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data());
crypto::public_key pkey;
if (!crypto::secret_key_to_public_key(viewkey, pkey)) {
- tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify view key secret key"));
}
}
@@ -272,14 +262,12 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
cryptonote::blobdata spendkey_data;
if(!epee::string_tools::parse_hexstr_to_binbuff(field_spendkey, spendkey_data) || spendkey_data.size() != sizeof(crypto::secret_key))
{
- tools::fail_msg_writer() << tools::wallet2::tr("failed to parse spend key secret key");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to parse spend key secret key"));
}
spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data());
crypto::public_key pkey;
if (!crypto::secret_key_to_public_key(spendkey, pkey)) {
- tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key"));
}
}
@@ -291,8 +279,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
{
if (!crypto::ElectrumWords::words_to_bytes(field_seed, recovery_key, old_language))
{
- tools::fail_msg_writer() << tools::wallet2::tr("Electrum-style word list failed verification");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Electrum-style word list failed verification"));
}
restore_deterministic_wallet = true;
@@ -309,13 +296,11 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
// compatibility checks
if (!field_seed_found && !field_viewkey_found && !field_spendkey_found)
{
- tools::fail_msg_writer() << tools::wallet2::tr("At least one of Electrum-style word list and private view key and private spend key must be specified");
- return false;
+ THROW_WALLET_EXCEPTION(tools::wallet2::tr("At least one of Electrum-style word list and private view key and private spend key must be specified"));
}
if (field_seed_found && (field_viewkey_found || field_spendkey_found))
{
- tools::fail_msg_writer() << tools::wallet2::tr("Both Electrum-style word list and private key(s) specified");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Both Electrum-style word list and private key(s) specified"));
}
// if an address was given, we check keys against it, and deduce the spend
@@ -325,43 +310,36 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
cryptonote::address_parse_info info;
if(!get_account_address_from_str(info, testnet, field_address))
{
- tools::fail_msg_writer() << tools::wallet2::tr("invalid address");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("invalid address"));
}
if (field_viewkey_found)
{
crypto::public_key pkey;
if (!crypto::secret_key_to_public_key(viewkey, pkey)) {
- tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify view key secret key"));
}
if (info.address.m_view_public_key != pkey) {
- tools::fail_msg_writer() << tools::wallet2::tr("view key does not match standard address");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("view key does not match standard address"));
}
}
if (field_spendkey_found)
{
crypto::public_key pkey;
if (!crypto::secret_key_to_public_key(spendkey, pkey)) {
- tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key"));
}
if (info.address.m_spend_public_key != pkey) {
- tools::fail_msg_writer() << tools::wallet2::tr("spend key does not match standard address");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("spend key does not match standard address"));
}
}
}
const bool deprecated_wallet = restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) ||
crypto::ElectrumWords::get_is_old_style_seed(field_seed));
- if (deprecated_wallet) {
- tools::fail_msg_writer() << tools::wallet2::tr("Cannot create deprecated wallets from JSON");
- return false;
- }
+ THROW_WALLET_EXCEPTION_IF(deprecated_wallet, tools::error::wallet_internal_error,
+ tools::wallet2::tr("Cannot create deprecated wallets from JSON"));
- wallet.reset(make_basic(vm, opts).release());
+ wallet.reset(make_basic(vm, opts, password_prompter).release());
wallet->set_refresh_from_block_height(field_scan_from_height);
try
@@ -378,8 +356,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
{
cryptonote::account_public_address address;
if (!crypto::secret_key_to_public_key(viewkey, address.m_view_public_key)) {
- tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify view key secret key"));
}
if (field_spendkey.empty())
@@ -391,8 +368,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
cryptonote::address_parse_info info;
if(!get_account_address_from_str(info, testnet, field_address))
{
- tools::fail_msg_writer() << tools::wallet2::tr("failed to parse address: ") << field_address;
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("failed to parse address: ")) + field_address);
}
address.m_spend_public_key = info.address.m_spend_public_key;
}
@@ -406,8 +382,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
else
{
if (!crypto::secret_key_to_public_key(spendkey, address.m_spend_public_key)) {
- tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key");
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key"));
}
wallet->generate(field_filename, field_password, address, spendkey, viewkey);
}
@@ -415,8 +390,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
}
catch (const std::exception& e)
{
- tools::fail_msg_writer() << tools::wallet2::tr("failed to generate new wallet: ") << e.what();
- return false;
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("failed to generate new wallet: ")) + e.what());
}
return true;
};
@@ -498,34 +472,22 @@ void wallet2::init_options(boost::program_options::options_description& desc_par
command_line::add_arg(desc_params, opts.restricted);
}
-boost::optional<password_container> wallet2::password_prompt(const bool new_password)
-{
- auto pwd_container = tools::password_container::prompt(
- new_password, (new_password ? tr("Enter new wallet password") : tr("Wallet password"))
- );
- if (!pwd_container)
- {
- tools::fail_msg_writer() << tr("failed to read wallet password");
- }
- return pwd_container;
-}
-
-std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file)
+std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
{
const options opts{};
- return generate_from_json(json_file, vm, opts);
+ return generate_from_json(json_file, vm, opts, password_prompter);
}
std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_from_file(
- const boost::program_options::variables_map& vm, const std::string& wallet_file)
+ const boost::program_options::variables_map& vm, const std::string& wallet_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
{
const options opts{};
- auto pwd = get_password(vm, opts, false);
+ auto pwd = get_password(vm, opts, password_prompter, false);
if (!pwd)
{
return {nullptr, password_container{}};
}
- auto wallet = make_basic(vm, opts);
+ auto wallet = make_basic(vm, opts, password_prompter);
if (wallet)
{
wallet->load(wallet_file, pwd->password());
@@ -533,21 +495,21 @@ std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_from_file(
return {std::move(wallet), std::move(*pwd)};
}
-std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_new(const boost::program_options::variables_map& vm)
+std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_new(const boost::program_options::variables_map& vm, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter)
{
const options opts{};
- auto pwd = get_password(vm, opts, true);
+ auto pwd = get_password(vm, opts, password_prompter, true);
if (!pwd)
{
return {nullptr, password_container{}};
}
- return {make_basic(vm, opts), std::move(*pwd)};
+ return {make_basic(vm, opts, password_prompter), std::move(*pwd)};
}
-std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::variables_map& vm)
+std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::variables_map& vm, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
{
const options opts{};
- return make_basic(vm, opts);
+ return make_basic(vm, opts, password_prompter);
}
//----------------------------------------------------------------------------------------------------
@@ -6525,16 +6487,12 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent
std::string data;
bool r = epee::file_io_utils::load_file_to_string(filename, data);
- if (!r)
- {
- fail_msg_writer() << tr("failed to read file ") << filename;
- return 0;
- }
+ THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename);
+
const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC);
if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen))
{
- fail_msg_writer() << "Bad key image export file magic in " << filename;
- return 0;
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic in ") + filename);
}
try
@@ -6543,31 +6501,22 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent
}
catch (const std::exception &e)
{
- fail_msg_writer() << "Failed to decrypt " << filename << ": " << e.what();
- return 0;
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + filename + ": " + e.what());
}
const size_t headerlen = 2 * sizeof(crypto::public_key);
- if (data.size() < headerlen)
- {
- fail_msg_writer() << "Bad data size from file " << filename;
- return 0;
- }
+ THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file ") + filename);
const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[0];
const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[sizeof(crypto::public_key)];
const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key)
{
- fail_msg_writer() << "Key images from " << filename << " are for a different account";
- return 0;
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + filename + " are for a different account");
}
const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature);
- if ((data.size() - headerlen) % record_size)
- {
- fail_msg_writer() << "Bad data size from file " << filename;
- return 0;
- }
+ THROW_WALLET_EXCEPTION_IF((data.size() - headerlen) % record_size,
+ error::wallet_internal_error, std::string("Bad data size from file ") + filename);
size_t nki = (data.size() - headerlen) / record_size;
std::vector<std::pair<crypto::key_image, crypto::signature>> ski;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 8576227e8..b07295253 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -155,21 +155,18 @@ namespace tools
static bool has_testnet_option(const boost::program_options::variables_map& vm);
static void init_options(boost::program_options::options_description& desc_params);
- //! \return Password retrieved from prompt. Logs error on failure.
- static boost::optional<password_container> password_prompt(const bool new_password);
-
//! Uses stdin and stdout. Returns a wallet2 if no errors.
- static std::unique_ptr<wallet2> make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file);
+ static std::unique_ptr<wallet2> make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
//! Uses stdin and stdout. Returns a wallet2 and password for `wallet_file` if no errors.
static std::pair<std::unique_ptr<wallet2>, password_container>
- make_from_file(const boost::program_options::variables_map& vm, const std::string& wallet_file);
+ make_from_file(const boost::program_options::variables_map& vm, const std::string& wallet_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
//! Uses stdin and stdout. Returns a wallet2 and password for wallet with no file if no errors.
- static std::pair<std::unique_ptr<wallet2>, password_container> make_new(const boost::program_options::variables_map& vm);
+ static std::pair<std::unique_ptr<wallet2>, password_container> make_new(const boost::program_options::variables_map& vm, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
//! Just parses variables.
- static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm);
+ static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
static bool verify_password(const std::string& keys_file_name, const std::string& password, bool watch_only);
diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp
index df01ec238..cc6bb1de2 100644
--- a/src/wallet/wallet_args.cpp
+++ b/src/wallet/wallet_args.cpp
@@ -30,7 +30,6 @@
#include <boost/filesystem/path.hpp>
#include <boost/format.hpp>
#include "common/i18n.h"
-#include "common/scoped_message_writer.h"
#include "common/util.h"
#include "misc_log_ex.h"
#include "string_tools.h"
@@ -50,6 +49,20 @@
#define DEFAULT_MAX_CONCURRENCY 0
#endif
+namespace
+{
+ class Print
+ {
+ public:
+ Print(const std::function<void(const std::string&, bool)> &p, bool em = false): print(p), emphasis(em) {}
+ ~Print() { print(ss.str(), emphasis); }
+ template<typename T> std::ostream &operator<<(const T &t) { ss << t; return ss; }
+ private:
+ const std::function<void(const std::string&, bool)> &print;
+ std::stringstream ss;
+ bool emphasis;
+ };
+}
namespace wallet_args
{
@@ -73,6 +86,7 @@ namespace wallet_args
const char* const usage,
boost::program_options::options_description desc_params,
const boost::program_options::positional_options_description& positional_options,
+ const std::function<void(const std::string&, bool)> &print,
const char *default_log_name,
bool log_to_console)
@@ -118,16 +132,16 @@ namespace wallet_args
if (command_line::get_arg(vm, command_line::arg_help))
{
- tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL;
- tools::msg_writer() << wallet_args::tr("This is the command line monero wallet. It needs to connect to a monero\n"
+ Print(print) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL;
+ Print(print) << wallet_args::tr("This is the command line monero wallet. It needs to connect to a monero\n"
"daemon to work correctly.") << ENDL;
- tools::msg_writer() << wallet_args::tr("Usage:") << ENDL << " " << usage;
- tools::msg_writer() << desc_all;
+ Print(print) << wallet_args::tr("Usage:") << ENDL << " " << usage;
+ Print(print) << desc_all;
return false;
}
else if (command_line::get_arg(vm, command_line::arg_version))
{
- tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")";
+ Print(print) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")";
return false;
}
@@ -142,7 +156,7 @@ namespace wallet_args
}
else
{
- tools::fail_msg_writer() << wallet_args::tr("Can't find config file ") << config;
+ MERROR(wallet_args::tr("Can't find config file ") << config);
return false;
}
}
@@ -167,14 +181,15 @@ namespace wallet_args
if(command_line::has_arg(vm, arg_max_concurrency))
tools::set_max_concurrency(command_line::get_arg(vm, arg_max_concurrency));
- tools::scoped_message_writer(epee::console_color_white, true) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")";
+ Print(print) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")";
if (!command_line::is_arg_defaulted(vm, arg_log_level))
MINFO("Setting log level = " << command_line::get_arg(vm, arg_log_level));
else
MINFO("Setting log levels = " << getenv("MONERO_LOGS"));
MINFO(wallet_args::tr("Logging to: ") << log_path);
- tools::scoped_message_writer(epee::console_color_white, true) << boost::format(wallet_args::tr("Logging to %s")) % log_path;
+
+ Print(print) << boost::format(wallet_args::tr("Logging to %s")) % log_path;
return {std::move(vm)};
}
diff --git a/src/wallet/wallet_args.h b/src/wallet/wallet_args.h
index cf23ffded..8974098ad 100644
--- a/src/wallet/wallet_args.h
+++ b/src/wallet/wallet_args.h
@@ -50,5 +50,6 @@ namespace wallet_args
const char* const usage,
boost::program_options::options_description desc_params,
const boost::program_options::positional_options_description& positional_options,
+ const std::function<void(const std::string&, bool)> &print,
const char *default_log_name, bool log_to_console = false);
}
diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h
index 9d66f125e..41eb77451 100644
--- a/src/wallet/wallet_errors.h
+++ b/src/wallet/wallet_errors.h
@@ -765,6 +765,12 @@ namespace tools
#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE(x) STRINGIZE_DETAIL(x)
+#define THROW_WALLET_EXCEPTION(err_type, ...) \
+ do { \
+ LOG_ERROR("THROW EXCEPTION: " << #err_type); \
+ tools::error::throw_wallet_ex<err_type>(std::string(__FILE__ ":" STRINGIZE(__LINE__)), ## __VA_ARGS__); \
+ } while(0)
+
#define THROW_WALLET_EXCEPTION_IF(cond, err_type, ...) \
if (cond) \
{ \
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index fda8f244a..173cc7bbe 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -38,6 +38,7 @@ using namespace epee;
#include "wallet/wallet_args.h"
#include "common/command_line.h"
#include "common/i18n.h"
+#include "common/scoped_message_writer.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "cryptonote_basic/account.h"
#include "wallet_rpc_server_commands_defs.h"
@@ -60,6 +61,16 @@ namespace
const command_line::arg_descriptor<std::string> arg_wallet_dir = {"wallet-dir", "Directory for newly created wallets"};
constexpr const char default_rpc_username[] = "monero";
+
+ boost::optional<tools::password_container> password_prompter(const char *prompt, bool verify)
+ {
+ auto pwd_container = tools::password_container::prompt(verify, prompt);
+ if (!pwd_container)
+ {
+ MERROR("failed to read wallet password");
+ }
+ return pwd_container;
+ }
}
namespace tools
@@ -131,7 +142,7 @@ namespace tools
walvars = m_wallet;
else
{
- tmpwal = tools::wallet2::make_dummy(*m_vm);
+ tmpwal = tools::wallet2::make_dummy(*m_vm, password_prompter);
walvars = tmpwal.get();
}
boost::optional<epee::net_utils::http::login> http_login{};
@@ -1798,7 +1809,7 @@ namespace tools
command_line::add_arg(desc, arg_password);
po::store(po::parse_command_line(argc, argv, desc), vm2);
}
- std::unique_ptr<tools::wallet2> wal = tools::wallet2::make_new(vm2).first;
+ std::unique_ptr<tools::wallet2> wal = tools::wallet2::make_new(vm2, password_prompter).first;
if (!wal)
{
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
@@ -1872,7 +1883,7 @@ namespace tools
}
std::unique_ptr<tools::wallet2> wal = nullptr;
try {
- wal = tools::wallet2::make_from_file(vm2, wallet_file).first;
+ wal = tools::wallet2::make_from_file(vm2, wallet_file, password_prompter).first;
}
catch (const std::exception& e)
{
@@ -1971,6 +1982,7 @@ int main(int argc, char** argv) {
"monero-wallet-rpc [--wallet-file=<file>|--generate-from-json=<file>|--wallet-dir=<directory>] [--rpc-bind-port=<port>]",
desc_params,
po::positional_options_description(),
+ [](const std::string &s, bool emphasis){ tools::scoped_message_writer(emphasis ? epee::console_color_white : epee::console_color_default, true) << s; },
"monero-wallet-rpc.log",
true
);
@@ -2007,11 +2019,19 @@ int main(int argc, char** argv) {
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Loading wallet..."));
if(!wallet_file.empty())
{
- wal = tools::wallet2::make_from_file(*vm, wallet_file).first;
+ wal = tools::wallet2::make_from_file(*vm, wallet_file, password_prompter).first;
}
else
{
- wal = tools::wallet2::make_from_json(*vm, from_json);
+ try
+ {
+ wal = tools::wallet2::make_from_json(*vm, from_json, password_prompter);
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("Error creating wallet: " << e.what());
+ return 1;
+ }
}
if (!wal)
{