diff --git a/CMakeLists.txt b/CMakeLists.txt index c7017b01..b26b1d93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(xmrig) option(WITH_LIBCPUID "Use Libcpuid" ON) option(WITH_AEON "CryptoNight-Lite support" ON) option(WITH_SUMO "CryptoNight-Heavy support" ON) +option(WITH_IPBC "CryptoNight-IPBC support" ON) option(WITH_HTTPD "HTTP REST API" ON) option(BUILD_STATIC "Build static binary" OFF) @@ -17,11 +18,24 @@ set(HEADERS src/common/config/CommonConfig.h src/common/config/ConfigLoader.h src/common/config/ConfigWatcher.h + src/common/Console.h + src/common/crypto/Algorithm.h + src/common/crypto/keccak.h + src/common/log/ConsoleLog.h + src/common/log/FileLog.h + src/common/log/Log.h + src/common/net/Client.h + src/common/net/Id.h + src/common/net/Job.h + src/common/net/Pool.h + src/common/net/Storage.h + src/common/net/strategies/FailoverStrategy.h + src/common/net/strategies/SinglePoolStrategy.h + src/common/net/SubmitResult.h src/common/Platform.h src/common/utils/c_str.h src/common/utils/mm_malloc.h src/common/xmrig.h - src/Console.h src/core/Config.cpp src/core/ConfigLoader_platform.h src/core/Controller.h @@ -38,21 +52,10 @@ set(HEADERS src/interfaces/IThread.h src/interfaces/IWatcherListener.h src/interfaces/IWorker.h - src/log/ConsoleLog.h - src/log/FileLog.h - src/log/Log.h src/Mem.h - src/net/Client.h - src/net/Id.h - src/net/Job.h src/net/JobResult.h src/net/Network.h - src/net/Pool.h - src/net/Storage.h src/net/strategies/DonateStrategy.h - src/net/strategies/FailoverStrategy.h - src/net/strategies/SinglePoolStrategy.h - src/net/SubmitResult.h src/Summary.h src/version.h src/workers/CpuThread.h @@ -67,7 +70,6 @@ set(HEADERS_CRYPTO src/crypto/c_blake256.h src/crypto/c_groestl.h src/crypto/c_jh.h - src/crypto/c_keccak.h src/crypto/c_skein.h src/crypto/CryptoNight.h src/crypto/CryptoNight_constants.h @@ -91,22 +93,24 @@ set(SOURCES src/common/config/CommonConfig.cpp src/common/config/ConfigLoader.cpp src/common/config/ConfigWatcher.cpp + src/common/Console.cpp + src/common/crypto/Algorithm.cpp + src/common/crypto/keccak.cpp + src/common/log/ConsoleLog.cpp + src/common/log/FileLog.cpp + src/common/log/Log.cpp + src/common/net/Client.cpp + src/common/net/Job.cpp + src/common/net/Pool.cpp + src/common/net/strategies/FailoverStrategy.cpp + src/common/net/strategies/SinglePoolStrategy.cpp + src/common/net/SubmitResult.cpp src/common/Platform.cpp - src/Console.cpp src/core/Config.cpp src/core/Controller.cpp - src/log/ConsoleLog.cpp - src/log/FileLog.cpp - src/log/Log.cpp src/Mem.cpp - src/net/Client.cpp - src/net/Job.cpp src/net/Network.cpp - src/net/Pool.cpp src/net/strategies/DonateStrategy.cpp - src/net/strategies/FailoverStrategy.cpp - src/net/strategies/SinglePoolStrategy.cpp - src/net/SubmitResult.cpp src/Summary.cpp src/workers/CpuThread.cpp src/workers/Handle.cpp @@ -118,7 +122,6 @@ set(SOURCES ) set(SOURCES_CRYPTO - src/crypto/c_keccak.c src/crypto/c_groestl.c src/crypto/c_blake256.c src/crypto/c_jh.c @@ -194,7 +197,7 @@ endif() CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H) if (HAVE_SYSLOG_H) add_definitions(/DHAVE_SYSLOG_H) - set(SOURCES_SYSLOG src/log/SysLog.h src/log/SysLog.cpp) + set(SOURCES_SYSLOG src/common/log/SysLog.h src/common/log/SysLog.cpp) endif() if (NOT WITH_AEON) @@ -205,6 +208,10 @@ if (NOT WITH_SUMO) add_definitions(/DXMRIG_NO_SUMO) endif() +if (NOT WITH_IPBC) + add_definitions(/DXMRIG_NO_IPBC) +endif() + if (WITH_HTTPD) find_package(MHD) diff --git a/src/App.cpp b/src/App.cpp index 78d6b328..adcc5752 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -28,15 +28,13 @@ #include "api/Api.h" #include "App.h" +#include "common/Console.h" +#include "common/log/Log.h" #include "common/Platform.h" -#include "Console.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" #include "crypto/CryptoNight.h" -#include "log/ConsoleLog.h" -#include "log/FileLog.h" -#include "log/Log.h" #include "Mem.h" #include "net/Network.h" #include "Summary.h" diff --git a/src/App_unix.cpp b/src/App_unix.cpp index f739e42e..45f73d2d 100644 --- a/src/App_unix.cpp +++ b/src/App_unix.cpp @@ -29,9 +29,9 @@ #include "App.h" +#include "common/log/Log.h" #include "core/Config.h" #include "core/Controller.h" -#include "log/Log.h" void App::background() diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 229a0d46..c1aa0fb1 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -27,10 +27,10 @@ #include +#include "common/log/Log.h" #include "common/utils/mm_malloc.h" #include "common/xmrig.h" #include "crypto/CryptoNight.h" -#include "log/Log.h" #include "Mem.h" diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 9a81b039..2bfcc3b0 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -29,11 +29,11 @@ #include +#include "common/log/Log.h" #include "common/utils/mm_malloc.h" #include "common/xmrig.h" #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_constants.h" -#include "log/Log.h" #include "Mem.h" diff --git a/src/Summary.cpp b/src/Summary.cpp index 32a0e4bb..e960dd8d 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -27,12 +27,12 @@ #include +#include "common/log/Log.h" +#include "common/net/Pool.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" -#include "log/Log.h" #include "Mem.h" -#include "net/Pool.h" #include "Summary.h" #include "version.h" @@ -104,7 +104,7 @@ static void print_threads(xmrig::Config *config) Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", config->threadsCount(), - config->algoName(), + config->algorithm().name(), config->algoVariant(), config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", config->donateLevel(), @@ -113,7 +113,7 @@ static void print_threads(xmrig::Config *config) else { Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, %sdonate=%d%%" : " * THREADS: %d, %s, %sdonate=%d%%", config->threadsCount(), - config->algoName(), + config->algorithm().name(), config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", config->donateLevel()); } @@ -132,8 +132,8 @@ static void print_pools(xmrig::Config *config) } # ifdef APP_DEBUG - for (size_t i = 0; i < pools.size(); ++i) { - Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i].host(), pools[i].port(), pools[i].user(), pools[i].password(), pools[i].keepAlive(), pools[i].isNicehash()); + for (const Pool &pool : pools) { + pool.print(); } # endif } diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 42256cc9..07e425f1 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -35,13 +35,14 @@ #include "api/ApiRouter.h" #include "common/api/HttpReply.h" #include "common/api/HttpRequest.h" +#include "common/crypto/keccak.h" +#include "common/net/Job.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" #include "interfaces/IThread.h" #include "Mem.h" -#include "net/Job.h" #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" #include "rapidjson/stringbuffer.h" @@ -50,12 +51,6 @@ #include "workers/Workers.h" -extern "C" -{ -#include "crypto/c_keccak.h" -} - - static inline double normalize(double d) { if (!isnormal(d)) { @@ -171,7 +166,7 @@ void ApiRouter::genId() memcpy(input, interfaces[i].phys_addr, addrSize); memcpy(input + addrSize, APP_KIND, strlen(APP_KIND)); - keccak(input, static_cast(inSize), hash, sizeof(hash)); + xmrig::keccak(input, inSize, hash); Job::toHex(hash, 8, m_id); delete [] input; @@ -249,7 +244,7 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const doc.AddMember("kind", APP_KIND, allocator); doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator); doc.AddMember("cpu", cpu, allocator); - doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algoName()), allocator); + doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), allocator); doc.AddMember("hugepages", Workers::hugePages() > 0, allocator); doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator); } diff --git a/src/api/NetworkState.cpp b/src/api/NetworkState.cpp index d3ffddd3..0ab80093 100644 --- a/src/api/NetworkState.cpp +++ b/src/api/NetworkState.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 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 @@ -29,7 +29,7 @@ #include "api/NetworkState.h" -#include "net/SubmitResult.h" +#include "common/net/SubmitResult.h" NetworkState::NetworkState() : diff --git a/src/Console.cpp b/src/common/Console.cpp similarity index 90% rename from src/Console.cpp rename to src/common/Console.cpp index 3d95ada4..350fb139 100644 --- a/src/Console.cpp +++ b/src/common/Console.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 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,7 +22,7 @@ */ -#include "Console.h" +#include "common/Console.h" #include "interfaces/IConsoleListener.h" diff --git a/src/Console.h b/src/common/Console.h similarity index 88% rename from src/Console.h rename to src/common/Console.h index bde95d7d..7f2e3cc9 100644 --- a/src/Console.h +++ b/src/common/Console.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 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 diff --git a/src/common/Platform_unix.cpp b/src/common/Platform_unix.cpp index 624594e9..63cd1c8b 100644 --- a/src/common/Platform_unix.cpp +++ b/src/common/Platform_unix.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 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 diff --git a/src/common/api/Httpd.cpp b/src/common/api/Httpd.cpp index 135ac7c9..eb6a4ba6 100644 --- a/src/common/api/Httpd.cpp +++ b/src/common/api/Httpd.cpp @@ -30,7 +30,7 @@ #include "common/api/Httpd.h" #include "common/api/HttpReply.h" #include "common/api/HttpRequest.h" -#include "log/Log.h" +#include "common/log/Log.h" Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) : @@ -81,7 +81,12 @@ bool Httpd::start() return false; } +# if MHD_VERSION >= 0x00093900 uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval); +# else + uv_timer_start(&m_timer, Httpd::onTimer, kActiveInterval, kActiveInterval); +# endif + return true; } @@ -107,6 +112,7 @@ void Httpd::run() { MHD_run(m_daemon); +# if MHD_VERSION >= 0x00093900 const MHD_DaemonInfo *info = MHD_get_daemon_info(m_daemon, MHD_DAEMON_INFO_CURRENT_CONNECTIONS); if (m_idle && info->num_connections) { uv_timer_set_repeat(&m_timer, kActiveInterval); @@ -116,6 +122,7 @@ void Httpd::run() uv_timer_set_repeat(&m_timer, kIdleInterval); m_idle = true; } +# endif } diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 22fd348d..5eaf68fd 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -30,16 +30,14 @@ #include "common/config/CommonConfig.h" +#include "common/log/Log.h" #include "donate.h" -#include "log/Log.h" -#include "net/Pool.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" xmrig::CommonConfig::CommonConfig() : - m_algorithm(CRYPTONIGHT), m_adjusted(false), m_apiIPv6(false), m_apiRestricted(true), @@ -57,7 +55,8 @@ xmrig::CommonConfig::CommonConfig() : m_donateLevel(kDefaultDonateLevel), m_printTime(60), m_retries(5), - m_retryPause(5) + m_retryPause(5), + m_state(NoneState) { m_pools.push_back(Pool()); @@ -73,28 +72,40 @@ xmrig::CommonConfig::~CommonConfig() } -bool xmrig::CommonConfig::adjust() +bool xmrig::CommonConfig::finalize() { - if (m_adjusted) { + if (m_state == ReadyState) { + return true; + } + + if (m_state == ErrorState) { return false; } - m_adjusted = true; - - for (Pool &pool : m_pools) { - pool.adjust(algorithm()); + if (!m_algorithm.isValid()) { + m_algorithm.setAlgo(CRYPTONIGHT); } + for (Pool &pool : m_pools) { + pool.adjust(m_algorithm.algo()); + + if (pool.isValid() && pool.algorithm().isValid()) { + m_activePools.push_back(std::move(pool)); + } + } + + m_pools.clear(); + + if (m_activePools.empty()) { + m_state = ErrorState; + return false; + } + + m_state = ReadyState; return true; } -bool xmrig::CommonConfig::isValid() const -{ - return m_pools[0].isValid() && m_algorithm != INVALID_ALGO; -} - - bool xmrig::CommonConfig::parseBoolean(int key, bool enable) { switch (key) { @@ -142,7 +153,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) { switch (key) { case AlgorithmKey: /* --algo */ - setAlgo(arg); + m_algorithm.parseAlgorithm(arg); break; case UserpassKey: /* --userpass */ @@ -178,6 +189,14 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) m_pools.back().setPassword(arg); break; + case RigIdKey: /* --rig-id */ + m_pools.back().setRigId(arg); + break; + + case VariantKey: /* --variant */ + m_pools.back().algorithm().parseVariant(arg); + break; + case LogFileKey: /* --log-file */ m_logFile = arg; break; @@ -196,7 +215,6 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) case RetriesKey: /* --retries */ case RetryPauseKey: /* --retry-pause */ - case VariantKey: /* --variant */ case ApiPort: /* --api-port */ case PrintTimeKey: /* --cpu-priority */ return parseUint64(key, strtol(arg, nullptr, 10)); @@ -205,7 +223,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) case SyslogKey: /* --syslog */ case KeepAliveKey: /* --keepalive */ case NicehashKey: /* --nicehash */ - case ApiIPv6Key: /* --api-ipv6 */ + case ApiIPv6Key: /* --api-ipv6 */ return parseBoolean(key, true); case ColorKey: /* --no-color */ @@ -296,7 +314,7 @@ bool xmrig::CommonConfig::parseInt(int key, int arg) break; case VariantKey: /* --variant */ - m_pools.back().setVariant(arg); + m_pools.back().algorithm().parseVariant(arg); break; case DonateLevelKey: /* --donate-level */ @@ -323,9 +341,3 @@ bool xmrig::CommonConfig::parseInt(int key, int arg) return true; } - - -void xmrig::CommonConfig::setAlgo(const char *algo) -{ - m_algorithm = Pool::algorithm(algo); -} diff --git a/src/common/config/CommonConfig.h b/src/common/config/CommonConfig.h index 5a229269..d54afe3a 100644 --- a/src/common/config/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -28,10 +28,10 @@ #include +#include "common/net/Pool.h" #include "common/utils/c_str.h" #include "common/xmrig.h" #include "interfaces/IConfig.h" -#include "net/Pool.h" namespace xmrig { @@ -43,18 +43,17 @@ public: CommonConfig(); ~CommonConfig(); - inline Algo algorithm() const { return m_algorithm; } inline bool isApiIPv6() const { return m_apiIPv6; } inline bool isApiRestricted() const { return m_apiRestricted; } inline bool isBackground() const { return m_background; } inline bool isColors() const { return m_colors; } inline bool isSyslog() const { return m_syslog; } - inline const char *algoName() const { return Pool::algoName(m_algorithm); } + inline const Algorithm &algorithm() const { return m_algorithm; } inline const char *apiToken() const { return m_apiToken.data(); } inline const char *apiWorkerId() const { return m_apiWorkerId.data(); } inline const char *logFile() const { return m_logFile.data(); } inline const char *userAgent() const { return m_userAgent.data(); } - inline const std::vector &pools() const { return m_pools; } + inline const std::vector &pools() const { return m_activePools; } inline int apiPort() const { return m_apiPort; } inline int donateLevel() const { return m_donateLevel; } inline int printTime() const { return m_printTime; } @@ -66,15 +65,20 @@ public: inline const char *fileName() const override { return m_fileName.data(); } protected: - bool adjust() override; - bool isValid() const override; + enum State { + NoneState, + ReadyState, + ErrorState + }; + + bool finalize() override; bool parseBoolean(int key, bool enable) override; bool parseString(int key, const char *arg) override; bool parseUint64(int key, uint64_t arg) override; bool save() override; void setFileName(const char *fileName) override; - Algo m_algorithm; + Algorithm m_algorithm; bool m_adjusted; bool m_apiIPv6; bool m_apiRestricted; @@ -87,6 +91,8 @@ protected: int m_printTime; int m_retries; int m_retryPause; + State m_state; + std::vector m_activePools; std::vector m_pools; xmrig::c_str m_apiToken; xmrig::c_str m_apiWorkerId; @@ -96,7 +102,6 @@ protected: private: bool parseInt(int key, int arg); - void setAlgo(const char *algo); }; diff --git a/src/common/config/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp index 47c6cdf9..919ff00c 100644 --- a/src/common/config/ConfigLoader.cpp +++ b/src/common/config/ConfigLoader.cpp @@ -34,12 +34,12 @@ #include "common/config/ConfigLoader.h" #include "common/config/ConfigWatcher.h" +#include "common/net/Pool.h" #include "common/Platform.h" #include "core/ConfigCreator.h" #include "core/ConfigLoader_platform.h" #include "interfaces/IConfig.h" #include "interfaces/IWatcherListener.h" -#include "net/Pool.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" #include "rapidjson/filereadstream.h" @@ -108,9 +108,8 @@ bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson:: } config->parseJSON(doc); - config->adjust(); - return config->isValid(); + return config->finalize(); } @@ -163,11 +162,14 @@ xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator return nullptr; } - if (!config->isValid()) { + if (!config->finalize()) { + delete config; + + config = m_creator->create(); loadFromFile(config, Platform::defaultConfigName()); } - if (!config->isValid()) { + if (!config->finalize()) { fprintf(stderr, "No valid configuration found. Exiting.\n"); delete config; return nullptr; @@ -177,7 +179,6 @@ xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator m_watcher = new xmrig::ConfigWatcher(config->fileName(), creator, listener); } - config->adjust(); return config; } diff --git a/src/common/config/ConfigWatcher.cpp b/src/common/config/ConfigWatcher.cpp index 21d73188..bde35f23 100644 --- a/src/common/config/ConfigWatcher.cpp +++ b/src/common/config/ConfigWatcher.cpp @@ -27,9 +27,9 @@ #include "common/config/ConfigLoader.h" #include "common/config/ConfigWatcher.h" +#include "common/log/Log.h" #include "core/ConfigCreator.h" #include "interfaces/IWatcherListener.h" -#include "log/Log.h" xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) : @@ -83,7 +83,7 @@ void xmrig::ConfigWatcher::reload() IConfig *config = m_creator->create(); ConfigLoader::loadFromFile(config, m_path.data()); - if (!config->isValid()) { + if (!config->finalize()) { LOG_ERR("reloading failed"); delete config; diff --git a/src/common/crypto/Algorithm.cpp b/src/common/crypto/Algorithm.cpp new file mode 100644 index 00000000..fce4d7b8 --- /dev/null +++ b/src/common/crypto/Algorithm.cpp @@ -0,0 +1,219 @@ +/* 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 Lee Clagett + * Copyright 2016-2018 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 +#include +#include +#include + + +#include "common/crypto/Algorithm.h" + + +#ifdef _MSC_VER +# define strncasecmp _strnicmp +# define strcasecmp _stricmp +#endif + + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + + +struct AlgoData +{ + const char *name; + const char *shortName; + xmrig::Algo algo; + xmrig::Variant variant; +}; + + +static AlgoData const algorithms[] = { + { "cryptonight", "cn", xmrig::CRYPTONIGHT, xmrig::VARIANT_AUTO }, + { "cryptonight/0", "cn/0", xmrig::CRYPTONIGHT, xmrig::VARIANT_0 }, + { "cryptonight/1", "cn/1", xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, + { "cryptonight/xtl", "cn/xtl", xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, + +# ifndef XMRIG_NO_AEON + { "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO }, + { "cryptonight-lite/0", "cn-lite/0", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, + { "cryptonight-lite/1", "cn-lite/1", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, + { "cryptonight-lite/ipbc", "cn-lite/ipbc", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IPBC }, +# endif + +# ifndef XMRIG_NO_SUMO + { "cryptonight-heavy", "cn-heavy", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 }, +# endif +}; + + +#ifdef XMRIG_PROXY_PROJECT +static AlgoData const xmrStakAlgorithms[] = { + { "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, + { "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, + { "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, + { "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, + { "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, + { "cryptonight_lite_v7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, + { "cryptonight_lite_v7_xor", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IPBC }, +}; +#endif + + +static const char *variants[] = { + "0", + "1", + "ipbc", + "xtl" +}; + + +bool xmrig::Algorithm::isValid() const +{ + if (m_algo == INVALID_ALGO) { + return false; + } + + for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { + if (algorithms[i].algo == m_algo && algorithms[i].variant == m_variant) { + return true; + } + } + + return false; +} + + +const char *xmrig::Algorithm::variantName() const +{ + if (m_variant == VARIANT_AUTO) { + return "auto"; + } + + return variants[m_variant]; +} + + +void xmrig::Algorithm::parseAlgorithm(const char *algo) +{ + m_algo = INVALID_ALGO; + m_variant = VARIANT_AUTO; + + assert(algo != nullptr); + if (algo == nullptr) { + return; + } + + for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { + if ((strcasecmp(algo, algorithms[i].name) == 0) || (strcasecmp(algo, algorithms[i].shortName) == 0)) { + m_algo = algorithms[i].algo; + m_variant = algorithms[i].variant; + break; + } + } + + if (m_algo == INVALID_ALGO) { + assert(false); + } +} + + +void xmrig::Algorithm::parseVariant(const char *variant) +{ + if (m_algo == CRYPTONIGHT_HEAVY) { + m_variant = VARIANT_0; + return; + } + + m_variant = VARIANT_AUTO; + + for (size_t i = 0; i < ARRAY_SIZE(variants); i++) { + if (strcasecmp(variant, variants[i]) == 0) { + m_variant = static_cast(i); + break; + } + } +} + + +void xmrig::Algorithm::parseVariant(int variant) +{ + if (variant >= VARIANT_AUTO && variant <= VARIANT_XTL) { + m_variant = static_cast(variant); + } + else { + assert(false); + } +} + + +void xmrig::Algorithm::setAlgo(Algo algo) +{ + m_algo = algo; + + if (m_algo == CRYPTONIGHT_HEAVY) { + m_variant = VARIANT_0; + } +} + + +#ifdef XMRIG_PROXY_PROJECT +void xmrig::Algorithm::parseXmrStakAlgorithm(const char *algo) +{ + m_algo = INVALID_ALGO; + m_variant = VARIANT_AUTO; + + assert(algo != nullptr); + if (algo == nullptr) { + return; + } + + for (size_t i = 0; i < ARRAY_SIZE(xmrStakAlgorithms); i++) { + if (strcasecmp(algo, xmrStakAlgorithms[i].name) == 0) { + m_algo = xmrStakAlgorithms[i].algo; + m_variant = xmrStakAlgorithms[i].variant; + break; + } + } + + if (m_algo == INVALID_ALGO) { + assert(false); + } +} +#endif + + +const char *xmrig::Algorithm::name(bool shortName) const +{ + for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { + if (algorithms[i].algo == m_algo && algorithms[i].variant == m_variant) { + return shortName ? algorithms[i].shortName : algorithms[i].name; + } + } + + return "invalid"; +} diff --git a/src/common/crypto/Algorithm.h b/src/common/crypto/Algorithm.h new file mode 100644 index 00000000..bcf029d8 --- /dev/null +++ b/src/common/crypto/Algorithm.h @@ -0,0 +1,91 @@ +/* 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 Lee Clagett + * Copyright 2016-2018 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 __ALGORITHM_H__ +#define __ALGORITHM_H__ + + +#include + + +#include "common/xmrig.h" + + +namespace xmrig { + + +class Algorithm +{ +public: + inline Algorithm() : + m_algo(INVALID_ALGO), + m_variant(VARIANT_AUTO) + {} + + inline Algorithm(Algo algo, Variant variant) : + m_variant(variant) + { + setAlgo(algo); + } + + inline Algorithm(const char *algo) + { + parseAlgorithm(algo); + } + + bool isEqual(const Algorithm &other) const { return m_algo == other.m_algo && m_variant == other.m_variant; } + inline Algo algo() const { return m_algo; } + inline const char *name() const { return name(false); } + inline const char *shortName() const { return name(true); } + inline Variant variant() const { return m_variant; } + inline void setVariant(Variant variant) { m_variant = variant; } + + inline bool operator!=(const Algorithm &other) const { return !isEqual(other); } + inline bool operator==(const Algorithm &other) const { return isEqual(other); } + + bool isValid() const; + const char *variantName() const; + void parseAlgorithm(const char *algo); + void parseVariant(const char *variant); + void parseVariant(int variant); + void setAlgo(Algo algo); + +# ifdef XMRIG_PROXY_PROJECT + void parseXmrStakAlgorithm(const char *algo); +# endif + +private: + const char *name(bool shortName) const; + + Algo m_algo; + Variant m_variant; +}; + + +typedef std::vector Algorithms; + + +} /* namespace xmrig */ + +#endif /* __ALGORITHM_H__ */ diff --git a/src/crypto/c_keccak.c b/src/common/crypto/keccak.cpp similarity index 74% rename from src/crypto/c_keccak.c rename to src/common/crypto/keccak.cpp index 997db241..0219ce36 100644 --- a/src/crypto/c_keccak.c +++ b/src/common/crypto/keccak.cpp @@ -1,10 +1,35 @@ -// keccak.c -// 19-Nov-11 Markku-Juhani O. Saarinen -// A baseline Keccak (3rd round) implementation. +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2011 Markku-Juhani O. Saarinen + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 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 #include + +#include "common/crypto/keccak.h" + + #define HASH_DATA_AREA 136 #define KECCAK_ROUNDS 24 @@ -26,7 +51,7 @@ const uint64_t keccakf_rndc[24] = // update the state with given number of rounds -void keccakf(uint64_t st[25], int rounds) +void xmrig::keccakf(uint64_t st[25], int rounds) { int i, j, round; uint64_t t, bc[5]; @@ -139,7 +164,8 @@ void keccakf(uint64_t st[25], int rounds) // compute a keccak hash (md) of given byte length from "in" typedef uint64_t state_t[25]; -void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) + +void xmrig::keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) { state_t st; uint8_t temp[144]; @@ -151,26 +177,24 @@ void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) memset(st, 0, sizeof(st)); for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) { - for (i = 0; i < rsizw; i++) + for (i = 0; i < rsizw; i++) { st[i] ^= ((uint64_t *) in)[i]; - keccakf(st, KECCAK_ROUNDS); + } + + xmrig::keccakf(st, KECCAK_ROUNDS); } - + // last block and padding memcpy(temp, in, inlen); temp[inlen++] = 1; memset(temp + inlen, 0, rsiz - inlen); temp[rsiz - 1] |= 0x80; - for (i = 0; i < rsizw; i++) + for (i = 0; i < rsizw; i++) { st[i] ^= ((uint64_t *) temp)[i]; + } keccakf(st, KECCAK_ROUNDS); memcpy(md, st, mdlen); } - -void keccak1600(const uint8_t *in, int inlen, uint8_t *md) -{ - keccak(in, inlen, md, sizeof(state_t)); -} diff --git a/src/common/crypto/keccak.h b/src/common/crypto/keccak.h new file mode 100644 index 00000000..0413ec2d --- /dev/null +++ b/src/common/crypto/keccak.h @@ -0,0 +1,49 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2011 Markku-Juhani O. Saarinen + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 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 KECCAK_H_ +#define KECCAK_H_ + +#include +#include + + +namespace xmrig { + +// compute a keccak hash (md) of given byte length from "in" +void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen); + + +inline void keccak(const uint8_t *in, size_t inlen, uint8_t *md) +{ + keccak(in, static_cast(inlen), md, 200); +} + +// update the state +void keccakf(uint64_t st[25], int norounds); + +} /* namespace xmrig */ + +#endif /* KECCAK_H_ */ diff --git a/src/log/ConsoleLog.cpp b/src/common/log/ConsoleLog.cpp similarity index 98% rename from src/log/ConsoleLog.cpp rename to src/common/log/ConsoleLog.cpp index eeed7355..b7d187d1 100644 --- a/src/log/ConsoleLog.cpp +++ b/src/common/log/ConsoleLog.cpp @@ -34,10 +34,10 @@ #endif +#include "common/log/ConsoleLog.h" +#include "common/log/Log.h" #include "core/Config.h" #include "core/Controller.h" -#include "log/ConsoleLog.h" -#include "log/Log.h" ConsoleLog::ConsoleLog(xmrig::Controller *controller) : diff --git a/src/log/ConsoleLog.h b/src/common/log/ConsoleLog.h similarity index 100% rename from src/log/ConsoleLog.h rename to src/common/log/ConsoleLog.h diff --git a/src/log/FileLog.cpp b/src/common/log/FileLog.cpp similarity index 98% rename from src/log/FileLog.cpp rename to src/common/log/FileLog.cpp index 5eeb252c..c8eaf5f7 100644 --- a/src/log/FileLog.cpp +++ b/src/common/log/FileLog.cpp @@ -29,7 +29,7 @@ #include -#include "log/FileLog.h" +#include "common/log/FileLog.h" FileLog::FileLog(const char *fileName) diff --git a/src/log/FileLog.h b/src/common/log/FileLog.h similarity index 100% rename from src/log/FileLog.h rename to src/common/log/FileLog.h diff --git a/src/log/Log.cpp b/src/common/log/Log.cpp similarity index 98% rename from src/log/Log.cpp rename to src/common/log/Log.cpp index 0e38634d..03237f03 100644 --- a/src/log/Log.cpp +++ b/src/common/log/Log.cpp @@ -29,8 +29,8 @@ #include +#include "common/log/Log.h" #include "interfaces/ILogBackend.h" -#include "log/Log.h" Log *Log::m_self = nullptr; diff --git a/src/log/Log.h b/src/common/log/Log.h similarity index 87% rename from src/log/Log.h rename to src/common/log/Log.h index f8c6a401..463c2248 100644 --- a/src/log/Log.h +++ b/src/common/log/Log.h @@ -80,6 +80,18 @@ private: }; +#define RED_BOLD(x) "\e[1;31m" x "\e[0m" +#define RED(x) "\e[0;31m" x "\e[0m" +#define GREEN_BOLD(x) "\e[1;32m" x "\e[0m" +#define GREEN(x) "\e[0;32m" x "\e[0m" +#define MAGENTA_BOLD(x) "\e[1;35m" x "\e[0m" +#define MAGENTA(x) "\e[0;35m" x "\e[0m" +#define CYAN_BOLD(x) "\e[1;36m" x "\e[0m" +#define CYAN(x) "\e[0;36m" x "\e[0m" +#define WHITE_BOLD(x) "\e[1;37m" x "\e[0m" +#define WHITE(x) "\e[0;37m" x "\e[0m" + + #define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__) #define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__) #define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__) diff --git a/src/log/SysLog.cpp b/src/common/log/SysLog.cpp similarity index 97% rename from src/log/SysLog.cpp rename to src/common/log/SysLog.cpp index f9b16cca..70879c33 100644 --- a/src/log/SysLog.cpp +++ b/src/common/log/SysLog.cpp @@ -25,7 +25,7 @@ #include -#include "log/SysLog.h" +#include "common/log/SysLog.h" #include "version.h" diff --git a/src/log/SysLog.h b/src/common/log/SysLog.h similarity index 100% rename from src/log/SysLog.h rename to src/common/log/SysLog.h diff --git a/src/net/Client.cpp b/src/common/net/Client.cpp similarity index 82% rename from src/net/Client.cpp rename to src/common/net/Client.cpp index 436bcd1a..921fa618 100644 --- a/src/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -29,22 +29,16 @@ #include +#include "common/log/Log.h" +#include "common/net/Client.h" #include "interfaces/IClientListener.h" -#include "log/Log.h" -#include "net/Client.h" +#include "net/JobResult.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/writer.h" -#ifdef XMRIG_PROXY_PROJECT -# include "proxy/JobResult.h" -#else -# include "net/JobResult.h" -#endif - - #ifdef _MSC_VER # define strncasecmp(x,y,z) _strnicmp(x,y,z) #endif @@ -60,7 +54,9 @@ Client::Client(int id, const char *agent, IClientListener *listener) : m_quiet(false), m_agent(agent), m_listener(listener), + m_extensions(0), m_id(id), + m_retries(5), m_retryPause(5000), m_failures(0), m_recvBufPos(0), @@ -166,12 +162,14 @@ bool Client::disconnect() int64_t Client::submit(const JobResult &result) { + using namespace rapidjson; + # ifdef XMRIG_PROXY_PROJECT const char *nonce = result.nonce; const char *data = result.result; # else - char nonce[9]; - char data[65]; + char *nonce = m_sendBuf; + char *data = m_sendBuf + 16; Job::toHex(reinterpret_cast(&result.nonce), 4, nonce); nonce[8] = '\0'; @@ -180,8 +178,24 @@ int64_t Client::submit(const JobResult &result) data[64] = '\0'; # endif - const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRIu64 ",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n", - m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data); + Document doc(kObjectType); + auto &allocator = doc.GetAllocator(); + + doc.AddMember("id", m_sequence, allocator); + doc.AddMember("jsonrpc", "2.0", allocator); + doc.AddMember("method", "submit", allocator); + + Value params(kObjectType); + params.AddMember("id", StringRef(m_rpcId.data()), allocator); + params.AddMember("job_id", StringRef(result.jobId.data()), allocator); + params.AddMember("nonce", StringRef(nonce), allocator); + params.AddMember("result", StringRef(data), allocator); + + if (m_extensions & AlgoExt) { + params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator); + } + + doc.AddMember("params", params, allocator); # ifdef XMRIG_PROXY_PROJECT m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id); @@ -189,7 +203,7 @@ int64_t Client::submit(const JobResult &result) m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff()); # endif - return send(size); + return send(doc); } @@ -238,12 +252,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } -# ifdef XMRIG_PROXY_PROJECT - Job job(m_id, m_pool.variant()); - job.setClientId(m_rpcId); -# else - Job job(m_id, m_nicehash, m_pool.algo(), m_pool.variant()); -# endif + Job job(m_id, m_nicehash, m_pool.algorithm(), m_rpcId); if (!job.setId(params["job_id"].GetString())) { *code = 3; @@ -260,12 +269,26 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - if (params.HasMember("coin")) { - job.setCoin(params["coin"].GetString()); + if (params.HasMember("algo")) { + job.algorithm().parseAlgorithm(params["algo"].GetString()); } if (params.HasMember("variant")) { - job.setVariant(params["variant"].GetInt()); + const rapidjson::Value &variant = params["variant"]; + + if (variant.IsInt()) { + job.algorithm().parseVariant(variant.GetInt()); + } + else if (variant.IsString()){ + job.algorithm().parseVariant(variant.GetString()); + } + } + + if (!verifyAlgorithm(job.algorithm())) { + *code = 6; + + close(); + return false; } if (m_job != job) { @@ -278,7 +301,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - if (!m_quiet) { + if (!isQuiet()) { LOG_WARN("[%s] duplicate job received, reconnect", m_pool.url()); } @@ -294,9 +317,7 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code) return false; } -# ifndef XMRIG_PROXY_PROJECT m_nicehash = m_pool.isNicehash(); -# endif if (result.HasMember("extensions")) { parseExtensions(result["extensions"]); @@ -309,6 +330,27 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code) } +bool Client::verifyAlgorithm(const xmrig::Algorithm &algorithm) const +{ + if (m_pool.isCompatible(algorithm)) { + return true; + } + + if (isQuiet()) { + return false; + } + + if (algorithm.isValid()) { + LOG_ERR("Incompatible algorithm \"%s\" detected, reconnect", algorithm.name()); + } + else { + LOG_ERR("Unknown/unsupported algorithm detected, reconnect"); + } + + return false; +} + + int Client::resolve(const char *host) { setState(HostLookupState); @@ -322,7 +364,7 @@ int Client::resolve(const char *host) const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, nullptr, &m_hints); if (r) { - if (!m_quiet) { + if (!isQuiet()) { LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_pool.port(), uv_strerror(r)); } return 1; @@ -332,6 +374,27 @@ int Client::resolve(const char *host) } +int64_t Client::send(const rapidjson::Document &doc) +{ + using namespace rapidjson; + + StringBuffer buffer(0, 512); + Writer writer(buffer); + doc.Accept(writer); + + const size_t size = buffer.GetSize(); + if (size > (sizeof(m_buf) - 2)) { + return -1; + } + + memcpy(m_sendBuf, buffer.GetString(), size); + m_sendBuf[size] = '\n'; + m_sendBuf[size + 1] = '\0'; + + return send(size + 1); +} + + int64_t Client::send(size_t size) { LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf); @@ -396,38 +459,35 @@ void Client::connect(sockaddr *addr) void Client::login() { + using namespace rapidjson; m_results.clear(); - rapidjson::Document doc; - doc.SetObject(); - + Document doc(kObjectType); auto &allocator = doc.GetAllocator(); doc.AddMember("id", 1, allocator); doc.AddMember("jsonrpc", "2.0", allocator); doc.AddMember("method", "login", allocator); - rapidjson::Value params(rapidjson::kObjectType); - params.AddMember("login", rapidjson::StringRef(m_pool.user()), allocator); - params.AddMember("pass", rapidjson::StringRef(m_pool.password()), allocator); - params.AddMember("agent", rapidjson::StringRef(m_agent), allocator); + Value params(kObjectType); + params.AddMember("login", StringRef(m_pool.user()), allocator); + params.AddMember("pass", StringRef(m_pool.password()), allocator); + params.AddMember("agent", StringRef(m_agent), allocator); - doc.AddMember("params", params, allocator); - - rapidjson::StringBuffer buffer(0, 512); - rapidjson::Writer writer(buffer); - doc.Accept(writer); - - const size_t size = buffer.GetSize(); - if (size > (sizeof(m_buf) - 2)) { - return; + if (m_pool.rigId()) { + params.AddMember("rigid", StringRef(m_pool.rigId()), allocator); } - memcpy(m_sendBuf, buffer.GetString(), size); - m_sendBuf[size] = '\n'; - m_sendBuf[size + 1] = '\0'; + Value algo(kArrayType); - send(size + 1); + for (const auto &a : m_pool.algorithms()) { + algo.PushBack(StringRef(a.shortName()), allocator); + } + + params.AddMember("algo", algo, allocator); + doc.AddMember("params", params, allocator); + + send(doc); } @@ -452,7 +512,7 @@ void Client::parse(char *line, size_t len) LOG_DEBUG("[%s] received (%d bytes): \"%s\"", m_pool.url(), len, line); if (len < 32 || line[0] != '{') { - if (!m_quiet) { + if (!isQuiet()) { LOG_ERR("[%s] JSON decode failed", m_pool.url()); } @@ -461,7 +521,7 @@ void Client::parse(char *line, size_t len) rapidjson::Document doc; if (doc.ParseInsitu(line).HasParseError()) { - if (!m_quiet) { + if (!isQuiet()) { LOG_ERR("[%s] JSON decode failed: \"%s\"", m_pool.url(), rapidjson::GetParseError_En(doc.GetParseError())); } @@ -484,6 +544,8 @@ void Client::parse(char *line, size_t len) void Client::parseExtensions(const rapidjson::Value &value) { + m_extensions = 0; + if (!value.IsArray()) { return; } @@ -493,8 +555,15 @@ void Client::parseExtensions(const rapidjson::Value &value) continue; } + if (strcmp(ext.GetString(), "algo") == 0) { + m_extensions |= AlgoExt; + continue; + } + if (strcmp(ext.GetString(), "nicehash") == 0) { + m_extensions |= NicehashExt; m_nicehash = true; + continue; } } } @@ -503,7 +572,7 @@ void Client::parseExtensions(const rapidjson::Value &value) void Client::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error) { if (error.IsObject()) { - if (!m_quiet) { + if (!isQuiet()) { LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), error["message"].GetString(), error["code"].GetInt()); } return; @@ -537,7 +606,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap m_listener->onResultAccepted(this, it->second, message); m_results.erase(it); } - else if (!m_quiet) { + else if (!isQuiet()) { LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), message, error["code"].GetInt()); } @@ -555,7 +624,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap if (id == 1) { int code = -1; if (!parseLogin(result, &code)) { - if (!m_quiet) { + if (!isQuiet()) { LOG_ERR("[%s] login error code: %d", m_pool.url(), code); } @@ -660,7 +729,7 @@ void Client::onConnect(uv_connect_t *req, int status) } if (status < 0) { - if (!client->m_quiet) { + if (!client->isQuiet()) { LOG_ERR("[%s] connect error: \"%s\"", client->m_pool.url(), uv_strerror(status)); } @@ -688,7 +757,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) } if (nread < 0) { - if (nread != UV_EOF && !client->m_quiet) { + if (nread != UV_EOF && !client->isQuiet()) { LOG_ERR("[%s] read error: \"%s\"", client->m_pool.url(), uv_strerror((int) nread)); } @@ -748,7 +817,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) } if (status < 0) { - if (!client->m_quiet) { + if (!client->isQuiet()) { LOG_ERR("[%s] DNS error: \"%s\"", client->m_pool.url(), uv_strerror(status)); } @@ -772,7 +841,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) } if (ipv4.empty() && ipv6.empty()) { - if (!client->m_quiet) { + if (!client->isQuiet()) { LOG_ERR("[%s] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_pool.url()); } diff --git a/src/net/Client.h b/src/common/net/Client.h similarity index 89% rename from src/net/Client.h rename to src/common/net/Client.h index 0692d38b..27273092 100644 --- a/src/net/Client.h +++ b/src/common/net/Client.h @@ -30,11 +30,11 @@ #include -#include "net/Id.h" -#include "net/Job.h" -#include "net/Storage.h" -#include "net/SubmitResult.h" -#include "net/Pool.h" +#include "common/net/Id.h" +#include "common/net/Job.h" +#include "common/net/Pool.h" +#include "common/net/Storage.h" +#include "common/net/SubmitResult.h" #include "rapidjson/fwd.h" @@ -74,14 +74,22 @@ public: inline SocketState state() const { return m_state; } inline uint16_t port() const { return m_pool.port(); } inline void setQuiet(bool quiet) { m_quiet = quiet; } + inline void setRetries(int retries) { m_retries = retries; } inline void setRetryPause(int ms) { m_retryPause = ms; } private: + enum Extensions { + NicehashExt = 1, + AlgoExt = 2 + }; + bool close(); bool isCriticalError(const char *message); bool parseJob(const rapidjson::Value ¶ms, int *code); bool parseLogin(const rapidjson::Value &result, int *code); + bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const; int resolve(const char *host); + int64_t send(const rapidjson::Document &doc); int64_t send(size_t size); void connect(const std::vector &ipv4, const std::vector &ipv6); void connect(sockaddr *addr); @@ -96,6 +104,8 @@ private: void setState(SocketState state); void startTimeout(); + inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; } + static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); static void onClose(uv_handle_t *handle); static void onConnect(uv_connect_t *req, int status); @@ -113,7 +123,9 @@ private: char m_sendBuf[768]; const char *m_agent; IClientListener *m_listener; + int m_extensions; int m_id; + int m_retries; int m_retryPause; int64_t m_failures; Job m_job; diff --git a/src/net/Id.h b/src/common/net/Id.h similarity index 100% rename from src/net/Id.h rename to src/common/net/Id.h diff --git a/src/net/Job.cpp b/src/common/net/Job.cpp similarity index 83% rename from src/net/Job.cpp rename to src/common/net/Job.cpp index 1434c87f..34aab326 100644 --- a/src/net/Job.cpp +++ b/src/common/net/Job.cpp @@ -27,7 +27,7 @@ #include -#include "net/Job.h" +#include "common/net/Job.h" static inline unsigned char hf_hex2bin(char c, bool &err) @@ -59,31 +59,27 @@ static inline char hf_bin2hex(unsigned char c) Job::Job() : m_nicehash(false), - m_coin(), - m_algo(xmrig::CRYPTONIGHT), m_poolId(-2), m_threadId(-1), m_size(0), m_diff(0), m_target(0), - m_blob(), - m_variant(xmrig::VARIANT_AUTO) -{ -} - - -Job::Job(int poolId, bool nicehash, int algo, int variant) : - m_nicehash(nicehash), - m_coin(), - m_algo(algo), - m_poolId(poolId), - m_threadId(-1), - m_size(0), - m_diff(0), - m_target(0), m_blob() { - setVariant(variant); +} + + +Job::Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId) : + m_nicehash(nicehash), + m_poolId(poolId), + m_threadId(-1), + m_size(0), + m_diff(0), + m_target(0), + m_blob(), + m_algorithm(algorithm), + m_clientId(clientId) +{ } @@ -116,6 +112,11 @@ bool Job::setBlob(const char *blob) m_nicehash = true; } +# ifdef XMRIG_PROXY_PROJECT + memset(m_rawBlob, 0, sizeof(m_rawBlob)); + memcpy(m_rawBlob, blob, m_size * 2); +# endif + return true; } @@ -152,40 +153,16 @@ bool Job::setTarget(const char *target) return false; } +# ifdef XMRIG_PROXY_PROJECT + memset(m_rawTarget, 0, sizeof(m_rawTarget)); + memcpy(m_rawTarget, target, len); +# endif + m_diff = toDiff(m_target); return true; } -void Job::setCoin(const char *coin) -{ - if (!coin || strlen(coin) > 4) { - memset(m_coin, 0, sizeof(m_coin)); - return; - } - - strncpy(m_coin, coin, sizeof(m_coin)); - m_algo = strcmp(m_coin, "AEON") == 0 ? xmrig::CRYPTONIGHT_LITE : xmrig::CRYPTONIGHT; -} - - -void Job::setVariant(int variant) -{ - switch (variant) { - case xmrig::VARIANT_AUTO: - case xmrig::VARIANT_NONE: - case xmrig::VARIANT_V1: - m_variant = static_cast(variant); - break; - - default: - assert(false); - m_variant = xmrig::VARIANT_AUTO; - break; - } -} - - bool Job::fromHex(const char* in, unsigned int len, unsigned char* out) { bool error = false; diff --git a/src/net/Job.h b/src/common/net/Job.h similarity index 50% rename from src/net/Job.h rename to src/common/net/Job.h index ee4728e3..08d5ae82 100644 --- a/src/net/Job.h +++ b/src/common/net/Job.h @@ -30,39 +30,49 @@ #include -#include "common/xmrig.h" -#include "net/Id.h" +#include "common/crypto/Algorithm.h" +#include "common/net/Id.h" class Job { public: Job(); - Job(int poolId, bool nicehash, int algo, int variant); + Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId); ~Job(); bool setBlob(const char *blob); bool setTarget(const char *target); - void setCoin(const char *coin); - void setVariant(int variant); - 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.setId(id); } - inline const char *coin() const { return m_coin; } - inline const uint32_t *nonce() const { return reinterpret_cast(m_blob + 39); } - inline const uint8_t *blob() const { return m_blob; } - inline const xmrig::Id &id() const { return m_id; } - inline int poolId() const { return m_poolId; } - inline int threadId() const { return m_threadId; } - inline size_t size() const { return m_size; } - inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } - inline uint32_t diff() const { return (uint32_t) m_diff; } - inline uint64_t target() const { return m_target; } - inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } - inline void setPoolId(int poolId) { m_poolId = poolId; } - inline void setThreadId(int threadId) { m_threadId = threadId; } - inline xmrig::Variant variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_V1 : xmrig::VARIANT_NONE) : m_variant); } + 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.setId(id); } + inline const uint32_t *nonce() const { return reinterpret_cast(m_blob + 39); } + inline const uint8_t *blob() const { return m_blob; } + inline const xmrig::Algorithm &algorithm() const { return m_algorithm; } + inline const xmrig::Id &clientId() const { return m_clientId; } + inline const xmrig::Id &id() const { return m_id; } + inline int poolId() const { return m_poolId; } + inline int threadId() const { return m_threadId; } + inline size_t size() const { return m_size; } + inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } + inline uint32_t diff() const { return static_cast(m_diff); } + inline uint64_t target() const { return m_target; } + inline void reset() { m_size = 0; m_diff = 0; } + inline void setClientId(const xmrig::Id &id) { m_clientId = id; } + inline void setPoolId(int poolId) { m_poolId = poolId; } + inline void setThreadId(int threadId) { m_threadId = threadId; } + inline xmrig::Algorithm &algorithm() { return m_algorithm; } + + inline xmrig::Variant variant() const + { + return (m_algorithm.variant() == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_1 : xmrig::VARIANT_0) : m_algorithm.variant()); + } + +# ifdef XMRIG_PROXY_PROJECT + inline char *rawBlob() { return m_rawBlob; } + inline const char *rawTarget() const { return m_rawTarget; } +# endif static bool fromHex(const char* in, unsigned int len, unsigned char* out); static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast(blob + 39); } @@ -78,16 +88,20 @@ public: private: bool m_nicehash; - char m_coin[5]; - int m_algo; int m_poolId; int m_threadId; size_t m_size; uint64_t m_diff; uint64_t m_target; uint8_t m_blob[96]; // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. + xmrig::Algorithm m_algorithm; + xmrig::Id m_clientId; xmrig::Id m_id; - xmrig::Variant m_variant; + +# ifdef XMRIG_PROXY_PROJECT + char m_rawBlob[176]; + char m_rawTarget[24]; +# endif }; #endif /* __JOB_H__ */ diff --git a/src/net/Pool.cpp b/src/common/net/Pool.cpp similarity index 57% rename from src/net/Pool.cpp rename to src/common/net/Pool.cpp index 2e167ebd..8c0de46a 100644 --- a/src/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -28,7 +28,13 @@ #include -#include "net/Pool.h" +#include "common/net/Pool.h" +#include "rapidjson/document.h" + + +#ifdef APP_DEBUG +# include "common/log/Log.h" +#endif #ifdef _MSC_VER @@ -37,42 +43,10 @@ #endif -static const char *algoNames[] = { - "cryptonight", -# ifndef XMRIG_NO_AEON - "cryptonight-lite", -# else - nullptr, -# endif -# ifndef XMRIG_NO_SUMO - "cryptonight-heavy" -# else - nullptr -# endif -}; - - -static const char *algoNamesShort[] = { - "cn", -# ifndef XMRIG_NO_AEON - "cn-lite", -# else - nullptr, -# endif -# ifndef XMRIG_NO_SUMO - "cn-heavy" -# else - nullptr -# endif -}; - - Pool::Pool() : m_nicehash(false), m_keepAlive(0), - m_port(kDefaultPort), - m_algo(xmrig::CRYPTONIGHT), - m_variant(xmrig::VARIANT_AUTO) + m_port(kDefaultPort) { } @@ -91,23 +65,19 @@ Pool::Pool() : Pool::Pool(const char *url) : m_nicehash(false), m_keepAlive(0), - m_port(kDefaultPort), - m_algo(xmrig::CRYPTONIGHT), - m_variant(xmrig::VARIANT_AUTO) + m_port(kDefaultPort) { parse(url); } -Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, xmrig::Variant variant) : +Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash) : m_nicehash(nicehash), m_keepAlive(keepAlive), m_port(port), - m_algo(xmrig::CRYPTONIGHT), m_host(host), m_password(password), - m_user(user), - m_variant(variant) + m_user(user) { const size_t size = m_host.size() + 8; assert(size > 8); @@ -119,34 +89,29 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo } -const char *Pool::algoName(xmrig::Algo algorithm) +bool Pool::isCompatible(const xmrig::Algorithm &algorithm) const { - return algoNames[algorithm]; -} - - -xmrig::Algo Pool::algorithm(const char *algo) -{ -# ifndef XMRIG_NO_AEON - if (strcasecmp(algo, "cryptonight-light") == 0) { - fprintf(stderr, "Algorithm \"cryptonight-light\" is deprecated, use \"cryptonight-lite\" instead\n"); - - return xmrig::CRYPTONIGHT_LITE; - } -# endif - - const size_t size = sizeof(algoNames) / sizeof(algoNames[0]); - - assert(size == (sizeof(algoNamesShort) / sizeof(algoNamesShort[0]))); - - for (size_t i = 0; i < size; i++) { - if ((algoNames[i] && strcasecmp(algo, algoNames[i]) == 0) || (algoNamesShort[i] && strcasecmp(algo, algoNamesShort[i]) == 0)) { - return static_cast(i); + for (const auto &a : m_algorithms) { + if (algorithm == a) { + return true; } } - fprintf(stderr, "Unknown algorithm \"%s\" specified.\n", algo); - return xmrig::INVALID_ALGO; + return false; +} + + +bool Pool::isEqual(const Pool &other) const +{ + return (m_nicehash == other.m_nicehash + && m_keepAlive == other.m_keepAlive + && m_port == other.m_port + && m_algorithm == other.m_algorithm + && m_host == other.m_host + && m_password == other.m_password + && m_rigId == other.m_rigId + && m_url == other.m_url + && m_user == other.m_user); } @@ -208,53 +173,98 @@ bool Pool::setUserpass(const char *userpass) } -void Pool::adjust(xmrig::Algo algo) +rapidjson::Value Pool::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + + auto &allocator = doc.GetAllocator(); + + Value obj(kObjectType); + + obj.AddMember("url", StringRef(url()), allocator); + obj.AddMember("user", StringRef(user()), allocator); + obj.AddMember("pass", StringRef(password()), allocator); + obj.AddMember("rig-id", rigId() ? Value(StringRef(rigId())).Move() : Value(kNullType).Move(), allocator); + +# ifndef XMRIG_PROXY_PROJECT + obj.AddMember("nicehash", isNicehash(), allocator); +# endif + + if (m_keepAlive == 0 || m_keepAlive == kKeepAliveTimeout) { + obj.AddMember("keepalive", m_keepAlive > 0, allocator); + } + else { + obj.AddMember("keepalive", m_keepAlive, allocator); + } + + switch (m_algorithm.variant()) { + case xmrig::VARIANT_AUTO: + case xmrig::VARIANT_0: + case xmrig::VARIANT_1: + obj.AddMember("variant", m_algorithm.variant(), allocator); + break; + + default: + obj.AddMember("variant", StringRef(m_algorithm.variantName()), allocator); + break; + } + + return obj; +} + + +void Pool::adjust(xmrig::Algo algorithm) { if (!isValid()) { return; } - m_algo = algo; + if (!m_algorithm.isValid()) { + m_algorithm.setAlgo(algorithm); + } if (strstr(m_host.data(), ".nicehash.com")) { m_keepAlive = false; m_nicehash = true; + + if (strstr(m_host.data(), "cryptonightv7.")) { + m_algorithm.setVariant(xmrig::VARIANT_1); + } } if (strstr(m_host.data(), ".minergate.com")) { m_keepAlive = false; + m_algorithm.setVariant(xmrig::VARIANT_1); } + + m_algorithms.push_back(m_algorithm); + +# ifndef XMRIG_PROXY_PROJECT + if (m_algorithm.algo() != xmrig::CRYPTONIGHT_HEAVY) { + addVariant(xmrig::VARIANT_1); + addVariant(xmrig::VARIANT_0); + addVariant(xmrig::VARIANT_XTL); + addVariant(xmrig::VARIANT_IPBC); + addVariant(xmrig::VARIANT_AUTO); + } +# endif } -void Pool::setVariant(int variant) +#ifdef APP_DEBUG +void Pool::print() const { - switch (variant) { - case xmrig::VARIANT_AUTO: - case xmrig::VARIANT_NONE: - case xmrig::VARIANT_V1: - m_variant = static_cast(variant); - break; - - default: - assert(false); - break; - } -} - - -bool Pool::isEqual(const Pool &other) const -{ - return (m_nicehash == other.m_nicehash - && m_keepAlive == other.m_keepAlive - && m_port == other.m_port - && m_algo == other.m_algo - && m_host == other.m_host - && m_password == other.m_password - && m_url == other.m_url - && m_user == other.m_user - && m_variant == other.m_variant); + LOG_NOTICE("url: %s", m_url.data()); + LOG_DEBUG ("host: %s", m_host.data()); + LOG_DEBUG ("port: %d", static_cast(m_port)); + LOG_DEBUG ("user: %s", m_user.data()); + LOG_DEBUG ("pass: %s", m_password.data()); + LOG_DEBUG ("rig-id %s", m_rigId.data()); + LOG_DEBUG ("algo: %s", m_algorithm.name()); + LOG_DEBUG ("nicehash: %d", static_cast(m_nicehash)); + LOG_DEBUG ("keepAlive: %d", m_keepAlive); } +#endif bool Pool::parseIPv6(const char *addr) @@ -278,3 +288,14 @@ bool Pool::parseIPv6(const char *addr) return true; } + + +void Pool::addVariant(xmrig::Variant variant) +{ + const xmrig::Algorithm algorithm(m_algorithm.algo(), variant); + if (!algorithm.isValid() || m_algorithm == algorithm) { + return; + } + + m_algorithms.push_back(algorithm); +} diff --git a/src/net/Pool.h b/src/common/net/Pool.h similarity index 53% rename from src/net/Pool.h rename to src/common/net/Pool.h index ecce865a..ad015bf2 100644 --- a/src/net/Pool.h +++ b/src/common/net/Pool.h @@ -25,11 +25,12 @@ #define __POOL_H__ -#include +#include +#include "common/crypto/Algorithm.h" #include "common/utils/c_str.h" -#include "common/xmrig.h" +#include "rapidjson/fwd.h" class Pool @@ -47,50 +48,58 @@ public: const char *user = nullptr, const char *password = nullptr, int keepAlive = 0, - bool nicehash = false, - xmrig::Variant variant = xmrig::VARIANT_AUTO + bool nicehash = false ); - static const char *algoName(xmrig::Algo algorithm); - static xmrig::Algo algorithm(const char *algo); - - inline bool isNicehash() const { return m_nicehash; } - inline bool isValid() const { return !m_host.isNull() && m_port > 0; } - inline const char *host() const { return m_host.data(); } - inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } - inline const char *url() const { return m_url.data(); } - inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } - inline int keepAlive() const { return m_keepAlive; } - inline uint16_t port() const { return m_port; } - inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } - inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } - inline void setPassword(const char *password) { m_password = password; } - inline void setUser(const char *user) { m_user = user; } - inline xmrig::Algo algo() const { return m_algo; } - inline xmrig::Variant variant() const { return m_variant; } + inline bool isNicehash() const { return m_nicehash; } + inline bool isValid() const { return !m_host.isNull() && m_port > 0; } + inline const char *host() const { return m_host.data(); } + inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } + inline const char *rigId() const { return m_rigId.data(); } + inline const char *url() const { return m_url.data(); } + inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } + inline const xmrig::Algorithm &algorithm() const { return m_algorithm; } + inline const xmrig::Algorithms &algorithms() const { return m_algorithms; } + inline int keepAlive() const { return m_keepAlive; } + inline uint16_t port() const { return m_port; } + inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } + inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } + inline void setPassword(const char *password) { m_password = password; } + inline void setRigId(const char *rigId) { m_rigId = rigId; } + inline void setUser(const char *user) { m_user = user; } + inline xmrig::Algorithm &algorithm() { return m_algorithm; } inline bool operator!=(const Pool &other) const { return !isEqual(other); } inline bool operator==(const Pool &other) const { return isEqual(other); } + bool isCompatible(const xmrig::Algorithm &algorithm) const; + bool isEqual(const Pool &other) const; bool parse(const char *url); bool setUserpass(const char *userpass); - void adjust(xmrig::Algo algo); - void setVariant(int variant); + rapidjson::Value toJSON(rapidjson::Document &doc) const; + void adjust(xmrig::Algo algorithm); - bool isEqual(const Pool &other) const; +# ifdef APP_DEBUG + void print() const; +# endif private: bool parseIPv6(const char *addr); + void addVariant(xmrig::Variant variant); bool m_nicehash; int m_keepAlive; uint16_t m_port; - xmrig::Algo m_algo; + xmrig::Algorithm m_algorithm; + xmrig::Algorithms m_algorithms; xmrig::c_str m_host; xmrig::c_str m_password; + xmrig::c_str m_rigId; xmrig::c_str m_url; xmrig::c_str m_user; - xmrig::Variant m_variant; }; + +typedef std::vector Pools; + #endif /* __POOL_H__ */ diff --git a/src/net/Storage.h b/src/common/net/Storage.h similarity index 99% rename from src/net/Storage.h rename to src/common/net/Storage.h index 105547ec..f36ce594 100644 --- a/src/net/Storage.h +++ b/src/common/net/Storage.h @@ -28,8 +28,6 @@ #include #include -#include "log/Log.h" - namespace xmrig { diff --git a/src/net/SubmitResult.cpp b/src/common/net/SubmitResult.cpp similarity index 82% rename from src/net/SubmitResult.cpp rename to src/common/net/SubmitResult.cpp index 2e81017c..251b2bf1 100644 --- a/src/net/SubmitResult.cpp +++ b/src/common/net/SubmitResult.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 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 @@ -25,10 +25,11 @@ #include -#include "net/SubmitResult.h" +#include "common/net/SubmitResult.h" -SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff) : +SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId) : + reqId(reqId), seq(seq), diff(diff), actualDiff(actualDiff), diff --git a/src/net/SubmitResult.h b/src/common/net/SubmitResult.h similarity index 80% rename from src/net/SubmitResult.h rename to src/common/net/SubmitResult.h index 8eddef89..e812cbf8 100644 --- a/src/net/SubmitResult.h +++ b/src/common/net/SubmitResult.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 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 @@ -31,11 +31,12 @@ class SubmitResult { public: - inline SubmitResult() : seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {} - SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff); + inline SubmitResult() : reqId(0), seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {} + SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId = 0); void done(); + int64_t reqId; int64_t seq; uint32_t diff; uint64_t actualDiff; diff --git a/src/net/strategies/FailoverStrategy.cpp b/src/common/net/strategies/FailoverStrategy.cpp similarity index 97% rename from src/net/strategies/FailoverStrategy.cpp rename to src/common/net/strategies/FailoverStrategy.cpp index cef9da0c..295b4335 100644 --- a/src/net/strategies/FailoverStrategy.cpp +++ b/src/common/net/strategies/FailoverStrategy.cpp @@ -22,10 +22,10 @@ */ +#include "common/net/Client.h" +#include "common/net/strategies/FailoverStrategy.h" #include "common/Platform.h" #include "interfaces/IStrategyListener.h" -#include "net/Client.h" -#include "net/strategies/FailoverStrategy.h" FailoverStrategy::FailoverStrategy(const std::vector &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) : @@ -157,6 +157,7 @@ void FailoverStrategy::add(const Pool &pool) { Client *client = new Client((int) m_pools.size(), Platform::userAgent(), this); client->setPool(pool); + client->setRetries(m_retries); client->setRetryPause(m_retryPause * 1000); client->setQuiet(m_quiet); diff --git a/src/net/strategies/FailoverStrategy.h b/src/common/net/strategies/FailoverStrategy.h similarity index 98% rename from src/net/strategies/FailoverStrategy.h rename to src/common/net/strategies/FailoverStrategy.h index a48496fb..f86b366a 100644 --- a/src/net/strategies/FailoverStrategy.h +++ b/src/common/net/strategies/FailoverStrategy.h @@ -28,9 +28,9 @@ #include +#include "common/net/Pool.h" #include "interfaces/IClientListener.h" #include "interfaces/IStrategy.h" -#include "net/Pool.h" class Client; diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/common/net/strategies/SinglePoolStrategy.cpp similarity index 93% rename from src/net/strategies/SinglePoolStrategy.cpp rename to src/common/net/strategies/SinglePoolStrategy.cpp index c74a794b..21ce7b34 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/common/net/strategies/SinglePoolStrategy.cpp @@ -22,18 +22,19 @@ */ +#include "common/net/Client.h" +#include "common/net/strategies/SinglePoolStrategy.h" #include "common/Platform.h" #include "interfaces/IStrategyListener.h" -#include "net/Client.h" -#include "net/strategies/SinglePoolStrategy.h" -SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet) : +SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet) : m_active(false), m_listener(listener) { m_client = new Client(0, Platform::userAgent(), this); m_client->setPool(pool); + m_client->setRetries(retries); m_client->setRetryPause(retryPause * 1000); m_client->setQuiet(quiet); } diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/common/net/strategies/SinglePoolStrategy.h similarity index 94% rename from src/net/strategies/SinglePoolStrategy.h rename to src/common/net/strategies/SinglePoolStrategy.h index ce3d0f7f..41d90e34 100644 --- a/src/net/strategies/SinglePoolStrategy.h +++ b/src/common/net/strategies/SinglePoolStrategy.h @@ -37,7 +37,7 @@ class Url; class SinglePoolStrategy : public IStrategy, public IClientListener { public: - SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet = false); + SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false); ~SinglePoolStrategy(); public: diff --git a/src/common/utils/c_str.h b/src/common/utils/c_str.h index 9a11ade6..3cc4d326 100644 --- a/src/common/utils/c_str.h +++ b/src/common/utils/c_str.h @@ -68,7 +68,7 @@ public: inline bool isEqual(const char *str) const { - return (m_data != nullptr && str != nullptr && strcmp(m_data, str)) || (m_data == nullptr && m_data == nullptr); + return (m_data != nullptr && str != nullptr && strcmp(m_data, str) == 0) || (m_data == nullptr && m_data == nullptr); } diff --git a/src/common/xmrig.h b/src/common/xmrig.h index 0aa6b842..a6fda9fc 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -33,7 +33,7 @@ enum Algo { INVALID_ALGO = -1, CRYPTONIGHT, /* CryptoNight (Monero) */ CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ - CRYPTONIGHT_HEAVY, /* CryptoNight-Heavy (SUMO) */ + CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (SUMO) */ }; @@ -59,8 +59,10 @@ enum AlgoVariant { enum Variant { VARIANT_AUTO = -1, // Autodetect - VARIANT_NONE = 0, // Original CryptoNight - VARIANT_V1 = 1 // Monero v7 PoW + VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy + VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7 + VARIANT_IPBC = 2, // CryptoNight Lite variant 1 with XOR (IPBC only) + VARIANT_XTL = 3 // CryptoNight variant 1 (Stellite only) }; diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 4d48af29..0c4ce779 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -31,7 +31,6 @@ #include "core/ConfigCreator.h" #include "Cpu.h" #include "crypto/CryptoNight_constants.h" -#include "net/Pool.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" @@ -72,7 +71,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const auto &allocator = doc.GetAllocator(); - doc.AddMember("algo", StringRef(algoName()), allocator); + doc.AddMember("algo", StringRef(algorithm().name()), allocator); Value api(kObjectType); api.AddMember("port", apiPort(), allocator); @@ -103,24 +102,8 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const Value pools(kArrayType); - for (const Pool &pool : m_pools) { - Value obj(kObjectType); - - obj.AddMember("url", StringRef(pool.url()), allocator); - obj.AddMember("user", StringRef(pool.user()), allocator); - obj.AddMember("pass", StringRef(pool.password()), allocator); - - if (pool.keepAlive() == 0 || pool.keepAlive() == Pool::kKeepAliveTimeout) { - obj.AddMember("keepalive", pool.keepAlive() > 0, allocator); - } - else { - obj.AddMember("keepalive", pool.keepAlive(), allocator); - } - - obj.AddMember("nicehash", pool.isNicehash(), allocator); - obj.AddMember("variant", pool.variant(), allocator); - - pools.PushBack(obj, allocator); + for (const Pool &pool : m_activePools) { + pools.PushBack(pool.toJSON(doc), allocator); } doc.AddMember("pools", pools, allocator); @@ -158,9 +141,13 @@ xmrig::Config *xmrig::Config::load(int argc, char **argv, IWatcherListener *list } -bool xmrig::Config::adjust() +bool xmrig::Config::finalize() { - if (!CommonConfig::adjust()) { + if (m_state != NoneState) { + return CommonConfig::finalize(); + } + + if (!CommonConfig::finalize()) { return false; } @@ -169,7 +156,7 @@ bool xmrig::Config::adjust() const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; for (size_t i = 0; i < m_threads.cpu.size(); ++i) { - m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm, m_threads.cpu[i], m_priority, softAES)); + m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES)); } return true; @@ -178,7 +165,7 @@ bool xmrig::Config::adjust() m_algoVariant = getAlgoVariant(); m_threads.mode = m_threads.count ? Simple : Automatic; - const size_t size = CpuThread::multiway(m_algoVariant) * cn_select_memory(m_algorithm) / 1024; + const size_t size = CpuThread::multiway(m_algoVariant) * cn_select_memory(m_algorithm.algo()) / 1024; if (!m_threads.count) { m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); @@ -191,7 +178,7 @@ bool xmrig::Config::adjust() } for (size_t i = 0; i < m_threads.count; ++i) { - m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm, m_algoVariant, m_threads.mask, m_priority)); + m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), m_algoVariant, m_threads.mask, m_priority)); } return true; @@ -351,7 +338,7 @@ bool xmrig::Config::parseInt(int key, int arg) xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const { # ifndef XMRIG_NO_AEON - if (m_algorithm == xmrig::CRYPTONIGHT_LITE) { + if (m_algorithm.algo() == xmrig::CRYPTONIGHT_LITE) { return getAlgoVariantLite(); } # endif diff --git a/src/core/Config.h b/src/core/Config.h index 13320a80..0c6a2173 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -88,7 +88,7 @@ public: static Config *load(int argc, char **argv, IWatcherListener *listener); protected: - bool adjust() override; + bool finalize() override; bool parseBoolean(int key, bool enable) override; bool parseString(int key, const char *arg) override; bool parseUint64(int key, uint64_t arg) override; diff --git a/src/core/ConfigLoader_platform.h b/src/core/ConfigLoader_platform.h index d02a9e8f..9704d5e3 100644 --- a/src/core/ConfigLoader_platform.h +++ b/src/core/ConfigLoader_platform.h @@ -58,6 +58,7 @@ Options:\n\ -O, --userpass=U:P username:password pair for mining server\n\ -u, --user=USERNAME username for mining server\n\ -p, --pass=PASSWORD password for mining server\n\ + --rig-id=ID rig identifier for pool-side statistics (needs pool support)\n\ -t, --threads=N number of miner threads\n\ -v, --av=N algorithm variation, 0 auto select\n\ -k, --keepalive send keepalived for prevent timeout (need pool support)\n\ @@ -128,6 +129,7 @@ static struct option const options[] = { { "user", 1, nullptr, xmrig::IConfig::UserKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, + { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, { "version", 0, nullptr, xmrig::IConfig::VersionKey }, { 0, 0, 0, 0 } }; @@ -165,6 +167,7 @@ static struct option const pool_options[] = { { "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey }, { "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey }, { "variant", 1, nullptr, xmrig::IConfig::VariantKey }, + { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, { 0, 0, 0, 0 } }; diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 5f0a9bb3..b1e03f32 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -26,19 +26,19 @@ #include "common/config/ConfigLoader.h" +#include "common/log/ConsoleLog.h" +#include "common/log/FileLog.h" +#include "common/log/Log.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" #include "interfaces/IControllerListener.h" -#include "log/ConsoleLog.h" -#include "log/FileLog.h" -#include "log/Log.h" #include "net/Network.h" #ifdef HAVE_SYSLOG_H -# include "log/SysLog.h" +# include "common/log/SysLog.h" #endif diff --git a/src/crypto/CryptoNight_constants.h b/src/crypto/CryptoNight_constants.h index 3c746d47..7e6627fd 100644 --- a/src/crypto/CryptoNight_constants.h +++ b/src/crypto/CryptoNight_constants.h @@ -53,6 +53,7 @@ template<> inline constexpr size_t cn_select_memory() { retur template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_LITE_MEMORY; } template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_HEAVY_MEMORY; } + inline size_t cn_select_memory(Algo algorithm) { switch(algorithm) @@ -79,6 +80,7 @@ template<> inline constexpr uint32_t cn_select_mask() { retur template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_LITE_MASK; } template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_HEAVY_MASK; } + inline uint32_t cn_select_mask(Algo algorithm) { switch(algorithm) @@ -105,6 +107,7 @@ template<> inline constexpr uint32_t cn_select_iter() { retur template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } + inline uint32_t cn_select_iter(Algo algorithm) { switch(algorithm) diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h index 93cbf23d..bf6013e8 100644 --- a/src/crypto/CryptoNight_test.h +++ b/src/crypto/CryptoNight_test.h @@ -84,6 +84,21 @@ const static uint8_t test_output_v1[160] = { }; +// Stellite (XTL) +const static uint8_t test_output_xtl[160] = { + 0x8F, 0xE5, 0xF0, 0x5F, 0x02, 0x2A, 0x61, 0x7D, 0xE5, 0x3F, 0x79, 0x36, 0x4B, 0x25, 0xCB, 0xC3, + 0xC0, 0x8E, 0x0E, 0x1F, 0xE3, 0xBE, 0x48, 0x57, 0x07, 0x03, 0xFE, 0xE1, 0xEC, 0x0E, 0xB0, 0xB1, + 0x21, 0x26, 0xFF, 0x98, 0xE6, 0x86, 0x08, 0x5B, 0xC9, 0x96, 0x44, 0xA3, 0xB8, 0x4E, 0x28, 0x90, + 0x76, 0xED, 0xAD, 0xB9, 0xAA, 0xAC, 0x01, 0x94, 0x1D, 0xBE, 0x3E, 0xEA, 0xAD, 0xEE, 0xB2, 0xCF, + 0xB0, 0x43, 0x4B, 0x88, 0xFC, 0xB2, 0xF3, 0x82, 0x9D, 0xD7, 0xDF, 0x51, 0x97, 0x2C, 0x5A, 0xE3, + 0xC7, 0x16, 0x0B, 0xC8, 0x7C, 0xB7, 0x2F, 0x1C, 0x55, 0x33, 0xCA, 0xE1, 0xEE, 0x08, 0xA4, 0x86, + 0x60, 0xED, 0x6E, 0x9D, 0x2D, 0x05, 0x0D, 0x7D, 0x02, 0x49, 0x23, 0x39, 0x7C, 0xC3, 0x6D, 0x3D, + 0x05, 0x51, 0x28, 0xF1, 0x9B, 0x3C, 0xDF, 0xC4, 0xEA, 0x8A, 0xA6, 0x6A, 0x3C, 0x8B, 0xE2, 0xAF, + 0x47, 0x00, 0xFC, 0x36, 0xED, 0x50, 0xBB, 0xD2, 0x2E, 0x63, 0x4B, 0x93, 0x11, 0x0C, 0xA7, 0xBA, + 0x32, 0x6E, 0x47, 0x4D, 0xCE, 0xCC, 0x82, 0x54, 0x1D, 0x06, 0xF8, 0x06, 0x86, 0xBD, 0x22, 0x48 +}; + + #ifndef XMRIG_NO_AEON const static uint8_t test_output_v0_lite[160] = { 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, @@ -112,6 +127,21 @@ const static uint8_t test_output_v1_lite[160] = { 0x8C, 0x2B, 0xA4, 0x1F, 0x60, 0x76, 0x39, 0xD7, 0xF6, 0x46, 0x77, 0x18, 0x20, 0xAD, 0xD4, 0xC9, 0x87, 0xF7, 0x37, 0xDA, 0xFD, 0xBA, 0xBA, 0xD2, 0xF2, 0x68, 0xDC, 0x26, 0x8D, 0x1B, 0x08, 0xC6 }; + + +// IPBC +const static uint8_t test_output_ipbc_lite[160] = { + 0xE4, 0x93, 0x8C, 0xAA, 0x59, 0x8D, 0x02, 0x8A, 0xB8, 0x6F, 0x25, 0xD2, 0xB1, 0x23, 0xD0, 0xD5, + 0x33, 0xE3, 0x9F, 0x37, 0xAC, 0xE5, 0xF8, 0xEB, 0x7A, 0xE8, 0x40, 0xEB, 0x5D, 0xB1, 0x35, 0x5F, + 0xB2, 0x47, 0x86, 0xF0, 0x7F, 0x6F, 0x4B, 0x55, 0x3E, 0xA1, 0xBB, 0xE8, 0xA1, 0x75, 0x00, 0x2D, + 0x07, 0x9A, 0x21, 0x0E, 0xBD, 0x06, 0x6A, 0xB0, 0xFD, 0x96, 0x9E, 0xE6, 0xE4, 0x69, 0x67, 0xBB, + 0x88, 0x45, 0x0B, 0x91, 0x0B, 0x7B, 0xCB, 0x21, 0x3C, 0x3C, 0x09, 0x30, 0x07, 0x71, 0x07, 0xD5, + 0xB8, 0x2D, 0x83, 0x09, 0xAF, 0x7E, 0xB2, 0xA8, 0xAC, 0x25, 0xDC, 0x10, 0xF8, 0x63, 0x6A, 0xBC, + 0x73, 0x01, 0x4E, 0xA8, 0x1C, 0xDA, 0x9A, 0x86, 0x17, 0xEC, 0xA8, 0xFB, 0xAA, 0x23, 0x23, 0x17, + 0xE1, 0x32, 0x68, 0x9C, 0x4C, 0xF4, 0x08, 0xED, 0xB0, 0x15, 0xC3, 0xA9, 0x0F, 0xF0, 0xA2, 0x7E, + 0xD9, 0xE4, 0x23, 0xA7, 0x9E, 0x91, 0xD8, 0x73, 0x94, 0xD6, 0x6C, 0x70, 0x9B, 0x8B, 0x72, 0x92, + 0xA3, 0xA4, 0x0A, 0xE2, 0x3C, 0x0A, 0x34, 0x88, 0xA1, 0x6D, 0xFE, 0x02, 0x44, 0x60, 0x7B, 0x3D +}; #endif diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index e19eb2c9..66bcf8b5 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -34,6 +34,7 @@ #endif +#include "common/crypto/keccak.h" #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_monero.h" @@ -42,7 +43,6 @@ extern "C" { -#include "crypto/c_keccak.h" #include "crypto/c_groestl.h" #include "crypto/c_blake256.h" #include "crypto/c_jh.h" @@ -386,6 +386,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } +template static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) { mem_out[0] = EXTRACT64(tmp); @@ -395,7 +396,7 @@ static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) uint8_t x = vh >> 24; static const uint16_t table = 0x7531; - const uint8_t index = (((x >> 3) & 6) | (x & 1)) << 1; + const uint8_t index = (((x >> SHIFT) & 6) | (x & 1)) << 1; vh ^= ((table >> index) & 0x3) << 28; mem_out[1] = vh; @@ -414,7 +415,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx[0]->state, 200); + xmrig::keccak(input, size, ctx[0]->state); VARIANT1_INIT(0) @@ -441,7 +442,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si } if (VARIANT > 0) { - cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); } else { _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); } @@ -457,13 +458,22 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si al0 += hi; ah0 += lo; - VARIANT1_2(ah0, 0); ((uint64_t*)&l0[idx0 & MASK])[0] = al0; - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; - VARIANT1_2(ah0, 0); - ah0 ^= ch; + if (VARIANT > 0) { + if (VARIANT == xmrig::VARIANT_IPBC) { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; + } + else { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; + } + } + else { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; + } + al0 ^= cl; + ah0 ^= ch; idx0 = al0; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { @@ -478,7 +488,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); - keccakf(h0, 24); + xmrig::keccakf(h0, 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); } @@ -495,8 +505,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx[0]->state, 200); - keccak(input + size, (int) size, ctx[1]->state, 200); + xmrig::keccak(input, size, ctx[0]->state); + xmrig::keccak(input + size, size, ctx[1]->state); VARIANT1_INIT(0); VARIANT1_INIT(1); @@ -535,8 +545,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si } if (VARIANT > 0) { - cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); - cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); + cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); } else { _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); @@ -556,13 +566,22 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si al0 += hi; ah0 += lo; - VARIANT1_2(ah0, 0); - ((uint64_t*) &l0[idx0 & MASK])[0] = al0; - ((uint64_t*) &l0[idx0 & MASK])[1] = ah0; - VARIANT1_2(ah0, 0); + ((uint64_t*)&l0[idx0 & MASK])[0] = al0; + + if (VARIANT > 0) { + if (VARIANT == xmrig::VARIANT_IPBC) { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; + } + else { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; + } + } + else { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; + } - ah0 ^= ch; al0 ^= cl; + ah0 ^= ch; idx0 = al0; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { @@ -581,13 +600,22 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si al1 += hi; ah1 += lo; - VARIANT1_2(ah1, 1); - ((uint64_t*) &l1[idx1 & MASK])[0] = al1; - ((uint64_t*) &l1[idx1 & MASK])[1] = ah1; - VARIANT1_2(ah1, 1); + ((uint64_t*)&l1[idx1 & MASK])[0] = al1; + + if (VARIANT > 0) { + if (VARIANT == xmrig::VARIANT_IPBC) { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1; + } + else { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1; + } + } + else { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1; + } - ah1 ^= ch; al1 ^= cl; + ah1 ^= ch; idx1 = al1; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { @@ -603,8 +631,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); - keccakf(h0, 24); - keccakf(h1, 24); + xmrig::keccakf(h0, 24); + xmrig::keccakf(h1, 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); @@ -626,7 +654,7 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si b = _mm_xor_si128(b, c); \ \ if (VARIANT > 0) { \ - cryptonight_monero_tweak(reinterpret_cast(ptr), b); \ + cryptonight_monero_tweak(reinterpret_cast(ptr), b); \ } else { \ _mm_store_si128(ptr, b); \ } @@ -644,6 +672,10 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si \ if (VARIANT > 0) { \ _mm_store_si128(ptr, _mm_xor_si128(a, mc)); \ + \ + if (VARIANT == xmrig::VARIANT_IPBC) { \ + ((uint64_t*)ptr)[1] ^= ((uint64_t*)ptr)[0]; \ + } \ } else { \ _mm_store_si128(ptr, a); \ } \ @@ -681,7 +713,7 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si } for (size_t i = 0; i < 3; i++) { - keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + xmrig::keccak(input + size * i, size, ctx[i]->state); cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } @@ -752,7 +784,7 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si for (size_t i = 0; i < 3; i++) { cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); - keccakf(reinterpret_cast(ctx[i]->state), 24); + xmrig::keccakf(reinterpret_cast(ctx[i]->state), 24); extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); } } @@ -771,7 +803,7 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size } for (size_t i = 0; i < 4; i++) { - keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + xmrig::keccak(input + size * i, size, ctx[i]->state); cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } @@ -858,7 +890,7 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size for (size_t i = 0; i < 4; i++) { cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); - keccakf(reinterpret_cast(ctx[i]->state), 24); + xmrig::keccakf(reinterpret_cast(ctx[i]->state), 24); extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); } } @@ -877,7 +909,7 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz } for (size_t i = 0; i < 5; i++) { - keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + xmrig::keccak(input + size * i, size, ctx[i]->state); cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } @@ -979,7 +1011,7 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz for (size_t i = 0; i < 5; i++) { cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); - keccakf(reinterpret_cast(ctx[i]->state), 24); + xmrig::keccakf(reinterpret_cast(ctx[i]->state), 24); extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); } } diff --git a/src/crypto/c_keccak.h b/src/crypto/c_keccak.h deleted file mode 100644 index 4f7f8572..00000000 --- a/src/crypto/c_keccak.h +++ /dev/null @@ -1,26 +0,0 @@ -// keccak.h -// 19-Nov-11 Markku-Juhani O. Saarinen - -#ifndef KECCAK_H -#define KECCAK_H - -#include -#include - -#ifndef KECCAK_ROUNDS -#define KECCAK_ROUNDS 24 -#endif - -#ifndef ROTL64 -#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) -#endif - -// compute a keccak hash (md) of given byte length from "in" -int keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen); - -// update the state -void keccakf(uint64_t st[25], int norounds); - -void keccak1600(const uint8_t *in, int inlen, uint8_t *md); - -#endif diff --git a/src/interfaces/IConfig.h b/src/interfaces/IConfig.h index f7433d7f..2422b891 100644 --- a/src/interfaces/IConfig.h +++ b/src/interfaces/IConfig.h @@ -36,30 +36,31 @@ public: enum Keys { // common AlgorithmKey = 'a', - ApiPort = 4000, ApiAccessTokenKey = 4001, - ApiWorkerIdKey = 4002, ApiIPv6Key = 4003, + ApiPort = 4000, ApiRestrictedKey = 4004, + ApiWorkerIdKey = 4002, BackgroundKey = 'B', + ColorKey = 1002, ConfigKey = 'c', DonateLevelKey = 1003, HelpKey = 'h', KeepAliveKey = 'k', LogFileKey = 'l', - ColorKey = 1002, - WatchKey = 1105, PasswordKey = 'p', RetriesKey = 'r', RetryPauseKey = 'R', + RigIdKey = 1012, SyslogKey = 'S', UrlKey = 'o', - UserKey = 'u', UserAgentKey = 1008, + UserKey = 'u', UserpassKey = 'O', + VariantKey = 1010, VerboseKey = 1100, VersionKey = 'V', - VariantKey = 1010, + WatchKey = 1105, // xmrig common CPUPriorityKey = 1021, @@ -90,8 +91,7 @@ public: virtual ~IConfig() {} - virtual bool adjust() = 0; - virtual bool isValid() const = 0; + virtual bool finalize() = 0; virtual bool isWatch() const = 0; virtual bool parseBoolean(int key, bool enable) = 0; virtual bool parseString(int key, const char *arg) = 0; diff --git a/src/net/JobResult.h b/src/net/JobResult.h index e3282584..4a920ca0 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -29,41 +29,24 @@ #include -#include "Job.h" +#include "common/net/Job.h" class JobResult { public: inline JobResult() : poolId(0), diff(0), nonce(0) {} - inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) : + inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff, const xmrig::Algorithm &algorithm) : poolId(poolId), diff(diff), nonce(nonce), + algorithm(algorithm), jobId(jobId) { memcpy(this->result, result, sizeof(this->result)); } - inline JobResult(const Job &job) : poolId(0), diff(0), nonce(0) - { - jobId = job.id(); - poolId = job.poolId(); - diff = job.diff(); - nonce = *job.nonce(); - } - - - inline JobResult &operator=(const Job &job) { - jobId = job.id(); - poolId = job.poolId(); - diff = job.diff(); - - return *this; - } - - inline uint64_t actualDiff() const { return Job::toDiff(reinterpret_cast(result)[3]); @@ -74,6 +57,7 @@ public: uint32_t diff; uint32_t nonce; uint8_t result[32]; + xmrig::Algorithm algorithm; xmrig::Id jobId; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 98ce7e8d..7293a0ac 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -31,16 +31,16 @@ #include "api/Api.h" -#include "log/Log.h" -#include "net/Client.h" +#include "common/log/Log.h" +#include "common/net/Client.h" +#include "common/net/strategies/FailoverStrategy.h" +#include "common/net/strategies/SinglePoolStrategy.h" +#include "common/net/SubmitResult.h" +#include "core/Config.h" +#include "core/Controller.h" #include "net/Network.h" #include "net/strategies/DonateStrategy.h" -#include "net/strategies/FailoverStrategy.h" -#include "net/strategies/SinglePoolStrategy.h" -#include "net/SubmitResult.h" #include "workers/Workers.h" -#include "core/Controller.h" -#include "core/Config.h" Network::Network(xmrig::Controller *controller) : @@ -57,11 +57,11 @@ Network::Network(xmrig::Controller *controller) : m_strategy = new FailoverStrategy(pools, controller->config()->retryPause(), controller->config()->retries(), this); } else { - m_strategy = new SinglePoolStrategy(pools.front(), controller->config()->retryPause(), this); + m_strategy = new SinglePoolStrategy(pools.front(), controller->config()->retryPause(), controller->config()->retries(), this); } if (controller->config()->donateLevel() > 0) { - m_donate = new DonateStrategy(controller->config()->donateLevel(), controller->config()->pools().front().user(), controller->config()->algorithm(), this); + m_donate = new DonateStrategy(controller->config()->donateLevel(), controller->config()->pools().front().user(), controller->config()->algorithm().algo(), this); } m_timer.data = this; @@ -166,12 +166,9 @@ bool Network::isColors() const void Network::setJob(Client *client, const Job &job, bool donate) { - if (isColors()) { - LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", client->host(), client->port(), job.diff()); - } - else { - LOG_INFO("new job from %s:%d diff %d", client->host(), client->port(), job.diff()); - } + LOG_INFO(isColors() ? MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s") + : "new job from %s:%d diff %d algo %s", + client->host(), client->port(), job.diff(), job.algorithm().shortName()); m_state.diff = job.diff(); Workers::setJob(job, donate); diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 27beae33..b4b41938 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -22,19 +22,15 @@ */ +#include "common/crypto/keccak.h" +#include "common/net/Client.h" +#include "common/net/Job.h" +#include "common/net/strategies/FailoverStrategy.h" +#include "common/net/strategies/SinglePoolStrategy.h" #include "common/Platform.h" #include "common/xmrig.h" #include "interfaces/IStrategyListener.h" -#include "net/Client.h" -#include "net/Job.h" #include "net/strategies/DonateStrategy.h" -#include "net/strategies/FailoverStrategy.h" - - -extern "C" -{ -#include "crypto/c_keccak.h" -} const static char *kDonatePool1 = "miner.fee.xmrig.com"; @@ -46,7 +42,7 @@ static inline float randomf(float min, float max) { } -DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyListener *listener) : +DonateStrategy::DonateStrategy(int level, const char *user, xmrig::Algo algo, IStrategyListener *listener) : m_active(false), m_donateTime(level * 60 * 1000), m_idleTime((100 - level) * 60 * 1000), @@ -56,7 +52,7 @@ DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyL uint8_t hash[200]; char userId[65] = { 0 }; - keccak(reinterpret_cast(user), static_cast(strlen(user)), hash, sizeof(hash)); + xmrig::keccak(reinterpret_cast(user), strlen(user), hash); Job::toHex(hash, 32, userId); if (algo == xmrig::CRYPTONIGHT) { @@ -66,14 +62,21 @@ DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyL } else if (algo == xmrig::CRYPTONIGHT_HEAVY) { m_pools.push_back(Pool(kDonatePool1, 8888, userId, nullptr, false, true)); - m_pools.push_back(Pool(kDonatePool1, 8889, userId, nullptr, false, true)); } else { m_pools.push_back(Pool(kDonatePool1, 5555, userId, nullptr, false, true)); - m_pools.push_back(Pool(kDonatePool1, 7777, userId, nullptr, false, true)); } - m_strategy = new FailoverStrategy(m_pools, 1, 1, this, true); + for (Pool &pool : m_pools) { + pool.algorithm().setAlgo(algo); + } + + if (m_pools.size() > 1) { + m_strategy = new FailoverStrategy(m_pools, 1, 2, this, true); + } + else { + m_strategy = new SinglePoolStrategy(m_pools.front(), 1, 2, this, true); + } m_timer.data = this; uv_timer_init(uv_default_loop(), &m_timer); diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index cad360b1..66c0375c 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -29,10 +29,10 @@ #include +#include "common/net/Pool.h" #include "interfaces/IClientListener.h" #include "interfaces/IStrategy.h" #include "interfaces/IStrategyListener.h" -#include "net/Pool.h" class Client; @@ -43,7 +43,7 @@ class Url; class DonateStrategy : public IStrategy, public IStrategyListener { public: - DonateStrategy(int level, const char *user, int algo, IStrategyListener *listener); + DonateStrategy(int level, const char *user, xmrig::Algo algo, IStrategyListener *listener); ~DonateStrategy(); public: diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 3632e193..e42139c0 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -24,7 +24,7 @@ #include -#include "net/Pool.h" +#include "common/net/Pool.h" #include "rapidjson/document.h" #include "workers/CpuThread.h" @@ -62,69 +62,97 @@ bool xmrig::CpuThread::isSoftAES(AlgoVariant av) xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) { - assert(variant == VARIANT_NONE || variant == VARIANT_V1); + assert(variant == VARIANT_0 || variant == VARIANT_1 || variant == VARIANT_IPBC || variant == VARIANT_XTL); - static const cn_hash_fun func_table[50] = { - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + static const cn_hash_fun func_table[90] = { + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, # ifndef XMRIG_NO_AEON - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, # else nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, # endif # ifndef XMRIG_NO_SUMO - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, # else nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, # endif @@ -132,11 +160,22 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a # ifndef XMRIG_NO_SUMO if (algorithm == CRYPTONIGHT_HEAVY) { - variant = VARIANT_NONE; + variant = VARIANT_0; } # endif - return func_table[20 * algorithm + 10 * variant + av - 1]; + const size_t index = 40 * algorithm + 10 * variant + av - 1; + +# ifndef NDEBUG + cn_hash_fun func = func_table[index]; + + assert(index < sizeof(func_table) / sizeof(func_table[0])); + assert(func != nullptr); + + return func; +# else + return func_table[index]; +# endif } @@ -252,7 +291,6 @@ rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const auto &allocator = doc.GetAllocator(); obj.AddMember("type", "cpu", allocator); - obj.AddMember("algo", rapidjson::StringRef(Pool::algoName(algorithm())), allocator); obj.AddMember("av", m_av, allocator); obj.AddMember("low_power_mode", multiway(), allocator); obj.AddMember("affine_to_cpu", affinity(), allocator); diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 71aa9cc6..42068eb7 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -29,9 +29,9 @@ #include +#include "common/log/Log.h" #include "core/Config.h" #include "core/Controller.h" -#include "log/Log.h" #include "workers/Hashrate.h" diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 09dd568f..c0f88446 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -50,23 +50,31 @@ MultiWorker::~MultiWorker() template bool MultiWorker::selfTest() { - if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { + if (m_thread->fn(xmrig::VARIANT_0) == nullptr) { return false; } - m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_hash, m_ctx); + m_thread->fn(xmrig::VARIANT_0)(test_input, 76, m_hash, m_ctx); if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, sizeof m_hash) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); + m_thread->fn(xmrig::VARIANT_1)(test_input, 76, m_hash, m_ctx); + if (memcmp(m_hash, test_output_v1, sizeof m_hash) != 0) { + return false; + } - return memcmp(m_hash, test_output_v1, sizeof m_hash) == 0; + m_thread->fn(xmrig::VARIANT_XTL)(test_input, 76, m_hash, m_ctx); + return memcmp(m_hash, test_output_xtl, sizeof m_hash) == 0; } # ifndef XMRIG_NO_AEON if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, sizeof m_hash) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); + m_thread->fn(xmrig::VARIANT_1)(test_input, 76, m_hash, m_ctx); + if (memcmp(m_hash, test_output_v1_lite, sizeof m_hash) != 0) { + return false; + } - return memcmp(m_hash, test_output_v1_lite, sizeof m_hash) == 0; + m_thread->fn(xmrig::VARIANT_IPBC)(test_input, 76, m_hash, m_ctx); + return memcmp(m_hash, test_output_ipbc_lite, sizeof m_hash) == 0; } # endif @@ -104,7 +112,7 @@ void MultiWorker::start() for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { - Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff())); + Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff(), m_state.job.algorithm())); } *nonce(i) += 1; diff --git a/src/workers/MultiWorker.h b/src/workers/MultiWorker.h index 2c231e8d..d89bbb33 100644 --- a/src/workers/MultiWorker.h +++ b/src/workers/MultiWorker.h @@ -26,8 +26,8 @@ #define __MULTIWORKER_H__ +#include "common/net/Job.h" #include "Mem.h" -#include "net/Job.h" #include "net/JobResult.h" #include "workers/Worker.h" diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 25e1d068..497e3060 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -26,12 +26,12 @@ #include "api/Api.h" +#include "common/log/Log.h" #include "core/Config.h" #include "core/Controller.h" #include "crypto/CryptoNight_constants.h" #include "interfaces/IJobResultListener.h" #include "interfaces/IThread.h" -#include "log/Log.h" #include "Mem.h" #include "rapidjson/document.h" #include "workers/Handle.h" @@ -132,8 +132,8 @@ void Workers::setJob(const Job &job, bool donate) void Workers::start(xmrig::Controller *controller) { const std::vector &threads = controller->config()->threads(); - m_status.algo = controller->config()->algorithm(); - m_status.colors = controller->config()->isHugePages(); + m_status.algo = controller->config()->algorithm().algo(); + m_status.colors = controller->config()->isColors(); m_status.threads = threads.size(); for (const xmrig::IThread *thread : threads) { @@ -301,9 +301,9 @@ void Workers::start(IWorker *worker) const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo) / 1048576; if (m_status.colors) { - LOG_INFO("\x1B[01;32mREADY (CPU)\x1B[0m threads \x1B[01;36m%zu(%zu)\x1B[0m huge pages %s%zu/%zu %1.0f%%\x1B[0m memory \x1B[01;36m%zu.0 MB", + LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\e[0m memory " CYAN_BOLD("%zu.0 MB") "", m_status.threads, m_status.ways, - (m_status.hugePages == m_status.pages ? "\x1B[01;32m" : (m_status.hugePages == 0 ? "\x1B[01;31m" : "\x1B[01;33m")), + (m_status.hugePages == m_status.pages ? "\e[1;32m" : (m_status.hugePages == 0 ? "\e[1;31m" : "\e[1;33m")), m_status.hugePages, m_status.pages, percent, memory); } else { diff --git a/src/workers/Workers.h b/src/workers/Workers.h index bbe9a760..ca01e698 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -30,7 +30,7 @@ #include #include -#include "net/Job.h" +#include "common/net/Job.h" #include "net/JobResult.h" #include "rapidjson/fwd.h"