diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 9 | ||||
-rw-r--r-- | src/cryptonote_protocol/cryptonote_protocol_handler.inl | 7 | ||||
-rw-r--r-- | src/p2p/net_peerlist.h | 3 | ||||
-rw-r--r-- | src/ringct/rctTypes.h | 2 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 130 | ||||
-rw-r--r-- | src/wallet/api/wallet.h | 6 | ||||
-rw-r--r-- | src/wallet/api/wallet_manager.cpp | 16 | ||||
-rw-r--r-- | src/wallet/api/wallet_manager.h | 7 | ||||
-rw-r--r-- | src/wallet/wallet2_api.h | 21 | ||||
-rw-r--r-- | src/wallet/wallet_args.cpp | 2 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 2 |
11 files changed, 189 insertions, 16 deletions
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index b695ae2d4..ef473cfba 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1019,12 +1019,11 @@ namespace cryptonote MGINFO_YELLOW(ENDL << "**********************************************************************" << ENDL << "The daemon will start synchronizing with the network. It may take up to several hours." << ENDL << ENDL - << "You can set the level of process detailization* through \"set_log <level|categories>\" command*, where <level> is between 0 (no details) and 4 (very verbose), or custom category based levels (eg, *:WARNING)" << ENDL + << "You can set the level of process detailization* through \"set_log <level|categories>\" command*," << ENDL + << "where <level> is between 0 (no details) and 4 (very verbose), or custom category based levels (eg, *:WARNING)" << ENDL << ENDL - << "Use \"help\" command to see the list of available commands." << ENDL - << ENDL - << "Note: in case you need to interrupt the process, use \"exit\" command. Otherwise, the current progress won't be saved." << ENDL - << "**********************************************************************"); + << "Use the \"help\" command to see the list of available commands." << ENDL + << "**********************************************************************" << ENDL); m_starter_message_showed = true; } diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index f42d31dcf..1309ff742 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -1022,13 +1022,10 @@ namespace cryptonote bool val_expected = false; if(m_synchronized.compare_exchange_strong(val_expected, true)) { - MGINFO_GREEN(ENDL << "**********************************************************************" << ENDL + MGINFO_YELLOW(ENDL << "**********************************************************************" << ENDL << "You are now synchronized with the network. You may now start monero-wallet-cli." << ENDL << ENDL - << "Please note, that the blockchain will be saved only after you quit the daemon with \"exit\" command or if you use \"save\" command." << ENDL - << "Otherwise, you will possibly need to synchronize the blockchain again." << ENDL - << ENDL - << "Use \"help\" command to see the list of available commands." << ENDL + << "Use the \"help\" command to see the list of available commands." << ENDL << "**********************************************************************"); m_core.on_synchronized(); } diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h index d477f881b..c73d6615d 100644 --- a/src/p2p/net_peerlist.h +++ b/src/p2p/net_peerlist.h @@ -395,7 +395,6 @@ namespace nodetool } return true; CATCH_ENTRY_L0("peerlist_manager::append_with_peer_gray()", false); - return true; } //-------------------------------------------------------------------------------------------------- inline @@ -420,7 +419,6 @@ namespace nodetool return true; CATCH_ENTRY_L0("peerlist_manager::get_random_gray_peer()", false); - return true; } //-------------------------------------------------------------------------------------------------- inline @@ -439,7 +437,6 @@ namespace nodetool return true; CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_gray()", false); - return true; } //-------------------------------------------------------------------------------------------------- } diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index b1aa243b9..0c27745e1 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -40,11 +40,11 @@ #include <cinttypes> extern "C" { -#include "crypto/generic-ops.h" #include "crypto/crypto-ops.h" #include "crypto/random.h" #include "crypto/keccak.h" } +#include "crypto/generic-ops.h" #include "crypto/crypto.h" #include "serialization/serialization.h" diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 52ecc2e6a..c1cc5d10d 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -197,6 +197,44 @@ bool Wallet::addressValid(const std::string &str, bool testnet) return get_account_integrated_address_from_str(address, has_payment_id, pid, testnet, str); } +bool Wallet::keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error) +{ + bool has_payment_id; + cryptonote::account_public_address address; + crypto::hash8 pid; + if(!get_account_integrated_address_from_str(address, has_payment_id, pid, testnet, address_string)) { + error = tr("Failed to parse address"); + return false; + } + + cryptonote::blobdata key_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(secret_key_string, key_data) || key_data.size() != sizeof(crypto::secret_key)) + { + error = tr("Failed to parse key"); + return false; + } + crypto::secret_key key = *reinterpret_cast<const crypto::secret_key*>(key_data.data()); + + // check the key match the given address + crypto::public_key pkey; + if (!crypto::secret_key_to_public_key(key, pkey)) { + error = tr("failed to verify key"); + return false; + } + bool matchAddress = false; + if(isViewKey) + matchAddress = address.m_view_public_key == pkey; + else + matchAddress = address.m_spend_public_key == pkey; + + if(!matchAddress) { + error = tr("key does not match address"); + return false; + } + + return true; +} + std::string Wallet::paymentIdFromAddress(const std::string &str, bool testnet) { bool has_payment_id; @@ -337,6 +375,98 @@ bool WalletImpl::createWatchOnly(const std::string &path, const std::string &pas return true; } +bool WalletImpl::recoverFromKeys(const std::string &path, + const std::string &language, + const std::string &address_string, + const std::string &viewkey_string, + const std::string &spendkey_string) +{ + cryptonote::account_public_address address; + bool has_payment_id; + crypto::hash8 new_payment_id; + if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, m_wallet->testnet(), address_string)) + { + m_errorString = tr("failed to parse address"); + m_status = Status_Error; + return false; + } + + // parse optional spend key + crypto::secret_key spendkey; + bool has_spendkey = false; + if (!spendkey_string.empty()) { + cryptonote::blobdata spendkey_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(spendkey_string, spendkey_data) || spendkey_data.size() != sizeof(crypto::secret_key)) + { + m_errorString = tr("failed to parse secret spend key"); + m_status = Status_Error; + return false; + } + has_spendkey = true; + spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data()); + } + + // parse view secret key + if (viewkey_string.empty()) { + m_errorString = tr("No view key supplied, cancelled"); + m_status = Status_Error; + return false; + } + cryptonote::blobdata viewkey_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(viewkey_string, viewkey_data) || viewkey_data.size() != sizeof(crypto::secret_key)) + { + m_errorString = tr("failed to parse secret view key"); + m_status = Status_Error; + return false; + } + crypto::secret_key viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data()); + + // check the spend and view keys match the given address + crypto::public_key pkey; + if(has_spendkey) { + if (!crypto::secret_key_to_public_key(spendkey, pkey)) { + m_errorString = tr("failed to verify secret spend key"); + m_status = Status_Error; + return false; + } + if (address.m_spend_public_key != pkey) { + m_errorString = tr("spend key does not match address"); + m_status = Status_Error; + return false; + } + } + if (!crypto::secret_key_to_public_key(viewkey, pkey)) { + m_errorString = tr("failed to verify secret view key"); + m_status = Status_Error; + return false; + } + if (address.m_view_public_key != pkey) { + m_errorString = tr("view key does not match address"); + m_status = Status_Error; + return false; + } + + try + { + if (has_spendkey) { + m_wallet->generate(path, "", address, spendkey, viewkey); + LOG_PRINT_L1("Generated new wallet from keys"); + } + else { + m_wallet->generate(path, "", address, viewkey); + LOG_PRINT_L1("Generated new view only wallet from keys"); + } + + } + catch (const std::exception& e) { + m_errorString = string(tr("failed to generate new wallet: ")) + e.what(); + m_status = Status_Error; + return false; + } + return true; +} + + bool WalletImpl::open(const std::string &path, const std::string &password) { clearStatus(); diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index e3df7fd01..16a7f5d95 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -58,6 +58,11 @@ public: const std::string &language) const; bool open(const std::string &path, const std::string &password); bool recover(const std::string &path, const std::string &seed); + bool recoverFromKeys(const std::string &path, + const std::string &language, + const std::string &address_string, + const std::string &viewkey_string, + const std::string &spendkey_string = ""); bool close(); std::string seed() const; std::string getSeedLanguage() const; @@ -94,6 +99,7 @@ public: void setRecoveringFromSeed(bool recoveringFromSeed); bool watchOnly() const; bool rescanSpent(); + bool testnet() const {return m_wallet->testnet();} PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id, diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index 904338a72..fcb39d1f3 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -72,6 +72,22 @@ Wallet *WalletManagerImpl::recoveryWallet(const std::string &path, const std::st return wallet; } +Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path, + const std::string &language, + bool testnet, + uint64_t restoreHeight, + const std::string &addressString, + const std::string &viewKeyString, + const std::string &spendKeyString) +{ + WalletImpl * wallet = new WalletImpl(testnet); + if(restoreHeight > 0){ + wallet->setRefreshFromBlockHeight(restoreHeight); + } + wallet->recoverFromKeys(path, language, addressString, viewKeyString, spendKeyString); + return wallet; +} + bool WalletManagerImpl::closeWallet(Wallet *wallet) { WalletImpl * wallet_ = dynamic_cast<WalletImpl*>(wallet); diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h index ca9570254..ce9b70e96 100644 --- a/src/wallet/api/wallet_manager.h +++ b/src/wallet/api/wallet_manager.h @@ -41,6 +41,13 @@ public: const std::string &language, bool testnet); Wallet * openWallet(const std::string &path, const std::string &password, bool testnet); virtual Wallet * recoveryWallet(const std::string &path, const std::string &memo, bool testnet, uint64_t restoreHeight); + virtual Wallet * createWalletFromKeys(const std::string &path, + const std::string &language, + bool testnet, + uint64_t restoreHeight, + const std::string &addressString, + const std::string &viewKeyString, + const std::string &spendKeyString = ""); virtual bool closeWallet(Wallet *wallet); bool walletExists(const std::string &path); std::vector<std::string> findWallets(const std::string &path); diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h index 78caddc0b..563f16eaa 100644 --- a/src/wallet/wallet2_api.h +++ b/src/wallet/wallet2_api.h @@ -295,6 +295,7 @@ struct Wallet virtual bool setPassword(const std::string &password) = 0; virtual std::string address() const = 0; virtual std::string path() const = 0; + virtual bool testnet() const = 0; /*! * \brief integratedAddress - returns integrated address for current wallet address and given payment_id. @@ -434,6 +435,7 @@ struct Wallet static std::string genPaymentId(); static bool paymentIdValid(const std::string &paiment_id); static bool addressValid(const std::string &str, bool testnet); + static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error); static std::string paymentIdFromAddress(const std::string &str, bool testnet); static uint64_t maximumAllowedAmount(); @@ -613,6 +615,25 @@ struct WalletManager */ virtual Wallet * recoveryWallet(const std::string &path, const std::string &memo, bool testnet = false, uint64_t restoreHeight = 0) = 0; + /*! + * \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted + * \param path Name of wallet file to be created + * \param language language + * \param testnet testnet + * \param restoreHeight restore from start height + * \param addressString public address + * \param viewKeyString view key + * \param spendKeyString spend key (optional) + * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) + */ + virtual Wallet * createWalletFromKeys(const std::string &path, + const std::string &language, + bool testnet, + uint64_t restoreHeight, + const std::string &addressString, + const std::string &viewKeyString, + const std::string &spendKeyString = "") = 0; + /*! * \brief Closes wallet. In case operation succeded, wallet object deleted. in case operation failed, wallet object not deleted * \param wallet previously opened / created wallet instance diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp index 7ec4ad6e4..b7a4532fd 100644 --- a/src/wallet/wallet_args.cpp +++ b/src/wallet/wallet_args.cpp @@ -137,7 +137,7 @@ namespace wallet_args if (!vm["log-file"].defaulted()) log_path = command_line::get_arg(vm, arg_log_file); else - log_path = mlog_get_default_log_path("monero-wallet-cli,log"); + log_path = mlog_get_default_log_path("monero-wallet-cli.log"); mlog_configure(log_path, false); if (!vm["log-level"].defaulted()) { diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 33e099ceb..d35e51068 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -369,7 +369,7 @@ namespace tools cryptonote::set_payment_id_to_tx_extra_nonce(extra_nonce, long_payment_id); } /* or short payment ID */ - else if (!wallet2::parse_short_payment_id(payment_id_str, short_payment_id)) { + else if (wallet2::parse_short_payment_id(payment_id_str, short_payment_id)) { cryptonote::set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, short_payment_id); } else { |