aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/api/wallet.cpp40
-rw-r--r--src/wallet/api/wallet.h3
-rw-r--r--src/wallet/wallet2.cpp15
-rw-r--r--src/wallet/wallet2_api.h16
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;
/*!