Merge branch 'feature-algo' into dev

This commit is contained in:
XMRig 2018-05-03 01:02:30 +07:00
commit 7badca3aa5
63 changed files with 1197 additions and 612 deletions

View file

@ -4,6 +4,7 @@ project(xmrig)
option(WITH_LIBCPUID "Use Libcpuid" ON) option(WITH_LIBCPUID "Use Libcpuid" ON)
option(WITH_AEON "CryptoNight-Lite support" ON) option(WITH_AEON "CryptoNight-Lite support" ON)
option(WITH_SUMO "CryptoNight-Heavy support" ON) option(WITH_SUMO "CryptoNight-Heavy support" ON)
option(WITH_IPBC "CryptoNight-IPBC support" ON)
option(WITH_HTTPD "HTTP REST API" ON) option(WITH_HTTPD "HTTP REST API" ON)
option(BUILD_STATIC "Build static binary" OFF) option(BUILD_STATIC "Build static binary" OFF)
@ -17,11 +18,24 @@ set(HEADERS
src/common/config/CommonConfig.h src/common/config/CommonConfig.h
src/common/config/ConfigLoader.h src/common/config/ConfigLoader.h
src/common/config/ConfigWatcher.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/Platform.h
src/common/utils/c_str.h src/common/utils/c_str.h
src/common/utils/mm_malloc.h src/common/utils/mm_malloc.h
src/common/xmrig.h src/common/xmrig.h
src/Console.h
src/core/Config.cpp src/core/Config.cpp
src/core/ConfigLoader_platform.h src/core/ConfigLoader_platform.h
src/core/Controller.h src/core/Controller.h
@ -38,21 +52,10 @@ set(HEADERS
src/interfaces/IThread.h src/interfaces/IThread.h
src/interfaces/IWatcherListener.h src/interfaces/IWatcherListener.h
src/interfaces/IWorker.h src/interfaces/IWorker.h
src/log/ConsoleLog.h
src/log/FileLog.h
src/log/Log.h
src/Mem.h src/Mem.h
src/net/Client.h
src/net/Id.h
src/net/Job.h
src/net/JobResult.h src/net/JobResult.h
src/net/Network.h src/net/Network.h
src/net/Pool.h
src/net/Storage.h
src/net/strategies/DonateStrategy.h src/net/strategies/DonateStrategy.h
src/net/strategies/FailoverStrategy.h
src/net/strategies/SinglePoolStrategy.h
src/net/SubmitResult.h
src/Summary.h src/Summary.h
src/version.h src/version.h
src/workers/CpuThread.h src/workers/CpuThread.h
@ -67,7 +70,6 @@ set(HEADERS_CRYPTO
src/crypto/c_blake256.h src/crypto/c_blake256.h
src/crypto/c_groestl.h src/crypto/c_groestl.h
src/crypto/c_jh.h src/crypto/c_jh.h
src/crypto/c_keccak.h
src/crypto/c_skein.h src/crypto/c_skein.h
src/crypto/CryptoNight.h src/crypto/CryptoNight.h
src/crypto/CryptoNight_constants.h src/crypto/CryptoNight_constants.h
@ -91,22 +93,24 @@ set(SOURCES
src/common/config/CommonConfig.cpp src/common/config/CommonConfig.cpp
src/common/config/ConfigLoader.cpp src/common/config/ConfigLoader.cpp
src/common/config/ConfigWatcher.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/common/Platform.cpp
src/Console.cpp
src/core/Config.cpp src/core/Config.cpp
src/core/Controller.cpp src/core/Controller.cpp
src/log/ConsoleLog.cpp
src/log/FileLog.cpp
src/log/Log.cpp
src/Mem.cpp src/Mem.cpp
src/net/Client.cpp
src/net/Job.cpp
src/net/Network.cpp src/net/Network.cpp
src/net/Pool.cpp
src/net/strategies/DonateStrategy.cpp src/net/strategies/DonateStrategy.cpp
src/net/strategies/FailoverStrategy.cpp
src/net/strategies/SinglePoolStrategy.cpp
src/net/SubmitResult.cpp
src/Summary.cpp src/Summary.cpp
src/workers/CpuThread.cpp src/workers/CpuThread.cpp
src/workers/Handle.cpp src/workers/Handle.cpp
@ -118,7 +122,6 @@ set(SOURCES
) )
set(SOURCES_CRYPTO set(SOURCES_CRYPTO
src/crypto/c_keccak.c
src/crypto/c_groestl.c src/crypto/c_groestl.c
src/crypto/c_blake256.c src/crypto/c_blake256.c
src/crypto/c_jh.c src/crypto/c_jh.c
@ -194,7 +197,7 @@ endif()
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H) CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
if (HAVE_SYSLOG_H) if (HAVE_SYSLOG_H)
add_definitions(/DHAVE_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() endif()
if (NOT WITH_AEON) if (NOT WITH_AEON)
@ -205,6 +208,10 @@ if (NOT WITH_SUMO)
add_definitions(/DXMRIG_NO_SUMO) add_definitions(/DXMRIG_NO_SUMO)
endif() endif()
if (NOT WITH_IPBC)
add_definitions(/DXMRIG_NO_IPBC)
endif()
if (WITH_HTTPD) if (WITH_HTTPD)
find_package(MHD) find_package(MHD)

View file

@ -28,15 +28,13 @@
#include "api/Api.h" #include "api/Api.h"
#include "App.h" #include "App.h"
#include "common/Console.h"
#include "common/log/Log.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "Console.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h" #include "Cpu.h"
#include "crypto/CryptoNight.h" #include "crypto/CryptoNight.h"
#include "log/ConsoleLog.h"
#include "log/FileLog.h"
#include "log/Log.h"
#include "Mem.h" #include "Mem.h"
#include "net/Network.h" #include "net/Network.h"
#include "Summary.h" #include "Summary.h"

View file

@ -29,9 +29,9 @@
#include "App.h" #include "App.h"
#include "common/log/Log.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "log/Log.h"
void App::background() void App::background()

View file

@ -27,10 +27,10 @@
#include <sys/mman.h> #include <sys/mman.h>
#include "common/log/Log.h"
#include "common/utils/mm_malloc.h" #include "common/utils/mm_malloc.h"
#include "common/xmrig.h" #include "common/xmrig.h"
#include "crypto/CryptoNight.h" #include "crypto/CryptoNight.h"
#include "log/Log.h"
#include "Mem.h" #include "Mem.h"

View file

@ -29,11 +29,11 @@
#include <tchar.h> #include <tchar.h>
#include "common/log/Log.h"
#include "common/utils/mm_malloc.h" #include "common/utils/mm_malloc.h"
#include "common/xmrig.h" #include "common/xmrig.h"
#include "crypto/CryptoNight.h" #include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_constants.h"
#include "log/Log.h"
#include "Mem.h" #include "Mem.h"

View file

@ -27,12 +27,12 @@
#include <uv.h> #include <uv.h>
#include "common/log/Log.h"
#include "common/net/Pool.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h" #include "Cpu.h"
#include "log/Log.h"
#include "Mem.h" #include "Mem.h"
#include "net/Pool.h"
#include "Summary.h" #include "Summary.h"
#include "version.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", 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->threadsCount(),
config->algoName(), config->algorithm().name(),
config->algoVariant(), config->algoVariant(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "",
config->donateLevel(), config->donateLevel(),
@ -113,7 +113,7 @@ static void print_threads(xmrig::Config *config)
else { 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%%", 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->threadsCount(),
config->algoName(), config->algorithm().name(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "",
config->donateLevel()); config->donateLevel());
} }
@ -132,8 +132,8 @@ static void print_pools(xmrig::Config *config)
} }
# ifdef APP_DEBUG # ifdef APP_DEBUG
for (size_t i = 0; i < pools.size(); ++i) { for (const Pool &pool : pools) {
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()); pool.print();
} }
# endif # endif
} }

View file

@ -35,13 +35,14 @@
#include "api/ApiRouter.h" #include "api/ApiRouter.h"
#include "common/api/HttpReply.h" #include "common/api/HttpReply.h"
#include "common/api/HttpRequest.h" #include "common/api/HttpRequest.h"
#include "common/crypto/keccak.h"
#include "common/net/Job.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h" #include "Cpu.h"
#include "interfaces/IThread.h" #include "interfaces/IThread.h"
#include "Mem.h" #include "Mem.h"
#include "net/Job.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h" #include "rapidjson/stringbuffer.h"
@ -50,12 +51,6 @@
#include "workers/Workers.h" #include "workers/Workers.h"
extern "C"
{
#include "crypto/c_keccak.h"
}
static inline double normalize(double d) static inline double normalize(double d)
{ {
if (!isnormal(d)) { if (!isnormal(d)) {
@ -171,7 +166,7 @@ void ApiRouter::genId()
memcpy(input, interfaces[i].phys_addr, addrSize); memcpy(input, interfaces[i].phys_addr, addrSize);
memcpy(input + addrSize, APP_KIND, strlen(APP_KIND)); memcpy(input + addrSize, APP_KIND, strlen(APP_KIND));
keccak(input, static_cast<int>(inSize), hash, sizeof(hash)); xmrig::keccak(input, inSize, hash);
Job::toHex(hash, 8, m_id); Job::toHex(hash, 8, m_id);
delete [] input; delete [] input;
@ -249,7 +244,7 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const
doc.AddMember("kind", APP_KIND, allocator); doc.AddMember("kind", APP_KIND, allocator);
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator); doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
doc.AddMember("cpu", cpu, 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("hugepages", Workers::hugePages() > 0, allocator);
doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator); doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator);
} }

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -29,7 +29,7 @@
#include "api/NetworkState.h" #include "api/NetworkState.h"
#include "net/SubmitResult.h" #include "common/net/SubmitResult.h"
NetworkState::NetworkState() : NetworkState::NetworkState() :

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * 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" #include "interfaces/IConsoleListener.h"

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View file

@ -30,7 +30,7 @@
#include "common/api/Httpd.h" #include "common/api/Httpd.h"
#include "common/api/HttpReply.h" #include "common/api/HttpReply.h"
#include "common/api/HttpRequest.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) : Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) :
@ -81,7 +81,12 @@ bool Httpd::start()
return false; return false;
} }
# if MHD_VERSION >= 0x00093900
uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval); uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval);
# else
uv_timer_start(&m_timer, Httpd::onTimer, kActiveInterval, kActiveInterval);
# endif
return true; return true;
} }
@ -107,6 +112,7 @@ void Httpd::run()
{ {
MHD_run(m_daemon); MHD_run(m_daemon);
# if MHD_VERSION >= 0x00093900
const MHD_DaemonInfo *info = MHD_get_daemon_info(m_daemon, MHD_DAEMON_INFO_CURRENT_CONNECTIONS); const MHD_DaemonInfo *info = MHD_get_daemon_info(m_daemon, MHD_DAEMON_INFO_CURRENT_CONNECTIONS);
if (m_idle && info->num_connections) { if (m_idle && info->num_connections) {
uv_timer_set_repeat(&m_timer, kActiveInterval); uv_timer_set_repeat(&m_timer, kActiveInterval);
@ -116,6 +122,7 @@ void Httpd::run()
uv_timer_set_repeat(&m_timer, kIdleInterval); uv_timer_set_repeat(&m_timer, kIdleInterval);
m_idle = true; m_idle = true;
} }
# endif
} }

View file

@ -30,16 +30,14 @@
#include "common/config/CommonConfig.h" #include "common/config/CommonConfig.h"
#include "common/log/Log.h"
#include "donate.h" #include "donate.h"
#include "log/Log.h"
#include "net/Pool.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
xmrig::CommonConfig::CommonConfig() : xmrig::CommonConfig::CommonConfig() :
m_algorithm(CRYPTONIGHT),
m_adjusted(false), m_adjusted(false),
m_apiIPv6(false), m_apiIPv6(false),
m_apiRestricted(true), m_apiRestricted(true),
@ -57,7 +55,8 @@ xmrig::CommonConfig::CommonConfig() :
m_donateLevel(kDefaultDonateLevel), m_donateLevel(kDefaultDonateLevel),
m_printTime(60), m_printTime(60),
m_retries(5), m_retries(5),
m_retryPause(5) m_retryPause(5),
m_state(NoneState)
{ {
m_pools.push_back(Pool()); 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; return false;
} }
m_adjusted = true; if (!m_algorithm.isValid()) {
m_algorithm.setAlgo(CRYPTONIGHT);
for (Pool &pool : m_pools) {
pool.adjust(algorithm());
} }
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; return true;
} }
bool xmrig::CommonConfig::isValid() const
{
return m_pools[0].isValid() && m_algorithm != INVALID_ALGO;
}
bool xmrig::CommonConfig::parseBoolean(int key, bool enable) bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
{ {
switch (key) { switch (key) {
@ -142,7 +153,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
{ {
switch (key) { switch (key) {
case AlgorithmKey: /* --algo */ case AlgorithmKey: /* --algo */
setAlgo(arg); m_algorithm.parseAlgorithm(arg);
break; break;
case UserpassKey: /* --userpass */ case UserpassKey: /* --userpass */
@ -178,6 +189,14 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
m_pools.back().setPassword(arg); m_pools.back().setPassword(arg);
break; 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 */ case LogFileKey: /* --log-file */
m_logFile = arg; m_logFile = arg;
break; break;
@ -196,7 +215,6 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
case RetriesKey: /* --retries */ case RetriesKey: /* --retries */
case RetryPauseKey: /* --retry-pause */ case RetryPauseKey: /* --retry-pause */
case VariantKey: /* --variant */
case ApiPort: /* --api-port */ case ApiPort: /* --api-port */
case PrintTimeKey: /* --cpu-priority */ case PrintTimeKey: /* --cpu-priority */
return parseUint64(key, strtol(arg, nullptr, 10)); return parseUint64(key, strtol(arg, nullptr, 10));
@ -205,7 +223,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
case SyslogKey: /* --syslog */ case SyslogKey: /* --syslog */
case KeepAliveKey: /* --keepalive */ case KeepAliveKey: /* --keepalive */
case NicehashKey: /* --nicehash */ case NicehashKey: /* --nicehash */
case ApiIPv6Key: /* --api-ipv6 */ case ApiIPv6Key: /* --api-ipv6 */
return parseBoolean(key, true); return parseBoolean(key, true);
case ColorKey: /* --no-color */ case ColorKey: /* --no-color */
@ -296,7 +314,7 @@ bool xmrig::CommonConfig::parseInt(int key, int arg)
break; break;
case VariantKey: /* --variant */ case VariantKey: /* --variant */
m_pools.back().setVariant(arg); m_pools.back().algorithm().parseVariant(arg);
break; break;
case DonateLevelKey: /* --donate-level */ case DonateLevelKey: /* --donate-level */
@ -323,9 +341,3 @@ bool xmrig::CommonConfig::parseInt(int key, int arg)
return true; return true;
} }
void xmrig::CommonConfig::setAlgo(const char *algo)
{
m_algorithm = Pool::algorithm(algo);
}

View file

@ -28,10 +28,10 @@
#include <vector> #include <vector>
#include "common/net/Pool.h"
#include "common/utils/c_str.h" #include "common/utils/c_str.h"
#include "common/xmrig.h" #include "common/xmrig.h"
#include "interfaces/IConfig.h" #include "interfaces/IConfig.h"
#include "net/Pool.h"
namespace xmrig { namespace xmrig {
@ -43,18 +43,17 @@ public:
CommonConfig(); CommonConfig();
~CommonConfig(); ~CommonConfig();
inline Algo algorithm() const { return m_algorithm; }
inline bool isApiIPv6() const { return m_apiIPv6; } inline bool isApiIPv6() const { return m_apiIPv6; }
inline bool isApiRestricted() const { return m_apiRestricted; } inline bool isApiRestricted() const { return m_apiRestricted; }
inline bool isBackground() const { return m_background; } inline bool isBackground() const { return m_background; }
inline bool isColors() const { return m_colors; } inline bool isColors() const { return m_colors; }
inline bool isSyslog() const { return m_syslog; } 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 *apiToken() const { return m_apiToken.data(); }
inline const char *apiWorkerId() const { return m_apiWorkerId.data(); } inline const char *apiWorkerId() const { return m_apiWorkerId.data(); }
inline const char *logFile() const { return m_logFile.data(); } inline const char *logFile() const { return m_logFile.data(); }
inline const char *userAgent() const { return m_userAgent.data(); } inline const char *userAgent() const { return m_userAgent.data(); }
inline const std::vector<Pool> &pools() const { return m_pools; } inline const std::vector<Pool> &pools() const { return m_activePools; }
inline int apiPort() const { return m_apiPort; } inline int apiPort() const { return m_apiPort; }
inline int donateLevel() const { return m_donateLevel; } inline int donateLevel() const { return m_donateLevel; }
inline int printTime() const { return m_printTime; } inline int printTime() const { return m_printTime; }
@ -66,15 +65,20 @@ public:
inline const char *fileName() const override { return m_fileName.data(); } inline const char *fileName() const override { return m_fileName.data(); }
protected: protected:
bool adjust() override; enum State {
bool isValid() const override; NoneState,
ReadyState,
ErrorState
};
bool finalize() override;
bool parseBoolean(int key, bool enable) override; bool parseBoolean(int key, bool enable) override;
bool parseString(int key, const char *arg) override; bool parseString(int key, const char *arg) override;
bool parseUint64(int key, uint64_t arg) override; bool parseUint64(int key, uint64_t arg) override;
bool save() override; bool save() override;
void setFileName(const char *fileName) override; void setFileName(const char *fileName) override;
Algo m_algorithm; Algorithm m_algorithm;
bool m_adjusted; bool m_adjusted;
bool m_apiIPv6; bool m_apiIPv6;
bool m_apiRestricted; bool m_apiRestricted;
@ -87,6 +91,8 @@ protected:
int m_printTime; int m_printTime;
int m_retries; int m_retries;
int m_retryPause; int m_retryPause;
State m_state;
std::vector<Pool> m_activePools;
std::vector<Pool> m_pools; std::vector<Pool> m_pools;
xmrig::c_str m_apiToken; xmrig::c_str m_apiToken;
xmrig::c_str m_apiWorkerId; xmrig::c_str m_apiWorkerId;
@ -96,7 +102,6 @@ protected:
private: private:
bool parseInt(int key, int arg); bool parseInt(int key, int arg);
void setAlgo(const char *algo);
}; };

View file

@ -34,12 +34,12 @@
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/config/ConfigWatcher.h" #include "common/config/ConfigWatcher.h"
#include "common/net/Pool.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/ConfigCreator.h" #include "core/ConfigCreator.h"
#include "core/ConfigLoader_platform.h" #include "core/ConfigLoader_platform.h"
#include "interfaces/IConfig.h" #include "interfaces/IConfig.h"
#include "interfaces/IWatcherListener.h" #include "interfaces/IWatcherListener.h"
#include "net/Pool.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/error/en.h" #include "rapidjson/error/en.h"
#include "rapidjson/filereadstream.h" #include "rapidjson/filereadstream.h"
@ -108,9 +108,8 @@ bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson::
} }
config->parseJSON(doc); 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; return nullptr;
} }
if (!config->isValid()) { if (!config->finalize()) {
delete config;
config = m_creator->create();
loadFromFile(config, Platform::defaultConfigName()); loadFromFile(config, Platform::defaultConfigName());
} }
if (!config->isValid()) { if (!config->finalize()) {
fprintf(stderr, "No valid configuration found. Exiting.\n"); fprintf(stderr, "No valid configuration found. Exiting.\n");
delete config; delete config;
return nullptr; 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); m_watcher = new xmrig::ConfigWatcher(config->fileName(), creator, listener);
} }
config->adjust();
return config; return config;
} }

View file

@ -27,9 +27,9 @@
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/config/ConfigWatcher.h" #include "common/config/ConfigWatcher.h"
#include "common/log/Log.h"
#include "core/ConfigCreator.h" #include "core/ConfigCreator.h"
#include "interfaces/IWatcherListener.h" #include "interfaces/IWatcherListener.h"
#include "log/Log.h"
xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) : xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) :
@ -83,7 +83,7 @@ void xmrig::ConfigWatcher::reload()
IConfig *config = m_creator->create(); IConfig *config = m_creator->create();
ConfigLoader::loadFromFile(config, m_path.data()); ConfigLoader::loadFromFile(config, m_path.data());
if (!config->isValid()) { if (!config->finalize()) {
LOG_ERR("reloading failed"); LOG_ERR("reloading failed");
delete config; delete config;

View file

@ -0,0 +1,219 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#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<Variant>(i);
break;
}
}
}
void xmrig::Algorithm::parseVariant(int variant)
{
if (variant >= VARIANT_AUTO && variant <= VARIANT_XTL) {
m_variant = static_cast<Variant>(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";
}

View file

@ -0,0 +1,91 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __ALGORITHM_H__
#define __ALGORITHM_H__
#include <vector>
#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<xmrig::Algorithm> Algorithms;
} /* namespace xmrig */
#endif /* __ALGORITHM_H__ */

View file

@ -1,10 +1,35 @@
// keccak.c /* XMRig
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi> * Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
// A baseline Keccak (3rd round) implementation. * Copyright 2011 Markku-Juhani O. Saarinen <mjos@iki.fi>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <stdint.h> #include <stdint.h>
#include <memory.h> #include <memory.h>
#include "common/crypto/keccak.h"
#define HASH_DATA_AREA 136 #define HASH_DATA_AREA 136
#define KECCAK_ROUNDS 24 #define KECCAK_ROUNDS 24
@ -26,7 +51,7 @@ const uint64_t keccakf_rndc[24] =
// update the state with given number of rounds // 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; int i, j, round;
uint64_t t, bc[5]; 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" // compute a keccak hash (md) of given byte length from "in"
typedef uint64_t state_t[25]; 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; state_t st;
uint8_t temp[144]; 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)); memset(st, 0, sizeof(st));
for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) { 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]; st[i] ^= ((uint64_t *) in)[i];
keccakf(st, KECCAK_ROUNDS); }
xmrig::keccakf(st, KECCAK_ROUNDS);
} }
// last block and padding // last block and padding
memcpy(temp, in, inlen); memcpy(temp, in, inlen);
temp[inlen++] = 1; temp[inlen++] = 1;
memset(temp + inlen, 0, rsiz - inlen); memset(temp + inlen, 0, rsiz - inlen);
temp[rsiz - 1] |= 0x80; temp[rsiz - 1] |= 0x80;
for (i = 0; i < rsizw; i++) for (i = 0; i < rsizw; i++) {
st[i] ^= ((uint64_t *) temp)[i]; st[i] ^= ((uint64_t *) temp)[i];
}
keccakf(st, KECCAK_ROUNDS); keccakf(st, KECCAK_ROUNDS);
memcpy(md, st, mdlen); memcpy(md, st, mdlen);
} }
void keccak1600(const uint8_t *in, int inlen, uint8_t *md)
{
keccak(in, inlen, md, sizeof(state_t));
}

View file

@ -0,0 +1,49 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2011 Markku-Juhani O. Saarinen <mjos@iki.fi>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef KECCAK_H_
#define KECCAK_H_
#include <stdint.h>
#include <string.h>
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<int>(inlen), md, 200);
}
// update the state
void keccakf(uint64_t st[25], int norounds);
} /* namespace xmrig */
#endif /* KECCAK_H_ */

View file

@ -34,10 +34,10 @@
#endif #endif
#include "common/log/ConsoleLog.h"
#include "common/log/Log.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "log/ConsoleLog.h"
#include "log/Log.h"
ConsoleLog::ConsoleLog(xmrig::Controller *controller) : ConsoleLog::ConsoleLog(xmrig::Controller *controller) :

View file

@ -29,7 +29,7 @@
#include <time.h> #include <time.h>
#include "log/FileLog.h" #include "common/log/FileLog.h"
FileLog::FileLog(const char *fileName) FileLog::FileLog(const char *fileName)

View file

@ -29,8 +29,8 @@
#include <time.h> #include <time.h>
#include "common/log/Log.h"
#include "interfaces/ILogBackend.h" #include "interfaces/ILogBackend.h"
#include "log/Log.h"
Log *Log::m_self = nullptr; Log *Log::m_self = nullptr;

View file

@ -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_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__)
#define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, 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__) #define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__)

View file

@ -25,7 +25,7 @@
#include <syslog.h> #include <syslog.h>
#include "log/SysLog.h" #include "common/log/SysLog.h"
#include "version.h" #include "version.h"

View file

@ -29,22 +29,16 @@
#include <utility> #include <utility>
#include "common/log/Log.h"
#include "common/net/Client.h"
#include "interfaces/IClientListener.h" #include "interfaces/IClientListener.h"
#include "log/Log.h" #include "net/JobResult.h"
#include "net/Client.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/error/en.h" #include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h" #include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h" #include "rapidjson/writer.h"
#ifdef XMRIG_PROXY_PROJECT
# include "proxy/JobResult.h"
#else
# include "net/JobResult.h"
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
# define strncasecmp(x,y,z) _strnicmp(x,y,z) # define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif #endif
@ -60,7 +54,9 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_quiet(false), m_quiet(false),
m_agent(agent), m_agent(agent),
m_listener(listener), m_listener(listener),
m_extensions(0),
m_id(id), m_id(id),
m_retries(5),
m_retryPause(5000), m_retryPause(5000),
m_failures(0), m_failures(0),
m_recvBufPos(0), m_recvBufPos(0),
@ -166,12 +162,14 @@ bool Client::disconnect()
int64_t Client::submit(const JobResult &result) int64_t Client::submit(const JobResult &result)
{ {
using namespace rapidjson;
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
const char *nonce = result.nonce; const char *nonce = result.nonce;
const char *data = result.result; const char *data = result.result;
# else # else
char nonce[9]; char *nonce = m_sendBuf;
char data[65]; char *data = m_sendBuf + 16;
Job::toHex(reinterpret_cast<const unsigned char*>(&result.nonce), 4, nonce); Job::toHex(reinterpret_cast<const unsigned char*>(&result.nonce), 4, nonce);
nonce[8] = '\0'; nonce[8] = '\0';
@ -180,8 +178,24 @@ int64_t Client::submit(const JobResult &result)
data[64] = '\0'; data[64] = '\0';
# endif # 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", Document doc(kObjectType);
m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data); 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 # ifdef XMRIG_PROXY_PROJECT
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id); 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()); m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
# endif # endif
return send(size); return send(doc);
} }
@ -238,12 +252,7 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
return false; return false;
} }
# ifdef XMRIG_PROXY_PROJECT Job job(m_id, m_nicehash, m_pool.algorithm(), m_rpcId);
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
if (!job.setId(params["job_id"].GetString())) { if (!job.setId(params["job_id"].GetString())) {
*code = 3; *code = 3;
@ -260,12 +269,26 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
return false; return false;
} }
if (params.HasMember("coin")) { if (params.HasMember("algo")) {
job.setCoin(params["coin"].GetString()); job.algorithm().parseAlgorithm(params["algo"].GetString());
} }
if (params.HasMember("variant")) { 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) { if (m_job != job) {
@ -278,7 +301,7 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
return false; return false;
} }
if (!m_quiet) { if (!isQuiet()) {
LOG_WARN("[%s] duplicate job received, reconnect", m_pool.url()); 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; return false;
} }
# ifndef XMRIG_PROXY_PROJECT
m_nicehash = m_pool.isNicehash(); m_nicehash = m_pool.isNicehash();
# endif
if (result.HasMember("extensions")) { if (result.HasMember("extensions")) {
parseExtensions(result["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) int Client::resolve(const char *host)
{ {
setState(HostLookupState); 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); const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, nullptr, &m_hints);
if (r) { if (r) {
if (!m_quiet) { if (!isQuiet()) {
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_pool.port(), uv_strerror(r)); LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_pool.port(), uv_strerror(r));
} }
return 1; 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<StringBuffer> 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) int64_t Client::send(size_t size)
{ {
LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf); 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() void Client::login()
{ {
using namespace rapidjson;
m_results.clear(); m_results.clear();
rapidjson::Document doc; Document doc(kObjectType);
doc.SetObject();
auto &allocator = doc.GetAllocator(); auto &allocator = doc.GetAllocator();
doc.AddMember("id", 1, allocator); doc.AddMember("id", 1, allocator);
doc.AddMember("jsonrpc", "2.0", allocator); doc.AddMember("jsonrpc", "2.0", allocator);
doc.AddMember("method", "login", allocator); doc.AddMember("method", "login", allocator);
rapidjson::Value params(rapidjson::kObjectType); Value params(kObjectType);
params.AddMember("login", rapidjson::StringRef(m_pool.user()), allocator); params.AddMember("login", StringRef(m_pool.user()), allocator);
params.AddMember("pass", rapidjson::StringRef(m_pool.password()), allocator); params.AddMember("pass", StringRef(m_pool.password()), allocator);
params.AddMember("agent", rapidjson::StringRef(m_agent), allocator); params.AddMember("agent", StringRef(m_agent), allocator);
doc.AddMember("params", params, allocator); if (m_pool.rigId()) {
params.AddMember("rigid", StringRef(m_pool.rigId()), allocator);
rapidjson::StringBuffer buffer(0, 512);
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
doc.Accept(writer);
const size_t size = buffer.GetSize();
if (size > (sizeof(m_buf) - 2)) {
return;
} }
memcpy(m_sendBuf, buffer.GetString(), size); Value algo(kArrayType);
m_sendBuf[size] = '\n';
m_sendBuf[size + 1] = '\0';
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); LOG_DEBUG("[%s] received (%d bytes): \"%s\"", m_pool.url(), len, line);
if (len < 32 || line[0] != '{') { if (len < 32 || line[0] != '{') {
if (!m_quiet) { if (!isQuiet()) {
LOG_ERR("[%s] JSON decode failed", m_pool.url()); LOG_ERR("[%s] JSON decode failed", m_pool.url());
} }
@ -461,7 +521,7 @@ void Client::parse(char *line, size_t len)
rapidjson::Document doc; rapidjson::Document doc;
if (doc.ParseInsitu(line).HasParseError()) { 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())); 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) void Client::parseExtensions(const rapidjson::Value &value)
{ {
m_extensions = 0;
if (!value.IsArray()) { if (!value.IsArray()) {
return; return;
} }
@ -493,8 +555,15 @@ void Client::parseExtensions(const rapidjson::Value &value)
continue; continue;
} }
if (strcmp(ext.GetString(), "algo") == 0) {
m_extensions |= AlgoExt;
continue;
}
if (strcmp(ext.GetString(), "nicehash") == 0) { if (strcmp(ext.GetString(), "nicehash") == 0) {
m_extensions |= NicehashExt;
m_nicehash = true; m_nicehash = true;
continue;
} }
} }
} }
@ -503,7 +572,7 @@ void Client::parseExtensions(const rapidjson::Value &value)
void Client::parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error) void Client::parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error)
{ {
if (error.IsObject()) { if (error.IsObject()) {
if (!m_quiet) { if (!isQuiet()) {
LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), error["message"].GetString(), error["code"].GetInt()); LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), error["message"].GetString(), error["code"].GetInt());
} }
return; 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_listener->onResultAccepted(this, it->second, message);
m_results.erase(it); 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()); 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) { if (id == 1) {
int code = -1; int code = -1;
if (!parseLogin(result, &code)) { if (!parseLogin(result, &code)) {
if (!m_quiet) { if (!isQuiet()) {
LOG_ERR("[%s] login error code: %d", m_pool.url(), code); 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 (status < 0) {
if (!client->m_quiet) { if (!client->isQuiet()) {
LOG_ERR("[%s] connect error: \"%s\"", client->m_pool.url(), uv_strerror(status)); 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 < 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)); 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 (status < 0) {
if (!client->m_quiet) { if (!client->isQuiet()) {
LOG_ERR("[%s] DNS error: \"%s\"", client->m_pool.url(), uv_strerror(status)); 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 (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()); LOG_ERR("[%s] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_pool.url());
} }

View file

@ -30,11 +30,11 @@
#include <vector> #include <vector>
#include "net/Id.h" #include "common/net/Id.h"
#include "net/Job.h" #include "common/net/Job.h"
#include "net/Storage.h" #include "common/net/Pool.h"
#include "net/SubmitResult.h" #include "common/net/Storage.h"
#include "net/Pool.h" #include "common/net/SubmitResult.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
@ -74,14 +74,22 @@ public:
inline SocketState state() const { return m_state; } inline SocketState state() const { return m_state; }
inline uint16_t port() const { return m_pool.port(); } inline uint16_t port() const { return m_pool.port(); }
inline void setQuiet(bool quiet) { m_quiet = quiet; } inline void setQuiet(bool quiet) { m_quiet = quiet; }
inline void setRetries(int retries) { m_retries = retries; }
inline void setRetryPause(int ms) { m_retryPause = ms; } inline void setRetryPause(int ms) { m_retryPause = ms; }
private: private:
enum Extensions {
NicehashExt = 1,
AlgoExt = 2
};
bool close(); bool close();
bool isCriticalError(const char *message); bool isCriticalError(const char *message);
bool parseJob(const rapidjson::Value &params, int *code); bool parseJob(const rapidjson::Value &params, int *code);
bool parseLogin(const rapidjson::Value &result, int *code); bool parseLogin(const rapidjson::Value &result, int *code);
bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const;
int resolve(const char *host); int resolve(const char *host);
int64_t send(const rapidjson::Document &doc);
int64_t send(size_t size); int64_t send(size_t size);
void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6); void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6);
void connect(sockaddr *addr); void connect(sockaddr *addr);
@ -96,6 +104,8 @@ private:
void setState(SocketState state); void setState(SocketState state);
void startTimeout(); 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 onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
static void onClose(uv_handle_t *handle); static void onClose(uv_handle_t *handle);
static void onConnect(uv_connect_t *req, int status); static void onConnect(uv_connect_t *req, int status);
@ -113,7 +123,9 @@ private:
char m_sendBuf[768]; char m_sendBuf[768];
const char *m_agent; const char *m_agent;
IClientListener *m_listener; IClientListener *m_listener;
int m_extensions;
int m_id; int m_id;
int m_retries;
int m_retryPause; int m_retryPause;
int64_t m_failures; int64_t m_failures;
Job m_job; Job m_job;

View file

@ -27,7 +27,7 @@
#include <string.h> #include <string.h>
#include "net/Job.h" #include "common/net/Job.h"
static inline unsigned char hf_hex2bin(char c, bool &err) static inline unsigned char hf_hex2bin(char c, bool &err)
@ -59,31 +59,27 @@ static inline char hf_bin2hex(unsigned char c)
Job::Job() : Job::Job() :
m_nicehash(false), m_nicehash(false),
m_coin(),
m_algo(xmrig::CRYPTONIGHT),
m_poolId(-2), m_poolId(-2),
m_threadId(-1), m_threadId(-1),
m_size(0), m_size(0),
m_diff(0), m_diff(0),
m_target(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() 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; m_nicehash = true;
} }
# ifdef XMRIG_PROXY_PROJECT
memset(m_rawBlob, 0, sizeof(m_rawBlob));
memcpy(m_rawBlob, blob, m_size * 2);
# endif
return true; return true;
} }
@ -152,40 +153,16 @@ bool Job::setTarget(const char *target)
return false; return false;
} }
# ifdef XMRIG_PROXY_PROJECT
memset(m_rawTarget, 0, sizeof(m_rawTarget));
memcpy(m_rawTarget, target, len);
# endif
m_diff = toDiff(m_target); m_diff = toDiff(m_target);
return true; 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<xmrig::Variant>(variant);
break;
default:
assert(false);
m_variant = xmrig::VARIANT_AUTO;
break;
}
}
bool Job::fromHex(const char* in, unsigned int len, unsigned char* out) bool Job::fromHex(const char* in, unsigned int len, unsigned char* out)
{ {
bool error = false; bool error = false;

View file

@ -30,39 +30,49 @@
#include <stdint.h> #include <stdint.h>
#include "common/xmrig.h" #include "common/crypto/Algorithm.h"
#include "net/Id.h" #include "common/net/Id.h"
class Job class Job
{ {
public: public:
Job(); Job();
Job(int poolId, bool nicehash, int algo, int variant); Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId);
~Job(); ~Job();
bool setBlob(const char *blob); bool setBlob(const char *blob);
bool setTarget(const char *target); bool setTarget(const char *target);
void setCoin(const char *coin);
void setVariant(int variant);
inline bool isNicehash() const { return m_nicehash; } inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_size > 0 && m_diff > 0; } inline bool isValid() const { return m_size > 0 && m_diff > 0; }
inline bool setId(const char *id) { return m_id.setId(id); } 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<const uint32_t*>(m_blob + 39); }
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); } inline const uint8_t *blob() const { return m_blob; }
inline const uint8_t *blob() const { return m_blob; } inline const xmrig::Algorithm &algorithm() const { return m_algorithm; }
inline const xmrig::Id &id() const { return m_id; } inline const xmrig::Id &clientId() const { return m_clientId; }
inline int poolId() const { return m_poolId; } inline const xmrig::Id &id() const { return m_id; }
inline int threadId() const { return m_threadId; } inline int poolId() const { return m_poolId; }
inline size_t size() const { return m_size; } inline int threadId() const { return m_threadId; }
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); } inline size_t size() const { return m_size; }
inline uint32_t diff() const { return (uint32_t) m_diff; } inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
inline uint64_t target() const { return m_target; } inline uint32_t diff() const { return static_cast<uint32_t>(m_diff); }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } inline uint64_t target() const { return m_target; }
inline void setPoolId(int poolId) { m_poolId = poolId; } inline void reset() { m_size = 0; m_diff = 0; }
inline void setThreadId(int threadId) { m_threadId = threadId; } inline void setClientId(const xmrig::Id &id) { m_clientId = id; }
inline xmrig::Variant variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_V1 : xmrig::VARIANT_NONE) : m_variant); } 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 bool fromHex(const char* in, unsigned int len, unsigned char* out);
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); } static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
@ -78,16 +88,20 @@ public:
private: private:
bool m_nicehash; bool m_nicehash;
char m_coin[5];
int m_algo;
int m_poolId; int m_poolId;
int m_threadId; int m_threadId;
size_t m_size; size_t m_size;
uint64_t m_diff; uint64_t m_diff;
uint64_t m_target; 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. 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::Id m_id;
xmrig::Variant m_variant;
# ifdef XMRIG_PROXY_PROJECT
char m_rawBlob[176];
char m_rawTarget[24];
# endif
}; };
#endif /* __JOB_H__ */ #endif /* __JOB_H__ */

View file

@ -28,7 +28,13 @@
#include <stdio.h> #include <stdio.h>
#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 #ifdef _MSC_VER
@ -37,42 +43,10 @@
#endif #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() : Pool::Pool() :
m_nicehash(false), m_nicehash(false),
m_keepAlive(0), m_keepAlive(0),
m_port(kDefaultPort), m_port(kDefaultPort)
m_algo(xmrig::CRYPTONIGHT),
m_variant(xmrig::VARIANT_AUTO)
{ {
} }
@ -91,23 +65,19 @@ Pool::Pool() :
Pool::Pool(const char *url) : Pool::Pool(const char *url) :
m_nicehash(false), m_nicehash(false),
m_keepAlive(0), m_keepAlive(0),
m_port(kDefaultPort), m_port(kDefaultPort)
m_algo(xmrig::CRYPTONIGHT),
m_variant(xmrig::VARIANT_AUTO)
{ {
parse(url); 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_nicehash(nicehash),
m_keepAlive(keepAlive), m_keepAlive(keepAlive),
m_port(port), m_port(port),
m_algo(xmrig::CRYPTONIGHT),
m_host(host), m_host(host),
m_password(password), m_password(password),
m_user(user), m_user(user)
m_variant(variant)
{ {
const size_t size = m_host.size() + 8; const size_t size = m_host.size() + 8;
assert(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]; for (const auto &a : m_algorithms) {
} if (algorithm == a) {
return true;
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<xmrig::Algo>(i);
} }
} }
fprintf(stderr, "Unknown algorithm \"%s\" specified.\n", algo); return false;
return xmrig::INVALID_ALGO; }
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()) { if (!isValid()) {
return; return;
} }
m_algo = algo; if (!m_algorithm.isValid()) {
m_algorithm.setAlgo(algorithm);
}
if (strstr(m_host.data(), ".nicehash.com")) { if (strstr(m_host.data(), ".nicehash.com")) {
m_keepAlive = false; m_keepAlive = false;
m_nicehash = true; m_nicehash = true;
if (strstr(m_host.data(), "cryptonightv7.")) {
m_algorithm.setVariant(xmrig::VARIANT_1);
}
} }
if (strstr(m_host.data(), ".minergate.com")) { if (strstr(m_host.data(), ".minergate.com")) {
m_keepAlive = false; 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) { LOG_NOTICE("url: %s", m_url.data());
case xmrig::VARIANT_AUTO: LOG_DEBUG ("host: %s", m_host.data());
case xmrig::VARIANT_NONE: LOG_DEBUG ("port: %d", static_cast<int>(m_port));
case xmrig::VARIANT_V1: LOG_DEBUG ("user: %s", m_user.data());
m_variant = static_cast<xmrig::Variant>(variant); LOG_DEBUG ("pass: %s", m_password.data());
break; LOG_DEBUG ("rig-id %s", m_rigId.data());
LOG_DEBUG ("algo: %s", m_algorithm.name());
default: LOG_DEBUG ("nicehash: %d", static_cast<int>(m_nicehash));
assert(false); LOG_DEBUG ("keepAlive: %d", m_keepAlive);
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);
} }
#endif
bool Pool::parseIPv6(const char *addr) bool Pool::parseIPv6(const char *addr)
@ -278,3 +288,14 @@ bool Pool::parseIPv6(const char *addr)
return true; 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);
}

View file

@ -25,11 +25,12 @@
#define __POOL_H__ #define __POOL_H__
#include <stdint.h> #include <vector>
#include "common/crypto/Algorithm.h"
#include "common/utils/c_str.h" #include "common/utils/c_str.h"
#include "common/xmrig.h" #include "rapidjson/fwd.h"
class Pool class Pool
@ -47,50 +48,58 @@ public:
const char *user = nullptr, const char *user = nullptr,
const char *password = nullptr, const char *password = nullptr,
int keepAlive = 0, int keepAlive = 0,
bool nicehash = false, bool nicehash = false
xmrig::Variant variant = xmrig::VARIANT_AUTO
); );
static const char *algoName(xmrig::Algo algorithm); inline bool isNicehash() const { return m_nicehash; }
static xmrig::Algo algorithm(const char *algo); inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
inline const char *host() const { return m_host.data(); }
inline bool isNicehash() const { return m_nicehash; } inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; } inline const char *rigId() const { return m_rigId.data(); }
inline const char *host() const { return m_host.data(); } inline const char *url() const { return m_url.data(); }
inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; }
inline const char *url() const { return m_url.data(); } inline const xmrig::Algorithm &algorithm() const { return m_algorithm; }
inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } inline const xmrig::Algorithms &algorithms() const { return m_algorithms; }
inline int keepAlive() const { return m_keepAlive; } inline int keepAlive() const { return m_keepAlive; }
inline uint16_t port() const { return m_port; } inline uint16_t port() const { return m_port; }
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
inline void setPassword(const char *password) { m_password = password; } inline void setPassword(const char *password) { m_password = password; }
inline void setUser(const char *user) { m_user = user; } inline void setRigId(const char *rigId) { m_rigId = rigId; }
inline xmrig::Algo algo() const { return m_algo; } inline void setUser(const char *user) { m_user = user; }
inline xmrig::Variant variant() const { return m_variant; } 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); }
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 parse(const char *url);
bool setUserpass(const char *userpass); bool setUserpass(const char *userpass);
void adjust(xmrig::Algo algo); rapidjson::Value toJSON(rapidjson::Document &doc) const;
void setVariant(int variant); void adjust(xmrig::Algo algorithm);
bool isEqual(const Pool &other) const; # ifdef APP_DEBUG
void print() const;
# endif
private: private:
bool parseIPv6(const char *addr); bool parseIPv6(const char *addr);
void addVariant(xmrig::Variant variant);
bool m_nicehash; bool m_nicehash;
int m_keepAlive; int m_keepAlive;
uint16_t m_port; 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_host;
xmrig::c_str m_password; xmrig::c_str m_password;
xmrig::c_str m_rigId;
xmrig::c_str m_url; xmrig::c_str m_url;
xmrig::c_str m_user; xmrig::c_str m_user;
xmrig::Variant m_variant;
}; };
typedef std::vector<Pool> Pools;
#endif /* __POOL_H__ */ #endif /* __POOL_H__ */

View file

@ -28,8 +28,6 @@
#include <assert.h> #include <assert.h>
#include <map> #include <map>
#include "log/Log.h"
namespace xmrig { namespace xmrig {

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -25,10 +25,11 @@
#include <uv.h> #include <uv.h>
#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), seq(seq),
diff(diff), diff(diff),
actualDiff(actualDiff), actualDiff(actualDiff),

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -31,11 +31,12 @@
class SubmitResult class SubmitResult
{ {
public: public:
inline SubmitResult() : seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {} inline SubmitResult() : reqId(0), seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {}
SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff); SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId = 0);
void done(); void done();
int64_t reqId;
int64_t seq; int64_t seq;
uint32_t diff; uint32_t diff;
uint64_t actualDiff; uint64_t actualDiff;

View file

@ -22,10 +22,10 @@
*/ */
#include "common/net/Client.h"
#include "common/net/strategies/FailoverStrategy.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "interfaces/IStrategyListener.h" #include "interfaces/IStrategyListener.h"
#include "net/Client.h"
#include "net/strategies/FailoverStrategy.h"
FailoverStrategy::FailoverStrategy(const std::vector<Pool> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) : FailoverStrategy::FailoverStrategy(const std::vector<Pool> &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 *client = new Client((int) m_pools.size(), Platform::userAgent(), this);
client->setPool(pool); client->setPool(pool);
client->setRetries(m_retries);
client->setRetryPause(m_retryPause * 1000); client->setRetryPause(m_retryPause * 1000);
client->setQuiet(m_quiet); client->setQuiet(m_quiet);

View file

@ -28,9 +28,9 @@
#include <vector> #include <vector>
#include "common/net/Pool.h"
#include "interfaces/IClientListener.h" #include "interfaces/IClientListener.h"
#include "interfaces/IStrategy.h" #include "interfaces/IStrategy.h"
#include "net/Pool.h"
class Client; class Client;

View file

@ -22,18 +22,19 @@
*/ */
#include "common/net/Client.h"
#include "common/net/strategies/SinglePoolStrategy.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "interfaces/IStrategyListener.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_active(false),
m_listener(listener) m_listener(listener)
{ {
m_client = new Client(0, Platform::userAgent(), this); m_client = new Client(0, Platform::userAgent(), this);
m_client->setPool(pool); m_client->setPool(pool);
m_client->setRetries(retries);
m_client->setRetryPause(retryPause * 1000); m_client->setRetryPause(retryPause * 1000);
m_client->setQuiet(quiet); m_client->setQuiet(quiet);
} }

View file

@ -37,7 +37,7 @@ class Url;
class SinglePoolStrategy : public IStrategy, public IClientListener class SinglePoolStrategy : public IStrategy, public IClientListener
{ {
public: 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(); ~SinglePoolStrategy();
public: public:

View file

@ -68,7 +68,7 @@ public:
inline bool isEqual(const char *str) const 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);
} }

View file

@ -33,7 +33,7 @@ enum Algo {
INVALID_ALGO = -1, INVALID_ALGO = -1,
CRYPTONIGHT, /* CryptoNight (Monero) */ CRYPTONIGHT, /* CryptoNight (Monero) */
CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
CRYPTONIGHT_HEAVY, /* CryptoNight-Heavy (SUMO) */ CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (SUMO) */
}; };
@ -59,8 +59,10 @@ enum AlgoVariant {
enum Variant { enum Variant {
VARIANT_AUTO = -1, // Autodetect VARIANT_AUTO = -1, // Autodetect
VARIANT_NONE = 0, // Original CryptoNight VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy
VARIANT_V1 = 1 // Monero v7 PoW 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)
}; };

View file

@ -31,7 +31,6 @@
#include "core/ConfigCreator.h" #include "core/ConfigCreator.h"
#include "Cpu.h" #include "Cpu.h"
#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_constants.h"
#include "net/Pool.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
@ -72,7 +71,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
auto &allocator = doc.GetAllocator(); auto &allocator = doc.GetAllocator();
doc.AddMember("algo", StringRef(algoName()), allocator); doc.AddMember("algo", StringRef(algorithm().name()), allocator);
Value api(kObjectType); Value api(kObjectType);
api.AddMember("port", apiPort(), allocator); api.AddMember("port", apiPort(), allocator);
@ -103,24 +102,8 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
Value pools(kArrayType); Value pools(kArrayType);
for (const Pool &pool : m_pools) { for (const Pool &pool : m_activePools) {
Value obj(kObjectType); pools.PushBack(pool.toJSON(doc), allocator);
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);
} }
doc.AddMember("pools", pools, 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; 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; 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) { 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; return true;
@ -178,7 +165,7 @@ bool xmrig::Config::adjust()
m_algoVariant = getAlgoVariant(); m_algoVariant = getAlgoVariant();
m_threads.mode = m_threads.count ? Simple : Automatic; 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) { if (!m_threads.count) {
m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); 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) { 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; return true;
@ -351,7 +338,7 @@ bool xmrig::Config::parseInt(int key, int arg)
xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const
{ {
# ifndef XMRIG_NO_AEON # ifndef XMRIG_NO_AEON
if (m_algorithm == xmrig::CRYPTONIGHT_LITE) { if (m_algorithm.algo() == xmrig::CRYPTONIGHT_LITE) {
return getAlgoVariantLite(); return getAlgoVariantLite();
} }
# endif # endif

View file

@ -88,7 +88,7 @@ public:
static Config *load(int argc, char **argv, IWatcherListener *listener); static Config *load(int argc, char **argv, IWatcherListener *listener);
protected: protected:
bool adjust() override; bool finalize() override;
bool parseBoolean(int key, bool enable) override; bool parseBoolean(int key, bool enable) override;
bool parseString(int key, const char *arg) override; bool parseString(int key, const char *arg) override;
bool parseUint64(int key, uint64_t arg) override; bool parseUint64(int key, uint64_t arg) override;

View file

@ -58,6 +58,7 @@ Options:\n\
-O, --userpass=U:P username:password pair for mining server\n\ -O, --userpass=U:P username:password pair for mining server\n\
-u, --user=USERNAME username for mining server\n\ -u, --user=USERNAME username for mining server\n\
-p, --pass=PASSWORD password 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\ -t, --threads=N number of miner threads\n\
-v, --av=N algorithm variation, 0 auto select\n\ -v, --av=N algorithm variation, 0 auto select\n\
-k, --keepalive send keepalived for prevent timeout (need pool support)\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", 1, nullptr, xmrig::IConfig::UserKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
{ "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey },
{ "version", 0, nullptr, xmrig::IConfig::VersionKey }, { "version", 0, nullptr, xmrig::IConfig::VersionKey },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
@ -165,6 +167,7 @@ static struct option const pool_options[] = {
{ "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey }, { "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey },
{ "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey }, { "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey },
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey }, { "variant", 1, nullptr, xmrig::IConfig::VariantKey },
{ "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };

View file

@ -26,19 +26,19 @@
#include "common/config/ConfigLoader.h" #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 "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h" #include "Cpu.h"
#include "interfaces/IControllerListener.h" #include "interfaces/IControllerListener.h"
#include "log/ConsoleLog.h"
#include "log/FileLog.h"
#include "log/Log.h"
#include "net/Network.h" #include "net/Network.h"
#ifdef HAVE_SYSLOG_H #ifdef HAVE_SYSLOG_H
# include "log/SysLog.h" # include "common/log/SysLog.h"
#endif #endif

View file

@ -53,6 +53,7 @@ template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT>() { retur
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_MEMORY; } template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_MEMORY; }
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_MEMORY; } template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_MEMORY; }
inline size_t cn_select_memory(Algo algorithm) inline size_t cn_select_memory(Algo algorithm)
{ {
switch(algorithm) switch(algorithm)
@ -79,6 +80,7 @@ template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT>() { retur
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_MASK; } template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_MASK; }
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_MASK; } template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_MASK; }
inline uint32_t cn_select_mask(Algo algorithm) inline uint32_t cn_select_mask(Algo algorithm)
{ {
switch(algorithm) switch(algorithm)
@ -105,6 +107,7 @@ template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT>() { retur
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_ITER; }
inline uint32_t cn_select_iter(Algo algorithm) inline uint32_t cn_select_iter(Algo algorithm)
{ {
switch(algorithm) switch(algorithm)

View file

@ -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 #ifndef XMRIG_NO_AEON
const static uint8_t test_output_v0_lite[160] = { 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, 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, 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 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 #endif

View file

@ -34,6 +34,7 @@
#endif #endif
#include "common/crypto/keccak.h"
#include "crypto/CryptoNight.h" #include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_constants.h"
#include "crypto/CryptoNight_monero.h" #include "crypto/CryptoNight_monero.h"
@ -42,7 +43,6 @@
extern "C" extern "C"
{ {
#include "crypto/c_keccak.h"
#include "crypto/c_groestl.h" #include "crypto/c_groestl.h"
#include "crypto/c_blake256.h" #include "crypto/c_blake256.h"
#include "crypto/c_jh.h" #include "crypto/c_jh.h"
@ -386,6 +386,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
} }
template<int SHIFT>
static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp)
{ {
mem_out[0] = EXTRACT64(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; uint8_t x = vh >> 24;
static const uint16_t table = 0x7531; 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; vh ^= ((table >> index) & 0x3) << 28;
mem_out[1] = vh; mem_out[1] = vh;
@ -414,7 +415,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
return; return;
} }
keccak(input, (int) size, ctx[0]->state, 200); xmrig::keccak(input, size, ctx[0]->state);
VARIANT1_INIT(0) VARIANT1_INIT(0)
@ -441,7 +442,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
} }
if (VARIANT > 0) { if (VARIANT > 0) {
cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
} else { } else {
_mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); _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; al0 += hi;
ah0 += lo; ah0 += lo;
VARIANT1_2(ah0, 0);
((uint64_t*)&l0[idx0 & MASK])[0] = al0; ((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; al0 ^= cl;
ah0 ^= ch;
idx0 = al0; idx0 = al0;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { 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<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__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); 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; return;
} }
keccak(input, (int) size, ctx[0]->state, 200); xmrig::keccak(input, size, ctx[0]->state);
keccak(input + size, (int) size, ctx[1]->state, 200); xmrig::keccak(input + size, size, ctx[1]->state);
VARIANT1_INIT(0); VARIANT1_INIT(0);
VARIANT1_INIT(1); VARIANT1_INIT(1);
@ -535,8 +545,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
} }
if (VARIANT > 0) { if (VARIANT > 0) {
cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((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<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
} else { } else {
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); _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; al0 += hi;
ah0 += lo; ah0 += lo;
VARIANT1_2(ah0, 0); ((uint64_t*)&l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0; if (VARIANT > 0) {
VARIANT1_2(ah0, 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; al0 ^= cl;
ah0 ^= ch;
idx0 = al0; idx0 = al0;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
@ -581,13 +600,22 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
al1 += hi; al1 += hi;
ah1 += lo; ah1 += lo;
VARIANT1_2(ah1, 1); ((uint64_t*)&l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1; if (VARIANT > 0) {
VARIANT1_2(ah1, 1); 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; al1 ^= cl;
ah1 ^= ch;
idx1 = al1; idx1 = al1;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { 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<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
keccakf(h0, 24); xmrig::keccakf(h0, 24);
keccakf(h1, 24); xmrig::keccakf(h1, 24);
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); 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); 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); \ b = _mm_xor_si128(b, c); \
\ \
if (VARIANT > 0) { \ if (VARIANT > 0) { \
cryptonight_monero_tweak(reinterpret_cast<uint64_t*>(ptr), b); \ cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>(reinterpret_cast<uint64_t*>(ptr), b); \
} else { \ } else { \
_mm_store_si128(ptr, b); \ _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) { \ if (VARIANT > 0) { \
_mm_store_si128(ptr, _mm_xor_si128(a, mc)); \ _mm_store_si128(ptr, _mm_xor_si128(a, mc)); \
\
if (VARIANT == xmrig::VARIANT_IPBC) { \
((uint64_t*)ptr)[1] ^= ((uint64_t*)ptr)[0]; \
} \
} else { \ } else { \
_mm_store_si128(ptr, a); \ _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++) { for (size_t i = 0; i < 3; i++) {
keccak(input + size * i, static_cast<int>(size), ctx[i]->state, 200); xmrig::keccak(input + size * i, size, ctx[i]->state);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(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++) { for (size_t i = 0; i < 3; i++) {
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24); xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); 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++) { for (size_t i = 0; i < 4; i++) {
keccak(input + size * i, static_cast<int>(size), ctx[i]->state, 200); xmrig::keccak(input + size * i, size, ctx[i]->state);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(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++) { for (size_t i = 0; i < 4; i++) {
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24); xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); 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++) { for (size_t i = 0; i < 5; i++) {
keccak(input + size * i, static_cast<int>(size), ctx[i]->state, 200); xmrig::keccak(input + size * i, size, ctx[i]->state);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(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++) { for (size_t i = 0; i < 5; i++) {
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24); xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
} }
} }

View file

@ -1,26 +0,0 @@
// keccak.h
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
#ifndef KECCAK_H
#define KECCAK_H
#include <stdint.h>
#include <string.h>
#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

View file

@ -36,30 +36,31 @@ public:
enum Keys { enum Keys {
// common // common
AlgorithmKey = 'a', AlgorithmKey = 'a',
ApiPort = 4000,
ApiAccessTokenKey = 4001, ApiAccessTokenKey = 4001,
ApiWorkerIdKey = 4002,
ApiIPv6Key = 4003, ApiIPv6Key = 4003,
ApiPort = 4000,
ApiRestrictedKey = 4004, ApiRestrictedKey = 4004,
ApiWorkerIdKey = 4002,
BackgroundKey = 'B', BackgroundKey = 'B',
ColorKey = 1002,
ConfigKey = 'c', ConfigKey = 'c',
DonateLevelKey = 1003, DonateLevelKey = 1003,
HelpKey = 'h', HelpKey = 'h',
KeepAliveKey = 'k', KeepAliveKey = 'k',
LogFileKey = 'l', LogFileKey = 'l',
ColorKey = 1002,
WatchKey = 1105,
PasswordKey = 'p', PasswordKey = 'p',
RetriesKey = 'r', RetriesKey = 'r',
RetryPauseKey = 'R', RetryPauseKey = 'R',
RigIdKey = 1012,
SyslogKey = 'S', SyslogKey = 'S',
UrlKey = 'o', UrlKey = 'o',
UserKey = 'u',
UserAgentKey = 1008, UserAgentKey = 1008,
UserKey = 'u',
UserpassKey = 'O', UserpassKey = 'O',
VariantKey = 1010,
VerboseKey = 1100, VerboseKey = 1100,
VersionKey = 'V', VersionKey = 'V',
VariantKey = 1010, WatchKey = 1105,
// xmrig common // xmrig common
CPUPriorityKey = 1021, CPUPriorityKey = 1021,
@ -90,8 +91,7 @@ public:
virtual ~IConfig() {} virtual ~IConfig() {}
virtual bool adjust() = 0; virtual bool finalize() = 0;
virtual bool isValid() const = 0;
virtual bool isWatch() const = 0; virtual bool isWatch() const = 0;
virtual bool parseBoolean(int key, bool enable) = 0; virtual bool parseBoolean(int key, bool enable) = 0;
virtual bool parseString(int key, const char *arg) = 0; virtual bool parseString(int key, const char *arg) = 0;

View file

@ -29,41 +29,24 @@
#include <stdint.h> #include <stdint.h>
#include "Job.h" #include "common/net/Job.h"
class JobResult class JobResult
{ {
public: public:
inline JobResult() : poolId(0), diff(0), nonce(0) {} 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), poolId(poolId),
diff(diff), diff(diff),
nonce(nonce), nonce(nonce),
algorithm(algorithm),
jobId(jobId) jobId(jobId)
{ {
memcpy(this->result, result, sizeof(this->result)); 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 inline uint64_t actualDiff() const
{ {
return Job::toDiff(reinterpret_cast<const uint64_t*>(result)[3]); return Job::toDiff(reinterpret_cast<const uint64_t*>(result)[3]);
@ -74,6 +57,7 @@ public:
uint32_t diff; uint32_t diff;
uint32_t nonce; uint32_t nonce;
uint8_t result[32]; uint8_t result[32];
xmrig::Algorithm algorithm;
xmrig::Id jobId; xmrig::Id jobId;
}; };

View file

@ -31,16 +31,16 @@
#include "api/Api.h" #include "api/Api.h"
#include "log/Log.h" #include "common/log/Log.h"
#include "net/Client.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/Network.h"
#include "net/strategies/DonateStrategy.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 "workers/Workers.h"
#include "core/Controller.h"
#include "core/Config.h"
Network::Network(xmrig::Controller *controller) : 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); m_strategy = new FailoverStrategy(pools, controller->config()->retryPause(), controller->config()->retries(), this);
} }
else { 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) { 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; m_timer.data = this;
@ -166,12 +166,9 @@ bool Network::isColors() const
void Network::setJob(Client *client, const Job &job, bool donate) void Network::setJob(Client *client, const Job &job, bool donate)
{ {
if (isColors()) { LOG_INFO(isColors() ? MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s")
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()); : "new job from %s:%d diff %d algo %s",
} client->host(), client->port(), job.diff(), job.algorithm().shortName());
else {
LOG_INFO("new job from %s:%d diff %d", client->host(), client->port(), job.diff());
}
m_state.diff = job.diff(); m_state.diff = job.diff();
Workers::setJob(job, donate); Workers::setJob(job, donate);

View file

@ -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/Platform.h"
#include "common/xmrig.h" #include "common/xmrig.h"
#include "interfaces/IStrategyListener.h" #include "interfaces/IStrategyListener.h"
#include "net/Client.h"
#include "net/Job.h"
#include "net/strategies/DonateStrategy.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"; 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_active(false),
m_donateTime(level * 60 * 1000), m_donateTime(level * 60 * 1000),
m_idleTime((100 - 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]; uint8_t hash[200];
char userId[65] = { 0 }; char userId[65] = { 0 };
keccak(reinterpret_cast<const uint8_t *>(user), static_cast<int>(strlen(user)), hash, sizeof(hash)); xmrig::keccak(reinterpret_cast<const uint8_t *>(user), strlen(user), hash);
Job::toHex(hash, 32, userId); Job::toHex(hash, 32, userId);
if (algo == xmrig::CRYPTONIGHT) { if (algo == xmrig::CRYPTONIGHT) {
@ -66,14 +62,21 @@ DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyL
} }
else if (algo == xmrig::CRYPTONIGHT_HEAVY) { else if (algo == xmrig::CRYPTONIGHT_HEAVY) {
m_pools.push_back(Pool(kDonatePool1, 8888, userId, nullptr, false, true)); m_pools.push_back(Pool(kDonatePool1, 8888, userId, nullptr, false, true));
m_pools.push_back(Pool(kDonatePool1, 8889, userId, nullptr, false, true));
} }
else { else {
m_pools.push_back(Pool(kDonatePool1, 5555, userId, nullptr, false, true)); 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; m_timer.data = this;
uv_timer_init(uv_default_loop(), &m_timer); uv_timer_init(uv_default_loop(), &m_timer);

View file

@ -29,10 +29,10 @@
#include <vector> #include <vector>
#include "common/net/Pool.h"
#include "interfaces/IClientListener.h" #include "interfaces/IClientListener.h"
#include "interfaces/IStrategy.h" #include "interfaces/IStrategy.h"
#include "interfaces/IStrategyListener.h" #include "interfaces/IStrategyListener.h"
#include "net/Pool.h"
class Client; class Client;
@ -43,7 +43,7 @@ class Url;
class DonateStrategy : public IStrategy, public IStrategyListener class DonateStrategy : public IStrategy, public IStrategyListener
{ {
public: public:
DonateStrategy(int level, const char *user, int algo, IStrategyListener *listener); DonateStrategy(int level, const char *user, xmrig::Algo algo, IStrategyListener *listener);
~DonateStrategy(); ~DonateStrategy();
public: public:

View file

@ -24,7 +24,7 @@
#include <assert.h> #include <assert.h>
#include "net/Pool.h" #include "common/net/Pool.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "workers/CpuThread.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) 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] = { static const cn_hash_fun func_table[90] = {
cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_NONE>, cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_0>,
cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_NONE>, cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_0>,
cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_NONE>, cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_0>,
cryptonight_double_hash<CRYPTONIGHT, true, VARIANT_NONE>, cryptonight_double_hash<CRYPTONIGHT, true, VARIANT_0>,
cryptonight_triple_hash<CRYPTONIGHT, false, VARIANT_NONE>, cryptonight_triple_hash<CRYPTONIGHT, false, VARIANT_0>,
cryptonight_quad_hash<CRYPTONIGHT, false, VARIANT_NONE>, cryptonight_quad_hash<CRYPTONIGHT, false, VARIANT_0>,
cryptonight_penta_hash<CRYPTONIGHT, false, VARIANT_NONE>, cryptonight_penta_hash<CRYPTONIGHT, false, VARIANT_0>,
cryptonight_triple_hash<CRYPTONIGHT, true, VARIANT_NONE>, cryptonight_triple_hash<CRYPTONIGHT, true, VARIANT_0>,
cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_NONE>, cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_0>,
cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_NONE>, cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_0>,
cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_V1>, cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_1>,
cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_V1>, cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_1>,
cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_V1>, cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_1>,
cryptonight_double_hash<CRYPTONIGHT, true, VARIANT_V1>, cryptonight_double_hash<CRYPTONIGHT, true, VARIANT_1>,
cryptonight_triple_hash<CRYPTONIGHT, false, VARIANT_V1>, cryptonight_triple_hash<CRYPTONIGHT, false, VARIANT_1>,
cryptonight_quad_hash<CRYPTONIGHT, false, VARIANT_V1>, cryptonight_quad_hash<CRYPTONIGHT, false, VARIANT_1>,
cryptonight_penta_hash<CRYPTONIGHT, false, VARIANT_V1>, cryptonight_penta_hash<CRYPTONIGHT, false, VARIANT_1>,
cryptonight_triple_hash<CRYPTONIGHT, true, VARIANT_V1>, cryptonight_triple_hash<CRYPTONIGHT, true, VARIANT_1>,
cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_V1>, cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_1>,
cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_V1>, cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_1>,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_XTL>,
cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_XTL>,
cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_XTL>,
cryptonight_double_hash<CRYPTONIGHT, true, VARIANT_XTL>,
cryptonight_triple_hash<CRYPTONIGHT, false, VARIANT_XTL>,
cryptonight_quad_hash<CRYPTONIGHT, false, VARIANT_XTL>,
cryptonight_penta_hash<CRYPTONIGHT, false, VARIANT_XTL>,
cryptonight_triple_hash<CRYPTONIGHT, true, VARIANT_XTL>,
cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_XTL>,
cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_XTL>,
# ifndef XMRIG_NO_AEON # ifndef XMRIG_NO_AEON
cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_NONE>, cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_NONE>, cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
cryptonight_single_hash<CRYPTONIGHT_LITE, true, VARIANT_NONE>, cryptonight_single_hash<CRYPTONIGHT_LITE, true, VARIANT_0>,
cryptonight_double_hash<CRYPTONIGHT_LITE, true, VARIANT_NONE>, cryptonight_double_hash<CRYPTONIGHT_LITE, true, VARIANT_0>,
cryptonight_triple_hash<CRYPTONIGHT_LITE, false, VARIANT_NONE>, cryptonight_triple_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
cryptonight_quad_hash<CRYPTONIGHT_LITE, false, VARIANT_NONE>, cryptonight_quad_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
cryptonight_penta_hash<CRYPTONIGHT_LITE, false, VARIANT_NONE>, cryptonight_penta_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
cryptonight_triple_hash<CRYPTONIGHT_LITE, true, VARIANT_NONE>, cryptonight_triple_hash<CRYPTONIGHT_LITE, true, VARIANT_0>,
cryptonight_quad_hash<CRYPTONIGHT_LITE, true, VARIANT_NONE>, cryptonight_quad_hash<CRYPTONIGHT_LITE, true, VARIANT_0>,
cryptonight_penta_hash<CRYPTONIGHT_LITE, true, VARIANT_NONE>, cryptonight_penta_hash<CRYPTONIGHT_LITE, true, VARIANT_0>,
cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_V1>, cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_1>,
cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_V1>, cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_1>,
cryptonight_single_hash<CRYPTONIGHT_LITE, true, VARIANT_V1>, cryptonight_single_hash<CRYPTONIGHT_LITE, true, VARIANT_1>,
cryptonight_double_hash<CRYPTONIGHT_LITE, true, VARIANT_V1>, cryptonight_double_hash<CRYPTONIGHT_LITE, true, VARIANT_1>,
cryptonight_triple_hash<CRYPTONIGHT_LITE, false, VARIANT_V1>, cryptonight_triple_hash<CRYPTONIGHT_LITE, false, VARIANT_1>,
cryptonight_quad_hash<CRYPTONIGHT_LITE, false, VARIANT_V1>, cryptonight_quad_hash<CRYPTONIGHT_LITE, false, VARIANT_1>,
cryptonight_penta_hash<CRYPTONIGHT_LITE, false, VARIANT_V1>, cryptonight_penta_hash<CRYPTONIGHT_LITE, false, VARIANT_1>,
cryptonight_triple_hash<CRYPTONIGHT_LITE, true, VARIANT_V1>, cryptonight_triple_hash<CRYPTONIGHT_LITE, true, VARIANT_1>,
cryptonight_quad_hash<CRYPTONIGHT_LITE, true, VARIANT_V1>, cryptonight_quad_hash<CRYPTONIGHT_LITE, true, VARIANT_1>,
cryptonight_penta_hash<CRYPTONIGHT_LITE, true, VARIANT_V1>, cryptonight_penta_hash<CRYPTONIGHT_LITE, true, VARIANT_1>,
cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_IPBC>,
cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_IPBC>,
cryptonight_single_hash<CRYPTONIGHT_LITE, true, VARIANT_IPBC>,
cryptonight_double_hash<CRYPTONIGHT_LITE, true, VARIANT_IPBC>,
cryptonight_triple_hash<CRYPTONIGHT_LITE, false, VARIANT_IPBC>,
cryptonight_quad_hash<CRYPTONIGHT_LITE, false, VARIANT_IPBC>,
cryptonight_penta_hash<CRYPTONIGHT_LITE, false, VARIANT_IPBC>,
cryptonight_triple_hash<CRYPTONIGHT_LITE, true, VARIANT_IPBC>,
cryptonight_quad_hash<CRYPTONIGHT_LITE, true, VARIANT_IPBC>,
cryptonight_penta_hash<CRYPTONIGHT_LITE, true, VARIANT_IPBC>,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
# else # 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,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
# endif # endif
# ifndef XMRIG_NO_SUMO # ifndef XMRIG_NO_SUMO
cryptonight_single_hash<CRYPTONIGHT_HEAVY, false, VARIANT_NONE>, cryptonight_single_hash<CRYPTONIGHT_HEAVY, false, VARIANT_0>,
cryptonight_double_hash<CRYPTONIGHT_HEAVY, false, VARIANT_NONE>, cryptonight_double_hash<CRYPTONIGHT_HEAVY, false, VARIANT_0>,
cryptonight_single_hash<CRYPTONIGHT_HEAVY, true, VARIANT_NONE>, cryptonight_single_hash<CRYPTONIGHT_HEAVY, true, VARIANT_0>,
cryptonight_double_hash<CRYPTONIGHT_HEAVY, true, VARIANT_NONE>, cryptonight_double_hash<CRYPTONIGHT_HEAVY, true, VARIANT_0>,
cryptonight_triple_hash<CRYPTONIGHT_HEAVY, false, VARIANT_NONE>, cryptonight_triple_hash<CRYPTONIGHT_HEAVY, false, VARIANT_0>,
cryptonight_quad_hash<CRYPTONIGHT_HEAVY, false, VARIANT_NONE>, cryptonight_quad_hash<CRYPTONIGHT_HEAVY, false, VARIANT_0>,
cryptonight_penta_hash<CRYPTONIGHT_HEAVY, false, VARIANT_NONE>, cryptonight_penta_hash<CRYPTONIGHT_HEAVY, false, VARIANT_0>,
cryptonight_triple_hash<CRYPTONIGHT_HEAVY, true, VARIANT_NONE>, cryptonight_triple_hash<CRYPTONIGHT_HEAVY, true, VARIANT_0>,
cryptonight_quad_hash<CRYPTONIGHT_HEAVY, true, VARIANT_NONE>, cryptonight_quad_hash<CRYPTONIGHT_HEAVY, true, VARIANT_0>,
cryptonight_penta_hash<CRYPTONIGHT_HEAVY, true, VARIANT_NONE>, cryptonight_penta_hash<CRYPTONIGHT_HEAVY, true, VARIANT_0>,
# else # else
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
# endif # endif
@ -132,11 +160,22 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
# ifndef XMRIG_NO_SUMO # ifndef XMRIG_NO_SUMO
if (algorithm == CRYPTONIGHT_HEAVY) { if (algorithm == CRYPTONIGHT_HEAVY) {
variant = VARIANT_NONE; variant = VARIANT_0;
} }
# endif # 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(); auto &allocator = doc.GetAllocator();
obj.AddMember("type", "cpu", allocator); obj.AddMember("type", "cpu", allocator);
obj.AddMember("algo", rapidjson::StringRef(Pool::algoName(algorithm())), allocator);
obj.AddMember("av", m_av, allocator); obj.AddMember("av", m_av, allocator);
obj.AddMember("low_power_mode", multiway(), allocator); obj.AddMember("low_power_mode", multiway(), allocator);
obj.AddMember("affine_to_cpu", affinity(), allocator); obj.AddMember("affine_to_cpu", affinity(), allocator);

View file

@ -29,9 +29,9 @@
#include <stdio.h> #include <stdio.h>
#include "common/log/Log.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "log/Log.h"
#include "workers/Hashrate.h" #include "workers/Hashrate.h"

View file

@ -50,23 +50,31 @@ MultiWorker<N>::~MultiWorker()
template<size_t N> template<size_t N>
bool MultiWorker<N>::selfTest() bool MultiWorker<N>::selfTest()
{ {
if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { if (m_thread->fn(xmrig::VARIANT_0) == nullptr) {
return false; 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) { 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 # ifndef XMRIG_NO_AEON
if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, sizeof m_hash) == 0) { 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 # endif
@ -104,7 +112,7 @@ void MultiWorker<N>::start()
for (size_t i = 0; i < N; ++i) { for (size_t i = 0; i < N; ++i) {
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < m_state.job.target()) { if (*reinterpret_cast<uint64_t*>(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; *nonce(i) += 1;

View file

@ -26,8 +26,8 @@
#define __MULTIWORKER_H__ #define __MULTIWORKER_H__
#include "common/net/Job.h"
#include "Mem.h" #include "Mem.h"
#include "net/Job.h"
#include "net/JobResult.h" #include "net/JobResult.h"
#include "workers/Worker.h" #include "workers/Worker.h"

View file

@ -26,12 +26,12 @@
#include "api/Api.h" #include "api/Api.h"
#include "common/log/Log.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_constants.h"
#include "interfaces/IJobResultListener.h" #include "interfaces/IJobResultListener.h"
#include "interfaces/IThread.h" #include "interfaces/IThread.h"
#include "log/Log.h"
#include "Mem.h" #include "Mem.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "workers/Handle.h" #include "workers/Handle.h"
@ -132,8 +132,8 @@ void Workers::setJob(const Job &job, bool donate)
void Workers::start(xmrig::Controller *controller) void Workers::start(xmrig::Controller *controller)
{ {
const std::vector<xmrig::IThread *> &threads = controller->config()->threads(); const std::vector<xmrig::IThread *> &threads = controller->config()->threads();
m_status.algo = controller->config()->algorithm(); m_status.algo = controller->config()->algorithm().algo();
m_status.colors = controller->config()->isHugePages(); m_status.colors = controller->config()->isColors();
m_status.threads = threads.size(); m_status.threads = threads.size();
for (const xmrig::IThread *thread : threads) { 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; const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo) / 1048576;
if (m_status.colors) { 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.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); m_status.hugePages, m_status.pages, percent, memory);
} }
else { else {

View file

@ -30,7 +30,7 @@
#include <uv.h> #include <uv.h>
#include <vector> #include <vector>
#include "net/Job.h" #include "common/net/Job.h"
#include "net/JobResult.h" #include "net/JobResult.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"