diff options
Diffstat (limited to 'src/wallet/api/wallet.cpp')
-rw-r--r-- | src/wallet/api/wallet.cpp | 108 |
1 files changed, 89 insertions, 19 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 49ccceb13..4d35bc404 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -46,7 +46,9 @@ namespace Bitmonero { namespace { // copy-pasted from simplewallet static const size_t DEFAULT_MIXIN = 4; - static const int DEFAULT_REFRESH_INTERVAL_SECONDS = 10; + static const int DEFAULT_REFRESH_INTERVAL_MILLIS = 1000 * 10; + // limit maximum refresh interval as one minute + static const int MAX_REFRESH_INTERVAL_MILLIS = 1000 * 60 * 1; } struct Wallet2CallbackImpl : public tools::i_wallet2_callback @@ -75,8 +77,12 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback virtual void on_new_block(uint64_t height, const cryptonote::block& block) { - // TODO; LOG_PRINT_L3(__FUNCTION__ << ": new block. height: " << height); + + if (m_listener) { + m_listener->newBlock(height); + // m_listener->updated(); + } } virtual void on_money_received(uint64_t height, const cryptonote::transaction& tx, uint64_t amount) @@ -161,7 +167,7 @@ uint64_t Wallet::maximumAllowedAmount() ///////////////////////// WalletImpl implementation //////////////////////// WalletImpl::WalletImpl(bool testnet) :m_wallet(nullptr), m_status(Wallet::Status_Ok), m_trustedDaemon(false), - m_wallet2Callback(nullptr) + m_wallet2Callback(nullptr), m_recoveringFromSeed(false) { m_wallet = new tools::wallet2(testnet); m_history = new TransactionHistoryImpl(this); @@ -170,7 +176,8 @@ WalletImpl::WalletImpl(bool testnet) m_refreshThreadDone = false; m_refreshEnabled = false; - m_refreshIntervalSeconds = DEFAULT_REFRESH_INTERVAL_SECONDS; + + m_refreshIntervalMillis = DEFAULT_REFRESH_INTERVAL_MILLIS; m_refreshThread = boost::thread([this] () { this->refreshThreadFunc(); @@ -190,7 +197,7 @@ bool WalletImpl::create(const std::string &path, const std::string &password, co { clearStatus(); - + m_recoveringFromSeed = false; bool keys_file_exists; bool wallet_file_exists; tools::wallet2::wallet_exists(path, keys_file_exists, wallet_file_exists); @@ -227,6 +234,7 @@ bool WalletImpl::create(const std::string &path, const std::string &password, co bool WalletImpl::open(const std::string &path, const std::string &password) { clearStatus(); + m_recoveringFromSeed = false; try { // TODO: handle "deprecated" m_wallet->load(path, password); @@ -251,6 +259,7 @@ bool WalletImpl::recover(const std::string &path, const std::string &seed) return false; } + m_recoveringFromSeed = true; crypto::secret_key recovery_key; std::string old_language; if (!crypto::ElectrumWords::words_to_bytes(seed, recovery_key, old_language)) { @@ -263,6 +272,7 @@ bool WalletImpl::recover(const std::string &path, const std::string &seed) m_wallet->set_seed_language(old_language); m_wallet->generate(path, "", recovery_key, true, false); // TODO: wallet->init(daemon_address); + } catch (const std::exception &e) { m_status = Status_Error; m_errorString = e.what(); @@ -379,11 +389,7 @@ string WalletImpl::keysFilename() const bool WalletImpl::init(const std::string &daemon_address, uint64_t upper_transaction_size_limit) { clearStatus(); - - m_wallet->init(daemon_address, upper_transaction_size_limit); - if (Utils::isAddressLocal(daemon_address)) { - this->setTrustedDaemon(true); - } + doInit(daemon_address, upper_transaction_size_limit); bool result = this->refresh(); // enabling background refresh thread startRefresh(); @@ -394,10 +400,7 @@ bool WalletImpl::init(const std::string &daemon_address, uint64_t upper_transact void WalletImpl::initAsync(const string &daemon_address, uint64_t upper_transaction_size_limit) { clearStatus(); - m_wallet->init(daemon_address, upper_transaction_size_limit); - if (Utils::isAddressLocal(daemon_address)) { - this->setTrustedDaemon(true); - } + doInit(daemon_address, upper_transaction_size_limit); startRefresh(); } @@ -413,6 +416,44 @@ uint64_t WalletImpl::unlockedBalance() const return m_wallet->unlocked_balance(); } +uint64_t WalletImpl::blockChainHeight() const +{ + return m_wallet->get_blockchain_current_height(); +} + +uint64_t WalletImpl::daemonBlockChainHeight() const +{ + std::string err; + uint64_t result = m_wallet->get_daemon_blockchain_height(err); + if (!err.empty()) { + LOG_ERROR(__FUNCTION__ << ": " << err); + result = 0; + m_errorString = err; + m_status = Status_Error; + + } else { + m_status = Status_Ok; + m_errorString = ""; + } + return result; +} + +uint64_t WalletImpl::daemonBlockChainTargetHeight() const +{ + std::string err; + uint64_t result = m_wallet->get_daemon_blockchain_target_height(err); + if (!err.empty()) { + LOG_ERROR(__FUNCTION__ << ": " << err); + result = 0; + m_errorString = err; + m_status = Status_Error; + + } else { + m_status = Status_Ok; + m_errorString = ""; + } + return result; +} bool WalletImpl::refresh() { @@ -428,14 +469,20 @@ void WalletImpl::refreshAsync() m_refreshCV.notify_one(); } -void WalletImpl::setAutoRefreshInterval(int seconds) +void WalletImpl::setAutoRefreshInterval(int millis) { - m_refreshIntervalSeconds = seconds; + if (millis > MAX_REFRESH_INTERVAL_MILLIS) { + LOG_ERROR(__FUNCTION__<< ": invalid refresh interval " << millis + << " ms, maximum allowed is " << MAX_REFRESH_INTERVAL_MILLIS << " ms"); + m_refreshIntervalMillis = MAX_REFRESH_INTERVAL_MILLIS; + } else { + m_refreshIntervalMillis = millis; + } } int WalletImpl::autoRefreshInterval() const { - return m_refreshIntervalSeconds; + return m_refreshIntervalMillis; } // TODO: @@ -652,8 +699,8 @@ void WalletImpl::refreshThreadFunc() LOG_PRINT_L3(__FUNCTION__ << ": waiting for refresh..."); // if auto refresh enabled, we wait for the "m_refreshIntervalSeconds" interval. // if not - we wait forever - if (m_refreshIntervalSeconds > 0) { - boost::posix_time::milliseconds wait_for_ms(m_refreshIntervalSeconds * 1000); + if (m_refreshIntervalMillis > 0) { + boost::posix_time::milliseconds wait_for_ms(m_refreshIntervalMillis); m_refreshCV.timed_wait(lock, wait_for_ms); } else { m_refreshCV.wait(lock); @@ -715,4 +762,27 @@ void WalletImpl::pauseRefresh() } +bool WalletImpl::isNewWallet() const +{ + // in case wallet created without daemon connection, closed and opened again, + // it's the same case as if it created from scratch, i.e. we need "fast sync" + // with the daemon (pull hashes instead of pull blocks) + return !(blockChainHeight() > 1 || m_recoveringFromSeed); +} + +void WalletImpl::doInit(const string &daemon_address, uint64_t upper_transaction_size_limit) +{ + m_wallet->init(daemon_address, upper_transaction_size_limit); + + // in case new wallet, this will force fast-refresh (pulling hashes instead of blocks) + if (isNewWallet()) { + m_wallet->set_refresh_from_block_height(daemonBlockChainHeight()); + } + + if (Utils::isAddressLocal(daemon_address)) { + this->setTrustedDaemon(true); + } + +} + } // namespace |