From 87ed25a701aee65f93863a85d5a8c2048276e959 Mon Sep 17 00:00:00 2001 From: Adrian Herridge Date: Mon, 22 Jan 2018 22:01:01 +0000 Subject: [PATCH] Added reset to wallet & RPC. Supply a blockchain height to save time resync wallet from the start. Also fixed bug where reset would not pick up old transactions. --- include/IWalletLegacy.h | 3 +- src/SimpleWallet/SimpleWallet.cpp | 26 +++++++++++++-- src/SimpleWallet/SimpleWallet.h | 1 + src/Wallet/WalletRpcServer.cpp | 33 ++++++++++++------- src/Wallet/WalletRpcServer.h | 9 ++--- .../WalletRpcServerCommandsDefinitions.h | 16 +++++++++ src/WalletLegacy/WalletLegacy.cpp | 19 +++++++++-- src/WalletLegacy/WalletLegacy.h | 6 ++-- 8 files changed, 89 insertions(+), 24 deletions(-) diff --git a/include/IWalletLegacy.h b/include/IWalletLegacy.h index 0864e84c93..f91d69c294 100755 --- a/include/IWalletLegacy.h +++ b/include/IWalletLegacy.h @@ -88,6 +88,7 @@ class IWalletLegacy { virtual void initWithKeys(const AccountKeys& accountKeys, const std::string& password) = 0; virtual void shutdown() = 0; virtual void reset() = 0; + virtual void reset(uint64_t height) = 0; virtual void save(std::ostream& destination, bool saveDetailed = true, bool saveCache = true) = 0; @@ -111,7 +112,7 @@ class IWalletLegacy { virtual std::error_code cancelTransaction(size_t transferId) = 0; virtual void getAccountKeys(AccountKeys& keys) = 0; - virtual void syncAll(bool syncWalletFromZero = 0) = 0; + virtual void syncAll(bool syncWalletFromZero = 0, uint64_t height = 0) = 0; }; } diff --git a/src/SimpleWallet/SimpleWallet.cpp b/src/SimpleWallet/SimpleWallet.cpp index b98f5af922..2ff58e88ce 100755 --- a/src/SimpleWallet/SimpleWallet.cpp +++ b/src/SimpleWallet/SimpleWallet.cpp @@ -559,6 +559,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { std::string walletFileName; sync_from_zero = command_line::get_arg(vm, arg_SYNC_FROM_ZERO); + if (sync_from_zero) { + sync_from_height = 0; + } if (!m_generate_new.empty() || !m_import_new.empty()) { std::string ignoredString; if (!m_generate_new.empty()) { @@ -611,6 +614,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { } sync_from_zero = command_line::get_arg(vm, arg_SYNC_FROM_ZERO); + if (sync_from_zero) { + sync_from_height = 0; + } if (!m_generate_new.empty()) { std::string walletAddressFile = prepareWalletAddressFilename(m_generate_new); boost::system::error_code ignore; @@ -672,7 +678,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { m_wallet.reset(new WalletLegacy(m_currency, *m_node)); - m_wallet->syncAll(sync_from_zero); + m_wallet->syncAll(sync_from_zero, 0); try { m_wallet_file = tryToOpenWalletOrLoadKeysOrThrow(logger, m_wallet, m_wallet_file_arg, pwd_container.password()); @@ -723,7 +729,7 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string try { m_initResultPromise.reset(new std::promise()); std::future f_initError = m_initResultPromise->get_future(); - m_wallet->syncAll(sync_from_zero); + m_wallet->syncAll(sync_from_zero, 0); m_wallet->initAndGenerate(password); auto initError = f_initError.get(); m_initResultPromise.reset(nullptr); @@ -849,7 +855,21 @@ bool simple_wallet::reset(const std::vector &args) { m_walletSynchronized = false; } - m_wallet->reset(); + if(0 == args.size()) { + success_msg_writer(true) << "Resetting wallet from block height 0"; + m_wallet->syncAll(true, 0); + m_wallet->reset(); + } else { + uint64_t height = 0; + bool ok = Common::fromString(args[0], height); + if (ok) { + success_msg_writer(true) << "Resetting wallet from block height " << height; + m_wallet->syncAll(true, height); + m_wallet->reset(height); + } + } + + success_msg_writer(true) << "Reset completed successfully."; std::unique_lock lock(m_walletSynchronizedMutex); diff --git a/src/SimpleWallet/SimpleWallet.h b/src/SimpleWallet/SimpleWallet.h index 8ce3138a04..77d09c84b7 100755 --- a/src/SimpleWallet/SimpleWallet.h +++ b/src/SimpleWallet/SimpleWallet.h @@ -165,6 +165,7 @@ std::string m_import_new; std::string m_wallet_file; bool sync_from_zero; + uint64_t sync_from_height; std::unique_ptr> m_initResultPromise; diff --git a/src/Wallet/WalletRpcServer.cpp b/src/Wallet/WalletRpcServer.cpp index f562d060e6..859782d5b6 100755 --- a/src/Wallet/WalletRpcServer.cpp +++ b/src/Wallet/WalletRpcServer.cpp @@ -43,19 +43,19 @@ void wallet_rpc_server::init_options(boost::program_options::options_description } //------------------------------------------------------------------------------------------------------------------------------ wallet_rpc_server::wallet_rpc_server( - System::Dispatcher& dispatcher, - Logging::ILogger& log, + System::Dispatcher& dispatcher, + Logging::ILogger& log, CryptoNote::IWalletLegacy&w, - CryptoNote::INode& n, - CryptoNote::Currency& currency, + CryptoNote::INode& n, + CryptoNote::Currency& currency, const std::string& walletFile) - : - HttpServer(dispatcher, log), - logger(log, "WalletRpc"), - m_dispatcher(dispatcher), - m_stopComplete(dispatcher), + : + HttpServer(dispatcher, log), + logger(log, "WalletRpc"), + m_dispatcher(dispatcher), + m_stopComplete(dispatcher), m_wallet(w), - m_node(n), + m_node(n), m_currency(currency), m_walletFilename(walletFile) { } @@ -108,7 +108,11 @@ void wallet_rpc_server::processRequest(const CryptoNote::HttpRequest& request, C { "get_payments", makeMemberMethod(&wallet_rpc_server::on_get_payments) }, { "get_transfers", makeMemberMethod(&wallet_rpc_server::on_get_transfers) }, { "get_height", makeMemberMethod(&wallet_rpc_server::on_get_height) }, - { "reset", makeMemberMethod(&wallet_rpc_server::on_reset) } + { "reset", makeMemberMethod(&wallet_rpc_server::on_reset) }, + { "reset_from", makeMemberMethod(&wallet_rpc_server::on_reset_from) } + //{ "stop_wallet", makeMemberMethod(&wallet_rpc_server::on_stop_wallet) }, + //{ "get_address", makeMemberMethod(&wallet_rpc_server::on_get_address) }, + //{ "view_keys", makeMemberMethod(&wallet_rpc_server::on_view_keys) } }; auto it = s_methods.find(jsonRequest.getMethod()); @@ -149,7 +153,7 @@ bool wallet_rpc_server::on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::requ Crypto::Hash payment_id; if (!CryptoNote::parsePaymentId(payment_id_str, payment_id)) { - throw JsonRpc::JsonRpcError(WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID, + throw JsonRpc::JsonRpcError(WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID, "Payment id has invalid format: \"" + payment_id_str + "\", expected 64-character string"); } @@ -292,4 +296,9 @@ bool wallet_rpc_server::on_reset(const wallet_rpc::COMMAND_RPC_RESET::request& r return true; } +bool wallet_rpc_server::on_reset_from(const wallet_rpc::COMMAND_RPC_RESET_FROM::request& req, wallet_rpc::COMMAND_RPC_RESET_FROM::response& res) { + m_wallet.reset(); + return true; +} + } diff --git a/src/Wallet/WalletRpcServer.h b/src/Wallet/WalletRpcServer.h index 1f7f2ef960..623901b937 100755 --- a/src/Wallet/WalletRpcServer.h +++ b/src/Wallet/WalletRpcServer.h @@ -37,17 +37,17 @@ namespace Tools public: wallet_rpc_server( - System::Dispatcher& dispatcher, + System::Dispatcher& dispatcher, Logging::ILogger& log, - CryptoNote::IWalletLegacy &w, - CryptoNote::INode &n, + CryptoNote::IWalletLegacy &w, + CryptoNote::INode &n, CryptoNote::Currency& currency, const std::string& walletFilename); static void init_options(boost::program_options::options_description& desc); bool init(const boost::program_options::variables_map& vm); - + bool run(); void send_stop_signal(); @@ -66,6 +66,7 @@ namespace Tools bool on_get_transfers(const wallet_rpc::COMMAND_RPC_GET_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFERS::response& res); bool on_get_height(const wallet_rpc::COMMAND_RPC_GET_HEIGHT::request& req, wallet_rpc::COMMAND_RPC_GET_HEIGHT::response& res); bool on_reset(const wallet_rpc::COMMAND_RPC_RESET::request& req, wallet_rpc::COMMAND_RPC_RESET::response& res); + bool on_reset_from(const wallet_rpc::COMMAND_RPC_RESET_FROM::request& req, wallet_rpc::COMMAND_RPC_RESET_FROM::response& res); bool handle_command_line(const boost::program_options::variables_map& vm); diff --git a/src/Wallet/WalletRpcServerCommandsDefinitions.h b/src/Wallet/WalletRpcServerCommandsDefinitions.h index 82f7b42d7f..937a29277b 100755 --- a/src/Wallet/WalletRpcServerCommandsDefinitions.h +++ b/src/Wallet/WalletRpcServerCommandsDefinitions.h @@ -182,5 +182,21 @@ using CryptoNote::ISerializer; typedef CryptoNote::EMPTY_STRUCT request; typedef CryptoNote::EMPTY_STRUCT response; }; + + struct COMMAND_RPC_RESET_FROM { + + struct request + { + uint64_t height; + + void serialize(ISerializer& s) { + KV_MEMBER(height) + } + }; + + typedef CryptoNote::EMPTY_STRUCT response; + + }; + } } diff --git a/src/WalletLegacy/WalletLegacy.cpp b/src/WalletLegacy/WalletLegacy.cpp index 3b3f243aa2..944ff783cb 100755 --- a/src/WalletLegacy/WalletLegacy.cpp +++ b/src/WalletLegacy/WalletLegacy.cpp @@ -203,8 +203,12 @@ void WalletLegacy::initSync() { sub.transactionSpendableAge = 1; sub.syncStart.height = 0; sub.syncStart.timestamp = m_account.get_createtime() - ACCOUN_CREATE_TIME_ACCURACY; - if (m_syncAll == 1) + if (m_syncAll == 1) { sub.syncStart.timestamp = 0; + if (m_syncStartHeight) { + sub.syncStart.height = m_syncStartHeight; + } + } std::cout << "Sync from timestamp: " << sub.syncStart.timestamp << std::endl; auto& subObject = m_transfersSync.addSubscription(sub); @@ -311,6 +315,12 @@ void WalletLegacy::reset() { } } +void WalletLegacy::reset(uint64_t height) { + m_syncAll = 1; + m_syncStartHeight = height; + reset(); +} + void WalletLegacy::save(std::ostream& destination, bool saveDetailed, bool saveCache) { if(m_isStopping) { m_observerManager.notify(&IWalletLegacyObserver::saveCompleted, make_error_code(CryptoNote::error::OPERATION_CANCELLED)); @@ -598,8 +608,13 @@ void WalletLegacy::notifyIfBalanceChanged() { } -void WalletLegacy::syncAll(bool syncWalletFromZero) { +void WalletLegacy::syncAll(bool syncWalletFromZero, uint64_t height) { m_syncAll = syncWalletFromZero; + if (height) { + m_syncStartHeight = height; + } else { + m_syncStartHeight = 0; + } } void WalletLegacy::getAccountKeys(AccountKeys& keys) { if (m_state == NOT_INITIALIZED) { diff --git a/src/WalletLegacy/WalletLegacy.h b/src/WalletLegacy/WalletLegacy.h index f93e55df69..5067b17941 100755 --- a/src/WalletLegacy/WalletLegacy.h +++ b/src/WalletLegacy/WalletLegacy.h @@ -62,6 +62,7 @@ class WalletLegacy : virtual void initWithKeys(const AccountKeys& accountKeys, const std::string& password) override; virtual void shutdown() override; virtual void reset() override; + virtual void reset(uint64_t height) override; virtual void save(std::ostream& destination, bool saveDetailed = true, bool saveCache = true) override; @@ -84,7 +85,7 @@ class WalletLegacy : virtual TransactionId sendTransaction(const std::vector& transfers, uint64_t fee, const std::string& extra = "", uint64_t mixIn = 0, uint64_t unlockTimestamp = 0) override; virtual std::error_code cancelTransaction(size_t transactionId) override; - void syncAll(bool syncWalletFromZero) override; + void syncAll(bool syncWalletFromZero, uint64_t height) override; virtual void getAccountKeys(AccountKeys& keys) override; private: @@ -141,7 +142,8 @@ class WalletLegacy : Tools::ObserverManager m_observerManager; std::unique_ptr m_onInitSyncStarter; -bool m_syncAll = 0; + bool m_syncAll = 0; + uint64_t m_syncStartHeight = 0; }; } //namespace CryptoNote