mirror of
https://github.com/xmrig/xmrig.git
synced 2025-12-06 23:52:38 -05:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4545c84a11 | ||
|
|
f4dadfd90b | ||
|
|
955134b162 | ||
|
|
6ed2d61586 | ||
|
|
a96782218f | ||
|
|
32e7041def | ||
|
|
c16388ade3 | ||
|
|
72569a7fc7 | ||
|
|
751be470b8 | ||
|
|
7937c814ff | ||
|
|
8e42fb9138 | ||
|
|
dbc6f26c91 | ||
|
|
074db6bb72 | ||
|
|
71522214ae | ||
|
|
8ec58a8394 | ||
|
|
263634f585 | ||
|
|
a383eba8df | ||
|
|
152b65b67c | ||
|
|
970b5d1964 | ||
|
|
7536663caf | ||
|
|
7e17f77c11 | ||
|
|
25faeabd61 | ||
|
|
bd8776b7ee | ||
|
|
b2d26eb019 | ||
|
|
14c6f8699e | ||
|
|
c0dcfc2a97 | ||
|
|
f36b5eeaad | ||
|
|
952017ae7a | ||
|
|
faf793b0aa | ||
|
|
e97cd98f90 | ||
|
|
95002ead7d | ||
|
|
c1b3802590 | ||
|
|
1bfbc97c7d | ||
|
|
052290d0e9 | ||
|
|
4f512c41d4 | ||
|
|
91ed7e36cd | ||
|
|
77d9beaf89 | ||
|
|
a791bc113e | ||
|
|
9bfa49b7d0 | ||
|
|
9dc02fc7f3 | ||
|
|
6551818610 |
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,3 +1,16 @@
|
|||||||
|
# v2.0.1
|
||||||
|
- [#27](https://github.com/xmrig/xmrig/issues/27) Fixed possibility crash on 32bit systems.
|
||||||
|
|
||||||
|
# v2.0.0
|
||||||
|
- Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3`
|
||||||
|
- [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-l, --log-file=FILE` to write log to file.
|
||||||
|
- [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-S, --syslog` to use syslog for logging, Linux only.
|
||||||
|
- [#18](https://github.com/xmrig/xmrig/issues/18) Added nice messages for accepted/rejected shares with diff and network latency.
|
||||||
|
- [#20](https://github.com/xmrig/xmrig/issues/20) Fixed `--cpu-affinity` for more than 32 threads.
|
||||||
|
- Fixed Windows XP support.
|
||||||
|
- Fixed regression, option `--no-color` was not fully disable colored output.
|
||||||
|
- Show resolved pool IP address in miner output.
|
||||||
|
|
||||||
# v1.0.1
|
# v1.0.1
|
||||||
- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected.
|
- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected.
|
||||||
|
|
||||||
|
|||||||
@@ -4,20 +4,33 @@ project(xmrig)
|
|||||||
option(WITH_LIBCPUID "Use Libcpuid" ON)
|
option(WITH_LIBCPUID "Use Libcpuid" ON)
|
||||||
option(WITH_AEON "CryptoNight-Lite support" ON)
|
option(WITH_AEON "CryptoNight-Lite support" ON)
|
||||||
|
|
||||||
|
|
||||||
|
include (CheckIncludeFile)
|
||||||
|
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
src/3rdparty/align.h
|
src/3rdparty/align.h
|
||||||
src/App.h
|
src/App.h
|
||||||
src/Console.h
|
|
||||||
src/Cpu.h
|
src/Cpu.h
|
||||||
src/interfaces/IClientListener.h
|
src/interfaces/IClientListener.h
|
||||||
src/interfaces/IJobResultListener.h
|
src/interfaces/IJobResultListener.h
|
||||||
|
src/interfaces/ILogBackend.h
|
||||||
|
src/interfaces/IStrategy.h
|
||||||
|
src/interfaces/IStrategyListener.h
|
||||||
src/interfaces/IWorker.h
|
src/interfaces/IWorker.h
|
||||||
|
src/log/ConsoleLog.h
|
||||||
|
src/log/FileLog.h
|
||||||
|
src/log/Log.h
|
||||||
src/Mem.h
|
src/Mem.h
|
||||||
src/net/Client.h
|
src/net/Client.h
|
||||||
src/net/Job.h
|
src/net/Job.h
|
||||||
src/net/JobResult.h
|
src/net/JobResult.h
|
||||||
src/net/Network.h
|
src/net/Network.h
|
||||||
|
src/net/SubmitResult.h
|
||||||
src/net/Url.h
|
src/net/Url.h
|
||||||
|
src/net/strategies/DonateStrategy.h
|
||||||
|
src/net/strategies/FailoverStrategy.h
|
||||||
|
src/net/strategies/SinglePoolStrategy.h
|
||||||
src/Options.h
|
src/Options.h
|
||||||
src/Summary.h
|
src/Summary.h
|
||||||
src/version.h
|
src/version.h
|
||||||
@@ -45,12 +58,17 @@ set(HEADERS_CRYPTO
|
|||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
src/App.cpp
|
src/App.cpp
|
||||||
src/Console.cpp
|
src/log/ConsoleLog.cpp
|
||||||
|
src/log/FileLog.cpp
|
||||||
|
src/log/Log.cpp
|
||||||
src/Mem.cpp
|
src/Mem.cpp
|
||||||
src/net/Client.cpp
|
src/net/Client.cpp
|
||||||
src/net/Job.cpp
|
src/net/Job.cpp
|
||||||
src/net/Network.cpp
|
src/net/Network.cpp
|
||||||
src/net/Url.cpp
|
src/net/Url.cpp
|
||||||
|
src/net/strategies/DonateStrategy.cpp
|
||||||
|
src/net/strategies/FailoverStrategy.cpp
|
||||||
|
src/net/strategies/SinglePoolStrategy.cpp
|
||||||
src/Options.cpp
|
src/Options.cpp
|
||||||
src/Summary.cpp
|
src/Summary.cpp
|
||||||
src/workers/DoubleWorker.cpp
|
src/workers/DoubleWorker.cpp
|
||||||
@@ -119,7 +137,7 @@ endif()
|
|||||||
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
|
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -Wno-strict-aliasing")
|
||||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
|
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -std=c++14 -fno-exceptions -fno-rtti")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -std=c++14 -fno-exceptions -fno-rtti")
|
||||||
@@ -161,6 +179,12 @@ else()
|
|||||||
set(SOURCES_CPUID src/Cpu_stub.cpp)
|
set(SOURCES_CPUID src/Cpu_stub.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
|
||||||
|
if (HAVE_SYSLOG_H)
|
||||||
|
add_definitions(/DHAVE_SYSLOG_H)
|
||||||
|
set(SOURCES_SYSLOG src/log/SysLog.h src/log/SysLog.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(src)
|
include_directories(src)
|
||||||
include_directories(src/3rdparty)
|
include_directories(src/3rdparty)
|
||||||
include_directories(src/3rdparty/jansson)
|
include_directories(src/3rdparty/jansson)
|
||||||
@@ -168,5 +192,5 @@ include_directories(${UV_INCLUDE_DIR})
|
|||||||
|
|
||||||
add_subdirectory(src/3rdparty/jansson)
|
add_subdirectory(src/3rdparty/jansson)
|
||||||
|
|
||||||
add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO})
|
add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG})
|
||||||
target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB})
|
target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
XMRig is high performance Monero (XMR) CPU miner, with the official full Windows support.
|
XMRig is high performance Monero (XMR) CPU miner, with the official full Windows support.
|
||||||
Based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code.
|
Based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code.
|
||||||
|
|
||||||
<img src="http://i.imgur.com/GdRDnAu.png" width="596" >
|
<img src="https://i.imgur.com/OXoB10D.png" width="628" >
|
||||||
|
|
||||||
#### Table of contents
|
#### Table of contents
|
||||||
* [Features](#features)
|
* [Features](#features)
|
||||||
@@ -38,11 +38,16 @@ Based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of
|
|||||||
xmrig.exe -o xmr-eu.dwarfpool.com:8005 -u YOUR_WALLET -p x -k
|
xmrig.exe -o xmr-eu.dwarfpool.com:8005 -u YOUR_WALLET -p x -k
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Failover
|
||||||
|
```
|
||||||
|
xmrig.exe -o pool.supportxmr.com:5555 -u YOUR_WALLET1 -k -o xmr-eu.dwarfpool.com:8005 -u YOUR_WALLET2 -p x -k
|
||||||
|
```
|
||||||
|
For failover you can add multiple pools, maximum count not limited.
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
```
|
```
|
||||||
-a, --algo=ALGO cryptonight (default) or cryptonight-lite
|
-a, --algo=ALGO cryptonight (default) or cryptonight-lite
|
||||||
-o, --url=URL URL of mining server
|
-o, --url=URL URL of mining server
|
||||||
-b, --backup-url=URL URL of backup mining server
|
|
||||||
-O, --userpass=U:P username:password pair for mining server
|
-O, --userpass=U:P username:password pair for mining server
|
||||||
-u, --user=USERNAME username for mining server
|
-u, --user=USERNAME username for mining server
|
||||||
-p, --pass=PASSWORD password for mining server
|
-p, --pass=PASSWORD password for mining server
|
||||||
|
|||||||
40
src/App.cpp
40
src/App.cpp
@@ -27,9 +27,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
#include "Console.h"
|
|
||||||
#include "Cpu.h"
|
#include "Cpu.h"
|
||||||
#include "crypto/CryptoNight.h"
|
#include "crypto/CryptoNight.h"
|
||||||
|
#include "log/ConsoleLog.h"
|
||||||
|
#include "log/FileLog.h"
|
||||||
|
#include "log/Log.h"
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
#include "net/Network.h"
|
#include "net/Network.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
@@ -38,6 +40,11 @@
|
|||||||
#include "workers/Workers.h"
|
#include "workers/Workers.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_SYSLOG_H
|
||||||
|
# include "log/SysLog.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
App *App::m_self = nullptr;
|
App *App::m_self = nullptr;
|
||||||
|
|
||||||
|
|
||||||
@@ -48,10 +55,25 @@ App::App(int argc, char **argv) :
|
|||||||
{
|
{
|
||||||
m_self = this;
|
m_self = this;
|
||||||
|
|
||||||
Console::init();
|
|
||||||
Cpu::init();
|
Cpu::init();
|
||||||
|
|
||||||
m_options = Options::parse(argc, argv);
|
m_options = Options::parse(argc, argv);
|
||||||
|
|
||||||
|
Log::init();
|
||||||
|
|
||||||
|
if (!m_options->background()) {
|
||||||
|
Log::add(new ConsoleLog(m_options->colors()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_options->logFile()) {
|
||||||
|
Log::add(new FileLog(m_options->logFile()));
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef HAVE_SYSLOG_H
|
||||||
|
if (m_options->syslog()) {
|
||||||
|
Log::add(new SysLog());
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
m_network = new Network(m_options);
|
m_network = new Network(m_options);
|
||||||
|
|
||||||
uv_signal_init(uv_default_loop(), &m_signal);
|
uv_signal_init(uv_default_loop(), &m_signal);
|
||||||
@@ -69,21 +91,21 @@ int App::exec()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CryptoNight::init(m_options->algo(), m_options->algoVariant())) {
|
|
||||||
LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uv_signal_start(&m_signal, App::onSignal, SIGHUP);
|
uv_signal_start(&m_signal, App::onSignal, SIGHUP);
|
||||||
uv_signal_start(&m_signal, App::onSignal, SIGTERM);
|
uv_signal_start(&m_signal, App::onSignal, SIGTERM);
|
||||||
uv_signal_start(&m_signal, App::onSignal, SIGINT);
|
uv_signal_start(&m_signal, App::onSignal, SIGINT);
|
||||||
|
|
||||||
background();
|
background();
|
||||||
|
|
||||||
|
if (!CryptoNight::init(m_options->algo(), m_options->algoVariant())) {
|
||||||
|
LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash());
|
Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash());
|
||||||
Summary::print();
|
Summary::print();
|
||||||
|
|
||||||
Workers::start(m_options->affinity(), m_options->nicehash());
|
Workers::start(m_options->affinity());
|
||||||
|
|
||||||
m_network->connect();
|
m_network->connect();
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
#include "Console.h"
|
|
||||||
#include "Cpu.h"
|
#include "Cpu.h"
|
||||||
|
#include "log/Log.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
#define __CPU_H__
|
#define __CPU_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
class Cpu
|
class Cpu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -36,7 +39,7 @@ public:
|
|||||||
|
|
||||||
static int optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage);
|
static int optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage);
|
||||||
static void init();
|
static void init();
|
||||||
static void setAffinity(int id, unsigned long mask);
|
static void setAffinity(int id, uint64_t mask);
|
||||||
|
|
||||||
static inline bool hasAES() { return m_flags & AES; }
|
static inline bool hasAES() { return m_flags & AES; }
|
||||||
static inline bool isX64() { return m_flags & X86_64; }
|
static inline bool isX64() { return m_flags & X86_64; }
|
||||||
|
|||||||
@@ -40,6 +40,6 @@ void Cpu::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Cpu::setAffinity(int id, unsigned long mask)
|
void Cpu::setAffinity(int id, uint64_t mask)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ void Cpu::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Cpu::setAffinity(int id, unsigned long mask)
|
void Cpu::setAffinity(int id, uint64_t mask)
|
||||||
{
|
{
|
||||||
cpu_set_t set;
|
cpu_set_t set;
|
||||||
CPU_ZERO(&set);
|
CPU_ZERO(&set);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void Cpu::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Cpu::setAffinity(int id, unsigned long mask)
|
void Cpu::setAffinity(int id, uint64_t mask)
|
||||||
{
|
{
|
||||||
if (id == -1) {
|
if (id == -1) {
|
||||||
SetProcessAffinityMask(GetCurrentProcess(), mask);
|
SetProcessAffinityMask(GetCurrentProcess(), mask);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#define __MEM_H__
|
#define __MEM_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,9 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "crypto/CryptoNight.h"
|
#include "crypto/CryptoNight.h"
|
||||||
|
#include "log/Log.h"
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "Console.h"
|
|
||||||
|
|
||||||
|
|
||||||
bool Mem::allocate(int algo, int threads, bool doubleHash)
|
bool Mem::allocate(int algo, int threads, bool doubleHash)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Console.h"
|
#include "log/Log.h"
|
||||||
#include "crypto/CryptoNight.h"
|
#include "crypto/CryptoNight.h"
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
|
|||||||
122
src/Options.cpp
122
src/Options.cpp
@@ -34,7 +34,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "Console.h"
|
|
||||||
#include "Cpu.h"
|
#include "Cpu.h"
|
||||||
#include "donate.h"
|
#include "donate.h"
|
||||||
#include "net/Url.h"
|
#include "net/Url.h"
|
||||||
@@ -55,7 +54,6 @@ Usage: " APP_ID " [OPTIONS]\n\
|
|||||||
Options:\n\
|
Options:\n\
|
||||||
-a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\
|
-a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\
|
||||||
-o, --url=URL URL of mining server\n\
|
-o, --url=URL URL of mining server\n\
|
||||||
-b, --backup-url=URL URL of backup mining server\n\
|
|
||||||
-O, --userpass=U:P username:password pair for mining server\n\
|
-O, --userpass=U:P username:password pair for mining server\n\
|
||||||
-u, --user=USERNAME username for mining server\n\
|
-u, --user=USERNAME username for mining server\n\
|
||||||
-p, --pass=PASSWORD password for mining server\n\
|
-p, --pass=PASSWORD password for mining server\n\
|
||||||
@@ -69,6 +67,12 @@ Options:\n\
|
|||||||
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\
|
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\
|
||||||
-B, --background run the miner in the background\n\
|
-B, --background run the miner in the background\n\
|
||||||
-c, --config=FILE load a JSON-format configuration file\n\
|
-c, --config=FILE load a JSON-format configuration file\n\
|
||||||
|
-l, --log-file=FILE log all output to a file\n"
|
||||||
|
# ifdef HAVE_SYSLOG_H
|
||||||
|
"\
|
||||||
|
-S, --syslog use system log for output messages\n"
|
||||||
|
# endif
|
||||||
|
"\
|
||||||
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\
|
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\
|
||||||
--safe safe adjust threads and av settings for current CPU\n\
|
--safe safe adjust threads and av settings for current CPU\n\
|
||||||
--nicehash enable nicehash support\n\
|
--nicehash enable nicehash support\n\
|
||||||
@@ -78,19 +82,19 @@ Options:\n\
|
|||||||
";
|
";
|
||||||
|
|
||||||
|
|
||||||
static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vb:";
|
static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vl:S";
|
||||||
|
|
||||||
|
|
||||||
static struct option const options[] = {
|
static struct option const options[] = {
|
||||||
{ "algo", 1, nullptr, 'a' },
|
{ "algo", 1, nullptr, 'a' },
|
||||||
{ "av", 1, nullptr, 'v' },
|
{ "av", 1, nullptr, 'v' },
|
||||||
{ "background", 0, nullptr, 'B' },
|
{ "background", 0, nullptr, 'B' },
|
||||||
{ "backup-url", 1, nullptr, 'b' },
|
|
||||||
{ "config", 1, nullptr, 'c' },
|
{ "config", 1, nullptr, 'c' },
|
||||||
{ "cpu-affinity", 1, nullptr, 1020 },
|
{ "cpu-affinity", 1, nullptr, 1020 },
|
||||||
{ "donate-level", 1, nullptr, 1003 },
|
{ "donate-level", 1, nullptr, 1003 },
|
||||||
{ "help", 0, nullptr, 'h' },
|
{ "help", 0, nullptr, 'h' },
|
||||||
{ "keepalive", 0, nullptr ,'k' },
|
{ "keepalive", 0, nullptr ,'k' },
|
||||||
|
{ "log-file", 1, nullptr, 'l' },
|
||||||
{ "max-cpu-usage", 1, nullptr, 1004 },
|
{ "max-cpu-usage", 1, nullptr, 1004 },
|
||||||
{ "nicehash", 0, nullptr, 1006 },
|
{ "nicehash", 0, nullptr, 1006 },
|
||||||
{ "no-color", 0, nullptr, 1002 },
|
{ "no-color", 0, nullptr, 1002 },
|
||||||
@@ -99,6 +103,7 @@ static struct option const options[] = {
|
|||||||
{ "retries", 1, nullptr, 'r' },
|
{ "retries", 1, nullptr, 'r' },
|
||||||
{ "retry-pause", 1, nullptr, 'R' },
|
{ "retry-pause", 1, nullptr, 'R' },
|
||||||
{ "safe", 0, nullptr, 1005 },
|
{ "safe", 0, nullptr, 1005 },
|
||||||
|
{ "syslog", 0, nullptr, 'S' },
|
||||||
{ "threads", 1, nullptr, 't' },
|
{ "threads", 1, nullptr, 't' },
|
||||||
{ "url", 1, nullptr, 'o' },
|
{ "url", 1, nullptr, 'o' },
|
||||||
{ "user", 1, nullptr, 'u' },
|
{ "user", 1, nullptr, 'u' },
|
||||||
@@ -136,12 +141,10 @@ Options::Options(int argc, char **argv) :
|
|||||||
m_background(false),
|
m_background(false),
|
||||||
m_colors(true),
|
m_colors(true),
|
||||||
m_doubleHash(false),
|
m_doubleHash(false),
|
||||||
m_keepAlive(false),
|
|
||||||
m_nicehash(false),
|
|
||||||
m_ready(false),
|
m_ready(false),
|
||||||
m_safe(false),
|
m_safe(false),
|
||||||
m_pass(nullptr),
|
m_syslog(false),
|
||||||
m_user(nullptr),
|
m_logFile(nullptr),
|
||||||
m_algo(0),
|
m_algo(0),
|
||||||
m_algoVariant(0),
|
m_algoVariant(0),
|
||||||
m_donateLevel(kDonateLevel),
|
m_donateLevel(kDonateLevel),
|
||||||
@@ -150,10 +153,10 @@ Options::Options(int argc, char **argv) :
|
|||||||
m_retries(5),
|
m_retries(5),
|
||||||
m_retryPause(5),
|
m_retryPause(5),
|
||||||
m_threads(0),
|
m_threads(0),
|
||||||
m_affinity(-1L),
|
m_affinity(-1L)
|
||||||
m_backupUrl(nullptr),
|
|
||||||
m_url(nullptr)
|
|
||||||
{
|
{
|
||||||
|
m_pools.push_back(new Url());
|
||||||
|
|
||||||
int key;
|
int key;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -172,23 +175,11 @@ Options::Options(int argc, char **argv) :
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_url) {
|
if (!m_pools[0]->isValid()) {
|
||||||
LOG_ERR("No pool URL supplied. Exiting.", argv[0]);
|
fprintf(stderr, "No pool URL supplied. Exiting.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_nicehash && m_url->isNicehash()) {
|
|
||||||
m_nicehash = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_user) {
|
|
||||||
m_user = strdup("x");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_pass) {
|
|
||||||
m_pass = strdup("x");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_algoVariant = getAlgoVariant();
|
m_algoVariant = getAlgoVariant();
|
||||||
if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) {
|
if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) {
|
||||||
m_doubleHash = true;
|
m_doubleHash = true;
|
||||||
@@ -210,11 +201,6 @@ Options::Options(int argc, char **argv) :
|
|||||||
|
|
||||||
Options::~Options()
|
Options::~Options()
|
||||||
{
|
{
|
||||||
delete m_url;
|
|
||||||
delete m_backupUrl;
|
|
||||||
|
|
||||||
free(m_user);
|
|
||||||
free(m_pass);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -222,8 +208,6 @@ bool Options::parseArg(int key, char *arg)
|
|||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int v;
|
int v;
|
||||||
uint64_t ul;
|
|
||||||
Url *url;
|
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'a': /* --algo */
|
case 'a': /* --algo */
|
||||||
@@ -233,35 +217,44 @@ bool Options::parseArg(int key, char *arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'O': /* --userpass */
|
case 'O': /* --userpass */
|
||||||
if (!setUserpass(arg)) {
|
if (!m_pools.back()->setUserpass(arg)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o': /* --url */
|
case 'o': /* --url */
|
||||||
url = parseUrl(arg);
|
if (m_pools.size() > 1 || m_pools[0]->isValid()) {
|
||||||
if (url) {
|
Url *url = new Url(arg);
|
||||||
free(m_url);
|
if (url->isValid()) {
|
||||||
m_url = url;
|
m_pools.push_back(url);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_pools[0]->parse(arg);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case 'b': /* --backup-url */
|
if (!m_pools.back()->isValid()) {
|
||||||
url = parseUrl(arg);
|
return false;
|
||||||
if (url) {
|
|
||||||
free(m_backupUrl);
|
|
||||||
m_backupUrl = url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u': /* --user */
|
case 'u': /* --user */
|
||||||
free(m_user);
|
m_pools.back()->setUser(arg);
|
||||||
m_user = strdup(arg);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p': /* --pass */
|
case 'p': /* --pass */
|
||||||
free(m_pass);
|
m_pools.back()->setPassword(arg);
|
||||||
m_pass = strdup(arg);
|
break;
|
||||||
|
|
||||||
|
case 'l': /* --log-file */
|
||||||
|
free(m_logFile);
|
||||||
|
m_logFile = strdup(arg);
|
||||||
|
m_colors = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r': /* --retries */
|
case 'r': /* --retries */
|
||||||
@@ -309,7 +302,7 @@ bool Options::parseArg(int key, char *arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'k': /* --keepalive */
|
case 'k': /* --keepalive */
|
||||||
m_keepAlive = true;
|
m_pools.back()->setKeepAlive(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'V': /* --version */
|
case 'V': /* --version */
|
||||||
@@ -325,6 +318,11 @@ bool Options::parseArg(int key, char *arg)
|
|||||||
m_colors = false;
|
m_colors = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'S': /* --syslog */
|
||||||
|
m_syslog = true;
|
||||||
|
m_colors = false;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'v': /* --av */
|
case 'v': /* --av */
|
||||||
v = strtol(arg, nullptr, 10);
|
v = strtol(arg, nullptr, 10);
|
||||||
if (v < 0 || v > 1000) {
|
if (v < 0 || v > 1000) {
|
||||||
@@ -337,12 +335,7 @@ bool Options::parseArg(int key, char *arg)
|
|||||||
|
|
||||||
case 1020: /* --cpu-affinity */
|
case 1020: /* --cpu-affinity */
|
||||||
p = strstr(arg, "0x");
|
p = strstr(arg, "0x");
|
||||||
ul = p ? strtoul(p, NULL, 16) : atol(arg);
|
m_affinity = p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10);
|
||||||
if (ul > (1UL << Cpu::threads()) -1) {
|
|
||||||
ul = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_affinity = ul;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1002: /* --no-color */
|
case 1002: /* --no-color */
|
||||||
@@ -360,7 +353,7 @@ bool Options::parseArg(int key, char *arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 1006: /* --nicehash */
|
case 1006: /* --nicehash */
|
||||||
m_nicehash = true;
|
m_pools.back()->setNicehash(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1007: /* --print-time */
|
case 1007: /* --print-time */
|
||||||
@@ -463,25 +456,6 @@ bool Options::setAlgo(const char *algo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Options::setUserpass(const char *userpass)
|
|
||||||
{
|
|
||||||
const char *p = strchr(userpass, ':');
|
|
||||||
if (!p) {
|
|
||||||
showUsage(1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(m_user);
|
|
||||||
free(m_pass);
|
|
||||||
|
|
||||||
m_user = static_cast<char*>(calloc(p - userpass + 1, 1));
|
|
||||||
strncpy(m_user, userpass, p - userpass);
|
|
||||||
m_pass = strdup(p + 1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Options::getAlgoVariant() const
|
int Options::getAlgoVariant() const
|
||||||
{
|
{
|
||||||
# ifndef XMRIG_NO_AEON
|
# ifndef XMRIG_NO_AEON
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#define __OPTIONS_H__
|
#define __OPTIONS_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -51,24 +52,21 @@ public:
|
|||||||
static inline Options* i() { return m_self; }
|
static inline Options* i() { return m_self; }
|
||||||
static Options *parse(int argc, char **argv);
|
static Options *parse(int argc, char **argv);
|
||||||
|
|
||||||
inline bool background() const { return m_background; }
|
inline bool background() const { return m_background; }
|
||||||
inline bool colors() const { return m_colors; }
|
inline bool colors() const { return m_colors; }
|
||||||
inline bool doubleHash() const { return m_doubleHash; }
|
inline bool doubleHash() const { return m_doubleHash; }
|
||||||
inline bool isReady() const { return m_ready; }
|
inline bool isReady() const { return m_ready; }
|
||||||
inline bool keepAlive() const { return m_keepAlive; }
|
inline bool syslog() const { return m_syslog; }
|
||||||
inline bool nicehash() const { return m_nicehash; }
|
inline const char *logFile() const { return m_logFile; }
|
||||||
inline const char *pass() const { return m_pass; }
|
inline const std::vector<Url*> &pools() const { return m_pools; }
|
||||||
inline const char *user() const { return m_user; }
|
inline int algo() const { return m_algo; }
|
||||||
inline const Url *backupUrl() const { return m_backupUrl; }
|
inline int algoVariant() const { return m_algoVariant; }
|
||||||
inline const Url *url() const { return m_url; }
|
inline int donateLevel() const { return m_donateLevel; }
|
||||||
inline int algo() const { return m_algo; }
|
inline int printTime() const { return m_printTime; }
|
||||||
inline int algoVariant() const { return m_algoVariant; }
|
inline int retries() const { return m_retries; }
|
||||||
inline int donateLevel() const { return m_donateLevel; }
|
inline int retryPause() const { return m_retryPause; }
|
||||||
inline int printTime() const { return m_printTime; }
|
inline int threads() const { return m_threads; }
|
||||||
inline int retries() const { return m_retries; }
|
inline int64_t affinity() const { return m_affinity; }
|
||||||
inline int retryPause() const { return m_retryPause; }
|
|
||||||
inline int threads() const { return m_threads; }
|
|
||||||
inline int64_t affinity() const { return m_affinity; }
|
|
||||||
|
|
||||||
const char *algoName() const;
|
const char *algoName() const;
|
||||||
|
|
||||||
@@ -84,7 +82,6 @@ private:
|
|||||||
void showVersion(void);
|
void showVersion(void);
|
||||||
|
|
||||||
bool setAlgo(const char *algo);
|
bool setAlgo(const char *algo);
|
||||||
bool setUserpass(const char *userpass);
|
|
||||||
|
|
||||||
int getAlgoVariant() const;
|
int getAlgoVariant() const;
|
||||||
# ifndef XMRIG_NO_AEON
|
# ifndef XMRIG_NO_AEON
|
||||||
@@ -94,12 +91,10 @@ private:
|
|||||||
bool m_background;
|
bool m_background;
|
||||||
bool m_colors;
|
bool m_colors;
|
||||||
bool m_doubleHash;
|
bool m_doubleHash;
|
||||||
bool m_keepAlive;
|
|
||||||
bool m_nicehash;
|
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
bool m_safe;
|
bool m_safe;
|
||||||
char *m_pass;
|
bool m_syslog;
|
||||||
char *m_user;
|
char *m_logFile;
|
||||||
int m_algo;
|
int m_algo;
|
||||||
int m_algoVariant;
|
int m_algoVariant;
|
||||||
int m_donateLevel;
|
int m_donateLevel;
|
||||||
@@ -109,8 +104,7 @@ private:
|
|||||||
int m_retryPause;
|
int m_retryPause;
|
||||||
int m_threads;
|
int m_threads;
|
||||||
int64_t m_affinity;
|
int64_t m_affinity;
|
||||||
Url *m_backupUrl;
|
std::vector<Url*> m_pools;
|
||||||
Url *m_url;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __OPTIONS_H__ */
|
#endif /* __OPTIONS_H__ */
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
#include "Console.h"
|
|
||||||
#include "Cpu.h"
|
#include "Cpu.h"
|
||||||
|
#include "log/Log.h"
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
#include "net/Url.h"
|
#include "net/Url.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
@@ -50,21 +50,21 @@ static void print_versions()
|
|||||||
|
|
||||||
|
|
||||||
if (Options::i()->colors()) {
|
if (Options::i()->colors()) {
|
||||||
Console::i()->text("\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s", APP_VERSION, uv_version_string(), buf);
|
Log::i()->text("\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s", APP_VERSION, uv_version_string(), buf);
|
||||||
} else {
|
} else {
|
||||||
Console::i()->text(" * VERSIONS: XMRig/%s libuv/%s%s", APP_VERSION, uv_version_string(), buf);
|
Log::i()->text(" * VERSIONS: XMRig/%s libuv/%s%s", APP_VERSION, uv_version_string(), buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_memory() {
|
static void print_memory() {
|
||||||
if (Options::i()->colors()) {
|
if (Options::i()->colors()) {
|
||||||
Console::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s",
|
Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s",
|
||||||
Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable",
|
Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable",
|
||||||
Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled");
|
Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Console::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable", Mem::isHugepagesEnabled() ? "enabled" : "disabled");
|
Log::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable", Mem::isHugepagesEnabled() ? "enabled" : "disabled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,19 +72,19 @@ static void print_memory() {
|
|||||||
static void print_cpu()
|
static void print_cpu()
|
||||||
{
|
{
|
||||||
if (Options::i()->colors()) {
|
if (Options::i()->colors()) {
|
||||||
Console::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI",
|
Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI",
|
||||||
Cpu::brand(),
|
Cpu::brand(),
|
||||||
Cpu::sockets(),
|
Cpu::sockets(),
|
||||||
Cpu::isX64() ? "\x1B[01;32m" : "\x1B[01;31m-",
|
Cpu::isX64() ? "\x1B[01;32m" : "\x1B[01;31m-",
|
||||||
Cpu::hasAES() ? "\x1B[01;32m" : "\x1B[01;31m-");
|
Cpu::hasAES() ? "\x1B[01;32m" : "\x1B[01;31m-");
|
||||||
# ifndef XMRIG_NO_LIBCPUID
|
# ifndef XMRIG_NO_LIBCPUID
|
||||||
Console::i()->text("\x1B[01;32m * \x1B[01;37mCPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0);
|
Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Console::i()->text(" * CPU: %s (%d) %sx64 %sAES-NI", Cpu::brand(), Cpu::sockets(), Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-");
|
Log::i()->text(" * CPU: %s (%d) %sx64 %sAES-NI", Cpu::brand(), Cpu::sockets(), Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-");
|
||||||
# ifndef XMRIG_NO_LIBCPUID
|
# ifndef XMRIG_NO_LIBCPUID
|
||||||
Console::i()->text(" * CPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0);
|
Log::i()->text(" * CPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,28 +100,32 @@ static void print_threads()
|
|||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
Console::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s%s" : " * THREADS: %d, %s, av=%d, donate=%d%%%s%s",
|
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s",
|
||||||
Options::i()->threads(),
|
Options::i()->threads(),
|
||||||
Options::i()->algoName(),
|
Options::i()->algoName(),
|
||||||
Options::i()->algoVariant(),
|
Options::i()->algoVariant(),
|
||||||
Options::i()->donateLevel(),
|
Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "",
|
||||||
Options::i()->nicehash() ? ", nicehash" : "", buf);
|
Options::i()->donateLevel(),
|
||||||
|
buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_pools()
|
static void print_pools()
|
||||||
{
|
{
|
||||||
Console::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #1: \x1B[01;36m%s:%d" : " * POOL #1: %s:%d",
|
const std::vector<Url*> &pools = Options::i()->pools();
|
||||||
Options::i()->url()->host(),
|
|
||||||
Options::i()->url()->port());
|
|
||||||
|
|
||||||
if (!Options::i()->backupUrl()) {
|
for (size_t i = 0; i < pools.size(); ++i) {
|
||||||
return;
|
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s:%d" : " * POOL #%d: %s:%d",
|
||||||
|
i + 1,
|
||||||
|
pools[i]->host(),
|
||||||
|
pools[i]->port());
|
||||||
}
|
}
|
||||||
|
|
||||||
Console::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #2: \x1B[01;36m%s:%d" : " * POOL #2: %s:%d",
|
# ifdef APP_DEBUG
|
||||||
Options::i()->backupUrl()->host(),
|
for (size_t i = 0; i < pools.size(); ++i) {
|
||||||
Options::i()->backupUrl()->port());
|
Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i]->host(), pools[i]->port(), pools[i]->user(), pools[i]->password(), pools[i]->isKeepAlive(), pools[i]->isNicehash());
|
||||||
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
#define __ICLIENTLISTENER_H__
|
#define __ICLIENTLISTENER_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
class Job;
|
class Job;
|
||||||
|
|
||||||
@@ -34,10 +37,10 @@ class IClientListener
|
|||||||
public:
|
public:
|
||||||
virtual ~IClientListener() {}
|
virtual ~IClientListener() {}
|
||||||
|
|
||||||
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) = 0;
|
||||||
virtual void onLoginCredentialsRequired(Client *client) = 0;
|
virtual void onLoginSuccess(Client *client) = 0;
|
||||||
virtual void onLoginSuccess(Client *client) = 0;
|
virtual void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
41
src/interfaces/ILogBackend.h
Normal file
41
src/interfaces/ILogBackend.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/* 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 __ILOGBACKEND_H__
|
||||||
|
#define __ILOGBACKEND_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
|
class ILogBackend
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ILogBackend() {}
|
||||||
|
|
||||||
|
virtual void message(int level, const char* fmt, va_list args) = 0;
|
||||||
|
virtual void text(const char* fmt, va_list args) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __ILOGBACKEND_H__
|
||||||
43
src/interfaces/IStrategy.h
Normal file
43
src/interfaces/IStrategy.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/* 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 __ISTRATEGY_H__
|
||||||
|
#define __ISTRATEGY_H__
|
||||||
|
|
||||||
|
|
||||||
|
class JobResult;
|
||||||
|
|
||||||
|
|
||||||
|
class IStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IStrategy() {}
|
||||||
|
|
||||||
|
virtual bool isActive() const = 0;
|
||||||
|
virtual void connect() = 0;
|
||||||
|
virtual void resume() = 0;
|
||||||
|
virtual void submit(const JobResult &result) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __ISTRATEGY_H__
|
||||||
48
src/interfaces/IStrategyListener.h
Normal file
48
src/interfaces/IStrategyListener.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* 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 __ISTRATEGYLISTENER_H__
|
||||||
|
#define __ISTRATEGYLISTENER_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
class IStrategy;
|
||||||
|
class Job;
|
||||||
|
|
||||||
|
|
||||||
|
class IStrategyListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IStrategyListener() {}
|
||||||
|
|
||||||
|
virtual void onActive(Client *client) = 0;
|
||||||
|
virtual void onJob(Client *client, const Job &job) = 0;
|
||||||
|
virtual void onPause(IStrategy *strategy) = 0;
|
||||||
|
virtual void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __ISTRATEGYLISTENER_H__
|
||||||
@@ -34,21 +34,17 @@
|
|||||||
# include "3rdparty/winansi.h"
|
# include "3rdparty/winansi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Console.h"
|
#include "log/ConsoleLog.h"
|
||||||
|
#include "log/Log.h"
|
||||||
|
|
||||||
|
|
||||||
Console *Console::m_self = nullptr;
|
ConsoleLog::ConsoleLog(bool colors) :
|
||||||
|
m_colors(colors)
|
||||||
|
|
||||||
void Console::init()
|
|
||||||
{
|
{
|
||||||
if (!m_self) {
|
|
||||||
m_self = new Console();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Console::message(Console::Level level, const char* fmt, ...)
|
void ConsoleLog::message(int level, const char* fmt, va_list args)
|
||||||
{
|
{
|
||||||
time_t now = time(nullptr);
|
time_t now = time(nullptr);
|
||||||
tm stime;
|
tm stime;
|
||||||
@@ -59,26 +55,23 @@ void Console::message(Console::Level level, const char* fmt, ...)
|
|||||||
localtime_r(&now, &stime);
|
localtime_r(&now, &stime);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
|
|
||||||
const char* color = nullptr;
|
const char* color = nullptr;
|
||||||
if (m_colors) {
|
if (m_colors) {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case ERR:
|
case Log::ERR:
|
||||||
color = kCL_RED;
|
color = Log::kCL_RED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WARNING:
|
case Log::WARNING:
|
||||||
color = kCL_YELLOW;
|
color = Log::kCL_YELLOW;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NOTICE:
|
case Log::NOTICE:
|
||||||
color = kCL_WHITE;
|
color = Log::kCL_WHITE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEBUG:
|
case Log::DEBUG:
|
||||||
color = kCL_GRAY;
|
color = Log::kCL_GRAY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -97,48 +90,23 @@ void Console::message(Console::Level level, const char* fmt, ...)
|
|||||||
stime.tm_hour,
|
stime.tm_hour,
|
||||||
stime.tm_min,
|
stime.tm_min,
|
||||||
stime.tm_sec,
|
stime.tm_sec,
|
||||||
color,
|
m_colors ? color : "",
|
||||||
fmt,
|
fmt,
|
||||||
m_colors ? kCL_N : ""
|
m_colors ? Log::kCL_N : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
uv_mutex_lock(&m_mutex);
|
vfprintf(stdout, buf, args);
|
||||||
|
|
||||||
vfprintf(stdout, buf, ap);
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
uv_mutex_unlock(&m_mutex);
|
|
||||||
|
|
||||||
va_end(ap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Console::text(const char* fmt, ...)
|
void ConsoleLog::text(const char* fmt, va_list args)
|
||||||
{
|
{
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
|
|
||||||
const int len = 64 + strlen(fmt) + 2;
|
const int len = 64 + strlen(fmt) + 2;
|
||||||
char *buf = static_cast<char *>(alloca(len));
|
char *buf = static_cast<char *>(alloca(len));
|
||||||
|
|
||||||
sprintf(buf, "%s%s\n",
|
sprintf(buf, "%s%s\n", fmt, m_colors ? Log::kCL_N : "");
|
||||||
fmt,
|
|
||||||
m_colors ? kCL_N : ""
|
|
||||||
);
|
|
||||||
|
|
||||||
uv_mutex_lock(&m_mutex);
|
vfprintf(stdout, buf, args);
|
||||||
|
|
||||||
vfprintf(stdout, buf, ap);
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
uv_mutex_unlock(&m_mutex);
|
|
||||||
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Console::Console() :
|
|
||||||
m_colors(true)
|
|
||||||
{
|
|
||||||
uv_mutex_init(&m_mutex);
|
|
||||||
}
|
}
|
||||||
43
src/log/ConsoleLog.h
Normal file
43
src/log/ConsoleLog.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/* 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 __CONSOLELOG_H__
|
||||||
|
#define __CONSOLELOG_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "interfaces/ILogBackend.h"
|
||||||
|
|
||||||
|
|
||||||
|
class ConsoleLog : public ILogBackend
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConsoleLog(bool colors);
|
||||||
|
|
||||||
|
void message(int level, const char* fmt, va_list args) override;
|
||||||
|
void text(const char* fmt, va_list args) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_colors;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __CONSOLELOG_H__ */
|
||||||
103
src/log/FileLog.cpp
Normal file
103
src/log/FileLog.cpp
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
# include <winsock2.h>
|
||||||
|
# include <malloc.h>
|
||||||
|
# include "3rdparty/winansi.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "log/FileLog.h"
|
||||||
|
|
||||||
|
|
||||||
|
FileLog::FileLog(const char *fileName)
|
||||||
|
{
|
||||||
|
uv_fs_t req;
|
||||||
|
m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
|
||||||
|
uv_fs_req_cleanup(&req);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileLog::message(int level, const char* fmt, va_list args)
|
||||||
|
{
|
||||||
|
if (m_file < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t now = time(nullptr);
|
||||||
|
tm stime;
|
||||||
|
|
||||||
|
# ifdef _WIN32
|
||||||
|
localtime_s(&stime, &now);
|
||||||
|
# else
|
||||||
|
localtime_r(&now, &stime);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
char *buf = static_cast<char*>(malloc(512));
|
||||||
|
int size = snprintf(buf, 23, "[%d-%02d-%02d %02d:%02d:%02d] ",
|
||||||
|
stime.tm_year + 1900,
|
||||||
|
stime.tm_mon + 1,
|
||||||
|
stime.tm_mday,
|
||||||
|
stime.tm_hour,
|
||||||
|
stime.tm_min,
|
||||||
|
stime.tm_sec);
|
||||||
|
|
||||||
|
size = vsnprintf(buf + size, 512 - size - 1, fmt, args) + size;
|
||||||
|
buf[size] = '\n';
|
||||||
|
|
||||||
|
write(buf, size + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileLog::text(const char* fmt, va_list args)
|
||||||
|
{
|
||||||
|
message(0, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FileLog::onWrite(uv_fs_t *req)
|
||||||
|
{
|
||||||
|
free(req->data);
|
||||||
|
|
||||||
|
uv_fs_req_cleanup(req);
|
||||||
|
free(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileLog::write(char *data, size_t size)
|
||||||
|
{
|
||||||
|
uv_buf_t buf = uv_buf_init(data, size);
|
||||||
|
uv_fs_t *req = static_cast<uv_fs_t*>(malloc(sizeof(uv_fs_t)));
|
||||||
|
req->data = buf.base;
|
||||||
|
|
||||||
|
uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, 0, FileLog::onWrite);
|
||||||
|
}
|
||||||
50
src/log/FileLog.h
Normal file
50
src/log/FileLog.h
Normal 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 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 __FILELOG_H__
|
||||||
|
#define __FILELOG_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "interfaces/ILogBackend.h"
|
||||||
|
|
||||||
|
|
||||||
|
class FileLog : public ILogBackend
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileLog(const char *fileName);
|
||||||
|
|
||||||
|
void message(int level, const char* fmt, va_list args) override;
|
||||||
|
void text(const char* fmt, va_list args) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void onWrite(uv_fs_t *req);
|
||||||
|
|
||||||
|
void write(char *data, size_t size);
|
||||||
|
|
||||||
|
int m_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __FILELOG_H__ */
|
||||||
79
src/log/Log.cpp
Normal file
79
src/log/Log.cpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
# include <winsock2.h>
|
||||||
|
# include <malloc.h>
|
||||||
|
# include "3rdparty/winansi.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "interfaces/ILogBackend.h"
|
||||||
|
#include "log/Log.h"
|
||||||
|
|
||||||
|
|
||||||
|
Log *Log::m_self = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
void Log::message(Log::Level level, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_list copy;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
for (ILogBackend *backend : m_backends) {
|
||||||
|
va_copy(copy, args);
|
||||||
|
backend->message(level, fmt, copy);
|
||||||
|
va_end(copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Log::text(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_list copy;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
for (ILogBackend *backend : m_backends) {
|
||||||
|
va_copy(copy, args);
|
||||||
|
backend->text(fmt, copy);
|
||||||
|
va_end(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log::~Log()
|
||||||
|
{
|
||||||
|
for (auto backend : m_backends) {
|
||||||
|
delete backend;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,14 +21,18 @@
|
|||||||
* 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 __LOG_H__
|
||||||
#define __CONSOLE_H__
|
#define __LOG_H__
|
||||||
|
|
||||||
|
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
class Console
|
class ILogBackend;
|
||||||
|
|
||||||
|
|
||||||
|
class Log
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Level {
|
enum Level {
|
||||||
@@ -50,34 +54,35 @@ public:
|
|||||||
constexpr static const char* kCL_GRAY = "\x1B[90m";
|
constexpr static const char* kCL_GRAY = "\x1B[90m";
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
static inline Console* i() { return m_self; }
|
static inline Log* i() { return m_self; }
|
||||||
static void init();
|
static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); }
|
||||||
|
static inline void init() { if (!m_self) { m_self = new Log();} }
|
||||||
|
|
||||||
void message(Level level, const char* fmt, ...);
|
void message(Level level, const char* fmt, ...);
|
||||||
void text(const char* fmt, ...);
|
void text(const char* fmt, ...);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Console();
|
inline Log() {}
|
||||||
|
~Log();
|
||||||
|
|
||||||
static Console *m_self;
|
static Log *m_self;
|
||||||
bool m_colors;
|
std::vector<ILogBackend*> m_backends;
|
||||||
uv_mutex_t m_mutex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define LOG_ERR(x, ...) Console::i()->message(Console::ERR, x, ##__VA_ARGS__)
|
#define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__)
|
||||||
#define LOG_WARN(x, ...) Console::i()->message(Console::WARNING, x, ##__VA_ARGS__)
|
#define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__)
|
||||||
#define LOG_NOTICE(x, ...) Console::i()->message(Console::NOTICE, x, ##__VA_ARGS__)
|
#define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__)
|
||||||
#define LOG_INFO(x, ...) Console::i()->message(Console::INFO, x, ##__VA_ARGS__)
|
#define LOG_INFO(x, ...) Log::i()->message(Log::INFO, x, ##__VA_ARGS__)
|
||||||
|
|
||||||
#ifdef APP_DEBUG
|
#ifdef APP_DEBUG
|
||||||
# define LOG_DEBUG(x, ...) Console::i()->message(Console::DEBUG, x, ##__VA_ARGS__)
|
# define LOG_DEBUG(x, ...) Log::i()->message(Log::DEBUG, x, ##__VA_ARGS__)
|
||||||
# define LOG_DEBUG_ERR(x, ...) Console::i()->message(Console::ERR, x, ##__VA_ARGS__)
|
# define LOG_DEBUG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__)
|
||||||
# define LOG_DEBUG_WARN(x, ...) Console::i()->message(Console::WARNING, x, ##__VA_ARGS__)
|
# define LOG_DEBUG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
# define LOG_DEBUG(x, ...)
|
# define LOG_DEBUG(x, ...)
|
||||||
# define LOG_DEBUG_ERR(x, ...)
|
# define LOG_DEBUG_ERR(x, ...)
|
||||||
# define LOG_DEBUG_WARN(x, ...)
|
# define LOG_DEBUG_WARN(x, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __CONSOLE_H__ */
|
#endif /* __LOG_H__ */
|
||||||
47
src/log/SysLog.cpp
Normal file
47
src/log/SysLog.cpp
Normal 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 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "log/SysLog.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
|
||||||
|
SysLog::SysLog()
|
||||||
|
{
|
||||||
|
openlog(APP_ID, LOG_PID, LOG_USER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SysLog::message(int level, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
vsyslog(level, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SysLog::text(const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
message(LOG_INFO, fmt, args);
|
||||||
|
}
|
||||||
40
src/log/SysLog.h
Normal file
40
src/log/SysLog.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/* 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 __SYSLOG_H__
|
||||||
|
#define __SYSLOG_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "interfaces/ILogBackend.h"
|
||||||
|
|
||||||
|
|
||||||
|
class SysLog : public ILogBackend
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SysLog();
|
||||||
|
|
||||||
|
void message(int level, const char *fmt, va_list args) override;
|
||||||
|
void text(const char *fmt, va_list args) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __SYSLOG_BACKEND_H__ */
|
||||||
@@ -22,10 +22,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
#include "Console.h"
|
#include "log/Log.h"
|
||||||
#include "interfaces/IClientListener.h"
|
#include "interfaces/IClientListener.h"
|
||||||
#include "net/Client.h"
|
#include "net/Client.h"
|
||||||
#include "net/JobResult.h"
|
#include "net/JobResult.h"
|
||||||
@@ -37,9 +38,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
Client::Client(int id, IClientListener *listener) :
|
Client::Client(int id, const char *agent, IClientListener *listener) :
|
||||||
m_keepAlive(false),
|
m_quiet(false),
|
||||||
m_host(nullptr),
|
m_agent(agent),
|
||||||
m_listener(listener),
|
m_listener(listener),
|
||||||
m_id(id),
|
m_id(id),
|
||||||
m_retryPause(5000),
|
m_retryPause(5000),
|
||||||
@@ -47,16 +48,17 @@ Client::Client(int id, IClientListener *listener) :
|
|||||||
m_sequence(1),
|
m_sequence(1),
|
||||||
m_recvBufPos(0),
|
m_recvBufPos(0),
|
||||||
m_state(UnconnectedState),
|
m_state(UnconnectedState),
|
||||||
m_port(0),
|
|
||||||
m_stream(nullptr),
|
m_stream(nullptr),
|
||||||
m_socket(nullptr)
|
m_socket(nullptr)
|
||||||
{
|
{
|
||||||
|
memset(m_ip, 0, sizeof(m_ip));
|
||||||
|
memset(&m_hints, 0, sizeof(m_hints));
|
||||||
|
|
||||||
m_resolver.data = m_responseTimer.data = m_retriesTimer.data = m_keepAliveTimer.data = this;
|
m_resolver.data = m_responseTimer.data = m_retriesTimer.data = m_keepAliveTimer.data = this;
|
||||||
|
|
||||||
m_hints.ai_family = PF_INET;
|
m_hints.ai_family = PF_INET;
|
||||||
m_hints.ai_socktype = SOCK_STREAM;
|
m_hints.ai_socktype = SOCK_STREAM;
|
||||||
m_hints.ai_protocol = IPPROTO_TCP;
|
m_hints.ai_protocol = IPPROTO_TCP;
|
||||||
m_hints.ai_flags = 0;
|
|
||||||
|
|
||||||
m_recvBuf.base = static_cast<char*>(malloc(kRecvBufSize));
|
m_recvBuf.base = static_cast<char*>(malloc(kRecvBufSize));
|
||||||
m_recvBuf.len = kRecvBufSize;
|
m_recvBuf.len = kRecvBufSize;
|
||||||
@@ -72,13 +74,12 @@ Client::~Client()
|
|||||||
{
|
{
|
||||||
free(m_recvBuf.base);
|
free(m_recvBuf.base);
|
||||||
free(m_socket);
|
free(m_socket);
|
||||||
free(m_host);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::connect()
|
void Client::connect()
|
||||||
{
|
{
|
||||||
resolve(m_host);
|
resolve(m_url.host());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -90,30 +91,19 @@ void Client::connect()
|
|||||||
void Client::connect(const Url *url)
|
void Client::connect(const Url *url)
|
||||||
{
|
{
|
||||||
setUrl(url);
|
setUrl(url);
|
||||||
resolve(m_host);
|
resolve(m_url.host());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::disconnect()
|
void Client::disconnect()
|
||||||
{
|
{
|
||||||
|
uv_timer_stop(&m_retriesTimer);
|
||||||
m_failures = -1;
|
m_failures = -1;
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::login(const char *user, const char *pass, const char *agent)
|
|
||||||
{
|
|
||||||
m_sequence = 1;
|
|
||||||
|
|
||||||
const size_t size = 96 + strlen(user) + strlen(pass) + strlen(agent);
|
|
||||||
char *req = static_cast<char*>(malloc(size));
|
|
||||||
snprintf(req, size, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"}}\n", m_sequence, user, pass, agent);
|
|
||||||
|
|
||||||
send(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send raw data to server.
|
* @brief Send raw data to server.
|
||||||
*
|
*
|
||||||
@@ -121,9 +111,9 @@ void Client::login(const char *user, const char *pass, const char *agent)
|
|||||||
*/
|
*/
|
||||||
void Client::send(char *data)
|
void Client::send(char *data)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_host, m_port, strlen(data), data);
|
LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), strlen(data), data);
|
||||||
if (state() != ConnectedState) {
|
if (state() != ConnectedState) {
|
||||||
LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_host, m_port, m_state);
|
LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,9 +138,7 @@ void Client::setUrl(const Url *url)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(m_host);
|
m_url = url;
|
||||||
m_host = strdup(url->host());
|
|
||||||
m_port = url->port();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -169,6 +157,7 @@ void Client::submit(const JobResult &result)
|
|||||||
snprintf(req, 345, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
|
snprintf(req, 345, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
|
||||||
m_sequence, m_rpcId, result.jobId, nonce, data);
|
m_sequence, m_rpcId, result.jobId, nonce, data);
|
||||||
|
|
||||||
|
m_results[m_sequence] = SubmitResult(result.diff);
|
||||||
send(req);
|
send(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +169,7 @@ bool Client::parseJob(const json_t *params, int *code)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Job job;
|
Job job(m_id, m_url.isNicehash());
|
||||||
if (!job.setId(json_string_value(json_object_get(params, "job_id")))) {
|
if (!job.setId(json_string_value(json_object_get(params, "job_id")))) {
|
||||||
*code = 3;
|
*code = 3;
|
||||||
return false;
|
return false;
|
||||||
@@ -196,10 +185,9 @@ bool Client::parseJob(const json_t *params, int *code)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
job.setPoolId(m_id);
|
|
||||||
m_job = std::move(job);
|
m_job = std::move(job);
|
||||||
|
|
||||||
LOG_DEBUG("[%s:%u] job: \"%s\", diff: %lld", m_host, m_port, job.id(), job.diff());
|
LOG_DEBUG("[%s:%u] job: \"%s\", diff: %lld", m_url.host(), m_url.port(), job.id(), job.diff());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,9 +213,15 @@ int Client::resolve(const char *host)
|
|||||||
|
|
||||||
m_recvBufPos = 0;
|
m_recvBufPos = 0;
|
||||||
|
|
||||||
|
if (m_failures == -1) {
|
||||||
|
m_failures = 0;
|
||||||
|
}
|
||||||
|
|
||||||
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints);
|
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints);
|
||||||
if (r) {
|
if (r) {
|
||||||
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_port, uv_strerror(r));
|
if (!m_quiet) {
|
||||||
|
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r));
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +244,7 @@ void Client::connect(struct sockaddr *addr)
|
|||||||
{
|
{
|
||||||
setState(ConnectingState);
|
setState(ConnectingState);
|
||||||
|
|
||||||
reinterpret_cast<struct sockaddr_in*>(addr)->sin_port = htons(m_port);
|
reinterpret_cast<struct sockaddr_in*>(addr)->sin_port = htons(m_url.port());
|
||||||
free(m_socket);
|
free(m_socket);
|
||||||
|
|
||||||
uv_connect_t *req = (uv_connect_t*) malloc(sizeof(uv_connect_t));
|
uv_connect_t *req = (uv_connect_t*) malloc(sizeof(uv_connect_t));
|
||||||
@@ -261,25 +255,43 @@ void Client::connect(struct sockaddr *addr)
|
|||||||
|
|
||||||
uv_tcp_init(uv_default_loop(), m_socket);
|
uv_tcp_init(uv_default_loop(), m_socket);
|
||||||
uv_tcp_nodelay(m_socket, 1);
|
uv_tcp_nodelay(m_socket, 1);
|
||||||
|
|
||||||
|
# ifndef WIN32
|
||||||
uv_tcp_keepalive(m_socket, 1, 60);
|
uv_tcp_keepalive(m_socket, 1, 60);
|
||||||
|
# endif
|
||||||
|
|
||||||
uv_tcp_connect(req, m_socket, (const sockaddr*) addr, Client::onConnect);
|
uv_tcp_connect(req, m_socket, (const sockaddr*) addr, Client::onConnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Client::login()
|
||||||
|
{
|
||||||
|
m_sequence = 1;
|
||||||
|
m_results.clear();
|
||||||
|
|
||||||
|
const size_t size = 96 + strlen(m_url.user()) + strlen(m_url.password()) + strlen(m_agent);
|
||||||
|
char *req = static_cast<char*>(malloc(size));
|
||||||
|
snprintf(req, size, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"}}\n", m_sequence, m_url.user(), m_url.password(), m_agent);
|
||||||
|
|
||||||
|
send(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::parse(char *line, size_t len)
|
void Client::parse(char *line, size_t len)
|
||||||
{
|
{
|
||||||
startTimeout();
|
startTimeout();
|
||||||
|
|
||||||
line[len - 1] = '\0';
|
line[len - 1] = '\0';
|
||||||
|
|
||||||
LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_host, m_port, len, line);
|
LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
|
||||||
|
|
||||||
json_error_t err;
|
json_error_t err;
|
||||||
json_t *val = json_loads(line, 0, &err);
|
json_t *val = json_loads(line, 0, &err);
|
||||||
|
|
||||||
if (!val) {
|
if (!val) {
|
||||||
LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_host, m_port, err.text);
|
if (!m_quiet) {
|
||||||
|
LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(), err.text);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +310,9 @@ void Client::parse(char *line, size_t len)
|
|||||||
void Client::parseNotification(const char *method, const json_t *params, const json_t *error)
|
void Client::parseNotification(const char *method, const json_t *params, const json_t *error)
|
||||||
{
|
{
|
||||||
if (json_is_object(error)) {
|
if (json_is_object(error)) {
|
||||||
LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_host, m_port, json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code")));
|
if (!m_quiet) {
|
||||||
|
LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code")));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +329,7 @@ void Client::parseNotification(const char *method, const json_t *params, const j
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_host, m_port, method);
|
LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_url.host(), m_url.port(), method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -323,7 +337,15 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error
|
|||||||
{
|
{
|
||||||
if (json_is_object(error)) {
|
if (json_is_object(error)) {
|
||||||
const char *message = json_string_value(json_object_get(error, "message"));
|
const char *message = json_string_value(json_object_get(error, "message"));
|
||||||
LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_host, m_port, message, json_integer_value(json_object_get(error, "code")));
|
|
||||||
|
auto it = m_results.find(id);
|
||||||
|
if (it != m_results.end()) {
|
||||||
|
m_listener->onResultAccepted(this, it->second.diff, it->second.elapsed(), message);
|
||||||
|
m_results.erase(it);
|
||||||
|
}
|
||||||
|
else if (!m_quiet) {
|
||||||
|
LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), message, json_integer_value(json_object_get(error, "code")));
|
||||||
|
}
|
||||||
|
|
||||||
if (id == 1 || (message && strncasecmp(message, "Unauthenticated", 15) == 0)) {
|
if (id == 1 || (message && strncasecmp(message, "Unauthenticated", 15) == 0)) {
|
||||||
close();
|
close();
|
||||||
@@ -339,7 +361,10 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error
|
|||||||
if (id == 1) {
|
if (id == 1) {
|
||||||
int code = -1;
|
int code = -1;
|
||||||
if (!parseLogin(result, &code)) {
|
if (!parseLogin(result, &code)) {
|
||||||
LOG_ERR("[%s:%u] login error code: %d", m_host, m_port, code);
|
if (!m_quiet) {
|
||||||
|
LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code);
|
||||||
|
}
|
||||||
|
|
||||||
return close();
|
return close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,6 +373,12 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error
|
|||||||
m_listener->onJobReceived(this, m_job);
|
m_listener->onJobReceived(this, m_job);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto it = m_results.find(id);
|
||||||
|
if (it != m_results.end()) {
|
||||||
|
m_listener->onResultAccepted(this, it->second.diff, it->second.elapsed(), nullptr);
|
||||||
|
m_results.erase(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -362,8 +393,10 @@ void Client::ping()
|
|||||||
|
|
||||||
void Client::reconnect()
|
void Client::reconnect()
|
||||||
{
|
{
|
||||||
|
setState(ConnectingState);
|
||||||
|
|
||||||
uv_timer_stop(&m_responseTimer);
|
uv_timer_stop(&m_responseTimer);
|
||||||
if (m_keepAlive) {
|
if (m_url.isKeepAlive()) {
|
||||||
uv_timer_stop(&m_keepAliveTimer);
|
uv_timer_stop(&m_keepAliveTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,7 +413,7 @@ void Client::reconnect()
|
|||||||
|
|
||||||
void Client::setState(SocketState state)
|
void Client::setState(SocketState state)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("[%s:%u] state: %d", m_host, m_port, state);
|
LOG_DEBUG("[%s:%u] state: %d", m_url.host(), m_url.port(), state);
|
||||||
|
|
||||||
if (m_state == state) {
|
if (m_state == state) {
|
||||||
return;
|
return;
|
||||||
@@ -393,7 +426,7 @@ void Client::setState(SocketState state)
|
|||||||
void Client::startTimeout()
|
void Client::startTimeout()
|
||||||
{
|
{
|
||||||
uv_timer_stop(&m_responseTimer);
|
uv_timer_stop(&m_responseTimer);
|
||||||
if (!m_keepAlive) {
|
if (!m_url.isKeepAlive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,7 +461,10 @@ void Client::onConnect(uv_connect_t *req, int status)
|
|||||||
{
|
{
|
||||||
auto client = getClient(req->data);
|
auto client = getClient(req->data);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_host, client->m_port, uv_strerror(status));
|
if (!client->m_quiet) {
|
||||||
|
LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
|
||||||
|
}
|
||||||
|
|
||||||
free(req);
|
free(req);
|
||||||
client->close();
|
client->close();
|
||||||
return;
|
return;
|
||||||
@@ -441,7 +477,7 @@ void Client::onConnect(uv_connect_t *req, int status)
|
|||||||
uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead);
|
uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead);
|
||||||
free(req);
|
free(req);
|
||||||
|
|
||||||
client->m_listener->onLoginCredentialsRequired(client);
|
client->login();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -449,8 +485,8 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
|||||||
{
|
{
|
||||||
auto client = getClient(stream->data);
|
auto client = getClient(stream->data);
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
if (nread != UV_EOF) {
|
if (nread != UV_EOF && !client->m_quiet) {
|
||||||
LOG_ERR("[%s:%u] read error: \"%s\"", client->m_host, client->m_port, uv_strerror(nread));
|
LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(nread));
|
||||||
}
|
}
|
||||||
|
|
||||||
return client->close();;
|
return client->close();;
|
||||||
@@ -489,10 +525,12 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
|
|||||||
{
|
{
|
||||||
auto client = getClient(req->data);
|
auto client = getClient(req->data);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_host, client->m_port, uv_strerror(status));
|
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
|
||||||
return client->reconnect();;
|
return client->reconnect();;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uv_ip4_name(reinterpret_cast<sockaddr_in*>(res->ai_addr), client->m_ip, 16);
|
||||||
|
|
||||||
client->connect(res->ai_addr);
|
client->connect(res->ai_addr);
|
||||||
uv_freeaddrinfo(res);
|
uv_freeaddrinfo(res);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,15 +26,17 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
#include <map>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
#include "net/Job.h"
|
#include "net/Job.h"
|
||||||
|
#include "net/SubmitResult.h"
|
||||||
|
#include "net/Url.h"
|
||||||
|
|
||||||
|
|
||||||
class IClientListener;
|
class IClientListener;
|
||||||
class JobResult;
|
class JobResult;
|
||||||
class Url;
|
|
||||||
|
|
||||||
|
|
||||||
class Client
|
class Client
|
||||||
@@ -48,27 +50,27 @@ public:
|
|||||||
ClosingState
|
ClosingState
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr static int kResponseTimeout = 15 * 1000;
|
constexpr static int kResponseTimeout = 20 * 1000;
|
||||||
constexpr static int kKeepAliveTimeout = 60 * 1000;
|
constexpr static int kKeepAliveTimeout = 60 * 1000;
|
||||||
|
|
||||||
Client(int id, IClientListener *listener);
|
Client(int id, const char *agent, IClientListener *listener);
|
||||||
~Client();
|
~Client();
|
||||||
|
|
||||||
void connect();
|
void connect();
|
||||||
void connect(const Url *url);
|
void connect(const Url *url);
|
||||||
void disconnect();
|
void disconnect();
|
||||||
void login(const char *user, const char *pass, const char *agent);
|
|
||||||
void send(char *data);
|
void send(char *data);
|
||||||
void setUrl(const Url *url);
|
void setUrl(const Url *url);
|
||||||
void submit(const JobResult &result);
|
void submit(const JobResult &result);
|
||||||
|
|
||||||
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_host; }
|
inline const char *host() const { return m_url.host(); }
|
||||||
|
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 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_port; }
|
inline uint16_t port() const { return m_url.port(); }
|
||||||
inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; }
|
inline void setQuiet(bool quiet) { m_quiet = quiet; }
|
||||||
inline void setRetryPause(int ms) { m_retryPause = ms; }
|
inline void setRetryPause(int ms) { m_retryPause = ms; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -79,6 +81,7 @@ private:
|
|||||||
int resolve(const char *host);
|
int resolve(const char *host);
|
||||||
void close();
|
void close();
|
||||||
void connect(struct sockaddr *addr);
|
void connect(struct sockaddr *addr);
|
||||||
|
void login();
|
||||||
void parse(char *line, size_t len);
|
void parse(char *line, size_t len);
|
||||||
void parseNotification(const char *method, const json_t *params, const json_t *error);
|
void parseNotification(const char *method, const json_t *params, const json_t *error);
|
||||||
void parseResponse(int64_t id, const json_t *result, const json_t *error);
|
void parseResponse(int64_t id, const json_t *result, const json_t *error);
|
||||||
@@ -95,9 +98,10 @@ private:
|
|||||||
|
|
||||||
static Client *getClient(void *data);
|
static Client *getClient(void *data);
|
||||||
|
|
||||||
bool m_keepAlive;
|
bool m_quiet;
|
||||||
char *m_host;
|
char m_ip[17];
|
||||||
char m_rpcId[64];
|
char m_rpcId[64];
|
||||||
|
const char *m_agent;
|
||||||
IClientListener *m_listener;
|
IClientListener *m_listener;
|
||||||
int m_id;
|
int m_id;
|
||||||
int m_retryPause;
|
int m_retryPause;
|
||||||
@@ -106,8 +110,9 @@ private:
|
|||||||
Job m_job;
|
Job m_job;
|
||||||
size_t m_recvBufPos;
|
size_t m_recvBufPos;
|
||||||
SocketState m_state;
|
SocketState m_state;
|
||||||
|
std::map<int64_t, SubmitResult> m_results;
|
||||||
struct addrinfo m_hints;
|
struct addrinfo m_hints;
|
||||||
uint16_t m_port;
|
Url m_url;
|
||||||
uv_buf_t m_recvBuf;
|
uv_buf_t m_recvBuf;
|
||||||
uv_getaddrinfo_t m_resolver;
|
uv_getaddrinfo_t m_resolver;
|
||||||
uv_stream_t *m_stream;
|
uv_stream_t *m_stream;
|
||||||
|
|||||||
@@ -23,11 +23,10 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
//#include <stdlib.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "log/Log.h"
|
||||||
#include "net/Job.h"
|
#include "net/Job.h"
|
||||||
#include "Console.h"
|
|
||||||
|
|
||||||
|
|
||||||
static inline unsigned char hf_hex2bin(char c, bool &err)
|
static inline unsigned char hf_hex2bin(char c, bool &err)
|
||||||
@@ -57,7 +56,8 @@ static inline char hf_bin2hex(unsigned char c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Job::Job(int poolId) :
|
Job::Job(int poolId, bool nicehash) :
|
||||||
|
m_nicehash(nicehash),
|
||||||
m_poolId(poolId),
|
m_poolId(poolId),
|
||||||
m_size(0),
|
m_size(0),
|
||||||
m_diff(0),
|
m_diff(0),
|
||||||
@@ -82,7 +82,15 @@ bool Job::setBlob(const char *blob)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fromHex(blob, m_size * 2, m_blob);
|
if (!fromHex(blob, m_size * 2, m_blob)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*nonce() != 0 && !m_nicehash) {
|
||||||
|
m_nicehash = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,20 +34,21 @@
|
|||||||
class Job
|
class Job
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Job(int poolId = -2);
|
Job(int poolId = -2, bool nicehash = false);
|
||||||
bool setBlob(const char *blob);
|
bool setBlob(const char *blob);
|
||||||
bool setId(const char *id);
|
bool setId(const char *id);
|
||||||
bool setTarget(const char *target);
|
bool setTarget(const char *target);
|
||||||
|
|
||||||
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
|
inline bool isNicehash() const { return m_nicehash; }
|
||||||
inline const char *id() const { return m_id; }
|
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
|
||||||
inline const uint8_t *blob() const { return m_blob; }
|
inline const char *id() const { return m_id; }
|
||||||
inline int poolId() const { return m_poolId; }
|
inline const uint8_t *blob() const { return m_blob; }
|
||||||
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
|
inline int poolId() const { return m_poolId; }
|
||||||
inline uint32_t diff() const { return m_diff; }
|
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
|
||||||
inline uint32_t size() const { return m_size; }
|
inline uint32_t diff() const { return m_diff; }
|
||||||
inline uint64_t target() const { return m_target; }
|
inline uint32_t size() const { return m_size; }
|
||||||
inline void setPoolId(int poolId) { m_poolId = poolId; }
|
inline uint64_t target() const { return m_target; }
|
||||||
|
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
|
||||||
|
|
||||||
static bool fromHex(const char* in, unsigned int len, unsigned char* out);
|
static bool fromHex(const char* in, unsigned int len, unsigned char* out);
|
||||||
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
|
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
|
||||||
@@ -55,6 +56,7 @@ public:
|
|||||||
static void toHex(const unsigned char* in, unsigned int len, char* out);
|
static void toHex(const unsigned char* in, unsigned int len, char* out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_nicehash;
|
||||||
int m_poolId;
|
int m_poolId;
|
||||||
VAR_ALIGN(16, char m_id[64]);
|
VAR_ALIGN(16, char m_id[64]);
|
||||||
VAR_ALIGN(16, uint8_t m_blob[84]); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
|
VAR_ALIGN(16, uint8_t m_blob[84]); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
|
||||||
|
|||||||
@@ -29,18 +29,32 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "Job.h"
|
||||||
|
|
||||||
|
|
||||||
class JobResult
|
class JobResult
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline JobResult() : poolId(0), nonce(0) {}
|
inline JobResult() : poolId(0), diff(0), nonce(0) {}
|
||||||
inline JobResult(int poolId, const char *jobId, uint32_t nonce, const uint8_t *result) : poolId(poolId), nonce(nonce)
|
inline JobResult(int poolId, const char *jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) : poolId(poolId), diff(diff), nonce(nonce)
|
||||||
{
|
{
|
||||||
memcpy(this->jobId, jobId, sizeof(this->jobId));
|
memcpy(this->jobId, jobId, sizeof(this->jobId));
|
||||||
memcpy(this->result, result, sizeof(this->result));
|
memcpy(this->result, result, sizeof(this->result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline JobResult &operator=(const Job &job) {
|
||||||
|
memcpy(jobId, job.id(), sizeof(jobId));
|
||||||
|
poolId = job.poolId();
|
||||||
|
diff = job.diff();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char jobId[64];
|
char jobId[64];
|
||||||
int poolId;
|
int poolId;
|
||||||
|
uint32_t diff;
|
||||||
uint32_t nonce;
|
uint32_t nonce;
|
||||||
uint8_t result[32];
|
uint8_t result[32];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,79 +25,68 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
#include "Console.h"
|
#include "log/Log.h"
|
||||||
#include "net/Client.h"
|
#include "net/Client.h"
|
||||||
#include "net/Network.h"
|
#include "net/Network.h"
|
||||||
|
#include "net/strategies/DonateStrategy.h"
|
||||||
|
#include "net/strategies/FailoverStrategy.h"
|
||||||
|
#include "net/strategies/SinglePoolStrategy.h"
|
||||||
#include "net/Url.h"
|
#include "net/Url.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "workers/Workers.h"
|
#include "workers/Workers.h"
|
||||||
|
|
||||||
|
|
||||||
Network::Network(const Options *options) :
|
Network::Network(const Options *options) :
|
||||||
m_donate(false),
|
m_donateActive(false),
|
||||||
m_options(options),
|
m_options(options),
|
||||||
m_pool(0),
|
m_donate(nullptr),
|
||||||
m_diff(0)
|
m_accepted(0),
|
||||||
|
m_rejected(0)
|
||||||
{
|
{
|
||||||
Workers::setListener(this);
|
Workers::setListener(this);
|
||||||
|
|
||||||
m_pools.reserve(2);
|
|
||||||
m_agent = userAgent();
|
m_agent = userAgent();
|
||||||
|
|
||||||
addPool(std::make_unique<Url>().get());
|
const std::vector<Url*> &pools = options->pools();
|
||||||
addPool(m_options->url());
|
|
||||||
addPool(m_options->backupUrl());
|
|
||||||
|
|
||||||
m_timer.data = this;
|
if (pools.size() > 1) {
|
||||||
uv_timer_init(uv_default_loop(), &m_timer);
|
m_strategy = new FailoverStrategy(pools, m_agent, this);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_strategy = new SinglePoolStrategy(pools.front(), m_agent, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_options->donateLevel() > 0) {
|
||||||
|
m_donate = new DonateStrategy(m_agent, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Network::~Network()
|
Network::~Network()
|
||||||
{
|
{
|
||||||
for (auto client : m_pools) {
|
|
||||||
delete client;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(m_agent);
|
free(m_agent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Network::connect()
|
void Network::connect()
|
||||||
{
|
{
|
||||||
m_pools[1]->connect();
|
m_strategy->connect();
|
||||||
|
|
||||||
if (m_options->donateLevel()) {
|
|
||||||
uv_timer_start(&m_timer, Network::onTimer, (100 - m_options->donateLevel()) * 60 * 1000, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Network::onClose(Client *client, int failures)
|
void Network::onActive(Client *client)
|
||||||
{
|
{
|
||||||
const int id = client->id();
|
if (client->id() == -1) {
|
||||||
if (id == 0) {
|
LOG_NOTICE("dev donate started");
|
||||||
if (failures == -1) {
|
|
||||||
stopDonate();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pool == id) {
|
LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "use pool %s:%d %s", client->host(), client->port(), client->ip());
|
||||||
m_pool = 0;
|
|
||||||
Workers::pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) {
|
|
||||||
m_pools[2]->connect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Network::onJobReceived(Client *client, const Job &job)
|
void Network::onJob(Client *client, const Job &job)
|
||||||
{
|
{
|
||||||
if (m_donate && client->id() != 0) {
|
if (m_donate && m_donate->isActive() && client->id() != -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,117 +96,52 @@ void Network::onJobReceived(Client *client, const Job &job)
|
|||||||
|
|
||||||
void Network::onJobResult(const JobResult &result)
|
void Network::onJobResult(const JobResult &result)
|
||||||
{
|
{
|
||||||
if (m_options->colors()) {
|
if (result.poolId == -1 && m_donate) {
|
||||||
LOG_NOTICE("\x1B[01;32mSHARE FOUND");
|
return m_donate->submit(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_strategy->submit(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Network::onPause(IStrategy *strategy)
|
||||||
|
{
|
||||||
|
if (m_donate && m_donate == strategy) {
|
||||||
|
LOG_NOTICE("dev donate finished");
|
||||||
|
m_strategy->resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_strategy->isActive()) {
|
||||||
|
LOG_ERR("no active pools, pause mining");
|
||||||
|
return Workers::pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Network::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error)
|
||||||
|
{
|
||||||
|
if (error) {
|
||||||
|
m_rejected++;
|
||||||
|
|
||||||
|
LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%lld/%lld) diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%llu ms)" : "accepted (%lld/%lld) diff %u \"%s\" (%llu ms)", m_accepted, m_rejected, diff, error, ms);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG_NOTICE("SHARE FOUND");
|
m_accepted++;
|
||||||
|
|
||||||
|
LOG_INFO(m_options->colors() ? "\x1B[01;32maccepted\x1B[0m (%lld/%lld) diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%llu ms)" : "accepted (%lld/%lld) diff %u (%llu ms)", m_accepted, m_rejected, diff, ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pools[result.poolId]->submit(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Network::onLoginCredentialsRequired(Client *client)
|
|
||||||
{
|
|
||||||
client->login(m_options->user(), m_options->pass(), m_agent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Network::onLoginSuccess(Client *client)
|
|
||||||
{
|
|
||||||
const int id = client->id();
|
|
||||||
if (id == 0) {
|
|
||||||
return startDonate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id == 2 && m_pool) { // primary pool is already active
|
|
||||||
m_pools[2]->disconnect();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_NOTICE("use pool: \"%s:%d\"", client->host(), client->port());
|
|
||||||
m_pool = id;
|
|
||||||
|
|
||||||
if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool
|
|
||||||
m_pools[2]->disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Network::addPool(const Url *url)
|
|
||||||
{
|
|
||||||
if (!url) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Client *client = new Client(m_pools.size(), this);
|
|
||||||
client->setUrl(url);
|
|
||||||
client->setRetryPause(m_options->retryPause() * 1000);
|
|
||||||
client->setKeepAlive(m_options->keepAlive());
|
|
||||||
|
|
||||||
m_pools.push_back(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Network::setJob(Client *client, const Job &job)
|
void Network::setJob(Client *client, const Job &job)
|
||||||
{
|
{
|
||||||
if (m_options->colors()) {
|
if (m_options->colors()) {
|
||||||
LOG_INFO("\x1B[01;35mnew job\x1B[0m from \"%s:%d\", diff: %d", client->host(), client->port(), job.diff());
|
LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", client->host(), client->port(), job.diff());
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG_INFO("new job from \"%s:%d\", diff: %d", client->host(), client->port(), job.diff());
|
LOG_INFO("new job from %s:%d diff %d", client->host(), client->port(), job.diff());
|
||||||
}
|
}
|
||||||
|
|
||||||
Workers::setJob(job);
|
Workers::setJob(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Network::startDonate()
|
|
||||||
{
|
|
||||||
if (m_donate) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_NOTICE("dev donate started");
|
|
||||||
|
|
||||||
m_donate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Network::stopDonate()
|
|
||||||
{
|
|
||||||
if (!m_donate) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_NOTICE("dev donate finished");
|
|
||||||
|
|
||||||
m_donate = false;
|
|
||||||
if (!m_pool) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Client *client = m_pools[m_pool];
|
|
||||||
if (client->isReady()) {
|
|
||||||
setJob(client, client->job());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Network::onTimer(uv_timer_t *handle)
|
|
||||||
{
|
|
||||||
auto net = static_cast<Network*>(handle->data);
|
|
||||||
|
|
||||||
if (!net->m_donate) {
|
|
||||||
auto url = std::make_unique<Url>("donate.xmrig.com", net->m_options->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443);
|
|
||||||
net->m_pools[0]->connect(url.get());
|
|
||||||
|
|
||||||
uv_timer_start(&net->m_timer, Network::onTimer, net->m_options->donateLevel() * 60 * 1000, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
net->m_pools[0]->disconnect();
|
|
||||||
uv_timer_start(&net->m_timer, Network::onTimer, (100 - net->m_options->donateLevel()) * 60 * 1000, 0);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -31,13 +31,15 @@
|
|||||||
|
|
||||||
#include "interfaces/IClientListener.h"
|
#include "interfaces/IClientListener.h"
|
||||||
#include "interfaces/IJobResultListener.h"
|
#include "interfaces/IJobResultListener.h"
|
||||||
|
#include "interfaces/IStrategyListener.h"
|
||||||
|
|
||||||
|
|
||||||
|
class IStrategy;
|
||||||
class Options;
|
class Options;
|
||||||
class Url;
|
class Url;
|
||||||
|
|
||||||
|
|
||||||
class Network : public IClientListener, public IJobResultListener
|
class Network : public IJobResultListener, public IStrategyListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Network(const Options *options);
|
Network(const Options *options);
|
||||||
@@ -48,11 +50,11 @@ public:
|
|||||||
static char *userAgent();
|
static char *userAgent();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onClose(Client *client, int failures) override;
|
void onActive(Client *client) override;
|
||||||
void onJobReceived(Client *client, const Job &job) override;
|
void onJob(Client *client, const Job &job) override;
|
||||||
void onJobResult(const JobResult &result) override;
|
void onJobResult(const JobResult &result) override;
|
||||||
void onLoginCredentialsRequired(Client *client) override;
|
void onPause(IStrategy *strategy) override;
|
||||||
void onLoginSuccess(Client *client) override;
|
void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addPool(const Url *url);
|
void addPool(const Url *url);
|
||||||
@@ -60,15 +62,13 @@ private:
|
|||||||
void startDonate();
|
void startDonate();
|
||||||
void stopDonate();
|
void stopDonate();
|
||||||
|
|
||||||
static void onTimer(uv_timer_t *handle);
|
bool m_donateActive;
|
||||||
|
|
||||||
bool m_donate;
|
|
||||||
char *m_agent;
|
char *m_agent;
|
||||||
const Options *m_options;
|
const Options *m_options;
|
||||||
int m_pool;
|
IStrategy *m_donate;
|
||||||
std::vector<Client*> m_pools;
|
IStrategy *m_strategy;
|
||||||
uint64_t m_diff;
|
uint64_t m_accepted;
|
||||||
uv_timer_t m_timer;
|
uint64_t m_rejected;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
47
src/net/SubmitResult.h
Normal file
47
src/net/SubmitResult.h
Normal 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 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 __SUBMITRESULT_H__
|
||||||
|
#define __SUBMITRESULT_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
class SubmitResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SubmitResult() : diff(0), start(0) {}
|
||||||
|
inline SubmitResult(uint32_t diff) :
|
||||||
|
diff(diff)
|
||||||
|
{
|
||||||
|
start = uv_hrtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64_t elapsed() const { return (uv_hrtime() - start) / 1000000; }
|
||||||
|
|
||||||
|
uint32_t diff;
|
||||||
|
uint64_t start;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __SUBMITRESULT_H__ */
|
||||||
139
src/net/Url.cpp
139
src/net/Url.cpp
@@ -35,8 +35,12 @@
|
|||||||
|
|
||||||
|
|
||||||
Url::Url() :
|
Url::Url() :
|
||||||
|
m_keepAlive(false),
|
||||||
|
m_nicehash(false),
|
||||||
m_host(nullptr),
|
m_host(nullptr),
|
||||||
m_port(3333)
|
m_password(nullptr),
|
||||||
|
m_user(nullptr),
|
||||||
|
m_port(kDefaultPort)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,40 +57,22 @@ Url::Url() :
|
|||||||
* @param url
|
* @param url
|
||||||
*/
|
*/
|
||||||
Url::Url(const char *url) :
|
Url::Url(const char *url) :
|
||||||
|
m_keepAlive(false),
|
||||||
|
m_nicehash(false),
|
||||||
m_host(nullptr),
|
m_host(nullptr),
|
||||||
m_port(3333)
|
m_password(nullptr),
|
||||||
|
m_user(nullptr),
|
||||||
|
m_port(kDefaultPort)
|
||||||
{
|
{
|
||||||
const char *p = strstr(url, "://");
|
parse(url);
|
||||||
const char *base = url;
|
|
||||||
|
|
||||||
if (p) {
|
|
||||||
if (strncasecmp(url, "stratum+tcp://", 14)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
base = url + 14;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strlen(base) || *base == '/') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *port = strchr(base, ':');
|
|
||||||
if (!port) {
|
|
||||||
m_host = strdup(base);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t size = port++ - base + 1;
|
|
||||||
m_host = static_cast<char*>(malloc(size));
|
|
||||||
memcpy(m_host, base, size - 1);
|
|
||||||
m_host[size - 1] = '\0';
|
|
||||||
|
|
||||||
m_port = strtol(port, nullptr, 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Url::Url(const char *host, uint16_t port) :
|
Url::Url(const char *host, uint16_t port, const char *user, const char *password, bool keepAlive, bool nicehash) :
|
||||||
|
m_keepAlive(keepAlive),
|
||||||
|
m_nicehash(nicehash),
|
||||||
|
m_password(password ? strdup(password) : nullptr),
|
||||||
|
m_user(user ? strdup(user) : nullptr),
|
||||||
m_port(port)
|
m_port(port)
|
||||||
{
|
{
|
||||||
m_host = strdup(host);
|
m_host = strdup(host);
|
||||||
@@ -96,10 +82,101 @@ Url::Url(const char *host, uint16_t port) :
|
|||||||
Url::~Url()
|
Url::~Url()
|
||||||
{
|
{
|
||||||
free(m_host);
|
free(m_host);
|
||||||
|
free(m_password);
|
||||||
|
free(m_user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Url::isNicehash() const
|
bool Url::isNicehash() const
|
||||||
{
|
{
|
||||||
return isValid() && strstr(m_host, ".nicehash.com");
|
return isValid() && (m_nicehash || strstr(m_host, ".nicehash.com"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Url::parse(const char *url)
|
||||||
|
{
|
||||||
|
const char *p = strstr(url, "://");
|
||||||
|
const char *base = url;
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
if (strncasecmp(url, "stratum+tcp://", 14)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
base = url + 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strlen(base) || *base == '/') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *port = strchr(base, ':');
|
||||||
|
if (!port) {
|
||||||
|
m_host = strdup(base);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t size = port++ - base + 1;
|
||||||
|
m_host = static_cast<char*>(malloc(size));
|
||||||
|
memcpy(m_host, base, size - 1);
|
||||||
|
m_host[size - 1] = '\0';
|
||||||
|
|
||||||
|
m_port = strtol(port, nullptr, 10);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Url::setUserpass(const char *userpass)
|
||||||
|
{
|
||||||
|
const char *p = strchr(userpass, ':');
|
||||||
|
if (!p) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(m_user);
|
||||||
|
free(m_password);
|
||||||
|
|
||||||
|
m_user = static_cast<char*>(calloc(p - userpass + 1, 1));
|
||||||
|
strncpy(m_user, userpass, p - userpass);
|
||||||
|
m_password = strdup(p + 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Url::setPassword(const char *password)
|
||||||
|
{
|
||||||
|
if (!password) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(m_password);
|
||||||
|
m_password = strdup(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Url::setUser(const char *user)
|
||||||
|
{
|
||||||
|
if (!user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(m_user);
|
||||||
|
m_user = strdup(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Url &Url::operator=(const Url *other)
|
||||||
|
{
|
||||||
|
m_keepAlive = other->m_keepAlive;
|
||||||
|
m_nicehash = other->m_nicehash;
|
||||||
|
m_port = other->m_port;
|
||||||
|
|
||||||
|
free(m_host);
|
||||||
|
m_host = strdup(other->m_host);
|
||||||
|
|
||||||
|
setPassword(other->m_password);
|
||||||
|
setUser(other->m_user);
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,19 +31,38 @@
|
|||||||
class Url
|
class Url
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
constexpr static const char *kDefaultPassword = "x";
|
||||||
|
constexpr static const char *kDefaultUser = "x";
|
||||||
|
constexpr static uint16_t kDefaultPort = 3333;
|
||||||
|
|
||||||
Url();
|
Url();
|
||||||
Url(const char *url);
|
Url(const char *url);
|
||||||
Url(const char *host, uint16_t port);
|
Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, bool keepAlive = false, bool nicehash = false );
|
||||||
~Url();
|
~Url();
|
||||||
|
|
||||||
bool isNicehash() const;
|
inline bool isKeepAlive() const { return m_keepAlive; }
|
||||||
|
inline bool isValid() const { return m_host && m_port > 0; }
|
||||||
|
inline const char *host() const { return m_host; }
|
||||||
|
inline const char *password() const { return m_password ? m_password : kDefaultPassword; }
|
||||||
|
inline const char *user() const { return m_user ? m_user : kDefaultUser; }
|
||||||
|
inline uint16_t port() const { return m_port; }
|
||||||
|
inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; }
|
||||||
|
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
|
||||||
|
|
||||||
inline bool isValid() const { return m_host && m_port > 0; }
|
bool isNicehash() const;
|
||||||
inline const char *host() const { return m_host; }
|
bool parse(const char *url);
|
||||||
inline uint16_t port() const { return m_port; }
|
bool setUserpass(const char *userpass);
|
||||||
|
void setPassword(const char *password);
|
||||||
|
void setUser(const char *user);
|
||||||
|
|
||||||
|
Url &operator=(const Url *other);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_keepAlive;
|
||||||
|
bool m_nicehash;
|
||||||
char *m_host;
|
char *m_host;
|
||||||
|
char *m_password;
|
||||||
|
char *m_user;
|
||||||
uint16_t m_port;
|
uint16_t m_port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
119
src/net/strategies/DonateStrategy.cpp
Normal file
119
src/net/strategies/DonateStrategy.cpp
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "interfaces/IStrategyListener.h"
|
||||||
|
#include "net/Client.h"
|
||||||
|
#include "net/strategies/DonateStrategy.h"
|
||||||
|
#include "Options.h"
|
||||||
|
|
||||||
|
|
||||||
|
DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
|
||||||
|
m_active(false),
|
||||||
|
m_donateTime(Options::i()->donateLevel() * 60 * 1000),
|
||||||
|
m_idleTime((100 - Options::i()->donateLevel()) * 60 * 1000),
|
||||||
|
m_listener(listener)
|
||||||
|
{
|
||||||
|
Url *url = new Url("donate2.xmrig.com", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443, Options::i()->pools().front()->user());
|
||||||
|
|
||||||
|
m_client = new Client(-1, agent, this);
|
||||||
|
m_client->setUrl(url);
|
||||||
|
m_client->setRetryPause(Options::i()->retryPause() * 1000);
|
||||||
|
m_client->setQuiet(true);
|
||||||
|
|
||||||
|
delete url;
|
||||||
|
|
||||||
|
m_timer.data = this;
|
||||||
|
uv_timer_init(uv_default_loop(), &m_timer);
|
||||||
|
|
||||||
|
idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DonateStrategy::connect()
|
||||||
|
{
|
||||||
|
m_client->connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DonateStrategy::submit(const JobResult &result)
|
||||||
|
{
|
||||||
|
m_client->submit(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DonateStrategy::onClose(Client *client, int failures)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DonateStrategy::onJobReceived(Client *client, const Job &job)
|
||||||
|
{
|
||||||
|
m_listener->onJob(client, job);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DonateStrategy::onLoginSuccess(Client *client)
|
||||||
|
{
|
||||||
|
if (!isActive()) {
|
||||||
|
uv_timer_start(&m_timer, DonateStrategy::onTimer, m_donateTime, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_active = true;
|
||||||
|
m_listener->onActive(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DonateStrategy::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error)
|
||||||
|
{
|
||||||
|
m_listener->onResultAccepted(client, diff, ms, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DonateStrategy::idle()
|
||||||
|
{
|
||||||
|
uv_timer_start(&m_timer, DonateStrategy::onTimer, m_idleTime, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DonateStrategy::stop()
|
||||||
|
{
|
||||||
|
m_client->disconnect();
|
||||||
|
|
||||||
|
m_active = false;
|
||||||
|
m_listener->onPause(this);
|
||||||
|
|
||||||
|
idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DonateStrategy::onTimer(uv_timer_t *handle)
|
||||||
|
{
|
||||||
|
auto strategy = static_cast<DonateStrategy*>(handle->data);
|
||||||
|
|
||||||
|
if (!strategy->isActive()) {
|
||||||
|
return strategy->connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
strategy->stop();
|
||||||
|
}
|
||||||
72
src/net/strategies/DonateStrategy.h
Normal file
72
src/net/strategies/DonateStrategy.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/* 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 __DONATESTRATEGY_H__
|
||||||
|
#define __DONATESTRATEGY_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "interfaces/IClientListener.h"
|
||||||
|
#include "interfaces/IStrategy.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
class IStrategyListener;
|
||||||
|
class Url;
|
||||||
|
|
||||||
|
|
||||||
|
class DonateStrategy : public IStrategy, public IClientListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DonateStrategy(const char *agent, IStrategyListener *listener);
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline bool isActive() const override { return m_active; }
|
||||||
|
inline void resume() override {}
|
||||||
|
|
||||||
|
void connect() override;
|
||||||
|
void submit(const JobResult &result) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onClose(Client *client, int failures) override;
|
||||||
|
void onJobReceived(Client *client, const Job &job) override;
|
||||||
|
void onLoginSuccess(Client *client) override;
|
||||||
|
void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void idle();
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
static void onTimer(uv_timer_t *handle);
|
||||||
|
|
||||||
|
bool m_active;
|
||||||
|
Client *m_client;
|
||||||
|
const int m_donateTime;
|
||||||
|
const int m_idleTime;
|
||||||
|
IStrategyListener *m_listener;
|
||||||
|
uv_timer_t m_timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __DONATESTRATEGY_H__ */
|
||||||
127
src/net/strategies/FailoverStrategy.cpp
Normal file
127
src/net/strategies/FailoverStrategy.cpp
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
/* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "interfaces/IStrategyListener.h"
|
||||||
|
#include "net/Client.h"
|
||||||
|
#include "net/strategies/FailoverStrategy.h"
|
||||||
|
#include "Options.h"
|
||||||
|
|
||||||
|
|
||||||
|
FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, const char *agent, IStrategyListener *listener) :
|
||||||
|
m_active(-1),
|
||||||
|
m_index(0),
|
||||||
|
m_listener(listener)
|
||||||
|
{
|
||||||
|
for (const Url *url : urls) {
|
||||||
|
add(url, agent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FailoverStrategy::connect()
|
||||||
|
{
|
||||||
|
m_pools[m_index]->connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FailoverStrategy::resume()
|
||||||
|
{
|
||||||
|
if (!isActive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_listener->onJob( m_pools[m_active], m_pools[m_active]->job());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FailoverStrategy::submit(const JobResult &result)
|
||||||
|
{
|
||||||
|
m_pools[m_active]->submit(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FailoverStrategy::onClose(Client *client, int failures)
|
||||||
|
{
|
||||||
|
if (failures == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_active == client->id()) {
|
||||||
|
m_active = -1;
|
||||||
|
m_listener->onPause(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_index == 0 && failures < Options::i()->retries()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_index == client->id() && (m_pools.size() - m_index) > 1) {
|
||||||
|
m_pools[++m_index]->connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FailoverStrategy::onJobReceived(Client *client, const Job &job)
|
||||||
|
{
|
||||||
|
if (m_active == client->id()) {
|
||||||
|
m_listener->onJob(client, job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FailoverStrategy::onLoginSuccess(Client *client)
|
||||||
|
{
|
||||||
|
int active = m_active;
|
||||||
|
|
||||||
|
if (client->id() == 0 || !isActive()) {
|
||||||
|
active = client->id();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < m_pools.size(); ++i) {
|
||||||
|
if (active != static_cast<int>(i)) {
|
||||||
|
m_pools[i]->disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active >= 0 && active != m_active) {
|
||||||
|
m_index = m_active = active;
|
||||||
|
m_listener->onActive(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FailoverStrategy::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error)
|
||||||
|
{
|
||||||
|
m_listener->onResultAccepted(client, diff, ms, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FailoverStrategy::add(const Url *url, const char *agent)
|
||||||
|
{
|
||||||
|
Client *client = new Client(m_pools.size(), agent, this);
|
||||||
|
client->setUrl(url);
|
||||||
|
client->setRetryPause(Options::i()->retryPause() * 1000);
|
||||||
|
|
||||||
|
m_pools.push_back(client);
|
||||||
|
}
|
||||||
67
src/net/strategies/FailoverStrategy.h
Normal file
67
src/net/strategies/FailoverStrategy.h
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/* 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 __FAILOVERSTRATEGY_H__
|
||||||
|
#define __FAILOVERSTRATEGY_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
#include "interfaces/IClientListener.h"
|
||||||
|
#include "interfaces/IStrategy.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
class IStrategyListener;
|
||||||
|
class Url;
|
||||||
|
|
||||||
|
|
||||||
|
class FailoverStrategy : public IStrategy, public IClientListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FailoverStrategy(const std::vector<Url*> &urls, const char *agent, IStrategyListener *listener);
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline bool isActive() const override { return m_active >= 0; }
|
||||||
|
|
||||||
|
void connect() override;
|
||||||
|
void resume() override;
|
||||||
|
void submit(const JobResult &result) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onClose(Client *client, int failures) override;
|
||||||
|
void onJobReceived(Client *client, const Job &job) override;
|
||||||
|
void onLoginSuccess(Client *client) override;
|
||||||
|
void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void add(const Url *url, const char *agent);
|
||||||
|
|
||||||
|
int m_active;
|
||||||
|
int m_index;
|
||||||
|
IStrategyListener *m_listener;
|
||||||
|
std::vector<Client*> m_pools;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __FAILOVERSTRATEGY_H__ */
|
||||||
90
src/net/strategies/SinglePoolStrategy.cpp
Normal file
90
src/net/strategies/SinglePoolStrategy.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "interfaces/IStrategyListener.h"
|
||||||
|
#include "net/Client.h"
|
||||||
|
#include "net/strategies/SinglePoolStrategy.h"
|
||||||
|
#include "Options.h"
|
||||||
|
|
||||||
|
|
||||||
|
SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener) :
|
||||||
|
m_active(false),
|
||||||
|
m_listener(listener)
|
||||||
|
{
|
||||||
|
m_client = new Client(0, agent, this);
|
||||||
|
m_client->setUrl(url);
|
||||||
|
m_client->setRetryPause(Options::i()->retryPause() * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SinglePoolStrategy::connect()
|
||||||
|
{
|
||||||
|
m_client->connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SinglePoolStrategy::resume()
|
||||||
|
{
|
||||||
|
if (!isActive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_listener->onJob(m_client, m_client->job());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SinglePoolStrategy::submit(const JobResult &result)
|
||||||
|
{
|
||||||
|
m_client->submit(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SinglePoolStrategy::onClose(Client *client, int failures)
|
||||||
|
{
|
||||||
|
if (!isActive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_active = false;
|
||||||
|
m_listener->onPause(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SinglePoolStrategy::onJobReceived(Client *client, const Job &job)
|
||||||
|
{
|
||||||
|
m_listener->onJob(client, job);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SinglePoolStrategy::onLoginSuccess(Client *client)
|
||||||
|
{
|
||||||
|
m_active = true;
|
||||||
|
m_listener->onActive(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SinglePoolStrategy::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error)
|
||||||
|
{
|
||||||
|
m_listener->onResultAccepted(client, diff, ms, error);
|
||||||
|
}
|
||||||
61
src/net/strategies/SinglePoolStrategy.h
Normal file
61
src/net/strategies/SinglePoolStrategy.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* 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 __SINGLEPOOLSTRATEGY_H__
|
||||||
|
#define __SINGLEPOOLSTRATEGY_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "interfaces/IClientListener.h"
|
||||||
|
#include "interfaces/IStrategy.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
class IStrategyListener;
|
||||||
|
class Url;
|
||||||
|
|
||||||
|
|
||||||
|
class SinglePoolStrategy : public IStrategy, public IClientListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener);
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline bool isActive() const override { return m_active; }
|
||||||
|
|
||||||
|
void connect() override;
|
||||||
|
void resume() override;
|
||||||
|
void submit(const JobResult &result) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onClose(Client *client, int failures) override;
|
||||||
|
void onJobReceived(Client *client, const Job &job) override;
|
||||||
|
void onLoginSuccess(Client *client) override;
|
||||||
|
void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_active;
|
||||||
|
Client *m_client;
|
||||||
|
IStrategyListener *m_listener;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __SINGLEPOOLSTRATEGY_H__ */
|
||||||
@@ -27,12 +27,12 @@
|
|||||||
#define APP_ID "xmrig"
|
#define APP_ID "xmrig"
|
||||||
#define APP_NAME "XMRig"
|
#define APP_NAME "XMRig"
|
||||||
#define APP_DESC "Monero (XMR) CPU miner"
|
#define APP_DESC "Monero (XMR) CPU miner"
|
||||||
#define APP_VERSION "1.0.1"
|
#define APP_VERSION "2.0.1"
|
||||||
#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-2017 xmrig.com"
|
#define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com"
|
||||||
|
|
||||||
#define APP_VER_MAJOR 1
|
#define APP_VER_MAJOR 2
|
||||||
#define APP_VER_MINOR 0
|
#define APP_VER_MINOR 0
|
||||||
#define APP_VER_BUILD 1
|
#define APP_VER_BUILD 1
|
||||||
#define APP_VER_REV 0
|
#define APP_VER_REV 0
|
||||||
|
|||||||
@@ -30,11 +30,33 @@
|
|||||||
#include "workers/Workers.h"
|
#include "workers/Workers.h"
|
||||||
|
|
||||||
|
|
||||||
DoubleWorker::DoubleWorker(Handle *handle)
|
class DoubleWorker::State
|
||||||
: Worker(handle),
|
|
||||||
m_nonce1(0),
|
|
||||||
m_nonce2(0)
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
inline State() :
|
||||||
|
nonce1(0),
|
||||||
|
nonce2(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Job job;
|
||||||
|
uint32_t nonce1;
|
||||||
|
uint32_t nonce2;
|
||||||
|
uint8_t blob[84 * 2];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DoubleWorker::DoubleWorker(Handle *handle)
|
||||||
|
: Worker(handle)
|
||||||
|
{
|
||||||
|
m_state = new State();
|
||||||
|
m_pausedState = new State();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DoubleWorker::~DoubleWorker()
|
||||||
|
{
|
||||||
|
delete m_state;
|
||||||
|
delete m_pausedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -56,17 +78,17 @@ void DoubleWorker::start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_count += 2;
|
m_count += 2;
|
||||||
*Job::nonce(m_blob) = ++m_nonce1;
|
*Job::nonce(m_state->blob) = ++m_state->nonce1;
|
||||||
*Job::nonce(m_blob + m_job.size()) = ++m_nonce2;
|
*Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2;
|
||||||
|
|
||||||
CryptoNight::hash(m_blob, m_job.size(), m_hash, m_ctx);
|
CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx);
|
||||||
|
|
||||||
if (*reinterpret_cast<uint64_t*>(m_hash + 24) < m_job.target()) {
|
if (*reinterpret_cast<uint64_t*>(m_hash + 24) < m_state->job.target()) {
|
||||||
Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce1, m_hash));
|
Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*reinterpret_cast<uint64_t*>(m_hash + 32 + 24) < m_job.target()) {
|
if (*reinterpret_cast<uint64_t*>(m_hash + 32 + 24) < m_state->job.target()) {
|
||||||
Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce2, m_hash + 32));
|
Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce2, m_hash + 32, m_state->job.diff()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
@@ -77,20 +99,46 @@ void DoubleWorker::start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DoubleWorker::resume(const Job &job)
|
||||||
|
{
|
||||||
|
if (m_state->job.poolId() == -1 && job.poolId() >= 0 && memcmp(job.id(), m_pausedState->job.id(), 64) == 0) {
|
||||||
|
*m_state = *m_pausedState;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DoubleWorker::consumeJob()
|
void DoubleWorker::consumeJob()
|
||||||
{
|
{
|
||||||
m_job = Workers::job();
|
Job job = Workers::job();
|
||||||
m_sequence = Workers::sequence();
|
m_sequence = Workers::sequence();
|
||||||
|
|
||||||
memcpy(m_blob, m_job.blob(), m_job.size());
|
save(job);
|
||||||
memcpy(m_blob + m_job.size(), m_job.blob(), m_job.size());
|
|
||||||
|
|
||||||
if (m_nicehash) {
|
if (resume(job)) {
|
||||||
m_nonce1 = (*Job::nonce(m_blob) & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id);
|
return;
|
||||||
m_nonce2 = (*Job::nonce(m_blob + m_job.size()) & 0xff000000U) + (0xffffffU / (m_threads * 2) * (m_id + m_threads));
|
}
|
||||||
|
|
||||||
|
m_state->job = std::move(job);
|
||||||
|
memcpy(m_state->blob, m_state->job.blob(), m_state->job.size());
|
||||||
|
memcpy(m_state->blob + m_state->job.size(), m_state->job.blob(), m_state->job.size());
|
||||||
|
|
||||||
|
if (m_state->job.isNicehash()) {
|
||||||
|
m_state->nonce1 = (*Job::nonce(m_state->blob) & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id);
|
||||||
|
m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / (m_threads * 2) * (m_id + m_threads));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_nonce1 = 0xffffffffU / (m_threads * 2) * m_id;
|
m_state->nonce1 = 0xffffffffU / (m_threads * 2) * m_id;
|
||||||
m_nonce2 = 0xffffffffU / (m_threads * 2) * (m_id + m_threads);
|
m_state->nonce2 = 0xffffffffU / (m_threads * 2) * (m_id + m_threads);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DoubleWorker::save(const Job &job)
|
||||||
|
{
|
||||||
|
if (job.poolId() == -1 && m_state->job.poolId() >= 0) {
|
||||||
|
*m_pausedState = *m_state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,17 +38,20 @@ class DoubleWorker : public Worker
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DoubleWorker(Handle *handle);
|
DoubleWorker(Handle *handle);
|
||||||
|
~DoubleWorker();
|
||||||
|
|
||||||
void start() override;
|
void start() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool resume(const Job &job);
|
||||||
void consumeJob();
|
void consumeJob();
|
||||||
|
void save(const Job &job);
|
||||||
|
|
||||||
|
class State;
|
||||||
|
|
||||||
Job m_job;
|
|
||||||
uint32_t m_nonce1;
|
|
||||||
uint32_t m_nonce2;
|
|
||||||
uint8_t m_hash[64];
|
uint8_t m_hash[64];
|
||||||
uint8_t m_blob[84 * 2];
|
State *m_state;
|
||||||
|
State *m_pausedState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,7 @@
|
|||||||
#include "workers/Handle.h"
|
#include "workers/Handle.h"
|
||||||
|
|
||||||
|
|
||||||
Handle::Handle(int threadId, int threads, int64_t affinity, bool nicehash) :
|
Handle::Handle(int threadId, int threads, int64_t affinity) :
|
||||||
m_nicehash(nicehash),
|
|
||||||
m_threadId(threadId),
|
m_threadId(threadId),
|
||||||
m_threads(threads),
|
m_threads(threads),
|
||||||
m_affinity(affinity),
|
m_affinity(affinity),
|
||||||
|
|||||||
@@ -35,10 +35,9 @@ class IWorker;
|
|||||||
class Handle
|
class Handle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Handle(int threadId, int threads, int64_t affinity, bool nicehash);
|
Handle(int threadId, int threads, int64_t affinity);
|
||||||
void start(void (*callback) (void *));
|
void start(void (*callback) (void *));
|
||||||
|
|
||||||
inline bool nicehash() const { return m_nicehash; }
|
|
||||||
inline int threadId() const { return m_threadId; }
|
inline int threadId() const { return m_threadId; }
|
||||||
inline int threads() const { return m_threads; }
|
inline int threads() const { return m_threads; }
|
||||||
inline int64_t affinity() const { return m_affinity; }
|
inline int64_t affinity() const { return m_affinity; }
|
||||||
@@ -46,7 +45,6 @@ public:
|
|||||||
inline void setWorker(IWorker *worker) { m_worker = worker; }
|
inline void setWorker(IWorker *worker) { m_worker = worker; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_nicehash;
|
|
||||||
int m_threadId;
|
int m_threadId;
|
||||||
int m_threads;
|
int m_threads;
|
||||||
int64_t m_affinity;
|
int64_t m_affinity;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
#include "Console.h"
|
#include "log/Log.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "workers/Hashrate.h"
|
#include "workers/Hashrate.h"
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ void Hashrate::print()
|
|||||||
char num3[8];
|
char num3[8];
|
||||||
char num4[8];
|
char num4[8];
|
||||||
|
|
||||||
LOG_INFO(Options::i()->colors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m highest: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s highest: %s H/s",
|
LOG_INFO(Options::i()->colors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s max: %s H/s",
|
||||||
format(calc(2500), num1, sizeof(num1)),
|
format(calc(2500), num1, sizeof(num1)),
|
||||||
format(calc(60000), num2, sizeof(num2)),
|
format(calc(60000), num2, sizeof(num2)),
|
||||||
format(calc(900000), num3, sizeof(num3)),
|
format(calc(900000), num3, sizeof(num3)),
|
||||||
|
|||||||
@@ -68,19 +68,45 @@ void SingleWorker::start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SingleWorker::resume(const Job &job)
|
||||||
|
{
|
||||||
|
if (m_job.poolId() == -1 && job.poolId() >= 0 && memcmp(job.id(), m_paused.id(), 64) == 0) {
|
||||||
|
m_job = m_paused;
|
||||||
|
m_result = m_job;
|
||||||
|
m_result.nonce = *m_job.nonce();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SingleWorker::consumeJob()
|
void SingleWorker::consumeJob()
|
||||||
{
|
{
|
||||||
m_job = Workers::job();
|
Job job = Workers::job();
|
||||||
m_sequence = Workers::sequence();
|
m_sequence = Workers::sequence();
|
||||||
|
|
||||||
memcpy(m_result.jobId, m_job.id(), sizeof(m_result.jobId));
|
save(job);
|
||||||
m_result.poolId = m_job.poolId();
|
|
||||||
|
|
||||||
if (m_nicehash) {
|
if (resume(job)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_job = std::move(job);
|
||||||
|
m_result = m_job;
|
||||||
|
|
||||||
|
if (m_job.isNicehash()) {
|
||||||
m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id);
|
m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_result.nonce = 0xffffffffU / m_threads * m_id;
|
m_result.nonce = 0xffffffffU / m_threads * m_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SingleWorker::save(const Job &job)
|
||||||
|
{
|
||||||
|
if (job.poolId() == -1 && m_job.poolId() >= 0) {
|
||||||
|
m_paused = m_job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,9 +41,12 @@ public:
|
|||||||
void start() override;
|
void start() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool resume(const Job &job);
|
||||||
void consumeJob();
|
void consumeJob();
|
||||||
|
void save(const Job &job);
|
||||||
|
|
||||||
Job m_job;
|
Job m_job;
|
||||||
|
Job m_paused;
|
||||||
JobResult m_result;
|
JobResult m_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
#include "Console.h"
|
|
||||||
|
|
||||||
#include "Cpu.h"
|
#include "Cpu.h"
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
@@ -32,7 +31,6 @@
|
|||||||
|
|
||||||
|
|
||||||
Worker::Worker(Handle *handle) :
|
Worker::Worker(Handle *handle) :
|
||||||
m_nicehash(handle->nicehash()),
|
|
||||||
m_id(handle->threadId()),
|
m_id(handle->threadId()),
|
||||||
m_threads(handle->threads()),
|
m_threads(handle->threads()),
|
||||||
m_hashCount(0),
|
m_hashCount(0),
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
void storeStats();
|
void storeStats();
|
||||||
|
|
||||||
bool m_nicehash;
|
|
||||||
cryptonight_ctx *m_ctx;
|
cryptonight_ctx *m_ctx;
|
||||||
int m_id;
|
int m_id;
|
||||||
int m_threads;
|
int m_threads;
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
||||||
#include "Console.h"
|
|
||||||
#include "interfaces/IJobResultListener.h"
|
#include "interfaces/IJobResultListener.h"
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
@@ -70,7 +69,7 @@ void Workers::setJob(const Job &job)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Workers::start(int64_t affinity, bool nicehash)
|
void Workers::start(int64_t affinity)
|
||||||
{
|
{
|
||||||
const int threads = Mem::threads();
|
const int threads = Mem::threads();
|
||||||
m_hashrate = new Hashrate(threads);
|
m_hashrate = new Hashrate(threads);
|
||||||
@@ -86,7 +85,7 @@ void Workers::start(int64_t affinity, bool nicehash)
|
|||||||
uv_timer_start(&m_timer, Workers::onTick, 500, 500);
|
uv_timer_start(&m_timer, Workers::onTick, 500, 500);
|
||||||
|
|
||||||
for (int i = 0; i < threads; ++i) {
|
for (int i = 0; i < threads; ++i) {
|
||||||
Handle *handle = new Handle(i, threads, affinity, nicehash);
|
Handle *handle = new Handle(i, threads, affinity);
|
||||||
m_workers.push_back(handle);
|
m_workers.push_back(handle);
|
||||||
handle->start(Workers::onReady);
|
handle->start(Workers::onReady);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,13 +44,13 @@ class Workers
|
|||||||
public:
|
public:
|
||||||
static Job job();
|
static Job job();
|
||||||
static void setJob(const Job &job);
|
static void setJob(const Job &job);
|
||||||
static void start(int64_t affinity, bool nicehash);
|
static void start(int64_t affinity);
|
||||||
static void submit(const JobResult &result);
|
static void submit(const JobResult &result);
|
||||||
|
|
||||||
static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; }
|
static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; }
|
||||||
static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; }
|
static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; }
|
||||||
static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); }
|
static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); }
|
||||||
static inline void pause() { m_paused = 1; }
|
static inline void pause() { m_paused = 1; m_sequence++; }
|
||||||
static inline void setListener(IJobResultListener *listener) { m_listener = listener; }
|
static inline void setListener(IJobResultListener *listener) { m_listener = listener; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user