From 4789347b27a9a7b42ef67e789cb85a438e970ca6 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Wed, 28 Sep 2016 01:36:49 +0300 Subject: [PATCH 1/5] libwallet_api: test for create/init wallet on mainnet --- tests/libwallet_api_tests/main.cpp | 53 ++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/tests/libwallet_api_tests/main.cpp b/tests/libwallet_api_tests/main.cpp index 87e0cc935..ad61a1032 100644 --- a/tests/libwallet_api_tests/main.cpp +++ b/tests/libwallet_api_tests/main.cpp @@ -58,6 +58,7 @@ namespace Consts // TODO: get rid of hardcoded paths const char * WALLET_NAME = "testwallet"; +const char * WALLET_NAME_MAINNET = "testwallet_mainnet"; const char * WALLET_NAME_COPY = "testwallet_copy"; const char * WALLET_NAME_WITH_DIR = "walletdir/testwallet_test"; const char * WALLET_NAME_WITH_DIR_NON_WRITABLE = "/var/walletdir/testwallet_test"; @@ -85,6 +86,7 @@ const uint64_t AMOUNT_1XMR = 1000000000000L; const std::string PAYMENT_ID_EMPTY = ""; std::string TESTNET_DAEMON_ADDRESS = "localhost:38081"; +std::string MAINNET_DAEMON_ADDRESS = "localhost:18081"; } @@ -157,6 +159,25 @@ struct WalletManagerTest : public testing::Test }; +struct WalletManagerMainnetTest : public testing::Test +{ + Bitmonero::WalletManager * wmgr; + + + WalletManagerMainnetTest() + { + std::cout << __FUNCTION__ << std::endl; + wmgr = Bitmonero::WalletManagerFactory::getWalletManager(); + Utils::deleteWallet(WALLET_NAME_MAINNET); + } + + + ~WalletManagerMainnetTest() + { + std::cout << __FUNCTION__ << std::endl; + } + +}; struct WalletTest1 : public testing::Test { @@ -871,6 +892,7 @@ TEST_F(WalletTest2, WalletCallBackRefreshedAsync) + TEST_F(WalletTest2, WalletCallbackSent) { @@ -984,17 +1006,42 @@ TEST_F(WalletTest2, WalletCallbackNewBlock) } +TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNet) +{ + + Bitmonero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); + MyWalletListener * wallet_listener = new MyWalletListener(wallet); + std::chrono::seconds wait_for = std::chrono::seconds(30); + std::unique_lock lock (wallet_listener->mutex); + wallet->initAsync(MAINNET_DAEMON_ADDRESS, 0); + std::cerr << "TEST: waiting on refresh lock...\n"; + wallet_listener->cv_refresh.wait_for(lock, wait_for); + std::cerr << "TEST: refresh lock acquired...\n"; + ASSERT_TRUE(wallet_listener->refresh_triggered); + ASSERT_TRUE(wallet->connected()); + ASSERT_TRUE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight()); + std::cerr << "TEST: closing wallet...\n"; + wmgr->closeWallet(wallet); +} + int main(int argc, char** argv) { // we can override default values for "TESTNET_DAEMON_ADDRESS" and "WALLETS_ROOT_DIR" - const char * monero_daemon_addr = std::getenv("TESTNET_DAEMON_ADDRESS"); - if (monero_daemon_addr) { - TESTNET_DAEMON_ADDRESS = monero_daemon_addr; + const char * testnet_daemon_addr = std::getenv("TESTNET_DAEMON_ADDRESS"); + if (testnet_daemon_addr) { + TESTNET_DAEMON_ADDRESS = testnet_daemon_addr; } + const char * mainnet_daemon_addr = std::getenv("MAINNET_DAEMON_ADDRESS"); + if (mainnet_daemon_addr) { + MAINNET_DAEMON_ADDRESS = mainnet_daemon_addr; + } + + + const char * wallets_root_dir = std::getenv("WALLETS_ROOT_DIR"); if (wallets_root_dir) { WALLETS_ROOT_DIR = wallets_root_dir; From 1f73f80c94f2f60990abd2e07f4e75eb59112b30 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Fri, 30 Sep 2016 02:11:28 +0300 Subject: [PATCH 2/5] libwallet_api: fast-refresh for new wallet --- src/wallet/api/wallet.cpp | 34 ++++++++++++++++++++++-------- src/wallet/api/wallet.h | 3 +++ tests/libwallet_api_tests/main.cpp | 31 ++++++++++++++++++++++++--- 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index eefb49e95..55b13ba7e 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -175,6 +175,7 @@ WalletImpl::WalletImpl(bool testnet) m_wallet->callback(m_wallet2Callback); m_refreshThreadDone = false; m_refreshEnabled = false; + m_newWallet = true; m_refreshIntervalMillis = DEFAULT_REFRESH_INTERVAL_MILLIS; @@ -195,6 +196,7 @@ WalletImpl::~WalletImpl() bool WalletImpl::create(const std::string &path, const std::string &password, const std::string &language) { + m_newWallet = true; clearStatus(); bool keys_file_exists; @@ -232,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) { + m_newWallet = false; clearStatus(); try { // TODO: handle "deprecated" @@ -385,11 +388,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(); @@ -400,10 +399,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(); } @@ -748,4 +744,24 @@ void WalletImpl::pauseRefresh() } +bool WalletImpl::isNewWallet() const +{ + return m_newWallet; +} + +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 diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index d97a8f3b3..e2eb05167 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -101,6 +101,8 @@ private: void startRefresh(); void stopRefresh(); void pauseRefresh(); + bool isNewWallet() const; + void doInit(const std::string &daemon_address, uint64_t upper_transaction_size_limit); private: friend class PendingTransactionImpl; @@ -126,6 +128,7 @@ private: boost::mutex m_refreshMutex2; boost::condition_variable m_refreshCV; boost::thread m_refreshThread; + bool m_newWallet; }; diff --git a/tests/libwallet_api_tests/main.cpp b/tests/libwallet_api_tests/main.cpp index ad61a1032..42445d53a 100644 --- a/tests/libwallet_api_tests/main.cpp +++ b/tests/libwallet_api_tests/main.cpp @@ -830,8 +830,12 @@ struct MyWalletListener : public Bitmonero::WalletListener virtual void newBlock(uint64_t height) { - std::cout << "wallet: " << wallet->address() - <<", new block received, blockHeight: " << height << std::endl; +// std::cout << "wallet: " << wallet->address() +// <<", new block received, blockHeight: " << height << std::endl; + static int bc_height = wallet->daemonBlockChainHeight(); + std::cout << height + << " / " << bc_height/* 0*/ + << std::endl; newblock_triggered = true; cv_newblock.notify_one(); } @@ -1006,7 +1010,27 @@ TEST_F(WalletTest2, WalletCallbackNewBlock) } -TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNet) +TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNetSync) +{ + + Bitmonero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); + MyWalletListener * wallet_listener = new MyWalletListener(wallet); + std::chrono::seconds wait_for = std::chrono::seconds(30); + std::unique_lock lock (wallet_listener->mutex); + // wallet->initAsync(MAINNET_DAEMON_ADDRESS, 0); + wallet->init(MAINNET_DAEMON_ADDRESS, 0); + std::cerr << "TEST: waiting on refresh lock...\n"; + //wallet_listener->cv_refresh.wait_for(lock, wait_for); + std::cerr << "TEST: refresh lock acquired...\n"; + ASSERT_TRUE(wallet_listener->refresh_triggered); + ASSERT_TRUE(wallet->connected()); + ASSERT_TRUE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight()); + std::cerr << "TEST: closing wallet...\n"; + wmgr->closeWallet(wallet); +} + + +TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNetAsync) { Bitmonero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); @@ -1014,6 +1038,7 @@ TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNet) std::chrono::seconds wait_for = std::chrono::seconds(30); std::unique_lock lock (wallet_listener->mutex); wallet->initAsync(MAINNET_DAEMON_ADDRESS, 0); + // wallet->init(MAINNET_DAEMON_ADDRESS, 0); std::cerr << "TEST: waiting on refresh lock...\n"; wallet_listener->cv_refresh.wait_for(lock, wait_for); std::cerr << "TEST: refresh lock acquired...\n"; From 0019e3106bffcdb269af56de13ecababe545b395 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Fri, 30 Sep 2016 21:43:57 +0300 Subject: [PATCH 3/5] libwallet_api: fix unhandled exception on address check --- src/wallet/api/utils.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/wallet/api/utils.cpp b/src/wallet/api/utils.cpp index aa85323f0..1bf35197c 100644 --- a/src/wallet/api/utils.cpp +++ b/src/wallet/api/utils.cpp @@ -56,18 +56,22 @@ bool isAddressLocal(const std::string &address) LOG_PRINT_L1("Failed to determine whether daemon is local, assuming not"); return false; } - - // resolve to IP - boost::asio::io_service io_service; - boost::asio::ip::tcp::resolver resolver(io_service); - boost::asio::ip::tcp::resolver::query query(u_c.host, ""); - boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); - while (i != boost::asio::ip::tcp::resolver::iterator()) - { - const boost::asio::ip::tcp::endpoint &ep = *i; - if (ep.address().is_loopback()) - return true; - ++i; + // resolver::resolve can throw an exception + try { + // resolve to IP + boost::asio::io_service io_service; + boost::asio::ip::tcp::resolver resolver(io_service); + boost::asio::ip::tcp::resolver::query query(u_c.host, ""); + boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); + while (i != boost::asio::ip::tcp::resolver::iterator()) + { + const boost::asio::ip::tcp::endpoint &ep = *i; + if (ep.address().is_loopback()) + return true; + ++i; + } + } catch (const boost::system::system_error &e) { + LOG_ERROR("Failed to resolve " << address << ", :" << e.what()); } return false; From 10fe626e13297d9712763a51174cd6437185e53d Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Fri, 30 Sep 2016 22:42:15 +0300 Subject: [PATCH 4/5] libwallet_api: fast-refresh in case of opening non-synced wallet --- src/wallet/api/wallet.cpp | 9 +++++---- src/wallet/api/wallet.h | 2 -- tests/libwallet_api_tests/main.cpp | 26 +++++++++++++++++++++++++- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 55b13ba7e..9bb7f0569 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -175,7 +175,7 @@ WalletImpl::WalletImpl(bool testnet) m_wallet->callback(m_wallet2Callback); m_refreshThreadDone = false; m_refreshEnabled = false; - m_newWallet = true; + m_refreshIntervalMillis = DEFAULT_REFRESH_INTERVAL_MILLIS; @@ -196,7 +196,6 @@ WalletImpl::~WalletImpl() bool WalletImpl::create(const std::string &path, const std::string &password, const std::string &language) { - m_newWallet = true; clearStatus(); bool keys_file_exists; @@ -234,7 +233,6 @@ bool WalletImpl::create(const std::string &path, const std::string &password, co bool WalletImpl::open(const std::string &path, const std::string &password) { - m_newWallet = false; clearStatus(); try { // TODO: handle "deprecated" @@ -746,7 +744,10 @@ void WalletImpl::pauseRefresh() bool WalletImpl::isNewWallet() const { - return m_newWallet; + // 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); } 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 e2eb05167..09db05d08 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -128,8 +128,6 @@ private: boost::mutex m_refreshMutex2; boost::condition_variable m_refreshCV; boost::thread m_refreshThread; - bool m_newWallet; - }; diff --git a/tests/libwallet_api_tests/main.cpp b/tests/libwallet_api_tests/main.cpp index 42445d53a..a4b881407 100644 --- a/tests/libwallet_api_tests/main.cpp +++ b/tests/libwallet_api_tests/main.cpp @@ -1030,7 +1030,7 @@ TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNetSync) } -TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNetAsync) +TEST_F(WalletManagerMainnetTest, CreateAndRefreshWalletMainNetAsync) { Bitmonero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); @@ -1049,6 +1049,30 @@ TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNetAsync) wmgr->closeWallet(wallet); } +TEST_F(WalletManagerMainnetTest, OpenAndRefreshWalletMainNetAsync) +{ + + Bitmonero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); + + wmgr->closeWallet(wallet); + wallet = wmgr->openWallet(WALLET_NAME_MAINNET, ""); + + MyWalletListener * wallet_listener = new MyWalletListener(wallet); + std::chrono::seconds wait_for = std::chrono::seconds(30); + std::unique_lock lock (wallet_listener->mutex); + wallet->initAsync(MAINNET_DAEMON_ADDRESS, 0); + // wallet->init(MAINNET_DAEMON_ADDRESS, 0); + std::cerr << "TEST: waiting on refresh lock...\n"; + wallet_listener->cv_refresh.wait_for(lock, wait_for); + std::cerr << "TEST: refresh lock acquired...\n"; + ASSERT_TRUE(wallet_listener->refresh_triggered); + ASSERT_TRUE(wallet->connected()); + ASSERT_TRUE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight()); + std::cerr << "TEST: closing wallet...\n"; + wmgr->closeWallet(wallet); +} + + int main(int argc, char** argv) From 8b20cbfa7dcdae314ae8090b3fe0bd83deae0116 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sat, 1 Oct 2016 21:04:49 +0300 Subject: [PATCH 5/5] libwallet_api: do not use fast-refresh on recovery --- src/wallet/api/wallet.cpp | 9 +++-- src/wallet/api/wallet.h | 4 ++ tests/libwallet_api_tests/main.cpp | 64 +++++++++++++++++++++++++----- 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 9bb7f0569..16321a5a2 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -167,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); @@ -197,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); @@ -234,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); @@ -258,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)) { @@ -270,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(); @@ -747,7 +750,7 @@ 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); + return !(blockChainHeight() > 1 || m_recoveringFromSeed); } 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 09db05d08..5706b2bf5 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -128,6 +128,10 @@ private: boost::mutex m_refreshMutex2; boost::condition_variable m_refreshCV; boost::thread m_refreshThread; + // 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; }; diff --git a/tests/libwallet_api_tests/main.cpp b/tests/libwallet_api_tests/main.cpp index a4b881407..45a94b4dd 100644 --- a/tests/libwallet_api_tests/main.cpp +++ b/tests/libwallet_api_tests/main.cpp @@ -950,7 +950,7 @@ TEST_F(WalletTest2, WalletCallbackReceived) ASSERT_TRUE(wallet_dst->refresh()); uint64_t balance = wallet_dst->balance(); std::cout << "** Balance dst1: " << wallet_dst->displayAmount(wallet_dst->balance()) << std::endl; - MyWalletListener * wallet_dst_listener = new MyWalletListener(wallet_dst); + std::unique_ptr wallet_dst_listener (new MyWalletListener(wallet_dst)); uint64_t amount = AMOUNT_1XMR * 5; std::cout << "** Sending " << Bitmonero::Wallet::displayAmount(amount) << " to " << wallet_dst->address(); @@ -994,7 +994,7 @@ TEST_F(WalletTest2, WalletCallbackNewBlock) std::cout << "** Block height: " << bc1 << std::endl; - MyWalletListener * wallet_listener = new MyWalletListener(wallet_src); + std::unique_ptr wallet_listener (new MyWalletListener(wallet_src)); // wait max 4 min for new block std::chrono::seconds wait_for = std::chrono::seconds(60*4); @@ -1014,10 +1014,7 @@ TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNetSync) { Bitmonero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); - MyWalletListener * wallet_listener = new MyWalletListener(wallet); - std::chrono::seconds wait_for = std::chrono::seconds(30); - std::unique_lock lock (wallet_listener->mutex); - // wallet->initAsync(MAINNET_DAEMON_ADDRESS, 0); + std::unique_ptr wallet_listener (new MyWalletListener(wallet)); wallet->init(MAINNET_DAEMON_ADDRESS, 0); std::cerr << "TEST: waiting on refresh lock...\n"; //wallet_listener->cv_refresh.wait_for(lock, wait_for); @@ -1032,16 +1029,20 @@ TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNetSync) TEST_F(WalletManagerMainnetTest, CreateAndRefreshWalletMainNetAsync) { + // supposing 120 seconds should be enough for fast refresh + int SECONDS_TO_REFRESH = 120; Bitmonero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); - MyWalletListener * wallet_listener = new MyWalletListener(wallet); - std::chrono::seconds wait_for = std::chrono::seconds(30); + std::unique_ptr wallet_listener (new MyWalletListener(wallet)); + + std::chrono::seconds wait_for = std::chrono::seconds(SECONDS_TO_REFRESH); std::unique_lock lock (wallet_listener->mutex); wallet->initAsync(MAINNET_DAEMON_ADDRESS, 0); // wallet->init(MAINNET_DAEMON_ADDRESS, 0); std::cerr << "TEST: waiting on refresh lock...\n"; wallet_listener->cv_refresh.wait_for(lock, wait_for); std::cerr << "TEST: refresh lock acquired...\n"; + ASSERT_TRUE(wallet->status() == Bitmonero::Wallet::Status_Ok); ASSERT_TRUE(wallet_listener->refresh_triggered); ASSERT_TRUE(wallet->connected()); ASSERT_TRUE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight()); @@ -1052,26 +1053,67 @@ TEST_F(WalletManagerMainnetTest, CreateAndRefreshWalletMainNetAsync) TEST_F(WalletManagerMainnetTest, OpenAndRefreshWalletMainNetAsync) { + // supposing 120 seconds should be enough for fast refresh + int SECONDS_TO_REFRESH = 120; Bitmonero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); - wmgr->closeWallet(wallet); wallet = wmgr->openWallet(WALLET_NAME_MAINNET, ""); - MyWalletListener * wallet_listener = new MyWalletListener(wallet); - std::chrono::seconds wait_for = std::chrono::seconds(30); + std::unique_ptr wallet_listener (new MyWalletListener(wallet)); + + std::chrono::seconds wait_for = std::chrono::seconds(SECONDS_TO_REFRESH); std::unique_lock lock (wallet_listener->mutex); wallet->initAsync(MAINNET_DAEMON_ADDRESS, 0); // wallet->init(MAINNET_DAEMON_ADDRESS, 0); std::cerr << "TEST: waiting on refresh lock...\n"; wallet_listener->cv_refresh.wait_for(lock, wait_for); std::cerr << "TEST: refresh lock acquired...\n"; + ASSERT_TRUE(wallet->status() == Bitmonero::Wallet::Status_Ok); ASSERT_TRUE(wallet_listener->refresh_triggered); ASSERT_TRUE(wallet->connected()); ASSERT_TRUE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight()); std::cerr << "TEST: closing wallet...\n"; wmgr->closeWallet(wallet); + } +TEST_F(WalletManagerMainnetTest, RecoverAndRefreshWalletMainNetAsync) +{ + + // supposing 120 seconds should be enough for fast refresh + int SECONDS_TO_REFRESH = 120; + Bitmonero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG); + std::string seed = wallet->seed(); + std::string address = wallet->address(); + wmgr->closeWallet(wallet); + + // deleting wallet files + Utils::deleteWallet(WALLET_NAME_MAINNET); + // ..and recovering wallet from seed + + wallet = wmgr->recoveryWallet(WALLET_NAME_MAINNET, seed); + ASSERT_TRUE(wallet->status() == Bitmonero::Wallet::Status_Ok); + ASSERT_TRUE(wallet->address() == address); + std::unique_ptr wallet_listener (new MyWalletListener(wallet)); + std::chrono::seconds wait_for = std::chrono::seconds(SECONDS_TO_REFRESH); + std::unique_lock lock (wallet_listener->mutex); + wallet->initAsync(MAINNET_DAEMON_ADDRESS, 0); + // wallet->init(MAINNET_DAEMON_ADDRESS, 0); + std::cerr << "TEST: waiting on refresh lock...\n"; + + // here we wait for 120 seconds and test if wallet doesn't syncrnonize blockchain completely, + // as it needs much more than 120 seconds for mainnet + + wallet_listener->cv_refresh.wait_for(lock, wait_for); + ASSERT_TRUE(wallet->status() == Bitmonero::Wallet::Status_Ok); + ASSERT_FALSE(wallet_listener->refresh_triggered); + ASSERT_TRUE(wallet->connected()); + ASSERT_FALSE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight()); + std::cerr << "TEST: closing wallet...\n"; + wmgr->closeWallet(wallet); + std::cerr << "TEST: wallet closed\n"; + +}