diff options
-rw-r--r-- | README.md | 15 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 11 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 15 | ||||
-rw-r--r-- | src/wallet/wallet2_api.h | 1 | ||||
-rw-r--r-- | tests/libwallet_api_tests/main.cpp | 92 |
5 files changed, 118 insertions, 16 deletions
@@ -36,9 +36,9 @@ Monero development can be supported directly through donations. Both Monero and Bitcoin donations can be made to donate.getmonero.org if using a client that supports the [OpenAlias](https://openalias.org) standard -The Monero donation address is: 44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A (viewkey: f359631075708155cc3d92a32b75a7d02a5dcf27756707b47a2b31b21c389501) +The Monero donation address is: `44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A` (viewkey: `f359631075708155cc3d92a32b75a7d02a5dcf27756707b47a2b31b21c389501`) -The Bitcoin donation address is: 1KTexdemPdxSBcG55heUuTjDRYqbC5ZL8H +The Bitcoin donation address is: `1KTexdemPdxSBcG55heUuTjDRYqbC5ZL8H` Core development funding and/or some supporting services are also graciously provided by sponsors: @@ -48,6 +48,7 @@ Core development funding and/or some supporting services are also graciously pro [<img width="150" src="https://static.getmonero.org/images/sponsors/araxis.png"/>](http://araxis.com) [<img width="150" src="https://static.getmonero.org/images/sponsors/jetbrains.png"/>](http://www.jetbrains.com/) [<img width="150" src="https://static.getmonero.org/images/sponsors/navicat.png"/>](http://www.navicat.com/) +[<img width="150" src="https://static.getmonero.org/images/sponsors/symas.png"/>](http://www.symas.com/) There are also several mining pools that kindly donate a portion of their fees, [a list of them can be found on our Bitcointalk post](https://bitcointalk.org/index.php?topic=583449.0). @@ -67,7 +68,7 @@ Dependencies: * libunbound `>=1.4.16` (note: Unbound is not a dependency, libunbound is) * libevent `>=2.0` * libgtest `>=1.5` -* Boost `>=1.53 && !=1.54` (note: 1.54 is not supported [more details here](http://goo.gl/RrCFmA)), +* Boost `>=1.58` * BerkeleyDB `>=4.8` (note: on Ubuntu this means installing libdb-dev and libdb++-dev) * libunwind (optional, for stack trace on exception) * miniupnpc (optional, for NAT punching) @@ -244,10 +245,6 @@ TAILS ships with a very restrictive set of firewall rules. Therefore, you need t ## Using readline -While bitmonerod and simplewallet do not use readline directly, most of the -functionality can be obtained by running them via rlwrap. This allows command -recall, edit capabilities, etc. It does not give autocompletion without an -extra completion file, however. To use rlwrap, prefix the command with -`rlwrap`: +While bitmonerod and simplewallet do not use readline directly, most of the functionality can be obtained by running them via rlwrap. This allows command recall, edit capabilities, etc. It does not give autocompletion without an extra completion file, however. To use rlwrap, simply prepend `rlwrap` to the command line, eg: - rlwrap bin/simplewallet --wallet-file /path/to/wallet +`rlwrap bin/simplewallet --wallet-file /path/to/wallet` diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 36d1fa0a9..1840e54c9 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -76,6 +76,13 @@ typedef cryptonote::simple_wallet sw; #define DEFAULT_MIX 4 +// workaround for a suspected bug in pthread/kernel on MacOS X +#ifdef __APPLE__ +#define DEFAULT_MAX_CONCURRENCY 1 +#else +#define DEFAULT_MAX_CONCURRENCY 0 +#endif + #define LOCK_IDLE_SCOPE() \ bool auto_refresh_enabled = m_auto_refresh_enabled.load(std::memory_order_relaxed); \ m_auto_refresh_enabled.store(false, std::memory_order_relaxed); \ @@ -95,7 +102,7 @@ typedef cryptonote::simple_wallet sw; namespace { const command_line::arg_descriptor<std::string> arg_wallet_file = {"wallet-file", sw::tr("Use wallet <arg>"), ""}; - const command_line::arg_descriptor<std::string> arg_generate_new_wallet = {"generate-new-wallet", sw::tr("Generate new wallet and save it to <arg> or <address>.wallet by default"), ""}; + const command_line::arg_descriptor<std::string> arg_generate_new_wallet = {"generate-new-wallet", sw::tr("Generate new wallet and save it to <arg>"), ""}; const command_line::arg_descriptor<std::string> arg_generate_from_view_key = {"generate-from-view-key", sw::tr("Generate incoming-only wallet from view key"), ""}; const command_line::arg_descriptor<std::string> arg_generate_from_keys = {"generate-from-keys", sw::tr("Generate wallet from private keys"), ""}; const command_line::arg_descriptor<std::string> arg_generate_from_json = {"generate-from-json", sw::tr("Generate wallet from JSON format file"), ""}; @@ -108,7 +115,7 @@ namespace const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", sw::tr("Create non-deterministic view and spend keys"), false}; const command_line::arg_descriptor<int> arg_daemon_port = {"daemon-port", sw::tr("Use daemon instance at port <arg> instead of 18081"), 0}; const command_line::arg_descriptor<uint32_t> arg_log_level = {"log-level", "", LOG_LEVEL_0}; - const command_line::arg_descriptor<uint32_t> arg_max_concurrency = {"max-concurrency", "Max number of threads to use for a parallel job", 0}; + const command_line::arg_descriptor<uint32_t> arg_max_concurrency = {"max-concurrency", "Max number of threads to use for a parallel job", DEFAULT_MAX_CONCURRENCY}; const command_line::arg_descriptor<std::string> arg_log_file = {"log-file", sw::tr("Specify log file"), ""}; const command_line::arg_descriptor<bool> arg_testnet = {"testnet", sw::tr("For testnet. Daemon must also be launched with --testnet flag"), false}; const command_line::arg_descriptor<bool> arg_restricted = {"restricted-rpc", sw::tr("Restricts RPC to view-only commands"), false}; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 4b97e2f1d..b3ee4112b 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -129,7 +129,7 @@ string Wallet::displayAmount(uint64_t amount) uint64_t Wallet::amountFromString(const string &amount) { - uint64_t result; + uint64_t result = 0; cryptonote::parse_amount(result, amount); return result; } @@ -154,6 +154,11 @@ bool Wallet::paymentIdValid(const string &paiment_id) return tools::wallet2::parse_short_payment_id(paiment_id, pid); } +uint64_t Wallet::maximumAllowedAmount() +{ + return std::numeric_limits<uint64_t>::max(); +} + ///////////////////////// WalletImpl implementation //////////////////////// WalletImpl::WalletImpl(bool testnet) @@ -267,16 +272,18 @@ bool WalletImpl::recover(const std::string &path, const std::string &seed) bool WalletImpl::close() { - clearStatus(); + bool result = false; try { - // LOG_PRINT_L0("Calling wallet::store..."); - m_wallet->store(); + // do not store wallet with invalid status + if (status() == Status_Ok) + m_wallet->store(); // LOG_PRINT_L0("wallet::store done"); // LOG_PRINT_L0("Calling wallet::stop..."); m_wallet->stop(); // LOG_PRINT_L0("wallet::stop done"); result = true; + clearStatus(); } catch (const std::exception &e) { m_status = Status_Error; m_errorString = e.what(); diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h index 2c5836573..e880b1c68 100644 --- a/src/wallet/wallet2_api.h +++ b/src/wallet/wallet2_api.h @@ -216,6 +216,7 @@ struct Wallet static uint64_t amountFromDouble(double amount); static std::string genPaymentId(); static bool paymentIdValid(const std::string &paiment_id); + static uint64_t maximumAllowedAmount(); /** * @brief refresh - refreshes the wallet, updating transactions from daemon diff --git a/tests/libwallet_api_tests/main.cpp b/tests/libwallet_api_tests/main.cpp index d642534b0..b4bc86f91 100644 --- a/tests/libwallet_api_tests/main.cpp +++ b/tests/libwallet_api_tests/main.cpp @@ -31,6 +31,7 @@ #include "gtest/gtest.h" #include "wallet/wallet2_api.h" +#include "wallet/wallet2.h" #include "include_base_utils.h" #include <boost/filesystem.hpp> @@ -41,6 +42,7 @@ #include <mutex> #include <thread> #include <atomic> +#include <functional> #include <condition_variable> @@ -210,6 +212,94 @@ TEST_F(WalletManagerTest, WalletManagerOpensWallet) std::cout << "** seed: " << wallet2->seed() << std::endl; } + +TEST_F(WalletManagerTest, WalletMaxAmountAsString) +{ + LOG_PRINT_L3("max amount: " << Bitmonero::Wallet::displayAmount( + Bitmonero::Wallet::maximumAllowedAmount())); + +} + +TEST_F(WalletManagerTest, WalletAmountFromString) +{ + uint64_t amount = Bitmonero::Wallet::amountFromString("18446740"); + ASSERT_TRUE(amount > 0); + amount = Bitmonero::Wallet::amountFromString("11000000000000"); + ASSERT_FALSE(amount > 0); + amount = Bitmonero::Wallet::amountFromString("0.0"); + ASSERT_FALSE(amount > 0); + amount = Bitmonero::Wallet::amountFromString("10.1"); + ASSERT_TRUE(amount > 0); + +} + +void open_wallet_helper(Bitmonero::WalletManager *wmgr, Bitmonero::Wallet **wallet, const std::string &pass, std::mutex *mutex) +{ + if (mutex) + mutex->lock(); + LOG_PRINT_L3("opening wallet in thread: " << std::this_thread::get_id()); + *wallet = wmgr->openWallet(WALLET_NAME, pass, true); + LOG_PRINT_L3("wallet address: " << (*wallet)->address()); + LOG_PRINT_L3("wallet status: " << (*wallet)->status()); + LOG_PRINT_L3("closing wallet in thread: " << std::this_thread::get_id()); + if (mutex) + mutex->unlock(); +} + + + + +//TEST_F(WalletManagerTest, WalletManagerOpensWalletWithPasswordAndReopenMultiThreaded) +//{ +// // create password protected wallet +// std::string wallet_pass = "password"; +// std::string wrong_wallet_pass = "1111"; +// Bitmonero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, true); +// std::string seed1 = wallet1->seed(); +// ASSERT_TRUE(wmgr->closeWallet(wallet1)); + +// Bitmonero::Wallet *wallet2 = nullptr; +// Bitmonero::Wallet *wallet3 = nullptr; + +// std::mutex mutex; +// std::thread thread1(open_wallet, wmgr, &wallet2, wrong_wallet_pass, &mutex); +// thread1.join(); +// ASSERT_TRUE(wallet2->status() != Bitmonero::Wallet::Status_Ok); +// ASSERT_TRUE(wmgr->closeWallet(wallet2)); + +// std::thread thread2(open_wallet, wmgr, &wallet3, wallet_pass, &mutex); +// thread2.join(); + +// ASSERT_TRUE(wallet3->status() == Bitmonero::Wallet::Status_Ok); +// ASSERT_TRUE(wmgr->closeWallet(wallet3)); +//} + + +TEST_F(WalletManagerTest, WalletManagerOpensWalletWithPasswordAndReopen) +{ + // create password protected wallet + std::string wallet_pass = "password"; + std::string wrong_wallet_pass = "1111"; + Bitmonero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, true); + std::string seed1 = wallet1->seed(); + ASSERT_TRUE(wmgr->closeWallet(wallet1)); + + Bitmonero::Wallet *wallet2 = nullptr; + Bitmonero::Wallet *wallet3 = nullptr; + std::mutex mutex; + + open_wallet_helper(wmgr, &wallet2, wrong_wallet_pass, nullptr); + ASSERT_TRUE(wallet2 != nullptr); + ASSERT_TRUE(wallet2->status() != Bitmonero::Wallet::Status_Ok); + ASSERT_TRUE(wmgr->closeWallet(wallet2)); + + open_wallet_helper(wmgr, &wallet3, wallet_pass, nullptr); + ASSERT_TRUE(wallet3 != nullptr); + ASSERT_TRUE(wallet3->status() == Bitmonero::Wallet::Status_Ok); + ASSERT_TRUE(wmgr->closeWallet(wallet3)); +} + + TEST_F(WalletManagerTest, WalletManagerStoresWallet) { @@ -239,7 +329,6 @@ TEST_F(WalletManagerTest, WalletManagerMovesWallet) } - TEST_F(WalletManagerTest, WalletManagerChangesPassword) { Bitmonero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG); @@ -819,6 +908,7 @@ TEST_F(WalletTest2, WalletCallbackReceived) } + int main(int argc, char** argv) { |