From 4dc7a8103b8bed1d65fa49e468e5cb46dd99b3a8 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 11 Oct 2019 09:58:11 +0700 Subject: [PATCH 01/28] Added class Url. --- src/base/base.cmake | 2 + src/base/net/stratum/Pool.cpp | 172 ++++------------------------------ src/base/net/stratum/Pool.h | 25 ++--- src/base/net/stratum/Url.cpp | 165 ++++++++++++++++++++++++++++++++ src/base/net/stratum/Url.h | 77 +++++++++++++++ 5 files changed, 274 insertions(+), 167 deletions(-) create mode 100644 src/base/net/stratum/Url.cpp create mode 100644 src/base/net/stratum/Url.h diff --git a/src/base/base.cmake b/src/base/base.cmake index 8e43b6e08..6a59c8acf 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -41,6 +41,7 @@ set(HEADERS_BASE src/base/net/stratum/strategies/FailoverStrategy.h src/base/net/stratum/strategies/SinglePoolStrategy.h src/base/net/stratum/SubmitResult.h + src/base/net/stratum/Url.h src/base/net/tools/RecvBuf.h src/base/net/tools/Storage.h src/base/tools/Arguments.h @@ -78,6 +79,7 @@ set(SOURCES_BASE src/base/net/stratum/Pools.cpp src/base/net/stratum/strategies/FailoverStrategy.cpp src/base/net/stratum/strategies/SinglePoolStrategy.cpp + src/base/net/stratum/Url.cpp src/base/tools/Arguments.cpp src/base/tools/Buffer.cpp src/base/tools/String.cpp diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index 15586fe87..072dc5347 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -24,10 +24,10 @@ */ -#include -#include -#include -#include +#include +#include +#include +#include #include "base/io/json/Json.h" @@ -40,11 +40,6 @@ #endif -#ifdef _MSC_VER -# define strncasecmp _strnicmp -#endif - - namespace xmrig { static const char *kAlgo = "algo"; @@ -64,54 +59,23 @@ static const char *kUser = "user"; const String Pool::kDefaultPassword = "x"; const String Pool::kDefaultUser = "x"; -static const char kStratumTcp[] = "stratum+tcp://"; -static const char kStratumSsl[] = "stratum+ssl://"; - -#ifdef XMRIG_FEATURE_HTTP -static const char kDaemonHttp[] = "daemon+http://"; -static const char kDaemonHttps[] = "daemon+https://"; -#endif - } -xmrig::Pool::Pool() : - m_keepAlive(0), - m_flags(0), - m_port(kDefaultPort), - m_pollInterval(kDefaultPollInterval) -{ -} - - -/** - * @brief Parse url. - * - * Valid urls: - * example.com - * example.com:3333 - * stratum+tcp://example.com - * stratum+tcp://example.com:3333 - * - * @param url - */ xmrig::Pool::Pool(const char *url) : - m_keepAlive(0), - m_flags(1), - m_port(kDefaultPort), - m_pollInterval(kDefaultPollInterval) + m_flags(1 << FLAG_ENABLED), + m_pollInterval(kDefaultPollInterval), + m_url(url) { - parse(url); } xmrig::Pool::Pool(const rapidjson::Value &object) : - m_keepAlive(0), - m_flags(1), - m_port(kDefaultPort), - m_pollInterval(kDefaultPollInterval) + m_flags(1 << FLAG_ENABLED), + m_pollInterval(kDefaultPollInterval), + m_url(Json::getString(object, kUrl)) { - if (!parse(Json::getString(object, kUrl))) { + if (!m_url.isValid()) { return; } @@ -125,8 +89,8 @@ xmrig::Pool::Pool(const rapidjson::Value &object) : m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true)); m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash)); - m_flags.set(FLAG_TLS, Json::getBool(object, kTls, m_flags.test(FLAG_TLS))); - m_flags.set(FLAG_DAEMON, Json::getBool(object, kDaemon, m_flags.test(FLAG_DAEMON))); + m_flags.set(FLAG_TLS, Json::getBool(object, kTls) || m_url.isTLS()); + m_flags.set(FLAG_DAEMON, Json::getBool(object, kDaemon)); const rapidjson::Value &keepalive = Json::getValue(object, kKeepalive); if (keepalive.IsInt()) { @@ -140,21 +104,12 @@ xmrig::Pool::Pool(const rapidjson::Value &object) : xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls) : m_keepAlive(keepAlive), - m_flags(1), - m_host(host), + m_flags(1 << FLAG_ENABLED), m_password(password), m_user(user), - m_port(port), - m_pollInterval(kDefaultPollInterval) + m_pollInterval(kDefaultPollInterval), + m_url(host, port, tls) { - const size_t size = m_host.size() + 8; - assert(size > 8); - - char *url = new char[size](); - snprintf(url, size - 1, "%s:%d", m_host.data(), m_port); - - m_url = url; - m_flags.set(FLAG_NICEHASH, nicehash); m_flags.set(FLAG_TLS, tls); } @@ -186,11 +141,9 @@ bool xmrig::Pool::isEqual(const Pool &other) const { return (m_flags == other.m_flags && m_keepAlive == other.m_keepAlive - && m_port == other.m_port && m_algorithm == other.m_algorithm && m_coin == other.m_coin && m_fingerprint == other.m_fingerprint - && m_host == other.m_host && m_password == other.m_password && m_rigId == other.m_rigId && m_url == other.m_url @@ -200,68 +153,6 @@ bool xmrig::Pool::isEqual(const Pool &other) const } -bool xmrig::Pool::parse(const char *url) -{ - assert(url != nullptr); - if (url == nullptr) { - return false; - } - - const char *p = strstr(url, "://"); - const char *base = url; - - if (p) { - if (strncasecmp(url, kStratumTcp, sizeof(kStratumTcp) - 1) == 0) { - m_flags.set(FLAG_DAEMON, false); - m_flags.set(FLAG_TLS, false); - } - else if (strncasecmp(url, kStratumSsl, sizeof(kStratumSsl) - 1) == 0) { - m_flags.set(FLAG_DAEMON, false); - m_flags.set(FLAG_TLS, true); - } -# ifdef XMRIG_FEATURE_HTTP - else if (strncasecmp(url, kDaemonHttps, sizeof(kDaemonHttps) - 1) == 0) { - m_flags.set(FLAG_DAEMON, true); - m_flags.set(FLAG_TLS, true); - } - else if (strncasecmp(url, kDaemonHttp, sizeof(kDaemonHttp) - 1) == 0) { - m_flags.set(FLAG_DAEMON, true); - m_flags.set(FLAG_TLS, false); - } -# endif - else { - return false; - } - - base = p + 3; - } - - if (!strlen(base) || *base == '/') { - return false; - } - - m_url = url; - if (base[0] == '[') { - return parseIPv6(base); - } - - const char *port = strchr(base, ':'); - if (!port) { - m_host = base; - return true; - } - - const size_t size = static_cast(port++ - base + 1); - char *host = new char[size](); - memcpy(host, base, size - 1); - - m_host = host; - m_port = static_cast(strtol(port, nullptr, 10)); - - return true; -} - - rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const { using namespace rapidjson; @@ -272,7 +163,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const obj.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator); obj.AddMember(StringRef(kCoin), m_coin.toJSON(), allocator); - obj.AddMember(StringRef(kUrl), m_url.toJSON(), allocator); + obj.AddMember(StringRef(kUrl), url().toJSON(), allocator); obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator); if (!isDaemon()) { @@ -307,9 +198,9 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const #ifdef APP_DEBUG void xmrig::Pool::print() const { - LOG_NOTICE("url: %s", m_url.data()); - LOG_DEBUG ("host: %s", m_host.data()); - LOG_DEBUG ("port: %d", static_cast(m_port)); + LOG_NOTICE("url: %s", url().data()); + LOG_DEBUG ("host: %s", host().data()); + LOG_DEBUG ("port: %d", static_cast(port())); LOG_DEBUG ("user: %s", m_user.data()); LOG_DEBUG ("pass: %s", m_password.data()); LOG_DEBUG ("rig-id %s", m_rigId.data()); @@ -318,26 +209,3 @@ void xmrig::Pool::print() const LOG_DEBUG ("keepAlive: %d", m_keepAlive); } #endif - - -bool xmrig::Pool::parseIPv6(const char *addr) -{ - const char *end = strchr(addr, ']'); - if (!end) { - return false; - } - - const char *port = strchr(end, ':'); - if (!port) { - return false; - } - - const size_t size = static_cast(end - addr); - char *host = new char[size](); - memcpy(host, addr + 1, size - 1); - - m_host = host; - m_port = static_cast(strtol(port + 1, nullptr, 10)); - - return true; -} diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h index 15d31ccc7..fc6b6326a 100644 --- a/src/base/net/stratum/Pool.h +++ b/src/base/net/stratum/Pool.h @@ -31,7 +31,7 @@ #include -#include "base/tools/String.h" +#include "base/net/stratum/Url.h" #include "crypto/common/Coin.h" #include "rapidjson/fwd.h" @@ -57,7 +57,7 @@ public: constexpr static uint16_t kDefaultPort = 3333; constexpr static uint64_t kDefaultPollInterval = 1000; - Pool(); + Pool() = default; Pool(const char *url); Pool(const rapidjson::Value &object); Pool(const char *host, @@ -72,17 +72,17 @@ public: inline bool isDaemon() const { return m_flags.test(FLAG_DAEMON); } inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); } inline bool isTLS() const { return m_flags.test(FLAG_TLS); } - inline bool isValid() const { return !m_host.isNull() && m_port > 0; } + inline bool isValid() const { return m_url.isValid(); } inline const Algorithm &algorithm() const { return m_algorithm; } inline const Coin &coin() const { return m_coin; } inline const String &fingerprint() const { return m_fingerprint; } - inline const String &host() const { return m_host; } + inline const String &host() const { return m_url.host(); } inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; } inline const String &rigId() const { return m_rigId; } - inline const String &url() const { return m_url; } + inline const String &url() const { return m_url.url(); } inline const String &user() const { return !m_user.isNull() ? m_user : kDefaultUser; } inline int keepAlive() const { return m_keepAlive; } - inline uint16_t port() const { return m_port; } + inline uint16_t port() const { return m_url.port(); } inline uint64_t pollInterval() const { return m_pollInterval; } inline void setAlgo(const Algorithm &algorithm) { m_algorithm = algorithm; } inline void setPassword(const String &password) { m_password = password; } @@ -94,7 +94,6 @@ public: bool isEnabled() const; bool isEqual(const Pool &other) const; - bool parse(const char *url); rapidjson::Value toJSON(rapidjson::Document &doc) const; # ifdef APP_DEBUG @@ -105,20 +104,16 @@ private: inline void setKeepAlive(bool enable) { setKeepAlive(enable ? kKeepAliveTimeout : 0); } inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } - bool parseIPv6(const char *addr); - Algorithm m_algorithm; Coin m_coin; - int m_keepAlive; - std::bitset m_flags; + int m_keepAlive = 0; + std::bitset m_flags = 0; String m_fingerprint; - String m_host; String m_password; String m_rigId; - String m_url; String m_user; - uint16_t m_port; - uint64_t m_pollInterval; + uint64_t m_pollInterval = kDefaultPollInterval; + Url m_url; }; diff --git a/src/base/net/stratum/Url.cpp b/src/base/net/stratum/Url.cpp new file mode 100644 index 000000000..193c72913 --- /dev/null +++ b/src/base/net/stratum/Url.cpp @@ -0,0 +1,165 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2019 Howard Chu + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "base/net/stratum/Url.h" + + +#include +#include +#include +#include + + +#ifdef _MSC_VER +# define strncasecmp _strnicmp +#endif + + +namespace xmrig { + +static const char kStratumTcp[] = "stratum+tcp://"; +static const char kStratumSsl[] = "stratum+ssl://"; + +#ifdef XMRIG_FEATURE_HTTP +static const char kDaemonHttp[] = "daemon+http://"; +static const char kDaemonHttps[] = "daemon+https://"; +#endif + +} + + +xmrig::Url::Url(const char *url) +{ + parse(url); +} + + +xmrig::Url::Url(const char *host, uint16_t port, bool tls, Scheme scheme) : + m_tls(tls), + m_scheme(scheme), + m_host(host), + m_port(port) +{ + const size_t size = m_host.size() + 8; + assert(size > 8); + + char *url = new char[size](); + snprintf(url, size - 1, "%s:%d", m_host.data(), m_port); + + m_url = url; +} + + +bool xmrig::Url::isEqual(const Url &other) const +{ + return (m_tls == other.m_tls && m_scheme == other.m_scheme && m_host == other.m_host && m_url == other.m_url && m_port == other.m_port); +} + + +bool xmrig::Url::parse(const char *url) +{ + assert(url != nullptr); + + if (url == nullptr) { + return false; + } + + const char *p = strstr(url, "://"); + const char *base = url; + + if (p) { + if (strncasecmp(url, kStratumTcp, sizeof(kStratumTcp) - 1) == 0) { + m_scheme = STRATUM; + m_tls = false; + } + else if (strncasecmp(url, kStratumSsl, sizeof(kStratumSsl) - 1) == 0) { + m_scheme = STRATUM; + m_tls = true; + } +# ifdef XMRIG_FEATURE_HTTP + else if (strncasecmp(url, kDaemonHttps, sizeof(kDaemonHttps) - 1) == 0) { + m_scheme = DAEMON; + m_tls = true; + } + else if (strncasecmp(url, kDaemonHttp, sizeof(kDaemonHttp) - 1) == 0) { + m_scheme = DAEMON; + m_tls = false; + } +# endif + else { + return false; + } + + base = p + 3; + } + + if (!strlen(base) || *base == '/') { + return false; + } + + m_url = url; + if (base[0] == '[') { + return parseIPv6(base); + } + + const char *port = strchr(base, ':'); + if (!port) { + m_host = base; + return true; + } + + const auto size = static_cast(port++ - base + 1); + char *host = new char[size](); + memcpy(host, base, size - 1); + + m_host = host; + m_port = static_cast(strtol(port, nullptr, 10)); + + return true; +} + + +bool xmrig::Url::parseIPv6(const char *addr) +{ + const char *end = strchr(addr, ']'); + if (!end) { + return false; + } + + const char *port = strchr(end, ':'); + if (!port) { + return false; + } + + const auto size = static_cast(end - addr); + char *host = new char[size](); + memcpy(host, addr + 1, size - 1); + + m_host = host; + m_port = static_cast(strtol(port + 1, nullptr, 10)); + + return true; +} diff --git a/src/base/net/stratum/Url.h b/src/base/net/stratum/Url.h new file mode 100644 index 000000000..23fd750e9 --- /dev/null +++ b/src/base/net/stratum/Url.h @@ -0,0 +1,77 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2019 Howard Chu + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_URL_H +#define XMRIG_URL_H + + +#include "base/tools/String.h" + + +namespace xmrig { + + +class Url +{ +public: + enum Scheme { + UNSPECIFIED, + STRATUM, + DAEMON + }; + + Url() = default; + Url(const char *url); + Url(const char *host, uint16_t port, bool tls = false, Scheme scheme = UNSPECIFIED); + + inline bool isTLS() const { return m_tls; } + inline bool isValid() const { return !m_host.isNull() && m_port > 0; } + inline const String &host() const { return m_host; } + inline const String &url() const { return m_url; } + inline Scheme scheme() const { return m_scheme; } + inline uint16_t port() const { return m_port; } + + inline bool operator!=(const Url &other) const { return !isEqual(other); } + inline bool operator==(const Url &other) const { return isEqual(other); } + + bool isEqual(const Url &other) const; + rapidjson::Value toJSON(rapidjson::Document &doc) const; + +private: + bool parse(const char *url); + bool parseIPv6(const char *addr); + + bool m_tls = false; + Scheme m_scheme = UNSPECIFIED; + String m_host; + String m_url; + uint16_t m_port = 3333; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_URL_H */ From 72c45d882b13293660cc24b6aa0365d9bf56a71d Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 11 Oct 2019 14:55:12 +0700 Subject: [PATCH 02/28] Prepare for self select. --- src/base/kernel/config/BaseTransform.cpp | 3 ++ src/base/kernel/interfaces/IConfig.h | 1 + src/base/net/stratum/Job.cpp | 22 ++++++----- src/base/net/stratum/Job.h | 50 +++++++++++++----------- src/base/net/stratum/Pool.cpp | 48 +++++++++++++++++------ src/base/net/stratum/Pool.h | 24 ++++++++---- src/base/net/stratum/Pools.cpp | 10 +---- src/base/net/stratum/Url.cpp | 2 - src/core/config/Config_platform.h | 1 + src/core/config/usage.h | 1 + 10 files changed, 102 insertions(+), 60 deletions(-) diff --git a/src/base/kernel/config/BaseTransform.cpp b/src/base/kernel/config/BaseTransform.cpp index 2f629bcab..ccf5ccf11 100644 --- a/src/base/kernel/config/BaseTransform.cpp +++ b/src/base/kernel/config/BaseTransform.cpp @@ -183,6 +183,9 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch case IConfig::FingerprintKey: /* --tls-fingerprint */ return add(doc, kPools, "tls-fingerprint", arg); + case IConfig::SelfSelectKey: /* --self-select */ + return add(doc, kPools, "self-select", arg); + case IConfig::LogFileKey: /* --log-file */ return set(doc, "log-file", arg); diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index 848e78794..9f8d96180 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -72,6 +72,7 @@ public: ProxyDonateKey = 1017, DaemonKey = 1018, DaemonPollKey = 1019, + SelfSelectKey = 1028, // xmrig common CPUPriorityKey = 1021, diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index c86ecba53..ef1b03b59 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -152,16 +152,18 @@ void xmrig::Job::setDiff(uint64_t diff) void xmrig::Job::copy(const Job &other) { - m_algorithm = other.m_algorithm; - m_nicehash = other.m_nicehash; - m_size = other.m_size; - m_clientId = other.m_clientId; - m_id = other.m_id; - m_diff = other.m_diff; - m_height = other.m_height; - m_target = other.m_target; - m_index = other.m_index; - m_seed = other.m_seed; + m_algorithm = other.m_algorithm; + m_nicehash = other.m_nicehash; + m_size = other.m_size; + m_clientId = other.m_clientId; + m_id = other.m_id; + m_diff = other.m_diff; + m_height = other.m_height; + m_target = other.m_target; + m_index = other.m_index; + m_seed = other.m_seed; + m_extraNonce = other.m_extraNonce; + m_poolWallet = other.m_poolWallet; memcpy(m_blob, other.m_blob, sizeof(m_blob)); diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index d695c561e..3c4c4724c 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -58,28 +58,32 @@ public: bool setTarget(const char *target); void setDiff(uint64_t diff); - inline bool isNicehash() const { return m_nicehash; } - inline bool isValid() const { return m_size > 0 && m_diff > 0; } - inline bool setId(const char *id) { return m_id = id; } - inline const Algorithm &algorithm() const { return m_algorithm; } - inline const Buffer &seed() const { return m_seed; } - inline const String &clientId() const { return m_clientId; } - inline const String &id() const { return m_id; } - inline const uint32_t *nonce() const { return reinterpret_cast(m_blob + 39); } - inline const uint8_t *blob() const { return m_blob; } - inline size_t size() const { return m_size; } - inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } - inline uint64_t diff() const { return m_diff; } - inline uint64_t height() const { return m_height; } - inline uint64_t target() const { return m_target; } - inline uint8_t fixedByte() const { return *(m_blob + 42); } - inline uint8_t index() const { return m_index; } - inline void reset() { m_size = 0; m_diff = 0; } - inline void setAlgorithm(const Algorithm::Id id) { m_algorithm = id; } - inline void setAlgorithm(const char *algo) { m_algorithm = algo; } - inline void setClientId(const String &id) { m_clientId = id; } - inline void setHeight(uint64_t height) { m_height = height; } - inline void setIndex(uint8_t index) { m_index = index; } + inline bool isNicehash() const { return m_nicehash; } + inline bool isValid() const { return m_size > 0 && m_diff > 0; } + inline bool setId(const char *id) { return m_id = id; } + inline const Algorithm &algorithm() const { return m_algorithm; } + inline const Buffer &seed() const { return m_seed; } + inline const String &clientId() const { return m_clientId; } + inline const String &extraNonce() const { return m_extraNonce; } + inline const String &id() const { return m_id; } + inline const String &poolWallet() const { return m_poolWallet; } + inline const uint32_t *nonce() const { return reinterpret_cast(m_blob + 39); } + inline const uint8_t *blob() const { return m_blob; } + inline size_t size() const { return m_size; } + inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } + inline uint64_t diff() const { return m_diff; } + inline uint64_t height() const { return m_height; } + inline uint64_t target() const { return m_target; } + inline uint8_t fixedByte() const { return *(m_blob + 42); } + inline uint8_t index() const { return m_index; } + inline void reset() { m_size = 0; m_diff = 0; } + inline void setAlgorithm(const Algorithm::Id id) { m_algorithm = id; } + inline void setAlgorithm(const char *algo) { m_algorithm = algo; } + inline void setClientId(const String &id) { m_clientId = id; } + inline void setExtraNonce(const String &extraNonce) { m_extraNonce = extraNonce; } + inline void setHeight(uint64_t height) { m_height = height; } + inline void setIndex(uint8_t index) { m_index = index; } + inline void setPoolWallet(const String &poolWallet) { m_poolWallet = poolWallet; } # ifdef XMRIG_PROXY_PROJECT inline char *rawBlob() { return m_rawBlob; } @@ -103,7 +107,9 @@ private: Buffer m_seed; size_t m_size = 0; String m_clientId; + String m_extraNonce; String m_id; + String m_poolWallet; uint64_t m_diff = 0; uint64_t m_height = 0; uint64_t m_target = 0; diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index 072dc5347..ccce16c99 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -30,16 +30,12 @@ #include -#include "base/io/json/Json.h" #include "base/net/stratum/Pool.h" +#include "base/io/json/Json.h" +#include "base/io/log/Log.h" #include "rapidjson/document.h" -#ifdef APP_DEBUG -# include "base/io/log/Log.h" -#endif - - namespace xmrig { static const char *kAlgo = "algo"; @@ -52,6 +48,7 @@ static const char *kKeepalive = "keepalive"; static const char *kNicehash = "nicehash"; static const char *kPass = "pass"; static const char *kRigId = "rig-id"; +static const char *kSelfSelect = "self-select"; static const char *kTls = "tls"; static const char *kUrl = "url"; static const char *kUser = "user"; @@ -86,11 +83,18 @@ xmrig::Pool::Pool(const rapidjson::Value &object) : m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval); m_algorithm = Json::getString(object, kAlgo); m_coin = Json::getString(object, kCoin); + m_daemon = Json::getString(object, kSelfSelect); m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true)); m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash)); m_flags.set(FLAG_TLS, Json::getBool(object, kTls) || m_url.isTLS()); - m_flags.set(FLAG_DAEMON, Json::getBool(object, kDaemon)); + + if (m_daemon.isValid()) { + m_mode = MODE_SELF_SELECT; + } + else if (Json::getBool(object, kDaemon)) { + m_mode = MODE_DAEMON; + } const rapidjson::Value &keepalive = Json::getValue(object, kKeepalive); if (keepalive.IsInt()) { @@ -129,7 +133,7 @@ bool xmrig::Pool::isEnabled() const } # endif - if (isDaemon() && (!algorithm().isValid() && !coin().isValid())) { + if (m_mode == MODE_DAEMON && (!algorithm().isValid() && !coin().isValid())) { return false; } @@ -143,6 +147,7 @@ bool xmrig::Pool::isEqual(const Pool &other) const && m_keepAlive == other.m_keepAlive && m_algorithm == other.m_algorithm && m_coin == other.m_coin + && m_mode == other.m_mode && m_fingerprint == other.m_fingerprint && m_password == other.m_password && m_rigId == other.m_rigId @@ -166,7 +171,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const obj.AddMember(StringRef(kUrl), url().toJSON(), allocator); obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator); - if (!isDaemon()) { + if (m_mode != MODE_DAEMON) { obj.AddMember(StringRef(kPass), m_password.toJSON(), allocator); obj.AddMember(StringRef(kRigId), m_rigId.toJSON(), allocator); @@ -185,16 +190,37 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator); obj.AddMember(StringRef(kTls), isTLS(), allocator); obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator); - obj.AddMember(StringRef(kDaemon), m_flags.test(FLAG_DAEMON), allocator); + obj.AddMember(StringRef(kDaemon), m_mode == MODE_DAEMON, allocator); - if (isDaemon()) { + if (m_mode == MODE_DAEMON) { obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator); } + obj.AddMember(StringRef(kSelfSelect), m_daemon.url().toJSON(), allocator); + return obj; } +std::string xmrig::Pool::printableName() const +{ + std::string out(CSI "1;" + std::to_string(isEnabled() ? (isTLS() ? 32 : 36) : 31) + "m" + url().data() + CLEAR); + + if (m_coin.isValid()) { + out += std::string(" coin ") + WHITE_BOLD_S + m_coin.name() + CLEAR; + } + else { + out += std::string(" algo ") + WHITE_BOLD_S + (m_algorithm.isValid() ? m_algorithm.shortName() : "auto") + CLEAR; + } + + if (m_mode == MODE_SELF_SELECT) { + out += std::string(" self-select ") + CSI "1;" + std::to_string(m_daemon.isTLS() ? 32 : 36) + "m" + m_daemon.url().data() + CLEAR; + } + + return out; +} + + #ifdef APP_DEBUG void xmrig::Pool::print() const { diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h index fc6b6326a..3c7436022 100644 --- a/src/base/net/stratum/Pool.h +++ b/src/base/net/stratum/Pool.h @@ -42,12 +42,10 @@ namespace xmrig { class Pool { public: - enum Flags { - FLAG_ENABLED, - FLAG_NICEHASH, - FLAG_TLS, - FLAG_DAEMON, - FLAG_MAX + enum Mode { + MODE_POOL, + MODE_DAEMON, + MODE_SELF_SELECT }; static const String kDefaultPassword; @@ -69,7 +67,7 @@ public: bool tls = false ); - inline bool isDaemon() const { return m_flags.test(FLAG_DAEMON); } + inline bool isDaemon() const { return m_mode == MODE_DAEMON; } inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); } inline bool isTLS() const { return m_flags.test(FLAG_TLS); } inline bool isValid() const { return m_url.isValid(); } @@ -81,7 +79,9 @@ public: inline const String &rigId() const { return m_rigId; } inline const String &url() const { return m_url.url(); } inline const String &user() const { return !m_user.isNull() ? m_user : kDefaultUser; } + inline const Url &daemon() const { return m_daemon; } inline int keepAlive() const { return m_keepAlive; } + inline Mode mode() const { return m_mode; } inline uint16_t port() const { return m_url.port(); } inline uint64_t pollInterval() const { return m_pollInterval; } inline void setAlgo(const Algorithm &algorithm) { m_algorithm = algorithm; } @@ -95,24 +95,34 @@ public: bool isEnabled() const; bool isEqual(const Pool &other) const; rapidjson::Value toJSON(rapidjson::Document &doc) const; + std::string printableName() const; # ifdef APP_DEBUG void print() const; # endif private: + enum Flags { + FLAG_ENABLED, + FLAG_NICEHASH, + FLAG_TLS, + FLAG_MAX + }; + inline void setKeepAlive(bool enable) { setKeepAlive(enable ? kKeepAliveTimeout : 0); } inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } Algorithm m_algorithm; Coin m_coin; int m_keepAlive = 0; + Mode m_mode = MODE_POOL; std::bitset m_flags = 0; String m_fingerprint; String m_password; String m_rigId; String m_user; uint64_t m_pollInterval = kDefaultPollInterval; + Url m_daemon; Url m_url; }; diff --git a/src/base/net/stratum/Pools.cpp b/src/base/net/stratum/Pools.cpp index 600c97edb..c88e001fc 100644 --- a/src/base/net/stratum/Pools.cpp +++ b/src/base/net/stratum/Pools.cpp @@ -65,7 +65,7 @@ xmrig::IStrategy *xmrig::Pools::createStrategy(IStrategyListener *listener) cons } } - FailoverStrategy *strategy = new FailoverStrategy(retryPause(), retries(), listener); + auto strategy = new FailoverStrategy(retryPause(), retries(), listener); for (const Pool &pool : m_data) { if (pool.isEnabled()) { strategy->add(pool); @@ -135,13 +135,7 @@ void xmrig::Pools::print() const { size_t i = 1; for (const Pool &pool : m_data) { - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " %s " WHITE_BOLD("%s"), - i, - (pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31), - pool.url().data(), - pool.coin().isValid() ? "coin" : "algo", - pool.coin().isValid() ? pool.coin().name() : (pool.algorithm().isValid() ? pool.algorithm().shortName() : "auto") - ); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") "%s", i, pool.printableName().c_str()); i++; } diff --git a/src/base/net/stratum/Url.cpp b/src/base/net/stratum/Url.cpp index 193c72913..3de6bc9b8 100644 --- a/src/base/net/stratum/Url.cpp +++ b/src/base/net/stratum/Url.cpp @@ -81,8 +81,6 @@ bool xmrig::Url::isEqual(const Url &other) const bool xmrig::Url::parse(const char *url) { - assert(url != nullptr); - if (url == nullptr) { return false; } diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index ac288793a..a61f1a91a 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -56,6 +56,7 @@ static const option options[] = { { "http-no-restricted", 0, nullptr, IConfig::HttpRestrictedKey }, { "daemon", 0, nullptr, IConfig::DaemonKey }, { "daemon-poll-interval", 1, nullptr, IConfig::DaemonPollKey }, + { "self-select", 1, nullptr, IConfig::SelfSelectKey }, # endif { "av", 1, nullptr, IConfig::AVKey }, { "background", 0, nullptr, IConfig::BackgroundKey }, diff --git a/src/core/config/usage.h b/src/core/config/usage.h index 5d3718749..f5928fe9b 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -62,6 +62,7 @@ static inline const std::string &usage() # ifdef XMRIG_FEATURE_HTTP u += " --daemon use daemon RPC instead of pool for solo mining\n"; u += " --daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)\n"; + u += " --self-select=URL self-select block templates from URL\n"; # endif u += " -r, --retries=N number of times to retry before switch to backup server (default: 5)\n"; From e9d2e194f33a84865c02bd66b756a2a40051999f Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 12 Oct 2019 00:24:47 +0700 Subject: [PATCH 03/28] Added SelfSelectClient stub. --- src/base/base.cmake | 2 + src/base/kernel/interfaces/IClient.h | 2 +- src/base/kernel/interfaces/IClientListener.h | 2 +- src/base/net/stratum/BaseClient.h | 1 + src/base/net/stratum/Client.cpp | 8 +- src/base/net/stratum/Client.h | 5 +- src/base/net/stratum/DaemonClient.h | 7 +- src/base/net/stratum/Pool.cpp | 42 ++++++++- src/base/net/stratum/Pool.h | 6 +- src/base/net/stratum/SelfSelectClient.cpp | 40 +++++++++ src/base/net/stratum/SelfSelectClient.h | 87 +++++++++++++++++++ .../stratum/strategies/FailoverStrategy.cpp | 23 ++--- .../net/stratum/strategies/FailoverStrategy.h | 3 + .../stratum/strategies/SinglePoolStrategy.cpp | 23 +---- .../stratum/strategies/SinglePoolStrategy.h | 3 + src/net/strategies/DonateStrategy.cpp | 4 +- src/net/strategies/DonateStrategy.h | 2 +- 17 files changed, 209 insertions(+), 51 deletions(-) create mode 100644 src/base/net/stratum/SelfSelectClient.cpp create mode 100644 src/base/net/stratum/SelfSelectClient.h diff --git a/src/base/base.cmake b/src/base/base.cmake index 6a59c8acf..615d9ac5e 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -139,6 +139,7 @@ if (WITH_HTTP) src/base/net/http/HttpResponse.h src/base/net/http/HttpServer.h src/base/net/stratum/DaemonClient.h + src/base/net/stratum/SelfSelectClient.h src/base/net/tools/TcpServer.h ) @@ -154,6 +155,7 @@ if (WITH_HTTP) src/base/net/http/HttpResponse.cpp src/base/net/http/HttpServer.cpp src/base/net/stratum/DaemonClient.cpp + src/base/net/stratum/SelfSelectClient.cpp src/base/net/tools/TcpServer.cpp ) diff --git a/src/base/kernel/interfaces/IClient.h b/src/base/kernel/interfaces/IClient.h index c872a37ad..78e363485 100644 --- a/src/base/kernel/interfaces/IClient.h +++ b/src/base/kernel/interfaces/IClient.h @@ -26,7 +26,7 @@ #define XMRIG_ICLIENT_H -#include +#include namespace xmrig { diff --git a/src/base/kernel/interfaces/IClientListener.h b/src/base/kernel/interfaces/IClientListener.h index 3583be5ad..45b0bcfd2 100644 --- a/src/base/kernel/interfaces/IClientListener.h +++ b/src/base/kernel/interfaces/IClientListener.h @@ -26,7 +26,7 @@ #define XMRIG_ICLIENTLISTENER_H -#include +#include #include "rapidjson/fwd.h" diff --git a/src/base/net/stratum/BaseClient.h b/src/base/net/stratum/BaseClient.h index 56bdc1263..51da11133 100644 --- a/src/base/net/stratum/BaseClient.h +++ b/src/base/net/stratum/BaseClient.h @@ -46,6 +46,7 @@ class BaseClient : public IClient public: BaseClient(int id, IClientListener *listener); +protected: inline bool isEnabled() const override { return m_enabled; } inline const Job &job() const override { return m_job; } inline const Pool &pool() const override { return m_pool; } diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 287ce4a5e..70362bb8e 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -22,11 +22,11 @@ * along with this program. If not, see . */ -#include -#include +#include +#include #include -#include -#include +#include +#include #include diff --git a/src/base/net/stratum/Client.h b/src/base/net/stratum/Client.h index ff2bf7f6a..32121aa17 100644 --- a/src/base/net/stratum/Client.h +++ b/src/base/net/stratum/Client.h @@ -40,10 +40,11 @@ #include "base/net/stratum/SubmitResult.h" #include "base/net/tools/RecvBuf.h" #include "base/net/tools/Storage.h" +#include "base/tools/Object.h" #include "crypto/common/Algorithm.h" -typedef struct bio_st BIO; +using BIO = struct bio_st; namespace xmrig { @@ -56,6 +57,8 @@ class JobResult; class Client : public BaseClient, public IDnsListener, public ILineListener { public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(Client) + constexpr static uint64_t kConnectTimeout = 20 * 1000; constexpr static uint64_t kResponseTimeout = 20 * 1000; diff --git a/src/base/net/stratum/DaemonClient.h b/src/base/net/stratum/DaemonClient.h index 00b62e39a..781ea1b68 100644 --- a/src/base/net/stratum/DaemonClient.h +++ b/src/base/net/stratum/DaemonClient.h @@ -27,9 +27,10 @@ #define XMRIG_DAEMONCLIENT_H -#include "base/net/stratum/BaseClient.h" -#include "base/kernel/interfaces/ITimerListener.h" #include "base/kernel/interfaces/IHttpListener.h" +#include "base/kernel/interfaces/ITimerListener.h" +#include "base/net/stratum/BaseClient.h" +#include "base/tools/Object.h" namespace xmrig { @@ -38,6 +39,8 @@ namespace xmrig { class DaemonClient : public BaseClient, public ITimerListener, public IHttpListener { public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(DaemonClient) + DaemonClient(int id, IClientListener *listener); ~DaemonClient() override; diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index ccce16c99..1570d5fb7 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -33,9 +33,17 @@ #include "base/net/stratum/Pool.h" #include "base/io/json/Json.h" #include "base/io/log/Log.h" +#include "base/kernel/Platform.h" +#include "base/net/stratum/Client.h" #include "rapidjson/document.h" +#ifdef XMRIG_FEATURE_HTTP +# include "base/net/stratum/DaemonClient.h" +# include "base/net/stratum/SelfSelectClient.h" +#endif + + namespace xmrig { static const char *kAlgo = "algo"; @@ -128,7 +136,13 @@ bool xmrig::Pool::isEnabled() const # endif # ifndef XMRIG_FEATURE_HTTP - if (isDaemon()) { + if (m_mode == MODE_DAEMON) { + return false; + } +# endif + +# ifndef XMRIG_FEATURE_HTTP + if (m_mode == MODE_SELF_SELECT) { return false; } # endif @@ -158,6 +172,32 @@ bool xmrig::Pool::isEqual(const Pool &other) const } +xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) const +{ + IClient *client = nullptr; + + if (m_mode == MODE_POOL) { + client = new Client(id, Platform::userAgent(), listener); + } +# ifdef XMRIG_FEATURE_HTTP + else if (m_mode == MODE_DAEMON) { + client = new DaemonClient(id, listener); + } + else if (m_mode == MODE_SELF_SELECT) { + client = new SelfSelectClient(id, Platform::userAgent(), listener); + } +# endif + + assert(client != nullptr); + + if (client) { + client->setPool(*this); + } + + return client; +} + + rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const { using namespace rapidjson; diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h index 3c7436022..ca375c076 100644 --- a/src/base/net/stratum/Pool.h +++ b/src/base/net/stratum/Pool.h @@ -39,6 +39,10 @@ namespace xmrig { +class IClient; +class IClientListener; + + class Pool { public: @@ -67,7 +71,6 @@ public: bool tls = false ); - inline bool isDaemon() const { return m_mode == MODE_DAEMON; } inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); } inline bool isTLS() const { return m_flags.test(FLAG_TLS); } inline bool isValid() const { return m_url.isValid(); } @@ -94,6 +97,7 @@ public: bool isEnabled() const; bool isEqual(const Pool &other) const; + IClient *createClient(int id, IClientListener *listener) const; rapidjson::Value toJSON(rapidjson::Document &doc) const; std::string printableName() const; diff --git a/src/base/net/stratum/SelfSelectClient.cpp b/src/base/net/stratum/SelfSelectClient.cpp new file mode 100644 index 000000000..95a9ae957 --- /dev/null +++ b/src/base/net/stratum/SelfSelectClient.cpp @@ -0,0 +1,40 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "base/net/stratum/SelfSelectClient.h" +#include "base/net/stratum/Client.h" + + +xmrig::SelfSelectClient::SelfSelectClient(int id, const char *agent, IClientListener *listener) : + m_listener(listener) +{ + m_client = new Client(id, agent, this); +} + + +xmrig::SelfSelectClient::~SelfSelectClient() +{ + delete m_client; +} diff --git a/src/base/net/stratum/SelfSelectClient.h b/src/base/net/stratum/SelfSelectClient.h new file mode 100644 index 000000000..b4549ebe4 --- /dev/null +++ b/src/base/net/stratum/SelfSelectClient.h @@ -0,0 +1,87 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_SELFSELECTCLIENT_H +#define XMRIG_SELFSELECTCLIENT_H + + +#include "base/kernel/interfaces/IClientListener.h" +#include "base/tools/Object.h" +#include "base/kernel/interfaces/IClient.h" + + +namespace xmrig { + + +class SelfSelectClient : public IClient, public IClientListener +{ +public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(SelfSelectClient) + + SelfSelectClient(int id, const char *agent, IClientListener *listener); + ~SelfSelectClient() override; + +protected: + // IClient + bool disconnect() override { return m_client->disconnect(); } + bool hasExtension(Extension extension) const noexcept override { return m_client->hasExtension(extension); } + bool isEnabled() const override { return m_client->isEnabled(); } + bool isTLS() const override { return m_client->isTLS(); } + const char *mode() const override { return m_client->mode(); } + const char *tlsFingerprint() const override { return m_client->tlsFingerprint(); } + const char *tlsVersion() const override { return m_client->tlsVersion(); } + const Job &job() const override { return m_client->job(); } + const Pool &pool() const override { return m_client->pool(); } + const String &ip() const override { return m_client->ip(); } + int id() const override { return m_client->id(); } + int64_t submit(const JobResult &result) override { return m_client->submit(result); } + void connect() override { m_client->connect(); } + void connect(const Pool &pool) override { m_client->connect(pool); } + void deleteLater() override { m_client->deleteLater(); } + void setAlgo(const Algorithm &algo) override { m_client->setAlgo(algo); } + void setEnabled(bool enabled) override { m_client->setEnabled(enabled); } + void setPool(const Pool &pool) override { m_client->setPool(pool); } + void setQuiet(bool quiet) override { m_client->setQuiet(quiet); } + void setRetries(int retries) override { m_client->setRetries(retries); } + void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); } + void tick(uint64_t now) override { m_client->tick(now); } + + // IClientListener + void onClose(IClient *, int failures) override { m_listener->onClose(this, failures); } + void onJobReceived(IClient *, const Job &job, const rapidjson::Value ¶ms) override { m_listener->onJobReceived(this, job, params); } + void onLogin(IClient *, rapidjson::Document &doc, rapidjson::Value ¶ms) override { m_listener->onLogin(this, doc, params); } + void onLoginSuccess(IClient *) override { m_listener->onLoginSuccess(this); } + void onResultAccepted(IClient *, const SubmitResult &result, const char *error) override { m_listener->onResultAccepted(this, result, error); } + void onVerifyAlgorithm(const IClient *, const Algorithm &algorithm, bool *ok) override { m_listener->onVerifyAlgorithm(this, algorithm, ok); } + +private: + IClient *m_client; + IClientListener *m_listener; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_SELFSELECTCLIENT_H */ diff --git a/src/base/net/stratum/strategies/FailoverStrategy.cpp b/src/base/net/stratum/strategies/FailoverStrategy.cpp index 48be2ba35..28c1ad99f 100644 --- a/src/base/net/stratum/strategies/FailoverStrategy.cpp +++ b/src/base/net/stratum/strategies/FailoverStrategy.cpp @@ -23,15 +23,10 @@ */ +#include "base/net/stratum/strategies/FailoverStrategy.h" +#include "base/kernel/interfaces/IClient.h" #include "base/kernel/interfaces/IStrategyListener.h" #include "base/kernel/Platform.h" -#include "base/net/stratum/Client.h" -#include "base/net/stratum/strategies/FailoverStrategy.h" - - -#ifdef XMRIG_FEATURE_HTTP -# include "base/net/stratum/DaemonClient.h" -#endif xmrig::FailoverStrategy::FailoverStrategy(const std::vector &pools, int retryPause, int retries, IStrategyListener *listener, bool quiet) : @@ -69,16 +64,8 @@ xmrig::FailoverStrategy::~FailoverStrategy() void xmrig::FailoverStrategy::add(const Pool &pool) { - const int id = static_cast(m_pools.size()); + IClient *client = pool.createClient(static_cast(m_pools.size()), this); -# ifdef XMRIG_FEATURE_HTTP - IClient *client = !pool.isDaemon() ? static_cast(new Client(id, Platform::userAgent(), this)) - : static_cast(new DaemonClient(id, this)); -# else - IClient *client = new Client(id, Platform::userAgent(), this); -# endif - - client->setPool(pool); client->setRetries(m_retries); client->setRetryPause(m_retryPause * 1000); client->setQuiet(m_quiet); @@ -123,8 +110,8 @@ void xmrig::FailoverStrategy::setAlgo(const Algorithm &algo) void xmrig::FailoverStrategy::stop() { - for (size_t i = 0; i < m_pools.size(); ++i) { - m_pools[i]->disconnect(); + for (auto &pool : m_pools) { + pool->disconnect(); } m_index = 0; diff --git a/src/base/net/stratum/strategies/FailoverStrategy.h b/src/base/net/stratum/strategies/FailoverStrategy.h index 283d49165..c69160ee9 100644 --- a/src/base/net/stratum/strategies/FailoverStrategy.h +++ b/src/base/net/stratum/strategies/FailoverStrategy.h @@ -32,6 +32,7 @@ #include "base/kernel/interfaces/IClientListener.h" #include "base/kernel/interfaces/IStrategy.h" #include "base/net/stratum/Pool.h" +#include "base/tools/Object.h" namespace xmrig { @@ -44,6 +45,8 @@ class IStrategyListener; class FailoverStrategy : public IStrategy, public IClientListener { public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(FailoverStrategy) + FailoverStrategy(const std::vector &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false); FailoverStrategy(int retryPause, int retries, IStrategyListener *listener, bool quiet = false); ~FailoverStrategy() override; diff --git a/src/base/net/stratum/strategies/SinglePoolStrategy.cpp b/src/base/net/stratum/strategies/SinglePoolStrategy.cpp index c923e1c2c..a45be658f 100644 --- a/src/base/net/stratum/strategies/SinglePoolStrategy.cpp +++ b/src/base/net/stratum/strategies/SinglePoolStrategy.cpp @@ -23,33 +23,18 @@ */ +#include "base/net/stratum/strategies/SinglePoolStrategy.h" +#include "base/kernel/interfaces/IClient.h" #include "base/kernel/interfaces/IStrategyListener.h" #include "base/kernel/Platform.h" -#include "base/net/stratum/Client.h" -#include "base/net/stratum/strategies/SinglePoolStrategy.h" - - -#ifdef XMRIG_FEATURE_HTTP -# include "base/net/stratum/DaemonClient.h" -#endif +#include "base/net/stratum/Pool.h" xmrig::SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet) : m_active(false), m_listener(listener) { -# ifdef XMRIG_FEATURE_HTTP - if (!pool.isDaemon()) { - m_client = new Client(0, Platform::userAgent(), this); - } - else { - m_client = new DaemonClient(0, this); - } -# else - m_client = new Client(0, Platform::userAgent(), this); -# endif - - m_client->setPool(pool); + m_client = pool.createClient(0, this); m_client->setRetries(retries); m_client->setRetryPause(retryPause * 1000); m_client->setQuiet(quiet); diff --git a/src/base/net/stratum/strategies/SinglePoolStrategy.h b/src/base/net/stratum/strategies/SinglePoolStrategy.h index ea808193c..f2c8b2297 100644 --- a/src/base/net/stratum/strategies/SinglePoolStrategy.h +++ b/src/base/net/stratum/strategies/SinglePoolStrategy.h @@ -28,6 +28,7 @@ #include "base/kernel/interfaces/IClientListener.h" #include "base/kernel/interfaces/IStrategy.h" +#include "base/tools/Object.h" namespace xmrig { @@ -41,6 +42,8 @@ class Pool; class SinglePoolStrategy : public IStrategy, public IClientListener { public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(SinglePoolStrategy) + SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false); ~SinglePoolStrategy() override; diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 3952d94ec..2be0af049 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -234,7 +234,7 @@ void xmrig::DonateStrategy::onTimer(const Timer *) } -xmrig::Client *xmrig::DonateStrategy::createProxy() +xmrig::IClient *xmrig::DonateStrategy::createProxy() { if (m_controller->config()->pools().proxyDonate() == Pools::PROXY_DONATE_NONE) { return nullptr; @@ -251,7 +251,7 @@ xmrig::Client *xmrig::DonateStrategy::createProxy() Pool pool(client->ip(), client->pool().port(), m_userId, client->pool().password(), 0, true, client->isTLS()); pool.setAlgo(client->pool().algorithm()); - auto proxy = new Client(-1, Platform::userAgent(), this); + IClient *proxy = new Client(-1, Platform::userAgent(), this); proxy->setPool(pool); proxy->setQuiet(true); diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index 4c621f667..c249284b5 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -91,7 +91,7 @@ private: inline State state() const { return m_state; } - Client *createProxy(); + IClient *createProxy(); void idle(double min, double max); void setAlgorithms(rapidjson::Document &doc, rapidjson::Value ¶ms); void setJob(IClient *client, const Job &job); From 3752551e5351479aa942cb520bf91cc482d923a3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 12 Oct 2019 19:48:18 +0700 Subject: [PATCH 04/28] Self-select initial working implementation. --- src/base/kernel/interfaces/IClient.h | 5 +- src/base/net/stratum/BaseClient.cpp | 8 +- src/base/net/stratum/BaseClient.h | 13 +- src/base/net/stratum/Client.cpp | 71 +++++--- src/base/net/stratum/Client.h | 3 +- src/base/net/stratum/DaemonClient.h | 1 + src/base/net/stratum/Pool.cpp | 1 + src/base/net/stratum/SelfSelectClient.cpp | 194 ++++++++++++++++++++++ src/base/net/stratum/SelfSelectClient.h | 80 +++++---- 9 files changed, 302 insertions(+), 74 deletions(-) diff --git a/src/base/kernel/interfaces/IClient.h b/src/base/kernel/interfaces/IClient.h index 78e363485..06e129684 100644 --- a/src/base/kernel/interfaces/IClient.h +++ b/src/base/kernel/interfaces/IClient.h @@ -26,7 +26,7 @@ #define XMRIG_ICLIENT_H -#include +#include "rapidjson/fwd.h" namespace xmrig { @@ -64,6 +64,8 @@ public: virtual const Pool &pool() const = 0; virtual const String &ip() const = 0; virtual int id() const = 0; + virtual int64_t send(const rapidjson::Value &obj) = 0; + virtual int64_t sequence() const = 0; virtual int64_t submit(const JobResult &result) = 0; virtual void connect() = 0; virtual void connect(const Pool &pool) = 0; @@ -75,7 +77,6 @@ public: virtual void setRetries(int retries) = 0; virtual void setRetryPause(uint64_t ms) = 0; virtual void tick(uint64_t now) = 0; - }; diff --git a/src/base/net/stratum/BaseClient.cpp b/src/base/net/stratum/BaseClient.cpp index 325fce1c8..ccffa7ce7 100644 --- a/src/base/net/stratum/BaseClient.cpp +++ b/src/base/net/stratum/BaseClient.cpp @@ -36,14 +36,8 @@ int64_t BaseClient::m_sequence = 1; xmrig::BaseClient::BaseClient(int id, IClientListener *listener) : - m_quiet(false), m_listener(listener), - m_id(id), - m_retries(5), - m_failures(0), - m_state(UnconnectedState), - m_retryPause(5000), - m_enabled(true) + m_id(id) { } diff --git a/src/base/net/stratum/BaseClient.h b/src/base/net/stratum/BaseClient.h index 51da11133..0d73dc9bf 100644 --- a/src/base/net/stratum/BaseClient.h +++ b/src/base/net/stratum/BaseClient.h @@ -52,6 +52,7 @@ protected: inline const Pool &pool() const override { return m_pool; } inline const String &ip() const override { return m_ip; } inline int id() const override { return m_id; } + inline int64_t sequence() const override { return m_sequence; } inline void setAlgo(const Algorithm &algo) override { m_pool.setAlgo(algo); } inline void setEnabled(bool enabled) override { m_enabled = enabled; } inline void setPool(const Pool &pool) override { if (pool.isValid()) { m_pool = pool; } } @@ -73,22 +74,22 @@ protected: bool handleSubmitResponse(int64_t id, const char *error = nullptr); - bool m_quiet; + bool m_quiet = false; IClientListener *m_listener; int m_id; - int m_retries; - int64_t m_failures; + int m_retries = 5; + int64_t m_failures = 0; Job m_job; Pool m_pool; - SocketState m_state; + SocketState m_state = UnconnectedState; std::map m_results; String m_ip; - uint64_t m_retryPause; + uint64_t m_retryPause = 5000; static int64_t m_sequence; private: - bool m_enabled; + bool m_enabled = true; }; diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 70362bb8e..543495335 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018-2019 SChernykh + * Copyright 2019 jtgrassie * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -136,6 +137,31 @@ const char *xmrig::Client::tlsVersion() const } +int64_t xmrig::Client::send(const rapidjson::Value &obj) +{ + using namespace rapidjson; + + Value value; + + StringBuffer buffer(nullptr, 512); + Writer writer(buffer); + obj.Accept(writer); + + const size_t size = buffer.GetSize(); + if (size > (sizeof(m_sendBuf) - 2)) { + LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", url(), size, (sizeof(m_sendBuf) - 2)); + close(); + return -1; + } + + memcpy(m_sendBuf, buffer.GetString(), size); + m_sendBuf[size] = '\n'; + m_sendBuf[size + 1] = '\0'; + + return send(size + 1); +} + + int64_t xmrig::Client::submit(const JobResult &result) { # ifndef XMRIG_PROXY_PROJECT @@ -320,9 +346,23 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - if (!job.setBlob(params["blob"].GetString())) { - *code = 4; - return false; +# ifdef XMRIG_FEATURE_HTTP + if (m_pool.mode() == Pool::MODE_SELF_SELECT) { + job.setExtraNonce(Json::getString(params, "extra_nonce")); + job.setPoolWallet(Json::getString(params, "pool_wallet")); + + if (job.extraNonce().isNull() || job.poolWallet().isNull()) { + *code = 4; + return false; + } + } + else +# endif + { + if (!job.setBlob(params["blob"].GetString())) { + *code = 4; + return false; + } } if (!job.setTarget(params["target"].GetString())) { @@ -345,7 +385,7 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - if (job.algorithm().family() == Algorithm::RANDOM_X && !job.setSeedHash(Json::getString(params, "seed_hash"))) { + if (m_pool.mode() != Pool::MODE_SELF_SELECT && job.algorithm().family() == Algorithm::RANDOM_X && !job.setSeedHash(Json::getString(params, "seed_hash"))) { if (!isQuiet()) { LOG_ERR("[%s] failed to parse field \"seed_hash\" required by RandomX", url(), algo); } @@ -473,29 +513,6 @@ int xmrig::Client::resolve(const String &host) } -int64_t xmrig::Client::send(const rapidjson::Document &doc) -{ - using namespace rapidjson; - - StringBuffer buffer(nullptr, 512); - Writer writer(buffer); - doc.Accept(writer); - - const size_t size = buffer.GetSize(); - if (size > (sizeof(m_sendBuf) - 2)) { - LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", url(), size, (sizeof(m_sendBuf) - 2)); - close(); - return -1; - } - - memcpy(m_sendBuf, buffer.GetString(), size); - m_sendBuf[size] = '\n'; - m_sendBuf[size + 1] = '\0'; - - return send(size + 1); -} - - int64_t xmrig::Client::send(size_t size) { LOG_DEBUG("[%s] send (%d bytes): \"%.*s\"", url(), size, static_cast(size) - 1, m_sendBuf); diff --git a/src/base/net/stratum/Client.h b/src/base/net/stratum/Client.h index 32121aa17..8ff58c639 100644 --- a/src/base/net/stratum/Client.h +++ b/src/base/net/stratum/Client.h @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018-2019 SChernykh + * Copyright 2019 jtgrassie * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -76,6 +77,7 @@ protected: bool isTLS() const override; const char *tlsFingerprint() const override; const char *tlsVersion() const override; + int64_t send(const rapidjson::Value &obj) override; int64_t submit(const JobResult &result) override; void connect() override; void connect(const Pool &pool) override; @@ -98,7 +100,6 @@ private: bool send(BIO *bio); bool verifyAlgorithm(const Algorithm &algorithm, const char *algo) const; int resolve(const String &host); - int64_t send(const rapidjson::Document &doc); int64_t send(size_t size); void connect(sockaddr *addr); void handshake(); diff --git a/src/base/net/stratum/DaemonClient.h b/src/base/net/stratum/DaemonClient.h index 781ea1b68..0932b2bee 100644 --- a/src/base/net/stratum/DaemonClient.h +++ b/src/base/net/stratum/DaemonClient.h @@ -58,6 +58,7 @@ protected: inline const char *mode() const override { return "daemon"; } inline const char *tlsFingerprint() const override { return m_tlsFingerprint; } inline const char *tlsVersion() const override { return m_tlsVersion; } + inline int64_t send(const rapidjson::Value &) override { return -1; } inline void deleteLater() override { delete this; } inline void tick(uint64_t) override {} diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index 1570d5fb7..71152fd0a 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -168,6 +168,7 @@ bool xmrig::Pool::isEqual(const Pool &other) const && m_url == other.m_url && m_user == other.m_user && m_pollInterval == other.m_pollInterval + && m_daemon == other.m_daemon ); } diff --git a/src/base/net/stratum/SelfSelectClient.cpp b/src/base/net/stratum/SelfSelectClient.cpp index 95a9ae957..7398d6ee4 100644 --- a/src/base/net/stratum/SelfSelectClient.cpp +++ b/src/base/net/stratum/SelfSelectClient.cpp @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018-2019 SChernykh + * Copyright 2019 jtgrassie * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -24,7 +25,39 @@ #include "base/net/stratum/SelfSelectClient.h" +#include "3rdparty/http-parser/http_parser.h" +#include "base/io/json/Json.h" +#include "base/io/json/JsonRequest.h" +#include "base/io/log/Log.h" +#include "base/net/http/HttpClient.h" #include "base/net/stratum/Client.h" +#include "rapidjson/document.h" +#include "rapidjson/error/en.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/writer.h" + + +#ifdef XMRIG_FEATURE_TLS +# include "base/net/http/HttpsClient.h" +#endif + + +namespace xmrig { + +static const char *kBlob = "blob"; +static const char *kBlockhashingBlob = "blockhashing_blob"; +static const char *kBlocktemplateBlob = "blocktemplate_blob"; +static const char *kDifficulty = "difficulty"; +static const char *kHeight = "height"; +static const char *kId = "id"; +static const char *kJobId = "job_id"; +static const char *kNextSeedHash = "next_seed_hash"; +static const char *kPrevHash = "prev_hash"; +static const char *kSeedHash = "seed_hash"; + +static const char * const required_fields[] = { kBlocktemplateBlob, kBlockhashingBlob, kHeight, kDifficulty, kPrevHash }; + +} /* namespace xmrig */ xmrig::SelfSelectClient::SelfSelectClient(int id, const char *agent, IClientListener *listener) : @@ -38,3 +71,164 @@ xmrig::SelfSelectClient::~SelfSelectClient() { delete m_client; } + + +void xmrig::SelfSelectClient::onJobReceived(IClient *, const Job &job, const rapidjson::Value &) +{ + m_job = job; + + getBlockTemplate(); +} + + +void xmrig::SelfSelectClient::onLogin(IClient *, rapidjson::Document &doc, rapidjson::Value ¶ms) +{ + params.AddMember("mode", "self-select", doc.GetAllocator()); + + m_listener->onLogin(this, doc, params); +} + + +bool xmrig::SelfSelectClient::parseResponse(int64_t id, rapidjson::Value &result, const rapidjson::Value &error) +{ + if (id == -1) { + return false; + } + + if (error.IsObject()) { + LOG_ERR("[%s:%d] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", pool().daemon().host().data(), pool().daemon().port(), Json::getString(error, "message"), Json::getInt(error, "code")); + + return false; + } + + if (!result.IsObject()) { + return false; + } + + for (auto field : required_fields) { + if (!result.HasMember(field)) { + LOG_ERR("[%s:%d] required field " RED_BOLD("\"%s\"") RED_S " not found", pool().daemon().host().data(), pool().daemon().port(), field); + + return false; + } + } + + if (!m_job.setBlob(result[kBlockhashingBlob].GetString())) { + return false; + } + + m_job.setHeight(Json::getUint64(result, kHeight)); + m_job.setSeedHash(Json::getString(result, kSeedHash)); + + submitBlockTemplate(result); + + m_listener->onJobReceived(this, m_job, rapidjson::Value{}); + + return true; +} + + +void xmrig::SelfSelectClient::getBlockTemplate() +{ + using namespace rapidjson; + Document doc(kObjectType); + auto &allocator = doc.GetAllocator(); + + Value params(kObjectType); + params.AddMember("wallet_address", m_job.poolWallet().toJSON(), allocator); + params.AddMember("extra_nonce", m_job.extraNonce().toJSON(), allocator); + + JsonRequest::create(doc, sequence(), "getblocktemplate", params); + + send(HTTP_POST, "/json_rpc", doc); +} + + +void xmrig::SelfSelectClient::retry() +{ + // FIXME +} + + +void xmrig::SelfSelectClient::send(int method, const char *url, const char *data, size_t size) +{ + LOG_DEBUG("[%s:%d] " MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD_S " send (%zu bytes): \"%.*s\"", + pool().daemon().host().data(), + pool().daemon().port(), + http_method_str(static_cast(method)), + url, + size, + static_cast(size), + data); + + HttpClient *client; +# ifdef XMRIG_FEATURE_TLS + if (pool().daemon().isTLS()) { + client = new HttpsClient(method, url, this, data, size, String()); + } + else +# endif + { + client = new HttpClient(method, url, this, data, size); + } + + client->setQuiet(m_quiet); + client->connect(pool().daemon().host(), pool().daemon().port()); +} + + +void xmrig::SelfSelectClient::send(int method, const char *url, const rapidjson::Document &doc) +{ + using namespace rapidjson; + + StringBuffer buffer(nullptr, 512); + Writer writer(buffer); + doc.Accept(writer); + + send(method, url, buffer.GetString(), buffer.GetSize()); +} + + +void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result) +{ + using namespace rapidjson; + Document doc(kObjectType); + auto &allocator = doc.GetAllocator(); + + Value params(kObjectType); + params.AddMember(StringRef(kId), m_job.clientId().toJSON(), allocator); + params.AddMember(StringRef(kJobId), m_job.id().toJSON(), allocator); + params.AddMember(StringRef(kBlob), result[kBlocktemplateBlob], allocator); + params.AddMember(StringRef(kHeight), m_job.height(), allocator); + params.AddMember(StringRef(kDifficulty), result[kDifficulty], allocator); + params.AddMember(StringRef(kPrevHash), result[kPrevHash], allocator); + params.AddMember(StringRef(kSeedHash), result[kSeedHash], allocator); + params.AddMember(StringRef(kNextSeedHash), result[kNextSeedHash], allocator); + + JsonRequest::create(doc, sequence(), "block_template", params); + + send(doc); +} + + +void xmrig::SelfSelectClient::onHttpData(const HttpData &data) +{ + if (data.status != HTTP_STATUS_OK) { + return retry(); + } + + LOG_DEBUG("[%s:%d] received (%d bytes): \"%.*s\"", pool().daemon().host().data(), pool().daemon().port(), static_cast(data.body.size()), static_cast(data.body.size()), data.body.c_str()); + + rapidjson::Document doc; + if (doc.Parse(data.body.c_str()).HasParseError()) { + if (!m_quiet) { + LOG_ERR("[%s:%d] JSON decode failed: \"%s\"", pool().daemon().host().data(), pool().daemon().port(), rapidjson::GetParseError_En(doc.GetParseError())); + } + + return retry(); + } + + if (!parseResponse(Json::getInt64(doc, "id", -1), doc["result"], Json::getObject(doc, "error"))) { + retry(); + } +} diff --git a/src/base/net/stratum/SelfSelectClient.h b/src/base/net/stratum/SelfSelectClient.h index b4549ebe4..aa39d4306 100644 --- a/src/base/net/stratum/SelfSelectClient.h +++ b/src/base/net/stratum/SelfSelectClient.h @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018-2019 SChernykh + * Copyright 2019 jtgrassie * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -26,15 +27,17 @@ #define XMRIG_SELFSELECTCLIENT_H -#include "base/kernel/interfaces/IClientListener.h" -#include "base/tools/Object.h" #include "base/kernel/interfaces/IClient.h" +#include "base/kernel/interfaces/IClientListener.h" +#include "base/kernel/interfaces/IHttpListener.h" +#include "base/net/stratum/Job.h" +#include "base/tools/Object.h" namespace xmrig { -class SelfSelectClient : public IClient, public IClientListener +class SelfSelectClient : public IClient, public IClientListener, public IHttpListener { public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(SelfSelectClient) @@ -44,40 +47,55 @@ public: protected: // IClient - bool disconnect() override { return m_client->disconnect(); } - bool hasExtension(Extension extension) const noexcept override { return m_client->hasExtension(extension); } - bool isEnabled() const override { return m_client->isEnabled(); } - bool isTLS() const override { return m_client->isTLS(); } - const char *mode() const override { return m_client->mode(); } - const char *tlsFingerprint() const override { return m_client->tlsFingerprint(); } - const char *tlsVersion() const override { return m_client->tlsVersion(); } - const Job &job() const override { return m_client->job(); } - const Pool &pool() const override { return m_client->pool(); } - const String &ip() const override { return m_client->ip(); } - int id() const override { return m_client->id(); } - int64_t submit(const JobResult &result) override { return m_client->submit(result); } - void connect() override { m_client->connect(); } - void connect(const Pool &pool) override { m_client->connect(pool); } - void deleteLater() override { m_client->deleteLater(); } - void setAlgo(const Algorithm &algo) override { m_client->setAlgo(algo); } - void setEnabled(bool enabled) override { m_client->setEnabled(enabled); } - void setPool(const Pool &pool) override { m_client->setPool(pool); } - void setQuiet(bool quiet) override { m_client->setQuiet(quiet); } - void setRetries(int retries) override { m_client->setRetries(retries); } - void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); } - void tick(uint64_t now) override { m_client->tick(now); } + inline bool disconnect() override { return m_client->disconnect(); } + inline bool hasExtension(Extension extension) const noexcept override { return m_client->hasExtension(extension); } + inline bool isEnabled() const override { return m_client->isEnabled(); } + inline bool isTLS() const override { return m_client->isTLS(); } + inline const char *mode() const override { return m_client->mode(); } + inline const char *tlsFingerprint() const override { return m_client->tlsFingerprint(); } + inline const char *tlsVersion() const override { return m_client->tlsVersion(); } + inline const Job &job() const override { return m_client->job(); } + inline const Pool &pool() const override { return m_client->pool(); } + inline const String &ip() const override { return m_client->ip(); } + inline int id() const override { return m_client->id(); } + inline int64_t send(const rapidjson::Value &obj) override { return m_client->send(obj); } + inline int64_t sequence() const override { return m_client->sequence(); } + inline int64_t submit(const JobResult &result) override { return m_client->submit(result); } + inline void connect() override { m_client->connect(); } + inline void connect(const Pool &pool) override { m_client->connect(pool); } + inline void deleteLater() override { m_client->deleteLater(); } + inline void setAlgo(const Algorithm &algo) override { m_client->setAlgo(algo); } + inline void setEnabled(bool enabled) override { m_client->setEnabled(enabled); } + inline void setPool(const Pool &pool) override { m_client->setPool(pool); } + inline void setQuiet(bool quiet) override { m_client->setQuiet(quiet); m_quiet = quiet; } + inline void setRetries(int retries) override { m_client->setRetries(retries); } + inline void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); } + inline void tick(uint64_t now) override { m_client->tick(now); } // IClientListener - void onClose(IClient *, int failures) override { m_listener->onClose(this, failures); } - void onJobReceived(IClient *, const Job &job, const rapidjson::Value ¶ms) override { m_listener->onJobReceived(this, job, params); } - void onLogin(IClient *, rapidjson::Document &doc, rapidjson::Value ¶ms) override { m_listener->onLogin(this, doc, params); } - void onLoginSuccess(IClient *) override { m_listener->onLoginSuccess(this); } - void onResultAccepted(IClient *, const SubmitResult &result, const char *error) override { m_listener->onResultAccepted(this, result, error); } - void onVerifyAlgorithm(const IClient *, const Algorithm &algorithm, bool *ok) override { m_listener->onVerifyAlgorithm(this, algorithm, ok); } + inline void onClose(IClient *, int failures) override { m_listener->onClose(this, failures); } + inline void onLoginSuccess(IClient *) override { m_listener->onLoginSuccess(this); } + inline void onResultAccepted(IClient *, const SubmitResult &result, const char *error) override { m_listener->onResultAccepted(this, result, error); } + inline void onVerifyAlgorithm(const IClient *, const Algorithm &algorithm, bool *ok) override { m_listener->onVerifyAlgorithm(this, algorithm, ok); } + + void onJobReceived(IClient *, const Job &job, const rapidjson::Value ¶ms) override; + void onLogin(IClient *, rapidjson::Document &doc, rapidjson::Value ¶ms) override; + + // IHttpListener + void onHttpData(const HttpData &data) override; private: + bool parseResponse(int64_t id, rapidjson::Value &result, const rapidjson::Value &error); + void getBlockTemplate(); + void retry(); + void send(int method, const char *url, const char *data = nullptr, size_t size = 0); + void send(int method, const char *url, const rapidjson::Document &doc); + void submitBlockTemplate(rapidjson::Value &result); + + bool m_quiet = false; IClient *m_client; IClientListener *m_listener; + Job m_job; }; From c9798ba2e9170afeb6781de487a8779235cef82d Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sun, 13 Oct 2019 22:13:29 +0200 Subject: [PATCH 05/28] Sync with latest RandomX code Fix a possible out-of-bounds access in superscalar generator --- src/crypto/randomx/superscalar.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/crypto/randomx/superscalar.cpp b/src/crypto/randomx/superscalar.cpp index aaa91f620..7586c0282 100644 --- a/src/crypto/randomx/superscalar.cpp +++ b/src/crypto/randomx/superscalar.cpp @@ -631,7 +631,7 @@ namespace randomx { int cycle1 = scheduleUop(mop.getUop1(), portBusy, cycle); int cycle2 = scheduleUop(mop.getUop2(), portBusy, cycle); - if (cycle1 == cycle2) { + if (cycle1 >= 0 && cycle1 == cycle2) { if (commit) { scheduleUop(mop.getUop1(), portBusy, cycle1); scheduleUop(mop.getUop2(), portBusy, cycle2); @@ -755,6 +755,12 @@ namespace randomx { //recalculate when the instruction can be scheduled for execution based on operand availability scheduleCycle = scheduleMop(mop, portBusy, scheduleCycle, scheduleCycle); + if (scheduleCycle < 0) { + if (trace) std::cout << "Unable to map operation '" << mop.getName() << "' to execution port (cycle " << scheduleCycle << ")" << std::endl; + portsSaturated = true; + break; + } + //calculate when the result will be ready depCycle = scheduleCycle + mop.getLatency(); From ed08895d4a5243b3fe588b297c16080c8d851c5d Mon Sep 17 00:00:00 2001 From: Anton Kamenov Date: Mon, 14 Oct 2019 13:34:17 +0300 Subject: [PATCH 06/28] Fixes OclDevice::globalMemSize() that sometimes returns 0 --- src/backend/opencl/wrappers/OclDevice.cpp | 20 ++------------------ src/backend/opencl/wrappers/OclDevice.h | 10 +++++++--- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/backend/opencl/wrappers/OclDevice.cpp b/src/backend/opencl/wrappers/OclDevice.cpp index 67f8166b5..14e815608 100644 --- a/src/backend/opencl/wrappers/OclDevice.cpp +++ b/src/backend/opencl/wrappers/OclDevice.cpp @@ -132,6 +132,8 @@ xmrig::OclDevice::OclDevice(uint32_t index, cl_device_id id, cl_platform_id plat m_board(OclLib::getString(id, 0x4038 /* CL_DEVICE_BOARD_NAME_AMD */)), m_name(OclLib::getString(id, CL_DEVICE_NAME)), m_vendor(OclLib::getString(id, CL_DEVICE_VENDOR)), + m_maxMemoryAlloc(OclLib::getUlong(id, CL_DEVICE_MAX_MEM_ALLOC_SIZE)), + m_globalMemory(OclLib::getUlong(id, CL_DEVICE_GLOBAL_MEM_SIZE)), m_computeUnits(OclLib::getUint(id, CL_DEVICE_MAX_COMPUTE_UNITS, 1)), m_index(index) { @@ -155,24 +157,6 @@ xmrig::OclDevice::OclDevice(uint32_t index, cl_device_id id, cl_platform_id plat } -size_t xmrig::OclDevice::freeMemSize() const -{ - return std::min(maxMemAllocSize(), globalMemSize()); -} - - -size_t xmrig::OclDevice::globalMemSize() const -{ - return OclLib::getUlong(id(), CL_DEVICE_GLOBAL_MEM_SIZE); -} - - -size_t xmrig::OclDevice::maxMemAllocSize() const -{ - return OclLib::getUlong(id(), CL_DEVICE_MAX_MEM_ALLOC_SIZE); -} - - xmrig::String xmrig::OclDevice::printableName() const { const size_t size = m_board.size() + m_name.size() + 64; diff --git a/src/backend/opencl/wrappers/OclDevice.h b/src/backend/opencl/wrappers/OclDevice.h index 3be58ed22..faf03b667 100644 --- a/src/backend/opencl/wrappers/OclDevice.h +++ b/src/backend/opencl/wrappers/OclDevice.h @@ -33,6 +33,7 @@ #include "backend/opencl/wrappers/OclVendor.h" #include "base/tools/String.h" +#include using cl_device_id = struct _cl_device_id *; using cl_platform_id = struct _cl_platform_id *; @@ -62,9 +63,6 @@ public: OclDevice() = delete; OclDevice(uint32_t index, cl_device_id id, cl_platform_id platform); - size_t freeMemSize() const; - size_t globalMemSize() const; - size_t maxMemAllocSize() const; String printableName() const; uint32_t clock() const; void generate(const Algorithm &algorithm, OclThreads &threads) const; @@ -78,6 +76,9 @@ public: inline OclVendor vendorId() const { return m_vendorId; } inline Type type() const { return m_type; } inline uint32_t computeUnits() const { return m_computeUnits; } + inline size_t freeMemSize() const { return std::min(m_maxMemoryAlloc, m_globalMemory); } + inline size_t globalMemSize() const { return m_globalMemory; } + inline size_t maxMemAllocSize() const { return m_maxMemoryAlloc; } inline uint32_t index() const { return m_index; } # ifdef XMRIG_FEATURE_API @@ -90,6 +91,9 @@ private: const String m_board; const String m_name; const String m_vendor; + const size_t m_freeMemory = 0; + const size_t m_maxMemoryAlloc = 0; + const size_t m_globalMemory = 0; const uint32_t m_computeUnits = 1; const uint32_t m_index = 0; OclVendor m_vendorId = OCL_VENDOR_UNKNOWN; From 9e2b63890c9ba19d3dea4a9eda5e6e84590ea942 Mon Sep 17 00:00:00 2001 From: Anton Kamenov Date: Mon, 14 Oct 2019 14:14:12 +0300 Subject: [PATCH 07/28] Use functions to get memory variables --- src/backend/opencl/wrappers/OclDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/opencl/wrappers/OclDevice.h b/src/backend/opencl/wrappers/OclDevice.h index faf03b667..1e3b019a4 100644 --- a/src/backend/opencl/wrappers/OclDevice.h +++ b/src/backend/opencl/wrappers/OclDevice.h @@ -76,7 +76,7 @@ public: inline OclVendor vendorId() const { return m_vendorId; } inline Type type() const { return m_type; } inline uint32_t computeUnits() const { return m_computeUnits; } - inline size_t freeMemSize() const { return std::min(m_maxMemoryAlloc, m_globalMemory); } + inline size_t freeMemSize() const { return std::min(maxMemAllocSize(), globalMemSize()); } inline size_t globalMemSize() const { return m_globalMemory; } inline size_t maxMemAllocSize() const { return m_maxMemoryAlloc; } inline uint32_t index() const { return m_index; } From 83a592356873c181a6075f41374776283245759b Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 16 Oct 2019 19:34:33 +0700 Subject: [PATCH 08/28] Added send with callback. --- src/base/kernel/interfaces/IClient.h | 54 +++++++++++++---------- src/base/net/stratum/BaseClient.cpp | 27 ++++++++++++ src/base/net/stratum/BaseClient.h | 11 +++++ src/base/net/stratum/Client.cpp | 14 ++++++ src/base/net/stratum/Client.h | 1 + src/base/net/stratum/DaemonClient.h | 15 ++++--- src/base/net/stratum/SelfSelectClient.cpp | 6 ++- src/base/net/stratum/SelfSelectClient.h | 49 ++++++++++---------- src/base/net/stratum/SubmitResult.h | 22 +++------ 9 files changed, 127 insertions(+), 72 deletions(-) diff --git a/src/base/kernel/interfaces/IClient.h b/src/base/kernel/interfaces/IClient.h index 06e129684..db88638ad 100644 --- a/src/base/kernel/interfaces/IClient.h +++ b/src/base/kernel/interfaces/IClient.h @@ -29,6 +29,9 @@ #include "rapidjson/fwd.h" +#include + + namespace xmrig { @@ -51,32 +54,35 @@ public: EXT_MAX }; + using Callback = std::function; + virtual ~IClient() = default; - virtual bool disconnect() = 0; - virtual bool hasExtension(Extension extension) const noexcept = 0; - virtual bool isEnabled() const = 0; - virtual bool isTLS() const = 0; - virtual const char *mode() const = 0; - virtual const char *tlsFingerprint() const = 0; - virtual const char *tlsVersion() const = 0; - virtual const Job &job() const = 0; - virtual const Pool &pool() const = 0; - virtual const String &ip() const = 0; - virtual int id() const = 0; - virtual int64_t send(const rapidjson::Value &obj) = 0; - virtual int64_t sequence() const = 0; - virtual int64_t submit(const JobResult &result) = 0; - virtual void connect() = 0; - virtual void connect(const Pool &pool) = 0; - virtual void deleteLater() = 0; - virtual void setAlgo(const Algorithm &algo) = 0; - virtual void setEnabled(bool enabled) = 0; - virtual void setPool(const Pool &pool) = 0; - virtual void setQuiet(bool quiet) = 0; - virtual void setRetries(int retries) = 0; - virtual void setRetryPause(uint64_t ms) = 0; - virtual void tick(uint64_t now) = 0; + virtual bool disconnect() = 0; + virtual bool hasExtension(Extension extension) const noexcept = 0; + virtual bool isEnabled() const = 0; + virtual bool isTLS() const = 0; + virtual const char *mode() const = 0; + virtual const char *tlsFingerprint() const = 0; + virtual const char *tlsVersion() const = 0; + virtual const Job &job() const = 0; + virtual const Pool &pool() const = 0; + virtual const String &ip() const = 0; + virtual int id() const = 0; + virtual int64_t send(const rapidjson::Value &obj, Callback callback) = 0; + virtual int64_t send(const rapidjson::Value &obj) = 0; + virtual int64_t sequence() const = 0; + virtual int64_t submit(const JobResult &result) = 0; + virtual void connect() = 0; + virtual void connect(const Pool &pool) = 0; + virtual void deleteLater() = 0; + virtual void setAlgo(const Algorithm &algo) = 0; + virtual void setEnabled(bool enabled) = 0; + virtual void setPool(const Pool &pool) = 0; + virtual void setQuiet(bool quiet) = 0; + virtual void setRetries(int retries) = 0; + virtual void setRetryPause(uint64_t ms) = 0; + virtual void tick(uint64_t now) = 0; }; diff --git a/src/base/net/stratum/BaseClient.cpp b/src/base/net/stratum/BaseClient.cpp index ccffa7ce7..56e5ad7c5 100644 --- a/src/base/net/stratum/BaseClient.cpp +++ b/src/base/net/stratum/BaseClient.cpp @@ -26,6 +26,7 @@ #include "base/kernel/interfaces/IClientListener.h" #include "base/net/stratum/BaseClient.h" #include "base/net/stratum/SubmitResult.h" +#include "rapidjson/document.h" namespace xmrig { @@ -42,6 +43,32 @@ xmrig::BaseClient::BaseClient(int id, IClientListener *listener) : } +bool xmrig::BaseClient::handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error) +{ + if (id == 1) { + return false; + } + + auto it = m_callbacks.find(id); + if (it != m_callbacks.end()) { + const uint64_t elapsed = Chrono::steadyMSecs() - it->second.ts; + + if (error.IsObject()) { + it->second.callback(error, false, elapsed); + } + else { + it->second.callback(result, true, elapsed); + } + + m_callbacks.erase(it); + + return true; + } + + return false; +} + + bool xmrig::BaseClient::handleSubmitResponse(int64_t id, const char *error) { auto it = m_results.find(id); diff --git a/src/base/net/stratum/BaseClient.h b/src/base/net/stratum/BaseClient.h index 0d73dc9bf..974e61a5e 100644 --- a/src/base/net/stratum/BaseClient.h +++ b/src/base/net/stratum/BaseClient.h @@ -32,6 +32,7 @@ #include "base/kernel/interfaces/IClient.h" #include "base/net/stratum/Job.h" #include "base/net/stratum/Pool.h" +#include "base/tools/Chrono.h" namespace xmrig { @@ -70,8 +71,17 @@ protected: ReconnectingState }; + struct SendResult + { + inline SendResult(Callback &&callback) : callback(callback), ts(Chrono::steadyMSecs()) {} + + Callback callback; + const uint64_t ts; + }; + inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; } + bool handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error); bool handleSubmitResponse(int64_t id, const char *error = nullptr); bool m_quiet = false; @@ -82,6 +92,7 @@ protected: Job m_job; Pool m_pool; SocketState m_state = UnconnectedState; + std::map m_callbacks; std::map m_results; String m_ip; uint64_t m_retryPause = 5000; diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 543495335..3619e4e9f 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -137,6 +137,16 @@ const char *xmrig::Client::tlsVersion() const } +int64_t xmrig::Client::send(const rapidjson::Value &obj, Callback callback) +{ + assert(obj["id"] == sequence()); + + m_callbacks.insert({ sequence(), std::move(callback) }); + + return send(obj); +} + + int64_t xmrig::Client::send(const rapidjson::Value &obj) { using namespace rapidjson; @@ -736,6 +746,10 @@ void xmrig::Client::parseNotification(const char *method, const rapidjson::Value void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error) { + if (handleResponse(id, result, error)) { + return; + } + if (error.IsObject()) { const char *message = error["message"].GetString(); diff --git a/src/base/net/stratum/Client.h b/src/base/net/stratum/Client.h index 8ff58c639..da4234845 100644 --- a/src/base/net/stratum/Client.h +++ b/src/base/net/stratum/Client.h @@ -77,6 +77,7 @@ protected: bool isTLS() const override; const char *tlsFingerprint() const override; const char *tlsVersion() const override; + int64_t send(const rapidjson::Value &obj, Callback callback) override; int64_t send(const rapidjson::Value &obj) override; int64_t submit(const JobResult &result) override; void connect() override; diff --git a/src/base/net/stratum/DaemonClient.h b/src/base/net/stratum/DaemonClient.h index 0932b2bee..e819c07d6 100644 --- a/src/base/net/stratum/DaemonClient.h +++ b/src/base/net/stratum/DaemonClient.h @@ -54,13 +54,14 @@ protected: void onHttpData(const HttpData &data) override; void onTimer(const Timer *timer) override; - inline bool hasExtension(Extension) const noexcept override { return false; } - inline const char *mode() const override { return "daemon"; } - inline const char *tlsFingerprint() const override { return m_tlsFingerprint; } - inline const char *tlsVersion() const override { return m_tlsVersion; } - inline int64_t send(const rapidjson::Value &) override { return -1; } - inline void deleteLater() override { delete this; } - inline void tick(uint64_t) override {} + inline bool hasExtension(Extension) const noexcept override { return false; } + inline const char *mode() const override { return "daemon"; } + inline const char *tlsFingerprint() const override { return m_tlsFingerprint; } + inline const char *tlsVersion() const override { return m_tlsVersion; } + inline int64_t send(const rapidjson::Value &, Callback) override { return -1; } + inline int64_t send(const rapidjson::Value &) override { return -1; } + inline void deleteLater() override { delete this; } + inline void tick(uint64_t) override {} private: bool isOutdated(uint64_t height, const char *hash) const; diff --git a/src/base/net/stratum/SelfSelectClient.cpp b/src/base/net/stratum/SelfSelectClient.cpp index 7398d6ee4..3b6034a7e 100644 --- a/src/base/net/stratum/SelfSelectClient.cpp +++ b/src/base/net/stratum/SelfSelectClient.cpp @@ -122,7 +122,7 @@ bool xmrig::SelfSelectClient::parseResponse(int64_t id, rapidjson::Value &result submitBlockTemplate(result); - m_listener->onJobReceived(this, m_job, rapidjson::Value{}); + return true; } @@ -207,7 +207,9 @@ void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result) JsonRequest::create(doc, sequence(), "block_template", params); - send(doc); + send(doc, [this](const rapidjson::Value &result, bool success, uint64_t elapsed) { + m_listener->onJobReceived(this, m_job, rapidjson::Value{}); + }); } diff --git a/src/base/net/stratum/SelfSelectClient.h b/src/base/net/stratum/SelfSelectClient.h index aa39d4306..d8bc5585e 100644 --- a/src/base/net/stratum/SelfSelectClient.h +++ b/src/base/net/stratum/SelfSelectClient.h @@ -47,30 +47,31 @@ public: protected: // IClient - inline bool disconnect() override { return m_client->disconnect(); } - inline bool hasExtension(Extension extension) const noexcept override { return m_client->hasExtension(extension); } - inline bool isEnabled() const override { return m_client->isEnabled(); } - inline bool isTLS() const override { return m_client->isTLS(); } - inline const char *mode() const override { return m_client->mode(); } - inline const char *tlsFingerprint() const override { return m_client->tlsFingerprint(); } - inline const char *tlsVersion() const override { return m_client->tlsVersion(); } - inline const Job &job() const override { return m_client->job(); } - inline const Pool &pool() const override { return m_client->pool(); } - inline const String &ip() const override { return m_client->ip(); } - inline int id() const override { return m_client->id(); } - inline int64_t send(const rapidjson::Value &obj) override { return m_client->send(obj); } - inline int64_t sequence() const override { return m_client->sequence(); } - inline int64_t submit(const JobResult &result) override { return m_client->submit(result); } - inline void connect() override { m_client->connect(); } - inline void connect(const Pool &pool) override { m_client->connect(pool); } - inline void deleteLater() override { m_client->deleteLater(); } - inline void setAlgo(const Algorithm &algo) override { m_client->setAlgo(algo); } - inline void setEnabled(bool enabled) override { m_client->setEnabled(enabled); } - inline void setPool(const Pool &pool) override { m_client->setPool(pool); } - inline void setQuiet(bool quiet) override { m_client->setQuiet(quiet); m_quiet = quiet; } - inline void setRetries(int retries) override { m_client->setRetries(retries); } - inline void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); } - inline void tick(uint64_t now) override { m_client->tick(now); } + inline bool disconnect() override { return m_client->disconnect(); } + inline bool hasExtension(Extension extension) const noexcept override { return m_client->hasExtension(extension); } + inline bool isEnabled() const override { return m_client->isEnabled(); } + inline bool isTLS() const override { return m_client->isTLS(); } + inline const char *mode() const override { return m_client->mode(); } + inline const char *tlsFingerprint() const override { return m_client->tlsFingerprint(); } + inline const char *tlsVersion() const override { return m_client->tlsVersion(); } + inline const Job &job() const override { return m_client->job(); } + inline const Pool &pool() const override { return m_client->pool(); } + inline const String &ip() const override { return m_client->ip(); } + inline int id() const override { return m_client->id(); } + inline int64_t send(const rapidjson::Value &obj, Callback callback) override { return m_client->send(obj, callback); } + inline int64_t send(const rapidjson::Value &obj) override { return m_client->send(obj); } + inline int64_t sequence() const override { return m_client->sequence(); } + inline int64_t submit(const JobResult &result) override { return m_client->submit(result); } + inline void connect() override { m_client->connect(); } + inline void connect(const Pool &pool) override { m_client->connect(pool); } + inline void deleteLater() override { m_client->deleteLater(); } + inline void setAlgo(const Algorithm &algo) override { m_client->setAlgo(algo); } + inline void setEnabled(bool enabled) override { m_client->setEnabled(enabled); } + inline void setPool(const Pool &pool) override { m_client->setPool(pool); } + inline void setQuiet(bool quiet) override { m_client->setQuiet(quiet); m_quiet = quiet; } + inline void setRetries(int retries) override { m_client->setRetries(retries); } + inline void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); } + inline void tick(uint64_t now) override { m_client->tick(now); } // IClientListener inline void onClose(IClient *, int failures) override { m_listener->onClose(this, failures); } diff --git a/src/base/net/stratum/SubmitResult.h b/src/base/net/stratum/SubmitResult.h index 5abd3e4bf..1b49acb43 100644 --- a/src/base/net/stratum/SubmitResult.h +++ b/src/base/net/stratum/SubmitResult.h @@ -35,34 +35,26 @@ namespace xmrig { class SubmitResult { public: - inline SubmitResult() : - reqId(0), - seq(0), - actualDiff(0), - diff(0), - elapsed(0), - m_start(0) - {} + SubmitResult() = default; inline SubmitResult(int64_t seq, uint64_t diff, uint64_t actualDiff, int64_t reqId = 0) : reqId(reqId), seq(seq), actualDiff(actualDiff), diff(diff), - elapsed(0), m_start(Chrono::steadyMSecs()) {} inline void done() { elapsed = Chrono::steadyMSecs() - m_start; } - int64_t reqId; - int64_t seq; - uint64_t actualDiff; - uint64_t diff; - uint64_t elapsed; + int64_t reqId = 0; + int64_t seq = 0; + uint64_t actualDiff = 0; + uint64_t diff = 0; + uint64_t elapsed = 0; private: - uint64_t m_start; + uint64_t m_start = 0; }; From d783febad6a458e15838d0cc259565e104d5243a Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 17 Oct 2019 00:57:35 +0700 Subject: [PATCH 09/28] Added error handling for self-select mode. --- src/base/net/http/HttpClient.cpp | 14 ++- src/base/net/http/HttpClient.h | 7 +- src/base/net/http/HttpContext.cpp | 8 +- src/base/net/http/HttpContext.h | 15 +-- src/base/net/http/HttpsClient.cpp | 2 +- src/base/net/http/HttpsClient.h | 10 +- src/base/net/stratum/SelfSelectClient.cpp | 108 +++++++++++++++++----- src/base/net/stratum/SelfSelectClient.h | 29 ++++-- 8 files changed, 141 insertions(+), 52 deletions(-) diff --git a/src/base/net/http/HttpClient.cpp b/src/base/net/http/HttpClient.cpp index 113e2f139..2699e6631 100644 --- a/src/base/net/http/HttpClient.cpp +++ b/src/base/net/http/HttpClient.cpp @@ -78,9 +78,7 @@ private: xmrig::HttpClient::HttpClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) : - HttpContext(HTTP_RESPONSE, listener), - m_quiet(false), - m_port(0) + HttpContext(HTTP_RESPONSE, listener) { this->method = method; this->url = url; @@ -127,7 +125,7 @@ void xmrig::HttpClient::onResolved(const Dns &dns, int status) sockaddr *addr = dns.get().addr(m_port); - uv_connect_t *req = new uv_connect_t; + auto req = new uv_connect_t; req->data = this; uv_tcp_connect(req, m_tcp, addr, onConnect); @@ -140,7 +138,7 @@ void xmrig::HttpClient::handshake() headers.insert({ "Connection", "close" }); headers.insert({ "User-Agent", Platform::userAgent() }); - if (body.size()) { + if (!body.empty()) { headers.insert({ "Content-Length", std::to_string(body.size()) }); } @@ -169,14 +167,14 @@ void xmrig::HttpClient::read(const char *data, size_t size) void xmrig::HttpClient::write(const std::string &header) { - ClientWriteBaton *baton = new ClientWriteBaton(header, std::move(body)); + auto baton = new ClientWriteBaton(header, std::move(body)); uv_write(&baton->req, stream(), baton->bufs, baton->count(), ClientWriteBaton::onWrite); } void xmrig::HttpClient::onConnect(uv_connect_t *req, int status) { - HttpClient *client = static_cast(req->data); + auto client = static_cast(req->data); if (!client) { delete req; return; @@ -205,7 +203,7 @@ void xmrig::HttpClient::onConnect(uv_connect_t *req, int status) }, [](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf) { - HttpClient *client = static_cast(tcp->data); + auto client = static_cast(tcp->data); if (nread >= 0) { client->read(buf->base, static_cast(nread)); diff --git a/src/base/net/http/HttpClient.h b/src/base/net/http/HttpClient.h index c5dfc43d9..acf873dc7 100644 --- a/src/base/net/http/HttpClient.h +++ b/src/base/net/http/HttpClient.h @@ -30,6 +30,7 @@ #include "base/net/http/HttpContext.h" #include "base/kernel/interfaces/IDnsListener.h" +#include "base/tools/Object.h" namespace xmrig { @@ -41,6 +42,8 @@ class String; class HttpClient : public HttpContext, public IDnsListener { public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpClient); + HttpClient(int method, const String &url, IHttpListener *listener, const char *data = nullptr, size_t size = 0); ~HttpClient() override; @@ -57,13 +60,13 @@ protected: virtual void read(const char *data, size_t size); virtual void write(const std::string &header); - bool m_quiet; + bool m_quiet = false; private: static void onConnect(uv_connect_t *req, int status); Dns *m_dns; - uint16_t m_port; + uint16_t m_port = 0; }; diff --git a/src/base/net/http/HttpContext.cpp b/src/base/net/http/HttpContext.cpp index e97f989b2..1130d12c5 100644 --- a/src/base/net/http/HttpContext.cpp +++ b/src/base/net/http/HttpContext.cpp @@ -136,7 +136,7 @@ void xmrig::HttpContext::closeAll() int xmrig::HttpContext::onHeaderField(http_parser *parser, const char *at, size_t length) { - HttpContext *ctx = static_cast(parser->data); + auto ctx = static_cast(parser->data); if (ctx->m_wasHeaderValue) { if (!ctx->m_lastHeaderField.empty()) { @@ -155,7 +155,7 @@ int xmrig::HttpContext::onHeaderField(http_parser *parser, const char *at, size_ int xmrig::HttpContext::onHeaderValue(http_parser *parser, const char *at, size_t length) { - HttpContext *ctx = static_cast(parser->data); + auto ctx = static_cast(parser->data); if (!ctx->m_wasHeaderValue) { ctx->m_lastHeaderValue = std::string(at, length); @@ -185,7 +185,7 @@ void xmrig::HttpContext::attach(http_parser_settings *settings) settings->on_header_value = onHeaderValue; settings->on_headers_complete = [](http_parser* parser) -> int { - HttpContext *ctx = static_cast(parser->data); + auto ctx = static_cast(parser->data); ctx->status = parser->status_code; if (parser->type == HTTP_REQUEST) { @@ -208,7 +208,7 @@ void xmrig::HttpContext::attach(http_parser_settings *settings) settings->on_message_complete = [](http_parser *parser) -> int { - HttpContext *ctx = static_cast(parser->data); + auto ctx = static_cast(parser->data); ctx->m_listener->onHttpData(*ctx); ctx->m_listener = nullptr; diff --git a/src/base/net/http/HttpContext.h b/src/base/net/http/HttpContext.h index fbb453aa9..ba4418b61 100644 --- a/src/base/net/http/HttpContext.h +++ b/src/base/net/http/HttpContext.h @@ -28,15 +28,16 @@ #define XMRIG_HTTPCONTEXT_H -typedef struct http_parser http_parser; -typedef struct http_parser_settings http_parser_settings; -typedef struct uv_connect_s uv_connect_t; -typedef struct uv_handle_s uv_handle_t; -typedef struct uv_stream_s uv_stream_t; -typedef struct uv_tcp_s uv_tcp_t; +using http_parser = struct http_parser; +using http_parser_settings = struct http_parser_settings; +using uv_connect_t = struct uv_connect_s; +using uv_handle_t = struct uv_handle_s; +using uv_stream_t = struct uv_stream_s; +using uv_tcp_t = struct uv_tcp_s; #include "base/net/http/HttpData.h" +#include "base/tools/Object.h" namespace xmrig { @@ -48,6 +49,8 @@ class IHttpListener; class HttpContext : public HttpData { public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpContext) + HttpContext(int parser_type, IHttpListener *listener); virtual ~HttpContext(); diff --git a/src/base/net/http/HttpsClient.cpp b/src/base/net/http/HttpsClient.cpp index 2c2873309..747aeb31f 100644 --- a/src/base/net/http/HttpsClient.cpp +++ b/src/base/net/http/HttpsClient.cpp @@ -24,7 +24,7 @@ */ -#include +#include #include #include diff --git a/src/base/net/http/HttpsClient.h b/src/base/net/http/HttpsClient.h index c6a228099..a0de150e5 100644 --- a/src/base/net/http/HttpsClient.h +++ b/src/base/net/http/HttpsClient.h @@ -28,10 +28,10 @@ #define XMRIG_HTTPSCLIENT_H -typedef struct bio_st BIO; -typedef struct ssl_ctx_st SSL_CTX; -typedef struct ssl_st SSL; -typedef struct x509_st X509; +using BIO = struct bio_st; +using SSL_CTX = struct ssl_ctx_st; +using SSL = struct ssl_st; +using X509 = struct x509_st; #include "base/net/http/HttpClient.h" @@ -44,6 +44,8 @@ namespace xmrig { class HttpsClient : public HttpClient { public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpsClient) + HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint); ~HttpsClient() override; diff --git a/src/base/net/stratum/SelfSelectClient.cpp b/src/base/net/stratum/SelfSelectClient.cpp index 3b6034a7e..ae82dfafb 100644 --- a/src/base/net/stratum/SelfSelectClient.cpp +++ b/src/base/net/stratum/SelfSelectClient.cpp @@ -73,6 +73,20 @@ xmrig::SelfSelectClient::~SelfSelectClient() } +void xmrig::SelfSelectClient::tick(uint64_t now) +{ + m_client->tick(now); + + if (m_state == RetryState) { + if (Chrono::steadyMSecs() - m_timestamp < m_retryPause) { + return; + } + + getBlockTemplate(); + } +} + + void xmrig::SelfSelectClient::onJobReceived(IClient *, const Job &job, const rapidjson::Value &) { m_job = job; @@ -96,7 +110,7 @@ bool xmrig::SelfSelectClient::parseResponse(int64_t id, rapidjson::Value &result } if (error.IsObject()) { - LOG_ERR("[%s:%d] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", pool().daemon().host().data(), pool().daemon().port(), Json::getString(error, "message"), Json::getInt(error, "code")); + LOG_ERR("[%s] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", pool().daemon().url().data(), Json::getString(error, "message"), Json::getInt(error, "code")); return false; } @@ -107,7 +121,7 @@ bool xmrig::SelfSelectClient::parseResponse(int64_t id, rapidjson::Value &result for (auto field : required_fields) { if (!result.HasMember(field)) { - LOG_ERR("[%s:%d] required field " RED_BOLD("\"%s\"") RED_S " not found", pool().daemon().host().data(), pool().daemon().port(), field); + LOG_ERR("[%s] required field " RED_BOLD("\"%s\"") RED_S " not found", pool().daemon().url().data(), field); return false; } @@ -122,14 +136,14 @@ bool xmrig::SelfSelectClient::parseResponse(int64_t id, rapidjson::Value &result submitBlockTemplate(result); - - return true; } void xmrig::SelfSelectClient::getBlockTemplate() { + setState(WaitState); + using namespace rapidjson; Document doc(kObjectType); auto &allocator = doc.GetAllocator(); @@ -138,7 +152,7 @@ void xmrig::SelfSelectClient::getBlockTemplate() params.AddMember("wallet_address", m_job.poolWallet().toJSON(), allocator); params.AddMember("extra_nonce", m_job.extraNonce().toJSON(), allocator); - JsonRequest::create(doc, sequence(), "getblocktemplate", params); + JsonRequest::create(doc, m_sequence++, "getblocktemplate", params); send(HTTP_POST, "/json_rpc", doc); } @@ -146,15 +160,14 @@ void xmrig::SelfSelectClient::getBlockTemplate() void xmrig::SelfSelectClient::retry() { - // FIXME + setState(RetryState); } void xmrig::SelfSelectClient::send(int method, const char *url, const char *data, size_t size) { - LOG_DEBUG("[%s:%d] " MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD_S " send (%zu bytes): \"%.*s\"", - pool().daemon().host().data(), - pool().daemon().port(), + LOG_DEBUG("[%s] " MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD_S " send (%zu bytes): \"%.*s\"", + pool().daemon().url().data(), http_method_str(static_cast(method)), url, size, @@ -172,7 +185,7 @@ void xmrig::SelfSelectClient::send(int method, const char *url, const char *data client = new HttpClient(method, url, this, data, size); } - client->setQuiet(m_quiet); + client->setQuiet(isQuiet()); client->connect(pool().daemon().host(), pool().daemon().port()); } @@ -189,6 +202,37 @@ void xmrig::SelfSelectClient::send(int method, const char *url, const rapidjson: } +void xmrig::SelfSelectClient::setState(State state) +{ + if (m_state == state) { + return; + } + + switch (state) { + case IdleState: + m_timestamp = 0; + m_failures = 0; + break; + + case WaitState: + m_timestamp = Chrono::steadyMSecs(); + break; + + case RetryState: + m_timestamp = Chrono::steadyMSecs(); + + if (m_failures > m_retries) { + m_listener->onClose(this, static_cast(m_failures)); + } + + m_failures++; + break; + } + + m_state = state; +} + + void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result) { using namespace rapidjson; @@ -196,18 +240,35 @@ void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result) auto &allocator = doc.GetAllocator(); Value params(kObjectType); - params.AddMember(StringRef(kId), m_job.clientId().toJSON(), allocator); - params.AddMember(StringRef(kJobId), m_job.id().toJSON(), allocator); - params.AddMember(StringRef(kBlob), result[kBlocktemplateBlob], allocator); - params.AddMember(StringRef(kHeight), m_job.height(), allocator); - params.AddMember(StringRef(kDifficulty), result[kDifficulty], allocator); - params.AddMember(StringRef(kPrevHash), result[kPrevHash], allocator); - params.AddMember(StringRef(kSeedHash), result[kSeedHash], allocator); + params.AddMember(StringRef(kId), m_job.clientId().toJSON(), allocator); + params.AddMember(StringRef(kJobId), m_job.id().toJSON(), allocator); + params.AddMember(StringRef(kBlob), result[kBlocktemplateBlob], allocator); + params.AddMember(StringRef(kHeight), m_job.height(), allocator); + params.AddMember(StringRef(kDifficulty), result[kDifficulty], allocator); + params.AddMember(StringRef(kPrevHash), result[kPrevHash], allocator); + params.AddMember(StringRef(kSeedHash), result[kSeedHash], allocator); params.AddMember(StringRef(kNextSeedHash), result[kNextSeedHash], allocator); JsonRequest::create(doc, sequence(), "block_template", params); send(doc, [this](const rapidjson::Value &result, bool success, uint64_t elapsed) { + if (!success) { + if (!isQuiet()) { + LOG_ERR("[%s] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", pool().daemon().url().data(), Json::getString(result, "message"), Json::getInt(result, "code")); + } + + return retry(); + } + + if (!m_active) { + return; + } + + if (m_failures > m_retries) { + m_listener->onLoginSuccess(this); + } + + setState(IdleState); m_listener->onJobReceived(this, m_job, rapidjson::Value{}); }); } @@ -219,18 +280,23 @@ void xmrig::SelfSelectClient::onHttpData(const HttpData &data) return retry(); } - LOG_DEBUG("[%s:%d] received (%d bytes): \"%.*s\"", pool().daemon().host().data(), pool().daemon().port(), static_cast(data.body.size()), static_cast(data.body.size()), data.body.c_str()); + LOG_DEBUG("[%s] received (%d bytes): \"%.*s\"", pool().daemon().url().data(), static_cast(data.body.size()), static_cast(data.body.size()), data.body.c_str()); rapidjson::Document doc; if (doc.Parse(data.body.c_str()).HasParseError()) { - if (!m_quiet) { - LOG_ERR("[%s:%d] JSON decode failed: \"%s\"", pool().daemon().host().data(), pool().daemon().port(), rapidjson::GetParseError_En(doc.GetParseError())); + if (!isQuiet()) { + LOG_ERR("[%s] JSON decode failed: \"%s\"", pool().daemon().url().data(), rapidjson::GetParseError_En(doc.GetParseError())); } return retry(); } - if (!parseResponse(Json::getInt64(doc, "id", -1), doc["result"], Json::getObject(doc, "error"))) { + const int64_t id = Json::getInt64(doc, "id", -1); + if (id > 0 && m_sequence - id != 1) { + return; + } + + if (!parseResponse(id, doc["result"], Json::getObject(doc, "error"))) { retry(); } } diff --git a/src/base/net/stratum/SelfSelectClient.h b/src/base/net/stratum/SelfSelectClient.h index d8bc5585e..c48c50782 100644 --- a/src/base/net/stratum/SelfSelectClient.h +++ b/src/base/net/stratum/SelfSelectClient.h @@ -69,13 +69,14 @@ protected: inline void setEnabled(bool enabled) override { m_client->setEnabled(enabled); } inline void setPool(const Pool &pool) override { m_client->setPool(pool); } inline void setQuiet(bool quiet) override { m_client->setQuiet(quiet); m_quiet = quiet; } - inline void setRetries(int retries) override { m_client->setRetries(retries); } - inline void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); } - inline void tick(uint64_t now) override { m_client->tick(now); } + inline void setRetries(int retries) override { m_client->setRetries(retries); m_retries = retries; } + inline void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); m_retryPause = ms; } + + void tick(uint64_t now) override; // IClientListener - inline void onClose(IClient *, int failures) override { m_listener->onClose(this, failures); } - inline void onLoginSuccess(IClient *) override { m_listener->onLoginSuccess(this); } + inline void onClose(IClient *, int failures) override { m_listener->onClose(this, failures); setState(IdleState); m_active = false; } + inline void onLoginSuccess(IClient *) override { m_listener->onLoginSuccess(this); setState(IdleState); m_active = true; } inline void onResultAccepted(IClient *, const SubmitResult &result, const char *error) override { m_listener->onResultAccepted(this, result, error); } inline void onVerifyAlgorithm(const IClient *, const Algorithm &algorithm, bool *ok) override { m_listener->onVerifyAlgorithm(this, algorithm, ok); } @@ -86,17 +87,33 @@ protected: void onHttpData(const HttpData &data) override; private: + enum State { + IdleState, + WaitState, + RetryState + }; + + inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; } + bool parseResponse(int64_t id, rapidjson::Value &result, const rapidjson::Value &error); void getBlockTemplate(); void retry(); void send(int method, const char *url, const char *data = nullptr, size_t size = 0); void send(int method, const char *url, const rapidjson::Document &doc); + void setState(State state); void submitBlockTemplate(rapidjson::Value &result); - bool m_quiet = false; + bool m_active = false; + bool m_quiet = false; IClient *m_client; IClientListener *m_listener; + int m_retries = 5; + int64_t m_failures = 0; + int64_t m_sequence = 1; Job m_job; + State m_state = IdleState; + uint64_t m_retryPause = 5000; + uint64_t m_timestamp = 0; }; From 10d292092a45941da4f79a0cd029705a34bd713b Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 18 Oct 2019 12:02:10 +0700 Subject: [PATCH 10/28] #1246 Fixed build on iOS. --- src/crypto/randomx/jit_compiler_a64.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index 08f84f1ce..b31d1fa82 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -149,9 +149,9 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con codePos = ((uint8_t*)randomx_program_aarch64_update_spMix1) - ((uint8_t*)randomx_program_aarch64); emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos); -#ifdef __GNUC__ +# ifdef HAVE_BUILTIN_CLEAR_CACHE_ __builtin___clear_cache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); -#endif +# endif } void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration& config, uint32_t datasetOffset) @@ -206,9 +206,9 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration emit32(ARMV8A::ADD_IMM_LO | 2 | (2 << 5) | (imm_lo << 10), code, codePos); emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos); -#ifdef __GNUC__ +# ifdef HAVE_BUILTIN_CLEAR_CACHE __builtin___clear_cache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); -#endif +# endif } template @@ -324,9 +324,9 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N], s memcpy(code + codePos, p1, p2 - p1); codePos += p2 - p1; -#ifdef __GNUC__ +# ifdef HAVE_BUILTIN_CLEAR_CACHE __builtin___clear_cache(reinterpret_cast(code + CodeSize), reinterpret_cast(code + codePos)); -#endif +# endif } template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES], std::vector &reciprocalCache); From 432addab3360d0780b87bee180b97a00e165abd6 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 18 Oct 2019 16:18:45 +0200 Subject: [PATCH 11/28] Fix ARM64 code alignemtn --- src/crypto/randomx/jit_compiler_a64_static.S | 1 + 1 file changed, 1 insertion(+) diff --git a/src/crypto/randomx/jit_compiler_a64_static.S b/src/crypto/randomx/jit_compiler_a64_static.S index be37602b6..13fd5c573 100644 --- a/src/crypto/randomx/jit_compiler_a64_static.S +++ b/src/crypto/randomx/jit_compiler_a64_static.S @@ -98,6 +98,7 @@ # v30 -> E 'or' mask = 0x3*00000000******3*00000000****** # v31 -> scale mask = 0x81f000000000000081f0000000000000 + .balign 4 randomx_program_aarch64: # Save callee-saved registers sub sp, sp, 192 From 998c55030af226946b6408eabb965dd5f22c76c8 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 18 Oct 2019 16:26:15 +0200 Subject: [PATCH 12/28] Fixed code cache cleanup on iOS/Darwin --- src/crypto/randomx/jit_compiler_a64.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index b31d1fa82..1a6a6a06c 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -103,6 +103,19 @@ JitCompilerA64::~JitCompilerA64() freePagedMemory(code, CodeSize + CalcDatasetItemSize()); } +#if defined(ios_HOST_OS) || defined (darwin_HOST_OS) +void sys_icache_invalidate(void *start, size_t len); +#endif + +static void clear_code_cache(void* p, size_t size) +{ +# ifdef HAVE_BUILTIN_CLEAR_CACHE_ + __builtin___clear_cache(p, size); +# elif defined(ios_HOST_OS) || defined (darwin_HOST_OS) + sys_icache_invalidate(p, size); +# endif +} + void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& config) { uint32_t codePos = MainLoopBegin + 4; @@ -149,9 +162,7 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con codePos = ((uint8_t*)randomx_program_aarch64_update_spMix1) - ((uint8_t*)randomx_program_aarch64); emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos); -# ifdef HAVE_BUILTIN_CLEAR_CACHE_ - __builtin___clear_cache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); -# endif + clear_code_cache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); } void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration& config, uint32_t datasetOffset) @@ -206,9 +217,7 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration emit32(ARMV8A::ADD_IMM_LO | 2 | (2 << 5) | (imm_lo << 10), code, codePos); emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos); -# ifdef HAVE_BUILTIN_CLEAR_CACHE - __builtin___clear_cache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); -# endif + clear_code_cache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); } template @@ -324,9 +333,7 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N], s memcpy(code + codePos, p1, p2 - p1); codePos += p2 - p1; -# ifdef HAVE_BUILTIN_CLEAR_CACHE - __builtin___clear_cache(reinterpret_cast(code + CodeSize), reinterpret_cast(code + codePos)); -# endif + clear_code_cache(reinterpret_cast(code + CodeSize), reinterpret_cast(code + codePos)); } template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES], std::vector &reciprocalCache); From 5c02cb50dafdde339d7692b45045559ff19826eb Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 18 Oct 2019 21:26:15 +0700 Subject: [PATCH 13/28] Fix copy/paste typo. --- src/crypto/randomx/jit_compiler_a64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index b31d1fa82..5587ca242 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -149,7 +149,7 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con codePos = ((uint8_t*)randomx_program_aarch64_update_spMix1) - ((uint8_t*)randomx_program_aarch64); emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos); -# ifdef HAVE_BUILTIN_CLEAR_CACHE_ +# ifdef HAVE_BUILTIN_CLEAR_CACHE __builtin___clear_cache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); # endif } From 1a66c3f1a1063e3b12d3e54f965d0cccf7da8ff6 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 18 Oct 2019 16:32:01 +0200 Subject: [PATCH 14/28] Update jit_compiler_a64.cpp --- src/crypto/randomx/jit_compiler_a64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index f62550d04..79e099a0d 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -109,7 +109,7 @@ void sys_icache_invalidate(void *start, size_t len); static void clear_code_cache(void* p, size_t size) { -# ifdef HAVE_BUILTIN_CLEAR_CACHE_ +# ifdef HAVE_BUILTIN_CLEAR_CACHE __builtin___clear_cache(p, size); # elif defined(ios_HOST_OS) || defined (darwin_HOST_OS) sys_icache_invalidate(p, size); From 0ad992985c005d5f03685767988c3657ef6b4485 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 18 Oct 2019 16:36:50 +0200 Subject: [PATCH 15/28] Update jit_compiler_a64.cpp --- src/crypto/randomx/jit_compiler_a64.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index 79e099a0d..586b407f7 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -107,12 +107,12 @@ JitCompilerA64::~JitCompilerA64() void sys_icache_invalidate(void *start, size_t len); #endif -static void clear_code_cache(void* p, size_t size) +static void clear_code_cache(char* p1, char* p2) { # ifdef HAVE_BUILTIN_CLEAR_CACHE - __builtin___clear_cache(p, size); + __builtin___clear_cache(p1, p2); # elif defined(ios_HOST_OS) || defined (darwin_HOST_OS) - sys_icache_invalidate(p, size); + sys_icache_invalidate(p1, static_cast(p2 - p1)); # endif } From a56febcd13a4da8a62a55940b6edc7e8b9a79935 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 18 Oct 2019 17:39:57 +0200 Subject: [PATCH 16/28] Force HAVE_BUILTIN_CLEAR_CACHE for GNU compilers They always have __builtin___clear_cache --- cmake/flags.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/flags.cmake b/cmake/flags.cmake index 97f22f3c1..e9533eed5 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -54,6 +54,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU) #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") + add_definitions(/DHAVE_BUILTIN_CLEAR_CACHE) + elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL") From 5611249af7b4650d02bbdb7cce4502422edc3656 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 18 Oct 2019 18:04:13 +0200 Subject: [PATCH 17/28] Fixed __builtin___clear_cache detection --- src/crypto/randomx/jit_compiler_a64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index 586b407f7..f88f945ac 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -109,7 +109,7 @@ void sys_icache_invalidate(void *start, size_t len); static void clear_code_cache(char* p1, char* p2) { -# ifdef HAVE_BUILTIN_CLEAR_CACHE +# if defined (HAVE_BUILTIN_CLEAR_CACHE) || defined (__GNUC__) __builtin___clear_cache(p1, p2); # elif defined(ios_HOST_OS) || defined (darwin_HOST_OS) sys_icache_invalidate(p1, static_cast(p2 - p1)); From 578bebb04dbc9631f285860b48cee0bcee05b05d Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 18 Oct 2019 18:17:57 +0200 Subject: [PATCH 18/28] Prefer sys_icache_invalidate on iOS Also break compilation with error if clear cache is not available --- src/crypto/randomx/jit_compiler_a64.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index f88f945ac..bf790c2b4 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -109,10 +109,12 @@ void sys_icache_invalidate(void *start, size_t len); static void clear_code_cache(char* p1, char* p2) { -# if defined (HAVE_BUILTIN_CLEAR_CACHE) || defined (__GNUC__) - __builtin___clear_cache(p1, p2); -# elif defined(ios_HOST_OS) || defined (darwin_HOST_OS) +# if defined(ios_HOST_OS) || defined (darwin_HOST_OS) sys_icache_invalidate(p1, static_cast(p2 - p1)); +# elif defined (HAVE_BUILTIN_CLEAR_CACHE) || defined (__GNUC__) + __builtin___clear_cache(p1, p2); +# else +# error "No clear code cache function found" # endif } From 6b40ede2bce5061b141b5fc652fde1f5d4e42ede Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 19 Oct 2019 02:39:46 +0700 Subject: [PATCH 19/28] Don't add "self-select" field to generated config if it not supported. --- src/base/net/stratum/Pool.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index 71152fd0a..eb2fe5066 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -236,8 +236,9 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const if (m_mode == MODE_DAEMON) { obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator); } - - obj.AddMember(StringRef(kSelfSelect), m_daemon.url().toJSON(), allocator); + else { + obj.AddMember(StringRef(kSelfSelect), m_daemon.url().toJSON(), allocator); + } return obj; } From 2012ce384ee0ffbbe568f5ccaa9cf806faf269bf Mon Sep 17 00:00:00 2001 From: xmrig Date: Sun, 20 Oct 2019 11:48:23 +0700 Subject: [PATCH 20/28] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c7c6450b8..e520a5052 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,7 @@ [![GitHub stars](https://img.shields.io/github/stars/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/stargazers) [![GitHub forks](https://img.shields.io/github/forks/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/network) -XMRig is a high performance RandomX and CryptoNight CPU miner, with official support for Windows. - -* This is the **CPU-mining** version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd). +XMRig High performance, open source, cross platform RandomX, CryptoNight and Argon2 CPU/GPU miner, with official support for Windows @@ -30,6 +28,8 @@ XMRig is a high performance RandomX and CryptoNight CPU miner, with official sup ## Usage The preferred way to configure the miner is the [JSON config file](src/config.json) as it is more flexible and human friendly. The command line interface does not cover all features, such as mining profiles for different algorithms. Important options can be changed during runtime without miner restart by editing the config file or executing API calls. +* **[xmrig.com/wizard](https://xmrig.com/wizard)** helps you create initial configuration for the miner. + ### Command line options ``` Network: From b77c5428f9e13b6f6dc885dd37791b2554306e96 Mon Sep 17 00:00:00 2001 From: xmrig Date: Sun, 20 Oct 2019 16:02:49 +0700 Subject: [PATCH 21/28] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24964dbc8..3fa59cdfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v4.4.0-beta +- [#1068](https://github.com/xmrig/xmrig/pull/1068) Added support for `self-select` stratum protocol extension. +- [#1240](https://github.com/xmrig/xmrig/pull/1240) Sync with latest RandomX code. +- [#1243](https://github.com/xmrig/xmrig/pull/1243) Fixed incorrect OpenCL memory size detection in some cases. +- [#1247](https://github.com/xmrig/xmrig/pull/1247) Fixed ARM64 RandomX code alignment. +- [#1248](https://github.com/xmrig/xmrig/pull/1248) Fixed RandomX code cache cleanup on iOS/Darwin. + # v4.3.1-beta - Fixed regression in v4.3.0, miner didn't create `cn` mining profile with default config example. From 5613912ec446031618f294a73a0f38ae40bfe52b Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 20 Oct 2019 16:04:22 +0700 Subject: [PATCH 22/28] Added "self-select" to config example. --- src/config.json | 3 ++- src/core/config/Config_default.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/config.json b/src/config.json index 65a2a2dcc..cb027a27a 100644 --- a/src/config.json +++ b/src/config.json @@ -54,7 +54,8 @@ "enabled": true, "tls": false, "tls-fingerprint": null, - "daemon": false + "daemon": false, + "self-select": null } ], "print-time": 60, diff --git a/src/core/config/Config_default.h b/src/core/config/Config_default.h index e0e3f2722..8a2847583 100644 --- a/src/core/config/Config_default.h +++ b/src/core/config/Config_default.h @@ -88,7 +88,8 @@ R"===( "enabled": true, "tls": false, "tls-fingerprint": null, - "daemon": false + "daemon": false, + "self-select": null } ], "print-time": 60, From c29fa62260f99f8642f2be36b3be4b4e590f00fb Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 20 Oct 2019 23:59:29 +0700 Subject: [PATCH 23/28] #1241 Revert changes in ConsoleLog for Windows. --- src/base/io/log/backends/ConsoleLog.cpp | 28 ++++++++++++++++++++++++- src/base/io/log/backends/ConsoleLog.h | 6 ++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/base/io/log/backends/ConsoleLog.cpp b/src/base/io/log/backends/ConsoleLog.cpp index c2cd74dce..de907318f 100644 --- a/src/base/io/log/backends/ConsoleLog.cpp +++ b/src/base/io/log/backends/ConsoleLog.cpp @@ -49,6 +49,8 @@ xmrig::ConsoleLog::ConsoleLog() uv_tty_set_mode(m_tty, UV_TTY_MODE_NORMAL); # ifdef WIN32 + m_stream = reinterpret_cast(m_tty); + HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); if (handle != INVALID_HANDLE_VALUE) { DWORD mode = 0; @@ -67,14 +69,26 @@ xmrig::ConsoleLog::~ConsoleLog() } -void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t, bool colors) +void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool colors) { if (!m_tty || Log::colors != colors) { return; } +# ifdef _WIN32 + uv_buf_t buf = uv_buf_init(const_cast(line), static_cast(size)); + + if (!isWritable()) { + fputs(line, stdout); + fflush(stdout); + } + else { + uv_try_write(m_stream, &buf, 1); + } +# else fputs(line, stdout); fflush(stdout); +# endif } @@ -83,3 +97,15 @@ bool xmrig::ConsoleLog::isSupported() const const uv_handle_type type = uv_guess_handle(1); return type == UV_TTY || type == UV_NAMED_PIPE; } + + +#ifdef WIN32 +bool xmrig::ConsoleLog::isWritable() const +{ + if (!m_stream || uv_is_writable(m_stream) != 1) { + return false; + } + + return isSupported(); +} +#endif diff --git a/src/base/io/log/backends/ConsoleLog.h b/src/base/io/log/backends/ConsoleLog.h index 36610e5e8..549243ad9 100644 --- a/src/base/io/log/backends/ConsoleLog.h +++ b/src/base/io/log/backends/ConsoleLog.h @@ -53,6 +53,12 @@ private: bool isSupported() const; uv_tty_t *m_tty = nullptr; + +# ifdef _WIN32 + bool isWritable() const; + + uv_stream_t *m_stream = nullptr; +# endif }; From da20d7414597af97610f10f923c5b17e6e585705 Mon Sep 17 00:00:00 2001 From: xmrig Date: Mon, 21 Oct 2019 20:22:35 +0700 Subject: [PATCH 24/28] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fa59cdfb..9ada869bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,12 @@ # v4.4.0-beta - [#1068](https://github.com/xmrig/xmrig/pull/1068) Added support for `self-select` stratum protocol extension. - [#1240](https://github.com/xmrig/xmrig/pull/1240) Sync with latest RandomX code. +- [#1241](https://github.com/xmrig/xmrig/issues/1241) Fixed regression with colors on old Windows systems. - [#1243](https://github.com/xmrig/xmrig/pull/1243) Fixed incorrect OpenCL memory size detection in some cases. - [#1247](https://github.com/xmrig/xmrig/pull/1247) Fixed ARM64 RandomX code alignment. - [#1248](https://github.com/xmrig/xmrig/pull/1248) Fixed RandomX code cache cleanup on iOS/Darwin. + # v4.3.1-beta - Fixed regression in v4.3.0, miner didn't create `cn` mining profile with default config example. From 71ee145f70f66229f6839929b1facb04bac4995d Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 21 Oct 2019 21:27:05 +0700 Subject: [PATCH 25/28] Added "paused" field to API. --- src/core/Miner.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 45a903bac..49b548e9e 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -152,6 +152,7 @@ public: reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); reply.AddMember("cpu", Cpu::toJSON(doc), allocator); reply.AddMember("donate_level", controller->config()->pools().donateLevel(), allocator); + reply.AddMember("paused", !enabled, allocator); Value algo(kArrayType); From 52281906c6f424dcff9f3825e1a9d6ef1fdc06f3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 21 Oct 2019 23:01:30 +0700 Subject: [PATCH 26/28] Fixed "huge-pages" option. --- src/Summary.cpp | 8 ++++---- src/crypto/common/VirtualMemory.cpp | 2 +- src/crypto/common/VirtualMemory.h | 2 +- src/crypto/common/VirtualMemory_unix.cpp | 2 +- src/crypto/common/VirtualMemory_win.cpp | 6 ++++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index 227fdcc80..2b8939a7a 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -23,8 +23,8 @@ */ -#include -#include +#include +#include #include @@ -59,10 +59,10 @@ inline static const char *asmName(Assembly::Id assembly) #endif -static void print_memory(Config *) { +static void print_memory(Config *config) { # ifdef _WIN32 Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s", - "HUGE PAGES", VirtualMemory::isHugepagesAvailable() ? GREEN_BOLD("permission granted") : RED_BOLD("unavailable")); + "HUGE PAGES", config->cpu().isHugePages() ? (VirtualMemory::isHugepagesAvailable() ? GREEN_BOLD("permission granted") : RED_BOLD("unavailable")) : RED_BOLD("disabled")); # endif } diff --git a/src/crypto/common/VirtualMemory.cpp b/src/crypto/common/VirtualMemory.cpp index 66d29061f..0eaef3c5e 100644 --- a/src/crypto/common/VirtualMemory.cpp +++ b/src/crypto/common/VirtualMemory.cpp @@ -112,7 +112,7 @@ void xmrig::VirtualMemory::destroy() void xmrig::VirtualMemory::init(size_t poolSize, bool hugePages) { if (!pool) { - osInit(); + osInit(hugePages); } # ifdef XMRIG_FEATURE_HWLOC diff --git a/src/crypto/common/VirtualMemory.h b/src/crypto/common/VirtualMemory.h index 3c9839516..1c2e37d20 100644 --- a/src/crypto/common/VirtualMemory.h +++ b/src/crypto/common/VirtualMemory.h @@ -78,7 +78,7 @@ private: FLAG_MAX }; - static void osInit(); + static void osInit(bool hugePages); bool allocateLargePagesMemory(); void freeLargePagesMemory(); diff --git a/src/crypto/common/VirtualMemory_unix.cpp b/src/crypto/common/VirtualMemory_unix.cpp index bb0f9658a..3d099c761 100644 --- a/src/crypto/common/VirtualMemory_unix.cpp +++ b/src/crypto/common/VirtualMemory_unix.cpp @@ -96,7 +96,7 @@ void xmrig::VirtualMemory::unprotectExecutableMemory(void *p, size_t size) } -void xmrig::VirtualMemory::osInit() +void xmrig::VirtualMemory::osInit(bool) { } diff --git a/src/crypto/common/VirtualMemory_win.cpp b/src/crypto/common/VirtualMemory_win.cpp index 875a1e8e7..bfd8de1d6 100644 --- a/src/crypto/common/VirtualMemory_win.cpp +++ b/src/crypto/common/VirtualMemory_win.cpp @@ -201,9 +201,11 @@ void xmrig::VirtualMemory::unprotectExecutableMemory(void *p, size_t size) } -void xmrig::VirtualMemory::osInit() +void xmrig::VirtualMemory::osInit(bool hugePages) { - hugepagesAvailable = TrySetLockPagesPrivilege(); + if (hugePages) { + hugepagesAvailable = TrySetLockPagesPrivilege(); + } } From f7dcfffdb17573cae8c620a6b9e502540c41016b Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 22 Oct 2019 12:30:04 +0700 Subject: [PATCH 27/28] Removed unused class member. --- src/backend/opencl/wrappers/OclDevice.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/opencl/wrappers/OclDevice.h b/src/backend/opencl/wrappers/OclDevice.h index 1e3b019a4..04577d904 100644 --- a/src/backend/opencl/wrappers/OclDevice.h +++ b/src/backend/opencl/wrappers/OclDevice.h @@ -91,7 +91,6 @@ private: const String m_board; const String m_name; const String m_vendor; - const size_t m_freeMemory = 0; const size_t m_maxMemoryAlloc = 0; const size_t m_globalMemory = 0; const uint32_t m_computeUnits = 1; From 48545c591646d01ed640a2ef7cbff5bc429eaae2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 22 Oct 2019 13:09:58 +0700 Subject: [PATCH 28/28] Fixed compile warnings. --- src/crypto/common/MemoryPool.cpp | 3 +-- src/crypto/common/MemoryPool.h | 1 - src/crypto/common/NUMAMemoryPool.cpp | 9 --------- src/crypto/rx/RxQueue.cpp | 4 ++-- 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/crypto/common/MemoryPool.cpp b/src/crypto/common/MemoryPool.cpp index 475655b1e..2b2da6591 100644 --- a/src/crypto/common/MemoryPool.cpp +++ b/src/crypto/common/MemoryPool.cpp @@ -41,8 +41,7 @@ constexpr size_t pageSize = 2 * 1024 * 1024; } // namespace xmrig -xmrig::MemoryPool::MemoryPool(size_t size, bool hugePages, uint32_t node) : - m_size(size) +xmrig::MemoryPool::MemoryPool(size_t size, bool hugePages, uint32_t node) { if (!size) { return; diff --git a/src/crypto/common/MemoryPool.h b/src/crypto/common/MemoryPool.h index b5bd10203..d4d584ab9 100644 --- a/src/crypto/common/MemoryPool.h +++ b/src/crypto/common/MemoryPool.h @@ -52,7 +52,6 @@ protected: void release(uint32_t node) override; private: - size_t m_size = 0; size_t m_refs = 0; size_t m_offset = 0; VirtualMemory *m_memory = nullptr; diff --git a/src/crypto/common/NUMAMemoryPool.cpp b/src/crypto/common/NUMAMemoryPool.cpp index 8c48b4ca4..726700244 100644 --- a/src/crypto/common/NUMAMemoryPool.cpp +++ b/src/crypto/common/NUMAMemoryPool.cpp @@ -34,15 +34,6 @@ #include -namespace xmrig { - - -constexpr size_t pageSize = 2 * 1024 * 1024; - - -} // namespace xmrig - - xmrig::NUMAMemoryPool::NUMAMemoryPool(size_t size, bool hugePages) : m_hugePages(hugePages), m_nodeSize(std::max(size / Cpu::info()->nodes(), 1)), diff --git a/src/crypto/rx/RxQueue.cpp b/src/crypto/rx/RxQueue.cpp index 7eb3da362..6614d407c 100644 --- a/src/crypto/rx/RxQueue.cpp +++ b/src/crypto/rx/RxQueue.cpp @@ -46,7 +46,7 @@ xmrig::RxQueue::RxQueue(IRxListener *listener) : uv_async_init(uv_default_loop(), m_async, [](uv_async_t *handle) { static_cast(handle->data)->onReady(); }); - m_thread = std::move(std::thread(&RxQueue::backgroundInit, this)); + m_thread = std::thread(&RxQueue::backgroundInit, this); } @@ -158,7 +158,7 @@ void xmrig::RxQueue::backgroundInit() m_storage->init(item.seed, item.threads, item.hugePages); - lock = std::move(std::unique_lock(m_mutex)); + lock = std::unique_lock(m_mutex); if (m_state == STATE_SHUTDOWN || !m_queue.empty()) { continue;