aboutsummaryrefslogtreecommitdiff
path: root/src/simplewallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/simplewallet')
-rw-r--r--src/simplewallet/simplewallet.cpp239
-rw-r--r--src/simplewallet/simplewallet.h3
2 files changed, 115 insertions, 127 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index f0c1e914a..bbdf6a4a7 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -68,11 +68,13 @@ using boost::lexical_cast;
namespace po = boost::program_options;
typedef cryptonote::simple_wallet sw;
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "wallet.simplewallet"
+
#define EXTENDED_LOGS_FILE "wallet_details.log"
#define DEFAULT_MIX 4
-#define KEY_IMAGE_EXPORT_FILE_MAGIC "Monero key image export\002"
#define OUTPUT_EXPORT_FILE_MAGIC "Monero output export\003"
#define LOCK_IDLE_SCOPE() \
@@ -137,8 +139,8 @@ namespace
class message_writer
{
public:
- message_writer(epee::log_space::console_colors color = epee::log_space::console_color_default, bool bright = false,
- std::string&& prefix = std::string(), int log_level = LOG_LEVEL_2)
+ 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)
@@ -174,17 +176,17 @@ namespace
{
m_flush = false;
- LOG_PRINT(m_oss.str(), m_log_level);
+ MCLOG(m_log_level, "global", m_oss.str());
- if (epee::log_space::console_color_default == m_color)
+ if (console_color_default == m_color)
{
std::cout << m_oss.str();
}
else
{
- epee::log_space::set_console_color(m_color, m_bright);
+ set_console_color(m_color, m_bright);
std::cout << m_oss.str();
- epee::log_space::reset_console_color();
+ reset_console_color();
}
std::cout << std::endl;
}
@@ -198,19 +200,19 @@ namespace
private:
bool m_flush;
std::stringstream m_oss;
- epee::log_space::console_colors m_color;
+ console_colors m_color;
bool m_bright;
- int m_log_level;
+ el::Level m_log_level;
};
message_writer success_msg_writer(bool color = false)
{
- return message_writer(color ? epee::log_space::console_color_green : epee::log_space::console_color_default, false, std::string(), LOG_LEVEL_2);
+ return message_writer(color ? console_color_green : console_color_default, false, std::string(), el::Level::Info);
}
message_writer fail_msg_writer()
{
- return message_writer(epee::log_space::console_color_red, true, sw::tr("Error: "), LOG_LEVEL_0);
+ return message_writer(console_color_red, true, sw::tr("Error: "), el::Level::Error);
}
bool is_it_true(const std::string& s)
@@ -572,7 +574,7 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("donate", boost::bind(&simple_wallet::donate, this, _1), tr("donate [<mixin_count>] <amount> [payment_id] - Donate <amount> to the development team (donate.getmonero.org)"));
m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this, _1), tr("Sign a transaction from a file"));
m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), tr("Submit a signed transaction from a file"));
- m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), tr("set_log <level> - Change current log detail level, <0-4>"));
+ m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), tr("set_log <level>|<categories> - Change current log detail (level must be <0-4>)"));
m_cmd_binder.set_handler("address", boost::bind(&simple_wallet::print_address, this, _1), tr("Show current wallet public address"));
m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::print_integrated_address, this, _1), tr("integrated_address [PID] - Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID"));
m_cmd_binder.set_handler("address_book", boost::bind(&simple_wallet::address_book, this, _1), tr("address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)] - Print all entries in the address book, optionally adding/deleting an entry to/from it"));
@@ -746,22 +748,24 @@ bool simple_wallet::set_log(const std::vector<std::string> &args)
{
if(args.size() != 1)
{
- fail_msg_writer() << tr("usage: set_log <log_level_number_0-4>");
+ fail_msg_writer() << tr("usage: set_log <log_level_number_0-4> | <categories>");
return true;
}
uint16_t l = 0;
- if(!epee::string_tools::get_xtype_from_string(l, args[0]))
+ if(epee::string_tools::get_xtype_from_string(l, args[0]))
{
- fail_msg_writer() << tr("wrong number format, use: set_log <log_level_number_0-4>");
- return true;
+ if(4 < l)
+ {
+ fail_msg_writer() << tr("wrong number range, use: set_log <log_level_number_0-4>");
+ return true;
+ }
+
+ mlog_set_log_level(l);
}
- if(LOG_LEVEL_4 < l)
+ else
{
- fail_msg_writer() << tr("wrong number range, use: set_log <log_level_number_0-4>");
- return true;
+ mlog_set_categories(args.front().c_str());
}
-
- log_space::log_singletone::get_set_log_detalisation_level(true, l);
return true;
}
//----------------------------------------------------------------------------------------------------
@@ -935,22 +939,6 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
return false;
}
}
- if (!m_restore_height && m_restoring)
- {
- std::string heightstr = command_line::input_line("Restore from specific blockchain height (optional, default 0): ");
- if (std::cin.eof())
- return false;
- if (heightstr.size())
- {
- try {
- m_restore_height = boost::lexical_cast<uint64_t>(heightstr);
- }
- catch (boost::bad_lexical_cast &) {
- fail_msg_writer() << tr("bad m_restore_height parameter:") << " " << heightstr;
- return false;
- }
- }
- }
if (!m_generate_from_view_key.empty())
{
m_wallet_file = m_generate_from_view_key;
@@ -1091,6 +1079,70 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
bool r = new_wallet(vm, m_recovery_key, m_restore_deterministic_wallet, m_non_deterministic, old_language);
CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
}
+ if (!m_restore_height && m_restoring)
+ {
+ uint32_t version;
+ bool connected = try_connect_to_daemon(false, &version);
+ while (true)
+ {
+ 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): ");
+ else
+ heightstr = command_line::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())
+ {
+ m_restore_height = 0;
+ break;
+ }
+ try
+ {
+ m_restore_height = boost::lexical_cast<uint64_t>(heightstr);
+ break;
+ }
+ catch (const boost::bad_lexical_cast &)
+ {
+ if (!connected || version < MAKE_CORE_RPC_VERSION(1, 6))
+ {
+ fail_msg_writer() << tr("bad m_restore_height parameter: ") << heightstr;
+ continue;
+ }
+ if (heightstr.size() != 10 || heightstr[4] != '-' || heightstr[7] != '-')
+ {
+ fail_msg_writer() << tr("date format must be YYYY-MM-DD");
+ continue;
+ }
+ uint16_t year;
+ uint8_t month; // 1, 2, ..., 12
+ uint8_t day; // 1, 2, ..., 31
+ try
+ {
+ year = boost::lexical_cast<uint16_t>(heightstr.substr(0,4));
+ // lexical_cast<uint8_t> won't work becasue uint8_t is treated as character type
+ month = boost::lexical_cast<uint16_t>(heightstr.substr(5,2));
+ 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): "));
+ if (std::cin.eof())
+ return false;
+ if(command_line::is_yes(confirm))
+ break;
+ }
+ catch (const boost::bad_lexical_cast &)
+ {
+ fail_msg_writer() << tr("bad m_restore_height parameter: ") << heightstr;
+ }
+ catch (const std::runtime_error& e)
+ {
+ fail_msg_writer() << e.what();
+ }
+ }
+ }
+ m_wallet->set_refresh_from_block_height(m_restore_height);
+ }
}
else
{
@@ -1245,7 +1297,7 @@ bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm,
if (was_deprecated_wallet)
{
// The user had used an older version of the wallet with old style mnemonics.
- message_writer(epee::log_space::console_color_green, false) << "\n" << tr("You had been using "
+ message_writer(console_color_green, false) << "\n" << tr("You had been using "
"a deprecated version of the wallet. Please use the new seed that we provide.\n");
}
mnemonic_language = get_mnemonic_language();
@@ -1269,7 +1321,7 @@ bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm,
try
{
recovery_val = m_wallet->generate(m_wallet_file, std::move(rc.second).password(), recovery_key, recover, two_random);
- message_writer(epee::log_space::console_color_white, true) << tr("Generated new wallet: ")
+ message_writer(console_color_white, true) << tr("Generated new wallet: ")
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet());
std::cout << tr("View key: ") << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key) << ENDL;
}
@@ -1326,7 +1378,7 @@ bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm,
{
m_wallet->generate(m_wallet_file, std::move(rc.second).password(), address, viewkey);
}
- message_writer(epee::log_space::console_color_white, true) << tr("Generated new wallet: ")
+ message_writer(console_color_white, true) << tr("Generated new wallet: ")
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet());
}
catch (const std::exception& e)
@@ -1357,7 +1409,7 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
return false;
}
- message_writer(epee::log_space::console_color_white, true) <<
+ message_writer(console_color_white, true) <<
(m_wallet->watch_only() ? tr("Opened watch-only wallet") : tr("Opened wallet")) << ": "
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet());
// If the wallet file is deprecated, we should ask for mnemonic language again and store
@@ -1367,7 +1419,7 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
{
if (m_wallet->is_deterministic())
{
- message_writer(epee::log_space::console_color_green, false) << "\n" << tr("You had been using "
+ message_writer(console_color_green, false) << "\n" << tr("You had been using "
"a deprecated version of the wallet. Please proceed to upgrade your wallet.\n");
std::string mnemonic_language = get_mnemonic_language();
if (mnemonic_language.empty())
@@ -1382,7 +1434,7 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
}
else
{
- message_writer(epee::log_space::console_color_green, false) << "\n" << tr("You had been using "
+ message_writer(console_color_green, false) << "\n" << tr("You had been using "
"a deprecated version of the wallet. Your wallet file format is being upgraded now.\n");
m_wallet->rewrite(m_wallet_file, password);
}
@@ -1559,7 +1611,7 @@ void simple_wallet::on_new_block(uint64_t height, const cryptonote::block& block
//----------------------------------------------------------------------------------------------------
void simple_wallet::on_money_received(uint64_t height, const cryptonote::transaction& tx, uint64_t amount)
{
- message_writer(epee::log_space::console_color_green, false) << "\r" <<
+ message_writer(console_color_green, false) << "\r" <<
tr("Height ") << height << ", " <<
tr("transaction ") << get_transaction_hash(tx) << ", " <<
tr("received ") << print_money(amount);
@@ -1576,7 +1628,7 @@ void simple_wallet::on_unconfirmed_money_received(uint64_t height, const crypton
//----------------------------------------------------------------------------------------------------
void simple_wallet::on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, uint64_t amount, const cryptonote::transaction& spend_tx)
{
- message_writer(epee::log_space::console_color_magenta, false) << "\r" <<
+ message_writer(console_color_magenta, false) << "\r" <<
tr("Height ") << height << ", " <<
tr("transaction ") << get_transaction_hash(spend_tx) << ", " <<
tr("spent ") << print_money(amount);
@@ -1588,7 +1640,7 @@ void simple_wallet::on_money_spent(uint64_t height, const cryptonote::transactio
//----------------------------------------------------------------------------------------------------
void simple_wallet::on_skip_transaction(uint64_t height, const cryptonote::transaction& tx)
{
- message_writer(epee::log_space::console_color_red, true) << "\r" <<
+ message_writer(console_color_red, true) << "\r" <<
tr("Height ") << height << ", " <<
tr("transaction ") << get_transaction_hash(tx) << ", " <<
tr("unsupported transaction format");
@@ -1740,7 +1792,7 @@ bool simple_wallet::show_incoming_transfers(const std::vector<std::string>& args
std::string verbose_string;
if (verbose)
verbose_string = (boost::format("%68s%68s") % td.get_public_key() % (td.m_key_image_known ? epee::string_tools::pod_to_hex(td.m_key_image) : std::string('?', 64))).str();
- message_writer(td.m_spent ? epee::log_space::console_color_magenta : epee::log_space::console_color_green, false) <<
+ message_writer(td.m_spent ? console_color_magenta : console_color_green, false) <<
boost::format("%21s%8s%12s%8s%16u%68s%s") %
print_money(td.amount()) %
(td.m_spent ? tr("T") : tr("F")) %
@@ -1906,7 +1958,7 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending
return false;
}
// available for RPC version 1.4 or higher
- if (version < 0x10004)
+ if (version < MAKE_CORE_RPC_VERSION(1, 4))
return true;
std::string err;
uint64_t blockchain_height = get_daemon_blockchain_height(err);
@@ -3395,7 +3447,7 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
// print in and out sorted by height
for (std::map<uint64_t, std::pair<bool, std::string>>::const_iterator i = output.begin(); i != output.end(); ++i) {
- message_writer(i->second.first ? epee::log_space::console_color_green : epee::log_space::console_color_magenta, false) <<
+ message_writer(i->second.first ? console_color_green : console_color_magenta, false) <<
boost::format("%8.8llu %6.6s %s") %
((unsigned long long)i->first) % (i->second.first ? tr("in") : tr("out")) % i->second.second;
}
@@ -3605,7 +3657,7 @@ bool simple_wallet::run()
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(epee::log_space::console_color_green, false) << "Background refresh thread started";
+ message_writer(console_color_green, false) << "Background refresh thread started";
return m_cmd_binder.run_handling(std::string("[") + tr("wallet") + " " + addr_start + "]: ", "");
}
//----------------------------------------------------------------------------------------------------
@@ -3907,23 +3959,7 @@ bool simple_wallet::export_key_images(const std::vector<std::string> &args)
try
{
- std::vector<std::pair<crypto::key_image, crypto::signature>> ski = m_wallet->export_key_images();
- std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC));
- const cryptonote::account_public_address &keys = m_wallet->get_account().get_keys().m_account_address;
-
- std::string data;
- data += std::string((const char *)&keys.m_spend_public_key, sizeof(crypto::public_key));
- data += std::string((const char *)&keys.m_view_public_key, sizeof(crypto::public_key));
- for (const auto &i: ski)
- {
- data += std::string((const char *)&i.first, sizeof(crypto::key_image));
- data += std::string((const char *)&i.second, sizeof(crypto::signature));
- }
-
- // encrypt data, keep magic plaintext
- std::string ciphertext = m_wallet->encrypt_with_view_secret_key(data);
- bool r = epee::file_io_utils::save_string_to_file(filename, magic + ciphertext);
- if (!r)
+ if (!m_wallet->export_key_images(filename))
{
fail_msg_writer() << tr("failed to save file ") << filename;
return true;
@@ -3949,69 +3985,17 @@ bool simple_wallet::import_key_images(const std::vector<std::string> &args)
}
std::string filename = args[0];
- 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 true;
- }
- 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 true;
- }
-
- try
- {
- data = m_wallet->decrypt_with_view_secret_key(std::string(data, magiclen));
- }
- catch (const std::exception &e)
- {
- fail_msg_writer() << "Failed to decrypt " << filename << ": " << e.what();
- return true;
- }
-
- const size_t headerlen = 2 * sizeof(crypto::public_key);
- if (data.size() < headerlen)
- {
- fail_msg_writer() << "Bad data size from file " << filename;
- return true;
- }
- 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 = m_wallet->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 true;
- }
-
- 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 true;
- }
- size_t nki = (data.size() - headerlen) / record_size;
-
- std::vector<std::pair<crypto::key_image, crypto::signature>> ski;
- ski.reserve(nki);
- for (size_t n = 0; n < nki; ++n)
- {
- crypto::key_image key_image = *reinterpret_cast<const crypto::key_image*>(&data[headerlen + n * record_size]);
- crypto::signature signature = *reinterpret_cast<const crypto::signature*>(&data[headerlen + n * record_size + sizeof(crypto::key_image)]);
-
- ski.push_back(std::make_pair(key_image, signature));
- }
-
try
{
uint64_t spent = 0, unspent = 0;
- uint64_t height = m_wallet->import_key_images(ski, spent, unspent);
- success_msg_writer() << "Signed key images imported to height " << height << ", "
- << print_money(spent) << " spent, " << print_money(unspent) << " unspent";
+ 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";
+ }
}
catch (const std::exception &e)
{
@@ -4317,6 +4301,7 @@ int main(int argc, char* argv[])
const bool r = w.init(*vm);
CHECK_AND_ASSERT_MES(r, 1, sw::tr("Failed to initialize wallet"));
+try{ throw 1; } catch(...){}
std::vector<std::string> command = command_line::get_arg(*vm, arg_command);
if (!command.empty())
{
diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h
index bf4ace948..237c1e3e1 100644
--- a/src/simplewallet/simplewallet.h
+++ b/src/simplewallet/simplewallet.h
@@ -47,6 +47,9 @@
#include "wallet/password_container.h"
#include "crypto/crypto.h" // for definition of crypto::secret_key
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "wallet.simplewallet"
+
/*!
* \namespace cryptonote
* \brief Holds cryptonote related classes and helpers.