diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/wallet2.cpp | 127 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 1 | ||||
-rw-r--r-- | src/wallet/wallet2_api.cpp | 56 | ||||
-rw-r--r-- | src/wallet/wallet2_api.h | 10 |
4 files changed, 114 insertions, 80 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 363665024..e704951e1 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1431,6 +1431,42 @@ void wallet2::check_genesis(const crypto::hash& genesis_hash) const { //---------------------------------------------------------------------------------------------------- void wallet2::store() { + store_to("", ""); +} +//---------------------------------------------------------------------------------------------------- +void wallet2::store_to(const std::string &path, const std::string &password) +{ + // if file is the same, we do: + // 1. save wallet to the *.new file + // 2. remove old wallet file + // 3. rename *.new to wallet_name + + // handle if we want just store wallet state to current files (ex store() replacement); + bool same_file = true; + if (!path.empty()) + { + std::string canonical_path = boost::filesystem::canonical(m_wallet_file).string(); + size_t pos = canonical_path.find(path); + same_file = pos != std::string::npos; + } + + + if (!same_file) + { + // check if we want to store to directory which doesn't exists yet + boost::filesystem::path parent_path = boost::filesystem::path(path).parent_path(); + + // if path is not exists, try to create it + if (!parent_path.empty() && !boost::filesystem::exists(parent_path)) + { + boost::system::error_code ec; + if (!boost::filesystem::create_directories(parent_path, ec)) + { + throw std::logic_error(ec.message()); + } + } + } + // preparing wallet data std::stringstream oss; boost::archive::binary_oarchive ar(oss); ar << *this; @@ -1445,10 +1481,10 @@ void wallet2::store() crypto::chacha8(cache_file_data.cache_data.data(), cache_file_data.cache_data.size(), key, cache_file_data.iv, &cipher[0]); cache_file_data.cache_data = cipher; - // save to new file, rename main to old, rename new to main - // at all times, there should be a valid file on disk - const std::string new_file = m_wallet_file + ".new"; - const std::string old_file = m_wallet_file + ".old"; + const std::string new_file = same_file ? m_wallet_file + ".new" : path; + const std::string old_file = m_wallet_file; + const std::string old_keys_file = m_keys_file; + const std::string old_address_file = m_wallet_file + ".address.txt"; // save to new file std::ofstream ostr; @@ -1458,87 +1494,35 @@ void wallet2::store() ostr.close(); THROW_WALLET_EXCEPTION_IF(!success || !ostr.good(), error::file_save_error, new_file); - // rename - boost::filesystem::remove(old_file); // probably does not exist - if (boost::filesystem::exists(m_wallet_file)) { - std::error_code e = tools::replace_file(m_wallet_file, old_file); - THROW_WALLET_EXCEPTION_IF(e, error::file_save_error, m_wallet_file, e); - } - std::error_code e = tools::replace_file(new_file, m_wallet_file); - THROW_WALLET_EXCEPTION_IF(e, error::file_save_error, m_wallet_file, e); - boost::filesystem::remove(old_file); -} - -void wallet2::store_to(const std::string &path, const std::string &password) -{ - // TODO: merge it with wallet2::store() function - - // check if we want to store to directory which doesn't exists yet - boost::filesystem::path parent_path = boost::filesystem::path(path).parent_path(); - - // if path is not exists, try to create it - if (!parent_path.empty() && !boost::filesystem::exists(parent_path)) { - boost::system::error_code ec; - if (!boost::filesystem::create_directories(parent_path, ec)) { - throw std::logic_error(ec.message()); - } - } - - - std::stringstream oss; - boost::archive::binary_oarchive ar(oss); - ar << *this; - - wallet2::cache_file_data cache_file_data = boost::value_initialized<wallet2::cache_file_data>(); - cache_file_data.cache_data = oss.str(); - crypto::chacha8_key key; - generate_chacha8_key_from_secret_keys(key); - std::string cipher; - cipher.resize(cache_file_data.cache_data.size()); - cache_file_data.iv = crypto::rand<crypto::chacha8_iv>(); - crypto::chacha8(cache_file_data.cache_data.data(), cache_file_data.cache_data.size(), key, cache_file_data.iv, &cipher[0]); - cache_file_data.cache_data = cipher; - - - const std::string new_file = path; - const std::string old_file = m_wallet_file; - const std::string old_keys_file = m_keys_file; - const std::string old_address_file = m_wallet_file + ".address.txt"; - - // save to new file - std::ofstream ostr; - ostr.open(new_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc); - binary_archive<true> oar(ostr); - bool success = ::serialization::serialize(oar, cache_file_data); - ostr.close(); - THROW_WALLET_EXCEPTION_IF(!success || !ostr.good(), error::file_save_error, new_file); - - // save keys to the new file - // if we here, main wallet file is saved and we only need to save keys and address files + // save keys to the new file + // if we here, main wallet file is saved and we only need to save keys and address files + if (!same_file) { prepare_file_names(path); store_keys(m_keys_file, password, false); - // save address to the new file const std::string address_file = m_wallet_file + ".address.txt"; bool r = file_io_utils::save_string_to_file(address_file, m_account.get_public_address_str(m_testnet)); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_wallet_file); - - // remove old wallet file r = boost::filesystem::remove(old_file); if (!r) { - LOG_ERROR("error removing file: " << old_file); + LOG_ERROR("error removing file: " << old_file); } // remove old keys file r = boost::filesystem::remove(old_keys_file); if (!r) { - LOG_ERROR("error removing file: " << old_keys_file); + LOG_ERROR("error removing file: " << old_keys_file); } // remove old address file r = boost::filesystem::remove(old_address_file); if (!r) { - LOG_ERROR("error removing file: " << old_address_file); + LOG_ERROR("error removing file: " << old_address_file); } + } else { + // here we have "*.new" file, we need to rename it to be without ".new" + std::error_code e = tools::replace_file(new_file, m_wallet_file); + THROW_WALLET_EXCEPTION_IF(e, error::file_save_error, m_wallet_file, e); + } } //---------------------------------------------------------------------------------------------------- uint64_t wallet2::unlocked_balance() const @@ -2838,12 +2822,17 @@ bool wallet2::get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) c std::string wallet2::get_wallet_file() const { - return m_wallet_file; + return m_wallet_file; } std::string wallet2::get_keys_file() const { - return m_keys_file; + return m_keys_file; +} + +std::string wallet2::get_daemon_address() const +{ + return m_daemon_address; } //---------------------------------------------------------------------------------------------------- diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index fc700a3de..23df070f5 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -364,6 +364,7 @@ namespace tools std::string get_wallet_file() const; std::string get_keys_file() const; + std::string get_daemon_address() const; private: /*! * \brief Stores wallet information to wallet file. diff --git a/src/wallet/wallet2_api.cpp b/src/wallet/wallet2_api.cpp index 0644e3690..31015b355 100644 --- a/src/wallet/wallet2_api.cpp +++ b/src/wallet/wallet2_api.cpp @@ -54,7 +54,7 @@ Wallet::~Wallet() {} class WalletImpl : public Wallet { public: - WalletImpl(); + WalletImpl(bool testnet = false); ~WalletImpl(); bool create(const std::string &path, const std::string &password, const std::string &language); @@ -70,6 +70,9 @@ public: bool setPassword(const std::string &password); std::string address() const; bool store(const std::string &path); + bool init(const std::string &daemon_address, uint64_t upper_transaction_size_limit); + uint64_t balance() const; + bool connectToDaemon(); private: void clearStatus(); @@ -82,10 +85,10 @@ private: std::string m_password; }; -WalletImpl::WalletImpl() +WalletImpl::WalletImpl(bool testnet) :m_wallet(nullptr), m_status(Wallet::Status_Ok) { - m_wallet = new tools::wallet2(); + m_wallet = new tools::wallet2(testnet); } WalletImpl::~WalletImpl() @@ -257,6 +260,35 @@ bool WalletImpl::store(const std::string &path) return m_status == Status_Ok; } +bool WalletImpl::init(const std::string &daemon_address, uint64_t upper_transaction_size_limit) +{ + clearStatus(); + try { + m_wallet->init(daemon_address, upper_transaction_size_limit); + } catch (const std::exception &e) { + LOG_ERROR("Error initializing wallet: " << e.what()); + m_status = Status_Error; + m_errorString = e.what(); + } + + return m_status == Status_Ok; +} + +uint64_t WalletImpl::balance() const +{ + return m_wallet->balance(); +} + +bool WalletImpl::connectToDaemon() +{ + bool result = m_wallet->check_connection(); + m_status = result ? Status_Ok : Status_Error; + if (!result) { + m_errorString = "Error connecting to daemon at " + m_wallet->get_daemon_address(); + } + return result; +} + void WalletImpl::clearStatus() { m_status = Status_Ok; @@ -270,12 +302,13 @@ class WalletManagerImpl : public WalletManager { public: Wallet * createWallet(const std::string &path, const std::string &password, - const std::string &language); - Wallet * openWallet(const std::string &path, const std::string &password); + 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); virtual bool closeWallet(Wallet *wallet); bool walletExists(const std::string &path); std::string errorString() const; + void setDaemonHost(const std::string &hostname); private: @@ -286,16 +319,16 @@ private: }; Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::string &password, - const std::string &language) + const std::string &language, bool testnet) { - WalletImpl * wallet = new WalletImpl(); + WalletImpl * wallet = new WalletImpl(testnet); wallet->create(path, password, language); return wallet; } -Wallet *WalletManagerImpl::openWallet(const std::string &path, const std::string &password) +Wallet *WalletManagerImpl::openWallet(const std::string &path, const std::string &password, bool testnet) { - WalletImpl * wallet = new WalletImpl(); + WalletImpl * wallet = new WalletImpl(testnet); wallet->open(path, password); return wallet; } @@ -329,6 +362,11 @@ std::string WalletManagerImpl::errorString() const return m_errorString; } +void WalletManagerImpl::setDaemonHost(const std::string &hostname) +{ + +} + ///////////////////// WalletManagerFactory implementation ////////////////////// diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h index c7e7c536c..ad1e08fe3 100644 --- a/src/wallet/wallet2_api.h +++ b/src/wallet/wallet2_api.h @@ -67,6 +67,9 @@ struct Wallet virtual bool setPassword(const std::string &password) = 0; virtual std::string address() const = 0; virtual bool store(const std::string &path) = 0; + virtual bool init(const std::string &daemon_address, uint64_t upper_transaction_size_limit) = 0; + virtual bool connectToDaemon() = 0; + virtual uint64_t balance() const = 0; }; /** @@ -82,7 +85,7 @@ struct WalletManager * \param language Language to be used to generate electrum seed memo * \return Wallet instance (Wallet::status() needs to be called to check if created successfully) */ - virtual Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language) = 0; + virtual Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, bool testnet) = 0; /*! * \brief Opens existing wallet @@ -90,7 +93,7 @@ struct WalletManager * \param password Password of wallet file * \return Wallet instance (Wallet::status() needs to be called to check if opened successfully) */ - virtual Wallet * openWallet(const std::string &path, const std::string &password) = 0; + virtual Wallet * openWallet(const std::string &path, const std::string &password, bool testnet) = 0; /*! * \brief recovers existing wallet using memo (electrum seed) @@ -111,6 +114,9 @@ struct WalletManager virtual bool walletExists(const std::string &path) = 0; virtual std::string errorString() const = 0; +// //! set +// virtual void setDaemonAddress(const std::string &address) = 0; + }; |