From 4dc7a8103b8bed1d65fa49e468e5cb46dd99b3a8 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 11 Oct 2019 09:58:11 +0700 Subject: [PATCH 01/31] 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 8e43b6e0..6a59c8ac 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 15586fe8..072dc534 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 15d31ccc..fc6b6326 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 00000000..193c7291 --- /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 00000000..23fd750e --- /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/31] 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 2f629bca..ccf5ccf1 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 848e7879..9f8d9618 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 c86ecba5..ef1b03b5 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 d695c561..3c4c4724 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 072dc534..ccce16c9 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 fc6b6326..3c743602 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 600c97ed..c88e001f 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 193c7291..3de6bc9b 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 ac288793..a61f1a91 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 5d371874..f5928fe9 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/31] 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 6a59c8ac..615d9ac5 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 c872a37a..78e36348 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 3583be5a..45b0bcfd 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 56bdc126..51da1113 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 287ce4a5..70362bb8 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 ff2bf7f6..32121aa1 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 00b62e39..781ea1b6 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 ccce16c9..1570d5fb 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 3c743602..ca375c07 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 00000000..95a9ae95 --- /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 00000000..b4549ebe --- /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 48be2ba3..28c1ad99 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 283d4916..c69160ee 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 c923e1c2..a45be658 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 ea808193..f2c8b229 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 3952d94e..2be0af04 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 4c621f66..c249284b 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/31] 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 78e36348..06e12968 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 325fce1c..ccffa7ce 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 51da1113..0d73dc9b 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 70362bb8..54349533 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 32121aa1..8ff58c63 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 781ea1b6..0932b2be 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 1570d5fb..71152fd0 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 95a9ae95..7398d6ee 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 b4549ebe..aa39d430 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/31] 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 aaa91f62..7586c028 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/31] 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 67f8166b..14e81560 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 3be58ed2..faf03b66 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/31] 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 faf03b66..1e3b019a 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/31] 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 06e12968..db88638a 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 ccffa7ce..56e5ad7c 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 0d73dc9b..974e61a5 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 54349533..3619e4e9 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 8ff58c63..da423484 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 0932b2be..e819c07d 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 7398d6ee..3b6034a7 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 aa39d430..d8bc5585 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 5abd3e4b..1b49acb4 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/31] 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 113e2f13..2699e663 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 c5dfc43d..acf873dc 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 e97f989b..1130d12c 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 fbb453aa..ba4418b6 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 2c287330..747aeb31 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 c6a22809..a0de150e 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 3b6034a7..ae82dfaf 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 d8bc5585..c48c5078 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/31] #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 08f84f1c..b31d1fa8 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/31] 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 be37602b..13fd5c57 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/31] 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 b31d1fa8..1a6a6a06 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/31] 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 b31d1fa8..5587ca24 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/31] 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 f62550d0..79e099a0 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/31] 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 79e099a0..586b407f 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/31] 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 97f22f3c..e9533eed 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/31] 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 586b407f..f88f945a 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/31] 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 f88f945a..bf790c2b 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/31] 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 71152fd0..eb2fe506 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/31] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c7c6450b..e520a505 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/31] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24964dbc..3fa59cdf 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/31] 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 65a2a2dc..cb027a27 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 e0e3f272..8a284758 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/31] #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 c2cd74dc..de907318 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 36610e5e..549243ad 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/31] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fa59cdf..9ada869b 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/31] 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 45a903ba..49b548e9 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/31] 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 227fdcc8..2b8939a7 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 66d29061..0eaef3c5 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 3c983951..1c2e37d2 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 bb0f9658..3d099c76 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 875a1e8e..bfd8de1d 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/31] 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 1e3b019a..04577d90 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/31] 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 475655b1..2b2da659 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 b5bd1020..d4d584ab 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 8c48b4ca..72670024 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 7eb3da36..6614d407 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; From e3f37bc2f9647fbac37722c5f6e1e1c7e66529f5 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 22 Oct 2019 14:15:40 +0700 Subject: [PATCH 29/31] v4.4.0-beta --- src/version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/version.h b/src/version.h index a4e716d4..dab33f9d 100644 --- a/src/version.h +++ b/src/version.h @@ -28,15 +28,15 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "4.3.1-beta" +#define APP_VERSION "4.4.0-beta" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com" #define APP_KIND "miner" #define APP_VER_MAJOR 4 -#define APP_VER_MINOR 3 -#define APP_VER_PATCH 1 +#define APP_VER_MINOR 4 +#define APP_VER_PATCH 0 #ifdef _MSC_VER # if (_MSC_VER >= 1920) From 6e9fd5a430836e36549191cb13466c579e8a3435 Mon Sep 17 00:00:00 2001 From: xmrig Date: Tue, 22 Oct 2019 15:28:15 +0700 Subject: [PATCH 30/31] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ada869b..b380d75b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # 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. +- [#1240](https://github.com/xmrig/xmrig/pull/1240) Sync with the 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. From dc705d88ab19f30f6c1bd56d0724820ae87bf020 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 22 Oct 2019 16:54:36 +0700 Subject: [PATCH 31/31] Fixed "coin" option for self select mode. --- src/base/net/stratum/SelfSelectClient.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/base/net/stratum/SelfSelectClient.cpp b/src/base/net/stratum/SelfSelectClient.cpp index ae82dfaf..4de49f6e 100644 --- a/src/base/net/stratum/SelfSelectClient.cpp +++ b/src/base/net/stratum/SelfSelectClient.cpp @@ -131,6 +131,10 @@ bool xmrig::SelfSelectClient::parseResponse(int64_t id, rapidjson::Value &result return false; } + if (pool().coin().isValid()) { + m_job.setAlgorithm(pool().coin().algorithm(m_job.blob()[0])); + } + m_job.setHeight(Json::getUint64(result, kHeight)); m_job.setSeedHash(Json::getString(result, kSeedHash));