Simplewallet improvements

This commit is contained in:
Antonio Juarez 2015-04-14 19:00:44 +01:00
parent e15c01585f
commit 89271f54f3
2 changed files with 88 additions and 78 deletions

View file

@ -272,6 +272,17 @@ struct TransferCommand {
} }
}; };
std::error_code initAndLoadWallet(IWallet& wallet, std::istream& walletFile, const std::string& password) {
WalletHelper::InitWalletResultObserver initObserver;
std::future<std::error_code> f_initError = initObserver.initResult.get_future();
wallet.addObserver(&initObserver);
wallet.initAndLoad(walletFile, password);
auto initError = f_initError.get();
wallet.removeObserver(&initObserver);
return initError;
}
std::string tryToOpenWalletOrLoadKeysOrThrow(std::unique_ptr<IWallet>& wallet, const std::string& walletFile, const std::string& password) { std::string tryToOpenWalletOrLoadKeysOrThrow(std::unique_ptr<IWallet>& wallet, const std::string& walletFile, const std::string& password) {
std::string keys_file, walletFileName; std::string keys_file, walletFileName;
@ -280,20 +291,25 @@ std::string tryToOpenWalletOrLoadKeysOrThrow(std::unique_ptr<IWallet>& wallet, c
boost::system::error_code ignore; boost::system::error_code ignore;
bool keysExists = boost::filesystem::exists(keys_file, ignore); bool keysExists = boost::filesystem::exists(keys_file, ignore);
bool walletExists = boost::filesystem::exists(walletFileName, ignore); bool walletExists = boost::filesystem::exists(walletFileName, ignore);
if (!walletExists && !keysExists && boost::filesystem::exists(walletFile, ignore)) {
auto replaceEc = tools::replace_file(walletFile, walletFileName);
if (replaceEc) {
throw std::runtime_error("failed to rename file '" + walletFile + "' to '" + walletFileName + "'");
}
walletExists = true;
}
if (walletExists) { if (walletExists) {
LOG_PRINT_L0("Loading wallet..."); LOG_PRINT_L0("Loading wallet...");
std::ifstream walletFile; std::ifstream walletFile;
walletFile.open(walletFileName, std::ios_base::binary | std::ios_base::in); walletFile.open(walletFileName, std::ios_base::binary | std::ios_base::in);
if (walletFile.fail()) if (walletFile.fail()) {
throw std::runtime_error("error opening walletfile"); throw std::runtime_error("error opening wallet file '" + walletFileName + "'");
}
auto initError = initAndLoadWallet(*wallet, walletFile, password);
WalletHelper::InitWalletResultObserver initObserver;
std::future<std::error_code> f_initError = initObserver.initResult.get_future();
wallet->addObserver(&initObserver);
wallet->initAndLoad(walletFile, password);
auto initError = f_initError.get();
wallet->removeObserver(&initObserver);
walletFile.close(); walletFile.close();
if (initError) { //bad password, or legacy format if (initError) { //bad password, or legacy format
if (keysExists) { if (keysExists) {
@ -302,11 +318,7 @@ std::string tryToOpenWalletOrLoadKeysOrThrow(std::unique_ptr<IWallet>& wallet, c
boost::filesystem::rename(keys_file, keys_file + ".back"); boost::filesystem::rename(keys_file, keys_file + ".back");
boost::filesystem::rename(walletFileName, walletFileName + ".back"); boost::filesystem::rename(walletFileName, walletFileName + ".back");
f_initError = initObserver.initResult.get_future(); initError = initAndLoadWallet(*wallet, ss, password);
wallet->addObserver(&initObserver);
wallet->initAndLoad(ss, password);
auto initError = f_initError.get();
wallet->removeObserver(&initObserver);
if (initError) { if (initError) {
throw std::runtime_error("failed to load wallet: " + initError.message()); throw std::runtime_error("failed to load wallet: " + initError.message());
} }
@ -314,8 +326,9 @@ std::string tryToOpenWalletOrLoadKeysOrThrow(std::unique_ptr<IWallet>& wallet, c
LOG_PRINT_L0("Storing wallet..."); LOG_PRINT_L0("Storing wallet...");
std::ofstream walletFile; std::ofstream walletFile;
walletFile.open(walletFileName, std::ios_base::binary | std::ios_base::out | std::ios::trunc); walletFile.open(walletFileName, std::ios_base::binary | std::ios_base::out | std::ios::trunc);
if (walletFile.fail()) if (walletFile.fail()) {
throw std::runtime_error("error saving walletfile"); throw std::runtime_error("error saving wallet file '" + walletFileName + "'");
}
WalletHelper::SaveWalletResultObserver saveObserver; WalletHelper::SaveWalletResultObserver saveObserver;
std::future<std::error_code> f_saveError = saveObserver.saveResult.get_future(); std::future<std::error_code> f_saveError = saveObserver.saveResult.get_future();
wallet->addObserver(&saveObserver); wallet->addObserver(&saveObserver);
@ -324,54 +337,53 @@ std::string tryToOpenWalletOrLoadKeysOrThrow(std::unique_ptr<IWallet>& wallet, c
wallet->removeObserver(&saveObserver); wallet->removeObserver(&saveObserver);
if (saveError) { if (saveError) {
fail_msg_writer() << "Failed to store wallet: " << saveError.message(); fail_msg_writer() << "Failed to store wallet: " << saveError.message();
throw std::runtime_error("error saving walletfile"); throw std::runtime_error("error saving wallet file '" + walletFileName + "'");
} }
LOG_PRINT_GREEN("Stored ok", LOG_LEVEL_0); LOG_PRINT_GREEN("Stored ok", LOG_LEVEL_0);
return walletFileName; return walletFileName;
} else { // no keys, wallet error loading } else { // no keys, wallet error loading
throw std::runtime_error("can't load walletfile, check password"); throw std::runtime_error("can't load wallet file '" + walletFileName + "', check password");
} }
} else { //new wallet ok } else { //new wallet ok
return walletFileName; return walletFileName;
} }
} else { } else if (keysExists) { //wallet not exists but keys presented
if (keysExists) { //wallet not exists but keys presented std::stringstream ss;
std::stringstream ss; cryptonote::importLegacyKeys(keys_file, password, ss);
cryptonote::importLegacyKeys(keys_file, password, ss); boost::filesystem::rename(keys_file, keys_file + ".back");
boost::filesystem::rename(keys_file, keys_file + ".back");
WalletHelper::InitWalletResultObserver initObserver; WalletHelper::InitWalletResultObserver initObserver;
std::future<std::error_code> f_initError = initObserver.initResult.get_future(); std::future<std::error_code> f_initError = initObserver.initResult.get_future();
wallet->addObserver(&initObserver); wallet->addObserver(&initObserver);
wallet->initAndLoad(ss, password); wallet->initAndLoad(ss, password);
auto initError = f_initError.get(); auto initError = f_initError.get();
wallet->removeObserver(&initObserver); wallet->removeObserver(&initObserver);
if (initError) { if (initError) {
throw std::runtime_error("failed to load wallet: " + initError.message()); throw std::runtime_error("failed to load wallet: " + initError.message());
}
LOG_PRINT_L0("Storing wallet...");
std::ofstream walletFile;
walletFile.open(walletFileName, std::ios_base::binary | std::ios_base::out | std::ios::trunc);
if (walletFile.fail())
throw std::runtime_error("error saving walletfile");
WalletHelper::SaveWalletResultObserver saveObserver;
std::future<std::error_code> f_saveError = saveObserver.saveResult.get_future();
wallet->addObserver(&saveObserver);
wallet->save(walletFile, false, false);
auto saveError = f_saveError.get();
wallet->removeObserver(&saveObserver);
if (saveError) {
fail_msg_writer() << "Failed to store wallet: " << saveError.message();
throw std::runtime_error("error saving walletfile");
}
LOG_PRINT_GREEN("Stored ok", LOG_LEVEL_0);
return walletFileName;
} else { //no wallet no keys
throw std::runtime_error("walletfile not found");
} }
LOG_PRINT_L0("Storing wallet...");
std::ofstream walletFile;
walletFile.open(walletFileName, std::ios_base::binary | std::ios_base::out | std::ios::trunc);
if (walletFile.fail()) {
throw std::runtime_error("error saving wallet file '" + walletFileName + "'");
}
WalletHelper::SaveWalletResultObserver saveObserver;
std::future<std::error_code> f_saveError = saveObserver.saveResult.get_future();
wallet->addObserver(&saveObserver);
wallet->save(walletFile, false, false);
auto saveError = f_saveError.get();
wallet->removeObserver(&saveObserver);
if (saveError) {
fail_msg_writer() << "Failed to store wallet: " << saveError.message();
throw std::runtime_error("error saving wallet file '" + walletFileName + "'");
}
LOG_PRINT_GREEN("Stored ok", LOG_LEVEL_0);
return walletFileName;
} else { //no wallet no keys
throw std::runtime_error("wallet file '" + walletFileName + "' is not found");
} }
} }
@ -448,8 +460,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
{ {
handle_command_line(vm); handle_command_line(vm);
if (!m_daemon_address.empty() && !m_daemon_host.empty() && 0 != m_daemon_port) if (!m_daemon_address.empty() && (!m_daemon_host.empty() || 0 != m_daemon_port)) {
{
fail_msg_writer() << "you can't specify daemon host or port several times"; fail_msg_writer() << "you can't specify daemon host or port several times";
return false; return false;
} }
@ -462,7 +473,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
std::getline(std::cin, answer); std::getline(std::cin, answer);
c = answer[0]; c = answer[0];
if (!(c == 'O' || c == 'G' || c == 'E' || c == 'o' || c == 'g' || c == 'e')) { if (!(c == 'O' || c == 'G' || c == 'E' || c == 'o' || c == 'g' || c == 'e')) {
std::cout << "Unknown command: " << c<<std::endl; std::cout << "Unknown command: " << c <<std::endl;
} else { } else {
break; break;
} }
@ -473,13 +484,17 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
} }
std::cout << "Specify wallet file name (e.g., wallet.bin).\n"; std::cout << "Specify wallet file name (e.g., wallet.bin).\n";
std::cout << "Wallet file name: "; std::string userInput;
do {
std::cout << "Wallet file name: ";
std::getline(std::cin, userInput);
userInput = string_tools::trim(userInput);
} while (userInput.empty());
if (c == 'g' || c == 'G') { if (c == 'g' || c == 'G') {
std::getline(std::cin, m_generate_new); m_generate_new = userInput;
m_generate_new = string_tools::trim(m_generate_new);
} else { } else {
std::getline(std::cin, m_wallet_file_arg); m_wallet_file_arg = userInput;
m_wallet_file_arg = string_tools::trim(m_wallet_file_arg);
} }
} }
@ -488,21 +503,15 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
return false; return false;
} }
std::string keys_file, walletFileName; std::string walletFileName;
if (!m_generate_new.empty()) { if (!m_generate_new.empty()) {
WalletHelper::prepareFileNames(m_generate_new, keys_file, walletFileName); std::string ignoredString;
WalletHelper::prepareFileNames(m_generate_new, ignoredString, walletFileName);
boost::system::error_code ignore; boost::system::error_code ignore;
bool keysExists = boost::filesystem::exists(keys_file, ignore); if (boost::filesystem::exists(walletFileName, ignore)) {
bool walletExists = boost::filesystem::exists(walletFileName, ignore);
if (walletExists) {
fail_msg_writer() << walletFileName << " already exists"; fail_msg_writer() << walletFileName << " already exists";
return false; return false;
} }
if (keysExists) {
fail_msg_writer() << "keys file found: "<< keys_file<< " you should probably try to load existing wallet";
return false;
}
} }
if (m_daemon_host.empty()) if (m_daemon_host.empty())
@ -560,7 +569,6 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
message_writer(epee::log_space::console_color_white, true) << "Opened wallet: " << m_wallet->getAddress(); message_writer(epee::log_space::console_color_white, true) << "Opened wallet: " << m_wallet->getAddress();
success_msg_writer() << success_msg_writer() <<
"**********************************************************************\n" << "**********************************************************************\n" <<
"Use \"help\" command to see the list of available commands.\n" << "Use \"help\" command to see the list of available commands.\n" <<

View file

@ -9,12 +9,14 @@ using namespace epee;
void WalletHelper::prepareFileNames(const std::string& file_path, std::string& keys_file, std::string& wallet_file) { void WalletHelper::prepareFileNames(const std::string& file_path, std::string& keys_file, std::string& wallet_file) {
keys_file = file_path; if (string_tools::get_extension(file_path) == "wallet") {
wallet_file = file_path; keys_file = string_tools::cut_off_extension(file_path) + ".keys";
boost::system::error_code e; wallet_file = file_path;
if (string_tools::get_extension(keys_file) == "keys") {//provided keys file name } else if (string_tools::get_extension(file_path) == "keys") {
wallet_file = string_tools::cut_off_extension(wallet_file); keys_file = file_path;
} else {//provided wallet file name wallet_file = string_tools::cut_off_extension(file_path) + ".wallet";
keys_file += ".keys"; } else {
keys_file = file_path + ".keys";
wallet_file = file_path + ".wallet";
} }
} }