mirror of
https://github.com/xmrig/xmrig.git
synced 2025-01-11 05:14:40 +00:00
Merge branch 'feature-httpd' into dev
This commit is contained in:
commit
3d10636a8f
33 changed files with 1070 additions and 78 deletions
|
@ -3,13 +3,16 @@ project(xmrig)
|
||||||
|
|
||||||
option(WITH_LIBCPUID "Use Libcpuid" ON)
|
option(WITH_LIBCPUID "Use Libcpuid" ON)
|
||||||
option(WITH_AEON "CryptoNight-Lite support" ON)
|
option(WITH_AEON "CryptoNight-Lite support" ON)
|
||||||
|
option(WITH_HTTPD "HTTP REST API" ON)
|
||||||
|
|
||||||
include (CheckIncludeFile)
|
include (CheckIncludeFile)
|
||||||
|
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
src/3rdparty/align.h
|
src/3rdparty/align.h
|
||||||
|
src/api/Api.h
|
||||||
|
src/api/ApiState.h
|
||||||
|
src/api/NetworkState.h
|
||||||
src/App.h
|
src/App.h
|
||||||
src/Console.h
|
src/Console.h
|
||||||
src/Cpu.h
|
src/Cpu.h
|
||||||
|
@ -60,6 +63,9 @@ set(HEADERS_CRYPTO
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
|
src/api/Api.cpp
|
||||||
|
src/api/ApiState.cpp
|
||||||
|
src/api/NetworkState.cpp
|
||||||
src/App.cpp
|
src/App.cpp
|
||||||
src/Console.cpp
|
src/Console.cpp
|
||||||
src/log/ConsoleLog.cpp
|
src/log/ConsoleLog.cpp
|
||||||
|
@ -72,6 +78,7 @@ set(SOURCES
|
||||||
src/net/strategies/DonateStrategy.cpp
|
src/net/strategies/DonateStrategy.cpp
|
||||||
src/net/strategies/FailoverStrategy.cpp
|
src/net/strategies/FailoverStrategy.cpp
|
||||||
src/net/strategies/SinglePoolStrategy.cpp
|
src/net/strategies/SinglePoolStrategy.cpp
|
||||||
|
src/net/SubmitResult.cpp
|
||||||
src/net/Url.cpp
|
src/net/Url.cpp
|
||||||
src/Options.cpp
|
src/Options.cpp
|
||||||
src/Platform.cpp
|
src/Platform.cpp
|
||||||
|
@ -191,6 +198,15 @@ if (HAVE_SYSLOG_H)
|
||||||
set(SOURCES_SYSLOG src/log/SysLog.h src/log/SysLog.cpp)
|
set(SOURCES_SYSLOG src/log/SysLog.h src/log/SysLog.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
find_package(MHD REQUIRED)
|
||||||
|
if (WITH_HTTPD AND MHD_FOUND)
|
||||||
|
include_directories(${MHD_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
set(HTTPD_SOURCES src/api/Httpd.h src/api/Httpd.cpp)
|
||||||
|
else()
|
||||||
|
add_definitions(/DXMRIG_NO_HTTPD)
|
||||||
|
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)
|
||||||
|
@ -198,5 +214,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} ${SOURCES_SYSLOG})
|
add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES})
|
||||||
target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB})
|
target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
|
||||||
|
|
39
cmake/FindMHD.cmake
Normal file
39
cmake/FindMHD.cmake
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# - Try to find MHD
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# MHD_FOUND - system has MHD
|
||||||
|
# MHD_INCLUDE_DIRS - the MHD include directory
|
||||||
|
# MHD_LIBRARY - Link these to use MHD
|
||||||
|
|
||||||
|
find_path(
|
||||||
|
MHD_INCLUDE_DIR
|
||||||
|
NAMES microhttpd.h
|
||||||
|
DOC "microhttpd include dir"
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(
|
||||||
|
MHD_LIBRARY
|
||||||
|
NAMES microhttpd microhttpd-10 libmicrohttpd libmicrohttpd-dll
|
||||||
|
DOC "microhttpd library"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR})
|
||||||
|
set(MHD_LIBRARIES ${MHD_LIBRARY})
|
||||||
|
|
||||||
|
# debug library on windows
|
||||||
|
# same naming convention as in qt (appending debug library with d)
|
||||||
|
# boost is using the same "hack" as us with "optimized" and "debug"
|
||||||
|
# official MHD project actually uses _d suffix
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL MSVC)
|
||||||
|
find_library(
|
||||||
|
MHD_LIBRARY_DEBUG
|
||||||
|
NAMES microhttpd_d microhttpd-10_d libmicrohttpd_d libmicrohttpd-dll_d
|
||||||
|
DOC "mhd debug library"
|
||||||
|
)
|
||||||
|
set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(mhd DEFAULT_MSG MHD_INCLUDE_DIR MHD_LIBRARY)
|
||||||
|
mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY)
|
||||||
|
|
22
src/App.cpp
22
src/App.cpp
|
@ -26,6 +26,7 @@
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "api/Api.h"
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "Cpu.h"
|
#include "Cpu.h"
|
||||||
|
@ -46,6 +47,10 @@
|
||||||
# include "log/SysLog.h"
|
# include "log/SysLog.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef XMRIG_NO_HTTPD
|
||||||
|
# include "api/Httpd.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
App *App::m_self = nullptr;
|
App *App::m_self = nullptr;
|
||||||
|
|
||||||
|
@ -53,6 +58,7 @@ App *App::m_self = nullptr;
|
||||||
|
|
||||||
App::App(int argc, char **argv) :
|
App::App(int argc, char **argv) :
|
||||||
m_console(nullptr),
|
m_console(nullptr),
|
||||||
|
m_httpd(nullptr),
|
||||||
m_network(nullptr),
|
m_network(nullptr),
|
||||||
m_options(nullptr)
|
m_options(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -92,6 +98,12 @@ App::App(int argc, char **argv) :
|
||||||
|
|
||||||
App::~App()
|
App::~App()
|
||||||
{
|
{
|
||||||
|
uv_tty_reset_mode();
|
||||||
|
|
||||||
|
# ifndef XMRIG_NO_HTTPD
|
||||||
|
delete m_httpd;
|
||||||
|
# endif
|
||||||
|
|
||||||
delete m_console;
|
delete m_console;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,13 +128,21 @@ int App::exec()
|
||||||
Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash(), m_options->hugePages());
|
Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash(), m_options->hugePages());
|
||||||
Summary::print();
|
Summary::print();
|
||||||
|
|
||||||
|
# ifndef XMRIG_NO_API
|
||||||
|
Api::start();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef XMRIG_NO_HTTPD
|
||||||
|
m_httpd = new Httpd(m_options->apiPort(), m_options->apiToken());
|
||||||
|
m_httpd->start();
|
||||||
|
# endif
|
||||||
|
|
||||||
Workers::start(m_options->affinity(), m_options->priority());
|
Workers::start(m_options->affinity(), m_options->priority());
|
||||||
|
|
||||||
m_network->connect();
|
m_network->connect();
|
||||||
|
|
||||||
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||||
uv_loop_close(uv_default_loop());
|
uv_loop_close(uv_default_loop());
|
||||||
uv_tty_reset_mode();
|
|
||||||
|
|
||||||
delete m_network;
|
delete m_network;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
|
|
||||||
class Console;
|
class Console;
|
||||||
|
class Httpd;
|
||||||
class Network;
|
class Network;
|
||||||
class Options;
|
class Options;
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ private:
|
||||||
static App *m_self;
|
static App *m_self;
|
||||||
|
|
||||||
Console *m_console;
|
Console *m_console;
|
||||||
|
Httpd *m_httpd;
|
||||||
Network *m_network;
|
Network *m_network;
|
||||||
Options *m_options;
|
Options *m_options;
|
||||||
uv_signal_t m_signal;
|
uv_signal_t m_signal;
|
||||||
|
|
|
@ -116,6 +116,9 @@ static struct option const options[] = {
|
||||||
{ "user-agent", 1, nullptr, 1008 },
|
{ "user-agent", 1, nullptr, 1008 },
|
||||||
{ "userpass", 1, nullptr, 'O' },
|
{ "userpass", 1, nullptr, 'O' },
|
||||||
{ "version", 0, nullptr, 'V' },
|
{ "version", 0, nullptr, 'V' },
|
||||||
|
{ "api-port", 1, nullptr, 3000 },
|
||||||
|
{ "api-access-token", 1, nullptr, 3001 },
|
||||||
|
{ "api-worker-id", 1, nullptr, 3002 },
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -153,6 +156,14 @@ static struct option const pool_options[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct option const api_options[] = {
|
||||||
|
{ "port", 1, nullptr, 3000 },
|
||||||
|
{ "access-token", 1, nullptr, 3001 },
|
||||||
|
{ "worker-id", 1, nullptr, 3002 },
|
||||||
|
{ 0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static const char *algo_names[] = {
|
static const char *algo_names[] = {
|
||||||
"cryptonight",
|
"cryptonight",
|
||||||
# ifndef XMRIG_NO_AEON
|
# ifndef XMRIG_NO_AEON
|
||||||
|
@ -188,10 +199,13 @@ Options::Options(int argc, char **argv) :
|
||||||
m_ready(false),
|
m_ready(false),
|
||||||
m_safe(false),
|
m_safe(false),
|
||||||
m_syslog(false),
|
m_syslog(false),
|
||||||
|
m_apiToken(nullptr),
|
||||||
|
m_apiWorkerId(nullptr),
|
||||||
m_logFile(nullptr),
|
m_logFile(nullptr),
|
||||||
m_userAgent(nullptr),
|
m_userAgent(nullptr),
|
||||||
m_algo(0),
|
m_algo(0),
|
||||||
m_algoVariant(0),
|
m_algoVariant(0),
|
||||||
|
m_apiPort(0),
|
||||||
m_donateLevel(kDonateLevel),
|
m_donateLevel(kDonateLevel),
|
||||||
m_maxCpuUsage(75),
|
m_maxCpuUsage(75),
|
||||||
m_printTime(60),
|
m_printTime(60),
|
||||||
|
@ -302,6 +316,16 @@ bool Options::parseArg(int key, const char *arg)
|
||||||
m_colors = false;
|
m_colors = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 3001: /* --access-token */
|
||||||
|
free(m_apiToken);
|
||||||
|
m_apiToken = strdup(arg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3002: /* --worker-id */
|
||||||
|
free(m_apiWorkerId);
|
||||||
|
m_apiWorkerId = strdup(arg);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'r': /* --retries */
|
case 'r': /* --retries */
|
||||||
case 'R': /* --retry-pause */
|
case 'R': /* --retry-pause */
|
||||||
case 't': /* --threads */
|
case 't': /* --threads */
|
||||||
|
@ -310,6 +334,7 @@ bool Options::parseArg(int key, const char *arg)
|
||||||
case 1004: /* --max-cpu-usage */
|
case 1004: /* --max-cpu-usage */
|
||||||
case 1007: /* --print-time */
|
case 1007: /* --print-time */
|
||||||
case 1021: /* --cpu-priority */
|
case 1021: /* --cpu-priority */
|
||||||
|
case 3000: /* --api-port */
|
||||||
return parseArg(key, strtol(arg, nullptr, 10));
|
return parseArg(key, strtol(arg, nullptr, 10));
|
||||||
|
|
||||||
case 'B': /* --background */
|
case 'B': /* --background */
|
||||||
|
@ -432,6 +457,12 @@ bool Options::parseArg(int key, uint64_t arg)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 3000: /* --api-port */
|
||||||
|
if (arg <= 65536) {
|
||||||
|
m_apiPort = (int) arg;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -548,6 +579,13 @@ void Options::parseConfig(const char *fileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_t *api = json_object_get(config, "api");
|
||||||
|
if (json_is_object(api)) {
|
||||||
|
for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) {
|
||||||
|
parseJSON(&api_options[i], api);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
json_decref(config);
|
json_decref(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,11 +59,14 @@ public:
|
||||||
inline bool doubleHash() const { return m_doubleHash; }
|
inline bool doubleHash() const { return m_doubleHash; }
|
||||||
inline bool hugePages() const { return m_hugePages; }
|
inline bool hugePages() const { return m_hugePages; }
|
||||||
inline bool syslog() const { return m_syslog; }
|
inline bool syslog() const { return m_syslog; }
|
||||||
|
inline const char *apiToken() const { return m_apiToken; }
|
||||||
|
inline const char *apiWorkerId() const { return m_apiWorkerId; }
|
||||||
inline const char *logFile() const { return m_logFile; }
|
inline const char *logFile() const { return m_logFile; }
|
||||||
inline const char *userAgent() const { return m_userAgent; }
|
inline const char *userAgent() const { return m_userAgent; }
|
||||||
inline const std::vector<Url*> &pools() const { return m_pools; }
|
inline const std::vector<Url*> &pools() const { return m_pools; }
|
||||||
inline int algo() const { return m_algo; }
|
inline int algo() const { return m_algo; }
|
||||||
inline int algoVariant() const { return m_algoVariant; }
|
inline int algoVariant() const { return m_algoVariant; }
|
||||||
|
inline int apiPort() const { return m_apiPort; }
|
||||||
inline int donateLevel() const { return m_donateLevel; }
|
inline int donateLevel() const { return m_donateLevel; }
|
||||||
inline int printTime() const { return m_printTime; }
|
inline int printTime() const { return m_printTime; }
|
||||||
inline int priority() const { return m_priority; }
|
inline int priority() const { return m_priority; }
|
||||||
|
@ -107,10 +110,13 @@ private:
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
bool m_safe;
|
bool m_safe;
|
||||||
bool m_syslog;
|
bool m_syslog;
|
||||||
|
char *m_apiToken;
|
||||||
|
char *m_apiWorkerId;
|
||||||
char *m_logFile;
|
char *m_logFile;
|
||||||
char *m_userAgent;
|
char *m_userAgent;
|
||||||
int m_algo;
|
int m_algo;
|
||||||
int m_algoVariant;
|
int m_algoVariant;
|
||||||
|
int m_apiPort;
|
||||||
int m_donateLevel;
|
int m_donateLevel;
|
||||||
int m_maxCpuUsage;
|
int m_maxCpuUsage;
|
||||||
int m_printTime;
|
int m_printTime;
|
||||||
|
|
93
src/api/Api.cpp
Normal file
93
src/api/Api.cpp
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/* 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 "api/Api.h"
|
||||||
|
#include "api/ApiState.h"
|
||||||
|
|
||||||
|
|
||||||
|
ApiState *Api::m_state = nullptr;
|
||||||
|
char Api::m_buf[4096];
|
||||||
|
uv_mutex_t Api::m_mutex;
|
||||||
|
|
||||||
|
|
||||||
|
bool Api::start()
|
||||||
|
{
|
||||||
|
uv_mutex_init(&m_mutex);
|
||||||
|
m_state = new ApiState();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Api::release()
|
||||||
|
{
|
||||||
|
delete m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *Api::get(const char *url, size_t *size, int *status)
|
||||||
|
{
|
||||||
|
if (!m_state) {
|
||||||
|
*size = 0;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_mutex_lock(&m_mutex);
|
||||||
|
|
||||||
|
const char *buf = m_state->get(url, size);
|
||||||
|
if (*size) {
|
||||||
|
memcpy(m_buf, buf, *size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*status = 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_mutex_unlock(&m_mutex);
|
||||||
|
|
||||||
|
return m_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Api::tick(const Hashrate *hashrate)
|
||||||
|
{
|
||||||
|
if (!m_state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_mutex_lock(&m_mutex);
|
||||||
|
m_state->tick(hashrate);
|
||||||
|
uv_mutex_unlock(&m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Api::tick(const NetworkState &network)
|
||||||
|
{
|
||||||
|
if (!m_state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_mutex_lock(&m_mutex);
|
||||||
|
m_state->tick(network);
|
||||||
|
uv_mutex_unlock(&m_mutex);
|
||||||
|
}
|
52
src/api/Api.h
Normal file
52
src/api/Api.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/* 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 __API_H__
|
||||||
|
#define __API_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
class ApiState;
|
||||||
|
class Hashrate;
|
||||||
|
class NetworkState;
|
||||||
|
|
||||||
|
|
||||||
|
class Api
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool start();
|
||||||
|
static void release();
|
||||||
|
|
||||||
|
static const char *get(const char *url, size_t *size, int *status);
|
||||||
|
static void tick(const Hashrate *hashrate);
|
||||||
|
static void tick(const NetworkState &results);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ApiState *m_state;
|
||||||
|
static char m_buf[4096];
|
||||||
|
static uv_mutex_t m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __API_H__ */
|
242
src/api/ApiState.cpp
Normal file
242
src/api/ApiState.cpp
Normal file
|
@ -0,0 +1,242 @@
|
||||||
|
/* 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 <cmath>
|
||||||
|
#include <string.h>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
# include "winsock2.h"
|
||||||
|
#else
|
||||||
|
# include "unistd.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "api/ApiState.h"
|
||||||
|
#include "Cpu.h"
|
||||||
|
#include "Mem.h"
|
||||||
|
#include "net/Job.h"
|
||||||
|
#include "Options.h"
|
||||||
|
#include "Platform.h"
|
||||||
|
#include "version.h"
|
||||||
|
#include "workers/Hashrate.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include "crypto/c_keccak.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline double normalize(double d)
|
||||||
|
{
|
||||||
|
if (!std::isnormal(d)) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::floor(d * 10.0) / 10.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ApiState::ApiState()
|
||||||
|
{
|
||||||
|
m_threads = Options::i()->threads();
|
||||||
|
m_hashrate = new double[m_threads * 3]();
|
||||||
|
|
||||||
|
memset(m_totalHashrate, 0, sizeof(m_totalHashrate));
|
||||||
|
memset(m_workerId, 0, sizeof(m_workerId));
|
||||||
|
|
||||||
|
if (Options::i()->apiWorkerId()) {
|
||||||
|
strncpy(m_workerId, Options::i()->apiWorkerId(), sizeof(m_workerId) - 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gethostname(m_workerId, sizeof(m_workerId) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
genId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ApiState::~ApiState()
|
||||||
|
{
|
||||||
|
delete [] m_hashrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *ApiState::get(const char *url, size_t *size) const
|
||||||
|
{
|
||||||
|
json_t *reply = json_object();
|
||||||
|
|
||||||
|
getIdentify(reply);
|
||||||
|
getMiner(reply);
|
||||||
|
getHashrate(reply);
|
||||||
|
getResults(reply);
|
||||||
|
getConnection(reply);
|
||||||
|
|
||||||
|
return finalize(reply, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ApiState::tick(const Hashrate *hashrate)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_threads; ++i) {
|
||||||
|
m_hashrate[i * 3] = hashrate->calc((size_t) i, Hashrate::ShortInterval);
|
||||||
|
m_hashrate[i * 3 + 1] = hashrate->calc((size_t) i, Hashrate::MediumInterval);
|
||||||
|
m_hashrate[i * 3 + 2] = hashrate->calc((size_t) i, Hashrate::LargeInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_totalHashrate[0] = hashrate->calc(Hashrate::ShortInterval);
|
||||||
|
m_totalHashrate[1] = hashrate->calc(Hashrate::MediumInterval);
|
||||||
|
m_totalHashrate[2] = hashrate->calc(Hashrate::LargeInterval);
|
||||||
|
m_highestHashrate = hashrate->highest();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ApiState::tick(const NetworkState &network)
|
||||||
|
{
|
||||||
|
m_network = network;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *ApiState::finalize(json_t *reply, size_t *size) const
|
||||||
|
{
|
||||||
|
*size = json_dumpb(reply, m_buf, sizeof(m_buf) - 1, JSON_INDENT(4) | JSON_REAL_PRECISION(15));
|
||||||
|
|
||||||
|
json_decref(reply);
|
||||||
|
return m_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ApiState::genId()
|
||||||
|
{
|
||||||
|
memset(m_id, 0, sizeof(m_id));
|
||||||
|
|
||||||
|
uv_interface_address_t *interfaces;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (uv_interface_addresses(&interfaces, &count) < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
|
||||||
|
uint8_t hash[200];
|
||||||
|
const size_t addrSize = sizeof(interfaces[i].phys_addr);
|
||||||
|
const size_t inSize = strlen(APP_KIND) + addrSize;
|
||||||
|
|
||||||
|
uint8_t *input = new uint8_t[inSize]();
|
||||||
|
memcpy(input, interfaces[i].phys_addr, addrSize);
|
||||||
|
memcpy(input + addrSize, APP_KIND, strlen(APP_KIND));
|
||||||
|
|
||||||
|
keccak(input, static_cast<int>(inSize), hash, sizeof(hash));
|
||||||
|
Job::toHex(hash, 8, m_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_free_interface_addresses(interfaces, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ApiState::getConnection(json_t *reply) const
|
||||||
|
{
|
||||||
|
json_t *connection = json_object();
|
||||||
|
|
||||||
|
json_object_set(reply, "connection", connection);
|
||||||
|
json_object_set(connection, "pool", json_string(m_network.pool));
|
||||||
|
json_object_set(connection, "uptime", json_integer(m_network.connectionTime()));
|
||||||
|
json_object_set(connection, "ping", json_integer(m_network.latency()));
|
||||||
|
json_object_set(connection, "failures", json_integer(m_network.failures));
|
||||||
|
json_object_set(connection, "error_log", json_array());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ApiState::getHashrate(json_t *reply) const
|
||||||
|
{
|
||||||
|
json_t *hashrate = json_object();
|
||||||
|
json_t *threads = json_array();
|
||||||
|
json_t *total = json_array();
|
||||||
|
|
||||||
|
json_object_set(reply, "hashrate", hashrate);
|
||||||
|
json_object_set(hashrate, "total", total);
|
||||||
|
json_object_set(hashrate, "highest", json_real(normalize(m_highestHashrate)));
|
||||||
|
json_object_set(hashrate, "threads", threads);
|
||||||
|
|
||||||
|
for (int i = 0; i < m_threads * 3; i += 3) {
|
||||||
|
json_t *thread = json_array();
|
||||||
|
json_array_append(thread, json_real(normalize(m_hashrate[i])));
|
||||||
|
json_array_append(thread, json_real(normalize(m_hashrate[i + 1])));
|
||||||
|
json_array_append(thread, json_real(normalize(m_hashrate[i + 2])));
|
||||||
|
|
||||||
|
json_array_append(threads, thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
json_array_append(total, json_real(normalize(m_totalHashrate[i])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ApiState::getIdentify(json_t *reply) const
|
||||||
|
{
|
||||||
|
json_object_set(reply, "id", json_string(m_id));
|
||||||
|
json_object_set(reply, "worker_id", json_string(m_workerId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ApiState::getMiner(json_t *reply) const
|
||||||
|
{
|
||||||
|
json_t *cpu = json_object();
|
||||||
|
json_object_set(reply, "version", json_string(APP_VERSION));
|
||||||
|
json_object_set(reply, "kind", json_string(APP_KIND));
|
||||||
|
json_object_set(reply, "ua", json_string(Platform::userAgent()));
|
||||||
|
json_object_set(reply, "cpu", cpu);
|
||||||
|
json_object_set(reply, "algo", json_string(Options::i()->algoName()));
|
||||||
|
json_object_set(reply, "hugepages", json_boolean(Mem::isHugepagesEnabled()));
|
||||||
|
json_object_set(reply, "donate", json_integer(Options::i()->donateLevel()));
|
||||||
|
|
||||||
|
json_object_set(cpu, "brand", json_string(Cpu::brand()));
|
||||||
|
json_object_set(cpu, "aes", json_boolean(Cpu::hasAES()));
|
||||||
|
json_object_set(cpu, "x64", json_boolean(Cpu::isX64()));
|
||||||
|
json_object_set(cpu, "sockets", json_integer(Cpu::sockets()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ApiState::getResults(json_t *reply) const
|
||||||
|
{
|
||||||
|
json_t *results = json_object();
|
||||||
|
json_t *best = json_array();
|
||||||
|
|
||||||
|
json_object_set(reply, "results", results);
|
||||||
|
json_object_set(results, "diff_current", json_integer(m_network.diff));
|
||||||
|
json_object_set(results, "shares_good", json_integer(m_network.accepted));
|
||||||
|
json_object_set(results, "shares_total", json_integer(m_network.accepted + m_network.rejected));
|
||||||
|
json_object_set(results, "avg_time", json_integer(m_network.avgTime()));
|
||||||
|
json_object_set(results, "hashes_total", json_integer(m_network.total));
|
||||||
|
json_object_set(results, "best", best);
|
||||||
|
json_object_set(results, "error_log", json_array());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_network.topDiff.size(); ++i) {
|
||||||
|
json_array_append(best, json_integer(m_network.topDiff[i]));
|
||||||
|
}
|
||||||
|
}
|
64
src/api/ApiState.h
Normal file
64
src/api/ApiState.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/* 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 __APISTATE_H__
|
||||||
|
#define __APISTATE_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "api/NetworkState.h"
|
||||||
|
#include "jansson.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Hashrate;
|
||||||
|
|
||||||
|
|
||||||
|
class ApiState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ApiState();
|
||||||
|
~ApiState();
|
||||||
|
|
||||||
|
const char *get(const char *url, size_t *size) const;
|
||||||
|
void tick(const Hashrate *hashrate);
|
||||||
|
void tick(const NetworkState &results);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char *finalize(json_t *reply, size_t *size) const;
|
||||||
|
void genId();
|
||||||
|
void getConnection(json_t *reply) const;
|
||||||
|
void getHashrate(json_t *reply) const;
|
||||||
|
void getIdentify(json_t *reply) const;
|
||||||
|
void getMiner(json_t *reply) const;
|
||||||
|
void getResults(json_t *reply) const;
|
||||||
|
|
||||||
|
char m_id[17];
|
||||||
|
char m_workerId[128];
|
||||||
|
double *m_hashrate;
|
||||||
|
double m_highestHashrate;
|
||||||
|
double m_totalHashrate[3];
|
||||||
|
int m_threads;
|
||||||
|
mutable char m_buf[4096];
|
||||||
|
NetworkState m_network;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __APISTATE_H__ */
|
121
src/api/Httpd.cpp
Normal file
121
src/api/Httpd.cpp
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/* 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 <microhttpd.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "api/Api.h"
|
||||||
|
#include "api/Httpd.h"
|
||||||
|
#include "log/Log.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const char k500 [] = "{\"error\":\"INTERNAL_SERVER_ERROR\"}";
|
||||||
|
static const size_t k500Size = sizeof(k500) - 1;
|
||||||
|
|
||||||
|
|
||||||
|
Httpd::Httpd(int port, const char *accessToken) :
|
||||||
|
m_accessToken(accessToken),
|
||||||
|
m_port(port),
|
||||||
|
m_daemon(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Httpd::start()
|
||||||
|
{
|
||||||
|
if (!m_port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, 4455, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
|
||||||
|
if (!m_daemon) {
|
||||||
|
LOG_ERR("HTTP Daemon failed to start.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Httpd::auth(const char *header)
|
||||||
|
{
|
||||||
|
if (!m_accessToken) {
|
||||||
|
return MHD_HTTP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_accessToken && !header) {
|
||||||
|
return MHD_HTTP_UNAUTHORIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t size = strlen(header);
|
||||||
|
if (size < 8 || strlen(m_accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) {
|
||||||
|
return MHD_HTTP_FORBIDDEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strncmp(m_accessToken, header + 7, strlen(m_accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Httpd::done(MHD_Connection *connection, int status, MHD_Response *rsp)
|
||||||
|
{
|
||||||
|
if (!rsp) {
|
||||||
|
rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
MHD_add_response_header(rsp, "Content-Type", "application/json");
|
||||||
|
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*");
|
||||||
|
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET");
|
||||||
|
MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization");
|
||||||
|
|
||||||
|
const int ret = MHD_queue_response(connection, status, rsp);
|
||||||
|
MHD_destroy_response(rsp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
|
||||||
|
{
|
||||||
|
if (strcmp(method, "OPTIONS") == 0) {
|
||||||
|
return done(connection, MHD_HTTP_OK, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(method, "GET") != 0) {
|
||||||
|
return MHD_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int status = static_cast<Httpd*>(cls)->auth(MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Authorization"));
|
||||||
|
if (status != MHD_HTTP_OK) {
|
||||||
|
return done(connection, status, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
MHD_Response *rsp = nullptr;
|
||||||
|
size_t size = 0;
|
||||||
|
const char *buf = Api::get(url, &size, &status);
|
||||||
|
|
||||||
|
if (size) {
|
||||||
|
rsp = MHD_create_response_from_buffer(size, (void*) buf, MHD_RESPMEM_PERSISTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return done(connection, status, rsp);
|
||||||
|
}
|
53
src/api/Httpd.h
Normal file
53
src/api/Httpd.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* 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 __HTTPD_H__
|
||||||
|
#define __HTTPD_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct MHD_Connection;
|
||||||
|
struct MHD_Daemon;
|
||||||
|
struct MHD_Response;
|
||||||
|
|
||||||
|
|
||||||
|
class Httpd
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Httpd(int port, const char *accessToken);
|
||||||
|
bool start();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int auth(const char *header);
|
||||||
|
|
||||||
|
static int done(MHD_Connection *connection, int status, MHD_Response *rsp);
|
||||||
|
static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls);
|
||||||
|
|
||||||
|
const char *m_accessToken;
|
||||||
|
const int m_port;
|
||||||
|
MHD_Daemon *m_daemon;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __HTTPD_H__ */
|
111
src/api/NetworkState.cpp
Normal file
111
src/api/NetworkState.cpp
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/* 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 <algorithm>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "api/NetworkState.h"
|
||||||
|
#include "net/SubmitResult.h"
|
||||||
|
|
||||||
|
|
||||||
|
NetworkState::NetworkState() :
|
||||||
|
diff(0),
|
||||||
|
accepted(0),
|
||||||
|
failures(0),
|
||||||
|
rejected(0),
|
||||||
|
total(0),
|
||||||
|
m_active(false)
|
||||||
|
{
|
||||||
|
memset(pool, 0, sizeof(pool));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int NetworkState::connectionTime() const
|
||||||
|
{
|
||||||
|
return m_active ? ((uv_now(uv_default_loop()) - m_connectionTime) / 1000) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t NetworkState::avgTime() const
|
||||||
|
{
|
||||||
|
if (m_latency.empty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint32_t) connectionTime() / m_latency.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t NetworkState::latency() const
|
||||||
|
{
|
||||||
|
const size_t calls = m_latency.size();
|
||||||
|
if (calls == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto v = m_latency;
|
||||||
|
std::nth_element(v.begin(), v.begin() + calls / 2, v.end());
|
||||||
|
|
||||||
|
return v[calls / 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NetworkState::add(const SubmitResult &result, const char *error)
|
||||||
|
{
|
||||||
|
if (error) {
|
||||||
|
rejected++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
accepted++;
|
||||||
|
total += result.diff;
|
||||||
|
|
||||||
|
const size_t ln = topDiff.size() - 1;
|
||||||
|
if (result.actualDiff > topDiff[ln]) {
|
||||||
|
topDiff[ln] = result.actualDiff;
|
||||||
|
std::sort(topDiff.rbegin(), topDiff.rend());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_latency.push_back(result.elapsed > 0xFFFF ? 0xFFFF : (uint16_t) result.elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NetworkState::setPool(const char *host, int port, const char *ip)
|
||||||
|
{
|
||||||
|
snprintf(pool, sizeof(pool) - 1, "%s:%d", host, port);
|
||||||
|
|
||||||
|
m_active = true;
|
||||||
|
m_connectionTime = uv_now(uv_default_loop());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NetworkState::stop()
|
||||||
|
{
|
||||||
|
m_active = false;
|
||||||
|
diff = 0;
|
||||||
|
|
||||||
|
failures++;
|
||||||
|
m_latency.clear();
|
||||||
|
}
|
61
src/api/NetworkState.h
Normal file
61
src/api/NetworkState.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 __NETWORKSTATE_H__
|
||||||
|
#define __NETWORKSTATE_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
class SubmitResult;
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NetworkState();
|
||||||
|
|
||||||
|
int connectionTime() const;
|
||||||
|
uint32_t avgTime() const;
|
||||||
|
uint32_t latency() const;
|
||||||
|
void add(const SubmitResult &result, const char *error);
|
||||||
|
void setPool(const char *host, int port, const char *ip);
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
char pool[256];
|
||||||
|
std::array<uint64_t, 10> topDiff { { } };
|
||||||
|
uint32_t diff;
|
||||||
|
uint64_t accepted;
|
||||||
|
uint64_t failures;
|
||||||
|
uint64_t rejected;
|
||||||
|
uint64_t total;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_active;
|
||||||
|
std::vector<uint16_t> m_latency;
|
||||||
|
uint64_t m_connectionTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __NETWORKSTATE_H__ */
|
|
@ -22,5 +22,10 @@
|
||||||
"keepalive": true,
|
"keepalive": true,
|
||||||
"nicehash": false
|
"nicehash": false
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"api": {
|
||||||
|
"port": 0,
|
||||||
|
"access-token": null,
|
||||||
|
"worker-id": null
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
class Job;
|
class Job;
|
||||||
|
class SubmitResult;
|
||||||
|
|
||||||
|
|
||||||
class IClientListener
|
class IClientListener
|
||||||
|
@ -40,7 +41,7 @@ public:
|
||||||
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 onLoginSuccess(Client *client) = 0;
|
virtual void onLoginSuccess(Client *client) = 0;
|
||||||
virtual void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) = 0;
|
virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
class Client;
|
class Client;
|
||||||
class IStrategy;
|
class IStrategy;
|
||||||
class Job;
|
class Job;
|
||||||
|
class SubmitResult;
|
||||||
|
|
||||||
|
|
||||||
class IStrategyListener
|
class IStrategyListener
|
||||||
|
@ -41,7 +42,7 @@ public:
|
||||||
virtual void onActive(Client *client) = 0;
|
virtual void onActive(Client *client) = 0;
|
||||||
virtual void onJob(Client *client, const Job &job) = 0;
|
virtual void onJob(Client *client, const Job &job) = 0;
|
||||||
virtual void onPause(IStrategy *strategy) = 0;
|
virtual void onPause(IStrategy *strategy) = 0;
|
||||||
virtual void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) = 0;
|
virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ int64_t Client::submit(const JobResult &result)
|
||||||
snprintf(req, 345, "{\"id\":%" PRIu64 ",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
|
snprintf(req, 345, "{\"id\":%" PRIu64 ",\"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(m_sequence, result.diff);
|
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
|
||||||
return send(req);
|
return send(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +420,8 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error
|
||||||
|
|
||||||
auto it = m_results.find(id);
|
auto it = m_results.find(id);
|
||||||
if (it != m_results.end()) {
|
if (it != m_results.end()) {
|
||||||
m_listener->onResultAccepted(this, it->second.seq, it->second.diff, it->second.elapsed(), message);
|
it->second.done();
|
||||||
|
m_listener->onResultAccepted(this, it->second, message);
|
||||||
m_results.erase(it);
|
m_results.erase(it);
|
||||||
}
|
}
|
||||||
else if (!m_quiet) {
|
else if (!m_quiet) {
|
||||||
|
@ -456,7 +457,8 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error
|
||||||
|
|
||||||
auto it = m_results.find(id);
|
auto it = m_results.find(id);
|
||||||
if (it != m_results.end()) {
|
if (it != m_results.end()) {
|
||||||
m_listener->onResultAccepted(this, it->second.seq, it->second.diff, it->second.elapsed(), nullptr);
|
it->second.done();
|
||||||
|
m_listener->onResultAccepted(this, it->second, nullptr);
|
||||||
m_results.erase(it);
|
m_results.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline uint64_t actualDiff() const
|
||||||
|
{
|
||||||
|
return Job::toDiff(reinterpret_cast<const uint64_t*>(result)[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char jobId[64];
|
char jobId[64];
|
||||||
int poolId;
|
int poolId;
|
||||||
uint32_t diff;
|
uint32_t diff;
|
||||||
|
|
|
@ -30,12 +30,14 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "api/Api.h"
|
||||||
#include "log/Log.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/DonateStrategy.h"
|
||||||
#include "net/strategies/FailoverStrategy.h"
|
#include "net/strategies/FailoverStrategy.h"
|
||||||
#include "net/strategies/SinglePoolStrategy.h"
|
#include "net/strategies/SinglePoolStrategy.h"
|
||||||
|
#include "net/SubmitResult.h"
|
||||||
#include "net/Url.h"
|
#include "net/Url.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
|
@ -44,9 +46,7 @@
|
||||||
|
|
||||||
Network::Network(const Options *options) :
|
Network::Network(const Options *options) :
|
||||||
m_options(options),
|
m_options(options),
|
||||||
m_donate(nullptr),
|
m_donate(nullptr)
|
||||||
m_accepted(0),
|
|
||||||
m_rejected(0)
|
|
||||||
{
|
{
|
||||||
srand(time(0) ^ (uintptr_t) this);
|
srand(time(0) ^ (uintptr_t) this);
|
||||||
|
|
||||||
|
@ -100,6 +100,8 @@ void Network::onActive(Client *client)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_state.setPool(client->host(), client->port(), client->ip());
|
||||||
|
|
||||||
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());
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,26 +136,25 @@ void Network::onPause(IStrategy *strategy)
|
||||||
|
|
||||||
if (!m_strategy->isActive()) {
|
if (!m_strategy->isActive()) {
|
||||||
LOG_ERR("no active pools, stop mining");
|
LOG_ERR("no active pools, stop mining");
|
||||||
|
m_state.stop();
|
||||||
return Workers::pause();
|
return Workers::pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Network::onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error)
|
void Network::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
|
||||||
{
|
{
|
||||||
if (error) {
|
m_state.add(result, error);
|
||||||
m_rejected++;
|
|
||||||
|
|
||||||
|
if (error) {
|
||||||
LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
|
LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
|
||||||
: "rejected (%" PRId64 "/%" PRId64 ") diff %u \"%s\" (%" PRIu64 " ms)",
|
: "rejected (%" PRId64 "/%" PRId64 ") diff %u \"%s\" (%" PRIu64 " ms)",
|
||||||
m_accepted, m_rejected, diff, error, ms);
|
m_state.accepted, m_state.rejected, result.diff, error, result.elapsed);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_accepted++;
|
|
||||||
|
|
||||||
LOG_INFO(m_options->colors() ? "\x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
|
LOG_INFO(m_options->colors() ? "\x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
|
||||||
: "accepted (%" PRId64 "/%" PRId64 ") diff %u (%" PRIu64 " ms)",
|
: "accepted (%" PRId64 "/%" PRId64 ") diff %u (%" PRIu64 " ms)",
|
||||||
m_accepted, m_rejected, diff, ms);
|
m_state.accepted, m_state.rejected, result.diff, result.elapsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,12 +163,12 @@ 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 \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_state.diff = job.diff();
|
||||||
Workers::setJob(job);
|
Workers::setJob(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +182,10 @@ void Network::tick()
|
||||||
if (m_donate) {
|
if (m_donate) {
|
||||||
m_donate->tick(now);
|
m_donate->tick(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifndef XMRIG_NO_API
|
||||||
|
Api::tick(m_state);
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "api/NetworkState.h"
|
||||||
#include "interfaces/IJobResultListener.h"
|
#include "interfaces/IJobResultListener.h"
|
||||||
#include "interfaces/IStrategyListener.h"
|
#include "interfaces/IStrategyListener.h"
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ protected:
|
||||||
void onJob(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 onPause(IStrategy *strategy) override;
|
void onPause(IStrategy *strategy) override;
|
||||||
void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) override;
|
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
constexpr static int kTickInterval = 1 * 1000;
|
constexpr static int kTickInterval = 1 * 1000;
|
||||||
|
@ -65,8 +66,7 @@ private:
|
||||||
const Options *m_options;
|
const Options *m_options;
|
||||||
IStrategy *m_donate;
|
IStrategy *m_donate;
|
||||||
IStrategy *m_strategy;
|
IStrategy *m_strategy;
|
||||||
uint64_t m_accepted;
|
NetworkState m_state;
|
||||||
uint64_t m_rejected;
|
|
||||||
uv_timer_t m_timer;
|
uv_timer_t m_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
44
src/net/SubmitResult.cpp
Normal file
44
src/net/SubmitResult.cpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/* 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 <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "net/SubmitResult.h"
|
||||||
|
|
||||||
|
|
||||||
|
SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff) :
|
||||||
|
seq(seq),
|
||||||
|
diff(diff),
|
||||||
|
actualDiff(actualDiff),
|
||||||
|
elapsed(0)
|
||||||
|
{
|
||||||
|
start = uv_hrtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SubmitResult::done()
|
||||||
|
{
|
||||||
|
elapsed = (uv_hrtime() - start) / 1000000;
|
||||||
|
}
|
|
@ -31,18 +31,15 @@
|
||||||
class SubmitResult
|
class SubmitResult
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline SubmitResult() : seq(0), diff(0), start(0) {}
|
inline SubmitResult() : seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {}
|
||||||
inline SubmitResult(int64_t seq, uint32_t diff) :
|
SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff);
|
||||||
seq(seq),
|
|
||||||
diff(diff)
|
|
||||||
{
|
|
||||||
start = uv_hrtime();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t elapsed() const { return (uv_hrtime() - start) / 1000000; }
|
void done();
|
||||||
|
|
||||||
int64_t seq;
|
int64_t seq;
|
||||||
uint32_t diff;
|
uint32_t diff;
|
||||||
|
uint64_t actualDiff;
|
||||||
|
uint64_t elapsed;
|
||||||
uint64_t start;
|
uint64_t start;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -111,9 +111,9 @@ void DonateStrategy::onLoginSuccess(Client *client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DonateStrategy::onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error)
|
void DonateStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
|
||||||
{
|
{
|
||||||
m_listener->onResultAccepted(client, seq, diff, ms, error);
|
m_listener->onResultAccepted(client, result, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ protected:
|
||||||
void onClose(Client *client, int failures) override;
|
void onClose(Client *client, int failures) override;
|
||||||
void onJobReceived(Client *client, const Job &job) override;
|
void onJobReceived(Client *client, const Job &job) override;
|
||||||
void onLoginSuccess(Client *client) override;
|
void onLoginSuccess(Client *client) override;
|
||||||
void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) override;
|
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void idle();
|
void idle();
|
||||||
|
|
|
@ -132,9 +132,9 @@ void FailoverStrategy::onLoginSuccess(Client *client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FailoverStrategy::onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error)
|
void FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
|
||||||
{
|
{
|
||||||
m_listener->onResultAccepted(client, seq, diff, ms, error);
|
m_listener->onResultAccepted(client, result, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ protected:
|
||||||
void onClose(Client *client, int failures) override;
|
void onClose(Client *client, int failures) override;
|
||||||
void onJobReceived(Client *client, const Job &job) override;
|
void onJobReceived(Client *client, const Job &job) override;
|
||||||
void onLoginSuccess(Client *client) override;
|
void onLoginSuccess(Client *client) override;
|
||||||
void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) override;
|
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void add(const Url *url, const char *agent);
|
void add(const Url *url, const char *agent);
|
||||||
|
|
|
@ -96,7 +96,7 @@ void SinglePoolStrategy::onLoginSuccess(Client *client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SinglePoolStrategy::onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error)
|
void SinglePoolStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
|
||||||
{
|
{
|
||||||
m_listener->onResultAccepted(client, seq, diff, ms, error);
|
m_listener->onResultAccepted(client, result, error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ protected:
|
||||||
void onClose(Client *client, int failures) override;
|
void onClose(Client *client, int failures) override;
|
||||||
void onJobReceived(Client *client, const Job &job) override;
|
void onJobReceived(Client *client, const Job &job) override;
|
||||||
void onLoginSuccess(Client *client) override;
|
void onLoginSuccess(Client *client) override;
|
||||||
void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) override;
|
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_active;
|
bool m_active;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#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_KIND "cpu"
|
||||||
|
|
||||||
#define APP_VER_MAJOR 2
|
#define APP_VER_MAJOR 2
|
||||||
#define APP_VER_MINOR 3
|
#define APP_VER_MINOR 3
|
||||||
|
|
|
@ -153,9 +153,9 @@ void Hashrate::print()
|
||||||
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 max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s max: %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(ShortInterval), num1, sizeof(num1)),
|
||||||
format(calc(60000), num2, sizeof(num2)),
|
format(calc(MediumInterval), num2, sizeof(num2)),
|
||||||
format(calc(900000), num3, sizeof(num3)),
|
format(calc(LargeInterval), num3, sizeof(num3)),
|
||||||
format(m_highest, num4, sizeof(num4))
|
format(m_highest, num4, sizeof(num4))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ void Hashrate::stop()
|
||||||
|
|
||||||
void Hashrate::updateHighest()
|
void Hashrate::updateHighest()
|
||||||
{
|
{
|
||||||
double highest = calc(2500);
|
double highest = calc(ShortInterval);
|
||||||
if (std::isnormal(highest) && highest > m_highest) {
|
if (std::isnormal(highest) && highest > m_highest) {
|
||||||
m_highest = highest;
|
m_highest = highest;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,12 @@
|
||||||
class Hashrate
|
class Hashrate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum Intervals {
|
||||||
|
ShortInterval = 2500,
|
||||||
|
MediumInterval = 60000,
|
||||||
|
LargeInterval = 900000
|
||||||
|
};
|
||||||
|
|
||||||
Hashrate(int threads);
|
Hashrate(int threads);
|
||||||
double calc(size_t ms) const;
|
double calc(size_t ms) const;
|
||||||
double calc(size_t threadId, size_t ms) const;
|
double calc(size_t threadId, size_t ms) const;
|
||||||
|
@ -41,6 +47,7 @@ public:
|
||||||
void updateHighest();
|
void updateHighest();
|
||||||
|
|
||||||
inline double highest() const { return m_highest; }
|
inline double highest() const { return m_highest; }
|
||||||
|
inline int threads() const { return m_threads; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void onReport(uv_timer_t *handle);
|
static void onReport(uv_timer_t *handle);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
||||||
|
#include "api/Api.h"
|
||||||
#include "interfaces/IJobResultListener.h"
|
#include "interfaces/IJobResultListener.h"
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
|
@ -192,4 +193,8 @@ void Workers::onTick(uv_timer_t *handle)
|
||||||
if ((m_ticks++ & 0xF) == 0) {
|
if ((m_ticks++ & 0xF) == 0) {
|
||||||
m_hashrate->updateHighest();
|
m_hashrate->updateHighest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifndef XMRIG_NO_API
|
||||||
|
Api::tick(m_hashrate);
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue