aboutsummaryrefslogtreecommitdiff
path: root/src/simplewallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/simplewallet')
-rw-r--r--src/simplewallet/simplewallet.cpp120
1 files changed, 79 insertions, 41 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 269be285f..aa571755f 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -58,6 +58,7 @@
#include "crypto/crypto.h" // for crypto::secret_key definition
#include "mnemonics/electrum-words.h"
#include "rapidjson/document.h"
+#include "common/json_util.h"
#include <stdexcept>
#if defined(WIN32)
@@ -841,40 +842,27 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
return false;
}
- if (!json.HasMember("version")) {
- fail_msg_writer() << tr("Version not found in JSON");
- return false;
- }
- unsigned int version = json["version"].GetUint();
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, version, unsigned, Uint, true);
const int current_version = 1;
- if (version > current_version) {
- fail_msg_writer() << boost::format(tr("Version %u too new, we can only grok up to %u")) % version % current_version;
+ if (field_version > current_version) {
+ fail_msg_writer() << boost::format(tr("Version %u too new, we can only grok up to %u")) % field_version % current_version;
return false;
}
- if (!json.HasMember("filename")) {
- fail_msg_writer() << tr("Filename not found in JSON");
- return false;
- }
- std::string filename = json["filename"].GetString();
- bool recover = false;
- uint64_t scan_from_height = 0;
- if (json.HasMember("scan_from_height")) {
- scan_from_height = json["scan_from_height"].GetUint64();
- recover = true;
- }
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, filename, std::string, String, true);
- password = "";
- if (json.HasMember("password")) {
- password = json["password"].GetString();
- }
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, scan_from_height, uint64_t, Uint64, false);
+ bool recover = field_scan_from_height_found;
+
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, password, std::string, String, false);
+ password = field_password;
- std::string viewkey_string("");
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, viewkey, std::string, String, false);
crypto::secret_key viewkey;
- if (json.HasMember("viewkey")) {
- viewkey_string = json["viewkey"].GetString();
+ if (field_viewkey_found)
+ {
cryptonote::blobdata viewkey_data;
- if(!epee::string_tools::parse_hexstr_to_binbuff(viewkey_string, viewkey_data))
+ if(!epee::string_tools::parse_hexstr_to_binbuff(field_viewkey, viewkey_data))
{
fail_msg_writer() << tr("failed to parse view key secret key");
return false;
@@ -882,12 +870,12 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data());
}
- std::string spendkey_string("");
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, spendkey, std::string, String, false);
crypto::secret_key spendkey;
- if (json.HasMember("spendkey")) {
- spendkey_string = json["spendkey"].GetString();
+ if (field_spendkey_found)
+ {
cryptonote::blobdata spendkey_data;
- if(!epee::string_tools::parse_hexstr_to_binbuff(spendkey_string, spendkey_data))
+ if(!epee::string_tools::parse_hexstr_to_binbuff(field_spendkey, spendkey_data))
{
fail_msg_writer() << tr("failed to parse spend key secret key");
return false;
@@ -895,30 +883,32 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data());
}
- std::string seed("");
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, seed, std::string, String, false);
std::string old_language;
- if (json.HasMember("seed")) {
- seed = json["seed"].GetString();
- if (!crypto::ElectrumWords::words_to_bytes(seed, m_recovery_key, old_language))
+ if (field_seed_found)
+ {
+ if (!crypto::ElectrumWords::words_to_bytes(field_seed, m_recovery_key, old_language))
{
fail_msg_writer() << tr("Electrum-style word list failed verification");
return false;
}
- m_electrum_seed = seed;
+ m_electrum_seed = field_seed;
m_restore_deterministic_wallet = true;
}
// compatibility checks
- if (seed.empty() && viewkey_string.empty()) {
+ if (!field_seed_found && !field_viewkey_found)
+ {
fail_msg_writer() << tr("At least one of Electrum-style word list and private view key must be specified");
return false;
}
- if (!seed.empty() && (!viewkey_string.empty() || !spendkey_string.empty())) {
+ if (field_seed_found && (field_viewkey_found || field_spendkey_found))
+ {
fail_msg_writer() << tr("Both Electrum-style word list and private key(s) specified");
return false;
}
- m_wallet_file = filename;
+ m_wallet_file = field_filename;
bool was_deprecated_wallet = m_restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) ||
crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed));
@@ -933,7 +923,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
try
{
- if (!seed.empty())
+ if (!field_seed.empty())
{
m_wallet->generate(m_wallet_file, password, m_recovery_key, recover, false);
}
@@ -949,7 +939,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
return false;
}
- if (spendkey_string.empty())
+ if (field_spendkey.empty())
{
m_wallet->generate(m_wallet_file, password, address, viewkey);
}
@@ -965,13 +955,44 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
return false;
}
- m_wallet->set_refresh_from_block_height(scan_from_height);
+ m_wallet->set_refresh_from_block_height(field_scan_from_height);
wallet_file = m_wallet_file;
return r;
}
+static bool is_local_daemon(const std::string &address)
+{
+ // extract host
+ epee::net_utils::http::url_content u_c;
+ if (!epee::net_utils::parse_url(address, u_c))
+ {
+ LOG_PRINT_L1("Failed to determine whether daemon is local, assuming not");
+ return false;
+ }
+ if (u_c.host.empty())
+ {
+ LOG_PRINT_L1("Failed to determine whether daemon is local, assuming not");
+ return false;
+ }
+
+ // resolve to IP
+ boost::asio::io_service io_service;
+ boost::asio::ip::tcp::resolver resolver(io_service);
+ boost::asio::ip::tcp::resolver::query query(u_c.host, "");
+ boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query);
+ while (i != boost::asio::ip::tcp::resolver::iterator())
+ {
+ const boost::asio::ip::tcp::endpoint &ep = *i;
+ if (ep.address().is_loopback())
+ return true;
+ ++i;
+ }
+
+ return false;
+}
+
//----------------------------------------------------------------------------------------------------
bool simple_wallet::init(const boost::program_options::variables_map& vm)
{
@@ -1007,6 +1028,17 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
if (m_daemon_address.empty())
m_daemon_address = std::string("http://") + m_daemon_host + ":" + std::to_string(m_daemon_port);
+ // set --trusted-daemon if local
+ try
+ {
+ if (is_local_daemon(m_daemon_address))
+ {
+ LOG_PRINT_L1(tr("Daemon is local, assuming trusted"));
+ m_trusted_daemon = true;
+ }
+ }
+ catch (const std::exception &e) { }
+
tools::password_container pwd_container;
if (!get_password(vm, true, pwd_container))
return false;
@@ -2191,6 +2223,9 @@ bool simple_wallet::transfer_main(bool new_algorithm, const std::vector<std::str
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)
{
@@ -2350,6 +2385,9 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
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)
{