Merge branch 'feature-donate-over-proxy' into evo

This commit is contained in:
XMRig 2019-03-20 11:53:18 +07:00
commit 453443a2f1
149 changed files with 6138 additions and 5110 deletions

View file

@ -1,3 +1,24 @@
# v2.14.1
* [#975](https://github.com/xmrig/xmrig/issues/975) Fixed crash on Linux if double thread mode used.
# v2.14.0
- **[#969](https://github.com/xmrig/xmrig/pull/969) Added new algorithm `cryptonight/rwz`, short alias `cn/rwz` (also known as CryptoNight ReverseWaltz), for upcoming [Graft](https://www.graft.network/) fork.**
- **[#931](https://github.com/xmrig/xmrig/issues/931) Added new algorithm `cryptonight/zls`, short alias `cn/zls` for [Zelerius Network](https://zelerius.org) fork.**
- **[#940](https://github.com/xmrig/xmrig/issues/940) Added new algorithm `cryptonight/double`, short alias `cn/double` (also known as CryptoNight HeavyX), for [X-CASH](https://x-cash.org/).**
- [#951](https://github.com/xmrig/xmrig/issues/951#issuecomment-469581529) Fixed crash if AVX was disabled on OS level.
- [#952](https://github.com/xmrig/xmrig/issues/952) Fixed compile error on some Linux.
- [#957](https://github.com/xmrig/xmrig/issues/957#issuecomment-468890667) Added support for embedded config.
- [#958](https://github.com/xmrig/xmrig/pull/958) Fixed incorrect user agent on ARM platforms.
- [#968](https://github.com/xmrig/xmrig/pull/968) Optimized `cn/r` algorithm performance.
# v2.13.1
- [#946](https://github.com/xmrig/xmrig/pull/946) Optimized software AES implementations for CPUs without hardware AES support. `cn/r`, `cn/wow` up to 2.6 times faster, 4-9% improvements for other algorithms.
# v2.13.0
- **[#938](https://github.com/xmrig/xmrig/issues/938) Added support for new algorithm `cryptonight/r`, short alias `cn/r` (also known as CryptoNightR or CryptoNight variant 4), for upcoming [Monero](https://www.getmonero.org/) fork on March 9, thanks [@SChernykh](https://github.com/SChernykh).**
- [#939](https://github.com/xmrig/xmrig/issues/939) Added support for dynamic (runtime) pools reload.
- [#932](https://github.com/xmrig/xmrig/issues/932) Fixed `cn-pico` hashrate drop, regression since v2.11.0.
# v2.12.0 # v2.12.0
- [#929](https://github.com/xmrig/xmrig/pull/929) Added support for new algorithm `cryptonight/wow`, short alias `cn/wow` (also known as CryptonightR), for upcoming [Wownero](http://wownero.org) fork on February 14. - [#929](https://github.com/xmrig/xmrig/pull/929) Added support for new algorithm `cryptonight/wow`, short alias `cn/wow` (also known as CryptonightR), for upcoming [Wownero](http://wownero.org) fork on February 14.

View file

@ -1,69 +1,47 @@
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
project(xmrig) 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_CN_PICO "CryptoNight-Pico support" ON) option(WITH_CN_PICO "CryptoNight-Pico support" ON)
option(WITH_CN_GPU "CryptoNight-GPU support" ON) option(WITH_CN_GPU "CryptoNight-GPU support" ON)
option(WITH_HTTPD "HTTP REST API" ON) option(WITH_HTTPD "HTTP REST API" ON)
option(WITH_DEBUG_LOG "Enable debug log output" OFF) option(WITH_DEBUG_LOG "Enable debug log output" OFF)
option(WITH_TLS "Enable OpenSSL support" ON) option(WITH_TLS "Enable OpenSSL support" ON)
option(WITH_ASM "Enable ASM PoW implementations" ON) option(WITH_ASM "Enable ASM PoW implementations" ON)
option(BUILD_STATIC "Build static binary" OFF) option(BUILD_STATIC "Build static binary" OFF)
option(ARM_TARGET "Force use specific ARM target 8 or 7" 0) option(ARM_TARGET "Force use specific ARM target 8 or 7" 0)
option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF)
include (CheckIncludeFile) include (CheckIncludeFile)
include (cmake/cpu.cmake) include (cmake/cpu.cmake)
include (src/base/base.cmake)
set(HEADERS set(HEADERS
"${HEADERS_BASE}"
src/api/NetworkState.h src/api/NetworkState.h
src/App.h src/App.h
src/base/io/Json.h
src/base/io/Watcher.h
src/base/kernel/interfaces/IConfigListener.h
src/base/kernel/interfaces/ISignalListener.h
src/base/kernel/interfaces/IWatcherListener.h
src/base/kernel/Entry.h
src/base/kernel/Process.h
src/base/kernel/Signals.h
src/base/net/Pool.h
src/base/net/Pools.h
src/base/tools/Arguments.h
src/base/tools/Handle.h
src/base/tools/String.h
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/cpu/Cpu.h src/common/cpu/Cpu.h
src/common/crypto/Algorithm.h src/common/crypto/Algorithm.h
src/common/crypto/keccak.h src/common/crypto/keccak.h
src/common/interfaces/IClientListener.h
src/common/interfaces/IConfig.h src/common/interfaces/IConfig.h
src/common/interfaces/IConfigCreator.h src/common/interfaces/IConfigCreator.h
src/common/interfaces/IConsoleListener.h
src/common/interfaces/IControllerListener.h src/common/interfaces/IControllerListener.h
src/common/interfaces/ICpuInfo.h src/common/interfaces/ICpuInfo.h
src/common/interfaces/ILogBackend.h src/common/interfaces/ILogBackend.h
src/common/interfaces/IStrategy.h
src/common/interfaces/IStrategyListener.h
src/common/log/BasicLog.h src/common/log/BasicLog.h
src/common/log/ConsoleLog.h src/common/log/ConsoleLog.h
src/common/log/FileLog.h src/common/log/FileLog.h
src/common/log/Log.h src/common/log/Log.h
src/common/net/Client.h
src/common/net/Id.h
src/common/net/Job.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/mm_malloc.h src/common/utils/mm_malloc.h
src/common/xmrig.h src/common/xmrig.h
src/core/ConfigLoader_default.h
src/core/ConfigLoader_platform.h src/core/ConfigLoader_platform.h
src/core/Controller.h src/core/Controller.h
src/interfaces/IJobResultListener.h src/interfaces/IJobResultListener.h
@ -76,7 +54,7 @@ set(HEADERS
src/Summary.h src/Summary.h
src/version.h src/version.h
src/workers/CpuThread.h src/workers/CpuThread.h
src/workers/Handle.h src/workers/ThreadHandle.h
src/workers/Hashrate.h src/workers/Hashrate.h
src/workers/MultiWorker.h src/workers/MultiWorker.h
src/workers/Worker.h src/workers/Worker.h
@ -106,33 +84,18 @@ else()
endif() endif()
set(SOURCES set(SOURCES
"${SOURCES_BASE}"
src/api/NetworkState.cpp src/api/NetworkState.cpp
src/App.cpp src/App.cpp
src/base/io/Json.cpp
src/base/io/Watcher.cpp
src/base/kernel/Entry.cpp
src/base/kernel/Process.cpp
src/base/kernel/Signals.cpp
src/base/net/Pool.cpp
src/base/net/Pools.cpp
src/base/tools/Arguments.cpp
src/base/tools/Handle.cpp
src/base/tools/String.cpp
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/Algorithm.cpp
src/common/crypto/keccak.cpp src/common/crypto/keccak.cpp
src/common/log/BasicLog.cpp src/common/log/BasicLog.cpp
src/common/log/ConsoleLog.cpp src/common/log/ConsoleLog.cpp
src/common/log/FileLog.cpp src/common/log/FileLog.cpp
src/common/log/Log.cpp src/common/log/Log.cpp
src/common/net/Client.cpp
src/common/net/Job.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/core/Config.cpp src/core/Config.cpp
src/core/Controller.cpp src/core/Controller.cpp
@ -141,7 +104,7 @@ set(SOURCES
src/net/strategies/DonateStrategy.cpp src/net/strategies/DonateStrategy.cpp
src/Summary.cpp src/Summary.cpp
src/workers/CpuThread.cpp src/workers/CpuThread.cpp
src/workers/Handle.cpp src/workers/ThreadHandle.cpp
src/workers/Hashrate.cpp src/workers/Hashrate.cpp
src/workers/MultiWorker.cpp src/workers/MultiWorker.cpp
src/workers/Worker.cpp src/workers/Worker.cpp
@ -154,14 +117,13 @@ set(SOURCES_CRYPTO
src/crypto/c_blake256.c src/crypto/c_blake256.c
src/crypto/c_jh.c src/crypto/c_jh.c
src/crypto/c_skein.c src/crypto/c_skein.c
src/crypto/CryptonightR_gen.cpp
) )
if (WIN32) if (WIN32)
set(SOURCES_OS set(SOURCES_OS
"${SOURCES_OS}"
res/app.rc res/app.rc
src/App_win.cpp src/App_win.cpp
src/base/io/Json_win.cpp
src/common/Platform_win.cpp src/common/Platform_win.cpp
src/Mem_win.cpp src/Mem_win.cpp
) )
@ -170,15 +132,15 @@ if (WIN32)
set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv) set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv)
elseif (APPLE) elseif (APPLE)
set(SOURCES_OS set(SOURCES_OS
"${SOURCES_OS}"
src/App_unix.cpp src/App_unix.cpp
src/base/io/Json_unix.cpp
src/common/Platform_mac.cpp src/common/Platform_mac.cpp
src/Mem_unix.cpp src/Mem_unix.cpp
) )
else() else()
set(SOURCES_OS set(SOURCES_OS
"${SOURCES_OS}"
src/App_unix.cpp src/App_unix.cpp
src/base/io/Json_unix.cpp
src/common/Platform_unix.cpp src/common/Platform_unix.cpp
src/Mem_unix.cpp src/Mem_unix.cpp
) )
@ -249,6 +211,10 @@ if (NOT WITH_CN_PICO)
add_definitions(/DXMRIG_NO_CN_PICO) add_definitions(/DXMRIG_NO_CN_PICO)
endif() endif()
if (WITH_EMBEDDED_CONFIG)
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
endif()
if (WITH_HTTPD) if (WITH_HTTPD)
find_package(MHD) find_package(MHD)

View file

@ -11,14 +11,18 @@ if (WITH_TLS)
find_package(OpenSSL) find_package(OpenSSL)
if (OPENSSL_FOUND) if (OPENSSL_FOUND)
set(TLS_SOURCES src/common/net/Tls.h src/common/net/Tls.cpp) set(TLS_SOURCES src/base/net/stratum/Tls.h src/base/net/stratum/Tls.cpp)
include_directories(${OPENSSL_INCLUDE_DIR}) include_directories(${OPENSSL_INCLUDE_DIR})
else() else()
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support") message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
endif() endif()
add_definitions(/DXMRIG_FEATURE_TLS)
remove_definitions(/DXMRIG_NO_TLS)
else() else()
set(TLS_SOURCES "") set(TLS_SOURCES "")
set(OPENSSL_LIBRARIES "") set(OPENSSL_LIBRARIES "")
remove_definitions(/DXMRIG_FEATURE_TLS)
add_definitions(/DXMRIG_NO_TLS) add_definitions(/DXMRIG_NO_TLS)
set(CMAKE_PROJECT_NAME "${CMAKE_PROJECT_NAME}-notls") set(CMAKE_PROJECT_NAME "${CMAKE_PROJECT_NAME}-notls")

View file

@ -23,7 +23,7 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
if (WIN32 AND CMAKE_C_COMPILER_ID MATCHES GNU) if (WIN32 AND CMAKE_C_COMPILER_ID MATCHES GNU)
set(XMRIG_ASM_FILES set(XMRIG_ASM_FILES
"src/crypto/asm/win64/cn_main_loop.S" "src/crypto/asm/win64/cn_main_loop.S"
"src/crypto/asm/win64/CryptonightR_template.S" "src/crypto/asm/CryptonightR_template.S"
) )
else() else()
set(XMRIG_ASM_FILES set(XMRIG_ASM_FILES
@ -36,7 +36,7 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
endif() endif()
add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILES}) add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILES})
set(XMRIG_ASM_SOURCES src/crypto/Asm.h src/crypto/Asm.cpp) set(XMRIG_ASM_SOURCES src/crypto/Asm.h src/crypto/Asm.cpp src/crypto/CryptonightR_gen.cpp)
set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C) set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C)
else() else()
set(XMRIG_ASM_SOURCES "") set(XMRIG_ASM_SOURCES "")

View file

@ -30,8 +30,8 @@
#include "api/Api.h" #include "api/Api.h"
#include "App.h" #include "App.h"
#include "base/io/Console.h"
#include "base/kernel/Signals.h" #include "base/kernel/Signals.h"
#include "common/Console.h"
#include "common/cpu/Cpu.h" #include "common/cpu/Cpu.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/Platform.h" #include "common/Platform.h"
@ -55,7 +55,7 @@ xmrig::App::App(Process *process) :
m_httpd(nullptr), m_httpd(nullptr),
m_signals(nullptr) m_signals(nullptr)
{ {
m_controller = new xmrig::Controller(process); m_controller = new Controller(process);
if (m_controller->init() != 0) { if (m_controller->init() != 0) {
return; return;
} }
@ -68,8 +68,6 @@ xmrig::App::App(Process *process) :
xmrig::App::~App() xmrig::App::~App()
{ {
uv_tty_reset_mode();
delete m_signals; delete m_signals;
delete m_console; delete m_console;
delete m_controller; delete m_controller;
@ -178,7 +176,7 @@ void xmrig::App::onSignal(int signum)
break; break;
default: default:
break; return;
} }
close(); close();
@ -187,8 +185,14 @@ void xmrig::App::onSignal(int signum)
void xmrig::App::close() void xmrig::App::close()
{ {
m_controller->network()->stop(); # ifndef XMRIG_NO_HTTPD
Workers::stop(); m_httpd->stop();
# endif
uv_stop(uv_default_loop()); m_signals->stop();
m_console->stop();
m_controller->stop();
Workers::stop();
Log::release();
} }

View file

@ -27,18 +27,16 @@
#define XMRIG_APP_H #define XMRIG_APP_H
#include "base/kernel/interfaces/IConsoleListener.h"
#include "base/kernel/interfaces/ISignalListener.h" #include "base/kernel/interfaces/ISignalListener.h"
#include "common/interfaces/IConsoleListener.h"
class Console;
class Httpd;
namespace xmrig { namespace xmrig {
class Console;
class Controller; class Controller;
class Httpd;
class Network; class Network;
class Process; class Process;
class Signals; class Signals;

View file

@ -53,7 +53,7 @@ MemInfo Mem::create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count)
uint8_t* p = reinterpret_cast<uint8_t*>(allocateExecutableMemory(0x4000)); uint8_t* p = reinterpret_cast<uint8_t*>(allocateExecutableMemory(0x4000));
c->generated_code = reinterpret_cast<cn_mainloop_fun_ms_abi>(p); c->generated_code = reinterpret_cast<cn_mainloop_fun_ms_abi>(p);
c->generated_code_double = reinterpret_cast<cn_mainloop_double_fun_ms_abi>(p + 0x2000); c->generated_code_double = reinterpret_cast<cn_mainloop_fun_ms_abi>(p + 0x2000);
c->generated_code_data.variant = xmrig::VARIANT_MAX; c->generated_code_data.variant = xmrig::VARIANT_MAX;
c->generated_code_data.height = (uint64_t)(-1); c->generated_code_data.height = (uint64_t)(-1);

View file

@ -28,7 +28,7 @@
#include <uv.h> #include <uv.h>
#include "base/net/Pool.h" #include "base/net/stratum/Pool.h"
#include "common/cpu/Cpu.h" #include "common/cpu/Cpu.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "core/Config.h" #include "core/Config.h"
@ -59,11 +59,11 @@ inline static const char *asmName(xmrig::Assembly assembly, bool colors)
static void print_memory(xmrig::Config *config) { static void print_memory(xmrig::Config *config) {
# ifdef _WIN32 # ifdef _WIN32
if (config->isColors()) { if (config->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s", xmrig::Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
"HUGE PAGES", Mem::isHugepagesAvailable() ? "\x1B[1;32mavailable" : "\x1B[01;31munavailable"); "HUGE PAGES", Mem::isHugepagesAvailable() ? "\x1B[1;32mavailable" : "\x1B[01;31munavailable");
} }
else { else {
Log::i()->text(" * %-13s%s", "HUGE PAGES", Mem::isHugepagesAvailable() ? "available" : "unavailable"); xmrig::Log::i()->text(" * %-13s%s", "HUGE PAGES", Mem::isHugepagesAvailable() ? "available" : "unavailable");
} }
# endif # endif
} }
@ -108,35 +108,35 @@ static void print_threads(xmrig::Config *config)
snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity()); snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity());
} }
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, av=%d, %sdonate=%d%%") WHITE_BOLD("%s") xmrig::Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, av=%d, %sdonate=%d%%") WHITE_BOLD("%s")
: " * %-13s%d, %s, av=%d, %sdonate=%d%%%s", : " * %-13s%d, %s, av=%d, %sdonate=%d%%%s",
"THREADS", "THREADS",
config->threadsCount(), config->threadsCount(),
config->algorithm().name(), config->algorithm().name(),
config->algoVariant(), config->algoVariant(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "", config->isColors() && config->pools().donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel(), config->pools().donateLevel(),
buf); buf);
} }
else { else {
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, %sdonate=%d%%") xmrig::Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, %sdonate=%d%%")
: " * %-13s%d, %s, %sdonate=%d%%", : " * %-13s%d, %s, %sdonate=%d%%",
"THREADS", "THREADS",
config->threadsCount(), config->threadsCount(),
config->algorithm().name(), config->algorithm().name(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "", config->isColors() && config->pools().donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel()); config->pools().donateLevel());
} }
# ifndef XMRIG_NO_ASM # ifndef XMRIG_NO_ASM
if (config->assembly() == xmrig::ASM_AUTO) { if (config->assembly() == xmrig::ASM_AUTO) {
const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly(); const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly();
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s") xmrig::Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s")
: " * %-13sauto:%s", "ASSEMBLY", asmName(assembly, config->isColors())); : " * %-13sauto:%s", "ASSEMBLY", asmName(assembly, config->isColors()));
} }
else { else {
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s") : " * %-13s%s", "ASSEMBLY", asmName(config->assembly(), config->isColors())); xmrig::Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s") : " * %-13s%s", "ASSEMBLY", asmName(config->assembly(), config->isColors()));
} }
# endif # endif
} }
@ -145,12 +145,12 @@ static void print_threads(xmrig::Config *config)
static void print_commands(xmrig::Config *config) static void print_commands(xmrig::Config *config)
{ {
if (config->isColors()) { if (config->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ") xmrig::Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ")
MAGENTA_BOLD("p") WHITE_BOLD("ause, ") MAGENTA_BOLD("p") WHITE_BOLD("ause, ")
MAGENTA_BOLD("r") WHITE_BOLD("esume")); MAGENTA_BOLD("r") WHITE_BOLD("esume"));
} }
else { else {
Log::i()->text(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume"); xmrig::Log::i()->text(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume");
} }
} }

View file

@ -34,11 +34,11 @@
#include "api/ApiRouter.h" #include "api/ApiRouter.h"
#include "base/tools/Buffer.h"
#include "common/api/HttpReply.h" #include "common/api/HttpReply.h"
#include "common/api/HttpRequest.h" #include "common/api/HttpRequest.h"
#include "common/cpu/Cpu.h" #include "common/cpu/Cpu.h"
#include "common/crypto/keccak.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"
@ -174,7 +174,7 @@ void ApiRouter::genId(const char *id)
memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND)); memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND));
xmrig::keccak(input, inSize, hash); xmrig::keccak(input, inSize, hash);
xmrig::Job::toHex(hash, 8, m_id); xmrig::Buffer::toHex(hash, 8, m_id);
delete [] input; delete [] input;
break; break;
@ -254,7 +254,7 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const
doc.AddMember("cpu", cpu, allocator); doc.AddMember("cpu", cpu, allocator);
doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), 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()->pools().donateLevel(), allocator);
} }
@ -293,13 +293,16 @@ void ApiRouter::getThreads(rapidjson::Document &doc) const
const std::vector<xmrig::IThread *> &threads = m_controller->config()->threads(); const std::vector<xmrig::IThread *> &threads = m_controller->config()->threads();
rapidjson::Value list(rapidjson::kArrayType); rapidjson::Value list(rapidjson::kArrayType);
size_t i = 0;
for (const xmrig::IThread *thread : threads) { for (const xmrig::IThread *thread : threads) {
rapidjson::Value value = thread->toAPI(doc); rapidjson::Value value = thread->toAPI(doc);
rapidjson::Value hashrate(rapidjson::kArrayType); rapidjson::Value hashrate(rapidjson::kArrayType);
hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::ShortInterval)), allocator); hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::MediumInterval)), allocator); hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::LargeInterval)), allocator); hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
i++;
value.AddMember("hashrate", hashrate, allocator); value.AddMember("hashrate", hashrate, allocator);
list.PushBack(value, allocator); list.PushBack(value, allocator);

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 +30,8 @@
#include "api/NetworkState.h" #include "api/NetworkState.h"
#include "common/net/SubmitResult.h" #include "base/net/stratum/SubmitResult.h"
#include "base/tools/Chrono.h"
xmrig::NetworkState::NetworkState() : xmrig::NetworkState::NetworkState() :
@ -44,12 +46,6 @@ xmrig::NetworkState::NetworkState() :
} }
int xmrig::NetworkState::connectionTime() const
{
return m_active ? (int)((uv_now(uv_default_loop()) - m_connectionTime) / 1000) : 0;
}
uint32_t xmrig::NetworkState::avgTime() const uint32_t xmrig::NetworkState::avgTime() const
{ {
if (m_latency.empty()) { if (m_latency.empty()) {
@ -74,6 +70,12 @@ uint32_t xmrig::NetworkState::latency() const
} }
uint64_t xmrig::NetworkState::connectionTime() const
{
return m_active ? ((Chrono::steadyMSecs() - m_connectionTime) / 1000) : 0;
}
void xmrig::NetworkState::add(const SubmitResult &result, const char *error) void xmrig::NetworkState::add(const SubmitResult &result, const char *error)
{ {
if (error) { if (error) {
@ -99,7 +101,7 @@ void xmrig::NetworkState::setPool(const char *host, int port, const char *ip)
snprintf(pool, sizeof(pool) - 1, "%s:%d", host, port); snprintf(pool, sizeof(pool) - 1, "%s:%d", host, port);
m_active = true; m_active = true;
m_connectionTime = uv_now(uv_default_loop()); m_connectionTime = Chrono::steadyMSecs();
} }

View file

@ -41,9 +41,9 @@ class NetworkState
public: public:
NetworkState(); NetworkState();
int connectionTime() const;
uint32_t avgTime() const; uint32_t avgTime() const;
uint32_t latency() const; uint32_t latency() const;
uint64_t connectionTime() const;
void add(const SubmitResult &result, const char *error); void add(const SubmitResult &result, const char *error);
void setPool(const char *host, int port, const char *ip); void setPool(const char *host, int port, const char *ip);
void stop(); void stop();

63
src/base/base.cmake Normal file
View file

@ -0,0 +1,63 @@
set(HEADERS_BASE
src/base/io/Console.h
src/base/io/Json.h
src/base/io/Watcher.h
src/base/kernel/Entry.h
src/base/kernel/interfaces/IClientListener.h
src/base/kernel/interfaces/IConfigListener.h
src/base/kernel/interfaces/IConsoleListener.h
src/base/kernel/interfaces/IDnsListener.h
src/base/kernel/interfaces/ILineListener.h
src/base/kernel/interfaces/ISignalListener.h
src/base/kernel/interfaces/IStrategy.h
src/base/kernel/interfaces/IStrategyListener.h
src/base/kernel/interfaces/ITimerListener.h
src/base/kernel/interfaces/IWatcherListener.h
src/base/kernel/Process.h
src/base/kernel/Signals.h
src/base/net/dns/Dns.h
src/base/net/dns/DnsRecord.h
src/base/net/stratum/Client.h
src/base/net/stratum/Job.h
src/base/net/stratum/Pool.h
src/base/net/stratum/Pools.h
src/base/net/stratum/strategies/FailoverStrategy.h
src/base/net/stratum/strategies/SinglePoolStrategy.h
src/base/net/stratum/SubmitResult.h
src/base/net/tools/RecvBuf.h
src/base/net/tools/Storage.h
src/base/tools/Arguments.h
src/base/tools/Buffer.h
src/base/tools/Chrono.h
src/base/tools/Handle.h
src/base/tools/String.h
src/base/tools/Timer.h
)
set(SOURCES_BASE
src/base/io/Console.cpp
src/base/io/Json.cpp
src/base/io/Watcher.cpp
src/base/kernel/Entry.cpp
src/base/kernel/Process.cpp
src/base/kernel/Signals.cpp
src/base/net/dns/Dns.cpp
src/base/net/dns/DnsRecord.cpp
src/base/net/stratum/Client.cpp
src/base/net/stratum/Job.cpp
src/base/net/stratum/Pool.cpp
src/base/net/stratum/Pools.cpp
src/base/net/stratum/strategies/FailoverStrategy.cpp
src/base/net/stratum/strategies/SinglePoolStrategy.cpp
src/base/tools/Arguments.cpp
src/base/tools/Buffer.cpp
src/base/tools/String.cpp
src/base/tools/Timer.cpp
)
if (WIN32)
set(SOURCES_OS src/base/io/Json_win.cpp)
else()
set(SOURCES_OS src/base/io/Json_unix.cpp)
endif()

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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,26 +23,44 @@
*/ */
#include "common/Console.h" #include "base/io/Console.h"
#include "interfaces/IConsoleListener.h" #include "base/kernel/interfaces/IConsoleListener.h"
#include "base/tools/Handle.h"
Console::Console(IConsoleListener *listener) xmrig::Console::Console(IConsoleListener *listener)
: m_listener(listener) : m_listener(listener)
{ {
m_tty.data = this; m_tty = new uv_tty_t;
uv_tty_init(uv_default_loop(), &m_tty, 0, 1);
if (!uv_is_readable(reinterpret_cast<uv_stream_t*>(&m_tty))) { m_tty->data = this;
uv_tty_init(uv_default_loop(), m_tty, 0, 1);
if (!uv_is_readable(reinterpret_cast<uv_stream_t*>(m_tty))) {
return; return;
} }
uv_tty_set_mode(&m_tty, UV_TTY_MODE_RAW); uv_tty_set_mode(m_tty, UV_TTY_MODE_RAW);
uv_read_start(reinterpret_cast<uv_stream_t*>(&m_tty), Console::onAllocBuffer, Console::onRead); uv_read_start(reinterpret_cast<uv_stream_t*>(m_tty), Console::onAllocBuffer, Console::onRead);
} }
void Console::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) xmrig::Console::~Console()
{
stop();
}
void xmrig::Console::stop()
{
uv_tty_reset_mode();
Handle::close(m_tty);
m_tty = nullptr;
}
void xmrig::Console::onAllocBuffer(uv_handle_t *handle, size_t, uv_buf_t *buf)
{ {
auto console = static_cast<Console*>(handle->data); auto console = static_cast<Console*>(handle->data);
buf->len = 1; buf->len = 1;
@ -49,7 +68,7 @@ void Console::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t
} }
void Console::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) void xmrig::Console::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
{ {
if (nread < 0) { if (nread < 0) {
return uv_close(reinterpret_cast<uv_handle_t*>(stream), nullptr); return uv_close(reinterpret_cast<uv_handle_t*>(stream), nullptr);

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -21,13 +22,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CONSOLE_H__ #ifndef XMRIG_CONSOLE_H
#define __CONSOLE_H__ #define XMRIG_CONSOLE_H
#include <uv.h> #include <uv.h>
namespace xmrig {
class IConsoleListener; class IConsoleListener;
@ -35,6 +40,9 @@ class Console
{ {
public: public:
Console(IConsoleListener *listener); Console(IConsoleListener *listener);
~Console();
void stop();
private: private:
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);
@ -42,8 +50,11 @@ private:
char m_buf[1]; char m_buf[1];
IConsoleListener *m_listener; IConsoleListener *m_listener;
uv_tty_t m_tty; uv_tty_t *m_tty;
}; };
#endif /* __CONSOLE_H__ */ } /* namespace xmrig */
#endif /* XMRIG_CONSOLE_H */

View file

@ -47,3 +47,47 @@ const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key,
return defaultValue; return defaultValue;
} }
int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsInt()) {
return i->value.GetInt();
}
return defaultValue;
}
int64_t xmrig::Json::getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsInt64()) {
return i->value.GetInt64();
}
return defaultValue;
}
uint64_t xmrig::Json::getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsUint64()) {
return i->value.GetUint64();
}
return defaultValue;
}
unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsUint()) {
return i->value.GetUint();
}
return defaultValue;
}

View file

@ -36,7 +36,11 @@ class Json
{ {
public: public:
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false); static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr); static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
static unsigned getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue = 0);
static bool get(const char *fileName, rapidjson::Document &doc); static bool get(const char *fileName, rapidjson::Document &doc);
static bool save(const char *fileName, const rapidjson::Document &doc); static bool save(const char *fileName, const rapidjson::Document &doc);

View file

@ -29,37 +29,31 @@
#include "base/kernel/interfaces/IWatcherListener.h" #include "base/kernel/interfaces/IWatcherListener.h"
#include "base/io/Watcher.h" #include "base/io/Watcher.h"
#include "base/tools/Handle.h" #include "base/tools/Handle.h"
#include "base/tools/Timer.h"
xmrig::Watcher::Watcher(const String &path, IWatcherListener *listener) : xmrig::Watcher::Watcher(const String &path, IWatcherListener *listener) :
m_listener(listener), m_listener(listener),
m_path(path) m_path(path)
{ {
m_timer = new Timer(this);
m_fsEvent = new uv_fs_event_t; m_fsEvent = new uv_fs_event_t;
m_fsEvent->data = this;
uv_fs_event_init(uv_default_loop(), m_fsEvent); uv_fs_event_init(uv_default_loop(), m_fsEvent);
m_timer = new uv_timer_t;
uv_timer_init(uv_default_loop(), m_timer);
m_fsEvent->data = m_timer->data = this;
start(); start();
} }
xmrig::Watcher::~Watcher() xmrig::Watcher::~Watcher()
{ {
Handle::close(m_timer); delete m_timer;
Handle::close(m_fsEvent); Handle::close(m_fsEvent);
} }
void xmrig::Watcher::onTimer(uv_timer_t *handle)
{
static_cast<Watcher *>(handle->data)->reload();
}
void xmrig::Watcher::onFsEvent(uv_fs_event_t *handle, const char *filename, int, int) void xmrig::Watcher::onFsEvent(uv_fs_event_t *handle, const char *filename, int, int)
{ {
if (!filename) { if (!filename) {
@ -72,8 +66,8 @@ void xmrig::Watcher::onFsEvent(uv_fs_event_t *handle, const char *filename, int,
void xmrig::Watcher::queueUpdate() void xmrig::Watcher::queueUpdate()
{ {
uv_timer_stop(m_timer); m_timer->stop();
uv_timer_start(m_timer, xmrig::Watcher::onTimer, kDelay, 0); m_timer->start(kDelay, 0);
} }

View file

@ -26,30 +26,33 @@
#define XMRIG_WATCHER_H #define XMRIG_WATCHER_H
#include "base/kernel/interfaces/ITimerListener.h"
#include "base/tools/String.h" #include "base/tools/String.h"
typedef struct uv_fs_event_s uv_fs_event_t; typedef struct uv_fs_event_s uv_fs_event_t;
typedef struct uv_timer_s uv_timer_t;
namespace xmrig { namespace xmrig {
class IWatcherListener; class IWatcherListener;
class Timer;
class Watcher class Watcher : public ITimerListener
{ {
public: public:
Watcher(const String &path, IWatcherListener *listener); Watcher(const String &path, IWatcherListener *listener);
~Watcher(); ~Watcher() override;
protected:
inline void onTimer(const Timer *) override { reload(); }
private: private:
constexpr static int kDelay = 500; constexpr static int kDelay = 500;
static void onFsEvent(uv_fs_event_t *handle, const char *filename, int events, int status); static void onFsEvent(uv_fs_event_t *handle, const char *filename, int events, int status);
static void onTimer(uv_timer_t *handle);
void queueUpdate(); void queueUpdate();
void reload(); void reload();
@ -57,11 +60,12 @@ private:
IWatcherListener *m_listener; IWatcherListener *m_listener;
String m_path; String m_path;
Timer *m_timer;
uv_fs_event_t *m_fsEvent; uv_fs_event_t *m_fsEvent;
uv_timer_t *m_timer;
}; };
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* XMRIG_WATCHER_H */ #endif /* XMRIG_WATCHER_H */

View file

@ -23,6 +23,7 @@
*/ */
#include <stdio.h>
#include <uv.h> #include <uv.h>

View file

@ -28,6 +28,7 @@
#include "base/kernel/Process.h" #include "base/kernel/Process.h"
#include "base/tools/Chrono.h"
static size_t location(xmrig::Process::Location location, char *buf, size_t max) static size_t location(xmrig::Process::Location location, char *buf, size_t max)
@ -50,7 +51,7 @@ static size_t location(xmrig::Process::Location location, char *buf, size_t max)
xmrig::Process::Process(int argc, char **argv) : xmrig::Process::Process(int argc, char **argv) :
m_arguments(argc, argv) m_arguments(argc, argv)
{ {
srand(static_cast<unsigned int>(static_cast<uintptr_t>(time(nullptr)) ^ reinterpret_cast<uintptr_t>(this))); srand(static_cast<unsigned int>(Chrono::currentMSecsSinceEpoch() ^ reinterpret_cast<uintptr_t>(this)));
} }

View file

@ -5,8 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 SChernykh <https://github.com/SChernykh> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2019 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
@ -44,20 +44,31 @@ xmrig::Signals::Signals(ISignalListener *listener)
m_signals[i] = signal; m_signals[i] = signal;
uv_signal_init(uv_default_loop(), signal); uv_signal_init(uv_default_loop(), signal);
uv_signal_start(signal, xmrig::Signals::onSignal, signums[i]); uv_signal_start(signal, Signals::onSignal, signums[i]);
} }
} }
xmrig::Signals::~Signals() xmrig::Signals::~Signals()
{ {
stop();
}
void xmrig::Signals::stop()
{
if (!m_signals[0]) {
return;
}
for (size_t i = 0; i < kSignalsCount; ++i) { for (size_t i = 0; i < kSignalsCount; ++i) {
Handle::close(m_signals[i]); Handle::close(m_signals[i]);
m_signals[i] = nullptr;
} }
} }
void xmrig::Signals::onSignal(uv_signal_t *handle, int signum) void xmrig::Signals::onSignal(uv_signal_t *handle, int signum)
{ {
static_cast<xmrig::Signals *>(handle->data)->m_listener->onSignal(signum); static_cast<Signals *>(handle->data)->m_listener->onSignal(signum);
} }

View file

@ -46,6 +46,8 @@ public:
Signals(ISignalListener *listener); Signals(ISignalListener *listener);
~Signals(); ~Signals();
void stop();
private: private:
void close(int signum); void close(int signum);

View file

@ -29,6 +29,9 @@
#include <stdint.h> #include <stdint.h>
#include "rapidjson/fwd.h"
namespace xmrig { namespace xmrig {
@ -43,7 +46,8 @@ public:
virtual ~IClientListener() = default; virtual ~IClientListener() = default;
virtual void onClose(Client *client, int failures) = 0; virtual void onClose(Client *client, int failures) = 0;
virtual void onJobReceived(Client *client, const Job &job) = 0; virtual void onJobReceived(Client *client, const Job &job, const rapidjson::Value &params) = 0;
virtual void onLogin(Client *client, rapidjson::Document &doc, rapidjson::Value &params) = 0;
virtual void onLoginSuccess(Client *client) = 0; virtual void onLoginSuccess(Client *client) = 0;
virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0; virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
}; };

View file

@ -22,25 +22,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_ICONSOLELISTENER_H
#include <uv.h> #define XMRIG_ICONSOLELISTENER_H
#include "common/net/SubmitResult.h" namespace xmrig {
xmrig::SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId) : class IConsoleListener
reqId(reqId),
seq(seq),
diff(diff),
actualDiff(actualDiff),
elapsed(0)
{ {
start = uv_hrtime(); public:
} virtual ~IConsoleListener() = default;
virtual void onConsoleCommand(char command) = 0;
};
void xmrig::SubmitResult::done() } /* namespace xmrig */
{
elapsed = (uv_hrtime() - start) / 1000000;
} #endif // XMRIG_ICONSOLELISTENER_H

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -21,19 +22,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_C_STR_H #ifndef XMRIG_IDNSLISTENER_H
#define XMRIG_C_STR_H #define XMRIG_IDNSLISTENER_H
#include "base/tools/String.h"
namespace xmrig { namespace xmrig {
typedef String c_str; class Dns;
class IDnsListener
{
public:
virtual ~IDnsListener() = default;
virtual void onResolved(const Dns &dns, int status) = 0;
};
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* XMRIG_C_STR_H */
#endif // XMRIG_IDNSLISTENER_H

View file

@ -0,0 +1,50 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 XMRIG_ILINELISTENER_H
#define XMRIG_ILINELISTENER_H
#include <stdint.h>
namespace xmrig {
class String;
class ILineListener
{
public:
virtual ~ILineListener() = default;
virtual void onLine(char *line, size_t size) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_ILINELISTENER_H

View file

@ -29,13 +29,12 @@
#include <stdint.h> #include <stdint.h>
class JobResult;
namespace xmrig { namespace xmrig {
class Algorithm; class Algorithm;
class Client;
class JobResult;
class IStrategy class IStrategy
@ -44,6 +43,7 @@ public:
virtual ~IStrategy() = default; virtual ~IStrategy() = default;
virtual bool isActive() const = 0; virtual bool isActive() const = 0;
virtual Client *client() const = 0;
virtual int64_t submit(const JobResult &result) = 0; virtual int64_t submit(const JobResult &result) = 0;
virtual void connect() = 0; virtual void connect() = 0;
virtual void resume() = 0; virtual void resume() = 0;

View file

@ -0,0 +1,47 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 XMRIG_ITIMERLISTENER_H
#define XMRIG_ITIMERLISTENER_H
namespace xmrig {
class Timer;
class ITimerListener
{
public:
virtual ~ITimerListener() = default;
virtual void onTimer(const Timer *timer) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_ITIMERLISTENER_H

158
src/base/net/dns/Dns.cpp Normal file
View file

@ -0,0 +1,158 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 "base/kernel/interfaces/IDnsListener.h"
#include "base/net/dns/Dns.h"
#include "base/tools/Handle.h"
namespace xmrig {
Storage<Dns> Dns::m_storage;
static const DnsRecord defaultRecord;
}
xmrig::Dns::Dns(IDnsListener *listener) :
m_hints(),
m_listener(listener),
m_status(0)
{
m_key = m_storage.add(this);
m_resolver = new uv_getaddrinfo_t;
m_resolver->data = m_storage.ptr(m_key);
m_hints.ai_family = AF_UNSPEC;
m_hints.ai_socktype = SOCK_STREAM;
m_hints.ai_protocol = IPPROTO_TCP;
}
xmrig::Dns::~Dns()
{
m_storage.release(m_key);
Handle::close(m_resolver);
}
bool xmrig::Dns::resolve(const String &host)
{
if (m_host != host) {
m_host = host;
clear();
}
m_status = uv_getaddrinfo(uv_default_loop(), m_resolver, Dns::onResolved, m_host.data(), nullptr, &m_hints);
return m_status == 0;
}
const char *xmrig::Dns::error() const
{
return uv_strerror(m_status);
}
const xmrig::DnsRecord &xmrig::Dns::get(DnsRecord::Type prefered) const
{
if (count() == 0) {
return defaultRecord;
}
const size_t ipv4 = m_ipv4.size();
const size_t ipv6 = m_ipv6.size();
if (ipv6 && (prefered == DnsRecord::AAAA || !ipv4)) {
return m_ipv6[ipv6 == 1 ? 0 : static_cast<size_t>(rand()) % ipv6];
}
if (ipv4) {
return m_ipv4[ipv4 == 1 ? 0 : static_cast<size_t>(rand()) % ipv4];
}
return defaultRecord;
}
size_t xmrig::Dns::count(DnsRecord::Type type) const
{
if (type == DnsRecord::A) {
return m_ipv4.size();
}
if (type == DnsRecord::AAAA) {
return m_ipv6.size();
}
return m_ipv4.size() + m_ipv6.size();
}
void xmrig::Dns::clear()
{
m_ipv4.clear();
m_ipv6.clear();
}
void xmrig::Dns::onResolved(int status, addrinfo *res)
{
m_status = status;
if (m_status < 0) {
return m_listener->onResolved(*this, status);
}
clear();
addrinfo *ptr = res;
while (ptr != nullptr) {
if (ptr->ai_family == AF_INET) {
m_ipv4.push_back(ptr);
}
if (ptr->ai_family == AF_INET6) {
m_ipv6.push_back(ptr);
}
ptr = ptr->ai_next;
}
m_listener->onResolved(*this, status);
}
void xmrig::Dns::onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res)
{
Dns *dns = m_storage.get(req->data);
if (dns) {
dns->onResolved(status, res);
}
uv_freeaddrinfo(res);
}

View file

@ -5,6 +5,7 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2019 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
@ -21,78 +22,59 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_ID_H #ifndef XMRIG_DNS_H
#define XMRIG_ID_H #define XMRIG_DNS_H
#include <string.h> #include <vector>
#include <uv.h>
#include "base/net/dns/DnsRecord.h"
#include "base/net/tools/Storage.h"
#include "base/tools/String.h"
namespace xmrig { namespace xmrig {
class Id class IDnsListener;
class Dns
{ {
public: public:
inline Id() : Dns(IDnsListener *listener);
m_data() ~Dns();
{
}
inline bool isEmpty() const { return m_ipv4.empty() && m_ipv6.empty(); }
inline int status() const { return m_status; }
inline Id(const char *id, size_t sizeFix = 0) bool resolve(const String &host);
{ const char *error() const;
setId(id, sizeFix); const DnsRecord &get(DnsRecord::Type prefered = DnsRecord::A) const;
} size_t count(DnsRecord::Type type = DnsRecord::Unknown) const;
inline bool operator==(const Id &other) const
{
return memcmp(m_data, other.m_data, sizeof(m_data)) == 0;
}
inline bool operator!=(const Id &other) const
{
return memcmp(m_data, other.m_data, sizeof(m_data)) != 0;
}
Id &operator=(const Id &other)
{
memcpy(m_data, other.m_data, sizeof(m_data));
return *this;
}
inline bool setId(const char *id, size_t sizeFix = 0)
{
memset(m_data, 0, sizeof(m_data));
if (!id) {
return false;
}
const size_t size = strlen(id);
if (size >= sizeof(m_data)) {
return false;
}
memcpy(m_data, id, size - sizeFix);
return true;
}
inline const char *data() const { return m_data; }
inline bool isValid() const { return *m_data != '\0'; }
private: private:
char m_data[64]; void clear();
void onResolved(int status, addrinfo *res);
static void onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res);
addrinfo m_hints;
IDnsListener *m_listener;
int m_status;
std::vector<DnsRecord> m_ipv4;
std::vector<DnsRecord> m_ipv6;
String m_host;
uintptr_t m_key;
uv_getaddrinfo_t *m_resolver;
static Storage<Dns> m_storage;
}; };
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* XMRIG_ID_H */ #endif /* XMRIG_DNS_H */

View file

@ -26,54 +26,41 @@
#include <uv.h> #include <uv.h>
#include "base/tools/Handle.h" #include "base/net/dns/DnsRecord.h"
void xmrig::Handle::close(uv_fs_event_t *handle) xmrig::DnsRecord::DnsRecord(const addrinfo *addr) :
m_type(addr->ai_family == AF_INET6 ? AAAA : A)
{ {
if (handle) { char *buf = nullptr;
uv_fs_event_stop(handle);
close(reinterpret_cast<uv_handle_t *>(handle)); if (m_type == AAAA) {
buf = new char[45]();
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), buf, 45);
} }
} else {
buf = new char[16]();
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), buf, 16);
void xmrig::Handle::close(uv_getaddrinfo_t *handle)
{
if (handle) {
uv_cancel(reinterpret_cast<uv_req_t *>(handle));
close(reinterpret_cast<uv_handle_t *>(handle));
} }
m_ip = buf;
} }
void xmrig::Handle::close(uv_handle_t *handle) sockaddr *xmrig::DnsRecord::addr(uint16_t port) const
{ {
uv_close(handle, [](uv_handle_t *handle) { delete handle; }); if (m_type == A) {
} sockaddr_in *addr = new sockaddr_in();
uv_ip4_addr(m_ip.data(), port, addr);
return reinterpret_cast<sockaddr *>(addr);
void xmrig::Handle::close(uv_signal_t *handle)
{
if (handle) {
uv_signal_stop(handle);
close(reinterpret_cast<uv_handle_t *>(handle));
} }
} else if (m_type == AAAA) {
sockaddr_in6 *addr = new sockaddr_in6();
uv_ip6_addr(m_ip.data(), port, addr);
return reinterpret_cast<sockaddr *>(addr);
void xmrig::Handle::close(uv_tcp_t *handle)
{
if (handle) {
close(reinterpret_cast<uv_handle_t *>(handle));
} }
}
return nullptr;
void xmrig::Handle::close(uv_timer_s *handle)
{
if (handle) {
uv_timer_stop(handle);
close(reinterpret_cast<uv_handle_t *>(handle));
}
} }

View file

@ -0,0 +1,66 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 XMRIG_DNSRECORD_H
#define XMRIG_DNSRECORD_H
struct addrinfo;
struct sockaddr;
#include "base/tools/String.h"
namespace xmrig {
class DnsRecord
{
public:
enum Type {
Unknown,
A,
AAAA
};
inline DnsRecord() : m_type(Unknown) {}
DnsRecord(const addrinfo *addr);
sockaddr *addr(uint16_t port = 0) const;
inline bool isValid() const { return m_type != Unknown; }
inline const String &ip() const { return m_ip; }
inline Type type() const { return m_type; }
private:
Type m_type;
String m_ip;
};
} /* namespace xmrig */
#endif /* XMRIG_DNSRECORD_H */

View file

@ -33,13 +33,16 @@
#ifndef XMRIG_NO_TLS #ifndef XMRIG_NO_TLS
# include <openssl/ssl.h> # include <openssl/ssl.h>
# include <openssl/err.h> # include <openssl/err.h>
# include "common/net/Tls.h" # include "base/net/stratum/Tls.h"
#endif #endif
#include "common/interfaces/IClientListener.h" #include "base/kernel/interfaces/IClientListener.h"
#include "base/net/dns/Dns.h"
#include "base/net/stratum/Client.h"
#include "base/tools/Buffer.h"
#include "base/tools/Chrono.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/Client.h"
#include "net/JobResult.h" #include "net/JobResult.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/error/en.h" #include "rapidjson/error/en.h"
@ -72,17 +75,15 @@ static const char *states[] = {
xmrig::Client::Client(int id, const char *agent, IClientListener *listener) : xmrig::Client::Client(int id, const char *agent, IClientListener *listener) :
m_enabled(true),
m_ipv6(false), m_ipv6(false),
m_nicehash(false),
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_retries(5),
m_retryPause(5000), m_retryPause(5000),
m_failures(0), m_failures(0),
m_recvBufPos(0),
m_state(UnconnectedState), m_state(UnconnectedState),
m_tls(nullptr), m_tls(nullptr),
m_expire(0), m_expire(0),
@ -93,23 +94,13 @@ xmrig::Client::Client(int id, const char *agent, IClientListener *listener) :
m_socket(nullptr) m_socket(nullptr)
{ {
m_key = m_storage.add(this); m_key = m_storage.add(this);
m_dns = new Dns(this);
memset(m_ip, 0, sizeof(m_ip));
memset(&m_hints, 0, sizeof(m_hints));
m_resolver.data = m_storage.ptr(m_key);
m_hints.ai_family = AF_UNSPEC;
m_hints.ai_socktype = SOCK_STREAM;
m_hints.ai_protocol = IPPROTO_TCP;
m_recvBuf.base = m_buf;
m_recvBuf.len = sizeof(m_buf);
} }
xmrig::Client::~Client() xmrig::Client::~Client()
{ {
delete m_dns;
delete m_socket; delete m_socket;
} }
@ -167,7 +158,7 @@ void xmrig::Client::tick(uint64_t now)
{ {
if (m_state == ConnectedState) { if (m_state == ConnectedState) {
if (m_expire && now > m_expire) { if (m_expire && now > m_expire) {
LOG_DEBUG_ERR("[%s] timeout", m_pool.url()); LOG_DEBUG_ERR("[%s] timeout", url());
close(); close();
} }
else if (m_keepAlive && now > m_keepAlive) { else if (m_keepAlive && now > m_keepAlive) {
@ -191,6 +182,16 @@ bool xmrig::Client::disconnect()
} }
bool xmrig::Client::isTLS() const
{
# ifndef XMRIG_NO_TLS
return m_pool.isTLS() && m_tls;
# else
return false;
# endif
}
const char *xmrig::Client::tlsFingerprint() const const char *xmrig::Client::tlsFingerprint() const
{ {
# ifndef XMRIG_NO_TLS # ifndef XMRIG_NO_TLS
@ -223,11 +224,6 @@ int64_t xmrig::Client::submit(const JobResult &result)
} }
# endif # endif
const Variant variant = m_job.algorithm().variant();
if ((variant == VARIANT_WOW || variant == VARIANT_4) && m_job.id() != result.jobId) {
return -1;
}
using namespace rapidjson; using namespace rapidjson;
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
@ -237,10 +233,10 @@ int64_t xmrig::Client::submit(const JobResult &result)
char *nonce = m_sendBuf; char *nonce = m_sendBuf;
char *data = m_sendBuf + 16; char *data = m_sendBuf + 16;
Job::toHex(reinterpret_cast<const unsigned char*>(&result.nonce), 4, nonce); Buffer::toHex(reinterpret_cast<const char*>(&result.nonce), 4, nonce);
nonce[8] = '\0'; nonce[8] = '\0';
Job::toHex(result.result, 32, data); Buffer::toHex(result.result, 32, data);
data[64] = '\0'; data[64] = '\0';
# endif # endif
@ -257,7 +253,7 @@ int64_t xmrig::Client::submit(const JobResult &result)
params.AddMember("nonce", StringRef(nonce), allocator); params.AddMember("nonce", StringRef(nonce), allocator);
params.AddMember("result", StringRef(data), allocator); params.AddMember("result", StringRef(data), allocator);
if (m_extensions & AlgoExt) { if (has<EXT_ALGO>() && result.algorithm.isValid()) {
params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator); params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator);
} }
@ -273,6 +269,36 @@ int64_t xmrig::Client::submit(const JobResult &result)
} }
void xmrig::Client::onResolved(const Dns &dns, int status)
{
assert(m_listener != nullptr);
if (!m_listener) {
return reconnect();
}
if (status < 0 && dns.isEmpty()) {
if (!isQuiet()) {
LOG_ERR("[%s] DNS error: \"%s\"", url(), uv_strerror(status));
}
return reconnect();
}
if (dns.isEmpty()) {
if (!isQuiet()) {
LOG_ERR("[%s] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", url());
}
return reconnect();
}
const DnsRecord &record = dns.get();
m_ip = record.ip();
connect(record.addr(m_pool.port()));
}
bool xmrig::Client::close() bool xmrig::Client::close()
{ {
if (m_state == ClosingState) { if (m_state == ClosingState) {
@ -315,16 +341,6 @@ bool xmrig::Client::isCriticalError(const char *message)
} }
bool xmrig::Client::isTLS() const
{
# ifndef XMRIG_NO_TLS
return m_pool.isTLS() && m_tls;
# else
return false;
# endif
}
bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code) bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code)
{ {
if (!params.IsObject()) { if (!params.IsObject()) {
@ -332,7 +348,7 @@ bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code)
return false; return false;
} }
Job job(m_id, m_nicehash, m_pool.algorithm(), m_rpcId); Job job(m_id, has<EXT_NICEHASH>(), m_pool.algorithm(), m_rpcId);
if (!job.setId(params["job_id"].GetString())) { if (!job.setId(params["job_id"].GetString())) {
*code = 3; *code = 3;
@ -392,7 +408,7 @@ bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code)
} }
if (!isQuiet()) { if (!isQuiet()) {
LOG_WARN("[%s] duplicate job received, reconnect", m_pool.url()); LOG_WARN("[%s] duplicate job received, reconnect", url());
} }
close(); close();
@ -402,16 +418,13 @@ bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code)
bool xmrig::Client::parseLogin(const rapidjson::Value &result, int *code) bool xmrig::Client::parseLogin(const rapidjson::Value &result, int *code)
{ {
if (!m_rpcId.setId(result["id"].GetString())) { m_rpcId = result["id"].GetString();
if (m_rpcId.isNull()) {
*code = 1; *code = 1;
return false; return false;
} }
m_nicehash = m_pool.isNicehash(); parseExtensions(result);
if (result.HasMember("extensions")) {
parseExtensions(result["extensions"]);
}
const bool rc = parseJob(result["job"], code); const bool rc = parseJob(result["job"], code);
m_jobs = 0; m_jobs = 0;
@ -430,7 +443,7 @@ bool xmrig::Client::send(BIO *bio)
return true; return true;
} }
LOG_DEBUG("[%s] TLS send (%d bytes)", m_pool.url(), static_cast<int>(buf.len)); LOG_DEBUG("[%s] TLS send (%d bytes)", url(), static_cast<int>(buf.len));
bool result = false; bool result = false;
if (state() == ConnectedState && uv_is_writable(m_stream)) { if (state() == ConnectedState && uv_is_writable(m_stream)) {
@ -441,7 +454,7 @@ bool xmrig::Client::send(BIO *bio)
} }
} }
else { else {
LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state); LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", url(), m_state);
} }
(void) BIO_reset(bio); (void) BIO_reset(bio);
@ -480,22 +493,22 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm) const
} }
int xmrig::Client::resolve(const char *host) int xmrig::Client::resolve(const String &host)
{ {
setState(HostLookupState); setState(HostLookupState);
m_expire = 0; m_expire = 0;
m_recvBufPos = 0; m_recvBuf.reset();
if (m_failures == -1) { if (m_failures == -1) {
m_failures = 0; m_failures = 0;
} }
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, nullptr, &m_hints); if (!m_dns->resolve(host)) {
if (r) {
if (!isQuiet()) { if (!isQuiet()) {
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_pool.port(), uv_strerror(r)); LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host.data(), m_pool.port(), uv_strerror(m_dns->status()));
} }
return 1; return 1;
} }
@ -507,13 +520,13 @@ int64_t xmrig::Client::send(const rapidjson::Document &doc)
{ {
using namespace rapidjson; using namespace rapidjson;
StringBuffer buffer(0, 512); StringBuffer buffer(nullptr, 512);
Writer<StringBuffer> writer(buffer); Writer<StringBuffer> writer(buffer);
doc.Accept(writer); doc.Accept(writer);
const size_t size = buffer.GetSize(); const size_t size = buffer.GetSize();
if (size > (sizeof(m_sendBuf) - 2)) { if (size > (sizeof(m_sendBuf) - 2)) {
LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", m_pool.url(), size, (sizeof(m_sendBuf) - 2)); LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", url(), size, (sizeof(m_sendBuf) - 2));
close(); close();
return -1; return -1;
} }
@ -528,7 +541,7 @@ int64_t xmrig::Client::send(const rapidjson::Document &doc)
int64_t xmrig::Client::send(size_t size) int64_t xmrig::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\"", url(), size, m_sendBuf);
# ifndef XMRIG_NO_TLS # ifndef XMRIG_NO_TLS
if (isTLS()) { if (isTLS()) {
@ -540,7 +553,7 @@ int64_t xmrig::Client::send(size_t size)
# endif # endif
{ {
if (state() != ConnectedState || !uv_is_writable(m_stream)) { if (state() != ConnectedState || !uv_is_writable(m_stream)) {
LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state); LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", url(), m_state);
return -1; return -1;
} }
@ -552,29 +565,11 @@ int64_t xmrig::Client::send(size_t size)
} }
} }
m_expire = uv_now(uv_default_loop()) + kResponseTimeout; m_expire = Chrono::steadyMSecs() + kResponseTimeout;
return m_sequence++; return m_sequence++;
} }
void xmrig::Client::connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6)
{
addrinfo *addr = nullptr;
m_ipv6 = ipv4.empty() && !ipv6.empty();
if (m_ipv6) {
addr = ipv6[ipv6.size() == 1 ? 0 : rand() % ipv6.size()];
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), m_ip, 45);
}
else {
addr = ipv4[ipv4.size() == 1 ? 0 : rand() % ipv4.size()];
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), m_ip, 16);
}
connect(addr->ai_addr);
}
void xmrig::Client::connect(sockaddr *addr) void xmrig::Client::connect(sockaddr *addr)
{ {
setState(ConnectingState); setState(ConnectingState);
@ -595,6 +590,8 @@ void xmrig::Client::connect(sockaddr *addr)
# endif # endif
uv_tcp_connect(req, m_socket, reinterpret_cast<const sockaddr*>(addr), Client::onConnect); uv_tcp_connect(req, m_socket, reinterpret_cast<const sockaddr*>(addr), Client::onConnect);
delete addr;
} }
@ -602,7 +599,7 @@ void xmrig::Client::handshake()
{ {
# ifndef XMRIG_NO_TLS # ifndef XMRIG_NO_TLS
if (isTLS()) { if (isTLS()) {
m_expire = uv_now(uv_default_loop()) + kResponseTimeout; m_expire = Chrono::steadyMSecs() + kResponseTimeout;
m_tls->handshake(); m_tls->handshake();
} }
@ -627,12 +624,12 @@ void xmrig::Client::login()
doc.AddMember("method", "login", allocator); doc.AddMember("method", "login", allocator);
Value params(kObjectType); Value params(kObjectType);
params.AddMember("login", StringRef(m_pool.user()), allocator); params.AddMember("login", m_pool.user().toJSON(), allocator);
params.AddMember("pass", StringRef(m_pool.password()), allocator); params.AddMember("pass", m_pool.password().toJSON(), allocator);
params.AddMember("agent", StringRef(m_agent), allocator); params.AddMember("agent", StringRef(m_agent), allocator);
if (m_pool.rigId()) { if (!m_pool.rigId().isNull()) {
params.AddMember("rigid", StringRef(m_pool.rigId()), allocator); params.AddMember("rigid", m_pool.rigId().toJSON(), allocator);
} }
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
@ -648,6 +645,8 @@ void xmrig::Client::login()
params.AddMember("algo", algo, allocator); params.AddMember("algo", algo, allocator);
} }
m_listener->onLogin(this, doc, params);
doc.AddMember("params", params, allocator); doc.AddMember("params", params, allocator);
send(doc); send(doc);
@ -677,13 +676,11 @@ void xmrig::Client::parse(char *line, size_t len)
{ {
startTimeout(); startTimeout();
line[len - 1] = '\0'; LOG_DEBUG("[%s] received (%d bytes): \"%s\"", 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 (!isQuiet()) { if (!isQuiet()) {
LOG_ERR("[%s] JSON decode failed", m_pool.url()); LOG_ERR("[%s] JSON decode failed", url());
} }
return; return;
@ -692,7 +689,7 @@ void xmrig::Client::parse(char *line, size_t len)
rapidjson::Document doc; rapidjson::Document doc;
if (doc.ParseInsitu(line).HasParseError()) { if (doc.ParseInsitu(line).HasParseError()) {
if (!isQuiet()) { if (!isQuiet()) {
LOG_ERR("[%s] JSON decode failed: \"%s\"", m_pool.url(), rapidjson::GetParseError_En(doc.GetParseError())); LOG_ERR("[%s] JSON decode failed: \"%s\"", url(), rapidjson::GetParseError_En(doc.GetParseError()));
} }
return; return;
@ -712,29 +709,43 @@ void xmrig::Client::parse(char *line, size_t len)
} }
void xmrig::Client::parseExtensions(const rapidjson::Value &value) void xmrig::Client::parseExtensions(const rapidjson::Value &result)
{ {
m_extensions = 0; m_extensions.reset();
if (!value.IsArray()) { if (!result.HasMember("extensions")) {
return; return;
} }
for (const rapidjson::Value &ext : value.GetArray()) { const rapidjson::Value &extensions = result["extensions"];
if (!extensions.IsArray()) {
return;
}
for (const rapidjson::Value &ext : extensions.GetArray()) {
if (!ext.IsString()) { if (!ext.IsString()) {
continue; continue;
} }
if (strcmp(ext.GetString(), "algo") == 0) { const char *name = ext.GetString();
m_extensions |= AlgoExt;
continue;
}
if (strcmp(ext.GetString(), "nicehash") == 0) { if (strcmp(name, "algo") == 0) {
m_extensions |= NicehashExt; setExtension(EXT_ALGO, true);
m_nicehash = true;
continue;
} }
else if (strcmp(name, "nicehash") == 0) {
setExtension(EXT_NICEHASH, true);
}
else if (strcmp(name, "connect") == 0) {
setExtension(EXT_CONNECT, true);
}
else if (strcmp(name, "keepalive") == 0) {
setExtension(EXT_KEEPALIVE, true);
}
# ifdef XMRIG_FEATURE_TLS
else if (strcmp(name, "tls") == 0) {
setExtension(EXT_TLS, true);
}
# endif
} }
} }
@ -743,7 +754,7 @@ void xmrig::Client::parseNotification(const char *method, const rapidjson::Value
{ {
if (error.IsObject()) { if (error.IsObject()) {
if (!isQuiet()) { 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", url(), error["message"].GetString(), error["code"].GetInt());
} }
return; return;
} }
@ -755,13 +766,13 @@ void xmrig::Client::parseNotification(const char *method, const rapidjson::Value
if (strcmp(method, "job") == 0) { if (strcmp(method, "job") == 0) {
int code = -1; int code = -1;
if (parseJob(params, &code)) { if (parseJob(params, &code)) {
m_listener->onJobReceived(this, m_job); m_listener->onJobReceived(this, m_job, params);
} }
return; return;
} }
LOG_WARN("[%s] unsupported method: \"%s\"", m_pool.url(), method); LOG_WARN("[%s] unsupported method: \"%s\"", url(), method);
} }
@ -777,7 +788,7 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
m_results.erase(it); m_results.erase(it);
} }
else if (!isQuiet()) { else if (!isQuiet()) {
LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), message, error["code"].GetInt()); LOG_ERR("[%s] error: \"%s\", code: %d", url(), message, error["code"].GetInt());
} }
if (isCriticalError(message)) { if (isCriticalError(message)) {
@ -795,7 +806,7 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
int code = -1; int code = -1;
if (!parseLogin(result, &code)) { if (!parseLogin(result, &code)) {
if (!isQuiet()) { if (!isQuiet()) {
LOG_ERR("[%s] login error code: %d", m_pool.url(), code); LOG_ERR("[%s] login error code: %d", url(), code);
} }
close(); close();
@ -804,7 +815,7 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
m_failures = 0; m_failures = 0;
m_listener->onLoginSuccess(this); m_listener->onLoginSuccess(this);
m_listener->onJobReceived(this, m_job); m_listener->onJobReceived(this, m_job, result["job"]);
return; return;
} }
@ -823,32 +834,42 @@ void xmrig::Client::ping()
} }
void xmrig::Client::read() void xmrig::Client::read(ssize_t nread)
{ {
char* end; const size_t size = static_cast<size_t>(nread);
char* start = m_recvBuf.base;
size_t remaining = m_recvBufPos;
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) { if (nread > 0 && size > m_recvBuf.available()) {
end++; nread = UV_ENOBUFS;
size_t len = end - start;
parse(start, len);
remaining -= len;
start = end;
} }
if (remaining == 0) { if (nread < 0) {
m_recvBufPos = 0; if (!isQuiet()) {
LOG_ERR("[%s] read error: \"%s\"", url(), uv_strerror(static_cast<int>(nread)));
}
close();
return; return;
} }
if (start == m_recvBuf.base) { assert(m_listener != nullptr);
return; if (!m_listener) {
return reconnect();
} }
memcpy(m_recvBuf.base, start, remaining); m_recvBuf.nread(size);
m_recvBufPos = remaining;
# ifndef XMRIG_NO_TLS
if (isTLS()) {
LOG_DEBUG("[%s] TLS received (%d bytes)", url(), static_cast<int>(nread));
m_tls->read(m_recvBuf.base(), m_recvBuf.pos());
m_recvBuf.reset();
}
else
# endif
{
m_recvBuf.getline(this);
}
} }
@ -869,15 +890,15 @@ void xmrig::Client::reconnect()
setState(ConnectingState); setState(ConnectingState);
m_failures++; m_failures++;
m_listener->onClose(this, (int) m_failures); m_listener->onClose(this, static_cast<int>(m_failures));
m_expire = uv_now(uv_default_loop()) + m_retryPause; m_expire = Chrono::steadyMSecs() + m_retryPause;
} }
void xmrig::Client::setState(SocketState state) void xmrig::Client::setState(SocketState state)
{ {
LOG_DEBUG("[%s] state: \"%s\"", m_pool.url(), states[state]); LOG_DEBUG("[%s] state: \"%s\"", url(), states[state]);
if (m_state == state) { if (m_state == state) {
return; return;
@ -891,21 +912,28 @@ void xmrig::Client::startTimeout()
{ {
m_expire = 0; m_expire = 0;
if (m_pool.keepAlive()) { if (has<EXT_KEEPALIVE>()) {
m_keepAlive = uv_now(uv_default_loop()) + (m_pool.keepAlive() * 1000); const uint64_t ms = static_cast<uint64_t>(m_pool.keepAlive() > 0 ? m_pool.keepAlive() : Pool::kKeepAliveTimeout) * 1000;
m_keepAlive = Chrono::steadyMSecs() + ms;
} }
} }
void xmrig::Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) void xmrig::Client::onAllocBuffer(uv_handle_t *handle, size_t, uv_buf_t *buf)
{ {
auto client = getClient(handle->data); auto client = getClient(handle->data);
if (!client) { if (!client) {
return; return;
} }
buf->base = &client->m_recvBuf.base[client->m_recvBufPos]; buf->base = client->m_recvBuf.current();
buf->len = client->m_recvBuf.len - client->m_recvBufPos;
# ifdef _WIN32
buf->len = static_cast<ULONG>(client->m_recvBuf.available());
# else
buf->len = client->m_recvBuf.available();
# endif
} }
@ -930,7 +958,7 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status)
if (status < 0) { if (status < 0) {
if (!client->isQuiet()) { if (!client->isQuiet()) {
LOG_ERR("[%s] connect error: \"%s\"", client->m_pool.url(), uv_strerror(status)); LOG_ERR("[%s] connect error: \"%s\"", client->url(), uv_strerror(status));
} }
delete req; delete req;
@ -949,94 +977,10 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status)
} }
void xmrig::Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) void xmrig::Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *)
{ {
auto client = getClient(stream->data); auto client = getClient(stream->data);
if (!client) { if (client) {
return; client->read(nread);
}
if (nread < 0) {
if (!client->isQuiet()) {
LOG_ERR("[%s] read error: \"%s\"", client->m_pool.url(), uv_strerror((int) nread));
}
client->close();
return;
}
if ((size_t) nread > (sizeof(m_buf) - 8 - client->m_recvBufPos)) {
client->close();
return;
}
assert(client->m_listener != nullptr);
if (!client->m_listener) {
return client->reconnect();
}
client->m_recvBufPos += nread;
# ifndef XMRIG_NO_TLS
if (client->isTLS()) {
LOG_DEBUG("[%s] TLS received (%d bytes)", client->m_pool.url(), static_cast<int>(nread));
client->m_tls->read(client->m_recvBuf.base, client->m_recvBufPos);
client->m_recvBufPos = 0;
}
else
# endif
{
client->read();
} }
} }
void xmrig::Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
{
auto client = getClient(req->data);
if (!client) {
return;
}
assert(client->m_listener != nullptr);
if (!client->m_listener) {
return client->reconnect();
}
if (status < 0) {
if (!client->isQuiet()) {
LOG_ERR("[%s] DNS error: \"%s\"", client->m_pool.url(), uv_strerror(status));
}
return client->reconnect();
}
addrinfo *ptr = res;
std::vector<addrinfo*> ipv4;
std::vector<addrinfo*> ipv6;
while (ptr != nullptr) {
if (ptr->ai_family == AF_INET) {
ipv4.push_back(ptr);
}
if (ptr->ai_family == AF_INET6) {
ipv6.push_back(ptr);
}
ptr = ptr->ai_next;
}
if (ipv4.empty() && ipv6.empty()) {
if (!client->isQuiet()) {
LOG_ERR("[%s] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_pool.url());
}
uv_freeaddrinfo(res);
return client->reconnect();
}
client->connect(ipv4, ipv6);
uv_freeaddrinfo(res);
}

View file

@ -26,18 +26,21 @@
#define XMRIG_CLIENT_H #define XMRIG_CLIENT_H
#include <bitset>
#include <map> #include <map>
#include <uv.h> #include <uv.h>
#include <vector> #include <vector>
#include "base/net/Pool.h" #include "base/kernel/interfaces/IDnsListener.h"
#include "base/kernel/interfaces/ILineListener.h"
#include "base/net/stratum/Job.h"
#include "base/net/stratum/Pool.h"
#include "base/net/stratum/SubmitResult.h"
#include "base/net/tools/RecvBuf.h"
#include "base/net/tools/Storage.h"
#include "common/crypto/Algorithm.h" #include "common/crypto/Algorithm.h"
#include "common/net/Id.h"
#include "common/net/Job.h"
#include "common/net/Storage.h"
#include "common/net/SubmitResult.h"
#include "rapidjson/fwd.h"
typedef struct bio_st BIO; typedef struct bio_st BIO;
@ -50,7 +53,7 @@ class IClientListener;
class JobResult; class JobResult;
class Client class Client : public IDnsListener, public ILineListener
{ {
public: public:
enum SocketState { enum SocketState {
@ -61,6 +64,15 @@ public:
ClosingState ClosingState
}; };
enum Extension {
EXT_ALGO,
EXT_NICEHASH,
EXT_CONNECT,
EXT_TLS,
EXT_KEEPALIVE,
EXT_MAX
};
constexpr static int kResponseTimeout = 20 * 1000; constexpr static int kResponseTimeout = 20 * 1000;
# ifndef XMRIG_NO_TLS # ifndef XMRIG_NO_TLS
@ -70,9 +82,10 @@ public:
# endif # endif
Client(int id, const char *agent, IClientListener *listener); Client(int id, const char *agent, IClientListener *listener);
~Client(); ~Client() override;
bool disconnect(); bool disconnect();
bool isTLS() const;
const char *tlsFingerprint() const; const char *tlsFingerprint() const;
const char *tlsVersion() const; const char *tlsVersion() const;
int64_t submit(const JobResult &result); int64_t submit(const JobResult &result);
@ -82,97 +95,101 @@ public:
void setPool(const Pool &pool); void setPool(const Pool &pool);
void tick(uint64_t now); void tick(uint64_t now);
inline bool isEnabled() const { return m_enabled; }
inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; }
inline const char *host() const { return m_pool.host(); } inline const char *host() const { return m_pool.host(); }
inline const char *ip() const { return m_ip; } inline const char *ip() const { return m_ip; }
inline const Job &job() const { return m_job; } inline const Job &job() const { return m_job; }
inline const Pool &pool() const { return m_pool; }
inline int id() const { return m_id; } inline int id() const { return m_id; }
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 setAlgo(const Algorithm &algo) { m_pool.setAlgo(algo); } inline void setAlgo(const Algorithm &algo) { m_pool.setAlgo(algo); }
inline void setEnabled(bool enabled) { m_enabled = enabled; }
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 setRetries(int retries) { m_retries = retries; }
inline void setRetryPause(int ms) { m_retryPause = ms; } inline void setRetryPause(int ms) { m_retryPause = ms; }
template<Extension ext> inline bool has() const noexcept { return m_extensions.test(ext); }
protected:
inline void onLine(char *line, size_t size) override { parse(line, size); }
void onResolved(const Dns &dns, int status) override;
private: private:
class Tls; class Tls;
enum Extensions {
NicehashExt = 1,
AlgoExt = 2
};
bool close(); bool close();
bool isCriticalError(const char *message); bool isCriticalError(const char *message);
bool isTLS() const;
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 send(BIO *bio); bool send(BIO *bio);
bool verifyAlgorithm(const Algorithm &algorithm) const; bool verifyAlgorithm(const Algorithm &algorithm) const;
int resolve(const char *host); int resolve(const String &host);
int64_t send(const rapidjson::Document &doc); 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(sockaddr *addr); void connect(sockaddr *addr);
void handshake(); void handshake();
void login(); void login();
void onClose(); void onClose();
void parse(char *line, size_t len); void parse(char *line, size_t len);
void parseExtensions(const rapidjson::Value &value); void parseExtensions(const rapidjson::Value &result);
void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error); void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error);
void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error); void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
void ping(); void ping();
void read(); void read(ssize_t nread);
void reconnect(); void reconnect();
void setState(SocketState state); void setState(SocketState state);
void startTimeout(); void startTimeout();
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; } inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
inline const char *url() const { return m_pool.url(); }
inline void setExtension(Extension ext, bool enable) noexcept { m_extensions.set(ext, enable); }
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);
static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
static void onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res);
static inline Client *getClient(void *data) { return m_storage.get(data); } static inline Client *getClient(void *data) { return m_storage.get(data); }
addrinfo m_hints; bool m_enabled;
bool m_ipv6; bool m_ipv6;
bool m_nicehash;
bool m_quiet; bool m_quiet;
char m_buf[kInputBufferSize];
char m_ip[46];
char m_sendBuf[2048]; char m_sendBuf[2048];
const char *m_agent; const char *m_agent;
Dns *m_dns;
IClientListener *m_listener; IClientListener *m_listener;
int m_extensions;
int m_id; int m_id;
int m_retries; int m_retries;
int m_retryPause; int m_retryPause;
int64_t m_failures; int64_t m_failures;
Job m_job; Job m_job;
Pool m_pool; Pool m_pool;
size_t m_recvBufPos; RecvBuf<kInputBufferSize> m_recvBuf;
SocketState m_state; SocketState m_state;
std::bitset<EXT_MAX> m_extensions;
std::map<int64_t, SubmitResult> m_results; std::map<int64_t, SubmitResult> m_results;
String m_ip;
String m_rpcId;
Tls *m_tls; Tls *m_tls;
uint64_t m_expire; uint64_t m_expire;
uint64_t m_jobs; uint64_t m_jobs;
uint64_t m_keepAlive; uint64_t m_keepAlive;
uintptr_t m_key; uintptr_t m_key;
uv_buf_t m_recvBuf;
uv_getaddrinfo_t m_resolver;
uv_stream_t *m_stream; uv_stream_t *m_stream;
uv_tcp_t *m_socket; uv_tcp_t *m_socket;
Id m_rpcId;
static int64_t m_sequence; static int64_t m_sequence;
static Storage<Client> m_storage; static Storage<Client> m_storage;
}; };
template<> inline bool Client::has<Client::EXT_NICEHASH>() const noexcept { return m_extensions.test(EXT_NICEHASH) || m_pool.isNicehash(); }
template<> inline bool Client::has<Client::EXT_KEEPALIVE>() const noexcept { return m_extensions.test(EXT_KEEPALIVE) || m_pool.keepAlive() > 0; }
} /* namespace xmrig */ } /* namespace xmrig */

View file

@ -28,34 +28,8 @@
#include <string.h> #include <string.h>
#include "common/net/Job.h" #include "base/net/stratum/Job.h"
#include "base/tools/Buffer.h"
unsigned char hf_hex2bin(char c, bool &err)
{
if (c >= '0' && c <= '9') {
return c - '0';
}
else if (c >= 'a' && c <= 'f') {
return c - 'a' + 0xA;
}
else if (c >= 'A' && c <= 'F') {
return c - 'A' + 0xA;
}
err = true;
return 0;
}
char hf_bin2hex(unsigned char c)
{
if (c <= 0x9) {
return '0' + c;
}
return 'a' - 0xA + c;
}
xmrig::Job::Job() : xmrig::Job::Job() :
@ -65,25 +39,25 @@ xmrig::Job::Job() :
m_threadId(-1), m_threadId(-1),
m_size(0), m_size(0),
m_diff(0), m_diff(0),
m_height(0),
m_target(0), m_target(0),
m_blob(), m_blob()
m_height(0)
{ {
} }
xmrig::Job::Job(int poolId, bool nicehash, const Algorithm &algorithm, const Id &clientId) : xmrig::Job::Job(int poolId, bool nicehash, const Algorithm &algorithm, const String &clientId) :
m_algorithm(algorithm),
m_autoVariant(algorithm.variant() == VARIANT_AUTO), m_autoVariant(algorithm.variant() == VARIANT_AUTO),
m_nicehash(nicehash), m_nicehash(nicehash),
m_poolId(poolId), m_poolId(poolId),
m_threadId(-1), m_threadId(-1),
m_size(0), m_size(0),
m_clientId(clientId),
m_diff(0), m_diff(0),
m_target(0),
m_blob(),
m_height(0), m_height(0),
m_algorithm(algorithm), m_target(0),
m_clientId(clientId) m_blob()
{ {
} }
@ -115,7 +89,7 @@ bool xmrig::Job::setBlob(const char *blob)
return false; return false;
} }
if (!fromHex(blob, (int) m_size * 2, m_blob)) { if (!Buffer::fromHex(blob, m_size * 2, m_blob)) {
return false; return false;
} }
@ -137,6 +111,12 @@ bool xmrig::Job::setBlob(const char *blob)
else if (m_algorithm.variant() == VARIANT_WOW && m_blob[0] < 11) { else if (m_algorithm.variant() == VARIANT_WOW && m_blob[0] < 11) {
m_algorithm.setVariant(VARIANT_2); m_algorithm.setVariant(VARIANT_2);
} }
else if (m_algorithm.variant() == VARIANT_RWZ && m_blob[0] < 12) {
m_algorithm.setVariant(VARIANT_2);
}
else if (m_algorithm.variant() == VARIANT_ZLS && m_blob[0] < 8) {
m_algorithm.setVariant(VARIANT_2);
}
} }
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
@ -161,7 +141,7 @@ bool xmrig::Job::setTarget(const char *target)
char str[8]; char str[8];
memcpy(str, target, len); memcpy(str, target, len);
if (!fromHex(str, 8, reinterpret_cast<unsigned char*>(&tmp)) || tmp == 0) { if (!Buffer::fromHex(str, 8, reinterpret_cast<uint8_t *>(&tmp)) || tmp == 0) {
return false; return false;
} }
@ -172,7 +152,7 @@ bool xmrig::Job::setTarget(const char *target)
char str[16]; char str[16];
memcpy(str, target, len); memcpy(str, target, len);
if (!fromHex(str, 16, reinterpret_cast<unsigned char*>(&m_target)) || m_target == 0) { if (!Buffer::fromHex(str, 16, reinterpret_cast<uint8_t *>(&m_target)) || m_target == 0) {
return false; return false;
} }
} }
@ -206,40 +186,6 @@ void xmrig::Job::setHeight(uint64_t height)
} }
bool xmrig::Job::fromHex(const char* in, unsigned int len, unsigned char* out)
{
bool error = false;
for (unsigned int i = 0; i < len; i += 2) {
out[i / 2] = (hf_hex2bin(in[i], error) << 4) | hf_hex2bin(in[i + 1], error);
if (error) {
return false;
}
}
return true;
}
void xmrig::Job::toHex(const unsigned char* in, unsigned int len, char* out)
{
for (unsigned int i = 0; i < len; i++) {
out[i * 2] = hf_bin2hex((in[i] & 0xF0) >> 4);
out[i * 2 + 1] = hf_bin2hex(in[i] & 0x0F);
}
}
#ifdef APP_DEBUG
char *xmrig::Job::toHex(const unsigned char* in, unsigned int len)
{
char *out = new char[len * 2 + 1]();
toHex(in, len, out);
return out;
}
#endif
xmrig::Variant xmrig::Job::variant() const xmrig::Variant xmrig::Job::variant() const
{ {
switch (m_algorithm.algo()) { switch (m_algorithm.algo()) {

View file

@ -31,8 +31,8 @@
#include <stdint.h> #include <stdint.h>
#include "base/tools/String.h"
#include "common/crypto/Algorithm.h" #include "common/crypto/Algorithm.h"
#include "common/net/Id.h"
namespace xmrig { namespace xmrig {
@ -46,7 +46,7 @@ public:
static constexpr const size_t kMaxBlobSize = 128; static constexpr const size_t kMaxBlobSize = 128;
Job(); Job();
Job(int poolId, bool nicehash, const Algorithm &algorithm, const Id &clientId); Job(int poolId, bool nicehash, const Algorithm &algorithm, const String &clientId);
~Job(); ~Job();
bool isEqual(const Job &other) const; bool isEqual(const Job &other) const;
@ -57,21 +57,22 @@ public:
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 = id; }
inline const Algorithm &algorithm() const { return m_algorithm; }
inline const String &clientId() const { return m_clientId; }
inline const String &id() const { return m_id; }
inline const uint32_t *nonce() const { return reinterpret_cast<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 Algorithm &algorithm() const { return m_algorithm; }
inline const Id &clientId() const { return m_clientId; }
inline const Id &id() const { return m_id; }
inline int poolId() const { return m_poolId; } inline int poolId() const { return m_poolId; }
inline int threadId() const { return m_threadId; } inline int threadId() const { return m_threadId; }
inline size_t size() const { return m_size; } inline size_t size() const { return m_size; }
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); } inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
inline uint32_t diff() const { return static_cast<uint32_t>(m_diff); } inline uint32_t diff() const { return static_cast<uint32_t>(m_diff); }
inline uint64_t target() const { return m_target; }
inline uint64_t height() const { return m_height; } inline uint64_t height() const { return m_height; }
inline uint64_t target() const { return m_target; }
inline uint8_t fixedByte() const { return *(m_blob + 42); }
inline void reset() { m_size = 0; m_diff = 0; } inline void reset() { m_size = 0; m_diff = 0; }
inline void setClientId(const Id &id) { m_clientId = id; } inline void setClientId(const String &id) { m_clientId = id; }
inline void setPoolId(int poolId) { m_poolId = poolId; } inline void setPoolId(int poolId) { m_poolId = poolId; }
inline void setThreadId(int threadId) { m_threadId = threadId; } inline void setThreadId(int threadId) { m_threadId = threadId; }
inline void setVariant(const char *variant) { m_algorithm.parseVariant(variant); } inline void setVariant(const char *variant) { m_algorithm.parseVariant(variant); }
@ -79,17 +80,12 @@ public:
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
inline char *rawBlob() { return m_rawBlob; } inline char *rawBlob() { return m_rawBlob; }
inline const char *rawBlob() const { return m_rawBlob; }
inline const char *rawTarget() const { return m_rawTarget; } inline const char *rawTarget() const { return m_rawTarget; }
# endif # endif
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); }
static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; } static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; }
static void toHex(const unsigned char* in, unsigned int len, char* out);
# ifdef APP_DEBUG
static char *toHex(const unsigned char* in, unsigned int len);
# endif
inline bool operator==(const Job &other) const { return isEqual(other); } inline bool operator==(const Job &other) const { return isEqual(other); }
inline bool operator!=(const Job &other) const { return !isEqual(other); } inline bool operator!=(const Job &other) const { return !isEqual(other); }
@ -97,18 +93,18 @@ public:
private: private:
Variant variant() const; Variant variant() const;
Algorithm m_algorithm;
bool m_autoVariant; bool m_autoVariant;
bool m_nicehash; bool m_nicehash;
int m_poolId; int m_poolId;
int m_threadId; int m_threadId;
size_t m_size; size_t m_size;
String m_clientId;
String m_id;
uint64_t m_diff; uint64_t m_diff;
uint64_t m_height;
uint64_t m_target; uint64_t m_target;
uint8_t m_blob[kMaxBlobSize]; uint8_t m_blob[kMaxBlobSize];
uint64_t m_height;
xmrig::Algorithm m_algorithm;
xmrig::Id m_clientId;
xmrig::Id m_id;
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
char m_rawBlob[kMaxBlobSize * 2 + 8]; char m_rawBlob[kMaxBlobSize * 2 + 8];

View file

@ -30,7 +30,7 @@
#include "base/io/Json.h" #include "base/io/Json.h"
#include "base/net/Pool.h" #include "base/net/stratum/Pool.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
@ -45,16 +45,23 @@
#endif #endif
static const char *kEnabled = "enabled"; namespace xmrig {
static const char *kFingerprint = "tls-fingerprint";
static const char *kKeepalive = "keepalive"; static const char *kEnabled = "enabled";
static const char *kNicehash = "nicehash"; static const char *kFingerprint = "tls-fingerprint";
static const char *kPass = "pass"; static const char *kKeepalive = "keepalive";
static const char *kRigId = "rig-id"; static const char *kNicehash = "nicehash";
static const char *kTls = "tls"; static const char *kPass = "pass";
static const char *kUrl = "url"; static const char *kRigId = "rig-id";
static const char *kUser = "user"; static const char *kTls = "tls";
static const char *kVariant = "variant"; static const char *kUrl = "url";
static const char *kUser = "user";
static const char *kVariant = "variant";
const String Pool::kDefaultPassword = "x";
const String Pool::kDefaultUser = "x";
}
xmrig::Pool::Pool() : xmrig::Pool::Pool() :
@ -128,6 +135,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls) : xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls) :
m_enabled(true),
m_nicehash(nicehash), m_nicehash(nicehash),
m_tls(tls), m_tls(tls),
m_keepAlive(keepAlive), m_keepAlive(keepAlive),
@ -160,7 +168,7 @@ bool xmrig::Pool::isCompatible(const Algorithm &algorithm) const
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
if (m_algorithm.algo() == xmrig::CRYPTONIGHT && algorithm.algo() == xmrig::CRYPTONIGHT) { if (m_algorithm.algo() == xmrig::CRYPTONIGHT && algorithm.algo() == xmrig::CRYPTONIGHT) {
return m_algorithm.variant() == xmrig::VARIANT_XTL || m_algorithm.variant() == xmrig::VARIANT_MSR; return m_algorithm.variant() == xmrig::VARIANT_RWZ || m_algorithm.variant() == xmrig::VARIANT_ZLS;
} }
# endif # endif
@ -492,6 +500,9 @@ void xmrig::Pool::rebuild()
addVariant(VARIANT_XAO); addVariant(VARIANT_XAO);
addVariant(VARIANT_RTO); addVariant(VARIANT_RTO);
addVariant(VARIANT_GPU); addVariant(VARIANT_GPU);
addVariant(VARIANT_RWZ);
addVariant(VARIANT_ZLS);
addVariant(VARIANT_DOUBLE);
addVariant(VARIANT_AUTO); addVariant(VARIANT_AUTO);
# endif # endif
} }

View file

@ -40,8 +40,9 @@ namespace xmrig {
class Pool class Pool
{ {
public: public:
constexpr static const char *kDefaultPassword = "x"; static const String kDefaultPassword;
constexpr static const char *kDefaultUser = "x"; static const String kDefaultUser;
constexpr static uint16_t kDefaultPort = 3333; constexpr static uint16_t kDefaultPort = 3333;
constexpr static int kKeepAliveTimeout = 60; constexpr static int kKeepAliveTimeout = 60;
@ -57,28 +58,28 @@ public:
bool tls = false bool tls = false
); );
inline Algorithm &algorithm() { return m_algorithm; }
inline bool isNicehash() const { return m_nicehash; } inline bool isNicehash() const { return m_nicehash; }
inline bool isTLS() const { return m_tls; } inline bool isTLS() const { return m_tls; }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; } inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
inline const char *fingerprint() const { return m_fingerprint.data(); }
inline const char *host() const { return m_host.data(); }
inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; }
inline const char *rigId() const { return m_rigId.data(); }
inline const char *url() const { return m_url.data(); }
inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; }
inline const Algorithm &algorithm() const { return m_algorithm; } inline const Algorithm &algorithm() const { return m_algorithm; }
inline const Algorithms &algorithms() const { return m_algorithms; } inline const Algorithms &algorithms() const { return m_algorithms; }
inline const String &fingerprint() const { return m_fingerprint; }
inline const String &host() const { return m_host; }
inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; }
inline const String &rigId() const { return m_rigId; }
inline const String &url() const { return m_url; }
inline const String &user() const { return !m_user.isNull() ? m_user : kDefaultUser; }
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 setFingerprint(const char *fingerprint) { m_fingerprint = fingerprint; } inline void setFingerprint(const char *fingerprint) { m_fingerprint = fingerprint; }
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
inline void setKeepAlive(bool enable) { setKeepAlive(enable ? kKeepAliveTimeout : 0); } inline void setKeepAlive(bool enable) { setKeepAlive(enable ? kKeepAliveTimeout : 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 setRigId(const char *rigId) { m_rigId = rigId; } inline void setRigId(const char *rigId) { m_rigId = rigId; }
inline void setTLS(bool tls) { m_tls = tls; } inline void setTLS(bool tls) { m_tls = tls; }
inline void setUser(const char *user) { m_user = user; } inline void setUser(const char *user) { m_user = user; }
inline 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); }

View file

@ -23,16 +23,19 @@
*/ */
#include "base/net/Pools.h" #include "base/net/stratum/Pools.h"
#include "base/net/stratum/strategies/FailoverStrategy.h"
#include "base/net/stratum/strategies/SinglePoolStrategy.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/strategies/FailoverStrategy.h" #include "donate.h"
#include "common/net/strategies/SinglePoolStrategy.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
xmrig::Pools::Pools() : xmrig::Pools::Pools() :
m_donateLevel(kDefaultDonateLevel),
m_retries(5), m_retries(5),
m_retryPause(5) m_retryPause(5),
m_proxyDonate(PROXY_DONATE_AUTO)
{ {
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
m_retries = 2; m_retries = 2;
@ -164,7 +167,7 @@ void xmrig::Pools::print() const
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") "\x1B[1;%dm%s\x1B[0m variant " WHITE_BOLD("%s"), Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") "\x1B[1;%dm%s\x1B[0m variant " WHITE_BOLD("%s"),
i, i,
color, color,
pool.url(), pool.url().data(),
pool.algorithm().variantName() pool.algorithm().variantName()
); );
} }
@ -172,7 +175,7 @@ void xmrig::Pools::print() const
Log::i()->text(" * POOL #%-7zu%s%s variant=%s %s", Log::i()->text(" * POOL #%-7zu%s%s variant=%s %s",
i, i,
pool.isEnabled() ? "" : "-", pool.isEnabled() ? "" : "-",
pool.url(), pool.url().data(),
pool.algorithm().variantName(), pool.algorithm().variantName(),
pool.isTLS() ? "TLS" : "" pool.isTLS() ? "TLS" : ""
); );
@ -191,6 +194,25 @@ void xmrig::Pools::print() const
} }
void xmrig::Pools::setDonateLevel(int level)
{
if (level >= kMinimumDonateLevel && level <= 99) {
m_donateLevel = level;
}
}
void xmrig::Pools::setProxyDonate(int value)
{
switch (value) {
case PROXY_DONATE_NONE:
case PROXY_DONATE_AUTO:
case PROXY_DONATE_ALWAYS:
m_proxyDonate = static_cast<ProxyDonate>(value);
}
}
void xmrig::Pools::setRetries(int retries) void xmrig::Pools::setRetries(int retries)
{ {
if (retries > 0 && retries <= 1000) { if (retries > 0 && retries <= 1000) {

View file

@ -29,7 +29,7 @@
#include <vector> #include <vector>
#include "base/net/Pool.h" #include "base/net/stratum/Pool.h"
namespace xmrig { namespace xmrig {
@ -42,12 +42,20 @@ class IStrategyListener;
class Pools class Pools
{ {
public: public:
enum ProxyDonate {
PROXY_DONATE_NONE,
PROXY_DONATE_AUTO,
PROXY_DONATE_ALWAYS
};
Pools(); Pools();
inline bool setUserpass(const char *userpass) { return current().setUserpass(userpass); } inline bool setUserpass(const char *userpass) { return current().setUserpass(userpass); }
inline const std::vector<Pool> &data() const { return m_data; } inline const std::vector<Pool> &data() const { return m_data; }
inline int donateLevel() const { return m_donateLevel; }
inline int retries() const { return m_retries; } inline int retries() const { return m_retries; }
inline int retryPause() const { return m_retryPause; } inline int retryPause() const { return m_retryPause; }
inline ProxyDonate proxyDonate() const { return m_proxyDonate; }
inline void setFingerprint(const char *fingerprint) { current().setFingerprint(fingerprint); } inline void setFingerprint(const char *fingerprint) { current().setFingerprint(fingerprint); }
inline void setKeepAlive(bool enable) { current().setKeepAlive(enable); } inline void setKeepAlive(bool enable) { current().setKeepAlive(enable); }
inline void setKeepAlive(int keepAlive) { current().setKeepAlive(keepAlive); } inline void setKeepAlive(int keepAlive) { current().setKeepAlive(keepAlive); }
@ -70,14 +78,18 @@ public:
void adjust(const Algorithm &algorithm); void adjust(const Algorithm &algorithm);
void load(const rapidjson::Value &pools); void load(const rapidjson::Value &pools);
void print() const; void print() const;
void setDonateLevel(int level);
void setProxyDonate(int value);
void setRetries(int retries); void setRetries(int retries);
void setRetryPause(int retryPause); void setRetryPause(int retryPause);
private: private:
Pool &current(); Pool &current();
int m_donateLevel;
int m_retries; int m_retries;
int m_retryPause; int m_retryPause;
ProxyDonate m_proxyDonate;
std::vector<Pool> m_data; std::vector<Pool> m_data;
}; };

View file

@ -26,7 +26,7 @@
#define XMRIG_SUBMITRESULT_H #define XMRIG_SUBMITRESULT_H
#include <uv.h> #include "base/tools/Chrono.h"
namespace xmrig { namespace xmrig {
@ -35,10 +35,25 @@ namespace xmrig {
class SubmitResult class SubmitResult
{ {
public: public:
inline SubmitResult() : reqId(0), seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {} inline SubmitResult() :
SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId = 0); reqId(0),
seq(0),
diff(0),
actualDiff(0),
elapsed(0),
m_start(0)
{}
void done(); inline SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId = 0) :
reqId(reqId),
seq(seq),
diff(diff),
actualDiff(actualDiff),
elapsed(0),
m_start(Chrono::steadyMSecs())
{}
inline void done() { elapsed = Chrono::steadyMSecs() - m_start; }
int64_t reqId; int64_t reqId;
int64_t seq; int64_t seq;
@ -47,7 +62,7 @@ public:
uint64_t elapsed; uint64_t elapsed;
private: private:
uint64_t start; uint64_t m_start;
}; };

View file

@ -27,8 +27,9 @@
#include <assert.h> #include <assert.h>
#include "common/net/Client.h" #include "base/net/stratum/Client.h"
#include "common/net/Tls.h" #include "base/net/stratum/Tls.h"
#include "base/tools/Buffer.h"
#include "common/log/Log.h" #include "common/log/Log.h"
@ -134,7 +135,8 @@ void xmrig::Client::Tls::read(const char *data, size_t size)
int bytes_read = 0; int bytes_read = 0;
while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) { while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) {
m_client->parse(m_buf, bytes_read); m_buf[bytes_read - 1] = '\0';
m_client->parse(m_buf, static_cast<size_t>(bytes_read));
} }
} }
@ -148,13 +150,13 @@ bool xmrig::Client::Tls::send()
bool xmrig::Client::Tls::verify(X509 *cert) bool xmrig::Client::Tls::verify(X509 *cert)
{ {
if (cert == nullptr) { if (cert == nullptr) {
LOG_ERR("[%s] Failed to get server certificate", m_client->m_pool.url()); LOG_ERR("[%s] Failed to get server certificate", m_client->url());
return false; return false;
} }
if (!verifyFingerprint(cert)) { if (!verifyFingerprint(cert)) {
LOG_ERR("[%s] Failed to verify server certificate fingerprint", m_client->m_pool.url()); LOG_ERR("[%s] Failed to verify server certificate fingerprint", m_client->url());
const char *fingerprint = m_client->m_pool.fingerprint(); const char *fingerprint = m_client->m_pool.fingerprint();
if (strlen(m_fingerprint) == 64 && fingerprint != nullptr) { if (strlen(m_fingerprint) == 64 && fingerprint != nullptr) {
@ -183,7 +185,7 @@ bool xmrig::Client::Tls::verifyFingerprint(X509 *cert)
return false; return false;
} }
Job::toHex(md, 32, m_fingerprint); Buffer::toHex(md, 32, m_fingerprint);
const char *fingerprint = m_client->m_pool.fingerprint(); const char *fingerprint = m_client->m_pool.fingerprint();
return fingerprint == nullptr || strncasecmp(m_fingerprint, fingerprint, 64) == 0; return fingerprint == nullptr || strncasecmp(m_fingerprint, fingerprint, 64) == 0;

View file

@ -29,7 +29,7 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include "common/net/Client.h" #include "base/net/stratum/Client.h"
namespace xmrig { namespace xmrig {

View file

@ -23,9 +23,9 @@
*/ */
#include "common/interfaces/IStrategyListener.h" #include "base/kernel/interfaces/IStrategyListener.h"
#include "common/net/Client.h" #include "base/net/stratum/Client.h"
#include "common/net/strategies/FailoverStrategy.h" #include "base/net/stratum/strategies/FailoverStrategy.h"
#include "common/Platform.h" #include "common/Platform.h"
@ -34,8 +34,8 @@ xmrig::FailoverStrategy::FailoverStrategy(const std::vector<Pool> &pools, int re
m_retries(retries), m_retries(retries),
m_retryPause(retryPause), m_retryPause(retryPause),
m_active(-1), m_active(-1),
m_index(0), m_listener(listener),
m_listener(listener) m_index(0)
{ {
for (const Pool &pool : pools) { for (const Pool &pool : pools) {
add(pool); add(pool);
@ -48,8 +48,8 @@ xmrig::FailoverStrategy::FailoverStrategy(int retryPause, int retries, IStrategy
m_retries(retries), m_retries(retries),
m_retryPause(retryPause), m_retryPause(retryPause),
m_active(-1), m_active(-1),
m_index(0), m_listener(listener),
m_listener(listener) m_index(0)
{ {
} }
@ -86,7 +86,7 @@ int64_t xmrig::FailoverStrategy::submit(const JobResult &result)
void xmrig::FailoverStrategy::connect() void xmrig::FailoverStrategy::connect()
{ {
m_pools[static_cast<size_t>(m_index)]->connect(); m_pools[m_index]->connect();
} }
@ -144,13 +144,13 @@ void xmrig::FailoverStrategy::onClose(Client *client, int failures)
return; return;
} }
if (m_index == client->id() && (m_pools.size() - static_cast<size_t>(m_index)) > 1) { if (m_index == static_cast<size_t>(client->id()) && (m_pools.size() - m_index) > 1) {
m_pools[static_cast<size_t>(++m_index)]->connect(); m_pools[++m_index]->connect();
} }
} }
void xmrig::FailoverStrategy::onJobReceived(Client *client, const Job &job) void xmrig::FailoverStrategy::onJobReceived(Client *client, const Job &job, const rapidjson::Value &)
{ {
if (m_active == client->id()) { if (m_active == client->id()) {
m_listener->onJob(this, client, job); m_listener->onJob(this, client, job);

View file

@ -29,9 +29,9 @@
#include <vector> #include <vector>
#include "base/net/Pool.h" #include "base/kernel/interfaces/IClientListener.h"
#include "common/interfaces/IClientListener.h" #include "base/kernel/interfaces/IStrategy.h"
#include "common/interfaces/IStrategy.h" #include "base/net/stratum/Pool.h"
namespace xmrig { namespace xmrig {
@ -50,8 +50,10 @@ public:
void add(const Pool &pool); void add(const Pool &pool);
public: protected:
inline bool isActive() const override { return m_active >= 0; } inline bool isActive() const override { return m_active >= 0; }
inline Client *client() const override { return active(); }
inline void onLogin(Client *, rapidjson::Document &, rapidjson::Value &) override {}
int64_t submit(const JobResult &result) override; int64_t submit(const JobResult &result) override;
void connect() override; void connect() override;
@ -60,9 +62,8 @@ public:
void stop() override; void stop() override;
void tick(uint64_t now) override; void tick(uint64_t now) override;
protected:
void onClose(Client *client, int failures) override; void onClose(Client *client, int failures) override;
void onJobReceived(Client *client, const Job &job) override; void onJobReceived(Client *client, const Job &job, const rapidjson::Value &params) override;
void onLoginSuccess(Client *client) override; void onLoginSuccess(Client *client) override;
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override; void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
@ -73,8 +74,8 @@ private:
const int m_retries; const int m_retries;
const int m_retryPause; const int m_retryPause;
int m_active; int m_active;
int m_index;
IStrategyListener *m_listener; IStrategyListener *m_listener;
size_t m_index;
std::vector<Client*> m_pools; std::vector<Client*> m_pools;
}; };

View file

@ -23,9 +23,9 @@
*/ */
#include "common/interfaces/IStrategyListener.h" #include "base/kernel/interfaces/IStrategyListener.h"
#include "common/net/Client.h" #include "base/net/stratum/Client.h"
#include "common/net/strategies/SinglePoolStrategy.h" #include "base/net/stratum/strategies/SinglePoolStrategy.h"
#include "common/Platform.h" #include "common/Platform.h"
@ -98,7 +98,7 @@ void xmrig::SinglePoolStrategy::onClose(Client *, int)
} }
void xmrig::SinglePoolStrategy::onJobReceived(Client *client, const Job &job) void xmrig::SinglePoolStrategy::onJobReceived(Client *client, const Job &job, const rapidjson::Value &)
{ {
m_listener->onJob(this, client, job); m_listener->onJob(this, client, job);
} }

View file

@ -26,8 +26,8 @@
#define XMRIG_SINGLEPOOLSTRATEGY_H #define XMRIG_SINGLEPOOLSTRATEGY_H
#include "common/interfaces/IClientListener.h" #include "base/kernel/interfaces/IClientListener.h"
#include "common/interfaces/IStrategy.h" #include "base/kernel/interfaces/IStrategy.h"
namespace xmrig { namespace xmrig {
@ -44,8 +44,10 @@ public:
SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false); SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
~SinglePoolStrategy() override; ~SinglePoolStrategy() override;
public: protected:
inline bool isActive() const override { return m_active; } inline bool isActive() const override { return m_active; }
inline Client *client() const override { return m_client; }
inline void onLogin(Client *, rapidjson::Document &, rapidjson::Value &) override {}
int64_t submit(const JobResult &result) override; int64_t submit(const JobResult &result) override;
void connect() override; void connect() override;
@ -54,9 +56,8 @@ public:
void stop() override; void stop() override;
void tick(uint64_t now) override; void tick(uint64_t now) override;
protected:
void onClose(Client *client, int failures) override; void onClose(Client *client, int failures) override;
void onJobReceived(Client *client, const Job &job) override; void onJobReceived(Client *client, const Job &job, const rapidjson::Value &params) override;
void onLoginSuccess(Client *client) override; void onLoginSuccess(Client *client) override;
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override; void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;

View file

@ -0,0 +1,99 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 XMRIG_RECVBUF_H
#define XMRIG_RECVBUF_H
#include <string.h>
#include "base/kernel/interfaces/ILineListener.h"
namespace xmrig {
template<size_t N>
class RecvBuf
{
public:
inline RecvBuf() :
m_buf(),
m_pos(0)
{
}
inline char *base() { return m_buf; }
inline char *current() { return m_buf + m_pos; }
inline const char *base() const { return m_buf; }
inline const char *current() const { return m_buf + m_pos; }
inline size_t available() const { return N - m_pos; }
inline size_t pos() const { return m_pos; }
inline void nread(size_t size) { m_pos += size; }
inline void reset() { m_pos = 0; }
constexpr inline size_t size() const { return N; }
inline void getline(ILineListener *listener)
{
char *end;
char *start = m_buf;
size_t remaining = m_pos;
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
*end = '\0';
end++;
const size_t len = static_cast<size_t>(end - start);
listener->onLine(start, len - 1);
remaining -= len;
start = end;
}
if (remaining == 0) {
m_pos = 0;
return;
}
if (start == m_buf) {
return;
}
memcpy(m_buf, start, remaining);
m_pos = remaining;
}
private:
char m_buf[N];
size_t m_pos;
};
} /* namespace xmrig */
#endif /* XMRIG_RECVBUF_H */

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -21,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __STORAGE_H__ #ifndef XMRIG_STORAGE_H
#define __STORAGE_H__ #define XMRIG_STORAGE_H
#include <assert.h> #include <assert.h>
@ -53,11 +54,10 @@ public:
inline static void *ptr(uintptr_t id) { return reinterpret_cast<void *>(id); } inline static void *ptr(uintptr_t id) { return reinterpret_cast<void *>(id); }
inline TYPE *get(void *id) const { return get(reinterpret_cast<uintptr_t>(id)); } inline TYPE *get(const void *id) const { return get(reinterpret_cast<uintptr_t>(id)); }
inline TYPE *get(uintptr_t id) const inline TYPE *get(uintptr_t id) const
{ {
assert(m_data.count(id) > 0); assert(m_data.count(id) > 0);
if (m_data.count(id) == 0) { if (m_data.count(id) == 0) {
return nullptr; return nullptr;
} }
@ -66,20 +66,22 @@ public:
} }
inline void remove(void *id) { remove(reinterpret_cast<uintptr_t>(id)); } inline void remove(const void *id) { delete release(reinterpret_cast<uintptr_t>(id)); }
inline void remove(uintptr_t id) inline void remove(uintptr_t id) { delete release(id); }
inline TYPE *release(const void *id) { release(reinterpret_cast<uintptr_t>(id)); }
inline TYPE *release(uintptr_t id)
{ {
TYPE *obj = get(id); TYPE *obj = get(id);
if (obj == nullptr) { if (obj != nullptr) {
return; auto it = m_data.find(id);
if (it != m_data.end()) {
m_data.erase(it);
}
} }
auto it = m_data.find(id); return obj;
if (it != m_data.end()) {
m_data.erase(it);
}
delete obj;
} }
@ -92,4 +94,4 @@ private:
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* __STORAGE_H__ */ #endif /* XMRIG_STORAGE_H */

201
src/base/tools/Buffer.cpp Normal file
View file

@ -0,0 +1,201 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 "base/tools/Buffer.h"
static inline uint8_t hf_hex2bin(uint8_t c, bool &err)
{
if (c >= '0' && c <= '9') {
return c - '0';
}
else if (c >= 'a' && c <= 'f') {
return c - 'a' + 0xA;
}
else if (c >= 'A' && c <= 'F') {
return c - 'A' + 0xA;
}
err = true;
return 0;
}
static inline uint8_t hf_bin2hex(uint8_t c)
{
if (c <= 0x9) {
return '0' + c;
}
return 'a' - 0xA + c;
}
xmrig::Buffer::Buffer() :
m_data(nullptr),
m_size(0)
{
}
xmrig::Buffer::Buffer(Buffer &&other) :
m_data(other.m_data),
m_size(other.m_size)
{
other.m_data = nullptr;
other.m_size = 0;
}
xmrig::Buffer::Buffer(const Buffer &other)
{
copy(other.data(), other.size());
}
xmrig::Buffer::Buffer(const char *data, size_t size)
{
copy(data, size);
}
xmrig::Buffer::Buffer(size_t size) :
m_size(size)
{
m_data = new char[size]();
}
xmrig::Buffer::~Buffer()
{
delete [] m_data;
}
void xmrig::Buffer::from(const char *data, size_t size)
{
if (m_size > 0) {
if (m_size == size) {
memcpy(m_data, data, m_size);
return;
}
delete [] m_data;
}
copy(data, size);
}
xmrig::Buffer xmrig::Buffer::allocUnsafe(size_t size)
{
Buffer buf;
buf.m_size = size;
buf.m_data = new char[size];
return buf;
}
bool xmrig::Buffer::fromHex(const uint8_t *in, size_t size, uint8_t *out)
{
bool error = false;
for (size_t i = 0; i < size; i += 2) {
out[i / 2] = static_cast<uint8_t>((hf_hex2bin(in[i], error) << 4) | hf_hex2bin(in[i + 1], error));
if (error) {
return false;
}
}
return true;
}
xmrig::Buffer xmrig::Buffer::fromHex(const char *data, size_t size)
{
if (data == nullptr || size % 2 != 0) {
return Buffer();
}
Buffer buf(size / 2);
fromHex(data, size, buf.data());
return buf;
}
void xmrig::Buffer::toHex(const uint8_t *in, size_t size, uint8_t *out)
{
for (size_t i = 0; i < size; i++) {
out[i * 2] = hf_bin2hex((in[i] & 0xF0) >> 4);
out[i * 2 + 1] = hf_bin2hex(in[i] & 0x0F);
}
}
xmrig::String xmrig::Buffer::toHex(const uint8_t *in, size_t size)
{
return Buffer(reinterpret_cast<const char *>(in), size).toHex();
}
xmrig::String xmrig::Buffer::toHex() const
{
if (m_size == 0) {
return String();
}
char *buf = new char[m_size * 2 + 1];
buf[m_size * 2] = '\0';
toHex(m_data, m_size, buf);
return String(buf);
}
void xmrig::Buffer::copy(const char *data, size_t size)
{
m_data = new char[size];
m_size = size;
memcpy(m_data, data, m_size);
}
void xmrig::Buffer::move(Buffer &&other)
{
if (m_size > 0) {
delete [] m_data;
}
m_data = other.m_data;
m_size = other.m_size;
other.m_data = nullptr;
other.m_size = 0;
}

88
src/base/tools/Buffer.h Normal file
View file

@ -0,0 +1,88 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 XMRIG_BUFFER_H
#define XMRIG_BUFFER_H
#include "base/tools/String.h"
namespace xmrig {
class Buffer
{
public:
Buffer();
Buffer(Buffer &&other);
Buffer(const Buffer &other);
Buffer(const char *data, size_t size);
Buffer(size_t size);
~Buffer();
inline char *data() { return m_data; }
inline const char *data() const { return m_data; }
inline size_t size() const { return m_size; }
inline void from(const Buffer &other) { from(other.data(), other.size()); }
void from(const char *data, size_t size);
inline Buffer &operator=(const Buffer &other) { from(other); return *this; }
inline Buffer &operator=(Buffer &&other) { move(std::move(other)); return *this; }
static Buffer allocUnsafe(size_t size);
static inline Buffer alloc(size_t size) { return Buffer(size); }
inline static bool fromHex(const char *in, size_t size, char *out) { return fromHex(reinterpret_cast<const uint8_t *>(in), size, reinterpret_cast<uint8_t *>(out)); }
inline static bool fromHex(const char *in, size_t size, uint8_t *out) { return fromHex(reinterpret_cast<const uint8_t *>(in), size, out); }
inline static Buffer fromHex(const char *data) { return fromHex(data, strlen(data)); }
inline static Buffer fromHex(const String &str) { return fromHex(str.data(), str.size()); }
inline static void toHex(const char *in, size_t size, char *out) { return toHex(reinterpret_cast<const uint8_t *>(in), size, reinterpret_cast<uint8_t *>(out)); }
inline static void toHex(const uint8_t *in, size_t size, char *out) { return toHex(in, size, reinterpret_cast<uint8_t *>(out)); }
static bool fromHex(const uint8_t *in, size_t size, uint8_t *out);
static Buffer fromHex(const char *data, size_t size);
static String toHex(const uint8_t *in, size_t size);
static void toHex(const uint8_t *in, size_t size, uint8_t *out);
String toHex() const;
private:
void copy(const char *data, size_t size);
void move(Buffer &&other);
char *m_data;
size_t m_size;
};
} /* namespace xmrig */
#endif /* XMRIG_BUFFER_H */

60
src/base/tools/Chrono.h Normal file
View file

@ -0,0 +1,60 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 XMRIG_CHRONO_H
#define XMRIG_CHRONO_H
#include <chrono>
namespace xmrig {
class Chrono
{
public:
static inline uint64_t steadyMSecs()
{
using namespace std::chrono;
if (high_resolution_clock::is_steady) {
return static_cast<uint64_t>(time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count());
}
return static_cast<uint64_t>(time_point_cast<milliseconds>(steady_clock::now()).time_since_epoch().count());
}
static inline uint64_t currentMSecsSinceEpoch()
{
using namespace std::chrono;
return static_cast<uint64_t>(time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count());
}
};
} /* namespace xmrig */
#endif /* XMRIG_CHRONO_H */

View file

@ -26,12 +26,7 @@
#define XMRIG_HANDLE_H #define XMRIG_HANDLE_H
typedef struct uv_fs_event_s uv_fs_event_t; #include <uv.h>
typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_signal_s uv_signal_t;
typedef struct uv_tcp_s uv_tcp_t;
typedef struct uv_timer_s uv_timer_t;
namespace xmrig { namespace xmrig {
@ -40,15 +35,68 @@ namespace xmrig {
class Handle class Handle
{ {
public: public:
static void close(uv_fs_event_t *handle); template<typename T>
static void close(uv_getaddrinfo_t *handle); static inline void close(T handle)
static void close(uv_handle_t *handle); {
static void close(uv_signal_t *handle); if (handle) {
static void close(uv_tcp_t *handle); deleteLater(handle);
static void close(uv_timer_t *handle); }
}
template<typename T>
static inline void deleteLater(T handle)
{
if (uv_is_closing(reinterpret_cast<uv_handle_t *>(handle))) {
return;
}
uv_close(reinterpret_cast<uv_handle_t *>(handle), [](uv_handle_t *handle) { delete handle; });
}
}; };
template<>
inline void Handle::close(uv_timer_t *handle)
{
if (handle) {
uv_timer_stop(handle);
deleteLater(handle);
}
}
template<>
inline void Handle::close(uv_signal_t *handle)
{
if (handle) {
uv_signal_stop(handle);
deleteLater(handle);
}
}
template<>
inline void Handle::close(uv_getaddrinfo_t *handle)
{
if (handle) {
uv_cancel(reinterpret_cast<uv_req_t *>(handle));
delete handle;
}
}
template<>
inline void Handle::close(uv_fs_event_t *handle)
{
if (handle) {
uv_fs_event_stop(handle);
deleteLater(handle);
}
}
} /* namespace xmrig */ } /* namespace xmrig */

View file

@ -5,6 +5,7 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2019 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
@ -178,14 +179,10 @@ void xmrig::String::copy(const char *str)
void xmrig::String::copy(const String &other) void xmrig::String::copy(const String &other)
{ {
if (m_size > 0) { if (m_size > 0 && m_size == other.m_size) {
if (m_size == other.m_size) { memcpy(m_data, other.m_data, m_size + 1);
memcpy(m_data, other.m_data, m_size + 1);
return; return;
}
delete [] m_data;
} }
delete [] m_data; delete [] m_data;

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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

91
src/base/tools/Timer.cpp Normal file
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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 "base/kernel/interfaces/ITimerListener.h"
#include "base/tools/Handle.h"
#include "base/tools/Timer.h"
xmrig::Timer::Timer(ITimerListener *listener) :
m_listener(listener),
m_timer(nullptr)
{
init();
}
xmrig::Timer::Timer(ITimerListener *listener, uint64_t timeout, uint64_t repeat) :
m_listener(listener),
m_timer(nullptr)
{
init();
start(timeout, repeat);
}
xmrig::Timer::~Timer()
{
Handle::close(m_timer);
}
uint64_t xmrig::Timer::repeat() const
{
return uv_timer_get_repeat(m_timer);
}
void xmrig::Timer::setRepeat(uint64_t repeat)
{
uv_timer_set_repeat(m_timer, repeat);
}
void xmrig::Timer::start(uint64_t timeout, uint64_t repeat)
{
uv_timer_start(m_timer, onTimer, timeout, repeat);
}
void xmrig::Timer::stop()
{
uv_timer_stop(m_timer);
}
void xmrig::Timer::init()
{
m_timer = new uv_timer_t;
m_timer->data = this;
uv_timer_init(uv_default_loop(), m_timer);
}
void xmrig::Timer::onTimer(uv_timer_t *handle)
{
const Timer *timer = static_cast<Timer *>(handle->data);
timer->m_listener->onTimer(timer);
}

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -21,35 +22,45 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_TIMESTAMP_H #ifndef XMRIG_TIMER_H
#define XMRIG_TIMESTAMP_H #define XMRIG_TIMER_H
#include <chrono> #include <stdint.h>
typedef struct uv_timer_s uv_timer_t;
namespace xmrig { namespace xmrig {
static inline int64_t steadyTimestamp() class ITimerListener;
class Timer
{ {
using namespace std::chrono; public:
if (high_resolution_clock::is_steady) { Timer(ITimerListener *listener);
return time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count(); Timer(ITimerListener *listener, uint64_t timeout, uint64_t repeat);
} ~Timer();
return time_point_cast<milliseconds>(steady_clock::now()).time_since_epoch().count(); uint64_t repeat() const;
} void setRepeat(uint64_t repeat);
void start(uint64_t timeout, uint64_t repeat);
void stop();
private:
void init();
static inline int64_t currentMSecsSinceEpoch() static void onTimer(uv_timer_t *handle);
{
using namespace std::chrono;
return time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count(); ITimerListener *m_listener;
} uv_timer_t *m_timer;
};
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* XMRIG_TIMESTAMP_H */
#endif /* XMRIG_TIMER_H */

View file

@ -61,6 +61,10 @@ char *Platform::createUserAgent()
# if defined(__x86_64__) # if defined(__x86_64__)
length += snprintf(buf + length, max - length, "x86_64) libuv/%s", uv_version_string()); length += snprintf(buf + length, max - length, "x86_64) libuv/%s", uv_version_string());
# elif defined(__aarch64__)
length += snprintf(buf + length, max - length, "aarch64) libuv/%s", uv_version_string());
# elif defined(__arm__)
length += snprintf(buf + length, max - length, "arm) libuv/%s", uv_version_string());
# else # else
length += snprintf(buf + length, max - length, "i686) libuv/%s", uv_version_string()); length += snprintf(buf + length, max - length, "i686) libuv/%s", uv_version_string());
# endif # endif

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -27,13 +28,15 @@
#include "api/Api.h" #include "api/Api.h"
#include "base/tools/Handle.h"
#include "base/tools/Timer.h"
#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 "common/log/Log.h" #include "common/log/Log.h"
Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) : xmrig::Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) :
m_idle(true), m_idle(true),
m_IPv6(IPv6), m_IPv6(IPv6),
m_restricted(restricted), m_restricted(restricted),
@ -41,14 +44,13 @@ Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) :
m_port(port), m_port(port),
m_daemon(nullptr) m_daemon(nullptr)
{ {
uv_timer_init(uv_default_loop(), &m_timer); m_timer = new Timer(this);
m_timer.data = this;
} }
Httpd::~Httpd() xmrig::Httpd::~Httpd()
{ {
uv_timer_stop(&m_timer); stop();
if (m_daemon) { if (m_daemon) {
MHD_stop_daemon(m_daemon); MHD_stop_daemon(m_daemon);
@ -58,7 +60,7 @@ Httpd::~Httpd()
} }
bool Httpd::start() bool xmrig::Httpd::start()
{ {
if (!m_port) { if (!m_port) {
return false; return false;
@ -82,16 +84,23 @@ bool Httpd::start()
} }
# if MHD_VERSION >= 0x00093900 # if MHD_VERSION >= 0x00093900
uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval); m_timer->start(kIdleInterval, kIdleInterval);
# else # else
uv_timer_start(&m_timer, Httpd::onTimer, kActiveInterval, kActiveInterval); m_timer->start(kActiveInterval, kActiveInterval);
# endif # endif
return true; return true;
} }
int Httpd::process(xmrig::HttpRequest &req) void xmrig::Httpd::stop()
{
delete m_timer;
m_timer = nullptr;
}
int xmrig::Httpd::process(HttpRequest &req)
{ {
xmrig::HttpReply reply; xmrig::HttpReply reply;
if (!req.process(m_accessToken, m_restricted, reply)) { if (!req.process(m_accessToken, m_restricted, reply)) {
@ -108,27 +117,27 @@ int Httpd::process(xmrig::HttpRequest &req)
} }
void Httpd::run() void xmrig::Httpd::run()
{ {
MHD_run(m_daemon); MHD_run(m_daemon);
# if MHD_VERSION >= 0x00093900 # 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); m_timer->setRepeat(kActiveInterval);
m_idle = false; m_idle = false;
} }
else if (!m_idle && !info->num_connections) { else if (!m_idle && !info->num_connections) {
uv_timer_set_repeat(&m_timer, kIdleInterval); m_timer->setRepeat(kIdleInterval);
m_idle = true; m_idle = true;
} }
# endif # endif
} }
int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls) int xmrig::Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *, const char *uploadData, size_t *uploadSize, void **con_cls)
{ {
xmrig::HttpRequest req(connection, url, method, uploadData, uploadSize, con_cls); HttpRequest req(connection, url, method, uploadData, uploadSize, con_cls);
if (req.method() == xmrig::HttpRequest::Options) { if (req.method() == xmrig::HttpRequest::Options) {
return req.end(MHD_HTTP_OK, nullptr); return req.end(MHD_HTTP_OK, nullptr);
@ -140,9 +149,3 @@ int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url
return static_cast<Httpd*>(cls)->process(req); return static_cast<Httpd*>(cls)->process(req);
} }
void Httpd::onTimer(uv_timer_t *handle)
{
static_cast<Httpd*>(handle->data)->run();
}

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -21,11 +22,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __HTTPD_H__ #ifndef XMRIG_HTTPD_H
#define __HTTPD_H__ #define XMRIG_HTTPD_H
#include <uv.h> #include <stddef.h>
#include "base/kernel/interfaces/ITimerListener.h"
struct MHD_Connection; struct MHD_Connection;
@ -33,30 +37,33 @@ struct MHD_Daemon;
struct MHD_Response; struct MHD_Response;
class UploadCtx;
namespace xmrig { namespace xmrig {
class HttpRequest;
}
class Httpd class HttpRequest;
class Timer;
class Httpd : public ITimerListener
{ {
public: public:
Httpd(int port, const char *accessToken, bool IPv6, bool restricted); Httpd(int port, const char *accessToken, bool IPv6, bool restricted);
~Httpd(); ~Httpd() override;
bool start(); bool start();
void stop();
protected:
void onTimer(const Timer *) override { run(); }
private: private:
constexpr static const int kIdleInterval = 200; constexpr static const int kIdleInterval = 200;
constexpr static const int kActiveInterval = 25; constexpr static const int kActiveInterval = 25;
int process(xmrig::HttpRequest &req); int process(HttpRequest &req);
void run(); void run();
static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls); static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls);
static void onTimer(uv_timer_t *handle);
bool m_idle; bool m_idle;
bool m_IPv6; bool m_IPv6;
@ -64,7 +71,11 @@ private:
const char *m_accessToken; const char *m_accessToken;
const int m_port; const int m_port;
MHD_Daemon *m_daemon; MHD_Daemon *m_daemon;
uv_timer_t m_timer; Timer *m_timer;
}; };
#endif /* __HTTPD_H__ */
} /* namespace xmrig */
#endif /* XMRIG_HTTPD_H */

View file

@ -57,7 +57,6 @@
#include "base/io/Json.h" #include "base/io/Json.h"
#include "common/config/CommonConfig.h" #include "common/config/CommonConfig.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "donate.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"
@ -75,7 +74,6 @@ xmrig::CommonConfig::CommonConfig() :
m_syslog(false), m_syslog(false),
m_watch(true), m_watch(true),
m_apiPort(0), m_apiPort(0),
m_donateLevel(kDefaultDonateLevel),
m_printTime(60), m_printTime(60),
m_state(NoneState) m_state(NoneState)
{ {
@ -397,9 +395,11 @@ bool xmrig::CommonConfig::parseInt(int key, int arg)
break; break;
case DonateLevelKey: /* --donate-level */ case DonateLevelKey: /* --donate-level */
if (arg >= kMinimumDonateLevel && arg <= 99) { m_pools.setDonateLevel(arg);
m_donateLevel = arg; break;
}
case ProxyDonateKey: /* --donate-over-proxy */
m_pools.setProxyDonate(arg);
break; break;
case ApiPort: /* --api-port */ case ApiPort: /* --api-port */

View file

@ -26,7 +26,7 @@
#define XMRIG_COMMONCONFIG_H #define XMRIG_COMMONCONFIG_H
#include "base/net/Pools.h" #include "base/net/stratum/Pools.h"
#include "base/tools/String.h" #include "base/tools/String.h"
#include "common/interfaces/IConfig.h" #include "common/interfaces/IConfig.h"
#include "common/xmrig.h" #include "common/xmrig.h"
@ -53,7 +53,6 @@ public:
inline const char *userAgent() const { return m_userAgent.data(); } inline const char *userAgent() const { return m_userAgent.data(); }
inline const Pools &pools() const { return m_pools; } inline const Pools &pools() const { return m_pools; }
inline int apiPort() const { return m_apiPort; } inline int apiPort() const { return m_apiPort; }
inline int donateLevel() const { return m_donateLevel; }
inline int printTime() const { return m_printTime; } inline int printTime() const { return m_printTime; }
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); } inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
@ -91,7 +90,6 @@ protected:
bool m_syslog; bool m_syslog;
bool m_watch; bool m_watch;
int m_apiPort; int m_apiPort;
int m_donateLevel;
int m_printTime; int m_printTime;
Pools m_pools; Pools m_pools;
State m_state; State m_state;

View file

@ -53,6 +53,11 @@
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
# include "core/ConfigLoader_default.h"
#endif
xmrig::ConfigWatcher *xmrig::ConfigLoader::m_watcher = nullptr; xmrig::ConfigWatcher *xmrig::ConfigLoader::m_watcher = nullptr;
xmrig::IConfigCreator *xmrig::ConfigLoader::m_creator = nullptr; xmrig::IConfigCreator *xmrig::ConfigLoader::m_creator = nullptr;
xmrig::IConfigListener *xmrig::ConfigLoader::m_listener = nullptr; xmrig::IConfigListener *xmrig::ConfigLoader::m_listener = nullptr;
@ -180,6 +185,15 @@ xmrig::IConfig *xmrig::ConfigLoader::load(Process *process, IConfigCreator *crea
loadFromFile(config, process->location(Process::ExeLocation, "config.json")); loadFromFile(config, process->location(Process::ExeLocation, "config.json"));
} }
# ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
if (!config->finalize()) {
delete config;
config = m_creator->create();
loadFromJSON(config, default_config);
}
# endif
if (!config->finalize()) { if (!config->finalize()) {
if (!config->algorithm().isValid()) { if (!config->algorithm().isValid()) {
fprintf(stderr, "No valid algorithm specified. Exiting.\n"); fprintf(stderr, "No valid algorithm specified. Exiting.\n");

View file

@ -36,6 +36,10 @@
# define bit_AES (1 << 25) # define bit_AES (1 << 25)
#endif #endif
#ifndef bit_OSXSAVE
# define bit_OSXSAVE (1 << 27)
#endif
#ifndef bit_AVX2 #ifndef bit_AVX2
# define bit_AVX2 (1 << 5) # define bit_AVX2 (1 << 5)
#endif #endif
@ -107,10 +111,19 @@ static inline bool has_avx2()
} }
static inline bool has_ossave()
{
int32_t cpu_info[4] = { 0 };
cpuid(PROCESSOR_INFO, cpu_info);
return (cpu_info[ECX_Reg] & bit_OSXSAVE) != 0;
}
xmrig::BasicCpuInfo::BasicCpuInfo() : xmrig::BasicCpuInfo::BasicCpuInfo() :
m_assembly(ASM_NONE), m_assembly(ASM_NONE),
m_aes(has_aes_ni()), m_aes(has_aes_ni()),
m_avx2(has_avx2()), m_avx2(has_avx2() && has_ossave()),
m_brand(), m_brand(),
m_threads(std::thread::hardware_concurrency()) m_threads(std::thread::hardware_concurrency())
{ {

View file

@ -54,18 +54,21 @@ struct AlgoData
static AlgoData const algorithms[] = { static AlgoData const algorithms[] = {
{ "cryptonight", "cn", xmrig::CRYPTONIGHT, xmrig::VARIANT_AUTO }, { "cryptonight", "cn", xmrig::CRYPTONIGHT, xmrig::VARIANT_AUTO },
{ "cryptonight/0", "cn/0", xmrig::CRYPTONIGHT, xmrig::VARIANT_0 }, { "cryptonight/0", "cn/0", xmrig::CRYPTONIGHT, xmrig::VARIANT_0 },
{ "cryptonight/1", "cn/1", xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, { "cryptonight/1", "cn/1", xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
{ "cryptonight/xtl", "cn/xtl", xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, { "cryptonight/xtl", "cn/xtl", xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL },
{ "cryptonight/msr", "cn/msr", xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR }, { "cryptonight/msr", "cn/msr", xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR },
{ "cryptonight/xao", "cn/xao", xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO }, { "cryptonight/xao", "cn/xao", xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO },
{ "cryptonight/rto", "cn/rto", xmrig::CRYPTONIGHT, xmrig::VARIANT_RTO }, { "cryptonight/rto", "cn/rto", xmrig::CRYPTONIGHT, xmrig::VARIANT_RTO },
{ "cryptonight/2", "cn/2", xmrig::CRYPTONIGHT, xmrig::VARIANT_2 }, { "cryptonight/2", "cn/2", xmrig::CRYPTONIGHT, xmrig::VARIANT_2 },
{ "cryptonight/half", "cn/half", xmrig::CRYPTONIGHT, xmrig::VARIANT_HALF }, { "cryptonight/half", "cn/half", xmrig::CRYPTONIGHT, xmrig::VARIANT_HALF },
{ "cryptonight/xtlv9", "cn/xtlv9", xmrig::CRYPTONIGHT, xmrig::VARIANT_HALF }, { "cryptonight/xtlv9", "cn/xtlv9", xmrig::CRYPTONIGHT, xmrig::VARIANT_HALF },
{ "cryptonight/wow", "cn/wow", xmrig::CRYPTONIGHT, xmrig::VARIANT_WOW }, { "cryptonight/wow", "cn/wow", xmrig::CRYPTONIGHT, xmrig::VARIANT_WOW },
{ "cryptonight/r", "cn/r", xmrig::CRYPTONIGHT, xmrig::VARIANT_4 }, { "cryptonight/r", "cn/r", xmrig::CRYPTONIGHT, xmrig::VARIANT_4 },
{ "cryptonight/rwz", "cn/rwz", xmrig::CRYPTONIGHT, xmrig::VARIANT_RWZ },
{ "cryptonight/zls", "cn/zls", xmrig::CRYPTONIGHT, xmrig::VARIANT_ZLS },
{ "cryptonight/double", "cn/double", xmrig::CRYPTONIGHT, xmrig::VARIANT_DOUBLE },
# ifndef XMRIG_NO_AEON # ifndef XMRIG_NO_AEON
{ "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO }, { "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO },
@ -113,6 +116,7 @@ static AlgoData const xmrStakAlgorithms[] = {
{ "cryptonight_alloy", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO }, // xmr-stak-alloy { "cryptonight_alloy", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO }, // xmr-stak-alloy
{ "cryptonight_turtle", nullptr, xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL }, { "cryptonight_turtle", nullptr, xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL },
{ "cryptonight_gpu", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_GPU }, { "cryptonight_gpu", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_GPU },
{ "cryptonight_r", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_4 },
}; };
#endif #endif
@ -132,6 +136,9 @@ static const char *variants[] = {
"gpu", "gpu",
"wow", "wow",
"r", "r",
"rwz",
"zls",
"double"
}; };

View file

@ -69,6 +69,7 @@ public:
TlsKey = 1013, TlsKey = 1013,
FingerprintKey = 1014, FingerprintKey = 1014,
AutoSaveKey = 1016, AutoSaveKey = 1016,
ProxyDonateKey = 1017,
// xmrig common // xmrig common
CPUPriorityKey = 1021, CPUPriorityKey = 1021,
@ -117,6 +118,8 @@ public:
TlsCiphersKey = 1112, TlsCiphersKey = 1112,
TlsCipherSuitesKey = 1113, TlsCipherSuitesKey = 1113,
TlsProtocolsKey = 1114, TlsProtocolsKey = 1114,
AlgoExtKey = 1115,
ProxyPasswordKey = 1116,
// xmrig nvidia // xmrig nvidia
CudaMaxThreadsKey = 1200, CudaMaxThreadsKey = 1200,

View file

@ -1,37 +0,0 @@
/* 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 2016-2017 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 __ICONSOLELISTENER_H__
#define __ICONSOLELISTENER_H__
class IConsoleListener
{
public:
virtual ~IConsoleListener() {}
virtual void onConsoleCommand(char command) = 0;
};
#endif // __ICONSOLELISTENER_H__

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -21,14 +22,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __ILOGBACKEND_H__ #ifndef XMRIG_ILOGBACKEND_H
#define __ILOGBACKEND_H__ #define XMRIG_ILOGBACKEND_H
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> #include <stddef.h>
namespace xmrig {
class ILogBackend class ILogBackend
{ {
public: public:
@ -46,11 +50,14 @@ public:
constexpr static const size_t kBufferSize = 512; constexpr static const size_t kBufferSize = 512;
# endif # endif
virtual ~ILogBackend() {} virtual ~ILogBackend() = default;
virtual void message(Level level, const char* fmt, va_list args) = 0; virtual void message(Level level, const char* fmt, va_list args) = 0;
virtual void text(const char* fmt, va_list args) = 0; virtual void text(const char* fmt, va_list args) = 0;
}; };
#endif // __ILOGBACKEND_H__ } /* namespace xmrig */
#endif // XMRIG_ILOGBACKEND_H

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -38,12 +39,12 @@
#include "common/log/Log.h" #include "common/log/Log.h"
BasicLog::BasicLog() xmrig::BasicLog::BasicLog()
{ {
} }
void BasicLog::message(Level level, const char* fmt, va_list args) void xmrig::BasicLog::message(Level level, const char* fmt, va_list args)
{ {
time_t now = time(nullptr); time_t now = time(nullptr);
tm stime; tm stime;
@ -70,7 +71,7 @@ void BasicLog::message(Level level, const char* fmt, va_list args)
} }
void BasicLog::text(const char* fmt, va_list args) void xmrig::BasicLog::text(const char* fmt, va_list args)
{ {
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(false)); snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(false));
@ -78,7 +79,7 @@ void BasicLog::text(const char* fmt, va_list args)
} }
void BasicLog::print(va_list args) void xmrig::BasicLog::print(va_list args)
{ {
if (vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args) <= 0) { if (vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args) <= 0) {
return; return;

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -21,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __BASICLOG_H__ #ifndef XMRIG_BASICLOG_H
#define __BASICLOG_H__ #define XMRIG_BASICLOG_H
#include <uv.h> #include <uv.h>
@ -32,8 +33,6 @@
namespace xmrig { namespace xmrig {
class Controller;
}
class BasicLog : public ILogBackend class BasicLog : public ILogBackend
@ -52,4 +51,7 @@ private:
char m_fmt[256]; char m_fmt[256];
}; };
#endif /* __BASICLOG_H__ */
} /* namespace xmrig */
#endif /* XMRIG_BASICLOG_H */

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -34,24 +35,24 @@
#endif #endif
#include "base/tools/Handle.h"
#include "common/log/ConsoleLog.h" #include "common/log/ConsoleLog.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "core/Config.h"
#include "core/Controller.h"
ConsoleLog::ConsoleLog(xmrig::Controller *controller) : xmrig::ConsoleLog::ConsoleLog() :
m_stream(nullptr), m_stream(nullptr)
m_controller(controller)
{ {
if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) { m_tty = new uv_tty_t;
if (uv_tty_init(uv_default_loop(), m_tty, 1, 0) < 0) {
Log::colors = false; Log::colors = false;
return; return;
} }
uv_tty_set_mode(&m_tty, UV_TTY_MODE_NORMAL); uv_tty_set_mode(m_tty, UV_TTY_MODE_NORMAL);
m_uvBuf.base = m_buf; m_uvBuf.base = m_buf;
m_stream = reinterpret_cast<uv_stream_t*>(&m_tty); m_stream = reinterpret_cast<uv_stream_t*>(m_tty);
# ifdef WIN32 # ifdef WIN32
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
@ -66,7 +67,13 @@ ConsoleLog::ConsoleLog(xmrig::Controller *controller) :
} }
void ConsoleLog::message(Level level, const char* fmt, va_list args) xmrig::ConsoleLog::~ConsoleLog()
{
Handle::close(m_tty);
}
void xmrig::ConsoleLog::message(Level level, const char* fmt, va_list args)
{ {
time_t now = time(nullptr); time_t now = time(nullptr);
tm stime; tm stime;
@ -77,8 +84,6 @@ void ConsoleLog::message(Level level, const char* fmt, va_list args)
localtime_r(&now, &stime); localtime_r(&now, &stime);
# endif # endif
const bool isColors = m_controller->config()->isColors();
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s", snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
stime.tm_year + 1900, stime.tm_year + 1900,
stime.tm_mon + 1, stime.tm_mon + 1,
@ -86,24 +91,24 @@ void ConsoleLog::message(Level level, const char* fmt, va_list args)
stime.tm_hour, stime.tm_hour,
stime.tm_min, stime.tm_min,
stime.tm_sec, stime.tm_sec,
Log::colorByLevel(level, isColors), Log::colorByLevel(level, Log::colors),
fmt, fmt,
Log::endl(isColors) Log::endl(Log::colors)
); );
print(args); print(args);
} }
void ConsoleLog::text(const char* fmt, va_list args) void xmrig::ConsoleLog::text(const char* fmt, va_list args)
{ {
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(m_controller->config()->isColors())); snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(Log::colors));
print(args); print(args);
} }
bool ConsoleLog::isWritable() const bool xmrig::ConsoleLog::isWritable() const
{ {
if (!m_stream || uv_is_writable(m_stream) != 1) { if (!m_stream || uv_is_writable(m_stream) != 1) {
return false; return false;
@ -114,7 +119,7 @@ bool ConsoleLog::isWritable() const
} }
void ConsoleLog::print(va_list args) void xmrig::ConsoleLog::print(va_list args)
{ {
m_uvBuf.len = vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args); m_uvBuf.len = vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args);
if (m_uvBuf.len <= 0) { if (m_uvBuf.len <= 0) {

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -21,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CONSOLELOG_H__ #ifndef XMRIG_CONSOLELOG_H
#define __CONSOLELOG_H__ #define XMRIG_CONSOLELOG_H
#include <uv.h> #include <uv.h>
@ -32,15 +33,15 @@
namespace xmrig { namespace xmrig {
class Controller;
}
class ConsoleLog : public ILogBackend class ConsoleLog : public ILogBackend
{ {
public: public:
ConsoleLog(xmrig::Controller *controller); ConsoleLog();
~ConsoleLog() override;
protected:
void message(Level level, const char *fmt, va_list args) override; void message(Level level, const char *fmt, va_list args) override;
void text(const char *fmt, va_list args) override; void text(const char *fmt, va_list args) override;
@ -52,8 +53,11 @@ private:
char m_fmt[256]; char m_fmt[256];
uv_buf_t m_uvBuf; uv_buf_t m_uvBuf;
uv_stream_t *m_stream; uv_stream_t *m_stream;
uv_tty_t m_tty; uv_tty_t *m_tty;
xmrig::Controller *m_controller;
}; };
#endif /* __CONSOLELOG_H__ */
} /* namespace xmrig */
#endif /* XMRIG_CONSOLELOG_H */

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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,12 +32,9 @@
#include "common/log/FileLog.h" #include "common/log/FileLog.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "core/Config.h"
#include "core/Controller.h"
FileLog::FileLog(xmrig::Controller *controller, const char *fileName) : xmrig::FileLog::FileLog(const char *fileName)
m_controller(controller)
{ {
uv_fs_t req; uv_fs_t req;
m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr); m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
@ -44,7 +42,7 @@ FileLog::FileLog(xmrig::Controller *controller, const char *fileName) :
} }
void FileLog::message(Level level, const char* fmt, va_list args) void xmrig::FileLog::message(Level level, const char* fmt, va_list args)
{ {
if (m_file < 0) { if (m_file < 0) {
return; return;
@ -59,8 +57,6 @@ void FileLog::message(Level level, const char* fmt, va_list args)
localtime_r(&now, &stime); localtime_r(&now, &stime);
# endif # endif
const bool isColors = m_controller->config()->isColors();
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s", snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
stime.tm_year + 1900, stime.tm_year + 1900,
stime.tm_mon + 1, stime.tm_mon + 1,
@ -68,9 +64,9 @@ void FileLog::message(Level level, const char* fmt, va_list args)
stime.tm_hour, stime.tm_hour,
stime.tm_min, stime.tm_min,
stime.tm_sec, stime.tm_sec,
Log::colorByLevel(level, isColors), Log::colorByLevel(level, Log::colors),
fmt, fmt,
Log::endl(isColors) Log::endl(Log::colors)
); );
char *buf = new char[kBufferSize]; char *buf = new char[kBufferSize];
@ -80,13 +76,13 @@ void FileLog::message(Level level, const char* fmt, va_list args)
} }
void FileLog::text(const char* fmt, va_list args) void xmrig::FileLog::text(const char* fmt, va_list args)
{ {
message(INFO, fmt, args); message(INFO, fmt, args);
} }
void FileLog::onWrite(uv_fs_t *req) void xmrig::FileLog::onWrite(uv_fs_t *req)
{ {
delete [] static_cast<char *>(req->data); delete [] static_cast<char *>(req->data);
@ -95,7 +91,7 @@ void FileLog::onWrite(uv_fs_t *req)
} }
void FileLog::write(char *data, size_t size) void xmrig::FileLog::write(char *data, size_t size)
{ {
uv_buf_t buf = uv_buf_init(data, (unsigned int) size); uv_buf_t buf = uv_buf_init(data, (unsigned int) size);
uv_fs_t *req = new uv_fs_t; uv_fs_t *req = new uv_fs_t;

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -21,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __FILELOG_H__ #ifndef XMRIG_FILELOG_H
#define __FILELOG_H__ #define XMRIG_FILELOG_H
#include <uv.h> #include <uv.h>
@ -32,14 +33,12 @@
namespace xmrig { namespace xmrig {
class Controller;
}
class FileLog : public ILogBackend class FileLog : public ILogBackend
{ {
public: public:
FileLog(xmrig::Controller *controller, const char *fileName); FileLog(const char *fileName);
void message(Level level, const char* fmt, va_list args) override; void message(Level level, const char* fmt, va_list args) override;
void text(const char* fmt, va_list args) override; void text(const char* fmt, va_list args) override;
@ -51,7 +50,10 @@ private:
char m_fmt[256]; char m_fmt[256];
int m_file; int m_file;
xmrig::Controller *m_controller;
}; };
#endif /* __FILELOG_H__ */
} /* namespace xmrig */
#endif /* XMRIG_FILELOG_H */

View file

@ -35,6 +35,8 @@
#include "common/log/Log.h" #include "common/log/Log.h"
namespace xmrig {
Log *Log::m_self = nullptr; Log *Log::m_self = nullptr;
bool Log::colors = true; bool Log::colors = true;
@ -51,8 +53,10 @@ static const char *color[5] = {
# endif # endif
}; };
} /* namespace xmrig */
void Log::message(ILogBackend::Level level, const char* fmt, ...)
void xmrig::Log::message(ILogBackend::Level level, const char* fmt, ...)
{ {
uv_mutex_lock(&m_mutex); uv_mutex_lock(&m_mutex);
@ -72,7 +76,7 @@ void Log::message(ILogBackend::Level level, const char* fmt, ...)
} }
void Log::text(const char* fmt, ...) void xmrig::Log::text(const char* fmt, ...)
{ {
uv_mutex_lock(&m_mutex); uv_mutex_lock(&m_mutex);
@ -92,7 +96,7 @@ void Log::text(const char* fmt, ...)
} }
const char *Log::colorByLevel(ILogBackend::Level level, bool isColors) const char *xmrig::Log::colorByLevel(ILogBackend::Level level, bool isColors)
{ {
if (!isColors) { if (!isColors) {
return ""; return "";
@ -102,7 +106,7 @@ const char *Log::colorByLevel(ILogBackend::Level level, bool isColors)
} }
const char *Log::endl(bool isColors) const char *xmrig::Log::endl(bool isColors)
{ {
# ifdef _WIN32 # ifdef _WIN32
return isColors ? "\x1B[0m\r\n" : "\r\n"; return isColors ? "\x1B[0m\r\n" : "\r\n";
@ -112,7 +116,7 @@ const char *Log::endl(bool isColors)
} }
void Log::defaultInit() void xmrig::Log::defaultInit()
{ {
m_self = new Log(); m_self = new Log();
@ -120,8 +124,10 @@ void Log::defaultInit()
} }
Log::~Log() xmrig::Log::~Log()
{ {
m_self = nullptr;
for (auto backend : m_backends) { for (auto backend : m_backends) {
delete backend; delete backend;
} }

View file

@ -34,6 +34,9 @@
#include "common/interfaces/ILogBackend.h" #include "common/interfaces/ILogBackend.h"
namespace xmrig {
class Log class Log
{ {
public: public:
@ -68,6 +71,9 @@ private:
}; };
} /* namespace xmrig */
#define RED_BOLD(x) "\x1B[1;31m" x "\x1B[0m" #define RED_BOLD(x) "\x1B[1;31m" x "\x1B[0m"
#define RED(x) "\x1B[0;31m" x "\x1B[0m" #define RED(x) "\x1B[0;31m" x "\x1B[0m"
#define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m" #define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m"
@ -83,20 +89,20 @@ private:
#define GRAY(x) "\x1B[1;30m" x "\x1B[0m" #define GRAY(x) "\x1B[1;30m" x "\x1B[0m"
#define LOG_ERR(x, ...) Log::i()->message(ILogBackend::ERR, x, ##__VA_ARGS__) #define LOG_ERR(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::ERR, x, ##__VA_ARGS__)
#define LOG_WARN(x, ...) Log::i()->message(ILogBackend::WARNING, x, ##__VA_ARGS__) #define LOG_WARN(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::WARNING, x, ##__VA_ARGS__)
#define LOG_NOTICE(x, ...) Log::i()->message(ILogBackend::NOTICE, x, ##__VA_ARGS__) #define LOG_NOTICE(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::NOTICE, x, ##__VA_ARGS__)
#define LOG_INFO(x, ...) Log::i()->message(ILogBackend::INFO, x, ##__VA_ARGS__) #define LOG_INFO(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::INFO, x, ##__VA_ARGS__)
#ifdef APP_DEBUG #ifdef APP_DEBUG
# define LOG_DEBUG(x, ...) Log::i()->message(ILogBackend::DEBUG, x, ##__VA_ARGS__) # define LOG_DEBUG(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::DEBUG, x, ##__VA_ARGS__)
#else #else
# define LOG_DEBUG(x, ...) # define LOG_DEBUG(x, ...)
#endif #endif
#if defined(APP_DEBUG) || defined(APP_DEVEL) #if defined(APP_DEBUG) || defined(APP_DEVEL)
# define LOG_DEBUG_ERR(x, ...) Log::i()->message(ILogBackend::ERR, x, ##__VA_ARGS__) # define LOG_DEBUG_ERR(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::ERR, x, ##__VA_ARGS__)
# define LOG_DEBUG_WARN(x, ...) Log::i()->message(ILogBackend::WARNING, x, ##__VA_ARGS__) # define LOG_DEBUG_WARN(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::WARNING, x, ##__VA_ARGS__)
#else #else
# define LOG_DEBUG_ERR(x, ...) # define LOG_DEBUG_ERR(x, ...)
# define LOG_DEBUG_WARN(x, ...) # define LOG_DEBUG_WARN(x, ...)

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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,19 +30,19 @@
#include "version.h" #include "version.h"
SysLog::SysLog() xmrig::SysLog::SysLog()
{ {
openlog(APP_ID, LOG_PID, LOG_USER); openlog(APP_ID, LOG_PID, LOG_USER);
} }
void SysLog::message(Level level, const char *fmt, va_list args) void xmrig::SysLog::message(Level level, const char *fmt, va_list args)
{ {
vsyslog(static_cast<int>(level), fmt, args); vsyslog(static_cast<int>(level), fmt, args);
} }
void SysLog::text(const char *fmt, va_list args) void xmrig::SysLog::text(const char *fmt, va_list args)
{ {
vsyslog(LOG_INFO, fmt, args); vsyslog(LOG_INFO, fmt, args);
} }

View file

@ -5,7 +5,8 @@
* 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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * 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> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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
@ -21,13 +22,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __SYSLOG_H__ #ifndef XMRIG_SYSLOG_H
#define __SYSLOG_H__ #define XMRIG_SYSLOG_H
#include "common/interfaces/ILogBackend.h" #include "common/interfaces/ILogBackend.h"
namespace xmrig {
class SysLog : public ILogBackend class SysLog : public ILogBackend
{ {
public: public:
@ -37,4 +41,8 @@ public:
void text(const char *fmt, va_list args) override; void text(const char *fmt, va_list args) override;
}; };
#endif /* __SYSLOG_BACKEND_H__ */
} /* namespace xmrig */
#endif /* XMRIG_SYSLOG_H */

View file

@ -61,21 +61,24 @@ enum AlgoVariant {
enum Variant { enum Variant {
VARIANT_AUTO = -1, // Autodetect VARIANT_AUTO = -1, // Autodetect
VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy
VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7 VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7
VARIANT_TUBE = 2, // Modified CryptoNight-Heavy (TUBE only) VARIANT_TUBE = 2, // Modified CryptoNight-Heavy (TUBE only)
VARIANT_XTL = 3, // Modified CryptoNight variant 1 (Stellite only) VARIANT_XTL = 3, // Modified CryptoNight variant 1 (Stellite only)
VARIANT_MSR = 4, // Modified CryptoNight variant 1 (Masari only) VARIANT_MSR = 4, // Modified CryptoNight variant 1 (Masari only)
VARIANT_XHV = 5, // Modified CryptoNight-Heavy (Haven Protocol only) VARIANT_XHV = 5, // Modified CryptoNight-Heavy (Haven Protocol only)
VARIANT_XAO = 6, // Modified CryptoNight variant 0 (Alloy only) VARIANT_XAO = 6, // Modified CryptoNight variant 0 (Alloy only)
VARIANT_RTO = 7, // Modified CryptoNight variant 1 (Arto only) VARIANT_RTO = 7, // Modified CryptoNight variant 1 (Arto only)
VARIANT_2 = 8, // CryptoNight variant 2 VARIANT_2 = 8, // CryptoNight variant 2
VARIANT_HALF = 9, // CryptoNight variant 2 with half iterations (Masari/Stellite) VARIANT_HALF = 9, // CryptoNight variant 2 with half iterations (Masari/Stellite)
VARIANT_TRTL = 10, // CryptoNight Turtle (TRTL) VARIANT_TRTL = 10, // CryptoNight Turtle (TRTL)
VARIANT_GPU = 11, // CryptoNight-GPU (Ryo) VARIANT_GPU = 11, // CryptoNight-GPU (Ryo)
VARIANT_WOW = 12, // CryptoNightR (Wownero) VARIANT_WOW = 12, // CryptoNightR (Wownero)
VARIANT_4 = 13, // CryptoNightR (Monero's variant 4) VARIANT_4 = 13, // CryptoNightR (Monero's variant 4)
VARIANT_RWZ = 14, // CryptoNight variant 2 with 3/4 iterations and reversed shuffle operation (Graft)
VARIANT_ZLS = 15, // CryptoNight variant 2 with 3/4 iterations (Zelerius)
VARIANT_DOUBLE = 16, // CryptoNight variant 2 with double iterations (X-CASH)
VARIANT_MAX VARIANT_MAX
}; };

View file

@ -16,6 +16,7 @@
"cpu-affinity": null, "cpu-affinity": null,
"cpu-priority": null, "cpu-priority": null,
"donate-level": 5, "donate-level": 5,
"donate-over-proxy": 1,
"huge-pages": true, "huge-pages": true,
"hw-aes": null, "hw-aes": null,
"log-file": null, "log-file": null,
@ -39,5 +40,5 @@
"safe": false, "safe": false,
"threads": null, "threads": null,
"user-agent": null, "user-agent": null,
"watch": false "watch": true
} }

View file

@ -97,17 +97,18 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
doc.AddMember("cpu-affinity", kNullType, allocator); doc.AddMember("cpu-affinity", kNullType, allocator);
} }
doc.AddMember("cpu-priority", priority() != -1 ? Value(priority()) : Value(kNullType), allocator); doc.AddMember("cpu-priority", priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
doc.AddMember("donate-level", donateLevel(), allocator); doc.AddMember("donate-level", m_pools.donateLevel(), allocator);
doc.AddMember("huge-pages", isHugePages(), allocator); doc.AddMember("donate-over-proxy", m_pools.proxyDonate(), allocator);
doc.AddMember("hw-aes", m_aesMode == AES_AUTO ? Value(kNullType) : Value(m_aesMode == AES_HW), allocator); doc.AddMember("huge-pages", isHugePages(), allocator);
doc.AddMember("log-file", logFile() ? Value(StringRef(logFile())).Move() : Value(kNullType).Move(), allocator); doc.AddMember("hw-aes", m_aesMode == AES_AUTO ? Value(kNullType) : Value(m_aesMode == AES_HW), allocator);
doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator); doc.AddMember("log-file", m_logFile.toJSON(), allocator);
doc.AddMember("pools", m_pools.toJSON(doc), allocator); doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator);
doc.AddMember("print-time", printTime(), allocator); doc.AddMember("pools", m_pools.toJSON(doc), allocator);
doc.AddMember("retries", m_pools.retries(), allocator); doc.AddMember("print-time", printTime(), allocator);
doc.AddMember("retry-pause", m_pools.retryPause(), allocator); doc.AddMember("retries", m_pools.retries(), allocator);
doc.AddMember("safe", m_safe, allocator); doc.AddMember("retry-pause", m_pools.retryPause(), allocator);
doc.AddMember("safe", m_safe, allocator);
if (threadsMode() != Simple) { if (threadsMode() != Simple) {
Value threads(kArrayType); Value threads(kArrayType);

View file

@ -0,0 +1,84 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 XMRIG_CONFIGLOADER_DEFAULT_H
#define XMRIG_CONFIGLOADER_DEFAULT_H
namespace xmrig {
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
const static char *default_config =
R"===(
{
"algo": "cryptonight",
"api": {
"port": 0,
"access-token": null,
"id": null,
"worker-id": null,
"ipv6": false,
"restricted": true
},
"asm": true,
"autosave": true,
"av": 0,
"background": false,
"colors": true,
"cpu-affinity": null,
"cpu-priority": null,
"donate-level": 5,
"huge-pages": true,
"hw-aes": null,
"log-file": null,
"max-cpu-usage": 100,
"pools": [
{
"url": "donate.v2.xmrig.com:3333",
"user": "YOUR_WALLET_ADDRESS",
"pass": "x",
"rig-id": null,
"nicehash": false,
"keepalive": false,
"variant": -1,
"tls": false,
"tls-fingerprint": null
}
],
"print-time": 60,
"retries": 5,
"retry-pause": 5,
"safe": false,
"threads": null,
"user-agent": null,
"watch": false
}
)===";
#endif
} /* namespace xmrig */
#endif /* XMRIG_CONFIGLOADER_DEFAULT_H */

View file

@ -44,81 +44,83 @@ static char const short_options[] = "a:c:kBp:Px:r:R:s:t:T:o:u:O:v:l:S";
static struct option const options[] = { static struct option const options[] = {
{ "algo", 1, nullptr, xmrig::IConfig::AlgorithmKey }, { "algo", 1, nullptr, IConfig::AlgorithmKey },
{ "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey }, { "api-access-token", 1, nullptr, IConfig::ApiAccessTokenKey },
{ "api-port", 1, nullptr, xmrig::IConfig::ApiPort }, { "api-port", 1, nullptr, IConfig::ApiPort },
{ "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, { "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey },
{ "api-id", 1, nullptr, xmrig::IConfig::ApiIdKey }, { "api-id", 1, nullptr, IConfig::ApiIdKey },
{ "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, { "api-ipv6", 0, nullptr, IConfig::ApiIPv6Key },
{ "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, { "api-no-restricted", 0, nullptr, IConfig::ApiRestrictedKey },
{ "av", 1, nullptr, xmrig::IConfig::AVKey }, { "av", 1, nullptr, IConfig::AVKey },
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey }, { "background", 0, nullptr, IConfig::BackgroundKey },
{ "config", 1, nullptr, xmrig::IConfig::ConfigKey }, { "config", 1, nullptr, IConfig::ConfigKey },
{ "cpu-affinity", 1, nullptr, xmrig::IConfig::CPUAffinityKey }, { "cpu-affinity", 1, nullptr, IConfig::CPUAffinityKey },
{ "cpu-priority", 1, nullptr, xmrig::IConfig::CPUPriorityKey }, { "cpu-priority", 1, nullptr, IConfig::CPUPriorityKey },
{ "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey }, { "donate-level", 1, nullptr, IConfig::DonateLevelKey },
{ "dry-run", 0, nullptr, xmrig::IConfig::DryRunKey }, { "donate-over-proxy", 1, nullptr, IConfig::ProxyDonateKey },
{ "keepalive", 0, nullptr, xmrig::IConfig::KeepAliveKey }, { "dry-run", 0, nullptr, IConfig::DryRunKey },
{ "log-file", 1, nullptr, xmrig::IConfig::LogFileKey }, { "keepalive", 0, nullptr, IConfig::KeepAliveKey },
{ "max-cpu-usage", 1, nullptr, xmrig::IConfig::MaxCPUUsageKey }, { "log-file", 1, nullptr, IConfig::LogFileKey },
{ "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey }, { "max-cpu-usage", 1, nullptr, IConfig::MaxCPUUsageKey },
{ "no-color", 0, nullptr, xmrig::IConfig::ColorKey }, { "nicehash", 0, nullptr, IConfig::NicehashKey },
{ "no-watch", 0, nullptr, xmrig::IConfig::WatchKey }, { "no-color", 0, nullptr, IConfig::ColorKey },
{ "no-huge-pages", 0, nullptr, xmrig::IConfig::HugePagesKey }, { "no-watch", 0, nullptr, IConfig::WatchKey },
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey }, { "no-huge-pages", 0, nullptr, IConfig::HugePagesKey },
{ "pass", 1, nullptr, xmrig::IConfig::PasswordKey }, { "variant", 1, nullptr, IConfig::VariantKey },
{ "print-time", 1, nullptr, xmrig::IConfig::PrintTimeKey }, { "pass", 1, nullptr, IConfig::PasswordKey },
{ "retries", 1, nullptr, xmrig::IConfig::RetriesKey }, { "print-time", 1, nullptr, IConfig::PrintTimeKey },
{ "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey }, { "retries", 1, nullptr, IConfig::RetriesKey },
{ "safe", 0, nullptr, xmrig::IConfig::SafeKey }, { "retry-pause", 1, nullptr, IConfig::RetryPauseKey },
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey }, { "safe", 0, nullptr, IConfig::SafeKey },
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey }, { "syslog", 0, nullptr, IConfig::SyslogKey },
{ "url", 1, nullptr, xmrig::IConfig::UrlKey }, { "threads", 1, nullptr, IConfig::ThreadsKey },
{ "user", 1, nullptr, xmrig::IConfig::UserKey }, { "url", 1, nullptr, IConfig::UrlKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "user", 1, nullptr, IConfig::UserKey },
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, { "user-agent", 1, nullptr, IConfig::UserAgentKey },
{ "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, { "userpass", 1, nullptr, IConfig::UserpassKey },
{ "tls", 0, nullptr, xmrig::IConfig::TlsKey }, { "rig-id", 1, nullptr, IConfig::RigIdKey },
{ "tls-fingerprint", 1, nullptr, xmrig::IConfig::FingerprintKey }, { "tls", 0, nullptr, IConfig::TlsKey },
{ "asm", 1, nullptr, xmrig::IConfig::AssemblyKey }, { "tls-fingerprint", 1, nullptr, IConfig::FingerprintKey },
{ "asm", 1, nullptr, IConfig::AssemblyKey },
{ nullptr, 0, nullptr, 0 } { nullptr, 0, nullptr, 0 }
}; };
static struct option const config_options[] = { static struct option const config_options[] = {
{ "algo", 1, nullptr, xmrig::IConfig::AlgorithmKey }, { "algo", 1, nullptr, IConfig::AlgorithmKey },
{ "av", 1, nullptr, xmrig::IConfig::AVKey }, { "av", 1, nullptr, IConfig::AVKey },
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey }, { "background", 0, nullptr, IConfig::BackgroundKey },
{ "colors", 0, nullptr, xmrig::IConfig::ColorKey }, { "colors", 0, nullptr, IConfig::ColorKey },
{ "cpu-affinity", 1, nullptr, xmrig::IConfig::CPUAffinityKey }, { "cpu-affinity", 1, nullptr, IConfig::CPUAffinityKey },
{ "cpu-priority", 1, nullptr, xmrig::IConfig::CPUPriorityKey }, { "cpu-priority", 1, nullptr, IConfig::CPUPriorityKey },
{ "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey }, { "donate-level", 1, nullptr, IConfig::DonateLevelKey },
{ "dry-run", 0, nullptr, xmrig::IConfig::DryRunKey }, { "donate-over-proxy", 1, nullptr, IConfig::ProxyDonateKey },
{ "huge-pages", 0, nullptr, xmrig::IConfig::HugePagesKey }, { "dry-run", 0, nullptr, IConfig::DryRunKey },
{ "log-file", 1, nullptr, xmrig::IConfig::LogFileKey }, { "huge-pages", 0, nullptr, IConfig::HugePagesKey },
{ "max-cpu-usage", 1, nullptr, xmrig::IConfig::MaxCPUUsageKey }, { "log-file", 1, nullptr, IConfig::LogFileKey },
{ "print-time", 1, nullptr, xmrig::IConfig::PrintTimeKey }, { "max-cpu-usage", 1, nullptr, IConfig::MaxCPUUsageKey },
{ "retries", 1, nullptr, xmrig::IConfig::RetriesKey }, { "print-time", 1, nullptr, IConfig::PrintTimeKey },
{ "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey }, { "retries", 1, nullptr, IConfig::RetriesKey },
{ "safe", 0, nullptr, xmrig::IConfig::SafeKey }, { "retry-pause", 1, nullptr, IConfig::RetryPauseKey },
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey }, { "safe", 0, nullptr, IConfig::SafeKey },
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey }, { "syslog", 0, nullptr, IConfig::SyslogKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "threads", 1, nullptr, IConfig::ThreadsKey },
{ "watch", 0, nullptr, xmrig::IConfig::WatchKey }, { "user-agent", 1, nullptr, IConfig::UserAgentKey },
{ "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey }, { "watch", 0, nullptr, IConfig::WatchKey },
{ "asm", 1, nullptr, xmrig::IConfig::AssemblyKey }, { "hw-aes", 0, nullptr, IConfig::HardwareAESKey },
{ "autosave", 0, nullptr, xmrig::IConfig::AutoSaveKey }, { "asm", 1, nullptr, IConfig::AssemblyKey },
{ nullptr, 0, nullptr, 0 } { "autosave", 0, nullptr, IConfig::AutoSaveKey },
{ nullptr, 0, nullptr, 0 }
}; };
static struct option const api_options[] = { static struct option const api_options[] = {
{ "port", 1, nullptr, xmrig::IConfig::ApiPort }, { "port", 1, nullptr, IConfig::ApiPort },
{ "access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey }, { "access-token", 1, nullptr, IConfig::ApiAccessTokenKey },
{ "worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, { "worker-id", 1, nullptr, IConfig::ApiWorkerIdKey },
{ "ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, { "ipv6", 0, nullptr, IConfig::ApiIPv6Key },
{ "restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, { "restricted", 0, nullptr, IConfig::ApiRestrictedKey },
{ "id", 1, nullptr, xmrig::IConfig::ApiIdKey }, { "id", 1, nullptr, IConfig::ApiIdKey },
{ nullptr, 0, nullptr, 0 } { nullptr, 0, nullptr, 0 }
}; };

View file

@ -75,8 +75,6 @@ xmrig::Controller::Controller(Process *process)
xmrig::Controller::~Controller() xmrig::Controller::~Controller()
{ {
ConfigLoader::release();
delete d_ptr; delete d_ptr;
} }
@ -99,7 +97,7 @@ int xmrig::Controller::init()
{ {
Cpu::init(); Cpu::init();
d_ptr->config = xmrig::Config::load(d_ptr->process, this); d_ptr->config = Config::load(d_ptr->process, this);
if (!d_ptr->config) { if (!d_ptr->config) {
return 1; return 1;
} }
@ -109,11 +107,11 @@ int xmrig::Controller::init()
Platform::setProcessPriority(d_ptr->config->priority()); Platform::setProcessPriority(d_ptr->config->priority());
if (!config()->isBackground()) { if (!config()->isBackground()) {
Log::add(new ConsoleLog(this)); Log::add(new ConsoleLog());
} }
if (config()->logFile()) { if (config()->logFile()) {
Log::add(new FileLog(this, config()->logFile())); Log::add(new FileLog(config()->logFile()));
} }
# ifdef HAVE_SYSLOG_H # ifdef HAVE_SYSLOG_H
@ -166,3 +164,12 @@ void xmrig::Controller::onNewConfig(IConfig *config)
delete previousConfig; delete previousConfig;
} }
void xmrig::Controller::stop()
{
ConfigLoader::release();
delete d_ptr->network;
d_ptr->network = nullptr;
}

View file

@ -54,6 +54,7 @@ public:
Network *network() const; Network *network() const;
void addListener(IControllerListener *listener); void addListener(IControllerListener *listener);
void save(); void save();
void stop();
protected: protected:
void onNewConfig(IConfig *config) override; void onNewConfig(IConfig *config) override;

View file

@ -85,7 +85,7 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
} }
} }
m_avx2 = data.flags[CPU_FEATURE_AVX2]; m_avx2 = data.flags[CPU_FEATURE_AVX2] && data.flags[CPU_FEATURE_OSXSAVE];
} }

View file

@ -36,8 +36,7 @@
#endif #endif
struct cryptonight_ctx; struct cryptonight_ctx;
typedef void(*cn_mainloop_fun_ms_abi)(cryptonight_ctx*) ABI_ATTRIBUTE; typedef void(*cn_mainloop_fun_ms_abi)(cryptonight_ctx**) ABI_ATTRIBUTE;
typedef void(*cn_mainloop_double_fun_ms_abi)(cryptonight_ctx*, cryptonight_ctx*) ABI_ATTRIBUTE;
struct cryptonight_r_data { struct cryptonight_r_data {
int variant; int variant;
@ -49,8 +48,12 @@ struct cryptonight_r_data {
struct cryptonight_ctx { struct cryptonight_ctx {
alignas(16) uint8_t state[224]; alignas(16) uint8_t state[224];
alignas(16) uint8_t *memory; alignas(16) uint8_t *memory;
uint8_t unused[40];
const uint32_t* saes_table;
cn_mainloop_fun_ms_abi generated_code; cn_mainloop_fun_ms_abi generated_code;
cn_mainloop_double_fun_ms_abi generated_code_double; cn_mainloop_fun_ms_abi generated_code_double;
cryptonight_r_data generated_code_data; cryptonight_r_data generated_code_data;
cryptonight_r_data generated_code_double_data; cryptonight_r_data generated_code_double_data;
}; };

View file

@ -436,7 +436,7 @@ static inline void cryptonight_monero_tweak(const uint8_t* l, uint64_t idx, __m1
uint64_t* mem_out = (uint64_t*)&l[idx]; uint64_t* mem_out = (uint64_t*)&l[idx];
if (BASE == xmrig::VARIANT_2) { if (BASE == xmrig::VARIANT_2) {
VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1, cx); VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1, cx, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0));
_mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx)); _mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx));
} else { } else {
__m128i tmp = _mm_xor_si128(bx0, cx); __m128i tmp = _mm_xor_si128(bx0, cx);
@ -530,9 +530,9 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
if (BASE == xmrig::VARIANT_2) { if (BASE == xmrig::VARIANT_2) {
if (VARIANT == xmrig::VARIANT_4) { if (VARIANT == xmrig::VARIANT_4) {
VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx0, bx1, cx); VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx0, bx1, cx, 0);
} else { } else {
VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo); VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0));
} }
} }
@ -709,9 +709,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
if (BASE == xmrig::VARIANT_2) { if (BASE == xmrig::VARIANT_2) {
if (VARIANT == xmrig::VARIANT_4) { if (VARIANT == xmrig::VARIANT_4) {
VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx00, bx01, cx0); VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx00, bx01, cx0, 0);
} else { } else {
VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo); VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0));
} }
} }
@ -767,9 +767,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
if (BASE == xmrig::VARIANT_2) { if (BASE == xmrig::VARIANT_2) {
if (VARIANT == xmrig::VARIANT_4) { if (VARIANT == xmrig::VARIANT_4) {
VARIANT2_SHUFFLE(l1, idx1 & MASK, ax1, bx10, bx11, cx1); VARIANT2_SHUFFLE(l1, idx1 & MASK, ax1, bx10, bx11, cx1, 0);
} else { } else {
VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo); VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0));
} }
} }

View file

@ -42,6 +42,9 @@ constexpr const uint32_t CRYPTONIGHT_MASK = 0x1FFFF0;
constexpr const uint32_t CRYPTONIGHT_ITER = 0x80000; constexpr const uint32_t CRYPTONIGHT_ITER = 0x80000;
constexpr const uint32_t CRYPTONIGHT_HALF_ITER = 0x40000; constexpr const uint32_t CRYPTONIGHT_HALF_ITER = 0x40000;
constexpr const uint32_t CRYPTONIGHT_XAO_ITER = 0x100000; constexpr const uint32_t CRYPTONIGHT_XAO_ITER = 0x100000;
constexpr const uint32_t CRYPTONIGHT_DOUBLE_ITER = 0x100000;
constexpr const uint32_t CRYPTONIGHT_WALTZ_ITER = 0x60000;
constexpr const uint32_t CRYPTONIGHT_ZLS_ITER = 0x60000;
constexpr const uint32_t CRYPTONIGHT_GPU_ITER = 0xC000; constexpr const uint32_t CRYPTONIGHT_GPU_ITER = 0xC000;
constexpr const uint32_t CRYPTONIGHT_GPU_MASK = 0x1FFFC0; constexpr const uint32_t CRYPTONIGHT_GPU_MASK = 0x1FFFC0;
@ -134,6 +137,9 @@ template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_MSR>()
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_XAO>() { return CRYPTONIGHT_XAO_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_XAO>() { return CRYPTONIGHT_XAO_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_RTO>() { return CRYPTONIGHT_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_RTO>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_GPU>() { return CRYPTONIGHT_GPU_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_GPU>() { return CRYPTONIGHT_GPU_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_RWZ>() { return CRYPTONIGHT_WALTZ_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_ZLS>() { return CRYPTONIGHT_ZLS_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_DOUBLE>() { return CRYPTONIGHT_DOUBLE_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE, VARIANT_0>() { return CRYPTONIGHT_LITE_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE, VARIANT_0>() { return CRYPTONIGHT_LITE_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE, VARIANT_1>() { return CRYPTONIGHT_LITE_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE, VARIANT_1>() { return CRYPTONIGHT_LITE_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY, VARIANT_0>() { return CRYPTONIGHT_HEAVY_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY, VARIANT_0>() { return CRYPTONIGHT_HEAVY_ITER; }
@ -153,11 +159,16 @@ inline uint32_t cn_select_iter(Algo algorithm, Variant variant)
return CRYPTONIGHT_GPU_ITER; return CRYPTONIGHT_GPU_ITER;
case VARIANT_RTO: case VARIANT_RTO:
case VARIANT_DOUBLE:
return CRYPTONIGHT_XAO_ITER; return CRYPTONIGHT_XAO_ITER;
case VARIANT_TRTL: case VARIANT_TRTL:
return CRYPTONIGHT_TRTL_ITER; return CRYPTONIGHT_TRTL_ITER;
case VARIANT_RWZ:
case VARIANT_ZLS:
return CRYPTONIGHT_WALTZ_ITER;
default: default:
break; break;
} }
@ -184,26 +195,55 @@ inline uint32_t cn_select_iter(Algo algorithm, Variant variant)
} }
template<Variant variant> inline constexpr Variant cn_base_variant() { return VARIANT_0; } template<Variant variant> inline constexpr Variant cn_base_variant() { return VARIANT_0; }
template<> inline constexpr Variant cn_base_variant<VARIANT_0>() { return VARIANT_0; } template<> inline constexpr Variant cn_base_variant<VARIANT_0>() { return VARIANT_0; }
template<> inline constexpr Variant cn_base_variant<VARIANT_1>() { return VARIANT_1; } template<> inline constexpr Variant cn_base_variant<VARIANT_1>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_TUBE>() { return VARIANT_1; } template<> inline constexpr Variant cn_base_variant<VARIANT_TUBE>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_XTL>() { return VARIANT_1; } template<> inline constexpr Variant cn_base_variant<VARIANT_XTL>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_MSR>() { return VARIANT_1; } template<> inline constexpr Variant cn_base_variant<VARIANT_MSR>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_XHV>() { return VARIANT_0; } template<> inline constexpr Variant cn_base_variant<VARIANT_XHV>() { return VARIANT_0; }
template<> inline constexpr Variant cn_base_variant<VARIANT_XAO>() { return VARIANT_0; } template<> inline constexpr Variant cn_base_variant<VARIANT_XAO>() { return VARIANT_0; }
template<> inline constexpr Variant cn_base_variant<VARIANT_RTO>() { return VARIANT_1; } template<> inline constexpr Variant cn_base_variant<VARIANT_RTO>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_2>() { return VARIANT_2; } template<> inline constexpr Variant cn_base_variant<VARIANT_2>() { return VARIANT_2; }
template<> inline constexpr Variant cn_base_variant<VARIANT_HALF>() { return VARIANT_2; } template<> inline constexpr Variant cn_base_variant<VARIANT_HALF>() { return VARIANT_2; }
template<> inline constexpr Variant cn_base_variant<VARIANT_TRTL>() { return VARIANT_2; } template<> inline constexpr Variant cn_base_variant<VARIANT_TRTL>() { return VARIANT_2; }
template<> inline constexpr Variant cn_base_variant<VARIANT_GPU>() { return VARIANT_GPU; } template<> inline constexpr Variant cn_base_variant<VARIANT_GPU>() { return VARIANT_GPU; }
template<> inline constexpr Variant cn_base_variant<VARIANT_WOW>() { return VARIANT_2; } template<> inline constexpr Variant cn_base_variant<VARIANT_WOW>() { return VARIANT_2; }
template<> inline constexpr Variant cn_base_variant<VARIANT_4>() { return VARIANT_2; } template<> inline constexpr Variant cn_base_variant<VARIANT_4>() { return VARIANT_2; }
template<> inline constexpr Variant cn_base_variant<VARIANT_RWZ>() { return VARIANT_2; }
template<> inline constexpr Variant cn_base_variant<VARIANT_ZLS>() { return VARIANT_2; }
template<> inline constexpr Variant cn_base_variant<VARIANT_DOUBLE>() { return VARIANT_2; }
inline Variant cn_base_variant(Variant variant)
{
switch (variant) {
case VARIANT_0:
case VARIANT_XHV:
case VARIANT_XAO:
return VARIANT_0;
case VARIANT_1:
case VARIANT_TUBE:
case VARIANT_XTL:
case VARIANT_MSR:
case VARIANT_RTO:
return VARIANT_1;
case VARIANT_GPU:
return VARIANT_GPU;
default:
break;
}
return VARIANT_2;
}
template<Variant variant> inline constexpr bool cn_is_cryptonight_r() { return false; } template<Variant variant> inline constexpr bool cn_is_cryptonight_r() { return false; }
template<> inline constexpr bool cn_is_cryptonight_r<VARIANT_WOW>() { return true; } template<> inline constexpr bool cn_is_cryptonight_r<VARIANT_WOW>() { return true; }
template<> inline constexpr bool cn_is_cryptonight_r<VARIANT_4>() { return true; } template<> inline constexpr bool cn_is_cryptonight_r<VARIANT_4>() { return true; }
} /* namespace xmrig */ } /* namespace xmrig */

View file

@ -83,11 +83,11 @@
sqrt_result_xmm_##part = int_sqrt_v2(cx_0 + division_result); \ sqrt_result_xmm_##part = int_sqrt_v2(cx_0 + division_result); \
} while (0) } while (0)
# define VARIANT2_SHUFFLE(base_ptr, offset, _a, _b, _b1, _c) \ # define VARIANT2_SHUFFLE(base_ptr, offset, _a, _b, _b1, _c, reverse) \
do { \ do { \
const __m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))); \ const __m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ (reverse ? 0x30 : 0x10)))); \
const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \ const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \
const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \ const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ (reverse ? 0x10 : 0x30)))); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \
@ -96,15 +96,20 @@
} \ } \
} while (0) } while (0)
# define VARIANT2_SHUFFLE2(base_ptr, offset, _a, _b, _b1, hi, lo) \ # define VARIANT2_SHUFFLE2(base_ptr, offset, _a, _b, _b1, hi, lo, reverse) \
do { \ do { \
const __m128i chunk1 = _mm_xor_si128(_mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))), _mm_set_epi64x(lo, hi)); \ const __m128i chunk1 = _mm_xor_si128(_mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))), _mm_set_epi64x(lo, hi)); \
const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \ const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \
hi ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[0]; \ hi ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[0]; \
lo ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[1]; \ lo ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[1]; \
const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \ const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \ if (reverse) { \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk1, _b1)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk3, _b)); \
} else { \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \
} \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \
} while (0) } while (0)
@ -128,11 +133,11 @@
sqrt_result_##part += ((r2 + b > sqrt_input) ? -1 : 0) + ((r2 + (1ULL << 32) < sqrt_input - s) ? 1 : 0); \ sqrt_result_##part += ((r2 + b > sqrt_input) ? -1 : 0) + ((r2 + (1ULL << 32) < sqrt_input - s) ? 1 : 0); \
} while (0) } while (0)
# define VARIANT2_SHUFFLE(base_ptr, offset, _a, _b, _b1, _c) \ # define VARIANT2_SHUFFLE(base_ptr, offset, _a, _b, _b1, _c, reverse) \
do { \ do { \
const uint64x2_t chunk1 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10))); \ const uint64x2_t chunk1 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ (reverse ? 0x30 : 0x10)))); \
const uint64x2_t chunk2 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20))); \ const uint64x2_t chunk2 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20))); \
const uint64x2_t chunk3 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30))); \ const uint64x2_t chunk3 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ (reverse ? 0x10 : 0x30)))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \
@ -141,15 +146,20 @@
} \ } \
} while (0) } while (0)
# define VARIANT2_SHUFFLE2(base_ptr, offset, _a, _b, _b1, hi, lo) \ # define VARIANT2_SHUFFLE2(base_ptr, offset, _a, _b, _b1, hi, lo, reverse) \
do { \ do { \
const uint64x2_t chunk1 = veorq_u64(vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10))), vcombine_u64(vcreate_u64(hi), vcreate_u64(lo))); \ const uint64x2_t chunk1 = veorq_u64(vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10))), vcombine_u64(vcreate_u64(hi), vcreate_u64(lo))); \
const uint64x2_t chunk2 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20))); \ const uint64x2_t chunk2 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20))); \
hi ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[0]; \ hi ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[0]; \
lo ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[1]; \ lo ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[1]; \
const uint64x2_t chunk3 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30))); \ const uint64x2_t chunk3 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \ if (reverse) { \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b1))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b))); \
} else { \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \
} \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \
} while (0) } while (0)
#endif #endif
@ -158,6 +168,16 @@
#define SWAP64LE(x) x #define SWAP64LE(x) x
#define hash_extra_blake(data, length, hash) blake256_hash((uint8_t*)(hash), (uint8_t*)(data), (length)) #define hash_extra_blake(data, length, hash) blake256_hash((uint8_t*)(hash), (uint8_t*)(data), (length))
#ifndef NOINLINE
#ifdef __GNUC__
#define NOINLINE __attribute__ ((noinline))
#elif _MSC_VER
#define NOINLINE __declspec(noinline)
#else
#define NOINLINE
#endif
#endif
#include "common/xmrig.h" #include "common/xmrig.h"
#include "variant4_random_math.h" #include "variant4_random_math.h"

View file

@ -58,27 +58,58 @@ const static uint8_t test_input[380] = {
0xCF, 0x50, 0x29, 0x6A, 0x07, 0x0B, 0x93, 0x8F, 0x8F, 0xA8, 0x10, 0x04 0xCF, 0x50, 0x29, 0x6A, 0x07, 0x0B, 0x93, 0x8F, 0x8F, 0xA8, 0x10, 0x04
}; };
const static char* test_input_WOW = R"===(9d47bf4c41b7e8e727e681715acb47fa1677cdba9ca7bcb05ad8cc8abd5daa66 5468697320697320612074657374205468697320697320612074657374205468697320697320612074657374 1806260
0d4a495cb844a3ca8ba4edb8e6bcf829ef1c06d9cdea2b62ca46c2a21b8b0a79 4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e67 1806261
a1d6d848b5c5915fccd2f64cf216c6b1a02cf7c77bc80d8d4e51b419e88ff0dd 656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f7265 1806262
af3a8544a0221a148c2ac90484b19861e3afca33fe17021efb8ad6496b567915 657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c 1806263
313399e0963ae8a99dab8af66d343e097dae0c0feb08dbc43ccdafef5515f413 71756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e697369 1806264
6021c6ef90bff9ae94a7506d623d3a7a86c1756d655f50dd558f716d64622a34 757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e20447569732061757465 1806265
2b13000535f3db5f9b9b84a65c4351f386cd2cdedebb8c3ad2eab086e6a3fee5 697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c6974 1806266
fc0e1dad8e895749dc90eb690bc1ba059a1cd772afaaf65a106bf9e5e6b80503 657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e 1806267
b60b0afe144deff7d903ed2d5545e77ebe66a3c51fee7016eeb8fee9eb630c0f 4578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c 1806268
64774b27e7d5fec862fc4c0c13ac6bf09123b6f05bb0e4b75c97f379a2b3a679 73756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e 1806269)===";
const static char* test_input_R = R"===(f759588ad57e758467295443a9bd71490abff8e9dad1b95b6bf2f5d0d78387bc 5468697320697320612074657374205468697320697320612074657374205468697320697320612074657374 1806260 struct cn_r_test_input_data
5bb833deca2bdd7252a9ccd7b4ce0b6a4854515794b56c207262f7a5b9bdb566 4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e67 1806261 {
1ee6728da60fbd8d7d55b2b1ade487a3cf52a2c3ac6f520db12c27d8921f6cab 656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f7265 1806262 uint64_t height;
6969fe2ddfb758438d48049f302fc2108a4fcc93e37669170e6db4b0b9b4c4cb 657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c 1806263 size_t size;
7f3048b4e90d0cbe7a57c0394f37338a01fae3adfdc0e5126d863a895eb04e02 71756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e697369 1806264 uint8_t data[64];
1d290443a4b542af04a82f6b2494a6ee7f20f2754c58e0849032483a56e8e2ef 757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e20447569732061757465 1806265 };
c43cc6567436a86afbd6aa9eaa7c276e9806830334b614b2bee23cc76634f6fd 697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c6974 1806266
87be2479c0c4e8edfdfaa5603e93f4265b3f8224c1c5946feb424819d18990a4 657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e 1806267
dd9d6a6d8e47465cceac0877ef889b93e7eba979557e3935d7f86dce11b070f3 4578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c 1806268 const static cn_r_test_input_data cn_r_test_input[] = {
75c6f2ae49a20521de97285b431e717125847fb8935ed84a61e7f8d36a2c3d8e 73756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e 1806269)==="; { 1806260, 44, { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74 } },
{ 1806261, 50, { 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, 0x73, 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6d, 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, 0x63, 0x69, 0x6e, 0x67 } },
{ 1806262, 48, { 0x65, 0x6c, 0x69, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x64, 0x20, 0x64, 0x6f, 0x20, 0x65, 0x69, 0x75, 0x73, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x63, 0x69, 0x64, 0x69, 0x64, 0x75, 0x6e, 0x74, 0x20, 0x75, 0x74, 0x20, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x65 } },
{ 1806263, 48, { 0x65, 0x74, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x65, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x61, 0x20, 0x61, 0x6c, 0x69, 0x71, 0x75, 0x61, 0x2e, 0x20, 0x55, 0x74, 0x20, 0x65, 0x6e, 0x69, 0x6d, 0x20, 0x61, 0x64, 0x20, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x20, 0x76, 0x65, 0x6e, 0x69, 0x61, 0x6d, 0x2c } },
{ 1806264, 46, { 0x71, 0x75, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x73, 0x74, 0x72, 0x75, 0x64, 0x20, 0x65, 0x78, 0x65, 0x72, 0x63, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x6c, 0x6c, 0x61, 0x6d, 0x63, 0x6f, 0x20, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x69, 0x73, 0x20, 0x6e, 0x69, 0x73, 0x69 } },
{ 1806265, 45, { 0x75, 0x74, 0x20, 0x61, 0x6c, 0x69, 0x71, 0x75, 0x69, 0x70, 0x20, 0x65, 0x78, 0x20, 0x65, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x64, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x61, 0x74, 0x2e, 0x20, 0x44, 0x75, 0x69, 0x73, 0x20, 0x61, 0x75, 0x74, 0x65 } },
{ 1806266, 47, { 0x69, 0x72, 0x75, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x69, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61, 0x74, 0x65, 0x20, 0x76, 0x65, 0x6c, 0x69, 0x74 } },
{ 1806267, 44, { 0x65, 0x73, 0x73, 0x65, 0x20, 0x63, 0x69, 0x6c, 0x6c, 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x65, 0x20, 0x65, 0x75, 0x20, 0x66, 0x75, 0x67, 0x69, 0x61, 0x74, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x61, 0x20, 0x70, 0x61, 0x72, 0x69, 0x61, 0x74, 0x75, 0x72, 0x2e } },
{ 1806268, 47, { 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x65, 0x75, 0x72, 0x20, 0x73, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x63, 0x63, 0x61, 0x65, 0x63, 0x61, 0x74, 0x20, 0x63, 0x75, 0x70, 0x69, 0x64, 0x61, 0x74, 0x61, 0x74, 0x20, 0x6e, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2c } },
{ 1806269, 62, { 0x73, 0x75, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x75, 0x6c, 0x70, 0x61, 0x20, 0x71, 0x75, 0x69, 0x20, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x20, 0x64, 0x65, 0x73, 0x65, 0x72, 0x75, 0x6e, 0x74, 0x20, 0x6d, 0x6f, 0x6c, 0x6c, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x69, 0x6d, 0x20, 0x69, 0x64, 0x20, 0x65, 0x73, 0x74, 0x20, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x75, 0x6d, 0x2e } },
};
// "cn/wow"
const static uint8_t test_output_wow[] = {
0x9d, 0x47, 0xbf, 0x4c, 0x41, 0xb7, 0xe8, 0xe7, 0x27, 0xe6, 0x81, 0x71, 0x5a, 0xcb, 0x47, 0xfa, 0x16, 0x77, 0xcd, 0xba, 0x9c, 0xa7, 0xbc, 0xb0, 0x5a, 0xd8, 0xcc, 0x8a, 0xbd, 0x5d, 0xaa, 0x66,
0x0d, 0x4a, 0x49, 0x5c, 0xb8, 0x44, 0xa3, 0xca, 0x8b, 0xa4, 0xed, 0xb8, 0xe6, 0xbc, 0xf8, 0x29, 0xef, 0x1c, 0x06, 0xd9, 0xcd, 0xea, 0x2b, 0x62, 0xca, 0x46, 0xc2, 0xa2, 0x1b, 0x8b, 0x0a, 0x79,
0xa1, 0xd6, 0xd8, 0x48, 0xb5, 0xc5, 0x91, 0x5f, 0xcc, 0xd2, 0xf6, 0x4c, 0xf2, 0x16, 0xc6, 0xb1, 0xa0, 0x2c, 0xf7, 0xc7, 0x7b, 0xc8, 0x0d, 0x8d, 0x4e, 0x51, 0xb4, 0x19, 0xe8, 0x8f, 0xf0, 0xdd,
0xaf, 0x3a, 0x85, 0x44, 0xa0, 0x22, 0x1a, 0x14, 0x8c, 0x2a, 0xc9, 0x04, 0x84, 0xb1, 0x98, 0x61, 0xe3, 0xaf, 0xca, 0x33, 0xfe, 0x17, 0x02, 0x1e, 0xfb, 0x8a, 0xd6, 0x49, 0x6b, 0x56, 0x79, 0x15,
0x31, 0x33, 0x99, 0xe0, 0x96, 0x3a, 0xe8, 0xa9, 0x9d, 0xab, 0x8a, 0xf6, 0x6d, 0x34, 0x3e, 0x09, 0x7d, 0xae, 0x0c, 0x0f, 0xeb, 0x08, 0xdb, 0xc4, 0x3c, 0xcd, 0xaf, 0xef, 0x55, 0x15, 0xf4, 0x13,
0x60, 0x21, 0xc6, 0xef, 0x90, 0xbf, 0xf9, 0xae, 0x94, 0xa7, 0x50, 0x6d, 0x62, 0x3d, 0x3a, 0x7a, 0x86, 0xc1, 0x75, 0x6d, 0x65, 0x5f, 0x50, 0xdd, 0x55, 0x8f, 0x71, 0x6d, 0x64, 0x62, 0x2a, 0x34,
0x2b, 0x13, 0x00, 0x05, 0x35, 0xf3, 0xdb, 0x5f, 0x9b, 0x9b, 0x84, 0xa6, 0x5c, 0x43, 0x51, 0xf3, 0x86, 0xcd, 0x2c, 0xde, 0xde, 0xbb, 0x8c, 0x3a, 0xd2, 0xea, 0xb0, 0x86, 0xe6, 0xa3, 0xfe, 0xe5,
0xfc, 0x0e, 0x1d, 0xad, 0x8e, 0x89, 0x57, 0x49, 0xdc, 0x90, 0xeb, 0x69, 0x0b, 0xc1, 0xba, 0x05, 0x9a, 0x1c, 0xd7, 0x72, 0xaf, 0xaa, 0xf6, 0x5a, 0x10, 0x6b, 0xf9, 0xe5, 0xe6, 0xb8, 0x05, 0x03,
0xb6, 0x0b, 0x0a, 0xfe, 0x14, 0x4d, 0xef, 0xf7, 0xd9, 0x03, 0xed, 0x2d, 0x55, 0x45, 0xe7, 0x7e, 0xbe, 0x66, 0xa3, 0xc5, 0x1f, 0xee, 0x70, 0x16, 0xee, 0xb8, 0xfe, 0xe9, 0xeb, 0x63, 0x0c, 0x0f,
0x64, 0x77, 0x4b, 0x27, 0xe7, 0xd5, 0xfe, 0xc8, 0x62, 0xfc, 0x4c, 0x0c, 0x13, 0xac, 0x6b, 0xf0, 0x91, 0x23, 0xb6, 0xf0, 0x5b, 0xb0, 0xe4, 0xb7, 0x5c, 0x97, 0xf3, 0x79, 0xa2, 0xb3, 0xa6, 0x79,
};
// "cn/r"
const static uint8_t test_output_r[] = {
0xf7, 0x59, 0x58, 0x8a, 0xd5, 0x7e, 0x75, 0x84, 0x67, 0x29, 0x54, 0x43, 0xa9, 0xbd, 0x71, 0x49, 0x0a, 0xbf, 0xf8, 0xe9, 0xda, 0xd1, 0xb9, 0x5b, 0x6b, 0xf2, 0xf5, 0xd0, 0xd7, 0x83, 0x87, 0xbc,
0x5b, 0xb8, 0x33, 0xde, 0xca, 0x2b, 0xdd, 0x72, 0x52, 0xa9, 0xcc, 0xd7, 0xb4, 0xce, 0x0b, 0x6a, 0x48, 0x54, 0x51, 0x57, 0x94, 0xb5, 0x6c, 0x20, 0x72, 0x62, 0xf7, 0xa5, 0xb9, 0xbd, 0xb5, 0x66,
0x1e, 0xe6, 0x72, 0x8d, 0xa6, 0x0f, 0xbd, 0x8d, 0x7d, 0x55, 0xb2, 0xb1, 0xad, 0xe4, 0x87, 0xa3, 0xcf, 0x52, 0xa2, 0xc3, 0xac, 0x6f, 0x52, 0x0d, 0xb1, 0x2c, 0x27, 0xd8, 0x92, 0x1f, 0x6c, 0xab,
0x69, 0x69, 0xfe, 0x2d, 0xdf, 0xb7, 0x58, 0x43, 0x8d, 0x48, 0x04, 0x9f, 0x30, 0x2f, 0xc2, 0x10, 0x8a, 0x4f, 0xcc, 0x93, 0xe3, 0x76, 0x69, 0x17, 0x0e, 0x6d, 0xb4, 0xb0, 0xb9, 0xb4, 0xc4, 0xcb,
0x7f, 0x30, 0x48, 0xb4, 0xe9, 0x0d, 0x0c, 0xbe, 0x7a, 0x57, 0xc0, 0x39, 0x4f, 0x37, 0x33, 0x8a, 0x01, 0xfa, 0xe3, 0xad, 0xfd, 0xc0, 0xe5, 0x12, 0x6d, 0x86, 0x3a, 0x89, 0x5e, 0xb0, 0x4e, 0x02,
0x1d, 0x29, 0x04, 0x43, 0xa4, 0xb5, 0x42, 0xaf, 0x04, 0xa8, 0x2f, 0x6b, 0x24, 0x94, 0xa6, 0xee, 0x7f, 0x20, 0xf2, 0x75, 0x4c, 0x58, 0xe0, 0x84, 0x90, 0x32, 0x48, 0x3a, 0x56, 0xe8, 0xe2, 0xef,
0xc4, 0x3c, 0xc6, 0x56, 0x74, 0x36, 0xa8, 0x6a, 0xfb, 0xd6, 0xaa, 0x9e, 0xaa, 0x7c, 0x27, 0x6e, 0x98, 0x06, 0x83, 0x03, 0x34, 0xb6, 0x14, 0xb2, 0xbe, 0xe2, 0x3c, 0xc7, 0x66, 0x34, 0xf6, 0xfd,
0x87, 0xbe, 0x24, 0x79, 0xc0, 0xc4, 0xe8, 0xed, 0xfd, 0xfa, 0xa5, 0x60, 0x3e, 0x93, 0xf4, 0x26, 0x5b, 0x3f, 0x82, 0x24, 0xc1, 0xc5, 0x94, 0x6f, 0xeb, 0x42, 0x48, 0x19, 0xd1, 0x89, 0x90, 0xa4,
0xdd, 0x9d, 0x6a, 0x6d, 0x8e, 0x47, 0x46, 0x5c, 0xce, 0xac, 0x08, 0x77, 0xef, 0x88, 0x9b, 0x93, 0xe7, 0xeb, 0xa9, 0x79, 0x55, 0x7e, 0x39, 0x35, 0xd7, 0xf8, 0x6d, 0xce, 0x11, 0xb0, 0x70, 0xf3,
0x75, 0xc6, 0xf2, 0xae, 0x49, 0xa2, 0x05, 0x21, 0xde, 0x97, 0x28, 0x5b, 0x43, 0x1e, 0x71, 0x71, 0x25, 0x84, 0x7f, 0xb8, 0x93, 0x5e, 0xd8, 0x4a, 0x61, 0xe7, 0xf8, 0xd3, 0x6a, 0x2c, 0x3d, 0x8e,
};
// "cn/0" // "cn/0"
const static uint8_t test_output_v0[160] = { const static uint8_t test_output_v0[160] = {
@ -199,6 +230,47 @@ const static uint8_t test_output_rto[160] = {
0xE7, 0x81, 0x4E, 0x2A, 0xBD, 0x62, 0xC1, 0x1B, 0x7C, 0xB9, 0x33, 0x7B, 0xEE, 0x95, 0x80, 0xB3 0xE7, 0x81, 0x4E, 0x2A, 0xBD, 0x62, 0xC1, 0x1B, 0x7C, 0xB9, 0x33, 0x7B, 0xEE, 0x95, 0x80, 0xB3
}; };
// "cn/rwz"
const static uint8_t test_output_rwz[160] = {
0x5f, 0x56, 0xc6, 0xb0, 0x99, 0x6b, 0xa2, 0x3e, 0x0b, 0xba, 0x07, 0x29, 0xc9, 0x90, 0x74, 0x85,
0x5a, 0x10, 0xe3, 0x08, 0x7f, 0xdb, 0xfe, 0x94, 0x75, 0x33, 0x54, 0x73, 0x76, 0xf0, 0x75, 0xb8,
0x8b, 0x70, 0x43, 0x9a, 0xfc, 0xf5, 0xeb, 0x15, 0xbb, 0xf9, 0xad, 0x9d, 0x2a, 0xbd, 0x72, 0x52,
0x49, 0x54, 0x0b, 0x91, 0xea, 0x61, 0x7f, 0x98, 0x7d, 0x39, 0x17, 0xb7, 0xd7, 0x65, 0xff, 0x75,
0x13, 0x21, 0x1d, 0xce, 0x61, 0x5a, 0xdc, 0x5f, 0x8c, 0xcb, 0x1f, 0x6f, 0xbb, 0x92, 0x88, 0xc3,
0xe3, 0xe2, 0xfc, 0x4f, 0x62, 0xfb, 0xf0, 0x48, 0x02, 0x01, 0xd3, 0xbe, 0x77, 0x6a, 0x40, 0xca,
0x9a, 0xe9, 0xba, 0x0c, 0xc0, 0x2b, 0x11, 0xf6, 0x9b, 0xee, 0x24, 0x3a, 0xd8, 0x86, 0x18, 0xd0,
0xe8, 0xeb, 0xcb, 0x38, 0x2c, 0xf5, 0x99, 0x83, 0x14, 0x7b, 0x0c, 0x20, 0xbe, 0x50, 0xf4, 0x87,
0x83, 0x41, 0x75, 0xd8, 0xd1, 0xdd, 0x4b, 0x73, 0xb3, 0x92, 0x8f, 0xe6, 0x1c, 0x72, 0x70, 0xf5,
0x7c, 0xf6, 0x23, 0x3a, 0xb4, 0x5f, 0xdf, 0xde, 0xa6, 0x5a, 0x58, 0xec, 0x13, 0x5a, 0x23, 0x2f
};
// "cn/zls"
const static uint8_t test_output_zls[160] = {
0x51, 0x6E, 0x33, 0xC6, 0xE4, 0x46, 0xAB, 0xBC, 0xCD, 0xAD, 0x18, 0xC0, 0x4C, 0xD9, 0xA2, 0x5E,
0x64, 0x10, 0x28, 0x53, 0xB2, 0x0A, 0x42, 0xDF, 0xDE, 0xAA, 0x8B, 0x59, 0x9E, 0xCF, 0x40, 0xE2,
0x0D, 0x62, 0x5B, 0x42, 0x18, 0xE2, 0x76, 0xAD, 0xD0, 0x74, 0x90, 0x60, 0x8D, 0xC4, 0xC7, 0x80,
0x17, 0xB5, 0x1B, 0x25, 0x31, 0x39, 0x87, 0xD2, 0x2D, 0x6A, 0x9D, 0x1C, 0x74, 0xF4, 0x43, 0x22,
0x4B, 0x97, 0x1F, 0x6A, 0xD0, 0xBE, 0x00, 0x74, 0xEC, 0xC5, 0xD8, 0x3B, 0xE6, 0xF4, 0x03, 0x8A,
0x7B, 0xBA, 0x80, 0xCC, 0x9F, 0x00, 0xCB, 0xC2, 0x14, 0x8F, 0xF3, 0xD8, 0x92, 0x73, 0xBF, 0x17,
0x3D, 0x9B, 0x22, 0xA3, 0x61, 0x94, 0x41, 0x9E, 0xF9, 0x68, 0x1D, 0x42, 0x48, 0x3B, 0x39, 0x45,
0xE2, 0xE6, 0x16, 0x84, 0xFC, 0x21, 0xE6, 0xDA, 0x38, 0x7F, 0x17, 0xAB, 0xD3, 0xF2, 0xCE, 0x1A,
0x2F, 0x35, 0xD5, 0x74, 0xFA, 0x45, 0x3B, 0x06, 0xD1, 0x4E, 0x84, 0x3A, 0x5D, 0xE3, 0x0E, 0xA5,
0x00, 0x08, 0x64, 0xF0, 0xA6, 0xC8, 0x94, 0x45, 0x08, 0xED, 0x03, 0x95, 0x52, 0xE9, 0xBC, 0x5F
};
// "cn/double"
const static uint8_t test_output_double[160] = {
0xAE, 0xFB, 0xB3, 0xF0, 0xCC, 0x88, 0x04, 0x6D, 0x11, 0x9F, 0x6C, 0x54, 0xB9, 0x6D, 0x90, 0xC9,
0xE8, 0x84, 0xEA, 0x3B, 0x59, 0x83, 0xA6, 0x0D, 0x50, 0xA4, 0x2D, 0x7D, 0x3E, 0xBE, 0x48, 0x21,
0x49, 0xCE, 0x8E, 0xF3, 0xBC, 0x8A, 0x36, 0xBF, 0x86, 0x37, 0x89, 0x55, 0x09, 0xBA, 0x22, 0xF8,
0xEB, 0x3A, 0xE1, 0xDC, 0x91, 0xF7, 0x62, 0x4B, 0x9F, 0x48, 0xE6, 0x92, 0xBD, 0xE4, 0x5D, 0xC1,
0xF1, 0x3C, 0x63, 0x1D, 0xEB, 0x0B, 0x04, 0xA3, 0x30, 0xD5, 0x11, 0x15, 0x4C, 0xCE, 0xEF, 0x4F,
0xDF, 0x69, 0xE3, 0x9E, 0xD2, 0x68, 0xFC, 0x1B, 0x6F, 0xE8, 0x08, 0x9C, 0xBB, 0xA5, 0x2B, 0x60,
0x52, 0x0F, 0xE5, 0xD2, 0xF3, 0x8A, 0xB3, 0xE1, 0x76, 0x7F, 0x44, 0x25, 0x76, 0xEC, 0xFF, 0xA2,
0x0C, 0x64, 0xD0, 0x0E, 0x32, 0x33, 0x28, 0x20, 0x73, 0xE0, 0x31, 0x66, 0x4E, 0x54, 0x83, 0x49,
0x51, 0x55, 0x4D, 0x2E, 0x22, 0xB7, 0x51, 0x09, 0x73, 0x61, 0x7E, 0x6A, 0x57, 0x0B, 0x28, 0x3C,
0x5E, 0x2E, 0xC1, 0x80, 0x89, 0x39, 0xB3, 0x54, 0x39, 0x52, 0x0E, 0x69, 0x3D, 0xF6, 0xC5, 0x4A
};
#ifndef XMRIG_NO_AEON #ifndef XMRIG_NO_AEON
// "cn-lite/0" // "cn-lite/0"
@ -295,8 +367,6 @@ const static uint8_t test_output_pico_trtl[160] = {
}; };
#endif #endif
unsigned char hf_hex2bin(char c, bool &err);
char hf_bin2hex(unsigned char c);
#ifndef XMRIG_NO_CN_GPU #ifndef XMRIG_NO_CN_GPU
// "cn/gpu" // "cn/gpu"

View file

@ -192,31 +192,102 @@ static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, _
} }
template<bool SOFT_AES> static FORCEINLINE void soft_aesenc(void* __restrict ptr, const void* __restrict key, const uint32_t* __restrict t)
static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7)
{ {
if (SOFT_AES) { uint32_t x0 = ((const uint32_t*)(ptr))[0];
*x0 = soft_aesenc((uint32_t*)x0, key); uint32_t x1 = ((const uint32_t*)(ptr))[1];
*x1 = soft_aesenc((uint32_t*)x1, key); uint32_t x2 = ((const uint32_t*)(ptr))[2];
*x2 = soft_aesenc((uint32_t*)x2, key); uint32_t x3 = ((const uint32_t*)(ptr))[3];
*x3 = soft_aesenc((uint32_t*)x3, key);
*x4 = soft_aesenc((uint32_t*)x4, key); uint32_t y0 = t[x0 & 0xff]; x0 >>= 8;
*x5 = soft_aesenc((uint32_t*)x5, key); uint32_t y1 = t[x1 & 0xff]; x1 >>= 8;
*x6 = soft_aesenc((uint32_t*)x6, key); uint32_t y2 = t[x2 & 0xff]; x2 >>= 8;
*x7 = soft_aesenc((uint32_t*)x7, key); uint32_t y3 = t[x3 & 0xff]; x3 >>= 8;
} t += 256;
else {
*x0 = _mm_aesenc_si128(*x0, key); y0 ^= t[x1 & 0xff]; x1 >>= 8;
*x1 = _mm_aesenc_si128(*x1, key); y1 ^= t[x2 & 0xff]; x2 >>= 8;
*x2 = _mm_aesenc_si128(*x2, key); y2 ^= t[x3 & 0xff]; x3 >>= 8;
*x3 = _mm_aesenc_si128(*x3, key); y3 ^= t[x0 & 0xff]; x0 >>= 8;
*x4 = _mm_aesenc_si128(*x4, key); t += 256;
*x5 = _mm_aesenc_si128(*x5, key);
*x6 = _mm_aesenc_si128(*x6, key); y0 ^= t[x2 & 0xff]; x2 >>= 8;
*x7 = _mm_aesenc_si128(*x7, key); y1 ^= t[x3 & 0xff]; x3 >>= 8;
} y2 ^= t[x0 & 0xff]; x0 >>= 8;
y3 ^= t[x1 & 0xff]; x1 >>= 8;
t += 256;
y0 ^= t[x3];
y1 ^= t[x0];
y2 ^= t[x1];
y3 ^= t[x2];
((uint32_t*)ptr)[0] = y0 ^ ((uint32_t*)key)[0];
((uint32_t*)ptr)[1] = y1 ^ ((uint32_t*)key)[1];
((uint32_t*)ptr)[2] = y2 ^ ((uint32_t*)key)[2];
((uint32_t*)ptr)[3] = y3 ^ ((uint32_t*)key)[3];
} }
static FORCEINLINE __m128i soft_aesenc(const void* __restrict ptr, const __m128i key, const uint32_t* __restrict t)
{
uint32_t x0 = ((const uint32_t*)(ptr))[0];
uint32_t x1 = ((const uint32_t*)(ptr))[1];
uint32_t x2 = ((const uint32_t*)(ptr))[2];
uint32_t x3 = ((const uint32_t*)(ptr))[3];
uint32_t y0 = t[x0 & 0xff]; x0 >>= 8;
uint32_t y1 = t[x1 & 0xff]; x1 >>= 8;
uint32_t y2 = t[x2 & 0xff]; x2 >>= 8;
uint32_t y3 = t[x3 & 0xff]; x3 >>= 8;
t += 256;
y0 ^= t[x1 & 0xff]; x1 >>= 8;
y1 ^= t[x2 & 0xff]; x2 >>= 8;
y2 ^= t[x3 & 0xff]; x3 >>= 8;
y3 ^= t[x0 & 0xff]; x0 >>= 8;
t += 256;
y0 ^= t[x2 & 0xff]; x2 >>= 8;
y1 ^= t[x3 & 0xff]; x3 >>= 8;
y2 ^= t[x0 & 0xff]; x0 >>= 8;
y3 ^= t[x1 & 0xff]; x1 >>= 8;
y0 ^= t[x3 + 256];
y1 ^= t[x0 + 256];
y2 ^= t[x1 + 256];
y3 ^= t[x2 + 256];
return _mm_xor_si128(_mm_set_epi32(y3, y2, y1, y0), key);
}
template<bool SOFT_AES>
void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7);
template<>
NOINLINE void aes_round<true>(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7)
{
*x0 = soft_aesenc((uint32_t*)x0, key, (const uint32_t*)saes_table);
*x1 = soft_aesenc((uint32_t*)x1, key, (const uint32_t*)saes_table);
*x2 = soft_aesenc((uint32_t*)x2, key, (const uint32_t*)saes_table);
*x3 = soft_aesenc((uint32_t*)x3, key, (const uint32_t*)saes_table);
*x4 = soft_aesenc((uint32_t*)x4, key, (const uint32_t*)saes_table);
*x5 = soft_aesenc((uint32_t*)x5, key, (const uint32_t*)saes_table);
*x6 = soft_aesenc((uint32_t*)x6, key, (const uint32_t*)saes_table);
*x7 = soft_aesenc((uint32_t*)x7, key, (const uint32_t*)saes_table);
}
template<>
FORCEINLINE void aes_round<false>(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7)
{
*x0 = _mm_aesenc_si128(*x0, key);
*x1 = _mm_aesenc_si128(*x1, key);
*x2 = _mm_aesenc_si128(*x2, key);
*x3 = _mm_aesenc_si128(*x3, key);
*x4 = _mm_aesenc_si128(*x4, key);
*x5 = _mm_aesenc_si128(*x5, key);
*x6 = _mm_aesenc_si128(*x6, key);
*x7 = _mm_aesenc_si128(*x7, key);
}
inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3, __m128i& x4, __m128i& x5, __m128i& x6, __m128i& x7) inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3, __m128i& x4, __m128i& x5, __m128i& x6, __m128i& x7)
{ {
@ -460,7 +531,7 @@ template<xmrig::Variant VARIANT, xmrig::Variant BASE>
static inline void cryptonight_monero_tweak(uint64_t* mem_out, const uint8_t* l, uint64_t idx, __m128i ax0, __m128i bx0, __m128i bx1, __m128i& cx) static inline void cryptonight_monero_tweak(uint64_t* mem_out, const uint8_t* l, uint64_t idx, __m128i ax0, __m128i bx0, __m128i bx1, __m128i& cx)
{ {
if (BASE == xmrig::VARIANT_2) { if (BASE == xmrig::VARIANT_2) {
VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1, cx); VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1, cx, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0));
_mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx)); _mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx));
} else { } else {
__m128i tmp = _mm_xor_si128(bx0, cx); __m128i tmp = _mm_xor_si128(bx0, cx);
@ -478,6 +549,8 @@ static inline void cryptonight_monero_tweak(uint64_t* mem_out, const uint8_t* l,
} }
} }
void wow_soft_aes_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM);
void v4_soft_aes_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM);
template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT> template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT>
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height)
@ -498,9 +571,31 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory);
const uint8_t* l0 = ctx[0]->memory;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state); uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
#ifndef XMRIG_NO_ASM
if (SOFT_AES && xmrig::cn_is_cryptonight_r<VARIANT>())
{
if (!ctx[0]->generated_code_data.match(VARIANT, height)) {
V4_Instruction code[256];
const int code_size = v4_random_math_init<VARIANT>(code, height);
if (VARIANT == xmrig::VARIANT_WOW)
wow_soft_aes_compile_code(code, code_size, reinterpret_cast<void*>(ctx[0]->generated_code), xmrig::ASM_NONE);
else if (VARIANT == xmrig::VARIANT_4)
v4_soft_aes_compile_code(code, code_size, reinterpret_cast<void*>(ctx[0]->generated_code), xmrig::ASM_NONE);
ctx[0]->generated_code_data.variant = VARIANT;
ctx[0]->generated_code_data.height = height;
}
ctx[0]->saes_table = (const uint32_t*)saes_table;
ctx[0]->generated_code(ctx);
} else {
#endif
const uint8_t* l0 = ctx[0]->memory;
VARIANT1_INIT(0); VARIANT1_INIT(0);
VARIANT2_INIT(0); VARIANT2_INIT(0);
VARIANT2_SET_ROUNDING_MODE(); VARIANT2_SET_ROUNDING_MODE();
@ -524,7 +619,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
cx = aes_round_tweak_div(cx, ax0); cx = aes_round_tweak_div(cx, ax0);
} }
else if (SOFT_AES) { else if (SOFT_AES) {
cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0); cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0, (const uint32_t*)saes_table);
} }
else { else {
cx = _mm_aesenc_si128(cx, ax0); cx = _mm_aesenc_si128(cx, ax0);
@ -558,9 +653,9 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
if (BASE == xmrig::VARIANT_2) { if (BASE == xmrig::VARIANT_2) {
if (VARIANT == xmrig::VARIANT_4) { if (VARIANT == xmrig::VARIANT_4) {
VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx0, bx1, cx); VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx0, bx1, cx, 0);
} else { } else {
VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo); VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0));
} }
} }
@ -602,6 +697,10 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
bx0 = cx; bx0 = cx;
} }
#ifndef XMRIG_NO_ASM
}
#endif
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);
xmrig::keccakf(h0, 24); xmrig::keccakf(h0, 24);
@ -651,20 +750,32 @@ inline void cryptonight_single_hash_gpu(const uint8_t *__restrict__ input, size_
#ifndef XMRIG_NO_ASM #ifndef XMRIG_NO_ASM
extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx *ctx); extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx **ctx);
extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx *ctx); extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx **ctx);
extern "C" void cnv2_mainloop_bulldozer_asm(cryptonight_ctx *ctx); extern "C" void cnv2_mainloop_bulldozer_asm(cryptonight_ctx **ctx);
extern "C" void cnv2_double_mainloop_sandybridge_asm(cryptonight_ctx* ctx0, cryptonight_ctx* ctx1); extern "C" void cnv2_double_mainloop_sandybridge_asm(cryptonight_ctx **ctx);
extern "C" void cnv2_rwz_mainloop_asm(cryptonight_ctx **ctx);
extern "C" void cnv2_rwz_double_mainloop_asm(cryptonight_ctx **ctx);
extern xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_ivybridge_asm; extern xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_ivybridge_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_ryzen_asm; extern xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_ryzen_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_bulldozer_asm; extern xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_bulldozer_asm;
extern xmrig::CpuThread::cn_mainloop_double_fun cn_half_double_mainloop_sandybridge_asm; extern xmrig::CpuThread::cn_mainloop_fun cn_half_double_mainloop_sandybridge_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_ivybridge_asm; extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_ivybridge_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_ryzen_asm; extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_ryzen_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm; extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm;
extern xmrig::CpuThread::cn_mainloop_double_fun cn_trtl_double_mainloop_sandybridge_asm; extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_double_mainloop_sandybridge_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_ivybridge_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_ryzen_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_bulldozer_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_zls_double_mainloop_sandybridge_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_ivybridge_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_ryzen_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_bulldozer_asm;
extern xmrig::CpuThread::cn_mainloop_fun cn_double_double_mainloop_sandybridge_asm;
void wow_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM); void wow_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM);
void v4_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM); void v4_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM);
@ -713,39 +824,64 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_
if (VARIANT == xmrig::VARIANT_2) { if (VARIANT == xmrig::VARIANT_2) {
if (ASM == xmrig::ASM_INTEL) { if (ASM == xmrig::ASM_INTEL) {
cnv2_mainloop_ivybridge_asm(ctx[0]); cnv2_mainloop_ivybridge_asm(ctx);
} }
else if (ASM == xmrig::ASM_RYZEN) { else if (ASM == xmrig::ASM_RYZEN) {
cnv2_mainloop_ryzen_asm(ctx[0]); cnv2_mainloop_ryzen_asm(ctx);
} }
else { else {
cnv2_mainloop_bulldozer_asm(ctx[0]); cnv2_mainloop_bulldozer_asm(ctx);
} }
} }
else if (VARIANT == xmrig::VARIANT_HALF) { else if (VARIANT == xmrig::VARIANT_HALF) {
if (ASM == xmrig::ASM_INTEL) { if (ASM == xmrig::ASM_INTEL) {
cn_half_mainloop_ivybridge_asm(ctx[0]); cn_half_mainloop_ivybridge_asm(ctx);
} }
else if (ASM == xmrig::ASM_RYZEN) { else if (ASM == xmrig::ASM_RYZEN) {
cn_half_mainloop_ryzen_asm(ctx[0]); cn_half_mainloop_ryzen_asm(ctx);
} }
else { else {
cn_half_mainloop_bulldozer_asm(ctx[0]); cn_half_mainloop_bulldozer_asm(ctx);
} }
} }
else if (VARIANT == xmrig::VARIANT_TRTL) { else if (VARIANT == xmrig::VARIANT_TRTL) {
if (ASM == xmrig::ASM_INTEL) { if (ASM == xmrig::ASM_INTEL) {
cn_trtl_mainloop_ivybridge_asm(ctx[0]); cn_trtl_mainloop_ivybridge_asm(ctx);
} }
else if (ASM == xmrig::ASM_RYZEN) { else if (ASM == xmrig::ASM_RYZEN) {
cn_trtl_mainloop_ryzen_asm(ctx[0]); cn_trtl_mainloop_ryzen_asm(ctx);
} }
else { else {
cn_trtl_mainloop_bulldozer_asm(ctx[0]); cn_trtl_mainloop_bulldozer_asm(ctx);
}
}
else if (VARIANT == xmrig::VARIANT_RWZ) {
cnv2_rwz_mainloop_asm(ctx);
}
else if (VARIANT == xmrig::VARIANT_ZLS) {
if (ASM == xmrig::ASM_INTEL) {
cn_zls_mainloop_ivybridge_asm(ctx);
}
else if (ASM == xmrig::ASM_RYZEN) {
cn_zls_mainloop_ryzen_asm(ctx);
}
else {
cn_zls_mainloop_bulldozer_asm(ctx);
}
}
else if (VARIANT == xmrig::VARIANT_DOUBLE) {
if (ASM == xmrig::ASM_INTEL) {
cn_double_mainloop_ivybridge_asm(ctx);
}
else if (ASM == xmrig::ASM_RYZEN) {
cn_double_mainloop_ryzen_asm(ctx);
}
else {
cn_double_mainloop_bulldozer_asm(ctx);
} }
} }
else if (xmrig::cn_is_cryptonight_r<VARIANT>()) { else if (xmrig::cn_is_cryptonight_r<VARIANT>()) {
ctx[0]->generated_code(ctx[0]); ctx[0]->generated_code(ctx);
} }
cn_implode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state)); cn_implode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state));
@ -774,16 +910,25 @@ inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_
cn_explode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[1]->state), reinterpret_cast<__m128i*>(ctx[1]->memory)); cn_explode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[1]->state), reinterpret_cast<__m128i*>(ctx[1]->memory));
if (VARIANT == xmrig::VARIANT_2) { if (VARIANT == xmrig::VARIANT_2) {
cnv2_double_mainloop_sandybridge_asm(ctx[0], ctx[1]); cnv2_double_mainloop_sandybridge_asm(ctx);
} }
else if (VARIANT == xmrig::VARIANT_HALF) { else if (VARIANT == xmrig::VARIANT_HALF) {
cn_half_double_mainloop_sandybridge_asm(ctx[0], ctx[1]); cn_half_double_mainloop_sandybridge_asm(ctx);
} }
else if (VARIANT == xmrig::VARIANT_TRTL) { else if (VARIANT == xmrig::VARIANT_TRTL) {
cn_trtl_double_mainloop_sandybridge_asm(ctx[0], ctx[1]); cn_trtl_double_mainloop_sandybridge_asm(ctx);
}
else if (VARIANT == xmrig::VARIANT_RWZ) {
cnv2_rwz_double_mainloop_asm(ctx);
}
else if (VARIANT == xmrig::VARIANT_ZLS) {
cn_zls_double_mainloop_sandybridge_asm(ctx);
}
else if (VARIANT == xmrig::VARIANT_DOUBLE) {
cn_double_double_mainloop_sandybridge_asm(ctx);
} }
else if (xmrig::cn_is_cryptonight_r<VARIANT>()) { else if (xmrig::cn_is_cryptonight_r<VARIANT>()) {
ctx[0]->generated_code_double(ctx[0], ctx[1]); ctx[0]->generated_code_double(ctx);
} }
cn_implode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state)); cn_implode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state));
@ -857,8 +1002,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
cx1 = aes_round_tweak_div(cx1, ax1); cx1 = aes_round_tweak_div(cx1, ax1);
} }
else if (SOFT_AES) { else if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0); cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0, (const uint32_t*)saes_table);
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], ax1); cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], ax1, (const uint32_t*)saes_table);
} }
else { else {
cx0 = _mm_aesenc_si128(cx0, ax0); cx0 = _mm_aesenc_si128(cx0, ax0);
@ -896,9 +1041,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
if (BASE == xmrig::VARIANT_2) { if (BASE == xmrig::VARIANT_2) {
if (VARIANT == xmrig::VARIANT_4) { if (VARIANT == xmrig::VARIANT_4) {
VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx00, bx01, cx0); VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx00, bx01, cx0, 0);
} else { } else {
VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo); VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0));
} }
} }
@ -952,9 +1097,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
if (BASE == xmrig::VARIANT_2) { if (BASE == xmrig::VARIANT_2) {
if (VARIANT == xmrig::VARIANT_4) { if (VARIANT == xmrig::VARIANT_4) {
VARIANT2_SHUFFLE(l1, idx1 & MASK, ax1, bx10, bx11, cx1); VARIANT2_SHUFFLE(l1, idx1 & MASK, ax1, bx10, bx11, cx1, 0);
} else { } else {
VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo); VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0));
} }
} }
@ -1019,7 +1164,7 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
c = aes_round_tweak_div(c, a); \ c = aes_round_tweak_div(c, a); \
} \ } \
else if (SOFT_AES) { \ else if (SOFT_AES) { \
c = soft_aesenc(c, a); \ c = soft_aesenc(&c, a, (const uint32_t*)saes_table); \
} else { \ } else { \
c = _mm_aesenc_si128(c, a); \ c = _mm_aesenc_si128(c, a); \
} \ } \
@ -1056,9 +1201,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
lo = __umul128(idx, cl##part, &hi); \ lo = __umul128(idx, cl##part, &hi); \
if (BASE == xmrig::VARIANT_2) { \ if (BASE == xmrig::VARIANT_2) { \
if (VARIANT == xmrig::VARIANT_4) { \ if (VARIANT == xmrig::VARIANT_4) { \
VARIANT2_SHUFFLE(l, idx & MASK, a, b0, b1, c); \ VARIANT2_SHUFFLE(l, idx & MASK, a, b0, b1, c, 0); \
} else { \ } else { \
VARIANT2_SHUFFLE2(l, idx & MASK, a, b0, b1, hi, lo); \ VARIANT2_SHUFFLE2(l, idx & MASK, a, b0, b1, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0)); \
} \ } \
} \ } \
if (VARIANT == xmrig::VARIANT_4) { \ if (VARIANT == xmrig::VARIANT_4) { \

View file

@ -31,7 +31,6 @@ typedef void(*void_func)();
#include "crypto/asm/CryptonightR_template.h" #include "crypto/asm/CryptonightR_template.h"
#include "Mem.h" #include "Mem.h"
#if !defined XMRIG_ARM && !defined XMRIG_NO_ASM
static inline void add_code(uint8_t* &p, void (*p1)(), void (*p2)()) static inline void add_code(uint8_t* &p, void (*p1)(), void (*p2)())
{ {
@ -159,4 +158,30 @@ void v4_compile_code_double(const V4_Instruction* code, int code_size, void* mac
Mem::flushInstructionCache(machine_code, p - p0); Mem::flushInstructionCache(machine_code, p - p0);
} }
#endif void wow_soft_aes_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM)
{
uint8_t* p0 = reinterpret_cast<uint8_t*>(machine_code);
uint8_t* p = p0;
add_code(p, CryptonightWOW_soft_aes_template_part1, CryptonightWOW_soft_aes_template_part2);
add_random_math(p, code, code_size, instructions, instructions_mov, false, ASM);
add_code(p, CryptonightWOW_soft_aes_template_part2, CryptonightWOW_soft_aes_template_part3);
*(int*)(p - 4) = static_cast<int>((((const uint8_t*)CryptonightWOW_soft_aes_template_mainloop) - ((const uint8_t*)CryptonightWOW_soft_aes_template_part1)) - (p - p0));
add_code(p, CryptonightWOW_soft_aes_template_part3, CryptonightWOW_soft_aes_template_end);
Mem::flushInstructionCache(machine_code, p - p0);
}
void v4_soft_aes_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM)
{
uint8_t* p0 = reinterpret_cast<uint8_t*>(machine_code);
uint8_t* p = p0;
add_code(p, CryptonightR_soft_aes_template_part1, CryptonightR_soft_aes_template_part2);
add_random_math(p, code, code_size, instructions, instructions_mov, false, ASM);
add_code(p, CryptonightR_soft_aes_template_part2, CryptonightR_soft_aes_template_part3);
*(int*)(p - 4) = static_cast<int>((((const uint8_t*)CryptonightR_soft_aes_template_mainloop) - ((const uint8_t*)CryptonightR_soft_aes_template_part1)) - (p - p0));
add_code(p, CryptonightR_soft_aes_template_part3, CryptonightR_soft_aes_template_end);
Mem::flushInstructionCache(machine_code, p - p0);
}

View file

@ -0,0 +1,281 @@
PUBLIC FN_PREFIX(CryptonightR_soft_aes_template_part1)
PUBLIC FN_PREFIX(CryptonightR_soft_aes_template_mainloop)
PUBLIC FN_PREFIX(CryptonightR_soft_aes_template_part2)
PUBLIC FN_PREFIX(CryptonightR_soft_aes_template_part3)
PUBLIC FN_PREFIX(CryptonightR_soft_aes_template_end)
ALIGN(64)
FN_PREFIX(CryptonightR_soft_aes_template_part1):
mov rcx, [rcx]
mov QWORD PTR [rsp+8], rcx
push rbx
push rbp
push rsi
push rdi
push r12
push r13
push r14
push r15
sub rsp, 232
mov eax, [rcx+96]
mov ebx, [rcx+100]
mov esi, [rcx+104]
mov edx, [rcx+108]
mov [rsp+144], eax
mov [rsp+148], ebx
mov [rsp+152], esi
mov [rsp+156], edx
mov rax, QWORD PTR [rcx+48]
mov r10, rcx
xor rax, QWORD PTR [rcx+16]
mov r8, QWORD PTR [rcx+32]
xor r8, QWORD PTR [rcx]
mov r9, QWORD PTR [rcx+40]
xor r9, QWORD PTR [rcx+8]
movq xmm4, rax
mov rdx, QWORD PTR [rcx+56]
xor rdx, QWORD PTR [rcx+24]
mov r11, QWORD PTR [rcx+224]
mov rcx, QWORD PTR [rcx+88]
xor rcx, QWORD PTR [r10+72]
mov rax, QWORD PTR [r10+80]
movq xmm0, rdx
xor rax, QWORD PTR [r10+64]
movaps XMMWORD PTR [rsp+16], xmm6
movaps XMMWORD PTR [rsp+32], xmm7
movaps XMMWORD PTR [rsp+48], xmm8
movaps XMMWORD PTR [rsp+64], xmm9
movaps XMMWORD PTR [rsp+80], xmm10
movaps XMMWORD PTR [rsp+96], xmm11
movaps XMMWORD PTR [rsp+112], xmm12
movaps XMMWORD PTR [rsp+128], xmm13
movq xmm5, rax
mov rax, r8
punpcklqdq xmm4, xmm0
and eax, 2097136
movq xmm10, QWORD PTR [r10+96]
movq xmm0, rcx
mov rcx, QWORD PTR [r10+104]
xorps xmm9, xmm9
mov QWORD PTR [rsp+328], rax
movq xmm12, r11
mov QWORD PTR [rsp+320], r9
punpcklqdq xmm5, xmm0
movq xmm13, rcx
mov r12d, 524288
ALIGN(64)
FN_PREFIX(CryptonightR_soft_aes_template_mainloop):
movd xmm11, r12d
mov r12, QWORD PTR [r10+272]
lea r13, QWORD PTR [rax+r11]
mov esi, DWORD PTR [r13]
movq xmm0, r9
mov r10d, DWORD PTR [r13+4]
movq xmm7, r8
mov ebp, DWORD PTR [r13+12]
mov r14d, DWORD PTR [r13+8]
mov rdx, QWORD PTR [rsp+328]
movzx ecx, sil
shr esi, 8
punpcklqdq xmm7, xmm0
mov r15d, DWORD PTR [r12+rcx*4]
movzx ecx, r10b
shr r10d, 8
mov edi, DWORD PTR [r12+rcx*4]
movzx ecx, r14b
shr r14d, 8
mov ebx, DWORD PTR [r12+rcx*4]
movzx ecx, bpl
shr ebp, 8
mov r9d, DWORD PTR [r12+rcx*4]
movzx ecx, r10b
shr r10d, 8
xor r15d, DWORD PTR [r12+rcx*4+1024]
movzx ecx, r14b
shr r14d, 8
mov eax, r14d
shr eax, 8
xor edi, DWORD PTR [r12+rcx*4+1024]
add eax, 256
movzx ecx, bpl
shr ebp, 8
xor ebx, DWORD PTR [r12+rcx*4+1024]
movzx ecx, sil
shr esi, 8
xor r9d, DWORD PTR [r12+rcx*4+1024]
add r12, 2048
movzx ecx, r10b
shr r10d, 8
add r10d, 256
mov r11d, DWORD PTR [r12+rax*4]
xor r11d, DWORD PTR [r12+rcx*4]
xor r11d, r9d
movzx ecx, sil
mov r10d, DWORD PTR [r12+r10*4]
shr esi, 8
add esi, 256
xor r10d, DWORD PTR [r12+rcx*4]
movzx ecx, bpl
xor r10d, ebx
shr ebp, 8
movd xmm1, r11d
add ebp, 256
movq r11, xmm12
mov r9d, DWORD PTR [r12+rcx*4]
xor r9d, DWORD PTR [r12+rsi*4]
mov eax, DWORD PTR [r12+rbp*4]
xor r9d, edi
movzx ecx, r14b
movd xmm0, r10d
movd xmm2, r9d
xor eax, DWORD PTR [r12+rcx*4]
mov rcx, rdx
xor eax, r15d
punpckldq xmm2, xmm1
xor rcx, 16
movd xmm6, eax
mov rax, rdx
punpckldq xmm6, xmm0
xor rax, 32
punpckldq xmm6, xmm2
xor rdx, 48
movdqu xmm2, XMMWORD PTR [rcx+r11]
pxor xmm6, xmm2
pxor xmm6, xmm7
paddq xmm2, xmm4
movdqu xmm1, XMMWORD PTR [rax+r11]
movdqu xmm0, XMMWORD PTR [rdx+r11]
pxor xmm6, xmm1
pxor xmm6, xmm0
paddq xmm0, xmm5
movdqu XMMWORD PTR [rcx+r11], xmm0
movdqu XMMWORD PTR [rax+r11], xmm2
movq rcx, xmm13
paddq xmm1, xmm7
movdqu XMMWORD PTR [rdx+r11], xmm1
movq rdi, xmm6
mov r10, rdi
and r10d, 2097136
movdqa xmm0, xmm6
pxor xmm0, xmm4
movdqu XMMWORD PTR [r13], xmm0
mov ebx, [rsp+144]
mov ebp, [rsp+152]
add ebx, [rsp+148]
add ebp, [rsp+156]
shl rbp, 32
or rbx, rbp
xor rbx, QWORD PTR [r10+r11]
lea r14, QWORD PTR [r10+r11]
mov rbp, QWORD PTR [r14+8]
mov [rsp+160], rbx
mov [rsp+168], rdi
mov [rsp+176], rbp
mov [rsp+184], r10
mov r10, rsp
mov ebx, [rsp+144]
mov esi, [rsp+148]
mov edi, [rsp+152]
mov ebp, [rsp+156]
movd esp, xmm7
movaps xmm0, xmm7
psrldq xmm0, 8
movd r15d, xmm0
movd eax, xmm4
movd edx, xmm5
movaps xmm0, xmm5
psrldq xmm0, 8
movd r9d, xmm0
FN_PREFIX(CryptonightR_soft_aes_template_part2):
mov rsp, r10
mov [rsp+144], ebx
mov [rsp+148], esi
mov [rsp+152], edi
mov [rsp+156], ebp
mov edi, edi
shl rbp, 32
or rbp, rdi
xor r8, rbp
mov ebx, ebx
shl rsi, 32
or rsi, rbx
xor QWORD PTR [rsp+320], rsi
mov rbx, [rsp+160]
mov rdi, [rsp+168]
mov rbp, [rsp+176]
mov r10, [rsp+184]
mov r9, r10
xor r9, 16
mov rcx, r10
xor rcx, 32
xor r10, 48
mov rax, rbx
mul rdi
movdqu xmm2, XMMWORD PTR [r9+r11]
movdqu xmm1, XMMWORD PTR [rcx+r11]
pxor xmm6, xmm2
pxor xmm6, xmm1
paddq xmm1, xmm7
add r8, rdx
movdqu xmm0, XMMWORD PTR [r10+r11]
pxor xmm6, xmm0
paddq xmm0, xmm5
paddq xmm2, xmm4
movdqu XMMWORD PTR [r9+r11], xmm0
movdqa xmm5, xmm4
mov r9, QWORD PTR [rsp+320]
movdqa xmm4, xmm6
add r9, rax
movdqu XMMWORD PTR [rcx+r11], xmm2
movdqu XMMWORD PTR [r10+r11], xmm1
mov r10, QWORD PTR [rsp+304]
movd r12d, xmm11
mov QWORD PTR [r14], r8
xor r8, rbx
mov rax, r8
mov QWORD PTR [r14+8], r9
and eax, 2097136
xor r9, rbp
mov QWORD PTR [rsp+320], r9
mov QWORD PTR [rsp+328], rax
sub r12d, 1
jne FN_PREFIX(CryptonightR_soft_aes_template_mainloop)
FN_PREFIX(CryptonightR_soft_aes_template_part3):
movaps xmm6, XMMWORD PTR [rsp+16]
movaps xmm7, XMMWORD PTR [rsp+32]
movaps xmm8, XMMWORD PTR [rsp+48]
movaps xmm9, XMMWORD PTR [rsp+64]
movaps xmm10, XMMWORD PTR [rsp+80]
movaps xmm11, XMMWORD PTR [rsp+96]
movaps xmm12, XMMWORD PTR [rsp+112]
movaps xmm13, XMMWORD PTR [rsp+128]
add rsp, 232
pop r15
pop r14
pop r13
pop r12
pop rdi
pop rsi
pop rbp
pop rbx
ret
FN_PREFIX(CryptonightR_soft_aes_template_end):

View file

@ -0,0 +1,281 @@
PUBLIC CryptonightR_soft_aes_template_part1
PUBLIC CryptonightR_soft_aes_template_mainloop
PUBLIC CryptonightR_soft_aes_template_part2
PUBLIC CryptonightR_soft_aes_template_part3
PUBLIC CryptonightR_soft_aes_template_end
ALIGN(64)
CryptonightR_soft_aes_template_part1:
mov rcx, [rcx]
mov QWORD PTR [rsp+8], rcx
push rbx
push rbp
push rsi
push rdi
push r12
push r13
push r14
push r15
sub rsp, 232
mov eax, [rcx+96]
mov ebx, [rcx+100]
mov esi, [rcx+104]
mov edx, [rcx+108]
mov [rsp+144], eax
mov [rsp+148], ebx
mov [rsp+152], esi
mov [rsp+156], edx
mov rax, QWORD PTR [rcx+48]
mov r10, rcx
xor rax, QWORD PTR [rcx+16]
mov r8, QWORD PTR [rcx+32]
xor r8, QWORD PTR [rcx]
mov r9, QWORD PTR [rcx+40]
xor r9, QWORD PTR [rcx+8]
movq xmm4, rax
mov rdx, QWORD PTR [rcx+56]
xor rdx, QWORD PTR [rcx+24]
mov r11, QWORD PTR [rcx+224]
mov rcx, QWORD PTR [rcx+88]
xor rcx, QWORD PTR [r10+72]
mov rax, QWORD PTR [r10+80]
movq xmm0, rdx
xor rax, QWORD PTR [r10+64]
movaps XMMWORD PTR [rsp+16], xmm6
movaps XMMWORD PTR [rsp+32], xmm7
movaps XMMWORD PTR [rsp+48], xmm8
movaps XMMWORD PTR [rsp+64], xmm9
movaps XMMWORD PTR [rsp+80], xmm10
movaps XMMWORD PTR [rsp+96], xmm11
movaps XMMWORD PTR [rsp+112], xmm12
movaps XMMWORD PTR [rsp+128], xmm13
movq xmm5, rax
mov rax, r8
punpcklqdq xmm4, xmm0
and eax, 2097136
movq xmm10, QWORD PTR [r10+96]
movq xmm0, rcx
mov rcx, QWORD PTR [r10+104]
xorps xmm9, xmm9
mov QWORD PTR [rsp+328], rax
movq xmm12, r11
mov QWORD PTR [rsp+320], r9
punpcklqdq xmm5, xmm0
movq xmm13, rcx
mov r12d, 524288
ALIGN(64)
CryptonightR_soft_aes_template_mainloop:
movd xmm11, r12d
mov r12, QWORD PTR [r10+272]
lea r13, QWORD PTR [rax+r11]
mov esi, DWORD PTR [r13]
movq xmm0, r9
mov r10d, DWORD PTR [r13+4]
movq xmm7, r8
mov ebp, DWORD PTR [r13+12]
mov r14d, DWORD PTR [r13+8]
mov rdx, QWORD PTR [rsp+328]
movzx ecx, sil
shr esi, 8
punpcklqdq xmm7, xmm0
mov r15d, DWORD PTR [r12+rcx*4]
movzx ecx, r10b
shr r10d, 8
mov edi, DWORD PTR [r12+rcx*4]
movzx ecx, r14b
shr r14d, 8
mov ebx, DWORD PTR [r12+rcx*4]
movzx ecx, bpl
shr ebp, 8
mov r9d, DWORD PTR [r12+rcx*4]
movzx ecx, r10b
shr r10d, 8
xor r15d, DWORD PTR [r12+rcx*4+1024]
movzx ecx, r14b
shr r14d, 8
mov eax, r14d
shr eax, 8
xor edi, DWORD PTR [r12+rcx*4+1024]
add eax, 256
movzx ecx, bpl
shr ebp, 8
xor ebx, DWORD PTR [r12+rcx*4+1024]
movzx ecx, sil
shr esi, 8
xor r9d, DWORD PTR [r12+rcx*4+1024]
add r12, 2048
movzx ecx, r10b
shr r10d, 8
add r10d, 256
mov r11d, DWORD PTR [r12+rax*4]
xor r11d, DWORD PTR [r12+rcx*4]
xor r11d, r9d
movzx ecx, sil
mov r10d, DWORD PTR [r12+r10*4]
shr esi, 8
add esi, 256
xor r10d, DWORD PTR [r12+rcx*4]
movzx ecx, bpl
xor r10d, ebx
shr ebp, 8
movd xmm1, r11d
add ebp, 256
movq r11, xmm12
mov r9d, DWORD PTR [r12+rcx*4]
xor r9d, DWORD PTR [r12+rsi*4]
mov eax, DWORD PTR [r12+rbp*4]
xor r9d, edi
movzx ecx, r14b
movd xmm0, r10d
movd xmm2, r9d
xor eax, DWORD PTR [r12+rcx*4]
mov rcx, rdx
xor eax, r15d
punpckldq xmm2, xmm1
xor rcx, 16
movd xmm6, eax
mov rax, rdx
punpckldq xmm6, xmm0
xor rax, 32
punpckldq xmm6, xmm2
xor rdx, 48
movdqu xmm2, XMMWORD PTR [rcx+r11]
pxor xmm6, xmm2
pxor xmm6, xmm7
paddq xmm2, xmm4
movdqu xmm1, XMMWORD PTR [rax+r11]
movdqu xmm0, XMMWORD PTR [rdx+r11]
pxor xmm6, xmm1
pxor xmm6, xmm0
paddq xmm0, xmm5
movdqu XMMWORD PTR [rcx+r11], xmm0
movdqu XMMWORD PTR [rax+r11], xmm2
movq rcx, xmm13
paddq xmm1, xmm7
movdqu XMMWORD PTR [rdx+r11], xmm1
movq rdi, xmm6
mov r10, rdi
and r10d, 2097136
movdqa xmm0, xmm6
pxor xmm0, xmm4
movdqu XMMWORD PTR [r13], xmm0
mov ebx, [rsp+144]
mov ebp, [rsp+152]
add ebx, [rsp+148]
add ebp, [rsp+156]
shl rbp, 32
or rbx, rbp
xor rbx, QWORD PTR [r10+r11]
lea r14, QWORD PTR [r10+r11]
mov rbp, QWORD PTR [r14+8]
mov [rsp+160], rbx
mov [rsp+168], rdi
mov [rsp+176], rbp
mov [rsp+184], r10
mov r10, rsp
mov ebx, [rsp+144]
mov esi, [rsp+148]
mov edi, [rsp+152]
mov ebp, [rsp+156]
movd esp, xmm7
movaps xmm0, xmm7
psrldq xmm0, 8
movd r15d, xmm0
movd eax, xmm4
movd edx, xmm5
movaps xmm0, xmm5
psrldq xmm0, 8
movd r9d, xmm0
CryptonightR_soft_aes_template_part2:
mov rsp, r10
mov [rsp+144], ebx
mov [rsp+148], esi
mov [rsp+152], edi
mov [rsp+156], ebp
mov edi, edi
shl rbp, 32
or rbp, rdi
xor r8, rbp
mov ebx, ebx
shl rsi, 32
or rsi, rbx
xor QWORD PTR [rsp+320], rsi
mov rbx, [rsp+160]
mov rdi, [rsp+168]
mov rbp, [rsp+176]
mov r10, [rsp+184]
mov r9, r10
xor r9, 16
mov rcx, r10
xor rcx, 32
xor r10, 48
mov rax, rbx
mul rdi
movdqu xmm2, XMMWORD PTR [r9+r11]
movdqu xmm1, XMMWORD PTR [rcx+r11]
pxor xmm6, xmm2
pxor xmm6, xmm1
paddq xmm1, xmm7
add r8, rdx
movdqu xmm0, XMMWORD PTR [r10+r11]
pxor xmm6, xmm0
paddq xmm0, xmm5
paddq xmm2, xmm4
movdqu XMMWORD PTR [r9+r11], xmm0
movdqa xmm5, xmm4
mov r9, QWORD PTR [rsp+320]
movdqa xmm4, xmm6
add r9, rax
movdqu XMMWORD PTR [rcx+r11], xmm2
movdqu XMMWORD PTR [r10+r11], xmm1
mov r10, QWORD PTR [rsp+304]
movd r12d, xmm11
mov QWORD PTR [r14], r8
xor r8, rbx
mov rax, r8
mov QWORD PTR [r14+8], r9
and eax, 2097136
xor r9, rbp
mov QWORD PTR [rsp+320], r9
mov QWORD PTR [rsp+328], rax
sub r12d, 1
jne CryptonightR_soft_aes_template_mainloop
CryptonightR_soft_aes_template_part3:
movaps xmm6, XMMWORD PTR [rsp+16]
movaps xmm7, XMMWORD PTR [rsp+32]
movaps xmm8, XMMWORD PTR [rsp+48]
movaps xmm9, XMMWORD PTR [rsp+64]
movaps xmm10, XMMWORD PTR [rsp+80]
movaps xmm11, XMMWORD PTR [rsp+96]
movaps xmm12, XMMWORD PTR [rsp+112]
movaps xmm13, XMMWORD PTR [rsp+128]
add rsp, 232
pop r15
pop r14
pop r13
pop r12
pop rdi
pop rsi
pop rbp
pop rbx
ret
CryptonightR_soft_aes_template_end:

View file

@ -531,6 +531,8 @@ PUBLIC FN_PREFIX(CryptonightR_instruction_mov256)
#include "CryptonightWOW_template.inc" #include "CryptonightWOW_template.inc"
#include "CryptonightR_template.inc" #include "CryptonightR_template.inc"
#include "CryptonightWOW_soft_aes_template.inc"
#include "CryptonightR_soft_aes_template.inc"
FN_PREFIX(CryptonightR_instruction0): FN_PREFIX(CryptonightR_instruction0):
imul rbx, rbx imul rbx, rbx

View file

@ -518,6 +518,8 @@ PUBLIC CryptonightR_instruction_mov256
INCLUDE CryptonightWOW_template_win.inc INCLUDE CryptonightWOW_template_win.inc
INCLUDE CryptonightR_template_win.inc INCLUDE CryptonightR_template_win.inc
INCLUDE CryptonightWOW_soft_aes_template_win.inc
INCLUDE CryptonightR_soft_aes_template_win.inc
CryptonightR_instruction0: CryptonightR_instruction0:
imul rbx, rbx imul rbx, rbx

View file

@ -26,6 +26,30 @@ extern "C"
void CryptonightR_template_double_part4(); void CryptonightR_template_double_part4();
void CryptonightR_template_double_end(); void CryptonightR_template_double_end();
void CryptonightWOW_soft_aes_template_part1();
void CryptonightWOW_soft_aes_template_mainloop();
void CryptonightWOW_soft_aes_template_part2();
void CryptonightWOW_soft_aes_template_part3();
void CryptonightWOW_soft_aes_template_end();
void CryptonightWOW_soft_aes_template_double_part1();
void CryptonightWOW_soft_aes_template_double_mainloop();
void CryptonightWOW_soft_aes_template_double_part2();
void CryptonightWOW_soft_aes_template_double_part3();
void CryptonightWOW_soft_aes_template_double_part4();
void CryptonightWOW_soft_aes_template_double_end();
void CryptonightR_soft_aes_template_part1();
void CryptonightR_soft_aes_template_mainloop();
void CryptonightR_soft_aes_template_part2();
void CryptonightR_soft_aes_template_part3();
void CryptonightR_soft_aes_template_end();
void CryptonightR_soft_aes_template_double_part1();
void CryptonightR_soft_aes_template_double_mainloop();
void CryptonightR_soft_aes_template_double_part2();
void CryptonightR_soft_aes_template_double_part3();
void CryptonightR_soft_aes_template_double_part4();
void CryptonightR_soft_aes_template_double_end();
void CryptonightR_instruction0(); void CryptonightR_instruction0();
void CryptonightR_instruction1(); void CryptonightR_instruction1();
void CryptonightR_instruction2(); void CryptonightR_instruction2();

View file

@ -12,6 +12,8 @@ PUBLIC FN_PREFIX(CryptonightR_template_double_end)
ALIGN(64) ALIGN(64)
FN_PREFIX(CryptonightR_template_part1): FN_PREFIX(CryptonightR_template_part1):
mov rcx, [rcx]
mov QWORD PTR [rsp+16], rbx mov QWORD PTR [rsp+16], rbx
mov QWORD PTR [rsp+24], rbp mov QWORD PTR [rsp+24], rbp
mov QWORD PTR [rsp+32], rsi mov QWORD PTR [rsp+32], rsi
@ -70,29 +72,30 @@ FN_PREFIX(CryptonightR_template_mainloop):
aesenc xmm5, xmm4 aesenc xmm5, xmm4
mov r12d, r9d mov r13d, r9d
mov eax, r9d mov eax, r9d
xor r9d, 48 xor r9d, 48
xor r12d, 16 xor r13d, 16
xor eax, 32 xor eax, 32
movdqu xmm0, XMMWORD PTR [r9+r11] movdqu xmm0, XMMWORD PTR [r9+r11]
movaps xmm3, xmm0 movaps xmm3, xmm0
movdqu xmm2, XMMWORD PTR [r12+r11] movdqu xmm2, XMMWORD PTR [r13+r11]
movdqu xmm1, XMMWORD PTR [rax+r11] movdqu xmm1, XMMWORD PTR [rax+r11]
pxor xmm0, xmm2 pxor xmm0, xmm2
pxor xmm5, xmm1 pxor xmm5, xmm1
pxor xmm5, xmm0 pxor xmm5, xmm0
paddq xmm3, xmm7
paddq xmm2, xmm6
paddq xmm1, xmm4
movdqu XMMWORD PTR [r12+r11], xmm3
movdqu XMMWORD PTR [rax+r11], xmm2
movdqu XMMWORD PTR [r9+r11], xmm1
movq r12, xmm5 movq r12, xmm5
movd r10d, xmm5 movd r10d, xmm5
and r10d, 2097136 and r10d, 2097136
paddq xmm3, xmm7
paddq xmm2, xmm6
paddq xmm1, xmm4
movdqu XMMWORD PTR [r13+r11], xmm3
movdqu XMMWORD PTR [rax+r11], xmm2
movdqu XMMWORD PTR [r9+r11], xmm1
movdqa xmm0, xmm5 movdqa xmm0, xmm5
pxor xmm0, xmm6 pxor xmm0, xmm6
movdqu XMMWORD PTR [rdx], xmm0 movdqu XMMWORD PTR [rdx], xmm0
@ -102,14 +105,16 @@ FN_PREFIX(CryptonightR_template_mainloop):
shl rdx, 32 shl rdx, 32
or r13, rdx or r13, rdx
xor r13, QWORD PTR [r10+r11]
mov r14, QWORD PTR [r10+r11+8]
movd eax, xmm6 movd eax, xmm6
movd edx, xmm7 movd edx, xmm7
pextrd r9d, xmm7, 2 pextrd r9d, xmm7, 2
xor r13, QWORD PTR [r10+r11]
mov r14, QWORD PTR [r10+r11+8]
FN_PREFIX(CryptonightR_template_part2): FN_PREFIX(CryptonightR_template_part2):
lea rcx, [r10+r11]
mov eax, edi mov eax, edi
mov edx, ebp mov edx, ebp
shl rdx, 32 shl rdx, 32
@ -124,6 +129,8 @@ FN_PREFIX(CryptonightR_template_part2):
mov rax, r13 mov rax, r13
mul r12 mul r12
add r15, rax
add rsp, rdx
mov r9d, r10d mov r9d, r10d
mov r12d, r10d mov r12d, r10d
@ -145,13 +152,10 @@ FN_PREFIX(CryptonightR_template_part2):
movdqu XMMWORD PTR [r10+r11], xmm3 movdqu XMMWORD PTR [r10+r11], xmm3
movdqa xmm7, xmm6 movdqa xmm7, xmm6
add r15, rax mov QWORD PTR [rcx], rsp
add rsp, rdx
xor r10, 48
mov QWORD PTR [r10+r11], rsp
xor rsp, r13 xor rsp, r13
mov r9d, esp mov r9d, esp
mov QWORD PTR [r10+r11+8], r15 mov QWORD PTR [rcx+8], r15
and r9d, 2097136 and r9d, 2097136
xor r15, r14 xor r15, r14
movdqa xmm6, xmm5 movdqa xmm6, xmm5
@ -181,6 +185,9 @@ FN_PREFIX(CryptonightR_template_end):
ALIGN(64) ALIGN(64)
FN_PREFIX(CryptonightR_template_double_part1): FN_PREFIX(CryptonightR_template_double_part1):
mov rdx, [rcx+8]
mov rcx, [rcx]
mov QWORD PTR [rsp+24], rbx mov QWORD PTR [rsp+24], rbx
push rbp push rbp
push rsi push rsi

Some files were not shown because too many files have changed in this diff Show more