diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ringct/rctTypes.h | 6 | ||||
-rw-r--r-- | src/rpc/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 40 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.h | 1 | ||||
-rw-r--r-- | src/wallet/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 67 | ||||
-rw-r--r-- | src/wallet/api/wallet.h | 11 | ||||
-rw-r--r-- | src/wallet/wallet2_api.h | 9 |
8 files changed, 111 insertions, 26 deletions
diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 71cc61ddc..6b24fc470 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -308,10 +308,10 @@ namespace rct { ar.tag("cc"); FIELDS(MGs[i].cc) // MGs[i].II not saved, it can be reconstructed - if (mg_elements - i > 1) - ar.delimit_array(); - ar.end_object(); + + if (mg_elements - i > 1) + ar.delimit_array(); } ar.end_array(); return true; diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt index 050b5e569..6df93cde1 100644 --- a/src/rpc/CMakeLists.txt +++ b/src/rpc/CMakeLists.txt @@ -46,6 +46,7 @@ target_link_libraries(rpc PUBLIC cryptonote_core cryptonote_protocol + epee ${Boost_THREAD_LIBRARY} PRIVATE ${EXTRA_LIBRARIES}) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 85bdee16f..b46447975 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -663,6 +663,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("locked_transfer", boost::bind(&simple_wallet::locked_transfer, this, _1), tr("locked_transfer [<mixin_count>] <addr> <amount> <lockblocks>(Number of blocks to lock the transaction for, max 1000000) [<payment_id>]")); m_cmd_binder.set_handler("sweep_unmixable", boost::bind(&simple_wallet::sweep_unmixable, this, _1), tr("Send all unmixable outputs to yourself with mixin 0")); m_cmd_binder.set_handler("sweep_all", boost::bind(&simple_wallet::sweep_all, this, _1), tr("sweep_all [mixin] address [payment_id] - Send all unlocked balance an address")); + m_cmd_binder.set_handler("donate", boost::bind(&simple_wallet::donate, this, _1), tr("donate [<mixin_count>] <amount> [payment_id] - Donate <amount> to the development team (donate.getmonero.org)")); m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this, _1), tr("Sign a transaction from a file")); m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), tr("Submit a signed transaction from a file")); m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), tr("set_log <level> - Change current log detail level, <0-4>")); @@ -2826,6 +2827,45 @@ bool simple_wallet::sweep_all(const std::vector<std::string> &args_) return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::donate(const std::vector<std::string> &args_) +{ + std::vector<std::string> local_args = args_; + if(local_args.empty() || local_args.size() > 3) + { + fail_msg_writer() << tr("wrong number of arguments"); + return true; + } + std::string mixin_str; + std::string address_str = "donate.getmonero.org"; + std::string amount_str; + std::string payment_id_str; + // check payment id + crypto::hash payment_id; + crypto::hash8 payment_id8; + if (tools::wallet2::parse_long_payment_id (local_args.back(), payment_id ) || + tools::wallet2::parse_short_payment_id(local_args.back(), payment_id8)) + { + payment_id_str = local_args.back(); + local_args.pop_back(); + } + // check mixin + if (local_args.size() > 1) + { + mixin_str = local_args[0]; + local_args.erase(local_args.begin()); + } + amount_str = local_args[0]; + // refill args as necessary + local_args.clear(); + if (!mixin_str.empty()) + local_args.push_back(mixin_str); + local_args.push_back(address_str); + local_args.push_back(amount_str); + if (!payment_id_str.empty()) + local_args.push_back(payment_id_str); + transfer_new(local_args); +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message) { // gather info to ask the user diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 0d83f429b..420597699 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -124,6 +124,7 @@ namespace cryptonote bool locked_transfer(const std::vector<std::string> &args); bool sweep_all(const std::vector<std::string> &args); bool sweep_unmixable(const std::vector<std::string> &args); + bool donate(const std::vector<std::string> &args); bool sign_transfer(const std::vector<std::string> &args); bool submit_transfer(const std::vector<std::string> &args); std::vector<std::vector<cryptonote::tx_destination_entry>> split_amounts( diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index ba5c6b5ac..056a1ca10 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -34,7 +34,6 @@ set(wallet_sources password_container.cpp wallet2.cpp wallet_args.cpp - wallet_rpc_server.cpp api/wallet.cpp api/wallet_manager.cpp api/transaction_info.cpp @@ -103,6 +102,7 @@ if (NOT BUILD_GUI_DEPS) target_link_libraries(wallet_rpc_server PRIVATE wallet + epee rpc cryptonote_core crypto diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 6d8e48deb..3a4493ec3 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -204,6 +204,7 @@ WalletImpl::WalletImpl(bool testnet) , m_recoveringFromSeed(false) , m_synchronized(false) , m_rebuildWalletCache(false) + , m_is_connected(false) { m_wallet = new tools::wallet2(testnet); m_history = new TransactionHistoryImpl(this); @@ -224,11 +225,19 @@ WalletImpl::WalletImpl(bool testnet) WalletImpl::~WalletImpl() { + + LOG_PRINT_L1(__FUNCTION__); + // Pause refresh thread - prevents refresh from starting again + pauseRefresh(); + // Close wallet - stores cache and stops ongoing refresh operation + close(); + // Stop refresh thread stopRefresh(); + delete m_wallet2Callback; delete m_history; delete m_addressBook; delete m_wallet; - delete m_wallet2Callback; + LOG_PRINT_L1(__FUNCTION__ << " finished"); } bool WalletImpl::create(const std::string &path, const std::string &password, const std::string &language) @@ -329,7 +338,7 @@ bool WalletImpl::close() { bool result = false; - LOG_PRINT_L3("closing wallet..."); + LOG_PRINT_L1("closing wallet..."); try { // Do not store wallet with invalid status // Status Critical refers to errors on opening or creating wallets. @@ -337,10 +346,10 @@ bool WalletImpl::close() m_wallet->store(); else LOG_PRINT_L3("Status_Critical - not storing wallet"); - LOG_PRINT_L3("wallet::store done"); - LOG_PRINT_L3("Calling wallet::stop..."); + LOG_PRINT_L1("wallet::store done"); + LOG_PRINT_L1("Calling wallet::stop..."); m_wallet->stop(); - LOG_PRINT_L3("wallet::stop done"); + LOG_PRINT_L1("wallet::stop done"); result = true; clearStatus(); } catch (const std::exception &e) { @@ -487,6 +496,8 @@ uint64_t WalletImpl::approximateBlockChainHeight() const } uint64_t WalletImpl::daemonBlockChainHeight() const { + if (!m_is_connected) + return 0; std::string err; uint64_t result = m_wallet->get_daemon_blockchain_height(err); if (!err.empty()) { @@ -504,6 +515,8 @@ uint64_t WalletImpl::daemonBlockChainHeight() const uint64_t WalletImpl::daemonBlockChainTargetHeight() const { + if (!m_is_connected) + return 0; std::string err; uint64_t result = m_wallet->get_daemon_blockchain_target_height(err); if (!err.empty()) { @@ -516,9 +529,20 @@ uint64_t WalletImpl::daemonBlockChainTargetHeight() const m_status = Status_Ok; m_errorString = ""; } + // Target height can be 0 when daemon is synced. Use blockchain height instead. + if(result == 0) + result = daemonBlockChainHeight(); return result; } +bool WalletImpl::daemonSynced() const +{ + if(connected() == Wallet::ConnectionStatus_Disconnected) + return false; + uint64_t blockChainHeight = daemonBlockChainHeight(); + return (blockChainHeight >= daemonBlockChainTargetHeight() && blockChainHeight > 1); +} + bool WalletImpl::synchronized() const { return m_synchronized; @@ -924,8 +948,8 @@ bool WalletImpl::connectToDaemon() Wallet::ConnectionStatus WalletImpl::connected() const { uint32_t version = 0; - bool is_connected = m_wallet->check_connection(&version); - if (!is_connected) + m_is_connected = m_wallet->check_connection(&version); + if (!m_is_connected) return Wallet::ConnectionStatus_Disconnected; if ((version >> 16) != CORE_RPC_VERSION_MAJOR) return Wallet::ConnectionStatus_WrongVersion; @@ -970,7 +994,7 @@ void WalletImpl::refreshThreadFunc() LOG_PRINT_L3(__FUNCTION__ << ": refresh lock acquired..."); LOG_PRINT_L3(__FUNCTION__ << ": m_refreshEnabled: " << m_refreshEnabled); LOG_PRINT_L3(__FUNCTION__ << ": m_status: " << m_status); - if (m_refreshEnabled /*&& m_status == Status_Ok*/) { + if (m_refreshEnabled) { LOG_PRINT_L3(__FUNCTION__ << ": refreshing..."); doRefresh(); } @@ -983,16 +1007,23 @@ void WalletImpl::doRefresh() // synchronizing async and sync refresh calls boost::lock_guard<boost::mutex> guarg(m_refreshMutex2); try { - m_wallet->refresh(); - if (!m_synchronized) { - m_synchronized = true; - } - // assuming if we have empty history, it wasn't initialized yet - // for futher history changes client need to update history in - // "on_money_received" and "on_money_sent" callbacks - if (m_history->count() == 0) { - m_history->refresh(); - } + // Syncing daemon and refreshing wallet simultaneously is very resource intensive. + // Disable refresh if wallet is disconnected or daemon isn't synced. + if (daemonSynced()) { + // Use fast refresh for new wallets + if (isNewWallet()) + m_wallet->set_refresh_from_block_height(daemonBlockChainHeight()); + m_wallet->refresh(); + if (!m_synchronized) { + m_synchronized = true; + } + // assuming if we have empty history, it wasn't initialized yet + // for futher history changes client need to update history in + // "on_money_received" and "on_money_sent" callbacks + if (m_history->count() == 0) { + m_history->refresh(); + } + } } catch (const std::exception &e) { m_status = Status_Error; m_errorString = e.what(); diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 5046fbf0f..d245a78d0 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -107,14 +107,15 @@ public: virtual std::string getTxKey(const std::string &txid) const; virtual std::string signMessage(const std::string &message); virtual bool verifySignedMessage(const std::string &message, const std::string &address, const std::string &signature) const; + virtual void startRefresh(); + virtual void pauseRefresh(); private: void clearStatus(); void refreshThreadFunc(); void doRefresh(); - void startRefresh(); + bool daemonSynced() const; void stopRefresh(); - void pauseRefresh(); bool isNewWallet() const; void doInit(const std::string &daemon_address, uint64_t upper_transaction_size_limit); @@ -148,9 +149,11 @@ private: // flag indicating wallet is recovering from seed // so it shouldn't be considered as new and pull blocks (slow-refresh) // instead of pulling hashes (fast-refresh) - bool m_recoveringFromSeed; + std::atomic<bool> m_recoveringFromSeed; std::atomic<bool> m_synchronized; - bool m_rebuildWalletCache; + std::atomic<bool> m_rebuildWalletCache; + // cache connection status to avoid unnecessary RPC calls + mutable std::atomic<bool> m_is_connected; }; diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h index 4ba829421..6651b876d 100644 --- a/src/wallet/wallet2_api.h +++ b/src/wallet/wallet2_api.h @@ -364,6 +364,15 @@ struct Wallet static std::string paymentIdFromAddress(const std::string &str, bool testnet); static uint64_t maximumAllowedAmount(); + /** + * @brief StartRefresh - Start/resume refresh thread (refresh every 10 seconds) + */ + virtual void startRefresh() = 0; + /** + * @brief pauseRefresh - pause refresh thread + */ + virtual void pauseRefresh() = 0; + /** * @brief refresh - refreshes the wallet, updating transactions from daemon * @return - true if refreshed successfully; |