diff --git a/CHANGELOG.md b/CHANGELOG.md index 48472f029..655682cb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# v6.19.0 +- [#530](https://github.com/xmrig/xmrig-proxy/pull/530) Sync with latest XMRig. + # v6.18.0 - Sync changes with XMRig v6.18.0 - [#499](https://github.com/xmrig/xmrig-proxy/pull/499) Fixed socket and memory leak. diff --git a/cmake/os.cmake b/cmake/os.cmake index 0270cc930..c9e461650 100644 --- a/cmake/os.cmake +++ b/cmake/os.cmake @@ -15,7 +15,7 @@ else() set(XMRIG_OS_ANDROID ON) elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") set(XMRIG_OS_LINUX ON) - elseif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD) + elseif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL DragonFly) set(XMRIG_OS_FREEBSD ON) endif() endif() diff --git a/src/base/kernel/Platform_unix.cpp b/src/base/kernel/Platform_unix.cpp index f5bbc1931..4ffee2140 100644 --- a/src/base/kernel/Platform_unix.cpp +++ b/src/base/kernel/Platform_unix.cpp @@ -16,10 +16,12 @@ * along with this program. If not, see . */ -#ifdef __FreeBSD__ +#ifdef XMRIG_OS_FREEBSD # include # include -# include +# ifndef __DragonFly__ +# include +# endif # include #endif @@ -41,11 +43,6 @@ #include "version.h" -#ifdef __FreeBSD__ -typedef cpuset_t cpu_set_t; -#endif - - char *xmrig::Platform::createUserAgent() { constexpr const size_t max = 256; @@ -74,6 +71,19 @@ char *xmrig::Platform::createUserAgent() #ifndef XMRIG_FEATURE_HWLOC +#ifdef __DragonFly__ + +bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id) +{ + return true; +} + +#else + +#ifdef XMRIG_OS_FREEBSD +typedef cpuset_t cpu_set_t; +#endif + bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id) { cpu_set_t mn; @@ -89,7 +99,9 @@ bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id) std::this_thread::sleep_for(std::chrono::milliseconds(1)); return result; } -#endif + +#endif // __DragonFly__ +#endif // XMRIG_FEATURE_HWLOC void xmrig::Platform::setProcessPriority(int) diff --git a/src/base/kernel/config/BaseTransform.cpp b/src/base/kernel/config/BaseTransform.cpp index c924dd59a..a1b430da3 100644 --- a/src/base/kernel/config/BaseTransform.cpp +++ b/src/base/kernel/config/BaseTransform.cpp @@ -247,6 +247,7 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch case IConfig::HttpPort: /* --http-port */ case IConfig::DonateLevelKey: /* --donate-level */ case IConfig::DaemonPollKey: /* --daemon-poll-interval */ + case IConfig::DaemonJobTimeoutKey: /* --daemon-job-timeout */ case IConfig::DnsTtlKey: /* --dns-ttl */ case IConfig::DaemonZMQPortKey: /* --daemon-zmq-port */ return transformUint64(doc, key, static_cast(strtol(arg, nullptr, 10))); @@ -360,6 +361,9 @@ void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, ui case IConfig::DaemonPollKey: /* --daemon-poll-interval */ return add(doc, Pools::kPools, Pool::kDaemonPollInterval, arg); + case IConfig::DaemonJobTimeoutKey: /* --daemon-job-timeout */ + return add(doc, Pools::kPools, Pool::kDaemonJobTimeout, arg); + case IConfig::DaemonZMQPortKey: /* --daemon-zmq-port */ return add(doc, Pools::kPools, Pool::kDaemonZMQPort, arg); # endif diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index ed76f4cd2..98957fc4b 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -88,6 +88,7 @@ class IConfig DaemonZMQPortKey = 1056, HugePagesJitKey = 1057, RotationKey = 1058, + DaemonJobTimeoutKey = 1059, // xmrig common CPUPriorityKey = 1021, diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 7abb72533..dfe2d6640 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -1018,7 +1018,7 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status) if (status < 0) { if (!client->isQuiet()) { - LOG_ERR("%s " RED("connect error: ") RED_BOLD("\"%s\""), client->tag(), uv_strerror(status)); + LOG_ERR("%s %s " RED("connect error: ") RED_BOLD("\"%s\""), client->tag(), client->ip().data(), uv_strerror(status)); } if (client->state() == ReconnectingState || client->state() == ClosingState) { diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 821045e9d..10c041163 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -66,7 +66,6 @@ Storage DaemonClient::m_storage; static const char* kBlocktemplateBlob = "blocktemplate_blob"; static const char* kBlockhashingBlob = "blockhashing_blob"; -static const char* kLastError = "lasterror"; static const char *kGetHeight = "/getheight"; static const char *kGetInfo = "/getinfo"; static const char *kHash = "hash"; @@ -304,6 +303,18 @@ void xmrig::DaemonClient::onHttpData(const HttpData &data) void xmrig::DaemonClient::onTimer(const Timer *) { + if (m_pool.zmq_port() >= 0) { + m_prevHash = nullptr; + m_blocktemplateRequestHash = nullptr; + send(kGetHeight); + return; + } + + if (Chrono::steadyMSecs() >= m_jobSteadyMs + m_pool.jobTimeout()) { + m_prevHash = nullptr; + m_blocktemplateRequestHash = nullptr; + } + if (m_state == ConnectingState) { connect(); } @@ -353,7 +364,7 @@ void xmrig::DaemonClient::onResolved(const DnsRecords &records, int status, cons bool xmrig::DaemonClient::isOutdated(uint64_t height, const char *hash) const { - return m_job.height() != height || m_prevHash != hash; + return m_job.height() != height || m_prevHash != hash || Chrono::steadyMSecs() >= m_jobSteadyMs + m_pool.jobTimeout(); } @@ -469,6 +480,7 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code) m_job = std::move(job); m_blocktemplateStr = std::move(blocktemplate); m_prevHash = Json::getString(params, "prev_hash"); + m_jobSteadyMs = Chrono::steadyMSecs(); if (m_state == ConnectingState) { setState(ConnectedState); @@ -597,6 +609,10 @@ void xmrig::DaemonClient::setState(SocketState state) const uint64_t interval = std::max(20, m_pool.pollInterval()); m_timer->start(interval, interval); } + else { + const uint64_t t = m_pool.jobTimeout(); + m_timer->start(t, t); + } } break; @@ -866,7 +882,12 @@ void xmrig::DaemonClient::ZMQParse() // Clear previous hash and check daemon height to guarantee that xmrig will call get_block_template RPC later // We can't call get_block_template directly because daemon is not ready yet m_prevHash = nullptr; + m_blocktemplateRequestHash = nullptr; send(kGetHeight); + + const uint64_t t = m_pool.jobTimeout(); + m_timer->stop(); + m_timer->start(t, t); } diff --git a/src/base/net/stratum/DaemonClient.h b/src/base/net/stratum/DaemonClient.h index 7880de404..94d2b973a 100644 --- a/src/base/net/stratum/DaemonClient.h +++ b/src/base/net/stratum/DaemonClient.h @@ -104,6 +104,7 @@ class DaemonClient : public BaseClient, public IDnsListener, public ITimerListen String m_blocktemplateStr; String m_currentJobId; String m_prevHash; + uint64_t m_jobSteadyMs = 0; String m_tlsFingerprint; String m_tlsVersion; Timer *m_timer; diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index 7f5d8d3f3..56f5de804 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -48,7 +48,13 @@ xmrig::Job::Job(bool nicehash, const Algorithm &algorithm, const String &clientI bool xmrig::Job::isEqual(const Job &other) const { - return m_id == other.m_id && m_clientId == other.m_clientId && memcmp(m_blob, other.m_blob, sizeof(m_blob)) == 0 && m_target == other.m_target; + return m_id == other.m_id && m_clientId == other.m_clientId && isEqualBlob(other) && m_target == other.m_target; +} + + +bool xmrig::Job::isEqualBlob(const Job &other) const +{ + return (m_size == other.m_size) && (memcmp(m_blob, other.m_blob, m_size) == 0); } @@ -58,19 +64,19 @@ bool xmrig::Job::setBlob(const char *blob) return false; } - m_size = strlen(blob); - if (m_size % 2 != 0) { + size_t size = strlen(blob); + if (size % 2 != 0) { return false; } - m_size /= 2; + size /= 2; const size_t minSize = nonceOffset() + nonceSize(); - if (m_size < minSize || m_size >= sizeof(m_blob)) { + if (size < minSize || size >= sizeof(m_blob)) { return false; } - if (!Cvt::fromHex(m_blob, sizeof(m_blob), blob, m_size * 2)) { + if (!Cvt::fromHex(m_blob, sizeof(m_blob), blob, size * 2)) { return false; } @@ -80,9 +86,10 @@ bool xmrig::Job::setBlob(const char *blob) # ifdef XMRIG_PROXY_PROJECT memset(m_rawBlob, 0, sizeof(m_rawBlob)); - memcpy(m_rawBlob, blob, m_size * 2); + memcpy(m_rawBlob, blob, size * 2); # endif + m_size = size; return true; } diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index 3fb31baa5..e314a266d 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -59,6 +59,7 @@ class Job ~Job() = default; bool isEqual(const Job &other) const; + bool isEqualBlob(const Job &other) const; bool setBlob(const char *blob); bool setSeedHash(const char *hash); bool setTarget(const char *target); diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index 7a58f4cb5..b1773c46d 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -65,6 +65,7 @@ const char *Pool::kAlgo = "algo"; const char *Pool::kCoin = "coin"; const char *Pool::kDaemon = "daemon"; const char *Pool::kDaemonPollInterval = "daemon-poll-interval"; +const char *Pool::kDaemonJobTimeout = "daemon-job-timeout"; const char *Pool::kDaemonZMQPort = "daemon-zmq-port"; const char *Pool::kEnabled = "enabled"; const char *Pool::kFingerprint = "tls-fingerprint"; @@ -88,6 +89,7 @@ const char *Pool::kNicehashHost = "nicehash.com"; xmrig::Pool::Pool(const char *url) : m_flags(1 << FLAG_ENABLED), m_pollInterval(kDefaultPollInterval), + m_jobTimeout(kDefaultJobTimeout), m_url(url) { } @@ -101,6 +103,7 @@ xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char m_user(user), m_spendSecretKey(spendSecretKey), m_pollInterval(kDefaultPollInterval), + m_jobTimeout(kDefaultJobTimeout), m_url(host, port, tls) { m_flags.set(FLAG_NICEHASH, nicehash || strstr(host, kNicehashHost)); @@ -111,6 +114,7 @@ xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char xmrig::Pool::Pool(const rapidjson::Value &object) : m_flags(1 << FLAG_ENABLED), m_pollInterval(kDefaultPollInterval), + m_jobTimeout(kDefaultJobTimeout), m_url(Json::getString(object, kUrl)) { if (!m_url.isValid()) { @@ -123,6 +127,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) : m_rigId = Json::getString(object, kRigId); m_fingerprint = Json::getString(object, kFingerprint); m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval); + m_jobTimeout = Json::getUint64(object, kDaemonJobTimeout, kDefaultJobTimeout); m_algorithm = Json::getString(object, kAlgo); m_coin = Json::getString(object, kCoin); m_daemon = Json::getString(object, kSelfSelect); @@ -207,6 +212,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_jobTimeout == other.m_jobTimeout && m_daemon == other.m_daemon && m_proxy == other.m_proxy ); @@ -299,6 +305,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const if (m_mode == MODE_DAEMON) { obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator); + obj.AddMember(StringRef(kDaemonJobTimeout), m_jobTimeout, allocator); obj.AddMember(StringRef(kDaemonZMQPort), m_zmqPort, allocator); } else { diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h index 78684510f..8374f20ff 100644 --- a/src/base/net/stratum/Pool.h +++ b/src/base/net/stratum/Pool.h @@ -59,6 +59,7 @@ class Pool static const char *kCoin; static const char *kDaemon; static const char *kDaemonPollInterval; + static const char* kDaemonJobTimeout; static const char *kEnabled; static const char *kFingerprint; static const char *kKeepalive; @@ -78,6 +79,7 @@ class Pool constexpr static int kKeepAliveTimeout = 60; constexpr static uint16_t kDefaultPort = 3333; constexpr static uint64_t kDefaultPollInterval = 1000; + constexpr static uint64_t kDefaultJobTimeout = 15000; Pool() = default; Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, Mode mode); @@ -110,6 +112,7 @@ class Pool inline uint16_t port() const { return m_url.port(); } inline int zmq_port() const { return m_zmqPort; } inline uint64_t pollInterval() const { return m_pollInterval; } + inline uint64_t jobTimeout() const { return m_jobTimeout; } inline void setAlgo(const Algorithm &algorithm) { m_algorithm = algorithm; } inline void setUrl(const char *url) { m_url = Url(url); } inline void setPassword(const String &password) { m_password = password; } @@ -156,6 +159,7 @@ class Pool String m_user; String m_spendSecretKey; uint64_t m_pollInterval = kDefaultPollInterval; + uint64_t m_jobTimeout = kDefaultJobTimeout; Url m_daemon; Url m_url; int m_zmqPort = -1; diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index 2c090e3bb..e229220de 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -54,6 +54,12 @@ static struct option const options[] = { { "http-access-token", 1, nullptr, IConfig::HttpAccessTokenKey}, { "http-port", 1, nullptr, IConfig::HttpPort }, { "http-no-restricted",0, nullptr, IConfig::HttpRestrictedKey }, + { "daemon", 0, nullptr, IConfig::DaemonKey }, + { "daemon-poll-interval", 1, nullptr, IConfig::DaemonPollKey }, + { "daemon-job-timeout", 1, nullptr, IConfig::DaemonJobTimeoutKey }, + { "self-select", 1, nullptr, IConfig::SelfSelectKey }, + { "submit-to-origin", 0, nullptr, IConfig::SubmitToOriginKey }, + { "daemon-zmq-port", 1, nullptr, IConfig::DaemonZMQPortKey }, { "background", 0, nullptr, IConfig::BackgroundKey }, { "bind", 1, nullptr, IConfig::BindKey }, { "config", 1, nullptr, IConfig::ConfigKey }, diff --git a/src/core/config/usage.h b/src/core/config/usage.h index d55b61a57..8bc4fe341 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -64,7 +64,9 @@ static inline const std::string &usage() # ifdef XMRIG_FEATURE_HTTP u += " --daemon use daemon RPC instead of pool for solo mining\n"; + u += " --daemon-zmq-port daemon's zmq-pub port number (only use it if daemon has it enabled)\n"; u += " --daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)\n"; + u += " --daemon-job-timeout=N daemon job timeout in milliseconds (default: 15000)\n"; u += " --self-select=URL self-select block templates from URL\n"; u += " --submit-to-origin also submit solution back to self-select URL\n"; # endif diff --git a/src/version.h b/src/version.h index 200d4068d..1e1a20d35 100644 --- a/src/version.h +++ b/src/version.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2022 SChernykh - * Copyright (c) 2016-2022 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 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 @@ -22,18 +22,20 @@ #define APP_ID "xmrig-proxy" #define APP_NAME "xmrig-proxy" #define APP_DESC "XMRig Stratum proxy" -#define APP_VERSION "6.18.0" +#define APP_VERSION "6.19.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" -#define APP_COPYRIGHT "Copyright (C) 2016-2022 xmrig.com" +#define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" #define APP_KIND "proxy" #define APP_VER_MAJOR 6 -#define APP_VER_MINOR 18 +#define APP_VER_MINOR 19 #define APP_VER_PATCH 0 #ifdef _MSC_VER -# if (_MSC_VER >= 1920) +# if (_MSC_VER >= 1930) +# define MSVC_VERSION 2022 +# elif (_MSC_VER >= 1920 && _MSC_VER < 1930) # define MSVC_VERSION 2019 # elif (_MSC_VER >= 1910 && _MSC_VER < 1920) # define MSVC_VERSION 2017 @@ -50,4 +52,4 @@ # endif #endif -#endif /* XMRIG_VERSION_H */ +#endif // XMRIG_VERSION_H