Electroneum
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1// Copyrights(c) 2017-2021, The Electroneum Project
2// Copyrights(c) 2014-2019, The Monero Project
3//
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without modification, are
7// permitted provided that the following conditions are met:
8//
9// 1. Redistributions of source code must retain the above copyright notice, this list of
10// conditions and the following disclaimer.
11//
12// 2. Redistributions in binary form must reproduce the above copyright notice, this list
13// of conditions and the following disclaimer in the documentation and/or other
14// materials provided with the distribution.
15//
16// 3. Neither the name of the copyright holder nor the names of its contributors may be
17// used to endorse or promote products derived from this software without specific
18// prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31
32#include "gtest/gtest.h"
33
35#include "wallet/wallet2.h"
36#include "include_base_utils.h"
37#include "common/util.h"
38
39#include <boost/chrono/chrono.hpp>
40#include <boost/filesystem.hpp>
41#include <boost/algorithm/string.hpp>
42#include <boost/asio.hpp>
43#include <boost/date_time/posix_time/posix_time.hpp>
44#include <boost/thread/condition_variable.hpp>
45#include <boost/thread/mutex.hpp>
46#include <boost/thread/thread.hpp>
47
48#include <iostream>
49#include <vector>
50#include <atomic>
51#include <functional>
52
53
54using namespace std;
55//unsigned int epee::g_test_dbg_lock_sleep = 0;
56
57namespace Consts
58{
59
60
61// TODO: get rid of hardcoded paths
62
63const char * WALLET_NAME = "testwallet";
64const char * WALLET_NAME_MAINNET = "testwallet_mainnet";
65const char * WALLET_NAME_COPY = "testwallet_copy";
66const char * WALLET_NAME_WITH_DIR = "walletdir/testwallet_test";
67const char * WALLET_NAME_WITH_DIR_NON_WRITABLE = "/var/walletdir/testwallet_test";
68const char * WALLET_PASS = "password";
69const char * WALLET_PASS2 = "password22";
70const char * WALLET_LANG = "English";
71
72std::string WALLETS_ROOT_DIR = "/var/electroneum/testnet_pvt";
79
80const char * TESTNET_WALLET_PASS = "";
81
84
85const uint64_t AMOUNT_10ETN = 10000000000000L;
86const uint64_t AMOUNT_5ETN = 5000000000000L;
87const uint64_t AMOUNT_1ETN = 1000000000000L;
88
89const std::string PAYMENT_ID_EMPTY = "";
90
91std::string TESTNET_DAEMON_ADDRESS = "localhost:36968";
92std::string MAINNET_DAEMON_ADDRESS = "localhost:26968";
93
94
95}
96
97
98
99using namespace Consts;
100
101struct Utils
102{
103 static void deleteWallet(const std::string & walletname)
104 {
105 std::cout << "** deleting wallet: " << walletname << std::endl;
106 boost::filesystem::remove(walletname);
107 boost::filesystem::remove(walletname + ".address.txt");
108 boost::filesystem::remove(walletname + ".keys");
109 }
110
111 static void deleteDir(const std::string &path)
112 {
113 std::cout << "** removing dir recursively: " << path << std::endl;
114 boost::filesystem::remove_all(path);
115 }
116
118 {
119
120 std::cout << "d: "
121 << (t->direction() == Electroneum::TransactionInfo::Direction_In ? "in" : "out")
122 << ", pe: " << (t->isPending() ? "true" : "false")
123 << ", bh: " << t->blockHeight()
125 << ", f: " << Electroneum::Wallet::displayAmount(t->fee())
126 << ", h: " << t->hash()
127 << ", pid: " << t->paymentId()
128 << std::endl;
129 }
130
131 static std::string get_wallet_address(const std::string &filename, const std::string &password)
132 {
135 std::string result = w->mainAddress();
136 wmgr->closeWallet(w);
137 return result;
138 }
139};
140
141
143{
145
146
148 {
149 std::cout << __FUNCTION__ << std::endl;
151 // Electroneum::WalletManagerFactory::setLogLevel(Electroneum::WalletManagerFactory::LogLevel_4);
153 Utils::deleteDir(boost::filesystem::path(WALLET_NAME_WITH_DIR).parent_path().string());
154 }
155
156
158 {
159 std::cout << __FUNCTION__ << std::endl;
160 //deleteWallet(WALLET_NAME);
161 }
162
163};
164
166{
168
169
176
177
179 {
180 std::cout << __FUNCTION__ << std::endl;
181 }
182
183};
184
196
197
208
209TEST_F(WalletManagerTest, WalletManagerCreatesWallet)
210{
211
214 ASSERT_TRUE(!wallet->seed().empty());
215 std::vector<std::string> words;
216 std::string seed = wallet->seed();
217 boost::split(words, seed, boost::is_any_of(" "), boost::token_compress_on);
218 ASSERT_TRUE(words.size() == 25);
219 std::cout << "** seed: " << wallet->seed() << std::endl;
220 ASSERT_FALSE(wallet->mainAddress().empty());
221 std::cout << "** address: " << wallet->mainAddress() << std::endl;
222 ASSERT_TRUE(wmgr->closeWallet(wallet));
223
224}
225
226TEST_F(WalletManagerTest, WalletManagerOpensWallet)
227{
228
230 std::string seed1 = wallet1->seed();
231 ASSERT_TRUE(wmgr->closeWallet(wallet1));
234 ASSERT_TRUE(wallet2->seed() == seed1);
235 std::cout << "** seed: " << wallet2->seed() << std::endl;
236}
237
238
239TEST_F(WalletManagerTest, WalletMaxAmountAsString)
240{
243
244}
245
246
247TEST_F(WalletManagerTest, WalletAmountFromString)
248{
250 ASSERT_TRUE(amount > 0);
251 amount = Electroneum::Wallet::amountFromString("11000000000000");
252 ASSERT_FALSE(amount > 0);
254 ASSERT_FALSE(amount > 0);
256 ASSERT_TRUE(amount > 0);
257
258}
259
260void open_wallet_helper(Electroneum::WalletManager *wmgr, Electroneum::Wallet **wallet, const std::string &pass, boost::mutex *mutex)
261{
262 if (mutex)
263 mutex->lock();
264 LOG_PRINT_L3("opening wallet in thread: " << boost::this_thread::get_id());
266 LOG_PRINT_L3("wallet address: " << (*wallet)->mainAddress());
267 LOG_PRINT_L3("wallet status: " << (*wallet)->status());
268 LOG_PRINT_L3("closing wallet in thread: " << boost::this_thread::get_id());
269 if (mutex)
270 mutex->unlock();
271}
272
273
274
275
276//TEST_F(WalletManagerTest, WalletManagerOpensWalletWithPasswordAndReopenMultiThreaded)
277//{
278// // create password protected wallet
279// std::string wallet_pass = "password";
280// std::string wrong_wallet_pass = "1111";
281// Electroneum::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, Electroneum::NetworkType::TESTNET);
282// std::string seed1 = wallet1->seed();
283// ASSERT_TRUE(wmgr->closeWallet(wallet1));
284
285// Electroneum::Wallet *wallet2 = nullptr;
286// Electroneum::Wallet *wallet3 = nullptr;
287
288// std::mutex mutex;
289// std::thread thread1(open_wallet, wmgr, &wallet2, wrong_wallet_pass, &mutex);
290// thread1.join();
291// ASSERT_TRUE(wallet2->status() != Electroneum::Wallet::Status_Ok);
292// ASSERT_TRUE(wmgr->closeWallet(wallet2));
293
294// std::thread thread2(open_wallet, wmgr, &wallet3, wallet_pass, &mutex);
295// thread2.join();
296
297// ASSERT_TRUE(wallet3->status() == Electroneum::Wallet::Status_Ok);
298// ASSERT_TRUE(wmgr->closeWallet(wallet3));
299//}
300
301
302TEST_F(WalletManagerTest, WalletManagerOpensWalletWithPasswordAndReopen)
303{
304 // create password protected wallet
305 std::string wallet_pass = "password";
306 std::string wrong_wallet_pass = "1111";
307 Electroneum::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, Electroneum::NetworkType::TESTNET);
308 std::string seed1 = wallet1->seed();
309 ASSERT_TRUE(wmgr->closeWallet(wallet1));
310
311 Electroneum::Wallet *wallet2 = nullptr;
312 Electroneum::Wallet *wallet3 = nullptr;
313 boost::mutex mutex;
314
315 open_wallet_helper(wmgr, &wallet2, wrong_wallet_pass, nullptr);
316 ASSERT_TRUE(wallet2 != nullptr);
318 ASSERT_TRUE(wmgr->closeWallet(wallet2));
319
320 open_wallet_helper(wmgr, &wallet3, wallet_pass, nullptr);
321 ASSERT_TRUE(wallet3 != nullptr);
323 ASSERT_TRUE(wmgr->closeWallet(wallet3));
324}
325
326
327TEST_F(WalletManagerTest, WalletManagerStoresWallet)
328{
329
331 std::string seed1 = wallet1->seed();
332 wallet1->store("");
333 ASSERT_TRUE(wmgr->closeWallet(wallet1));
336 ASSERT_TRUE(wallet2->seed() == seed1);
337}
338
339
340TEST_F(WalletManagerTest, WalletManagerMovesWallet)
341{
342
344 std::string WALLET_NAME_MOVED = std::string("/tmp/") + WALLET_NAME + ".moved";
345 std::string seed1 = wallet1->seed();
346 ASSERT_TRUE(wallet1->store(WALLET_NAME_MOVED));
347
348 Electroneum::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME_MOVED, WALLET_PASS, Electroneum::NetworkType::MAINNET);
349 ASSERT_TRUE(wallet2->filename() == WALLET_NAME_MOVED);
350 ASSERT_TRUE(wallet2->keysFilename() == WALLET_NAME_MOVED + ".keys");
352 ASSERT_TRUE(wallet2->seed() == seed1);
353}
354
355
356TEST_F(WalletManagerTest, WalletManagerChangesPassword)
357{
359 std::string seed1 = wallet1->seed();
361 ASSERT_TRUE(wmgr->closeWallet(wallet1));
364 ASSERT_TRUE(wallet2->seed() == seed1);
365 ASSERT_TRUE(wmgr->closeWallet(wallet2));
368}
369
370
371
372TEST_F(WalletManagerTest, WalletManagerRecoversWallet)
373{
375 std::string seed1 = wallet1->seed();
376 std::string address1 = wallet1->mainAddress();
377 ASSERT_FALSE(address1.empty());
378 ASSERT_TRUE(wmgr->closeWallet(wallet1));
380 Electroneum::Wallet * wallet2 = wmgr->recoveryWallet(WALLET_NAME, seed1, Electroneum::NetworkType::MAINNET);
382 ASSERT_TRUE(wallet2->seed() == seed1);
383 ASSERT_TRUE(wallet2->mainAddress() == address1);
384 ASSERT_TRUE(wmgr->closeWallet(wallet2));
385}
386
387
388TEST_F(WalletManagerTest, WalletManagerStoresWallet1)
389{
391 std::string seed1 = wallet1->seed();
392 std::string address1 = wallet1->mainAddress();
393
394 ASSERT_TRUE(wallet1->store(""));
396 ASSERT_TRUE(wmgr->closeWallet(wallet1));
399 ASSERT_TRUE(wallet2->seed() == seed1);
400 ASSERT_TRUE(wallet2->mainAddress() == address1);
401 ASSERT_TRUE(wmgr->closeWallet(wallet2));
402}
403
404
405TEST_F(WalletManagerTest, WalletManagerStoresWallet2)
406{
408 std::string seed1 = wallet1->seed();
409 std::string address1 = wallet1->mainAddress();
410
412 ASSERT_TRUE(wmgr->closeWallet(wallet1));
413
416 ASSERT_TRUE(wallet1->seed() == seed1);
417 ASSERT_TRUE(wallet1->mainAddress() == address1);
418 ASSERT_TRUE(wmgr->closeWallet(wallet1));
419}
420
421
422TEST_F(WalletManagerTest, WalletManagerStoresWallet3)
423{
425 std::string seed1 = wallet1->seed();
426 std::string address1 = wallet1->mainAddress();
427
429 ASSERT_TRUE(wmgr->closeWallet(wallet1));
430
433
434 // "close" always returns true;
435 ASSERT_TRUE(wmgr->closeWallet(wallet1));
436
437 wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Electroneum::NetworkType::MAINNET);
439 ASSERT_TRUE(wallet1->seed() == seed1);
440 ASSERT_TRUE(wallet1->mainAddress() == address1);
441 ASSERT_TRUE(wmgr->closeWallet(wallet1));
442
443}
444
445
446TEST_F(WalletManagerTest, WalletManagerStoresWallet4)
447{
449 std::string seed1 = wallet1->seed();
450 std::string address1 = wallet1->mainAddress();
451
452 ASSERT_TRUE(wallet1->store(""));
454
455 ASSERT_TRUE(wallet1->store(""));
457
458 ASSERT_TRUE(wmgr->closeWallet(wallet1));
459
460 wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Electroneum::NetworkType::MAINNET);
462 ASSERT_TRUE(wallet1->seed() == seed1);
463 ASSERT_TRUE(wallet1->mainAddress() == address1);
464 ASSERT_TRUE(wmgr->closeWallet(wallet1));
465}
466
467
468
469
470TEST_F(WalletManagerTest, WalletManagerFindsWallet)
471{
472 std::vector<std::string> wallets = wmgr->findWallets(WALLETS_ROOT_DIR);
473 ASSERT_FALSE(wallets.empty());
474 std::cout << "Found wallets: " << std::endl;
475 for (auto wallet_path: wallets) {
476 std::cout << wallet_path << std::endl;
477 }
478}
479
480
481TEST_F(WalletTest1, WalletGeneratesPaymentId)
482{
483 std::string payment_id = Electroneum::Wallet::genPaymentId();
484 ASSERT_TRUE(payment_id.length() == 16);
485}
486
487
488TEST_F(WalletTest1, WalletGeneratesIntegratedAddress)
489{
490 std::string payment_id = Electroneum::Wallet::genPaymentId();
491
493 std::string integrated_address = wallet1->integratedAddress(payment_id);
494 ASSERT_TRUE(integrated_address.length() == 106);
495}
496
497
498TEST_F(WalletTest1, WalletShowsBalance)
499{
501 ASSERT_TRUE(wallet1->balance(0) > 0);
502 ASSERT_TRUE(wallet1->unlockedBalance(0) > 0);
503
504 uint64_t balance1 = wallet1->balance(0);
505 uint64_t unlockedBalance1 = wallet1->unlockedBalance(0);
506 ASSERT_TRUE(wmgr->closeWallet(wallet1));
508
509 ASSERT_TRUE(balance1 == wallet2->balance(0));
510 std::cout << "wallet balance: " << wallet2->balance(0) << std::endl;
511 ASSERT_TRUE(unlockedBalance1 == wallet2->unlockedBalance(0));
512 std::cout << "wallet unlocked balance: " << wallet2->unlockedBalance(0) << std::endl;
513 ASSERT_TRUE(wmgr->closeWallet(wallet2));
514}
515
516TEST_F(WalletTest1, WalletReturnsCurrentBlockHeight)
517{
519 ASSERT_TRUE(wallet1->blockChainHeight() > 0);
520 wmgr->closeWallet(wallet1);
521}
522
523
524TEST_F(WalletTest1, WalletReturnsDaemonBlockHeight)
525{
527 // wallet not connected to daemon
528 ASSERT_TRUE(wallet1->daemonBlockChainHeight() == 0);
530 ASSERT_FALSE(wallet1->errorString().empty());
531 wmgr->closeWallet(wallet1);
532
534 // wallet connected to daemon
535 wallet1->init(TESTNET_DAEMON_ADDRESS, 0);
536 ASSERT_TRUE(wallet1->daemonBlockChainHeight() > 0);
537 std::cout << "daemonBlockChainHeight: " << wallet1->daemonBlockChainHeight() << std::endl;
538 wmgr->closeWallet(wallet1);
539}
540
541
542TEST_F(WalletTest1, WalletRefresh)
543{
544
545 std::cout << "Opening wallet: " << CURRENT_SRC_WALLET << std::endl;
547 // make sure testnet daemon is running
548 std::cout << "connecting to daemon: " << TESTNET_DAEMON_ADDRESS << std::endl;
550 ASSERT_TRUE(wallet1->refresh());
551 ASSERT_TRUE(wmgr->closeWallet(wallet1));
552}
553
564
565
566
567TEST_F(WalletTest1, WalletTransaction)
568
569{
571 // make sure testnet daemon is running
573 ASSERT_TRUE(wallet1->refresh());
574 uint64_t balance = wallet1->balance(0);
576
577 std::string recepient_address = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS);
578 const int MIXIN_COUNT = 4;
579
580
581 Electroneum::PendingTransaction * transaction = wallet1->createTransaction(recepient_address,
584 MIXIN_COUNT,
586 0,
587 std::set<uint32_t>{});
589 wallet1->refresh();
590
591 ASSERT_TRUE(wallet1->balance(0) == balance);
592 ASSERT_TRUE(transaction->amount() == AMOUNT_10ETN);
593 ASSERT_TRUE(transaction->commit());
594 ASSERT_FALSE(wallet1->balance(0) == balance);
595 ASSERT_TRUE(wmgr->closeWallet(wallet1));
596}
597
598
599
600TEST_F(WalletTest1, WalletTransactionWithMixin)
601{
602
603 std::vector<int> mixins;
604 // 2,3,4,5,6,7,8,9,10,15,20,25 can we do it like that?
605 mixins.push_back(2); mixins.push_back(3); mixins.push_back(4); mixins.push_back(5); mixins.push_back(6);
606 mixins.push_back(7); mixins.push_back(8); mixins.push_back(9); mixins.push_back(10); mixins.push_back(15);
607 mixins.push_back(20); mixins.push_back(25);
608
609
610 std::string payment_id = "";
611
613
614
615 // make sure testnet daemon is running
617 ASSERT_TRUE(wallet1->refresh());
618 uint64_t balance = wallet1->balance(0);
620
621 std::string recepient_address = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS);
622 for (auto mixin : mixins) {
623 std::cerr << "Transaction mixin count: " << mixin << std::endl;
624
625 Electroneum::PendingTransaction * transaction = wallet1->createTransaction(
626 recepient_address, payment_id, AMOUNT_5ETN, mixin, Electroneum::PendingTransaction::Priority_Medium, 0, std::set<uint32_t>{});
627
628 std::cerr << "Transaction status: " << transaction->status() << std::endl;
629 std::cerr << "Transaction fee: " << Electroneum::Wallet::displayAmount(transaction->fee()) << std::endl;
630 std::cerr << "Transaction error: " << transaction->errorString() << std::endl;
632 wallet1->disposeTransaction(transaction);
633 }
634
635 wallet1->refresh();
636
637 ASSERT_TRUE(wallet1->balance(0) == balance);
638 ASSERT_TRUE(wmgr->closeWallet(wallet1));
639}
640
641TEST_F(WalletTest1, WalletTransactionWithPriority)
642{
643
644 std::string payment_id = "";
645
647
648 // make sure testnet daemon is running
650 ASSERT_TRUE(wallet1->refresh());
651 uint64_t balance = wallet1->balance(0);
653
654 std::string recepient_address = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS);
655 uint32_t mixin = 0;
656 uint64_t fee = 0;
657
658 std::vector<Electroneum::PendingTransaction::Priority> priorities = {
662 };
663
664 for (auto it = priorities.begin(); it != priorities.end(); ++it) {
665 std::cerr << "Transaction priority: " << *it << std::endl;
666
667 Electroneum::PendingTransaction * transaction = wallet1->createTransaction(
668 recepient_address, payment_id, AMOUNT_5ETN, mixin, *it, 0, std::set<uint32_t>{});
669 std::cerr << "Transaction status: " << transaction->status() << std::endl;
670 std::cerr << "Transaction fee: " << Electroneum::Wallet::displayAmount(transaction->fee()) << std::endl;
671 std::cerr << "Transaction error: " << transaction->errorString() << std::endl;
672 ASSERT_TRUE(transaction->fee() > fee);
674 fee = transaction->fee();
675 wallet1->disposeTransaction(transaction);
676 }
677 wallet1->refresh();
678 ASSERT_TRUE(wallet1->balance(0) == balance);
679 ASSERT_TRUE(wmgr->closeWallet(wallet1));
680}
681
682
683
684TEST_F(WalletTest1, WalletHistory)
685{
687 // make sure testnet daemon is running
689 ASSERT_TRUE(wallet1->refresh());
690 Electroneum::TransactionHistory * history = wallet1->history();
691 history->refresh();
692 ASSERT_TRUE(history->count() > 0);
693
694
695 for (auto t: history->getAll()) {
696 ASSERT_TRUE(t != nullptr);
698 }
699}
700
701TEST_F(WalletTest1, WalletTransactionAndHistory)
702{
703 return;
705 // make sure testnet daemon is running
706 ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0));
707 ASSERT_TRUE(wallet_src->refresh());
708 Electroneum::TransactionHistory * history = wallet_src->history();
709 history->refresh();
710 ASSERT_TRUE(history->count() > 0);
711 size_t count1 = history->count();
712
713 std::cout << "**** Transactions before transfer (" << count1 << ")" << std::endl;
714 for (auto t: history->getAll()) {
715 ASSERT_TRUE(t != nullptr);
717 }
718
720
721
722 Electroneum::PendingTransaction * tx = wallet_src->createTransaction(wallet4_addr,
724 AMOUNT_10ETN * 5, 1, Electroneum::PendingTransaction::Priority_Medium, 0, std::set<uint32_t>{});
725
727 ASSERT_TRUE(tx->commit());
728 history = wallet_src->history();
729 history->refresh();
730 ASSERT_TRUE(count1 != history->count());
731
732 std::cout << "**** Transactions after transfer (" << history->count() << ")" << std::endl;
733 for (auto t: history->getAll()) {
734 ASSERT_TRUE(t != nullptr);
736 }
737}
738
739
740TEST_F(WalletTest1, WalletTransactionWithPaymentId)
741{
742
744 // make sure testnet daemon is running
745 ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0));
746 ASSERT_TRUE(wallet_src->refresh());
747 Electroneum::TransactionHistory * history = wallet_src->history();
748 history->refresh();
749 ASSERT_TRUE(history->count() > 0);
750 size_t count1 = history->count();
751
752 std::cout << "**** Transactions before transfer (" << count1 << ")" << std::endl;
753 for (auto t: history->getAll()) {
754 ASSERT_TRUE(t != nullptr);
756 }
757
759
760 std::string payment_id = Electroneum::Wallet::genPaymentId();
761 ASSERT_TRUE(payment_id.length() == 16);
762
763
764 Electroneum::PendingTransaction * tx = wallet_src->createTransaction(wallet4_addr,
765 payment_id,
767
769 ASSERT_TRUE(tx->commit());
770 history = wallet_src->history();
771 history->refresh();
772 ASSERT_TRUE(count1 != history->count());
773
774 bool payment_id_in_history = false;
775
776 std::cout << "**** Transactions after transfer (" << history->count() << ")" << std::endl;
777 for (auto t: history->getAll()) {
778 ASSERT_TRUE(t != nullptr);
780 if (t->paymentId() == payment_id) {
781 payment_id_in_history = true;
782 }
783 }
784
785 ASSERT_TRUE(payment_id_in_history);
786}
787
788
790{
791
795 boost::mutex mutex;
796 boost::condition_variable cv_send;
797 boost::condition_variable cv_receive;
798 boost::condition_variable cv_update;
799 boost::condition_variable cv_refresh;
800 boost::condition_variable cv_newblock;
806
807
808
810 : total_tx(0), total_rx(0)
811 {
812 reset();
813
814 this->wallet = wallet;
815 this->wallet->setListener(this);
816 }
817
822
823 virtual void etnSpent(const string &txId, uint64_t amount)
824 {
825 std::cerr << "wallet: " << wallet->mainAddress() << "**** just spent ETN ("
826 << txId << ", " << wallet->displayAmount(amount) << ")" << std::endl;
827 total_tx += amount;
828 send_triggered = true;
829 cv_send.notify_one();
830 }
831
832 virtual void etnReceived(const string &txId, uint64_t amount)
833 {
834 std::cout << "wallet: " << wallet->mainAddress() << "**** just received ETN ("
835 << txId << ", " << wallet->displayAmount(amount) << ")" << std::endl;
836 total_rx += amount;
837 receive_triggered = true;
838 cv_receive.notify_one();
839 }
840
841 virtual void unconfirmedETNReceived(const string &txId, uint64_t amount)
842 {
843 std::cout << "wallet: " << wallet->mainAddress() << "**** just received unconfirmed ETN ("
844 << txId << ", " << wallet->displayAmount(amount) << ")" << std::endl;
845 // Don't trigger receive until tx is mined
846 // total_rx += amount;
847 // receive_triggered = true;
848 // cv_receive.notify_one();
849 }
850
852 {
853// std::cout << "wallet: " << wallet->mainAddress()
854// <<", new block received, blockHeight: " << height << std::endl;
855 static int bc_height = wallet->daemonBlockChainHeight();
856 std::cout << height
857 << " / " << bc_height/* 0*/
858 << std::endl;
859 newblock_triggered = true;
860 cv_newblock.notify_one();
861 }
862
863 virtual void updated()
864 {
865 std::cout << __FUNCTION__ << "Wallet updated";
866 update_triggered = true;
867 cv_update.notify_one();
868 }
869
870 virtual void refreshed()
871 {
872 std::cout << __FUNCTION__ << "Wallet refreshed";
873 refresh_triggered = true;
874 cv_refresh.notify_one();
875 }
876
877};
878
879
880
881
882TEST_F(WalletTest2, WalletCallBackRefreshedSync)
883{
884
886 MyWalletListener * wallet_src_listener = new MyWalletListener(wallet_src);
887 ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0));
888 ASSERT_TRUE(wallet_src_listener->refresh_triggered);
889 ASSERT_TRUE(wallet_src->connected());
890 boost::chrono::seconds wait_for = boost::chrono::seconds(60*3);
891 boost::unique_lock<boost::mutex> lock (wallet_src_listener->mutex);
892 wallet_src_listener->cv_refresh.wait_for(lock, wait_for);
893 wmgr->closeWallet(wallet_src);
894}
895
896
897
898
899TEST_F(WalletTest2, WalletCallBackRefreshedAsync)
900{
901
903 MyWalletListener * wallet_src_listener = new MyWalletListener(wallet_src);
904
905 boost::chrono::seconds wait_for = boost::chrono::seconds(20);
906 boost::unique_lock<boost::mutex> lock (wallet_src_listener->mutex);
907 wallet_src->init(MAINNET_DAEMON_ADDRESS, 0);
908 wallet_src->startRefresh();
909 std::cerr << "TEST: waiting on refresh lock...\n";
910 wallet_src_listener->cv_refresh.wait_for(lock, wait_for);
911 std::cerr << "TEST: refresh lock acquired...\n";
912 ASSERT_TRUE(wallet_src_listener->refresh_triggered);
913 ASSERT_TRUE(wallet_src->connected());
914 std::cerr << "TEST: closing wallet...\n";
915 wmgr->closeWallet(wallet_src);
916}
917
918
919
920
921TEST_F(WalletTest2, WalletCallbackSent)
922{
923
925 // make sure testnet daemon is running
926 ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0));
927 ASSERT_TRUE(wallet_src->refresh());
928 MyWalletListener * wallet_src_listener = new MyWalletListener(wallet_src);
929 uint64_t balance = wallet_src->balance(0);
930 std::cout << "** Balance: " << wallet_src->displayAmount(wallet_src->balance(0)) << std::endl;
932
933 uint64_t amount = AMOUNT_1ETN * 5;
934 std::cout << "** Sending " << Electroneum::Wallet::displayAmount(amount) << " to " << wallet_dst->mainAddress();
935
936
937 Electroneum::PendingTransaction * tx = wallet_src->createTransaction(wallet_dst->mainAddress(),
939 amount, 1, Electroneum::PendingTransaction::Priority_Medium, 0, std::set<uint32_t>{});
940 std::cout << "** Committing transaction: " << Electroneum::Wallet::displayAmount(tx->amount())
941 << " with fee: " << Electroneum::Wallet::displayAmount(tx->fee());
942
944 ASSERT_TRUE(tx->commit());
945
946 boost::chrono::seconds wait_for = boost::chrono::seconds(60*3);
947 boost::unique_lock<boost::mutex> lock (wallet_src_listener->mutex);
948 std::cerr << "TEST: waiting on send lock...\n";
949 wallet_src_listener->cv_send.wait_for(lock, wait_for);
950 std::cerr << "TEST: send lock acquired...\n";
951 ASSERT_TRUE(wallet_src_listener->send_triggered);
952 ASSERT_TRUE(wallet_src_listener->update_triggered);
953 std::cout << "** Balance: " << wallet_src->displayAmount(wallet_src->balance(0)) << std::endl;
954 ASSERT_TRUE(wallet_src->balance(0) < balance);
955 wmgr->closeWallet(wallet_src);
956 wmgr->closeWallet(wallet_dst);
957}
958
959
960TEST_F(WalletTest2, WalletCallbackReceived)
961{
962
964 // make sure testnet daemon is running
965 ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0));
966 ASSERT_TRUE(wallet_src->refresh());
967 std::cout << "** Balance src1: " << wallet_src->displayAmount(wallet_src->balance(0)) << std::endl;
968
970 ASSERT_TRUE(wallet_dst->init(TESTNET_DAEMON_ADDRESS, 0));
971 ASSERT_TRUE(wallet_dst->refresh());
972 uint64_t balance = wallet_dst->balance(0);
973 std::cout << "** Balance dst1: " << wallet_dst->displayAmount(wallet_dst->balance(0)) << std::endl;
974 std::unique_ptr<MyWalletListener> wallet_dst_listener (new MyWalletListener(wallet_dst));
975
976 uint64_t amount = AMOUNT_1ETN * 5;
977 std::cout << "** Sending " << Electroneum::Wallet::displayAmount(amount) << " to " << wallet_dst->mainAddress();
978 Electroneum::PendingTransaction * tx = wallet_src->createTransaction(wallet_dst->mainAddress(),
980 amount, 1, Electroneum::PendingTransaction::Priority_Medium, 0, std::set<uint32_t>{});
981
982 std::cout << "** Committing transaction: " << Electroneum::Wallet::displayAmount(tx->amount())
983 << " with fee: " << Electroneum::Wallet::displayAmount(tx->fee());
984
986 ASSERT_TRUE(tx->commit());
987
988 boost::chrono::seconds wait_for = boost::chrono::seconds(60*4);
989 boost::unique_lock<boost::mutex> lock (wallet_dst_listener->mutex);
990 std::cerr << "TEST: waiting on receive lock...\n";
991 wallet_dst_listener->cv_receive.wait_for(lock, wait_for);
992 std::cerr << "TEST: receive lock acquired...\n";
993 ASSERT_TRUE(wallet_dst_listener->receive_triggered);
994 ASSERT_TRUE(wallet_dst_listener->update_triggered);
995
996 std::cout << "** Balance src2: " << wallet_dst->displayAmount(wallet_src->balance(0)) << std::endl;
997 std::cout << "** Balance dst2: " << wallet_dst->displayAmount(wallet_dst->balance(0)) << std::endl;
998
999 ASSERT_TRUE(wallet_dst->balance(0) > balance);
1000
1001 wmgr->closeWallet(wallet_src);
1002 wmgr->closeWallet(wallet_dst);
1003}
1004
1005
1006
1007TEST_F(WalletTest2, WalletCallbackNewBlock)
1008{
1009
1011 // make sure testnet daemon is running
1012 ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0));
1013 ASSERT_TRUE(wallet_src->refresh());
1014 uint64_t bc1 = wallet_src->blockChainHeight();
1015 std::cout << "** Block height: " << bc1 << std::endl;
1016
1017
1018 std::unique_ptr<MyWalletListener> wallet_listener (new MyWalletListener(wallet_src));
1019
1020 // wait max 4 min for new block
1021 boost::chrono::seconds wait_for = boost::chrono::seconds(60*4);
1022 boost::unique_lock<boost::mutex> lock (wallet_listener->mutex);
1023 std::cerr << "TEST: waiting on newblock lock...\n";
1024 wallet_listener->cv_newblock.wait_for(lock, wait_for);
1025 std::cerr << "TEST: newblock lock acquired...\n";
1026 ASSERT_TRUE(wallet_listener->newblock_triggered);
1027 uint64_t bc2 = wallet_src->blockChainHeight();
1028 std::cout << "** Block height: " << bc2 << std::endl;
1029 ASSERT_TRUE(bc2 > bc1);
1030 wmgr->closeWallet(wallet_src);
1031
1032}
1033
1034TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNetSync)
1035{
1036
1038 std::unique_ptr<MyWalletListener> wallet_listener (new MyWalletListener(wallet));
1039 wallet->init(MAINNET_DAEMON_ADDRESS, 0);
1040 std::cerr << "TEST: waiting on refresh lock...\n";
1041 //wallet_listener->cv_refresh.wait_for(lock, wait_for);
1042 std::cerr << "TEST: refresh lock acquired...\n";
1043 ASSERT_TRUE(wallet_listener->refresh_triggered);
1044 ASSERT_TRUE(wallet->connected());
1045 ASSERT_TRUE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight());
1046 std::cerr << "TEST: closing wallet...\n";
1047 wmgr->closeWallet(wallet);
1048}
1049
1050
1051TEST_F(WalletManagerMainnetTest, CreateAndRefreshWalletMainNetAsync)
1052{
1053 // supposing 120 seconds should be enough for fast refresh
1054 int SECONDS_TO_REFRESH = 120;
1055
1057 std::unique_ptr<MyWalletListener> wallet_listener (new MyWalletListener(wallet));
1058
1059 boost::chrono::seconds wait_for = boost::chrono::seconds(SECONDS_TO_REFRESH);
1060 boost::unique_lock<boost::mutex> lock (wallet_listener->mutex);
1061 wallet->init(MAINNET_DAEMON_ADDRESS, 0);
1062 wallet->startRefresh();
1063 std::cerr << "TEST: waiting on refresh lock...\n";
1064 wallet_listener->cv_refresh.wait_for(lock, wait_for);
1065 std::cerr << "TEST: refresh lock acquired...\n";
1067 ASSERT_TRUE(wallet_listener->refresh_triggered);
1068 ASSERT_TRUE(wallet->connected());
1069 ASSERT_TRUE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight());
1070 std::cerr << "TEST: closing wallet...\n";
1071 wmgr->closeWallet(wallet);
1072}
1073
1074TEST_F(WalletManagerMainnetTest, OpenAndRefreshWalletMainNetAsync)
1075{
1076
1077 // supposing 120 seconds should be enough for fast refresh
1078 int SECONDS_TO_REFRESH = 120;
1080 wmgr->closeWallet(wallet);
1081 wallet = wmgr->openWallet(WALLET_NAME_MAINNET, "", Electroneum::NetworkType::MAINNET);
1082
1083 std::unique_ptr<MyWalletListener> wallet_listener (new MyWalletListener(wallet));
1084
1085 boost::chrono::seconds wait_for = boost::chrono::seconds(SECONDS_TO_REFRESH);
1086 boost::unique_lock<boost::mutex> lock (wallet_listener->mutex);
1087 wallet->init(MAINNET_DAEMON_ADDRESS, 0);
1088 wallet->startRefresh();
1089 std::cerr << "TEST: waiting on refresh lock...\n";
1090 wallet_listener->cv_refresh.wait_for(lock, wait_for);
1091 std::cerr << "TEST: refresh lock acquired...\n";
1093 ASSERT_TRUE(wallet_listener->refresh_triggered);
1094 ASSERT_TRUE(wallet->connected());
1095 ASSERT_TRUE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight());
1096 std::cerr << "TEST: closing wallet...\n";
1097 wmgr->closeWallet(wallet);
1098
1099}
1100
1101TEST_F(WalletManagerMainnetTest, RecoverAndRefreshWalletMainNetAsync)
1102{
1103
1104 // supposing 120 seconds should be enough for fast refresh
1105 int SECONDS_TO_REFRESH = 120;
1107 std::string seed = wallet->seed();
1108 std::string address = wallet->mainAddress();
1109 wmgr->closeWallet(wallet);
1110
1111 // deleting wallet files
1113 // ..and recovering wallet from seed
1114
1115 wallet = wmgr->recoveryWallet(WALLET_NAME_MAINNET, seed, Electroneum::NetworkType::MAINNET);
1117 ASSERT_TRUE(wallet->mainAddress() == address);
1118 std::unique_ptr<MyWalletListener> wallet_listener (new MyWalletListener(wallet));
1119 boost::chrono::seconds wait_for = boost::chrono::seconds(SECONDS_TO_REFRESH);
1120 boost::unique_lock<boost::mutex> lock (wallet_listener->mutex);
1121 wallet->init(MAINNET_DAEMON_ADDRESS, 0);
1122 wallet->startRefresh();
1123 std::cerr << "TEST: waiting on refresh lock...\n";
1124
1125 // here we wait for 120 seconds and test if wallet doesn't syncrnonize blockchain completely,
1126 // as it needs much more than 120 seconds for mainnet
1127
1128 wallet_listener->cv_refresh.wait_for(lock, wait_for);
1130 ASSERT_FALSE(wallet_listener->refresh_triggered);
1131 ASSERT_TRUE(wallet->connected());
1133 std::cerr << "TEST: closing wallet...\n";
1134 wmgr->closeWallet(wallet);
1135 std::cerr << "TEST: wallet closed\n";
1136
1137}
1138
1139
1140
1141int main(int argc, char** argv)
1142{
1143 TRY_ENTRY();
1144
1146 // we can override default values for "TESTNET_DAEMON_ADDRESS" and "WALLETS_ROOT_DIR"
1147
1148 const char * testnet_daemon_addr = std::getenv("TESTNET_DAEMON_ADDRESS");
1149 if (testnet_daemon_addr) {
1150 TESTNET_DAEMON_ADDRESS = testnet_daemon_addr;
1151 }
1152
1153 const char * mainnet_daemon_addr = std::getenv("MAINNET_DAEMON_ADDRESS");
1154 if (mainnet_daemon_addr) {
1155 MAINNET_DAEMON_ADDRESS = mainnet_daemon_addr;
1156 }
1157
1158
1159
1160 const char * wallets_root_dir = std::getenv("WALLETS_ROOT_DIR");
1161 if (wallets_root_dir) {
1162 WALLETS_ROOT_DIR = wallets_root_dir;
1163 }
1164
1165
1166 TESTNET_WALLET1_NAME = WALLETS_ROOT_DIR + "/wallet_01.bin";
1167 TESTNET_WALLET2_NAME = WALLETS_ROOT_DIR + "/wallet_02.bin";
1168 TESTNET_WALLET3_NAME = WALLETS_ROOT_DIR + "/wallet_03.bin";
1169 TESTNET_WALLET4_NAME = WALLETS_ROOT_DIR + "/wallet_04.bin";
1170 TESTNET_WALLET5_NAME = WALLETS_ROOT_DIR + "/wallet_05.bin";
1171 TESTNET_WALLET6_NAME = WALLETS_ROOT_DIR + "/wallet_06.bin";
1172
1175
1176 ::testing::InitGoogleTest(&argc, argv);
1178 return RUN_ALL_TESTS();
1179 CATCH_ENTRY_L0("main", 1);
1180}
int main()
uint64_t height
#define TEST_F(test_fixture, test_name)
Definition gtest.h:2216
#define ASSERT_FALSE(condition)
Definition gtest.h:1868
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition gtest.h:2232
#define ASSERT_TRUE(condition)
Definition gtest.h:1865
#define LOG_PRINT_L3(x)
#define CATCH_ENTRY_L0(lacation, return_val)
#define TRY_ENTRY()
std::string TESTNET_WALLET2_NAME
Definition main.cpp:74
std::string TESTNET_WALLET3_NAME
Definition main.cpp:75
std::string MAINNET_DAEMON_ADDRESS
Definition main.cpp:92
std::string TESTNET_WALLET1_NAME
Definition main.cpp:73
const char * WALLET_PASS2
Definition main.cpp:69
const char * WALLET_NAME_WITH_DIR_NON_WRITABLE
Definition main.cpp:67
const char * WALLET_NAME
Definition main.cpp:63
const uint64_t AMOUNT_5ETN
Definition main.cpp:86
const uint64_t AMOUNT_10ETN
Definition main.cpp:85
std::string CURRENT_DST_WALLET
Definition main.cpp:83
const char * TESTNET_WALLET_PASS
Definition main.cpp:80
const char * WALLET_NAME_WITH_DIR
Definition main.cpp:66
const uint64_t AMOUNT_1ETN
Definition main.cpp:87
std::string WALLETS_ROOT_DIR
Definition main.cpp:72
std::string TESTNET_DAEMON_ADDRESS
Definition main.cpp:91
std::string TESTNET_WALLET5_NAME
Definition main.cpp:77
std::string TESTNET_WALLET6_NAME
Definition main.cpp:78
const char * WALLET_LANG
Definition main.cpp:70
std::string TESTNET_WALLET4_NAME
Definition main.cpp:76
const char * WALLET_PASS
Definition main.cpp:68
const std::string PAYMENT_ID_EMPTY
Definition main.cpp:89
const char * WALLET_NAME_MAINNET
Definition main.cpp:64
const char * WALLET_NAME_COPY
Definition main.cpp:65
std::string CURRENT_SRC_WALLET
Definition main.cpp:82
STL namespace.
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
bool on_startup()
Definition util.cpp:778
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
Transaction-like interface for sending etn.
Definition wallet2_api.h:73
virtual int status() const =0
virtual uint64_t fee() const =0
virtual std::string errorString() const =0
virtual uint64_t amount() const =0
virtual bool commit(const std::string &filename="", bool overwrite=false)=0
The TransactionHistory - interface for displaying transaction history.
virtual int count() const =0
virtual std::vector< TransactionInfo * > getAll() const =0
The TransactionInfo - interface for displaying transaction information.
virtual bool isPending() const =0
virtual std::string paymentId() const =0
virtual uint64_t fee() const =0
virtual std::string hash() const =0
transaction_id
virtual uint64_t blockHeight() const =0
virtual int direction() const =0
virtual uint64_t amount() const =0
Interface for wallet operations. TODO: check if /include/IWallet.h is still actual.
virtual std::string errorString() const =0
in case error status, returns error string
virtual uint64_t balance(uint32_t accountIndex=0, bool public_blockchain=false) const =0
static uint64_t amountFromDouble(double amount)
Definition wallet.cpp:311
virtual TransactionHistory * history()=0
std::string mainAddress() const
static std::string displayAmount(uint64_t amount)
Definition wallet.cpp:299
virtual bool init(const std::string &daemon_address, uint64_t upper_transaction_size_limit=0, const std::string &daemon_username="", const std::string &daemon_password="", bool use_ssl=false, bool lightWallet=false)=0
init - initializes wallet with daemon connection params. if daemon_address is local address,...
virtual bool setPassword(const std::string &password)=0
virtual int status() const =0
returns wallet status (Status_Ok | Status_Error)
virtual std::string keysFilename() const =0
keysFilename - returns keys filename. usually this formed as "wallet_filename".keys
virtual void setListener(WalletListener *)=0
virtual ConnectionStatus connected() const =0
connected - checks if the wallet connected to the daemon
virtual bool refresh()=0
refresh - refreshes the wallet, updating transactions from daemon
virtual std::string seed() const =0
static uint64_t maximumAllowedAmount()
Definition wallet.cpp:388
static uint64_t amountFromString(const std::string &amount)
Definition wallet.cpp:304
static std::string genPaymentId()
Definition wallet.cpp:318
virtual uint64_t unlockedBalance(uint32_t accountIndex=0, bool public_blockchain=false) const =0
virtual std::string integratedAddress(const std::string &payment_id) const =0
integratedAddress - returns integrated address for current wallet address and given payment_id....
virtual PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id, optional< uint64_t > amount, uint32_t mixin_count, PendingTransaction::Priority=PendingTransaction::Priority_Low, uint32_t subaddr_account=0, std::set< uint32_t > subaddr_indices={})=0
createTransaction creates transaction. if dst_addr is an integrated address, payment_id is ignored
virtual bool store(const std::string &path)=0
store - stores wallet to file.
virtual void disposeTransaction(PendingTransaction *t)=0
disposeTransaction - destroys transaction object
virtual void startRefresh()=0
StartRefresh - Start/resume refresh thread (refresh every 10 seconds).
virtual std::string filename() const =0
filename - returns wallet filename
virtual uint64_t daemonBlockChainHeight() const =0
daemonBlockChainHeight - returns daemon blockchain height
virtual uint64_t blockChainHeight() const =0
blockChainHeight - returns current blockchain height
static WalletManager * getWalletManager()
WalletManager - provides functions to manage wallets.
virtual bool closeWallet(Wallet *wallet, bool store=true)=0
Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed,...
virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds=1, WalletListener *listener=nullptr)=0
Opens existing wallet.
boost::mutex mutex
Definition main.cpp:795
Electroneum::Wallet * wallet
Definition main.cpp:792
MyWalletListener(Electroneum::Wallet *wallet)
Definition main.cpp:809
uint64_t total_rx
Definition main.cpp:794
virtual void etnSpent(const string &txId, uint64_t amount)
etnSpent - called when etn spent
Definition main.cpp:823
bool newblock_triggered
Definition main.cpp:803
bool receive_triggered
Definition main.cpp:802
boost::condition_variable cv_newblock
Definition main.cpp:800
boost::condition_variable cv_receive
Definition main.cpp:797
bool update_triggered
Definition main.cpp:804
bool refresh_triggered
Definition main.cpp:805
boost::condition_variable cv_update
Definition main.cpp:798
virtual void newBlock(uint64_t height)
newBlock - called when new block received
Definition main.cpp:851
boost::condition_variable cv_send
Definition main.cpp:796
virtual void etnReceived(const string &txId, uint64_t amount)
etnReceived - called when etn received
Definition main.cpp:832
virtual void refreshed()
refreshed - called when wallet refreshed by background thread or explicitly refreshed by calling "ref...
Definition main.cpp:870
boost::condition_variable cv_refresh
Definition main.cpp:799
virtual void unconfirmedETNReceived(const string &txId, uint64_t amount)
unconfirmedETNReceived - called when payment arrived in tx pool
Definition main.cpp:841
uint64_t total_tx
Definition main.cpp:793
bool send_triggered
Definition main.cpp:801
virtual void updated()
updated - generic callback, called when any event (sent/received/block reveived/etc) happened with th...
Definition main.cpp:863
static void deleteWallet(const std::string &walletname)
Definition main.cpp:103
static void print_transaction(Electroneum::TransactionInfo *t)
Definition main.cpp:117
static void deleteDir(const std::string &path)
Definition main.cpp:111
static std::string get_wallet_address(const std::string &filename, const std::string &password)
Definition main.cpp:131
Electroneum::WalletManager * wmgr
Definition main.cpp:167
Electroneum::WalletManager * wmgr
Definition main.cpp:144
Electroneum::WalletManager * wmgr
Definition main.cpp:187
WalletTest1()
Definition main.cpp:189
Electroneum::WalletManager * wmgr
Definition main.cpp:200
WalletTest2()
Definition main.cpp:202
void open_wallet_helper(Electroneum::WalletManager *wmgr, Electroneum::Wallet **wallet, const std::string &pass, boost::mutex *mutex)
Definition main.cpp:260
const char * address
Definition multisig.cpp:37