aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdmojo <78273629+gdmojo@users.noreply.github.com>2021-01-31 11:48:05 +0000
committergdmojo <78273629+gdmojo@users.noreply.github.com>2021-02-20 18:23:06 +0000
commitf346e3ec0e53707655538eb2681e8148dd650004 (patch)
treefd6057183404b440fc16f0913121ead903304071
parentMerge pull request #7260 (diff)
downloadmonero-f346e3ec0e53707655538eb2681e8148dd650004.tar.xz
wallet_rpc_payments: implement multithreading
-rw-r--r--src/simplewallet/simplewallet.cpp22
-rw-r--r--src/simplewallet/simplewallet.h1
-rw-r--r--src/wallet/wallet2.h2
-rw-r--r--src/wallet/wallet_rpc_payments.cpp91
4 files changed, 76 insertions, 40 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index dfd6adf3a..68b6c27ff 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -276,7 +276,7 @@ namespace
const char* USAGE_PUBLIC_NODES("public_nodes");
const char* USAGE_WELCOME("welcome");
const char* USAGE_RPC_PAYMENT_INFO("rpc_payment_info");
- const char* USAGE_START_MINING_FOR_RPC("start_mining_for_rpc");
+ const char* USAGE_START_MINING_FOR_RPC("start_mining_for_rpc [<number_of_threads>]");
const char* USAGE_STOP_MINING_FOR_RPC("stop_mining_for_rpc");
const char* USAGE_SHOW_QR_CODE("show_qr_code [<subaddress_index>]");
const char* USAGE_VERSION("version");
@@ -2360,6 +2360,24 @@ bool simple_wallet::start_mining_for_rpc(const std::vector<std::string> &args)
if (!try_connect_to_daemon())
return true;
+ bool ok = true;
+ if(args.size() >= 1)
+ {
+ uint16_t num = 0;
+ ok = string_tools::get_xtype_from_string(num, args[0]);
+ m_rpc_payment_threads = num;
+ }
+ else
+ {
+ m_rpc_payment_threads = 0;
+ }
+
+ if (!ok)
+ {
+ PRINT_USAGE(USAGE_START_MINING_FOR_RPC);
+ return true;
+ }
+
LOCK_IDLE_SCOPE();
bool payment_required;
@@ -9272,7 +9290,7 @@ bool simple_wallet::check_rpc_payment()
fail_msg_writer() << tr("Error mining to daemon: ") << error;
m_cmd_binder.print_prompt();
};
- bool ret = m_wallet->search_for_rpc_payment(target, startfunc, contfunc, foundfunc, errorfunc);
+ bool ret = m_wallet->search_for_rpc_payment(target, m_rpc_payment_threads, startfunc, contfunc, foundfunc, errorfunc);
if (!ret)
{
fail_msg_writer() << tr("Failed to start mining for RPC payment");
diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h
index 61104c87f..80d31d6b0 100644
--- a/src/simplewallet/simplewallet.h
+++ b/src/simplewallet/simplewallet.h
@@ -463,6 +463,7 @@ namespace cryptonote
std::atomic<bool> m_need_payment;
boost::posix_time::ptime m_last_rpc_payment_mining_time;
bool m_rpc_payment_mining_requested;
+ uint32_t m_rpc_payment_threads = 0;
bool m_daemon_rpc_payment_message_displayed;
float m_rpc_payment_hash_rate;
std::atomic<bool> m_suspend_rpc_payment_mining;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 2e455c40c..305c589c6 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1426,7 +1426,7 @@ private:
bool get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &hashing_blob, uint64_t &height, uint64_t &seed_height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, uint32_t &cookie);
bool daemon_requires_payment();
bool make_rpc_payment(uint32_t nonce, uint32_t cookie, uint64_t &credits, uint64_t &balance);
- bool search_for_rpc_payment(uint64_t credits_target, const std::function<bool(uint64_t, uint64_t)> &startfunc, const std::function<bool(unsigned)> &contfunc, const std::function<bool(uint64_t)> &foundfunc = NULL, const std::function<void(const std::string&)> &errorfunc = NULL);
+ bool search_for_rpc_payment(uint64_t credits_target, uint32_t n_threads, const std::function<bool(uint64_t, uint64_t)> &startfunc, const std::function<bool(unsigned)> &contfunc, const std::function<bool(uint64_t)> &foundfunc = NULL, const std::function<void(const std::string&)> &errorfunc = NULL);
template<typename T> void handle_payment_changes(const T &res, std::true_type) {
if (res.status == CORE_RPC_STATUS_OK || res.status == CORE_RPC_STATUS_PAYMENT_REQUIRED)
m_rpc_payment_state.credits = res.credits;
diff --git a/src/wallet/wallet_rpc_payments.cpp b/src/wallet/wallet_rpc_payments.cpp
index 6527b1384..bf278f695 100644
--- a/src/wallet/wallet_rpc_payments.cpp
+++ b/src/wallet/wallet_rpc_payments.cpp
@@ -42,6 +42,7 @@
#include "cryptonote_basic/blobdatatype.h"
#include "common/i18n.h"
#include "common/util.h"
+#include "common/threadpool.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "wallet.wallet2.rpc_payments"
@@ -101,7 +102,7 @@ bool wallet2::make_rpc_payment(uint32_t nonce, uint32_t cookie, uint64_t &credit
return true;
}
//----------------------------------------------------------------------------------------------------
-bool wallet2::search_for_rpc_payment(uint64_t credits_target, const std::function<bool(uint64_t, uint64_t)> &startfunc, const std::function<bool(unsigned)> &contfunc, const std::function<bool(uint64_t)> &foundfunc, const std::function<void(const std::string&)> &errorfunc)
+bool wallet2::search_for_rpc_payment(uint64_t credits_target, uint32_t n_threads, const std::function<bool(uint64_t, uint64_t)> &startfunc, const std::function<bool(unsigned)> &contfunc, const std::function<bool(uint64_t)> &foundfunc, const std::function<void(const std::string&)> &errorfunc)
{
bool need_payment = false;
bool payment_required;
@@ -139,49 +140,65 @@ bool wallet2::search_for_rpc_payment(uint64_t credits_target, const std::functio
continue;
}
- crypto::hash hash;
- const uint32_t local_nonce = nonce++; // wrapping's OK
- *(uint32_t*)(hashing_blob.data() + 39) = SWAP32LE(local_nonce);
- const uint8_t major_version = hashing_blob[0];
- if (major_version >= RX_BLOCK_VERSION)
- {
- const int miners = 1;
- crypto::rx_slow_hash(height, seed_height, seed_hash.data, hashing_blob.data(), hashing_blob.size(), hash.data, miners, 0);
- }
- else
+ if(n_threads == 0)
+ n_threads = boost::thread::hardware_concurrency();
+
+ std::vector<crypto::hash> hash(n_threads);
+ tools::threadpool& tpool = tools::threadpool::getInstance();
+ tools::threadpool::waiter waiter(tpool);
+
+ const uint32_t local_nonce = nonce += n_threads; // wrapping's OK
+ for (size_t i = 0; i < n_threads; i++)
{
- int cn_variant = hashing_blob[0] >= 7 ? hashing_blob[0] - 6 : 0;
- crypto::cn_slow_hash(hashing_blob.data(), hashing_blob.size(), hash, cn_variant, height);
+ tpool.submit(&waiter, [&, i] {
+ *(uint32_t*)(hashing_blob.data() + 39) = SWAP32LE(local_nonce-i);
+ const uint8_t major_version = hashing_blob[0];
+ if (major_version >= RX_BLOCK_VERSION)
+ {
+ const int miners = 1;
+ crypto::rx_slow_hash(height, seed_height, seed_hash.data, hashing_blob.data(), hashing_blob.size(), hash[i].data, miners, 0);
+ }
+ else
+ {
+ int cn_variant = hashing_blob[0] >= 7 ? hashing_blob[0] - 6 : 0;
+ crypto::cn_slow_hash(hashing_blob.data(), hashing_blob.size(), hash[i], cn_variant, height);
+ }
+ });
}
- ++n_hashes;
- if (cryptonote::check_hash(hash, diff))
+ waiter.wait();
+ n_hashes += n_threads;
+
+ for(size_t i=0; i < n_threads; i++)
{
- uint64_t credits, balance;
- try
+ if (cryptonote::check_hash(hash[i], diff))
{
- make_rpc_payment(local_nonce, cookie, credits, balance);
- if (credits != credits_per_hash_found)
+ uint64_t credits, balance;
+ try
{
- MERROR("Found nonce, but daemon did not credit us with the expected amount");
+ make_rpc_payment(local_nonce-i, cookie, credits, balance);
+ if (credits != credits_per_hash_found)
+ {
+ MERROR("Found nonce, but daemon did not credit us with the expected amount");
+ if (errorfunc)
+ errorfunc("Found nonce, but daemon did not credit us with the expected amount");
+ return false;
+ }
+ MDEBUG("Found nonce " << local_nonce-i << " at diff " << diff << ", gets us " << credits_per_hash_found << ", now " << balance << " credits");
+ if (!foundfunc(credits))
+ break;
+ }
+ catch (const tools::error::wallet_coded_rpc_error &e)
+ {
+ MWARNING("Found a local_nonce at diff " << diff << ", but failed to send it to the daemon");
if (errorfunc)
- errorfunc("Found nonce, but daemon did not credit us with the expected amount");
- return false;
+ errorfunc("Found nonce, but daemon errored out with error " + std::to_string(e.code()) + ": " + e.status() + ", continuing");
+ }
+ catch (const std::exception &e)
+ {
+ MWARNING("Found a local_nonce at diff " << diff << ", but failed to send it to the daemon");
+ if (errorfunc)
+ errorfunc("Found nonce, but daemon errored out with: '" + std::string(e.what()) + "', continuing");
}
- MDEBUG("Found nonce " << local_nonce << " at diff " << diff << ", gets us " << credits_per_hash_found << ", now " << balance << " credits");
- if (!foundfunc(credits))
- break;
- }
- catch (const tools::error::wallet_coded_rpc_error &e)
- {
- MWARNING("Found a local_nonce at diff " << diff << ", but failed to send it to the daemon");
- if (errorfunc)
- errorfunc("Found nonce, but daemon errored out with error " + std::to_string(e.code()) + ": " + e.status() + ", continuing");
- }
- catch (const std::exception &e)
- {
- MWARNING("Found a local_nonce at diff " << diff << ", but failed to send it to the daemon");
- if (errorfunc)
- errorfunc("Found nonce, but daemon errored out with: '" + std::string(e.what()) + "', continuing");
}
}
}