1
0
mirror of https://github.com/xmrig/xmrig.git synced 2025-12-12 17:52:48 -05:00

Compare commits

..

23 Commits

Author SHA1 Message Date
XMRig
177e0c9c26 v2.15.0-beta 2019-03-24 02:35:51 +07:00
xmrig
a891d2a590 Update CHANGELOG.md 2019-03-24 02:34:54 +07:00
XMRig
cf7df3f629 v2.15.0-evo 2019-03-20 11:55:15 +07:00
XMRig
453443a2f1 Merge branch 'feature-donate-over-proxy' into evo 2019-03-20 11:53:18 +07:00
XMRig
8d61a47040 Fix uv_tty_reset_mode on Linux. 2019-03-19 22:13:43 +07:00
XMRig
4c95136e6a Implemented donate over proxy. 2019-03-19 21:31:54 +07:00
XMRig
0907d1eb0c Added "donate-over-proxy" option. 2019-03-19 00:16:30 +07:00
XMRig
55686c7d57 Use new Timer inside DonateStrategy. 2019-03-18 13:40:56 +07:00
XMRig
9a6a5a94b5 Add class Timer. 2019-03-18 02:36:17 +07:00
XMRig
bbf0d11a51 Sync changes. 2019-03-17 16:03:45 +07:00
XMRig
c94c0210f7 Fix copy. 2019-03-16 13:32:00 +07:00
XMRig
1b9fbf1132 Fix compile issues. 2019-03-16 13:10:04 +07:00
XMRig
0d86e53a32 Move files. 2019-03-16 02:07:26 +07:00
XMRig
ba68fb6c53 Added real graceful exit. 2019-03-16 00:44:15 +07:00
XMRig
1e62943010 Fix memory leak. 2019-03-15 18:54:45 +07:00
XMRig
af3655c27e Add classes Dns, DnsRecord, IDnsListener. 2019-03-15 18:14:25 +07:00
XMRig
3094741c64 Remove file SubmitResult.cpp. 2019-03-15 12:54:00 +07:00
XMRig
f5077cadbd Added class RecvBuf. 2019-03-15 03:44:02 +07:00
XMRig
9808fbe396 Added class Buffer. 2019-03-15 02:25:38 +07:00
XMRig
8c362411ef Removed class Id. 2019-03-15 02:03:01 +07:00
XMRig
ba01f2a9c4 Rename files. 2019-03-15 01:50:35 +07:00
XMRig
be5d609856 Client refactoring. 2019-03-15 01:06:10 +07:00
XMRig
d57b41c673 Sync changes. 2019-03-14 18:42:27 +07:00
96 changed files with 2293 additions and 1155 deletions

View File

@@ -1,9 +1,7 @@
# v2.14.4 # v2.15.0-beta
- [#992](https://github.com/xmrig/xmrig/pull/992) Fixed compilation with Clang 3.5. - [#314](https://github.com/xmrig/xmrig-proxy/issues/314) Added donate over proxy feature.
- [#1012](https://github.com/xmrig/xmrig/pull/1012) Fixed compilation with Clang 9.0. - Added new option `donate-over-proxy`.
- In HTTP API for unknown hashrate now used `null` instead of `0.0`. - Added real graceful exit.
- Fixed MSVC 2019 version detection.
- Removed obsolete automatic variants.
# v2.14.1 # v2.14.1
* [#975](https://github.com/xmrig/xmrig/issues/975) Fixed crash on Linux if double thread mode used. * [#975](https://github.com/xmrig/xmrig/issues/975) Fixed crash on Linux if double thread mode used.

View File

@@ -16,57 +16,33 @@ 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_platform.h
src/core/ConfigLoader_default.h src/core/ConfigLoader_default.h
src/core/ConfigLoader_platform.h
src/core/Controller.h src/core/Controller.h
src/interfaces/IJobResultListener.h src/interfaces/IJobResultListener.h
src/interfaces/IThread.h src/interfaces/IThread.h
@@ -78,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
@@ -108,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
@@ -143,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
@@ -160,9 +121,9 @@ set(SOURCES_CRYPTO
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
) )
@@ -171,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
) )

View File

@@ -13,7 +13,7 @@ Originally based on cpuminer-multi with heavy optimizations/rewrites and removin
* This is the **CPU-mining** version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd). * This is the **CPU-mining** version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd).
* [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases. * [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases.
<img src="http://i.imgur.com/Ymumes5.png" width="670" > <img src="http://i.imgur.com/OKZRVDh.png" width="619" >
#### Table of contents #### Table of contents
* [Features](#features) * [Features](#features)

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

@@ -10,8 +10,6 @@ if (CMAKE_BUILD_TYPE STREQUAL "Release")
add_definitions(/DNDEBUG) add_definitions(/DNDEBUG)
endif() endif()
include(CheckSymbolExists)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU) if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
@@ -29,8 +27,6 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
else() else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
add_definitions(/DHAVE_ROTR)
endif() endif()
if (WIN32) if (WIN32)
@@ -54,7 +50,6 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
add_definitions(/D_CRT_SECURE_NO_WARNINGS) add_definitions(/D_CRT_SECURE_NO_WARNINGS)
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS) add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
add_definitions(/DNOMINMAX) add_definitions(/DNOMINMAX)
add_definitions(/DHAVE_ROTR)
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
@@ -73,11 +68,6 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
else() else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
check_symbol_exists("_rotr" "x86intrin.h" HAVE_ROTR)
if (HAVE_ROTR)
add_definitions(/DHAVE_ROTR)
endif()
endif() endif()
endif() endif()

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"
@@ -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;
@@ -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

@@ -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"
@@ -51,15 +51,13 @@
#include "workers/Workers.h" #include "workers/Workers.h"
static inline rapidjson::Value normalize(double d) static inline double normalize(double d)
{ {
using namespace rapidjson;
if (!isnormal(d)) { if (!isnormal(d)) {
return Value(kNullType); return 0.0;
} }
return Value(floor(d * 100.0) / 100.0); return floor(d * 100.0) / 100.0;
} }
@@ -176,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;
@@ -256,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);
} }

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

@@ -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

@@ -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);
}
m_ip = buf;
} }
void xmrig::Handle::close(uv_getaddrinfo_t *handle) sockaddr *xmrig::DnsRecord::addr(uint16_t port) const
{ {
if (handle) { if (m_type == A) {
uv_cancel(reinterpret_cast<uv_req_t *>(handle)); sockaddr_in *addr = new sockaddr_in();
close(reinterpret_cast<uv_handle_t *>(handle)); uv_ip4_addr(m_ip.data(), port, addr);
return reinterpret_cast<sockaddr *>(addr);
} }
else if (m_type == AAAA) {
sockaddr_in6 *addr = new sockaddr_in6();
uv_ip6_addr(m_ip.data(), port, addr);
return reinterpret_cast<sockaddr *>(addr);
} }
return nullptr;
void xmrig::Handle::close(uv_handle_t *handle)
{
uv_close(handle, [](uv_handle_t *handle) { delete handle; });
}
void xmrig::Handle::close(uv_signal_t *handle)
{
if (handle) {
uv_signal_stop(handle);
close(reinterpret_cast<uv_handle_t *>(handle));
}
}
void xmrig::Handle::close(uv_tcp_t *handle)
{
if (handle) {
close(reinterpret_cast<uv_handle_t *>(handle));
}
}
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
@@ -232,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
@@ -252,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);
} }
@@ -268,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) {
@@ -310,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()) {
@@ -327,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;
@@ -387,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();
@@ -397,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;
@@ -425,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)) {
@@ -436,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);
@@ -475,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;
} }
@@ -502,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;
} }
@@ -523,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()) {
@@ -535,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;
} }
@@ -547,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);
@@ -590,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;
} }
@@ -597,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();
} }
@@ -622,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
@@ -643,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);
@@ -672,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;
@@ -687,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;
@@ -707,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
} }
} }
@@ -738,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;
} }
@@ -750,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);
} }
@@ -772,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)) {
@@ -790,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();
@@ -799,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;
} }
@@ -818,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);
}
} }
@@ -864,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;
@@ -886,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
} }
@@ -925,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;
@@ -944,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;
} }
@@ -127,6 +101,24 @@ bool xmrig::Job::setBlob(const char *blob)
m_algorithm.setVariant(variant()); m_algorithm.setVariant(variant());
} }
if (!m_algorithm.isForced()) {
if (m_algorithm.variant() == VARIANT_XTL && m_blob[0] >= 9) {
m_algorithm.setVariant(VARIANT_HALF);
}
else if (m_algorithm.variant() == VARIANT_MSR && m_blob[0] >= 8) {
m_algorithm.setVariant(VARIANT_HALF);
}
else if (m_algorithm.variant() == VARIANT_WOW && m_blob[0] < 11) {
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
memset(m_rawBlob, 0, sizeof(m_rawBlob)); memset(m_rawBlob, 0, sizeof(m_rawBlob));
memcpy(m_rawBlob, blob, m_size * 2); memcpy(m_rawBlob, blob, m_size * 2);
@@ -149,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;
} }
@@ -160,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;
} }
} }
@@ -194,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"
@@ -58,6 +58,9 @@ static const char *kUrl = "url";
static const char *kUser = "user"; static const char *kUser = "user";
static const char *kVariant = "variant"; static const char *kVariant = "variant";
const String Pool::kDefaultPassword = "x";
const String Pool::kDefaultUser = "x";
} }
@@ -165,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

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); auto it = m_data.find(id);
if (it != m_data.end()) { if (it != m_data.end()) {
m_data.erase(it); m_data.erase(it);
} }
}
delete obj; return 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,17 +179,13 @@ 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;
if (other.m_data == nullptr) { if (other.m_data == nullptr) {
m_size = 0; m_size = 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

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

@@ -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 HttpRequest;
} class Timer;
class Httpd 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

@@ -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

@@ -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,

View File

@@ -22,7 +22,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <algorithm>
#include <string.h> #include <string.h>
#include <uv.h> #include <uv.h>
#include <inttypes.h> #include <inttypes.h>
@@ -99,10 +98,11 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
} }
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("donate-over-proxy", m_pools.proxyDonate(), allocator);
doc.AddMember("huge-pages", isHugePages(), allocator); doc.AddMember("huge-pages", isHugePages(), allocator);
doc.AddMember("hw-aes", m_aesMode == AES_AUTO ? Value(kNullType) : Value(m_aesMode == AES_HW), allocator); doc.AddMember("hw-aes", m_aesMode == AES_AUTO ? Value(kNullType) : Value(m_aesMode == AES_HW), allocator);
doc.AddMember("log-file", logFile() ? Value(StringRef(logFile())).Move() : Value(kNullType).Move(), allocator); doc.AddMember("log-file", m_logFile.toJSON(), allocator);
doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator); doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator);
doc.AddMember("pools", m_pools.toJSON(doc), allocator); doc.AddMember("pools", m_pools.toJSON(doc), allocator);
doc.AddMember("print-time", printTime(), allocator); doc.AddMember("print-time", printTime(), allocator);

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 },
{ "autosave", 0, nullptr, IConfig::AutoSaveKey },
{ nullptr, 0, nullptr, 0 } { 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;
} }
@@ -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

@@ -215,6 +215,32 @@ template<> inline constexpr Variant cn_base_variant<VARIANT_ZLS>() { return V
template<> inline constexpr Variant cn_base_variant<VARIANT_DOUBLE>() { 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; }

View File

@@ -30,12 +30,6 @@
# include <intrin.h> # include <intrin.h>
# define __restrict__ __restrict # define __restrict__ __restrict
#endif #endif
#ifndef _mm256_bslli_epi128
#define _mm256_bslli_epi128(a, count) _mm256_slli_si256((a), (count))
#endif
#ifndef _mm256_bsrli_epi128
#define _mm256_bsrli_epi128(a, count) _mm256_srli_si256((a), (count))
#endif
inline void prep_dv_avx(__m256i* idx, __m256i& v, __m256& n01) inline void prep_dv_avx(__m256i* idx, __m256i& v, __m256& n01)
{ {

View File

@@ -130,7 +130,7 @@ static inline uint32_t sub_word(uint32_t key)
saes_sbox[key & 0xff]; saes_sbox[key & 0xff];
} }
#ifndef HAVE_ROTR #if defined(__clang__) || defined(XMRIG_ARM)
static inline uint32_t _rotr(uint32_t value, uint32_t amount) static inline uint32_t _rotr(uint32_t value, uint32_t amount)
{ {
return (value >> amount) | (value << ((32 - amount) & 31)); return (value >> amount) | (value << ((32 - amount) & 31));

View File

@@ -31,7 +31,8 @@
#include <stdint.h> #include <stdint.h>
#include "common/net/Job.h" #include "base/tools/String.h"
#include "base/net/stratum/Job.h"
namespace xmrig { namespace xmrig {
@@ -41,11 +42,11 @@ class JobResult
{ {
public: public:
inline JobResult() : poolId(0), diff(0), nonce(0) {} inline JobResult() : poolId(0), diff(0), nonce(0) {}
inline JobResult(int poolId, const Id &jobId, const Id &clientId, uint32_t nonce, const uint8_t *result, uint32_t diff, const Algorithm &algorithm) : inline JobResult(int poolId, const String &jobId, const String &clientId, uint32_t nonce, const uint8_t *result, uint32_t diff, const Algorithm &algorithm) :
algorithm(algorithm), algorithm(algorithm),
poolId(poolId),
clientId(clientId), clientId(clientId),
jobId(jobId), jobId(jobId),
poolId(poolId),
diff(diff), diff(diff),
nonce(nonce) nonce(nonce)
{ {
@@ -71,9 +72,9 @@ public:
Algorithm algorithm; Algorithm algorithm;
Id clientId;
Id jobId;
int poolId; int poolId;
String clientId;
String jobId;
uint32_t diff; uint32_t diff;
uint32_t nonce; uint32_t nonce;
uint8_t result[32]; uint8_t result[32];

View File

@@ -32,9 +32,11 @@
#include "api/Api.h" #include "api/Api.h"
#include "base/net/stratum/Client.h"
#include "base/net/stratum/SubmitResult.h"
#include "base/tools/Chrono.h"
#include "base/tools/Timer.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/Client.h"
#include "common/net/SubmitResult.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "net/Network.h" #include "net/Network.h"
@@ -43,7 +45,8 @@
xmrig::Network::Network(Controller *controller) : xmrig::Network::Network(Controller *controller) :
m_donate(nullptr) m_donate(nullptr),
m_timer(nullptr)
{ {
Workers::setListener(this); Workers::setListener(this);
controller->addListener(this); controller->addListener(this);
@@ -51,19 +54,22 @@ xmrig::Network::Network(Controller *controller) :
const Pools &pools = controller->config()->pools(); const Pools &pools = controller->config()->pools();
m_strategy = pools.createStrategy(this); m_strategy = pools.createStrategy(this);
if (controller->config()->donateLevel() > 0) { if (pools.donateLevel() > 0) {
m_donate = new DonateStrategy(controller->config()->donateLevel(), pools.data().front().user(), controller->config()->algorithm().algo(), this); m_donate = new DonateStrategy(controller, this);
} }
m_timer.data = this; m_timer = new Timer(this, kTickInterval, kTickInterval);
uv_timer_init(uv_default_loop(), &m_timer);
uv_timer_start(&m_timer, Network::onTick, kTickInterval, kTickInterval);
} }
xmrig::Network::~Network() xmrig::Network::~Network()
{ {
delete m_timer;
if (m_donate) {
delete m_donate;
}
delete m_strategy; delete m_strategy;
} }
@@ -74,16 +80,6 @@ void xmrig::Network::connect()
} }
void xmrig::Network::stop()
{
if (m_donate) {
m_donate->stop();
}
m_strategy->stop();
}
void xmrig::Network::onActive(IStrategy *strategy, Client *client) void xmrig::Network::onActive(IStrategy *strategy, Client *client)
{ {
if (m_donate && m_donate == strategy) { if (m_donate && m_donate == strategy) {
@@ -204,7 +200,7 @@ void xmrig::Network::setJob(Client *client, const Job &job, bool donate)
void xmrig::Network::tick() void xmrig::Network::tick()
{ {
const uint64_t now = uv_now(uv_default_loop()); const uint64_t now = Chrono::steadyMSecs();
m_strategy->tick(now); m_strategy->tick(now);
@@ -216,9 +212,3 @@ void xmrig::Network::tick()
Api::tick(m_state); Api::tick(m_state);
# endif # endif
} }
void xmrig::Network::onTick(uv_timer_t *handle)
{
static_cast<Network*>(handle->data)->tick();
}

View File

@@ -27,12 +27,12 @@
#include <vector> #include <vector>
#include <uv.h>
#include "api/NetworkState.h" #include "api/NetworkState.h"
#include "base/kernel/interfaces/IStrategyListener.h"
#include "base/kernel/interfaces/ITimerListener.h"
#include "common/interfaces/IControllerListener.h" #include "common/interfaces/IControllerListener.h"
#include "common/interfaces/IStrategyListener.h"
#include "interfaces/IJobResultListener.h" #include "interfaces/IJobResultListener.h"
@@ -43,16 +43,19 @@ class Controller;
class IStrategy; class IStrategy;
class Network : public IJobResultListener, public IStrategyListener, public IControllerListener class Network : public IJobResultListener, public IStrategyListener, public IControllerListener, public ITimerListener
{ {
public: public:
Network(Controller *controller); Network(Controller *controller);
~Network() override; ~Network() override;
inline IStrategy *strategy() const { return m_strategy; }
void connect(); void connect();
void stop();
protected: protected:
inline void onTimer(const Timer *) override { tick(); }
void onActive(IStrategy *strategy, Client *client) override; void onActive(IStrategy *strategy, Client *client) override;
void onConfigChanged(Config *config, Config *previousConfig) override; void onConfigChanged(Config *config, Config *previousConfig) override;
void onJob(IStrategy *strategy, Client *client, const Job &job) override; void onJob(IStrategy *strategy, Client *client, const Job &job) override;
@@ -67,12 +70,10 @@ private:
void setJob(Client *client, const Job &job, bool donate); void setJob(Client *client, const Job &job, bool donate);
void tick(); void tick();
static void onTick(uv_timer_t *handle);
IStrategy *m_donate; IStrategy *m_donate;
IStrategy *m_strategy; IStrategy *m_strategy;
NetworkState m_state; NetworkState m_state;
uv_timer_t m_timer; Timer *m_timer;
}; };

View File

@@ -23,45 +23,64 @@
*/ */
#include <assert.h>
#include "base/net/stratum/Client.h"
#include "base/net/stratum/Job.h"
#include "base/net/stratum/strategies/FailoverStrategy.h"
#include "base/net/stratum/strategies/SinglePoolStrategy.h"
#include "base/tools/Buffer.h"
#include "base/tools/Timer.h"
#include "common/crypto/keccak.h" #include "common/crypto/keccak.h"
#include "common/interfaces/IStrategyListener.h"
#include "common/net/Client.h"
#include "common/net/Job.h"
#include "common/net/strategies/FailoverStrategy.h"
#include "common/net/strategies/SinglePoolStrategy.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "common/xmrig.h" #include "common/xmrig.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "net/Network.h"
#include "net/strategies/DonateStrategy.h" #include "net/strategies/DonateStrategy.h"
#include "rapidjson/document.h"
static inline float randomf(float min, float max) { namespace xmrig {
return (max - min) * ((((float) rand()) / (float) RAND_MAX)) + min;
}
static inline double randomf(double min, double max) { return (max - min) * (((static_cast<double>(rand())) / static_cast<double>(RAND_MAX))) + min; }
static inline uint64_t random(uint64_t base, double min, double max) { return static_cast<uint64_t>(base * randomf(min, max)); }
xmrig::DonateStrategy::DonateStrategy(int level, const char *user, Algo algo, IStrategyListener *listener) : static const char *kDonateHost = "donate.v2.xmrig.com";
m_active(false), #ifdef XMRIG_FEATURE_TLS
m_donateTime(level * 60 * 1000), static const char *kDonateHostTls = "donate.ssl.xmrig.com";
m_idleTime((100 - level) * 60 * 1000),
m_strategy(nullptr),
m_listener(listener),
m_now(0),
m_stop(0)
{
uint8_t hash[200];
char userId[65] = { 0 };
keccak(reinterpret_cast<const uint8_t *>(user), strlen(user), hash);
Job::toHex(hash, 32, userId);
# ifndef XMRIG_NO_TLS
m_pools.push_back(Pool("donate.ssl.xmrig.com", 443, userId, nullptr, false, true, true));
#endif #endif
m_pools.push_back(Pool("donate.v2.xmrig.com", 3333, userId, nullptr, false, true)); } /* namespace xmrig */
xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener *listener) :
m_tls(false),
m_userId(),
m_proxy(nullptr),
m_donateTime(static_cast<uint64_t>(controller->config()->pools().donateLevel()) * 60 * 1000),
m_idleTime((100 - static_cast<uint64_t>(controller->config()->pools().donateLevel())) * 60 * 1000),
m_controller(controller),
m_strategy(nullptr),
m_listener(listener),
m_state(STATE_NEW),
m_now(0),
m_timestamp(0)
{
uint8_t hash[200];
const String &user = controller->config()->pools().data().front().user();
keccak(reinterpret_cast<const uint8_t *>(user.data()), user.size(), hash);
Buffer::toHex(hash, 32, m_userId);
# ifdef XMRIG_FEATURE_TLS
m_pools.push_back(Pool(kDonateHostTls, 443, m_userId, nullptr, 0, true, true));
# endif
m_pools.push_back(Pool(kDonateHost, 3333, m_userId, nullptr, 0, true));
for (Pool &pool : m_pools) { for (Pool &pool : m_pools) {
pool.adjust(Algorithm(algo, VARIANT_AUTO)); pool.adjust(Algorithm(controller->config()->algorithm().algo(), VARIANT_AUTO));
} }
if (m_pools.size() > 1) { if (m_pools.size() > 1) {
@@ -71,29 +90,42 @@ xmrig::DonateStrategy::DonateStrategy(int level, const char *user, Algo algo, IS
m_strategy = new SinglePoolStrategy(m_pools.front(), 1, 2, this, true); m_strategy = new SinglePoolStrategy(m_pools.front(), 1, 2, this, true);
} }
m_timer.data = this; m_timer = new Timer(this);
uv_timer_init(uv_default_loop(), &m_timer);
idle(m_idleTime * randomf(0.5, 1.5)); setState(STATE_IDLE);
} }
xmrig::DonateStrategy::~DonateStrategy() xmrig::DonateStrategy::~DonateStrategy()
{ {
delete m_timer;
delete m_strategy; delete m_strategy;
if (m_proxy) {
m_proxy->deleteLater();
}
} }
int64_t xmrig::DonateStrategy::submit(const JobResult &result) int64_t xmrig::DonateStrategy::submit(const JobResult &result)
{ {
return m_strategy->submit(result); return m_proxy ? m_proxy->submit(result) : m_strategy->submit(result);
} }
void xmrig::DonateStrategy::connect() void xmrig::DonateStrategy::connect()
{ {
m_proxy = createProxy();
if (m_proxy) {
m_proxy->connect();
}
else if (m_controller->config()->pools().proxyDonate() == Pools::PROXY_DONATE_ALWAYS) {
setState(STATE_IDLE);
}
else {
m_strategy->connect(); m_strategy->connect();
} }
}
void xmrig::DonateStrategy::setAlgo(const xmrig::Algorithm &algo) void xmrig::DonateStrategy::setAlgo(const xmrig::Algorithm &algo)
@@ -104,7 +136,7 @@ void xmrig::DonateStrategy::setAlgo(const xmrig::Algorithm &algo)
void xmrig::DonateStrategy::stop() void xmrig::DonateStrategy::stop()
{ {
uv_timer_stop(&m_timer); m_timer->stop();
m_strategy->stop(); m_strategy->stop();
} }
@@ -115,25 +147,111 @@ void xmrig::DonateStrategy::tick(uint64_t now)
m_strategy->tick(now); m_strategy->tick(now);
if (m_stop && now > m_stop) { if (m_proxy) {
m_strategy->stop(); m_proxy->tick(now);
m_stop = 0; }
if (state() == STATE_WAIT && now > m_timestamp) {
setState(STATE_IDLE);
} }
} }
void xmrig::DonateStrategy::onActive(IStrategy *strategy, Client *client) void xmrig::DonateStrategy::onActive(IStrategy *, Client *client)
{ {
if (!isActive()) { if (isActive()) {
uv_timer_start(&m_timer, DonateStrategy::onTimer, m_donateTime, 0); return;
} }
m_active = true; setState(STATE_ACTIVE);
m_listener->onActive(this, client); m_listener->onActive(this, client);
} }
void xmrig::DonateStrategy::onJob(IStrategy *strategy, Client *client, const Job &job) void xmrig::DonateStrategy::onPause(IStrategy *)
{
}
void xmrig::DonateStrategy::onClose(Client *, int failures)
{
if (failures == 2 && m_controller->config()->pools().proxyDonate() == Pools::PROXY_DONATE_AUTO) {
m_proxy->deleteLater();
m_proxy = nullptr;
m_strategy->connect();
}
}
void xmrig::DonateStrategy::onLogin(Client *, rapidjson::Document &doc, rapidjson::Value &params)
{
auto &allocator = doc.GetAllocator();
# ifdef XMRIG_FEATURE_TLS
if (m_tls) {
char buf[40] = { 0 };
snprintf(buf, sizeof(buf), "stratum+ssl://%s", m_pools[0].url().data());
params.AddMember("url", rapidjson::Value(buf, allocator), allocator);
}
else {
params.AddMember("url", m_pools[1].url().toJSON(), allocator);
}
# else
params.AddMember("url", m_pools[0].url().toJSON(), allocator);
# endif
}
void xmrig::DonateStrategy::onLoginSuccess(Client *client)
{
if (isActive()) {
return;
}
setState(STATE_ACTIVE);
m_listener->onActive(this, client);
}
void xmrig::DonateStrategy::onTimer(const Timer *)
{
setState(isActive() ? STATE_WAIT : STATE_CONNECT);
}
xmrig::Client *xmrig::DonateStrategy::createProxy()
{
if (m_controller->config()->pools().proxyDonate() == Pools::PROXY_DONATE_NONE) {
return nullptr;
}
IStrategy *strategy = m_controller->network()->strategy();
if (!strategy->isActive() || !strategy->client()->has<Client::EXT_CONNECT>()) {
return nullptr;
}
const Client *client = strategy->client();
m_tls = client->has<Client::EXT_TLS>();
Pool pool(client->ip(), client->port(), m_userId, client->pool().password(), 0, true, client->isTLS());
pool.setAlgo(client->pool().algorithm());
Client *proxy = new Client(-1, Platform::userAgent(), this);
proxy->setPool(pool);
proxy->setQuiet(true);
return proxy;
}
void xmrig::DonateStrategy::idle(double min, double max)
{
m_timer->start(random(m_idleTime, min, max), 0);
}
void xmrig::DonateStrategy::setJob(Client *client, const Job &job)
{ {
if (isActive()) { if (isActive()) {
m_listener->onJob(this, client, job); m_listener->onJob(this, client, job);
@@ -141,45 +259,57 @@ void xmrig::DonateStrategy::onJob(IStrategy *strategy, Client *client, const Job
} }
void xmrig::DonateStrategy::onPause(IStrategy *strategy) void xmrig::DonateStrategy::setResult(Client *client, const SubmitResult &result, const char *error)
{
}
void xmrig::DonateStrategy::onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error)
{ {
m_listener->onResultAccepted(this, client, result, error); m_listener->onResultAccepted(this, client, result, error);
} }
void xmrig::DonateStrategy::idle(uint64_t timeout) void xmrig::DonateStrategy::setState(State state)
{ {
uv_timer_start(&m_timer, DonateStrategy::onTimer, timeout, 0); constexpr const uint64_t waitTime = 3000;
assert(m_state != state && state != STATE_NEW);
if (m_state == state) {
return;
} }
const State prev = m_state;
m_state = state;
void xmrig::DonateStrategy::suspend() switch (state) {
{ case STATE_NEW:
# if defined(XMRIG_AMD_PROJECT) || defined(XMRIG_NVIDIA_PROJECT) break;
m_stop = m_now + 5000;
# else
m_stop = m_now + 500;
# endif
m_active = false; case STATE_IDLE:
if (prev == STATE_NEW) {
idle(0.5, 1.5);
}
else if (prev == STATE_CONNECT) {
m_timer->start(20000, 0);
}
else {
m_strategy->stop();
if (m_proxy) {
m_proxy->deleteLater();
m_proxy = nullptr;
}
idle(0.8, 1.2);
}
break;
case STATE_CONNECT:
connect();
break;
case STATE_ACTIVE:
m_timer->start(m_donateTime, 0);
break;
case STATE_WAIT:
m_timestamp = m_now + waitTime;
m_listener->onPause(this); m_listener->onPause(this);
break;
idle(m_idleTime);
} }
void xmrig::DonateStrategy::onTimer(uv_timer_t *handle)
{
auto strategy = static_cast<DonateStrategy*>(handle->data);
if (!strategy->isActive()) {
return strategy->connect();
}
strategy->suspend();
} }

View File

@@ -26,31 +26,37 @@
#define XMRIG_DONATESTRATEGY_H #define XMRIG_DONATESTRATEGY_H
#include <uv.h>
#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/kernel/interfaces/IStrategyListener.h"
#include "common/interfaces/IStrategyListener.h" #include "base/kernel/interfaces/ITimerListener.h"
#include "base/net/stratum/Pool.h"
namespace xmrig { namespace xmrig {
class Client; class Client;
class Controller;
class IStrategyListener; class IStrategyListener;
class DonateStrategy : public IStrategy, public IStrategyListener class DonateStrategy : public IStrategy, public IStrategyListener, public ITimerListener, public IClientListener
{ {
public: public:
DonateStrategy(int level, const char *user, Algo algo, IStrategyListener *listener); DonateStrategy(Controller *controller, IStrategyListener *listener);
~DonateStrategy() override; ~DonateStrategy() override;
public: protected:
inline bool isActive() const override { return m_active; } inline bool isActive() const override { return state() == STATE_ACTIVE; }
inline Client *client() const override { return m_proxy ? m_proxy : m_strategy->client(); }
inline void onJob(IStrategy *, Client *client, const Job &job) override { setJob(client, job); }
inline void onJobReceived(Client *client, const Job &job, const rapidjson::Value &) override { setJob(client, job); }
inline void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); }
inline void onResultAccepted(IStrategy *, Client *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); }
inline void resume() override {} inline void resume() override {}
int64_t submit(const JobResult &result) override; int64_t submit(const JobResult &result) override;
@@ -59,27 +65,45 @@ public:
void stop() override; void stop() override;
void tick(uint64_t now) override; void tick(uint64_t now) override;
protected:
void onActive(IStrategy *strategy, Client *client) override; void onActive(IStrategy *strategy, Client *client) override;
void onJob(IStrategy *strategy, Client *client, const Job &job) override;
void onPause(IStrategy *strategy) override; void onPause(IStrategy *strategy) override;
void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
void onClose(Client *client, int failures) override;
void onLogin(Client *client, rapidjson::Document &doc, rapidjson::Value &params) override;
void onLoginSuccess(Client *client) override;
void onTimer(const Timer *timer) override;
private: private:
void idle(uint64_t timeout); enum State {
void suspend(); STATE_NEW,
STATE_IDLE,
STATE_CONNECT,
STATE_ACTIVE,
STATE_WAIT
};
static void onTimer(uv_timer_t *handle); inline State state() const { return m_state; }
bool m_active; Client *createProxy();
void idle(double min, double max);
void setJob(Client *client, const Job &job);
void setResult(Client *client, const SubmitResult &result, const char *error);
void setState(State state);
bool m_tls;
char m_userId[65];
Client *m_proxy;
const uint64_t m_donateTime; const uint64_t m_donateTime;
const uint64_t m_idleTime; const uint64_t m_idleTime;
Controller *m_controller;
IStrategy *m_strategy; IStrategy *m_strategy;
IStrategyListener *m_listener; IStrategyListener *m_listener;
State m_state;
std::vector<Pool> m_pools; std::vector<Pool> m_pools;
Timer *m_timer;
uint64_t m_now; uint64_t m_now;
uint64_t m_stop; uint64_t m_timestamp;
uv_timer_t m_timer;
}; };

View File

@@ -28,20 +28,18 @@
#define APP_ID "xmrig" #define APP_ID "xmrig"
#define APP_NAME "XMRig" #define APP_NAME "XMRig"
#define APP_DESC "XMRig CPU miner" #define APP_DESC "XMRig CPU miner"
#define APP_VERSION "2.14.4" #define APP_VERSION "2.15.0-beta"
#define APP_DOMAIN "xmrig.com" #define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com" #define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com"
#define APP_KIND "cpu" #define APP_KIND "cpu"
#define APP_VER_MAJOR 2 #define APP_VER_MAJOR 2
#define APP_VER_MINOR 14 #define APP_VER_MINOR 15
#define APP_VER_PATCH 4 #define APP_VER_PATCH 0
#ifdef _MSC_VER #ifdef _MSC_VER
# if (_MSC_VER >= 1920) # if (_MSC_VER >= 1910)
# define MSVC_VERSION 2019
# elif (_MSC_VER >= 1910 && _MSC_VER < 1920)
# define MSVC_VERSION 2017 # define MSVC_VERSION 2017
# elif _MSC_VER == 1900 # elif _MSC_VER == 1900
# define MSVC_VERSION 2015 # define MSVC_VERSION 2015

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,6 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include "base/tools/Handle.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
@@ -49,6 +51,7 @@ inline static const char *format(double h, char *buf, size_t size)
Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) : Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) :
m_highest(0.0), m_highest(0.0),
m_threads(threads), m_threads(threads),
m_timer(nullptr),
m_controller(controller) m_controller(controller)
{ {
m_counts = new uint64_t*[threads]; m_counts = new uint64_t*[threads];
@@ -64,10 +67,11 @@ Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) :
const int printTime = controller->config()->printTime(); const int printTime = controller->config()->printTime();
if (printTime > 0) { if (printTime > 0) {
uv_timer_init(uv_default_loop(), &m_timer); m_timer = new uv_timer_t;
m_timer.data = this; uv_timer_init(uv_default_loop(), m_timer);
m_timer->data = this;
uv_timer_start(&m_timer, Hashrate::onReport, (printTime + 4) * 1000, printTime * 1000); uv_timer_start(m_timer, Hashrate::onReport, (printTime + 4) * 1000, printTime * 1000);
} }
} }
@@ -171,7 +175,8 @@ void Hashrate::print() const
void Hashrate::stop() void Hashrate::stop()
{ {
uv_timer_stop(&m_timer); xmrig::Handle::close(m_timer);
m_timer = 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,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 __HASHRATE_H__ #ifndef XMRIG_HASHRATE_H
#define __HASHRATE_H__ #define XMRIG_HASHRATE_H
#include <stdint.h> #include <stdint.h>
@@ -67,9 +68,9 @@ private:
uint32_t* m_top; uint32_t* m_top;
uint64_t** m_counts; uint64_t** m_counts;
uint64_t** m_timestamps; uint64_t** m_timestamps;
uv_timer_t m_timer; uv_timer_t *m_timer;
xmrig::Controller *m_controller; xmrig::Controller *m_controller;
}; };
#endif /* __HASHRATE_H__ */ #endif /* XMRIG_HASHRATE_H */

View File

@@ -35,7 +35,7 @@
template<size_t N> template<size_t N>
MultiWorker<N>::MultiWorker(Handle *handle) MultiWorker<N>::MultiWorker(ThreadHandle *handle)
: Worker(handle) : Worker(handle)
{ {
m_memory = Mem::create(m_ctx, m_thread->algorithm(), N); m_memory = Mem::create(m_ctx, m_thread->algorithm(), N);

View File

@@ -27,7 +27,7 @@
#define XMRIG_MULTIWORKER_H #define XMRIG_MULTIWORKER_H
#include "common/net/Job.h" #include "base/net/stratum/Job.h"
#include "Mem.h" #include "Mem.h"
#include "net/JobResult.h" #include "net/JobResult.h"
#include "workers/Worker.h" #include "workers/Worker.h"
@@ -40,7 +40,7 @@ template<size_t N>
class MultiWorker : public Worker class MultiWorker : public Worker
{ {
public: public:
MultiWorker(Handle *handle); MultiWorker(ThreadHandle *handle);
~MultiWorker(); ~MultiWorker();
protected: protected:

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,10 +23,10 @@
*/ */
#include "workers/Handle.h" #include "workers/ThreadHandle.h"
Handle::Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays) : ThreadHandle::ThreadHandle(xmrig::IThread *config, uint32_t offset, size_t totalWays) :
m_worker(nullptr), m_worker(nullptr),
m_totalWays(totalWays), m_totalWays(totalWays),
m_offset(offset), m_offset(offset),
@@ -34,13 +35,13 @@ Handle::Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays) :
} }
void Handle::join() void ThreadHandle::join()
{ {
uv_thread_join(&m_thread); uv_thread_join(&m_thread);
} }
void Handle::start(void (*callback) (void *)) void ThreadHandle::start(void (*callback) (void *))
{ {
uv_thread_create(&m_thread, callback, this); uv_thread_create(&m_thread, callback, this);
} }

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 __HANDLE_H__ #ifndef XMRIG_THREADHANDLE_H
#define __HANDLE_H__ #define XMRIG_THREADHANDLE_H
#include <assert.h> #include <assert.h>
@@ -36,10 +37,10 @@
class IWorker; class IWorker;
class Handle class ThreadHandle
{ {
public: public:
Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays); ThreadHandle(xmrig::IThread *config, uint32_t offset, size_t totalWays);
void join(); void join();
void start(void (*callback) (void *)); void start(void (*callback) (void *));
@@ -59,4 +60,4 @@ private:
}; };
#endif /* __HANDLE_H__ */ #endif /* XMRIG_THREADHANDLE_H */

View File

@@ -27,11 +27,11 @@
#include "common/cpu/Cpu.h" #include "common/cpu/Cpu.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "workers/CpuThread.h" #include "workers/CpuThread.h"
#include "workers/Handle.h" #include "workers/ThreadHandle.h"
#include "workers/Worker.h" #include "workers/Worker.h"
Worker::Worker(Handle *handle) : Worker::Worker(ThreadHandle *handle) :
m_id(handle->threadId()), m_id(handle->threadId()),
m_totalWays(handle->totalWays()), m_totalWays(handle->totalWays()),
m_offset(handle->offset()), m_offset(handle->offset()),

View File

@@ -33,7 +33,7 @@
#include "Mem.h" #include "Mem.h"
class Handle; class ThreadHandle;
namespace xmrig { namespace xmrig {
@@ -44,7 +44,7 @@ namespace xmrig {
class Worker : public IWorker class Worker : public IWorker
{ {
public: public:
Worker(Handle *handle); Worker(ThreadHandle *handle);
inline const MemInfo &memory() const { return m_memory; } inline const MemInfo &memory() const { return m_memory; }
inline size_t id() const override { return m_id; } inline size_t id() const override { return m_id; }

View File

@@ -28,6 +28,7 @@
#include "api/Api.h" #include "api/Api.h"
#include "base/tools/Handle.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
@@ -36,9 +37,9 @@
#include "interfaces/IThread.h" #include "interfaces/IThread.h"
#include "Mem.h" #include "Mem.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "workers/Handle.h"
#include "workers/Hashrate.h" #include "workers/Hashrate.h"
#include "workers/MultiWorker.h" #include "workers/MultiWorker.h"
#include "workers/ThreadHandle.h"
#include "workers/Workers.h" #include "workers/Workers.h"
@@ -51,12 +52,12 @@ Workers::LaunchStatus Workers::m_status;
std::atomic<int> Workers::m_paused; std::atomic<int> Workers::m_paused;
std::atomic<uint64_t> Workers::m_sequence; std::atomic<uint64_t> Workers::m_sequence;
std::list<xmrig::JobResult> Workers::m_queue; std::list<xmrig::JobResult> Workers::m_queue;
std::vector<Handle*> Workers::m_workers; std::vector<ThreadHandle*> Workers::m_workers;
uint64_t Workers::m_ticks = 0; uint64_t Workers::m_ticks = 0;
uv_async_t Workers::m_async; uv_async_t *Workers::m_async = nullptr;
uv_mutex_t Workers::m_mutex; uv_mutex_t Workers::m_mutex;
uv_rwlock_t Workers::m_rwlock; uv_rwlock_t Workers::m_rwlock;
uv_timer_t Workers::m_timer; uv_timer_t *Workers::m_timer = nullptr;
xmrig::Controller *Workers::m_controller = nullptr; xmrig::Controller *Workers::m_controller = nullptr;
@@ -103,11 +104,11 @@ void Workers::printHashrate(bool detail)
char num2[8] = { 0 }; char num2[8] = { 0 };
char num3[8] = { 0 }; char num3[8] = { 0 };
Log::i()->text("%s| THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |", isColors ? "\x1B[1;37m" : ""); xmrig::Log::i()->text("%s| THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |", isColors ? "\x1B[1;37m" : "");
size_t i = 0; size_t i = 0;
for (const xmrig::IThread *thread : m_controller->config()->threads()) { for (const xmrig::IThread *thread : m_controller->config()->threads()) {
Log::i()->text("| %6zu | %8" PRId64 " | %7s | %7s | %7s |", xmrig::Log::i()->text("| %6zu | %8" PRId64 " | %7s | %7s | %7s |",
thread->index(), thread->index(),
thread->affinity(), thread->affinity(),
Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::ShortInterval), num1, sizeof num1), Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::ShortInterval), num1, sizeof num1),
@@ -192,14 +193,17 @@ void Workers::start(xmrig::Controller *controller)
m_sequence = 1; m_sequence = 1;
m_paused = 1; m_paused = 1;
uv_async_init(uv_default_loop(), &m_async, Workers::onResult); m_async = new uv_async_t;
uv_timer_init(uv_default_loop(), &m_timer); uv_async_init(uv_default_loop(), m_async, Workers::onResult);
uv_timer_start(&m_timer, Workers::onTick, 500, 500);
m_timer = new uv_timer_t;
uv_timer_init(uv_default_loop(), m_timer);
uv_timer_start(m_timer, Workers::onTick, 500, 500);
uint32_t offset = 0; uint32_t offset = 0;
for (xmrig::IThread *thread : threads) { for (xmrig::IThread *thread : threads) {
Handle *handle = new Handle(thread, offset, m_status.ways); ThreadHandle *handle = new ThreadHandle(thread, offset, m_status.ways);
offset += thread->multiway(); offset += thread->multiway();
m_workers.push_back(handle); m_workers.push_back(handle);
@@ -212,10 +216,10 @@ void Workers::start(xmrig::Controller *controller)
void Workers::stop() void Workers::stop()
{ {
uv_timer_stop(&m_timer); xmrig::Handle::close(m_timer);
xmrig::Handle::close(m_async);
m_hashrate->stop(); m_hashrate->stop();
uv_close(reinterpret_cast<uv_handle_t*>(&m_async), nullptr);
m_paused = 0; m_paused = 0;
m_sequence = 0; m_sequence = 0;
@@ -231,7 +235,7 @@ void Workers::submit(const xmrig::JobResult &result)
m_queue.push_back(result); m_queue.push_back(result);
uv_mutex_unlock(&m_mutex); uv_mutex_unlock(&m_mutex);
uv_async_send(&m_async); uv_async_send(m_async);
} }
@@ -257,7 +261,7 @@ void Workers::threadsSummary(rapidjson::Document &doc)
void Workers::onReady(void *arg) void Workers::onReady(void *arg)
{ {
auto handle = static_cast<Handle*>(arg); auto handle = static_cast<ThreadHandle*>(arg);
IWorker *worker = nullptr; IWorker *worker = nullptr;
@@ -319,7 +323,7 @@ void Workers::onResult(uv_async_t *handle)
void Workers::onTick(uv_timer_t *handle) void Workers::onTick(uv_timer_t *handle)
{ {
for (Handle *handle : m_workers) { for (ThreadHandle *handle : m_workers) {
if (!handle->worker()) { if (!handle->worker()) {
return; return;
} }

View File

@@ -31,14 +31,14 @@
#include <uv.h> #include <uv.h>
#include <vector> #include <vector>
#include "common/net/Job.h" #include "base/net/stratum/Job.h"
#include "net/JobResult.h" #include "net/JobResult.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
class Handle;
class Hashrate; class Hashrate;
class IWorker; class IWorker;
class ThreadHandle;
namespace xmrig { namespace xmrig {
@@ -109,12 +109,12 @@ private:
static std::atomic<int> m_paused; static std::atomic<int> m_paused;
static std::atomic<uint64_t> m_sequence; static std::atomic<uint64_t> m_sequence;
static std::list<xmrig::JobResult> m_queue; static std::list<xmrig::JobResult> m_queue;
static std::vector<Handle*> m_workers; static std::vector<ThreadHandle*> m_workers;
static uint64_t m_ticks; static uint64_t m_ticks;
static uv_async_t m_async; static uv_async_t *m_async;
static uv_mutex_t m_mutex; static uv_mutex_t m_mutex;
static uv_rwlock_t m_rwlock; static uv_rwlock_t m_rwlock;
static uv_timer_t m_timer; static uv_timer_t *m_timer;
static xmrig::Controller *m_controller; static xmrig::Controller *m_controller;
}; };