diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/api/wallet.cpp | 40 | ||||
-rw-r--r-- | src/wallet/api/wallet.h | 3 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 15 | ||||
-rw-r--r-- | src/wallet/wallet2_api.h | 16 |
4 files changed, 55 insertions, 19 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 6c1c1fea2..134ea601c 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -201,6 +201,7 @@ WalletImpl::WalletImpl(bool testnet) , m_wallet2Callback(nullptr) , m_recoveringFromSeed(false) , m_synchronized(false) + , m_rebuildWalletCache(false) { m_wallet = new tools::wallet2(testnet); m_history = new TransactionHistoryImpl(this); @@ -269,6 +270,14 @@ bool WalletImpl::open(const std::string &path, const std::string &password) m_recoveringFromSeed = false; try { // TODO: handle "deprecated" + // Check if wallet cache exists + bool keys_file_exists; + bool wallet_file_exists; + tools::wallet2::wallet_exists(path, keys_file_exists, wallet_file_exists); + if(!wallet_file_exists){ + // Rebuilding wallet cache, using refresh height from .keys file + m_rebuildWalletCache = true; + } m_wallet->load(path, password); m_password = password; @@ -540,15 +549,14 @@ int WalletImpl::autoRefreshInterval() const // - unconfirmed_transfer_details; // - confirmed_transfer_details) -PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const string &payment_id, uint64_t amount, uint32_t mixin_count, +PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const string &payment_id, optional<uint64_t> amount, uint32_t mixin_count, PendingTransaction::Priority priority) { clearStatus(); // Pause refresh thread while creating transaction pauseRefresh(); - vector<cryptonote::tx_destination_entry> dsts; - cryptonote::tx_destination_entry de; + cryptonote::account_public_address addr; // indicates if dst_addr is integrated address (address + payment_id) bool has_payment_id; @@ -561,7 +569,7 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const PendingTransactionImpl * transaction = new PendingTransactionImpl(*this); do { - if(!cryptonote::get_account_integrated_address_from_str(de.addr, has_payment_id, payment_id_short, m_wallet->testnet(), dst_addr)) { + if(!cryptonote::get_account_integrated_address_from_str(addr, has_payment_id, payment_id_short, m_wallet->testnet(), dst_addr)) { // TODO: copy-paste 'if treating as an address fails, try as url' from simplewallet.cpp:1982 m_status = Status_Error; m_errorString = "Invalid destination address"; @@ -595,14 +603,23 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const } } - de.amount = amount; - dsts.push_back(de); //std::vector<tools::wallet2::pending_tx> ptx_vector; try { - transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, - static_cast<uint32_t>(priority), - extra, m_trustedDaemon); + if (amount) { + vector<cryptonote::tx_destination_entry> dsts; + cryptonote::tx_destination_entry de; + de.addr = addr; + de.amount = *amount; + dsts.push_back(de); + transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, + static_cast<uint32_t>(priority), + extra, m_trustedDaemon); + } else { + transaction->m_pending_tx = m_wallet->create_transactions_all(addr, fake_outs_count, 0 /* unlock_time */, + static_cast<uint32_t>(priority), + extra, m_trustedDaemon); + } } catch (const tools::error::daemon_busy&) { // TODO: make it translatable with "tr"? @@ -990,8 +1007,9 @@ 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); + // with the daemon (pull hashes instead of pull blocks). + // If wallet cache is rebuilt, creation height stored in .keys is used. + return !(blockChainHeight() > 1 || m_recoveringFromSeed || m_rebuildWalletCache); } void WalletImpl::doInit(const string &daemon_address, uint64_t upper_transaction_size_limit) diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index f40551fac..372d6efd7 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -89,7 +89,7 @@ public: PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id, - uint64_t amount, uint32_t mixin_count, + optional<uint64_t> amount, uint32_t mixin_count, PendingTransaction::Priority priority = PendingTransaction::Priority_Low); virtual PendingTransaction * createSweepUnmixableTransaction(); @@ -145,6 +145,7 @@ private: // instead of pulling hashes (fast-refresh) bool m_recoveringFromSeed; std::atomic<bool> m_synchronized; + bool m_rebuildWalletCache; }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ac8802ca4..1e3bb6253 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2972,9 +2972,9 @@ void wallet2::get_outs(std::vector<std::vector<entry>> &outs, const std::list<si break; } } - LOG_PRINT_L1("" << num_outs << " outputs of size " << print_money(amount)); + LOG_PRINT_L1("" << num_outs << " unlocked outputs of size " << print_money(amount)); THROW_WALLET_EXCEPTION_IF(num_outs == 0, error::wallet_internal_error, - "histogram reports no outputs for " + boost::lexical_cast<std::string>(amount) + ", not even ours"); + "histogram reports no unlocked outputs for " + boost::lexical_cast<std::string>(amount) + ", not even ours"); THROW_WALLET_EXCEPTION_IF(num_recent_outs > num_outs, error::wallet_internal_error, "histogram reports more recent outs than outs for " + boost::lexical_cast<std::string>(amount)); @@ -2984,7 +2984,7 @@ void wallet2::get_outs(std::vector<std::vector<entry>> &outs, const std::list<si recent_outputs_count = 1; // ensure we have at least one, if possible if (recent_outputs_count > num_recent_outs) recent_outputs_count = num_recent_outs; - if (td.m_global_output_index >= num_outs - num_recent_outs) + if (td.m_global_output_index >= num_outs - num_recent_outs && recent_outputs_count > 0) --recent_outputs_count; // if the real out is recent, pick one less recent fake out LOG_PRINT_L1("Using " << recent_outputs_count << " recent outputs"); @@ -3023,6 +3023,9 @@ void wallet2::get_outs(std::vector<std::vector<entry>> &outs, const std::list<si uint64_t r = crypto::rand<uint64_t>() % ((uint64_t)1 << 53); double frac = std::sqrt((double)r / ((uint64_t)1 << 53)); i = (uint64_t)(frac*num_recent_outs) + num_outs - num_recent_outs; + // just in case rounding up to 1 occurs after calc + if (i == num_outs) + --i; LOG_PRINT_L2("picking " << i << " as recent"); } else @@ -3031,11 +3034,11 @@ void wallet2::get_outs(std::vector<std::vector<entry>> &outs, const std::list<si uint64_t r = crypto::rand<uint64_t>() % ((uint64_t)1 << 53); double frac = std::sqrt((double)r / ((uint64_t)1 << 53)); i = (uint64_t)(frac*num_outs); + // just in case rounding up to 1 occurs after calc + if (i == num_outs) + --i; LOG_PRINT_L2("picking " << i << " as triangular"); } - // just in case rounding up to 1 occurs after calc - if (i == num_outs) - --i; if (seen_indices.count(i)) continue; diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h index f0a9ea68b..6fe15d1e3 100644 --- a/src/wallet/wallet2_api.h +++ b/src/wallet/wallet2_api.h @@ -41,6 +41,20 @@ namespace Bitmonero { namespace Utils { bool isAddressLocal(const std::string &hostaddr); } + + template<typename T> + class optional { + public: + optional(): set(false) {} + optional(const T &t): t(t), set(true) {} + const T &operator*() const { return t; } + T &operator*() { return t; } + operator bool() const { return set; } + private: + T t; + bool set; + }; + /** * @brief Transaction-like interface for sending money */ @@ -332,7 +346,7 @@ struct Wallet */ virtual PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id, - uint64_t amount, uint32_t mixin_count, + optional<uint64_t> amount, uint32_t mixin_count, PendingTransaction::Priority = PendingTransaction::Priority_Low) = 0; /*! |