Compare commits

...

9 Commits
v3.2.1 ... beta

Author SHA1 Message Date
XMRig
92ba6099a7 v4.5.0-beta 2019-11-02 19:25:52 +07:00
XMRig
5420e65503 Merge branch 'evo' into beta 2019-11-02 19:24:46 +07:00
xmrig
4782b441e9 Update CHANGELOG.md 2019-11-02 03:52:01 +07:00
XMRig
277e4ca2e4 Merge branch 'dev' into evo 2019-11-02 00:20:28 +07:00
XMRig
072638b5c6 Sync changes with miner. 2019-11-01 21:50:18 +07:00
XMRig
6ace89f832 #348 Added missing rx/arq. 2019-10-28 16:52:13 +07:00
XMRig
36704047e1 v4.4.0-evo 2019-10-23 03:03:24 +07:00
XMRig
9afe0f2cd4 Sync changes with miner. 2019-10-23 02:49:53 +07:00
XMRig
c0cae2f3c3 Merge branch 'dev' into evo 2019-10-23 01:37:36 +07:00
64 changed files with 1632 additions and 720 deletions

View File

@@ -1,3 +1,8 @@
# v4.5.0-beta
- Proxy rebased to latest miner codebase.
- [#1068](https://github.com/xmrig/xmrig/pull/1068) Added support for `self-select` stratum protocol extension.
- [#1227](https://github.com/xmrig/xmrig/pull/1227) Added new algorithm `rx/arq`, RandomX variant for upcoming ArQmA fork.
# v3.2.1
- [#349](https://github.com/xmrig/xmrig-proxy/issues/349) Fixed command line option `--coin`.

View File

@@ -117,9 +117,10 @@ void xmrig::Api::exec(IApiRequest &request)
auto &allocator = request.doc().GetAllocator();
request.accept();
request.reply().AddMember("id", StringRef(m_id), allocator);
request.reply().AddMember("worker_id", StringRef(m_workerId), allocator);
request.reply().AddMember("uptime", (Chrono::currentMSecsSinceEpoch() - m_timestamp) / 1000, allocator);
request.reply().AddMember("id", StringRef(m_id), allocator);
request.reply().AddMember("worker_id", StringRef(m_workerId), allocator);
request.reply().AddMember("uptime", (Chrono::currentMSecsSinceEpoch() - m_timestamp) / 1000, allocator);
request.reply().AddMember("restricted", request.isRestricted(), allocator);
Value features(kArrayType);
# ifdef XMRIG_FEATURE_API
@@ -139,6 +140,9 @@ void xmrig::Api::exec(IApiRequest &request)
# endif
# ifdef XMRIG_FEATURE_TLS
features.PushBack("tls", allocator);
# endif
# ifdef XMRIG_FEATURE_OPENCL
features.PushBack("opencl", allocator);
# endif
request.reply().AddMember("features", features, allocator);
}

View File

@@ -27,10 +27,11 @@
#include <vector>
#include <stdint.h>
#include <cstdint>
#include "base/kernel/interfaces/IBaseListener.h"
#include "base/tools/Object.h"
namespace xmrig {
@@ -47,6 +48,8 @@ class String;
class Api : public IBaseListener
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Api)
Api(Base *base);
~Api() override;

View File

@@ -41,6 +41,7 @@ set(HEADERS_BASE
src/base/net/stratum/strategies/FailoverStrategy.h
src/base/net/stratum/strategies/SinglePoolStrategy.h
src/base/net/stratum/SubmitResult.h
src/base/net/stratum/Url.h
src/base/net/tools/RecvBuf.h
src/base/net/tools/Storage.h
src/base/tools/Arguments.h
@@ -78,6 +79,7 @@ set(SOURCES_BASE
src/base/net/stratum/Pools.cpp
src/base/net/stratum/strategies/FailoverStrategy.cpp
src/base/net/stratum/strategies/SinglePoolStrategy.cpp
src/base/net/stratum/Url.cpp
src/base/tools/Arguments.cpp
src/base/tools/Buffer.cpp
src/base/tools/String.cpp
@@ -98,7 +100,14 @@ elseif (APPLE)
else()
set(SOURCES_OS
src/base/io/json/Json_unix.cpp
src/base/kernel//Platform_unix.cpp
src/base/kernel/Platform_unix.cpp
)
endif()
if (WITH_HWLOC)
list(APPEND SOURCES_OS
src/base/kernel/Platform_hwloc.cpp
)
endif()
@@ -130,6 +139,7 @@ if (WITH_HTTP)
src/base/net/http/HttpResponse.h
src/base/net/http/HttpServer.h
src/base/net/stratum/DaemonClient.h
src/base/net/stratum/SelfSelectClient.h
src/base/net/tools/TcpServer.h
)
@@ -145,6 +155,7 @@ if (WITH_HTTP)
src/base/net/http/HttpResponse.cpp
src/base/net/http/HttpServer.cpp
src/base/net/stratum/DaemonClient.cpp
src/base/net/stratum/SelfSelectClient.cpp
src/base/net/tools/TcpServer.cpp
)

View File

@@ -27,6 +27,9 @@
#include "rapidjson/document.h"
#include <cassert>
namespace xmrig {
static const rapidjson::Value kNullValue;
@@ -36,6 +39,8 @@ static const rapidjson::Value kNullValue;
bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue)
{
assert(obj.IsObject());
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsBool()) {
return i->value.GetBool();
@@ -47,6 +52,8 @@ bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool def
const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key, const char *defaultValue)
{
assert(obj.IsObject());
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsString()) {
return i->value.GetString();
@@ -58,6 +65,8 @@ const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key,
const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const char *key)
{
assert(obj.IsObject());
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsArray()) {
return i->value;
@@ -69,6 +78,8 @@ const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const
const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, const char *key)
{
assert(obj.IsObject());
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsObject()) {
return i->value;
@@ -80,6 +91,8 @@ const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, cons
const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const char *key)
{
assert(obj.IsObject());
auto i = obj.FindMember(key);
if (i != obj.MemberEnd()) {
return i->value;
@@ -91,6 +104,8 @@ const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const
int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue)
{
assert(obj.IsObject());
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsInt()) {
return i->value.GetInt();
@@ -102,6 +117,8 @@ int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaul
int64_t xmrig::Json::getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue)
{
assert(obj.IsObject());
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsInt64()) {
return i->value.GetInt64();
@@ -113,6 +130,8 @@ int64_t xmrig::Json::getInt64(const rapidjson::Value &obj, const char *key, int6
uint64_t xmrig::Json::getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue)
{
assert(obj.IsObject());
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsUint64()) {
return i->value.GetUint64();
@@ -124,6 +143,8 @@ uint64_t xmrig::Json::getUint64(const rapidjson::Value &obj, const char *key, ui
unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue)
{
assert(obj.IsObject());
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsUint()) {
return i->value.GetUint();

View File

@@ -31,10 +31,10 @@
#include <algorithm>
#include <cstring>
#include <ctime>
#include <mutex>
#include <string.h>
#include <string>
#include <time.h>
#include <uv.h>
#include <vector>
@@ -42,6 +42,7 @@
#include "base/io/log/Log.h"
#include "base/kernel/interfaces/ILogBackend.h"
#include "base/tools/Chrono.h"
#include "base/tools/Object.h"
namespace xmrig {
@@ -67,10 +68,10 @@ static const char *colors_map[] = {
class LogPrivate
{
public:
inline LogPrivate() :
m_buf()
{
}
XMRIG_DISABLE_COPY_MOVE(LogPrivate)
LogPrivate() = default;
inline ~LogPrivate()
@@ -134,7 +135,7 @@ private:
const uint64_t ms = Chrono::currentMSecsSinceEpoch();
time_t now = ms / 1000;
tm stime;
tm stime{};
# ifdef _WIN32
localtime_s(&stime, &now);
@@ -188,7 +189,7 @@ private:
}
char m_buf[4096];
char m_buf[4096]{};
std::mutex m_mutex;
std::vector<ILogBackend*> m_backends;
};

View File

@@ -82,6 +82,7 @@ private:
#define WHITE_S CSI "0;37m" // another name for LT.GRAY
#define WHITE_BOLD_S CSI "1;37m" // actually white
#define GREEN_BG_BOLD_S CSI "42;1m"
#define BLUE_BG_S CSI "44m"
#define BLUE_BG_BOLD_S CSI "44;1m"
#define MAGENTA_BG_S CSI "45m"
@@ -107,6 +108,7 @@ private:
#define WHITE(x) WHITE_S x CLEAR
#define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR
#define GREEN_BG_BOLD(x) GREEN_BG_BOLD_S x CLEAR
#define BLUE_BG(x) BLUE_BG_S x CLEAR
#define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR
#define MAGENTA_BG(x) MAGENTA_BG_S x CLEAR

View File

@@ -47,9 +47,10 @@ xmrig::ConsoleLog::ConsoleLog()
}
uv_tty_set_mode(m_tty, UV_TTY_MODE_NORMAL);
m_stream = reinterpret_cast<uv_stream_t*>(m_tty);
# ifdef WIN32
m_stream = reinterpret_cast<uv_stream_t*>(m_tty);
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
if (handle != INVALID_HANDLE_VALUE) {
DWORD mode = 0;
@@ -76,9 +77,6 @@ void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool c
# ifdef _WIN32
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), static_cast<unsigned int>(size));
# else
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), size);
# endif
if (!isWritable()) {
fputs(line, stdout);
@@ -87,6 +85,10 @@ void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool c
else {
uv_try_write(m_stream, &buf, 1);
}
# else
fputs(line, stdout);
fflush(stdout);
# endif
}
@@ -97,6 +99,7 @@ bool xmrig::ConsoleLog::isSupported() const
}
#ifdef WIN32
bool xmrig::ConsoleLog::isWritable() const
{
if (!m_stream || uv_is_writable(m_stream) != 1) {
@@ -105,3 +108,4 @@ bool xmrig::ConsoleLog::isWritable() const
return isSupported();
}
#endif

View File

@@ -51,10 +51,14 @@ protected:
private:
bool isSupported() const;
uv_tty_t *m_tty = nullptr;
# ifdef _WIN32
bool isWritable() const;
uv_stream_t *m_stream = nullptr;
uv_tty_t *m_tty = nullptr;
# endif
};

View File

@@ -23,7 +23,7 @@
*/
#include <assert.h>
#include <cassert>
#include <memory>
@@ -64,15 +64,16 @@ static const char *kConfigPathV2 = "/2/config";
#endif
class xmrig::BasePrivate
namespace xmrig {
class BasePrivate
{
public:
inline BasePrivate(Process *process) :
api(nullptr),
config(nullptr),
process(process),
watcher(nullptr)
{}
XMRIG_DISABLE_COPY_MOVE_DEFAULT(BasePrivate)
inline BasePrivate(Process *process) : config(load(process)) {}
inline ~BasePrivate()
@@ -94,13 +95,33 @@ public:
}
inline Config *load()
inline void replace(Config *newConfig)
{
Config *previousConfig = config;
config = newConfig;
for (IBaseListener *listener : listeners) {
listener->onConfigChanged(config, previousConfig);
}
delete previousConfig;
}
Api *api = nullptr;
Config *config = nullptr;
std::vector<IBaseListener *> listeners;
Watcher *watcher = nullptr;
private:
inline Config *load(Process *process)
{
JsonChain chain;
ConfigTransform transform;
std::unique_ptr<Config> config;
transform.load(chain, process, transform);
ConfigTransform::load(chain, process, transform);
if (read(chain, config)) {
return config.release();
@@ -122,29 +143,12 @@ public:
return nullptr;
}
inline void replace(Config *newConfig)
{
Config *previousConfig = config;
config = newConfig;
for (IBaseListener *listener : listeners) {
listener->onConfigChanged(config, previousConfig);
}
delete previousConfig;
}
Api *api;
Config *config;
Process *process;
std::vector<IBaseListener *> listeners;
Watcher *watcher;
};
} // namespace xmrig
xmrig::Base::Base(Process *process)
: d_ptr(new BasePrivate(process))
{
@@ -165,14 +169,6 @@ bool xmrig::Base::isReady() const
int xmrig::Base::init()
{
d_ptr->config = d_ptr->load();
if (!d_ptr->config) {
LOG_EMERG("No valid configuration found. Exiting.");
return 1;
}
# ifdef XMRIG_FEATURE_API
d_ptr->api = new Api(this);
d_ptr->api->addListener(this);
@@ -184,7 +180,7 @@ int xmrig::Base::init()
Platform::setProcessPriority(config()->cpu().priority());
# endif
if (config()->isBackground()) {
if (isBackground()) {
Log::background = true;
}
else {
@@ -240,6 +236,12 @@ xmrig::Api *xmrig::Base::api() const
}
bool xmrig::Base::isBackground() const
{
return d_ptr->config && d_ptr->config->isBackground();
}
bool xmrig::Base::reload(const rapidjson::Value &json)
{
JsonReader reader(json);
@@ -247,7 +249,7 @@ bool xmrig::Base::reload(const rapidjson::Value &json)
return false;
}
Config *config = new Config();
auto config = new Config();
if (!config->read(reader, d_ptr->config->fileName())) {
delete config;
@@ -289,7 +291,7 @@ void xmrig::Base::onFileChanged(const String &fileName)
JsonChain chain;
chain.addFile(fileName);
Config *config = new Config();
auto config = new Config();
if (!config->read(chain, chain.fileName())) {
LOG_ERR("reloading failed");

View File

@@ -29,6 +29,7 @@
#include "base/api/interfaces/IApiListener.h"
#include "base/kernel/interfaces/IConfigListener.h"
#include "base/kernel/interfaces/IWatcherListener.h"
#include "base/tools/Object.h"
#include "rapidjson/fwd.h"
@@ -45,6 +46,8 @@ class Process;
class Base : public IWatcherListener, public IApiListener
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Base)
Base(Process *process);
~Base() override;
@@ -54,6 +57,7 @@ public:
virtual void stop();
Api *api() const;
bool isBackground() const;
bool reload(const rapidjson::Value &json);
Config *config() const;
void addListener(IBaseListener *listener);

View File

@@ -23,7 +23,7 @@
*/
#include <stdio.h>
#include <cstdio>
#include <uv.h>
@@ -35,6 +35,11 @@
# include <hwloc.h>
#endif
#ifdef XMRIG_FEATURE_OPENCL
# include "backend/opencl/wrappers/OclLib.h"
# include "backend/opencl/wrappers/OclPlatform.h"
#endif
#include "base/kernel/Entry.h"
#include "base/kernel/Process.h"
#include "core/config/usage.h"
@@ -142,6 +147,12 @@ xmrig::Entry::Id xmrig::Entry::get(const Process &process)
}
# endif
# ifdef XMRIG_FEATURE_OPENCL
if (args.hasArg("--print-platforms")) {
return Platforms;
}
# endif
return Default;
}
@@ -150,7 +161,7 @@ int xmrig::Entry::exec(const Process &process, Id id)
{
switch (id) {
case Usage:
printf(usage);
printf("%s\n", usage().c_str());
return 0;
case Version:
@@ -161,6 +172,14 @@ int xmrig::Entry::exec(const Process &process, Id id)
return exportTopology(process);
# endif
# ifdef XMRIG_FEATURE_OPENCL
case Platforms:
if (OclLib::init()) {
OclPlatform::print();
}
return 0;
# endif
default:
break;
}

View File

@@ -39,7 +39,8 @@ public:
Default,
Usage,
Version,
Topo
Topo,
Platforms
};
static Id get(const Process &process);

View File

@@ -23,7 +23,10 @@
*/
#include <string.h>
#include "base/kernel/Platform.h"
#include <cstring>
#include <uv.h>
@@ -33,13 +36,14 @@
#endif
#include "Platform.h"
namespace xmrig {
String Platform::m_userAgent;
} // namespace xmrig
xmrig::String Platform::m_userAgent;
void Platform::init(const char *userAgent)
void xmrig::Platform::init(const char *userAgent)
{
# ifdef XMRIG_FEATURE_TLS
SSL_library_init();

View File

@@ -26,12 +26,15 @@
#define XMRIG_PLATFORM_H
#include <stdint.h>
#include <cstdint>
#include "base/tools/String.h"
namespace xmrig {
class Platform
{
public:
@@ -56,8 +59,11 @@ public:
private:
static char *createUserAgent();
static xmrig::String m_userAgent;
static String m_userAgent;
};
} // namespace xmrig
#endif /* XMRIG_PLATFORM_H */

View File

@@ -0,0 +1,49 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/kernel/Platform.h"
#include "backend/cpu/platform/HwlocCpuInfo.h"
#include "backend/cpu/Cpu.h"
#include <hwloc.h>
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
{
auto cpu = static_cast<HwlocCpuInfo *>(Cpu::info());
hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(cpu->topology(), static_cast<unsigned>(cpu_id));
if (pu == nullptr) {
return false;
}
if (hwloc_set_cpubind(cpu->topology(), pu->cpuset, HWLOC_CPUBIND_THREAD | HWLOC_CPUBIND_STRICT) >= 0) {
return true;
}
return hwloc_set_cpubind(cpu->topology(), pu->cpuset, HWLOC_CPUBIND_THREAD) >= 0;
}

View File

@@ -30,7 +30,7 @@
#include <uv.h>
#include "Platform.h"
#include "base/kernel/Platform.h"
#include "version.h"
#ifdef XMRIG_NVIDIA_PROJECT
@@ -38,7 +38,7 @@
#endif
char *Platform::createUserAgent()
char *xmrig::Platform::createUserAgent()
{
constexpr const size_t max = 256;
@@ -60,7 +60,8 @@ char *Platform::createUserAgent()
}
bool Platform::setThreadAffinity(uint64_t cpu_id)
#ifndef XMRIG_FEATURE_HWLOC
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
{
thread_port_t mach_thread;
thread_affinity_policy_data_t policy = { static_cast<integer_t>(cpu_id) };
@@ -68,25 +69,26 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
return thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1) == KERN_SUCCESS;
}
#endif
uint32_t Platform::setTimerResolution(uint32_t resolution)
uint32_t xmrig::Platform::setTimerResolution(uint32_t resolution)
{
return resolution;
}
void Platform::restoreTimerResolution()
void xmrig::Platform::restoreTimerResolution()
{
}
void Platform::setProcessPriority(int priority)
void xmrig::Platform::setProcessPriority(int priority)
{
}
void Platform::setThreadPriority(int priority)
void xmrig::Platform::setThreadPriority(int priority)
{
if (priority == -1) {
return;

View File

@@ -39,7 +39,7 @@
#include <uv.h>
#include "Platform.h"
#include "base/kernel/Platform.h"
#include "version.h"
#ifdef XMRIG_NVIDIA_PROJECT
@@ -52,7 +52,7 @@ typedef cpuset_t cpu_set_t;
#endif
char *Platform::createUserAgent()
char *xmrig::Platform::createUserAgent()
{
constexpr const size_t max = 256;
@@ -84,7 +84,8 @@ char *Platform::createUserAgent()
}
bool Platform::setThreadAffinity(uint64_t cpu_id)
#ifndef XMRIG_FEATURE_HWLOC
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
{
cpu_set_t mn;
CPU_ZERO(&mn);
@@ -96,25 +97,26 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
return sched_setaffinity(gettid(), sizeof(cpu_set_t), &mn) == 0;
# endif
}
#endif
uint32_t Platform::setTimerResolution(uint32_t resolution)
uint32_t xmrig::Platform::setTimerResolution(uint32_t resolution)
{
return resolution;
}
void Platform::restoreTimerResolution()
void xmrig::Platform::restoreTimerResolution()
{
}
void Platform::setProcessPriority(int priority)
void xmrig::Platform::setProcessPriority(int priority)
{
}
void Platform::setThreadPriority(int priority)
void xmrig::Platform::setThreadPriority(int priority)
{
if (priority == -1) {
return;

View File

@@ -29,8 +29,8 @@
#include <uv.h>
#include "base/kernel/Platform.h"
#include "base/io/log/Log.h"
#include "Platform.h"
#include "version.h"
@@ -51,10 +51,10 @@ static inline OSVERSIONINFOEX winOsVersion()
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
if (ntdll ) {
RtlGetVersionFunction pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(GetProcAddress(ntdll, "RtlGetVersion"));
auto pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(GetProcAddress(ntdll, "RtlGetVersion"));
if (pRtlGetVersion) {
pRtlGetVersion((LPOSVERSIONINFO) &result);
pRtlGetVersion(reinterpret_cast<LPOSVERSIONINFO>(&result));
}
}
@@ -62,7 +62,7 @@ static inline OSVERSIONINFOEX winOsVersion()
}
char *Platform::createUserAgent()
char *xmrig::Platform::createUserAgent()
{
const auto osver = winOsVersion();
constexpr const size_t max = 256;
@@ -91,7 +91,8 @@ char *Platform::createUserAgent()
}
bool Platform::setThreadAffinity(uint64_t cpu_id)
#ifndef XMRIG_FEATURE_HWLOC
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
{
if (cpu_id >= 64) {
LOG_ERR("Unable to set affinity. Windows supports only affinity up to 63.");
@@ -99,9 +100,10 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
return SetThreadAffinityMask(GetCurrentThread(), 1ULL << cpu_id) != 0;
}
#endif
uint32_t Platform::setTimerResolution(uint32_t resolution)
uint32_t xmrig::Platform::setTimerResolution(uint32_t resolution)
{
# ifdef XMRIG_AMD_PROJECT
TIMECAPS tc;
@@ -119,7 +121,7 @@ uint32_t Platform::setTimerResolution(uint32_t resolution)
}
void Platform::restoreTimerResolution()
void xmrig::Platform::restoreTimerResolution()
{
# ifdef XMRIG_AMD_PROJECT
if (timerResolution) {
@@ -129,7 +131,7 @@ void Platform::restoreTimerResolution()
}
void Platform::setProcessPriority(int priority)
void xmrig::Platform::setProcessPriority(int priority)
{
if (priority == -1) {
return;
@@ -166,7 +168,7 @@ void Platform::setProcessPriority(int priority)
}
void Platform::setThreadPriority(int priority)
void xmrig::Platform::setThreadPriority(int priority)
{
if (priority == -1) {
return;

View File

@@ -23,8 +23,8 @@
*/
#include <ctime>
#include <uv.h>
#include <time.h>
#include "base/kernel/Process.h"
@@ -55,11 +55,6 @@ xmrig::Process::Process(int argc, char **argv) :
}
xmrig::Process::~Process()
{
}
xmrig::String xmrig::Process::location(Location location, const char *fileName) const
{
constexpr const size_t max = 520;

View File

@@ -47,7 +47,6 @@ public:
# endif
Process(int argc, char **argv);
~Process();
String location(Location location, const char *fileName = nullptr) const;

View File

@@ -56,7 +56,6 @@ public:
inline const String &apiId() const { return m_apiId; }
inline const String &apiWorkerId() const { return m_apiWorkerId; }
inline uint32_t printTime() const { return m_printTime; }
inline uint32_t version() const { return m_version; }
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
inline const String &fileName() const override { return m_fileName; }

View File

@@ -23,7 +23,7 @@
*/
#include <stdio.h>
#include <cstdio>
#ifdef _MSC_VER
@@ -51,12 +51,7 @@ static const char *kCoin = "coin";
static const char *kHttp = "http";
static const char *kPools = "pools";
}
xmrig::BaseTransform::BaseTransform()
{
}
} // namespace xmrig
void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTransform &transform)
@@ -69,7 +64,7 @@ void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTrans
Document doc(kObjectType);
while (1) {
while (true) {
key = getopt_long(argc, argv, short_options, options, nullptr);
if (key < 0) {
break;
@@ -117,6 +112,10 @@ void xmrig::BaseTransform::finalize(rapidjson::Document &doc)
}
}
}
if (m_http) {
set(doc, kHttp, "enabled", true);
}
}
@@ -184,13 +183,18 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
case IConfig::FingerprintKey: /* --tls-fingerprint */
return add(doc, kPools, "tls-fingerprint", arg);
case IConfig::SelfSelectKey: /* --self-select */
return add(doc, kPools, "self-select", arg);
case IConfig::LogFileKey: /* --log-file */
return set(doc, "log-file", arg);
case IConfig::HttpAccessTokenKey: /* --http-access-token */
m_http = true;
return set(doc, kHttp, "access-token", arg);
case IConfig::HttpHostKey: /* --http-host */
m_http = true;
return set(doc, kHttp, "host", arg);
case IConfig::ApiWorkerIdKey: /* --api-worker-id */
@@ -245,8 +249,10 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
case IConfig::TlsKey: /* --tls */
return add(doc, kPools, "tls", enable);
# ifdef XMRIG_FEATURE_HTTP
case IConfig::DaemonKey: /* --daemon */
return add(doc, kPools, "daemon", enable);
# endif
# ifndef XMRIG_PROXY_PROJECT
case IConfig::NicehashKey: /* --nicehash */
@@ -257,10 +263,12 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
return set(doc, "colors", enable);
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
m_http = true;
return set(doc, kHttp, "restricted", enable);
case IConfig::HttpEnabledKey: /* --http-enabled */
return set(doc, kHttp, "enabled", enable);
m_http = true;
break;
case IConfig::DryRunKey: /* --dry-run */
return set(doc, "dry-run", enable);
@@ -287,13 +295,16 @@ void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, ui
return set(doc, "donate-over-proxy", arg);
case IConfig::HttpPort: /* --http-port */
m_http = true;
return set(doc, kHttp, "port", arg);
case IConfig::PrintTimeKey: /* --print-time */
return set(doc, "print-time", arg);
# ifdef XMRIG_FEATURE_HTTP
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
return add(doc, kPools, "daemon-poll-interval", arg);
# endif
default:
break;

View File

@@ -45,8 +45,6 @@ class Process;
class BaseTransform : public IConfigTransform
{
public:
BaseTransform();
static void load(JsonChain &chain, Process *process, IConfigTransform &transform);
protected:
@@ -106,6 +104,8 @@ protected:
private:
void transformBoolean(rapidjson::Document &doc, int key, bool enable);
void transformUint64(rapidjson::Document &doc, int key, uint64_t arg);
bool m_http = false;
};

View File

@@ -26,7 +26,10 @@
#define XMRIG_ICLIENT_H
#include <stdint.h>
#include "rapidjson/fwd.h"
#include <functional>
namespace xmrig {
@@ -51,31 +54,35 @@ public:
EXT_MAX
};
using Callback = std::function<void(const rapidjson::Value &result, bool success, uint64_t elapsed)>;
virtual ~IClient() = default;
virtual bool disconnect() = 0;
virtual bool hasExtension(Extension extension) const noexcept = 0;
virtual bool isEnabled() const = 0;
virtual bool isTLS() const = 0;
virtual const char *mode() const = 0;
virtual const char *tlsFingerprint() const = 0;
virtual const char *tlsVersion() const = 0;
virtual const Job &job() const = 0;
virtual const Pool &pool() const = 0;
virtual const String &ip() const = 0;
virtual int id() const = 0;
virtual int64_t submit(const JobResult &result) = 0;
virtual void connect() = 0;
virtual void connect(const Pool &pool) = 0;
virtual void deleteLater() = 0;
virtual void setAlgo(const Algorithm &algo) = 0;
virtual void setEnabled(bool enabled) = 0;
virtual void setPool(const Pool &pool) = 0;
virtual void setQuiet(bool quiet) = 0;
virtual void setRetries(int retries) = 0;
virtual void setRetryPause(uint64_t ms) = 0;
virtual void tick(uint64_t now) = 0;
virtual bool disconnect() = 0;
virtual bool hasExtension(Extension extension) const noexcept = 0;
virtual bool isEnabled() const = 0;
virtual bool isTLS() const = 0;
virtual const char *mode() const = 0;
virtual const char *tlsFingerprint() const = 0;
virtual const char *tlsVersion() const = 0;
virtual const Job &job() const = 0;
virtual const Pool &pool() const = 0;
virtual const String &ip() const = 0;
virtual int id() const = 0;
virtual int64_t send(const rapidjson::Value &obj, Callback callback) = 0;
virtual int64_t send(const rapidjson::Value &obj) = 0;
virtual int64_t sequence() const = 0;
virtual int64_t submit(const JobResult &result) = 0;
virtual void connect() = 0;
virtual void connect(const Pool &pool) = 0;
virtual void deleteLater() = 0;
virtual void setAlgo(const Algorithm &algo) = 0;
virtual void setEnabled(bool enabled) = 0;
virtual void setPool(const Pool &pool) = 0;
virtual void setQuiet(bool quiet) = 0;
virtual void setRetries(int retries) = 0;
virtual void setRetryPause(uint64_t ms) = 0;
virtual void tick(uint64_t now) = 0;
};

View File

@@ -26,7 +26,7 @@
#define XMRIG_ICLIENTLISTENER_H
#include <stdint.h>
#include <cstdint>
#include "rapidjson/fwd.h"

View File

@@ -72,6 +72,7 @@ public:
ProxyDonateKey = 1017,
DaemonKey = 1018,
DaemonPollKey = 1019,
SelfSelectKey = 1028,
// xmrig common
CPUPriorityKey = 1021,
@@ -79,6 +80,7 @@ public:
PrintTimeKey = 1007,
// xmrig cpu
CPUKey = 1024,
AVKey = 'v',
CPUAffinityKey = 1020,
DryRunKey = 5000,
@@ -87,6 +89,8 @@ public:
AssemblyKey = 1015,
RandomXInitKey = 1022,
RandomXNumaKey = 1023,
CPUMaxThreadsKey = 1026,
MemoryPoolKey = 1027,
// xmrig amd
OclPlatformKey = 1400,
@@ -100,6 +104,7 @@ public:
OclMemChunkKey = 1408,
OclUnrollKey = 1409,
OclCompModeKey = 1410,
OclKey = 1411,
// xmrig-proxy
AccessLogFileKey = 'A',
@@ -129,6 +134,10 @@ public:
CudaLaunchKey = 1204,
CudaAffinityKey = 1205,
CudaMaxUsageKey = 1206,
CudaKey = 1207,
CudaLoaderKey = 1208,
NvmlKey = 1209,
HealthPrintTimeKey = 1210,
};
virtual ~IConfig() = default;

View File

@@ -78,9 +78,7 @@ private:
xmrig::HttpClient::HttpClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) :
HttpContext(HTTP_RESPONSE, listener),
m_quiet(false),
m_port(0)
HttpContext(HTTP_RESPONSE, listener)
{
this->method = method;
this->url = url;
@@ -127,7 +125,7 @@ void xmrig::HttpClient::onResolved(const Dns &dns, int status)
sockaddr *addr = dns.get().addr(m_port);
uv_connect_t *req = new uv_connect_t;
auto req = new uv_connect_t;
req->data = this;
uv_tcp_connect(req, m_tcp, addr, onConnect);
@@ -140,7 +138,7 @@ void xmrig::HttpClient::handshake()
headers.insert({ "Connection", "close" });
headers.insert({ "User-Agent", Platform::userAgent() });
if (body.size()) {
if (!body.empty()) {
headers.insert({ "Content-Length", std::to_string(body.size()) });
}
@@ -169,14 +167,14 @@ void xmrig::HttpClient::read(const char *data, size_t size)
void xmrig::HttpClient::write(const std::string &header)
{
ClientWriteBaton *baton = new ClientWriteBaton(header, std::move(body));
auto baton = new ClientWriteBaton(header, std::move(body));
uv_write(&baton->req, stream(), baton->bufs, baton->count(), ClientWriteBaton::onWrite);
}
void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
{
HttpClient *client = static_cast<HttpClient *>(req->data);
auto client = static_cast<HttpClient *>(req->data);
if (!client) {
delete req;
return;
@@ -205,7 +203,7 @@ void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
},
[](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
{
HttpClient *client = static_cast<HttpClient*>(tcp->data);
auto client = static_cast<HttpClient*>(tcp->data);
if (nread >= 0) {
client->read(buf->base, static_cast<size_t>(nread));

View File

@@ -30,6 +30,7 @@
#include "base/net/http/HttpContext.h"
#include "base/kernel/interfaces/IDnsListener.h"
#include "base/tools/Object.h"
namespace xmrig {
@@ -41,6 +42,8 @@ class String;
class HttpClient : public HttpContext, public IDnsListener
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpClient);
HttpClient(int method, const String &url, IHttpListener *listener, const char *data = nullptr, size_t size = 0);
~HttpClient() override;
@@ -57,13 +60,13 @@ protected:
virtual void read(const char *data, size_t size);
virtual void write(const std::string &header);
bool m_quiet;
bool m_quiet = false;
private:
static void onConnect(uv_connect_t *req, int status);
Dns *m_dns;
uint16_t m_port;
uint16_t m_port = 0;
};

View File

@@ -136,7 +136,7 @@ void xmrig::HttpContext::closeAll()
int xmrig::HttpContext::onHeaderField(http_parser *parser, const char *at, size_t length)
{
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
auto ctx = static_cast<HttpContext*>(parser->data);
if (ctx->m_wasHeaderValue) {
if (!ctx->m_lastHeaderField.empty()) {
@@ -155,7 +155,7 @@ int xmrig::HttpContext::onHeaderField(http_parser *parser, const char *at, size_
int xmrig::HttpContext::onHeaderValue(http_parser *parser, const char *at, size_t length)
{
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
auto ctx = static_cast<HttpContext*>(parser->data);
if (!ctx->m_wasHeaderValue) {
ctx->m_lastHeaderValue = std::string(at, length);
@@ -185,7 +185,7 @@ void xmrig::HttpContext::attach(http_parser_settings *settings)
settings->on_header_value = onHeaderValue;
settings->on_headers_complete = [](http_parser* parser) -> int {
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
auto ctx = static_cast<HttpContext*>(parser->data);
ctx->status = parser->status_code;
if (parser->type == HTTP_REQUEST) {
@@ -208,7 +208,7 @@ void xmrig::HttpContext::attach(http_parser_settings *settings)
settings->on_message_complete = [](http_parser *parser) -> int
{
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
auto ctx = static_cast<HttpContext*>(parser->data);
ctx->m_listener->onHttpData(*ctx);
ctx->m_listener = nullptr;

View File

@@ -28,15 +28,16 @@
#define XMRIG_HTTPCONTEXT_H
typedef struct http_parser http_parser;
typedef struct http_parser_settings http_parser_settings;
typedef struct uv_connect_s uv_connect_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_stream_s uv_stream_t;
typedef struct uv_tcp_s uv_tcp_t;
using http_parser = struct http_parser;
using http_parser_settings = struct http_parser_settings;
using uv_connect_t = struct uv_connect_s;
using uv_handle_t = struct uv_handle_s;
using uv_stream_t = struct uv_stream_s;
using uv_tcp_t = struct uv_tcp_s;
#include "base/net/http/HttpData.h"
#include "base/tools/Object.h"
namespace xmrig {
@@ -48,6 +49,8 @@ class IHttpListener;
class HttpContext : public HttpData
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpContext)
HttpContext(int parser_type, IHttpListener *listener);
virtual ~HttpContext();

View File

@@ -24,7 +24,7 @@
*/
#include <assert.h>
#include <cassert>
#include <openssl/ssl.h>
#include <uv.h>

View File

@@ -28,10 +28,10 @@
#define XMRIG_HTTPSCLIENT_H
typedef struct bio_st BIO;
typedef struct ssl_ctx_st SSL_CTX;
typedef struct ssl_st SSL;
typedef struct x509_st X509;
using BIO = struct bio_st;
using SSL_CTX = struct ssl_ctx_st;
using SSL = struct ssl_st;
using X509 = struct x509_st;
#include "base/net/http/HttpClient.h"
@@ -44,6 +44,8 @@ namespace xmrig {
class HttpsClient : public HttpClient
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpsClient)
HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint);
~HttpsClient() override;

View File

@@ -26,6 +26,7 @@
#include "base/kernel/interfaces/IClientListener.h"
#include "base/net/stratum/BaseClient.h"
#include "base/net/stratum/SubmitResult.h"
#include "rapidjson/document.h"
namespace xmrig {
@@ -36,18 +37,38 @@ int64_t BaseClient::m_sequence = 1;
xmrig::BaseClient::BaseClient(int id, IClientListener *listener) :
m_quiet(false),
m_listener(listener),
m_id(id),
m_retries(5),
m_failures(0),
m_state(UnconnectedState),
m_retryPause(5000),
m_enabled(true)
m_id(id)
{
}
bool xmrig::BaseClient::handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error)
{
if (id == 1) {
return false;
}
auto it = m_callbacks.find(id);
if (it != m_callbacks.end()) {
const uint64_t elapsed = Chrono::steadyMSecs() - it->second.ts;
if (error.IsObject()) {
it->second.callback(error, false, elapsed);
}
else {
it->second.callback(result, true, elapsed);
}
m_callbacks.erase(it);
return true;
}
return false;
}
bool xmrig::BaseClient::handleSubmitResponse(int64_t id, const char *error)
{
auto it = m_results.find(id);

View File

@@ -32,6 +32,7 @@
#include "base/kernel/interfaces/IClient.h"
#include "base/net/stratum/Job.h"
#include "base/net/stratum/Pool.h"
#include "base/tools/Chrono.h"
namespace xmrig {
@@ -46,11 +47,13 @@ class BaseClient : public IClient
public:
BaseClient(int id, IClientListener *listener);
protected:
inline bool isEnabled() const override { return m_enabled; }
inline const Job &job() const override { return m_job; }
inline const Pool &pool() const override { return m_pool; }
inline const String &ip() const override { return m_ip; }
inline int id() const override { return m_id; }
inline int64_t sequence() const override { return m_sequence; }
inline void setAlgo(const Algorithm &algo) override { m_pool.setAlgo(algo); }
inline void setEnabled(bool enabled) override { m_enabled = enabled; }
inline void setPool(const Pool &pool) override { if (pool.isValid()) { m_pool = pool; } }
@@ -68,26 +71,36 @@ protected:
ReconnectingState
};
struct SendResult
{
inline SendResult(Callback &&callback) : callback(callback), ts(Chrono::steadyMSecs()) {}
Callback callback;
const uint64_t ts;
};
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
bool handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
bool handleSubmitResponse(int64_t id, const char *error = nullptr);
bool m_quiet;
bool m_quiet = false;
IClientListener *m_listener;
int m_id;
int m_retries;
int64_t m_failures;
int m_retries = 5;
int64_t m_failures = 0;
Job m_job;
Pool m_pool;
SocketState m_state;
SocketState m_state = UnconnectedState;
std::map<int64_t, SendResult> m_callbacks;
std::map<int64_t, SubmitResult> m_results;
String m_ip;
uint64_t m_retryPause;
uint64_t m_retryPause = 5000;
static int64_t m_sequence;
private:
bool m_enabled;
bool m_enabled = true;
};

View File

@@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2019 jtgrassie <https://github.com/jtgrassie>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -22,11 +23,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <inttypes.h>
#include <cassert>
#include <cinttypes>
#include <iterator>
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include <utility>
@@ -136,6 +137,41 @@ const char *xmrig::Client::tlsVersion() const
}
int64_t xmrig::Client::send(const rapidjson::Value &obj, Callback callback)
{
assert(obj["id"] == sequence());
m_callbacks.insert({ sequence(), std::move(callback) });
return send(obj);
}
int64_t xmrig::Client::send(const rapidjson::Value &obj)
{
using namespace rapidjson;
Value value;
StringBuffer buffer(nullptr, 512);
Writer<StringBuffer> writer(buffer);
obj.Accept(writer);
const size_t size = buffer.GetSize();
if (size > (sizeof(m_sendBuf) - 2)) {
LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", url(), size, (sizeof(m_sendBuf) - 2));
close();
return -1;
}
memcpy(m_sendBuf, buffer.GetString(), size);
m_sendBuf[size] = '\n';
m_sendBuf[size + 1] = '\0';
return send(size + 1);
}
int64_t xmrig::Client::submit(const JobResult &result)
{
# ifndef XMRIG_PROXY_PROJECT
@@ -176,9 +212,9 @@ int64_t xmrig::Client::submit(const JobResult &result)
JsonRequest::create(doc, m_sequence, "submit", params);
# ifdef XMRIG_PROXY_PROJECT
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id, 0);
# else
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend);
# endif
return send(doc);
@@ -320,9 +356,23 @@ bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code)
return false;
}
if (!job.setBlob(params["blob"].GetString())) {
*code = 4;
return false;
# ifdef XMRIG_FEATURE_HTTP
if (m_pool.mode() == Pool::MODE_SELF_SELECT) {
job.setExtraNonce(Json::getString(params, "extra_nonce"));
job.setPoolWallet(Json::getString(params, "pool_wallet"));
if (job.extraNonce().isNull() || job.poolWallet().isNull()) {
*code = 4;
return false;
}
}
else
# endif
{
if (!job.setBlob(params["blob"].GetString())) {
*code = 4;
return false;
}
}
if (!job.setTarget(params["target"].GetString())) {
@@ -345,7 +395,7 @@ bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code)
return false;
}
if (job.algorithm().family() == Algorithm::RANDOM_X && !job.setSeedHash(Json::getString(params, "seed_hash"))) {
if (m_pool.mode() != Pool::MODE_SELF_SELECT && job.algorithm().family() == Algorithm::RANDOM_X && !job.setSeedHash(Json::getString(params, "seed_hash"))) {
if (!isQuiet()) {
LOG_ERR("[%s] failed to parse field \"seed_hash\" required by RandomX", url(), algo);
}
@@ -473,29 +523,6 @@ int xmrig::Client::resolve(const String &host)
}
int64_t xmrig::Client::send(const rapidjson::Document &doc)
{
using namespace rapidjson;
StringBuffer buffer(nullptr, 512);
Writer<StringBuffer> writer(buffer);
doc.Accept(writer);
const size_t size = buffer.GetSize();
if (size > (sizeof(m_sendBuf) - 2)) {
LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", url(), size, (sizeof(m_sendBuf) - 2));
close();
return -1;
}
memcpy(m_sendBuf, buffer.GetString(), size);
m_sendBuf[size] = '\n';
m_sendBuf[size + 1] = '\0';
return send(size + 1);
}
int64_t xmrig::Client::send(size_t size)
{
LOG_DEBUG("[%s] send (%d bytes): \"%.*s\"", url(), size, static_cast<int>(size) - 1, m_sendBuf);
@@ -719,6 +746,10 @@ void xmrig::Client::parseNotification(const char *method, const rapidjson::Value
void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error)
{
if (handleResponse(id, result, error)) {
return;
}
if (error.IsObject()) {
const char *message = error["message"].GetString();
@@ -908,8 +939,14 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status)
LOG_ERR("[%s] connect error: \"%s\"", client->url(), uv_strerror(status));
}
if (client->state() == ReconnectingState) {
return;
}
if (client->state() != ConnectingState) {
LOG_ERR("[%s] connect error: \"invalid state: %d\"", client->url(), client->state());
if (!client->isQuiet()) {
LOG_ERR("[%s] connect error: \"invalid state: %d\"", client->url(), client->state());
}
return;
}

View File

@@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2019 jtgrassie <https://github.com/jtgrassie>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -40,10 +41,11 @@
#include "base/net/stratum/SubmitResult.h"
#include "base/net/tools/RecvBuf.h"
#include "base/net/tools/Storage.h"
#include "base/tools/Object.h"
#include "crypto/common/Algorithm.h"
typedef struct bio_st BIO;
using BIO = struct bio_st;
namespace xmrig {
@@ -56,6 +58,8 @@ class JobResult;
class Client : public BaseClient, public IDnsListener, public ILineListener
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Client)
constexpr static uint64_t kConnectTimeout = 20 * 1000;
constexpr static uint64_t kResponseTimeout = 20 * 1000;
@@ -73,6 +77,8 @@ protected:
bool isTLS() const override;
const char *tlsFingerprint() const override;
const char *tlsVersion() const override;
int64_t send(const rapidjson::Value &obj, Callback callback) override;
int64_t send(const rapidjson::Value &obj) override;
int64_t submit(const JobResult &result) override;
void connect() override;
void connect(const Pool &pool) override;
@@ -95,7 +101,6 @@ private:
bool send(BIO *bio);
bool verifyAlgorithm(const Algorithm &algorithm, const char *algo) const;
int resolve(const String &host);
int64_t send(const rapidjson::Document &doc);
int64_t send(size_t size);
void connect(sockaddr *addr);
void handshake();

View File

@@ -117,9 +117,9 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result)
JsonRequest::create(doc, m_sequence, "submitblock", params);
# ifdef XMRIG_PROXY_PROJECT
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id, 0);
# else
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend);
# endif
send(HTTP_POST, kJsonRPC, doc);

View File

@@ -27,9 +27,10 @@
#define XMRIG_DAEMONCLIENT_H
#include "base/net/stratum/BaseClient.h"
#include "base/kernel/interfaces/ITimerListener.h"
#include "base/kernel/interfaces/IHttpListener.h"
#include "base/kernel/interfaces/ITimerListener.h"
#include "base/net/stratum/BaseClient.h"
#include "base/tools/Object.h"
namespace xmrig {
@@ -38,6 +39,8 @@ namespace xmrig {
class DaemonClient : public BaseClient, public ITimerListener, public IHttpListener
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(DaemonClient)
DaemonClient(int id, IClientListener *listener);
~DaemonClient() override;
@@ -51,12 +54,14 @@ protected:
void onHttpData(const HttpData &data) override;
void onTimer(const Timer *timer) override;
inline bool hasExtension(Extension) const noexcept override { return false; }
inline const char *mode() const override { return "daemon"; }
inline const char *tlsFingerprint() const override { return m_tlsFingerprint; }
inline const char *tlsVersion() const override { return m_tlsVersion; }
inline void deleteLater() override { delete this; }
inline void tick(uint64_t) override {}
inline bool hasExtension(Extension) const noexcept override { return false; }
inline const char *mode() const override { return "daemon"; }
inline const char *tlsFingerprint() const override { return m_tlsFingerprint; }
inline const char *tlsVersion() const override { return m_tlsVersion; }
inline int64_t send(const rapidjson::Value &, Callback) override { return -1; }
inline int64_t send(const rapidjson::Value &) override { return -1; }
inline void deleteLater() override { delete this; }
inline void tick(uint64_t) override {}
private:
bool isOutdated(uint64_t height, const char *hash) const;

View File

@@ -25,32 +25,18 @@
*/
#include <assert.h>
#include <string.h>
#include <cassert>
#include <cstring>
#include "base/net/stratum/Job.h"
#include "base/tools/Buffer.h"
xmrig::Job::Job() :
m_blob(),
m_seedHash()
{
}
xmrig::Job::Job(bool nicehash, const Algorithm &algorithm, const String &clientId) :
m_algorithm(algorithm),
m_nicehash(nicehash),
m_clientId(clientId),
m_blob(),
m_seedHash()
{
}
xmrig::Job::~Job()
m_clientId(clientId)
{
}
@@ -96,7 +82,7 @@ bool xmrig::Job::setBlob(const char *blob)
bool xmrig::Job::setSeedHash(const char *hash)
{
if (!hash || (strlen(hash) != sizeof(m_seedHash) * 2)) {
if (!hash || (strlen(hash) != kMaxSeedSize * 2)) {
return false;
}
@@ -104,7 +90,9 @@ bool xmrig::Job::setSeedHash(const char *hash)
m_rawSeedHash = hash;
# endif
return Buffer::fromHex(hash, sizeof(m_seedHash) * 2, m_seedHash);
m_seed = Buffer::fromHex(hash, kMaxSeedSize * 2);
return !m_seed.isEmpty();
}
@@ -164,18 +152,21 @@ void xmrig::Job::setDiff(uint64_t diff)
void xmrig::Job::copy(const Job &other)
{
m_algorithm = other.m_algorithm;
m_nicehash = other.m_nicehash;
m_size = other.m_size;
m_clientId = other.m_clientId;
m_id = other.m_id;
m_diff = other.m_diff;
m_height = other.m_height;
m_target = other.m_target;
m_index = other.m_index;
m_algorithm = other.m_algorithm;
m_nicehash = other.m_nicehash;
m_size = other.m_size;
m_clientId = other.m_clientId;
m_id = other.m_id;
m_backend = other.m_backend;
m_diff = other.m_diff;
m_height = other.m_height;
m_target = other.m_target;
m_index = other.m_index;
m_seed = other.m_seed;
m_extraNonce = other.m_extraNonce;
m_poolWallet = other.m_poolWallet;
memcpy(m_blob, other.m_blob, sizeof(m_blob));
memcpy(m_seedHash, other.m_seedHash, sizeof(m_seedHash));
# ifdef XMRIG_PROXY_PROJECT
m_rawSeedHash = other.m_rawSeedHash;
@@ -184,3 +175,34 @@ void xmrig::Job::copy(const Job &other)
memcpy(m_rawTarget, other.m_rawTarget, sizeof(m_rawTarget));
# endif
}
void xmrig::Job::move(Job &&other)
{
m_algorithm = other.m_algorithm;
m_nicehash = other.m_nicehash;
m_size = other.m_size;
m_clientId = std::move(other.m_clientId);
m_id = std::move(other.m_id);
m_backend = other.m_backend;
m_diff = other.m_diff;
m_height = other.m_height;
m_target = other.m_target;
m_index = other.m_index;
m_seed = std::move(other.m_seed);
m_extraNonce = std::move(other.m_extraNonce);
m_poolWallet = std::move(other.m_poolWallet);
memcpy(m_blob, other.m_blob, sizeof(m_blob));
other.m_size = 0;
other.m_diff = 0;
other.m_algorithm = Algorithm::INVALID;
# ifdef XMRIG_PROXY_PROJECT
m_rawSeedHash = std::move(other.m_rawSeedHash);
memcpy(m_rawBlob, other.m_rawBlob, sizeof(m_rawBlob));
memcpy(m_rawTarget, other.m_rawTarget, sizeof(m_rawTarget));
# endif
}

View File

@@ -28,10 +28,11 @@
#define XMRIG_JOB_H
#include <stddef.h>
#include <stdint.h>
#include <cstddef>
#include <cstdint>
#include "base/tools/Buffer.h"
#include "base/tools/String.h"
#include "crypto/common/Algorithm.h"
@@ -45,10 +46,15 @@ public:
// Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
// SECOR increase requirements for blob size: https://github.com/xmrig/xmrig/issues/913
static constexpr const size_t kMaxBlobSize = 128;
static constexpr const size_t kMaxSeedSize = 32;
Job();
Job() = default;
Job(bool nicehash, const Algorithm &algorithm, const String &clientId);
~Job();
inline Job(const Job &other) { copy(other); }
inline Job(Job &&other) noexcept { move(std::move(other)); }
~Job() = default;
bool isEqual(const Job &other) const;
bool setBlob(const char *blob);
@@ -56,28 +62,34 @@ public:
bool setTarget(const char *target);
void setDiff(uint64_t diff);
inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
inline bool setId(const char *id) { return m_id = id; }
inline const Algorithm &algorithm() const { return m_algorithm; }
inline const String &clientId() const { return m_clientId; }
inline const String &id() const { return m_id; }
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
inline const uint8_t *blob() const { return m_blob; }
inline const uint8_t *seedHash() const { return m_seedHash; }
inline size_t size() const { return m_size; }
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
inline uint64_t diff() const { return m_diff; }
inline uint64_t height() const { return m_height; }
inline uint64_t target() const { return m_target; }
inline uint8_t fixedByte() const { return *(m_blob + 42); }
inline uint8_t index() const { return m_index; }
inline void reset() { m_size = 0; m_diff = 0; }
inline void setAlgorithm(const Algorithm::Id id) { m_algorithm = id; }
inline void setAlgorithm(const char *algo) { m_algorithm = algo; }
inline void setClientId(const String &id) { m_clientId = id; }
inline void setHeight(uint64_t height) { m_height = height; }
inline void setIndex(uint8_t index) { m_index = index; }
inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
inline bool setId(const char *id) { return m_id = id; }
inline const Algorithm &algorithm() const { return m_algorithm; }
inline const Buffer &seed() const { return m_seed; }
inline const String &clientId() const { return m_clientId; }
inline const String &extraNonce() const { return m_extraNonce; }
inline const String &id() const { return m_id; }
inline const String &poolWallet() const { return m_poolWallet; }
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
inline const uint8_t *blob() const { return m_blob; }
inline size_t size() const { return m_size; }
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
inline uint32_t backend() const { return m_backend; }
inline uint64_t diff() const { return m_diff; }
inline uint64_t height() const { return m_height; }
inline uint64_t target() const { return m_target; }
inline uint8_t fixedByte() const { return *(m_blob + 42); }
inline uint8_t index() const { return m_index; }
inline void reset() { m_size = 0; m_diff = 0; }
inline void setAlgorithm(const Algorithm::Id id) { m_algorithm = id; }
inline void setAlgorithm(const char *algo) { m_algorithm = algo; }
inline void setBackend(uint32_t backend) { m_backend = backend; }
inline void setClientId(const String &id) { m_clientId = id; }
inline void setExtraNonce(const String &extraNonce) { m_extraNonce = extraNonce; }
inline void setHeight(uint64_t height) { m_height = height; }
inline void setIndex(uint8_t index) { m_index = index; }
inline void setPoolWallet(const String &poolWallet) { m_poolWallet = poolWallet; }
# ifdef XMRIG_PROXY_PROJECT
inline char *rawBlob() { return m_rawBlob; }
@@ -89,28 +101,33 @@ public:
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; }
inline bool operator==(const Job &other) const { return isEqual(other); }
inline bool operator!=(const Job &other) const { return !isEqual(other); }
inline bool operator==(const Job &other) const { return isEqual(other); }
inline Job &operator=(const Job &other) { copy(other); return *this; }
inline Job &operator=(Job &&other) noexcept { move(std::move(other)); return *this; }
private:
void copy(const Job &other);
void move(Job &&other);
Algorithm m_algorithm;
bool m_nicehash = false;
Buffer m_seed;
size_t m_size = 0;
String m_clientId;
String m_extraNonce;
String m_id;
String m_poolWallet;
uint32_t m_backend = 0;
uint64_t m_diff = 0;
uint64_t m_height = 0;
uint64_t m_target = 0;
uint8_t m_blob[kMaxBlobSize];
uint8_t m_blob[kMaxBlobSize]{ 0 };
uint8_t m_index = 0;
uint8_t m_seedHash[32];
# ifdef XMRIG_PROXY_PROJECT
char m_rawBlob[kMaxBlobSize * 2 + 8];
char m_rawTarget[24];
char m_rawBlob[kMaxBlobSize * 2 + 8]{};
char m_rawTarget[24]{};
String m_rawSeedHash;
# endif
};

View File

@@ -24,24 +24,24 @@
*/
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <cassert>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <string>
#include "base/io/json/Json.h"
#include "base/net/stratum/Pool.h"
#include "base/io/json/Json.h"
#include "base/io/log/Log.h"
#include "base/kernel/Platform.h"
#include "base/net/stratum/Client.h"
#include "rapidjson/document.h"
#ifdef APP_DEBUG
# include "base/io/log/Log.h"
#endif
#ifdef _MSC_VER
# define strncasecmp _strnicmp
#ifdef XMRIG_FEATURE_HTTP
# include "base/net/stratum/DaemonClient.h"
# include "base/net/stratum/SelfSelectClient.h"
#endif
@@ -57,6 +57,7 @@ static const char *kKeepalive = "keepalive";
static const char *kNicehash = "nicehash";
static const char *kPass = "pass";
static const char *kRigId = "rig-id";
static const char *kSelfSelect = "self-select";
static const char *kTls = "tls";
static const char *kUrl = "url";
static const char *kUser = "user";
@@ -64,54 +65,23 @@ static const char *kUser = "user";
const String Pool::kDefaultPassword = "x";
const String Pool::kDefaultUser = "x";
static const char kStratumTcp[] = "stratum+tcp://";
static const char kStratumSsl[] = "stratum+ssl://";
#ifdef XMRIG_FEATURE_HTTP
static const char kDaemonHttp[] = "daemon+http://";
static const char kDaemonHttps[] = "daemon+https://";
#endif
}
xmrig::Pool::Pool() :
m_keepAlive(0),
m_flags(0),
m_port(kDefaultPort),
m_pollInterval(kDefaultPollInterval)
{
}
/**
* @brief Parse url.
*
* Valid urls:
* example.com
* example.com:3333
* stratum+tcp://example.com
* stratum+tcp://example.com:3333
*
* @param url
*/
xmrig::Pool::Pool(const char *url) :
m_keepAlive(0),
m_flags(1),
m_port(kDefaultPort),
m_pollInterval(kDefaultPollInterval)
m_flags(1 << FLAG_ENABLED),
m_pollInterval(kDefaultPollInterval),
m_url(url)
{
parse(url);
}
xmrig::Pool::Pool(const rapidjson::Value &object) :
m_keepAlive(0),
m_flags(1),
m_port(kDefaultPort),
m_pollInterval(kDefaultPollInterval)
m_flags(1 << FLAG_ENABLED),
m_pollInterval(kDefaultPollInterval),
m_url(Json::getString(object, kUrl))
{
if (!parse(Json::getString(object, kUrl))) {
if (!m_url.isValid()) {
return;
}
@@ -122,11 +92,18 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval);
m_algorithm = Json::getString(object, kAlgo);
m_coin = Json::getString(object, kCoin);
m_daemon = Json::getString(object, kSelfSelect);
m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true));
m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash));
m_flags.set(FLAG_TLS, Json::getBool(object, kTls, m_flags.test(FLAG_TLS)));
m_flags.set(FLAG_DAEMON, Json::getBool(object, kDaemon, m_flags.test(FLAG_DAEMON)));
m_flags.set(FLAG_TLS, Json::getBool(object, kTls) || m_url.isTLS());
if (m_daemon.isValid()) {
m_mode = MODE_SELF_SELECT;
}
else if (Json::getBool(object, kDaemon)) {
m_mode = MODE_DAEMON;
}
const rapidjson::Value &keepalive = Json::getValue(object, kKeepalive);
if (keepalive.IsInt()) {
@@ -140,21 +117,12 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls) :
m_keepAlive(keepAlive),
m_flags(1),
m_host(host),
m_flags(1 << FLAG_ENABLED),
m_password(password),
m_user(user),
m_port(port),
m_pollInterval(kDefaultPollInterval)
m_pollInterval(kDefaultPollInterval),
m_url(host, port, tls)
{
const size_t size = m_host.size() + 8;
assert(size > 8);
char *url = new char[size]();
snprintf(url, size - 1, "%s:%d", m_host.data(), m_port);
m_url = url;
m_flags.set(FLAG_NICEHASH, nicehash);
m_flags.set(FLAG_TLS, tls);
}
@@ -169,12 +137,18 @@ bool xmrig::Pool::isEnabled() const
# endif
# ifndef XMRIG_FEATURE_HTTP
if (isDaemon()) {
if (m_mode == MODE_DAEMON) {
return false;
}
# endif
if (isDaemon() && (!algorithm().isValid() && !coin().isValid())) {
# ifndef XMRIG_FEATURE_HTTP
if (m_mode == MODE_SELF_SELECT) {
return false;
}
# endif
if (m_mode == MODE_DAEMON && (!algorithm().isValid() && !coin().isValid())) {
return false;
}
@@ -186,79 +160,43 @@ bool xmrig::Pool::isEqual(const Pool &other) const
{
return (m_flags == other.m_flags
&& m_keepAlive == other.m_keepAlive
&& m_port == other.m_port
&& m_algorithm == other.m_algorithm
&& m_coin == other.m_coin
&& m_mode == other.m_mode
&& m_fingerprint == other.m_fingerprint
&& m_host == other.m_host
&& m_password == other.m_password
&& m_rigId == other.m_rigId
&& m_url == other.m_url
&& m_user == other.m_user
&& m_pollInterval == other.m_pollInterval
&& m_daemon == other.m_daemon
);
}
bool xmrig::Pool::parse(const char *url)
xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) const
{
assert(url != nullptr);
if (url == nullptr) {
return false;
IClient *client = nullptr;
if (m_mode == MODE_POOL) {
client = new Client(id, Platform::userAgent(), listener);
}
# ifdef XMRIG_FEATURE_HTTP
else if (m_mode == MODE_DAEMON) {
client = new DaemonClient(id, listener);
}
else if (m_mode == MODE_SELF_SELECT) {
client = new SelfSelectClient(id, Platform::userAgent(), listener);
}
# endif
assert(client != nullptr);
if (client) {
client->setPool(*this);
}
const char *p = strstr(url, "://");
const char *base = url;
if (p) {
if (strncasecmp(url, kStratumTcp, sizeof(kStratumTcp) - 1) == 0) {
m_flags.set(FLAG_DAEMON, false);
m_flags.set(FLAG_TLS, false);
}
else if (strncasecmp(url, kStratumSsl, sizeof(kStratumSsl) - 1) == 0) {
m_flags.set(FLAG_DAEMON, false);
m_flags.set(FLAG_TLS, true);
}
# ifdef XMRIG_FEATURE_HTTP
else if (strncasecmp(url, kDaemonHttps, sizeof(kDaemonHttps) - 1) == 0) {
m_flags.set(FLAG_DAEMON, true);
m_flags.set(FLAG_TLS, true);
}
else if (strncasecmp(url, kDaemonHttp, sizeof(kDaemonHttp) - 1) == 0) {
m_flags.set(FLAG_DAEMON, true);
m_flags.set(FLAG_TLS, false);
}
# endif
else {
return false;
}
base = p + 3;
}
if (!strlen(base) || *base == '/') {
return false;
}
m_url = url;
if (base[0] == '[') {
return parseIPv6(base);
}
const char *port = strchr(base, ':');
if (!port) {
m_host = base;
return true;
}
const size_t size = static_cast<size_t>(port++ - base + 1);
char *host = new char[size]();
memcpy(host, base, size - 1);
m_host = host;
m_port = static_cast<uint16_t>(strtol(port, nullptr, 10));
return true;
return client;
}
@@ -272,10 +210,10 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator);
obj.AddMember(StringRef(kCoin), m_coin.toJSON(), allocator);
obj.AddMember(StringRef(kUrl), m_url.toJSON(), allocator);
obj.AddMember(StringRef(kUrl), url().toJSON(), allocator);
obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator);
if (!isDaemon()) {
if (m_mode != MODE_DAEMON) {
obj.AddMember(StringRef(kPass), m_password.toJSON(), allocator);
obj.AddMember(StringRef(kRigId), m_rigId.toJSON(), allocator);
@@ -294,22 +232,44 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator);
obj.AddMember(StringRef(kTls), isTLS(), allocator);
obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator);
obj.AddMember(StringRef(kDaemon), m_flags.test(FLAG_DAEMON), allocator);
obj.AddMember(StringRef(kDaemon), m_mode == MODE_DAEMON, allocator);
if (isDaemon()) {
if (m_mode == MODE_DAEMON) {
obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator);
}
else {
obj.AddMember(StringRef(kSelfSelect), m_daemon.url().toJSON(), allocator);
}
return obj;
}
std::string xmrig::Pool::printableName() const
{
std::string out(CSI "1;" + std::to_string(isEnabled() ? (isTLS() ? 32 : 36) : 31) + "m" + url().data() + CLEAR);
if (m_coin.isValid()) {
out += std::string(" coin ") + WHITE_BOLD_S + m_coin.name() + CLEAR;
}
else {
out += std::string(" algo ") + WHITE_BOLD_S + (m_algorithm.isValid() ? m_algorithm.shortName() : "auto") + CLEAR;
}
if (m_mode == MODE_SELF_SELECT) {
out += std::string(" self-select ") + CSI "1;" + std::to_string(m_daemon.isTLS() ? 32 : 36) + "m" + m_daemon.url().data() + CLEAR;
}
return out;
}
#ifdef APP_DEBUG
void xmrig::Pool::print() const
{
LOG_NOTICE("url: %s", m_url.data());
LOG_DEBUG ("host: %s", m_host.data());
LOG_DEBUG ("port: %d", static_cast<int>(m_port));
LOG_NOTICE("url: %s", url().data());
LOG_DEBUG ("host: %s", host().data());
LOG_DEBUG ("port: %d", static_cast<int>(port()));
LOG_DEBUG ("user: %s", m_user.data());
LOG_DEBUG ("pass: %s", m_password.data());
LOG_DEBUG ("rig-id %s", m_rigId.data());
@@ -318,26 +278,3 @@ void xmrig::Pool::print() const
LOG_DEBUG ("keepAlive: %d", m_keepAlive);
}
#endif
bool xmrig::Pool::parseIPv6(const char *addr)
{
const char *end = strchr(addr, ']');
if (!end) {
return false;
}
const char *port = strchr(end, ':');
if (!port) {
return false;
}
const size_t size = static_cast<size_t>(end - addr);
char *host = new char[size]();
memcpy(host, addr + 1, size - 1);
m_host = host;
m_port = static_cast<uint16_t>(strtol(port + 1, nullptr, 10));
return true;
}

View File

@@ -31,7 +31,7 @@
#include <vector>
#include "base/tools/String.h"
#include "base/net/stratum/Url.h"
#include "crypto/common/Coin.h"
#include "rapidjson/fwd.h"
@@ -39,15 +39,17 @@
namespace xmrig {
class IClient;
class IClientListener;
class Pool
{
public:
enum Flags {
FLAG_ENABLED,
FLAG_NICEHASH,
FLAG_TLS,
FLAG_DAEMON,
FLAG_MAX
enum Mode {
MODE_POOL,
MODE_DAEMON,
MODE_SELF_SELECT
};
static const String kDefaultPassword;
@@ -57,7 +59,7 @@ public:
constexpr static uint16_t kDefaultPort = 3333;
constexpr static uint64_t kDefaultPollInterval = 1000;
Pool();
Pool() = default;
Pool(const char *url);
Pool(const rapidjson::Value &object);
Pool(const char *host,
@@ -69,20 +71,21 @@ public:
bool tls = false
);
inline bool isDaemon() const { return m_flags.test(FLAG_DAEMON); }
inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); }
inline bool isTLS() const { return m_flags.test(FLAG_TLS); }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
inline bool isValid() const { return m_url.isValid(); }
inline const Algorithm &algorithm() const { return m_algorithm; }
inline const Coin &coin() const { return m_coin; }
inline const String &fingerprint() const { return m_fingerprint; }
inline const String &host() const { return m_host; }
inline const String &host() const { return m_url.host(); }
inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; }
inline const String &rigId() const { return m_rigId; }
inline const String &url() const { return m_url; }
inline const String &url() const { return m_url.url(); }
inline const String &user() const { return !m_user.isNull() ? m_user : kDefaultUser; }
inline const Url &daemon() const { return m_daemon; }
inline int keepAlive() const { return m_keepAlive; }
inline uint16_t port() const { return m_port; }
inline Mode mode() const { return m_mode; }
inline uint16_t port() const { return m_url.port(); }
inline uint64_t pollInterval() const { return m_pollInterval; }
inline void setAlgo(const Algorithm &algorithm) { m_algorithm = algorithm; }
inline void setPassword(const String &password) { m_password = password; }
@@ -94,31 +97,37 @@ public:
bool isEnabled() const;
bool isEqual(const Pool &other) const;
bool parse(const char *url);
IClient *createClient(int id, IClientListener *listener) const;
rapidjson::Value toJSON(rapidjson::Document &doc) const;
std::string printableName() const;
# ifdef APP_DEBUG
void print() const;
# endif
private:
enum Flags {
FLAG_ENABLED,
FLAG_NICEHASH,
FLAG_TLS,
FLAG_MAX
};
inline void setKeepAlive(bool enable) { setKeepAlive(enable ? kKeepAliveTimeout : 0); }
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
bool parseIPv6(const char *addr);
Algorithm m_algorithm;
Coin m_coin;
int m_keepAlive;
std::bitset<FLAG_MAX> m_flags;
int m_keepAlive = 0;
Mode m_mode = MODE_POOL;
std::bitset<FLAG_MAX> m_flags = 0;
String m_fingerprint;
String m_host;
String m_password;
String m_rigId;
String m_url;
String m_user;
uint16_t m_port;
uint64_t m_pollInterval;
uint64_t m_pollInterval = kDefaultPollInterval;
Url m_daemon;
Url m_url;
};

View File

@@ -65,7 +65,7 @@ xmrig::IStrategy *xmrig::Pools::createStrategy(IStrategyListener *listener) cons
}
}
FailoverStrategy *strategy = new FailoverStrategy(retryPause(), retries(), listener);
auto strategy = new FailoverStrategy(retryPause(), retries(), listener);
for (const Pool &pool : m_data) {
if (pool.isEnabled()) {
strategy->add(pool);
@@ -135,13 +135,7 @@ void xmrig::Pools::print() const
{
size_t i = 1;
for (const Pool &pool : m_data) {
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " %s " WHITE_BOLD("%s"),
i,
(pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31),
pool.url().data(),
pool.coin().isValid() ? "coin" : "algo",
pool.coin().isValid() ? pool.coin().name() : (pool.algorithm().isValid() ? pool.algorithm().shortName() : "auto")
);
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") "%s", i, pool.printableName().c_str());
i++;
}

View File

@@ -0,0 +1,306 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2019 jtgrassie <https://github.com/jtgrassie>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/net/stratum/SelfSelectClient.h"
#include "3rdparty/http-parser/http_parser.h"
#include "base/io/json/Json.h"
#include "base/io/json/JsonRequest.h"
#include "base/io/log/Log.h"
#include "base/net/http/HttpClient.h"
#include "base/net/stratum/Client.h"
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#ifdef XMRIG_FEATURE_TLS
# include "base/net/http/HttpsClient.h"
#endif
namespace xmrig {
static const char *kBlob = "blob";
static const char *kBlockhashingBlob = "blockhashing_blob";
static const char *kBlocktemplateBlob = "blocktemplate_blob";
static const char *kDifficulty = "difficulty";
static const char *kHeight = "height";
static const char *kId = "id";
static const char *kJobId = "job_id";
static const char *kNextSeedHash = "next_seed_hash";
static const char *kPrevHash = "prev_hash";
static const char *kSeedHash = "seed_hash";
static const char * const required_fields[] = { kBlocktemplateBlob, kBlockhashingBlob, kHeight, kDifficulty, kPrevHash };
} /* namespace xmrig */
xmrig::SelfSelectClient::SelfSelectClient(int id, const char *agent, IClientListener *listener) :
m_listener(listener)
{
m_client = new Client(id, agent, this);
}
xmrig::SelfSelectClient::~SelfSelectClient()
{
delete m_client;
}
void xmrig::SelfSelectClient::tick(uint64_t now)
{
m_client->tick(now);
if (m_state == RetryState) {
if (Chrono::steadyMSecs() - m_timestamp < m_retryPause) {
return;
}
getBlockTemplate();
}
}
void xmrig::SelfSelectClient::onJobReceived(IClient *, const Job &job, const rapidjson::Value &)
{
m_job = job;
getBlockTemplate();
}
void xmrig::SelfSelectClient::onLogin(IClient *, rapidjson::Document &doc, rapidjson::Value &params)
{
params.AddMember("mode", "self-select", doc.GetAllocator());
m_listener->onLogin(this, doc, params);
}
bool xmrig::SelfSelectClient::parseResponse(int64_t id, rapidjson::Value &result, const rapidjson::Value &error)
{
if (id == -1) {
return false;
}
if (error.IsObject()) {
LOG_ERR("[%s] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", pool().daemon().url().data(), Json::getString(error, "message"), Json::getInt(error, "code"));
return false;
}
if (!result.IsObject()) {
return false;
}
for (auto field : required_fields) {
if (!result.HasMember(field)) {
LOG_ERR("[%s] required field " RED_BOLD("\"%s\"") RED_S " not found", pool().daemon().url().data(), field);
return false;
}
}
if (!m_job.setBlob(result[kBlockhashingBlob].GetString())) {
return false;
}
if (pool().coin().isValid()) {
m_job.setAlgorithm(pool().coin().algorithm(m_job.blob()[0]));
}
m_job.setHeight(Json::getUint64(result, kHeight));
m_job.setSeedHash(Json::getString(result, kSeedHash));
submitBlockTemplate(result);
return true;
}
void xmrig::SelfSelectClient::getBlockTemplate()
{
setState(WaitState);
using namespace rapidjson;
Document doc(kObjectType);
auto &allocator = doc.GetAllocator();
Value params(kObjectType);
params.AddMember("wallet_address", m_job.poolWallet().toJSON(), allocator);
params.AddMember("extra_nonce", m_job.extraNonce().toJSON(), allocator);
JsonRequest::create(doc, m_sequence++, "getblocktemplate", params);
send(HTTP_POST, "/json_rpc", doc);
}
void xmrig::SelfSelectClient::retry()
{
setState(RetryState);
}
void xmrig::SelfSelectClient::send(int method, const char *url, const char *data, size_t size)
{
LOG_DEBUG("[%s] " MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD_S " send (%zu bytes): \"%.*s\"",
pool().daemon().url().data(),
http_method_str(static_cast<http_method>(method)),
url,
size,
static_cast<int>(size),
data);
HttpClient *client;
# ifdef XMRIG_FEATURE_TLS
if (pool().daemon().isTLS()) {
client = new HttpsClient(method, url, this, data, size, String());
}
else
# endif
{
client = new HttpClient(method, url, this, data, size);
}
client->setQuiet(isQuiet());
client->connect(pool().daemon().host(), pool().daemon().port());
}
void xmrig::SelfSelectClient::send(int method, const char *url, const rapidjson::Document &doc)
{
using namespace rapidjson;
StringBuffer buffer(nullptr, 512);
Writer<StringBuffer> writer(buffer);
doc.Accept(writer);
send(method, url, buffer.GetString(), buffer.GetSize());
}
void xmrig::SelfSelectClient::setState(State state)
{
if (m_state == state) {
return;
}
switch (state) {
case IdleState:
m_timestamp = 0;
m_failures = 0;
break;
case WaitState:
m_timestamp = Chrono::steadyMSecs();
break;
case RetryState:
m_timestamp = Chrono::steadyMSecs();
if (m_failures > m_retries) {
m_listener->onClose(this, static_cast<int>(m_failures));
}
m_failures++;
break;
}
m_state = state;
}
void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result)
{
using namespace rapidjson;
Document doc(kObjectType);
auto &allocator = doc.GetAllocator();
Value params(kObjectType);
params.AddMember(StringRef(kId), m_job.clientId().toJSON(), allocator);
params.AddMember(StringRef(kJobId), m_job.id().toJSON(), allocator);
params.AddMember(StringRef(kBlob), result[kBlocktemplateBlob], allocator);
params.AddMember(StringRef(kHeight), m_job.height(), allocator);
params.AddMember(StringRef(kDifficulty), result[kDifficulty], allocator);
params.AddMember(StringRef(kPrevHash), result[kPrevHash], allocator);
params.AddMember(StringRef(kSeedHash), result[kSeedHash], allocator);
params.AddMember(StringRef(kNextSeedHash), result[kNextSeedHash], allocator);
JsonRequest::create(doc, sequence(), "block_template", params);
send(doc, [this](const rapidjson::Value &result, bool success, uint64_t elapsed) {
if (!success) {
if (!isQuiet()) {
LOG_ERR("[%s] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", pool().daemon().url().data(), Json::getString(result, "message"), Json::getInt(result, "code"));
}
return retry();
}
if (!m_active) {
return;
}
if (m_failures > m_retries) {
m_listener->onLoginSuccess(this);
}
setState(IdleState);
m_listener->onJobReceived(this, m_job, rapidjson::Value{});
});
}
void xmrig::SelfSelectClient::onHttpData(const HttpData &data)
{
if (data.status != HTTP_STATUS_OK) {
return retry();
}
LOG_DEBUG("[%s] received (%d bytes): \"%.*s\"", pool().daemon().url().data(), static_cast<int>(data.body.size()), static_cast<int>(data.body.size()), data.body.c_str());
rapidjson::Document doc;
if (doc.Parse(data.body.c_str()).HasParseError()) {
if (!isQuiet()) {
LOG_ERR("[%s] JSON decode failed: \"%s\"", pool().daemon().url().data(), rapidjson::GetParseError_En(doc.GetParseError()));
}
return retry();
}
const int64_t id = Json::getInt64(doc, "id", -1);
if (id > 0 && m_sequence - id != 1) {
return;
}
if (!parseResponse(id, doc["result"], Json::getObject(doc, "error"))) {
retry();
}
}

View File

@@ -0,0 +1,123 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2019 jtgrassie <https://github.com/jtgrassie>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_SELFSELECTCLIENT_H
#define XMRIG_SELFSELECTCLIENT_H
#include "base/kernel/interfaces/IClient.h"
#include "base/kernel/interfaces/IClientListener.h"
#include "base/kernel/interfaces/IHttpListener.h"
#include "base/net/stratum/Job.h"
#include "base/tools/Object.h"
namespace xmrig {
class SelfSelectClient : public IClient, public IClientListener, public IHttpListener
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(SelfSelectClient)
SelfSelectClient(int id, const char *agent, IClientListener *listener);
~SelfSelectClient() override;
protected:
// IClient
inline bool disconnect() override { return m_client->disconnect(); }
inline bool hasExtension(Extension extension) const noexcept override { return m_client->hasExtension(extension); }
inline bool isEnabled() const override { return m_client->isEnabled(); }
inline bool isTLS() const override { return m_client->isTLS(); }
inline const char *mode() const override { return m_client->mode(); }
inline const char *tlsFingerprint() const override { return m_client->tlsFingerprint(); }
inline const char *tlsVersion() const override { return m_client->tlsVersion(); }
inline const Job &job() const override { return m_client->job(); }
inline const Pool &pool() const override { return m_client->pool(); }
inline const String &ip() const override { return m_client->ip(); }
inline int id() const override { return m_client->id(); }
inline int64_t send(const rapidjson::Value &obj, Callback callback) override { return m_client->send(obj, callback); }
inline int64_t send(const rapidjson::Value &obj) override { return m_client->send(obj); }
inline int64_t sequence() const override { return m_client->sequence(); }
inline int64_t submit(const JobResult &result) override { return m_client->submit(result); }
inline void connect() override { m_client->connect(); }
inline void connect(const Pool &pool) override { m_client->connect(pool); }
inline void deleteLater() override { m_client->deleteLater(); }
inline void setAlgo(const Algorithm &algo) override { m_client->setAlgo(algo); }
inline void setEnabled(bool enabled) override { m_client->setEnabled(enabled); }
inline void setPool(const Pool &pool) override { m_client->setPool(pool); }
inline void setQuiet(bool quiet) override { m_client->setQuiet(quiet); m_quiet = quiet; }
inline void setRetries(int retries) override { m_client->setRetries(retries); m_retries = retries; }
inline void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); m_retryPause = ms; }
void tick(uint64_t now) override;
// IClientListener
inline void onClose(IClient *, int failures) override { m_listener->onClose(this, failures); setState(IdleState); m_active = false; }
inline void onLoginSuccess(IClient *) override { m_listener->onLoginSuccess(this); setState(IdleState); m_active = true; }
inline void onResultAccepted(IClient *, const SubmitResult &result, const char *error) override { m_listener->onResultAccepted(this, result, error); }
inline void onVerifyAlgorithm(const IClient *, const Algorithm &algorithm, bool *ok) override { m_listener->onVerifyAlgorithm(this, algorithm, ok); }
void onJobReceived(IClient *, const Job &job, const rapidjson::Value &params) override;
void onLogin(IClient *, rapidjson::Document &doc, rapidjson::Value &params) override;
// IHttpListener
void onHttpData(const HttpData &data) override;
private:
enum State {
IdleState,
WaitState,
RetryState
};
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
bool parseResponse(int64_t id, rapidjson::Value &result, const rapidjson::Value &error);
void getBlockTemplate();
void retry();
void send(int method, const char *url, const char *data = nullptr, size_t size = 0);
void send(int method, const char *url, const rapidjson::Document &doc);
void setState(State state);
void submitBlockTemplate(rapidjson::Value &result);
bool m_active = false;
bool m_quiet = false;
IClient *m_client;
IClientListener *m_listener;
int m_retries = 5;
int64_t m_failures = 0;
int64_t m_sequence = 1;
Job m_job;
State m_state = IdleState;
uint64_t m_retryPause = 5000;
uint64_t m_timestamp = 0;
};
} /* namespace xmrig */
#endif /* XMRIG_SELFSELECTCLIENT_H */

View File

@@ -35,34 +35,28 @@ namespace xmrig {
class SubmitResult
{
public:
inline SubmitResult() :
reqId(0),
seq(0),
actualDiff(0),
diff(0),
elapsed(0),
m_start(0)
{}
SubmitResult() = default;
inline SubmitResult(int64_t seq, uint64_t diff, uint64_t actualDiff, int64_t reqId = 0) :
inline SubmitResult(int64_t seq, uint64_t diff, uint64_t actualDiff, int64_t reqId, uint32_t backend) :
reqId(reqId),
seq(seq),
backend(backend),
actualDiff(actualDiff),
diff(diff),
elapsed(0),
m_start(Chrono::steadyMSecs())
{}
inline void done() { elapsed = Chrono::steadyMSecs() - m_start; }
int64_t reqId;
int64_t seq;
uint64_t actualDiff;
uint64_t diff;
uint64_t elapsed;
int64_t reqId = 0;
int64_t seq = 0;
uint32_t backend = 0;
uint64_t actualDiff = 0;
uint64_t diff = 0;
uint64_t elapsed = 0;
private:
uint64_t m_start;
uint64_t m_start = 0;
};

View File

@@ -0,0 +1,163 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2019 Howard Chu <https://github.com/hyc>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/net/stratum/Url.h"
#include <cassert>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#ifdef _MSC_VER
# define strncasecmp _strnicmp
#endif
namespace xmrig {
static const char kStratumTcp[] = "stratum+tcp://";
static const char kStratumSsl[] = "stratum+ssl://";
#ifdef XMRIG_FEATURE_HTTP
static const char kDaemonHttp[] = "daemon+http://";
static const char kDaemonHttps[] = "daemon+https://";
#endif
}
xmrig::Url::Url(const char *url)
{
parse(url);
}
xmrig::Url::Url(const char *host, uint16_t port, bool tls, Scheme scheme) :
m_tls(tls),
m_scheme(scheme),
m_host(host),
m_port(port)
{
const size_t size = m_host.size() + 8;
assert(size > 8);
char *url = new char[size]();
snprintf(url, size - 1, "%s:%d", m_host.data(), m_port);
m_url = url;
}
bool xmrig::Url::isEqual(const Url &other) const
{
return (m_tls == other.m_tls && m_scheme == other.m_scheme && m_host == other.m_host && m_url == other.m_url && m_port == other.m_port);
}
bool xmrig::Url::parse(const char *url)
{
if (url == nullptr) {
return false;
}
const char *p = strstr(url, "://");
const char *base = url;
if (p) {
if (strncasecmp(url, kStratumTcp, sizeof(kStratumTcp) - 1) == 0) {
m_scheme = STRATUM;
m_tls = false;
}
else if (strncasecmp(url, kStratumSsl, sizeof(kStratumSsl) - 1) == 0) {
m_scheme = STRATUM;
m_tls = true;
}
# ifdef XMRIG_FEATURE_HTTP
else if (strncasecmp(url, kDaemonHttps, sizeof(kDaemonHttps) - 1) == 0) {
m_scheme = DAEMON;
m_tls = true;
}
else if (strncasecmp(url, kDaemonHttp, sizeof(kDaemonHttp) - 1) == 0) {
m_scheme = DAEMON;
m_tls = false;
}
# endif
else {
return false;
}
base = p + 3;
}
if (!strlen(base) || *base == '/') {
return false;
}
m_url = url;
if (base[0] == '[') {
return parseIPv6(base);
}
const char *port = strchr(base, ':');
if (!port) {
m_host = base;
return true;
}
const auto size = static_cast<size_t>(port++ - base + 1);
char *host = new char[size]();
memcpy(host, base, size - 1);
m_host = host;
m_port = static_cast<uint16_t>(strtol(port, nullptr, 10));
return true;
}
bool xmrig::Url::parseIPv6(const char *addr)
{
const char *end = strchr(addr, ']');
if (!end) {
return false;
}
const char *port = strchr(end, ':');
if (!port) {
return false;
}
const auto size = static_cast<size_t>(end - addr);
char *host = new char[size]();
memcpy(host, addr + 1, size - 1);
m_host = host;
m_port = static_cast<uint16_t>(strtol(port + 1, nullptr, 10));
return true;
}

View File

@@ -0,0 +1,77 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2019 Howard Chu <https://github.com/hyc>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_URL_H
#define XMRIG_URL_H
#include "base/tools/String.h"
namespace xmrig {
class Url
{
public:
enum Scheme {
UNSPECIFIED,
STRATUM,
DAEMON
};
Url() = default;
Url(const char *url);
Url(const char *host, uint16_t port, bool tls = false, Scheme scheme = UNSPECIFIED);
inline bool isTLS() const { return m_tls; }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
inline const String &host() const { return m_host; }
inline const String &url() const { return m_url; }
inline Scheme scheme() const { return m_scheme; }
inline uint16_t port() const { return m_port; }
inline bool operator!=(const Url &other) const { return !isEqual(other); }
inline bool operator==(const Url &other) const { return isEqual(other); }
bool isEqual(const Url &other) const;
rapidjson::Value toJSON(rapidjson::Document &doc) const;
private:
bool parse(const char *url);
bool parseIPv6(const char *addr);
bool m_tls = false;
Scheme m_scheme = UNSPECIFIED;
String m_host;
String m_url;
uint16_t m_port = 3333;
};
} /* namespace xmrig */
#endif /* XMRIG_URL_H */

View File

@@ -23,15 +23,10 @@
*/
#include "base/net/stratum/strategies/FailoverStrategy.h"
#include "base/kernel/interfaces/IClient.h"
#include "base/kernel/interfaces/IStrategyListener.h"
#include "base/kernel/Platform.h"
#include "base/net/stratum/Client.h"
#include "base/net/stratum/strategies/FailoverStrategy.h"
#ifdef XMRIG_FEATURE_HTTP
# include "base/net/stratum/DaemonClient.h"
#endif
xmrig::FailoverStrategy::FailoverStrategy(const std::vector<Pool> &pools, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
@@ -69,16 +64,8 @@ xmrig::FailoverStrategy::~FailoverStrategy()
void xmrig::FailoverStrategy::add(const Pool &pool)
{
const int id = static_cast<int>(m_pools.size());
IClient *client = pool.createClient(static_cast<int>(m_pools.size()), this);
# ifdef XMRIG_FEATURE_HTTP
IClient *client = !pool.isDaemon() ? static_cast<IClient *>(new Client(id, Platform::userAgent(), this))
: static_cast<IClient *>(new DaemonClient(id, this));
# else
IClient *client = new Client(id, Platform::userAgent(), this);
# endif
client->setPool(pool);
client->setRetries(m_retries);
client->setRetryPause(m_retryPause * 1000);
client->setQuiet(m_quiet);
@@ -123,8 +110,8 @@ void xmrig::FailoverStrategy::setAlgo(const Algorithm &algo)
void xmrig::FailoverStrategy::stop()
{
for (size_t i = 0; i < m_pools.size(); ++i) {
m_pools[i]->disconnect();
for (auto &pool : m_pools) {
pool->disconnect();
}
m_index = 0;

View File

@@ -32,6 +32,7 @@
#include "base/kernel/interfaces/IClientListener.h"
#include "base/kernel/interfaces/IStrategy.h"
#include "base/net/stratum/Pool.h"
#include "base/tools/Object.h"
namespace xmrig {
@@ -44,6 +45,8 @@ class IStrategyListener;
class FailoverStrategy : public IStrategy, public IClientListener
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(FailoverStrategy)
FailoverStrategy(const std::vector<Pool> &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
FailoverStrategy(int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
~FailoverStrategy() override;

View File

@@ -23,33 +23,18 @@
*/
#include "base/net/stratum/strategies/SinglePoolStrategy.h"
#include "base/kernel/interfaces/IClient.h"
#include "base/kernel/interfaces/IStrategyListener.h"
#include "base/kernel/Platform.h"
#include "base/net/stratum/Client.h"
#include "base/net/stratum/strategies/SinglePoolStrategy.h"
#ifdef XMRIG_FEATURE_HTTP
# include "base/net/stratum/DaemonClient.h"
#endif
#include "base/net/stratum/Pool.h"
xmrig::SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
m_active(false),
m_listener(listener)
{
# ifdef XMRIG_FEATURE_HTTP
if (!pool.isDaemon()) {
m_client = new Client(0, Platform::userAgent(), this);
}
else {
m_client = new DaemonClient(0, this);
}
# else
m_client = new Client(0, Platform::userAgent(), this);
# endif
m_client->setPool(pool);
m_client = pool.createClient(0, this);
m_client->setRetries(retries);
m_client->setRetryPause(retryPause * 1000);
m_client->setQuiet(quiet);

View File

@@ -28,6 +28,7 @@
#include "base/kernel/interfaces/IClientListener.h"
#include "base/kernel/interfaces/IStrategy.h"
#include "base/tools/Object.h"
namespace xmrig {
@@ -41,6 +42,8 @@ class Pool;
class SinglePoolStrategy : public IStrategy, public IClientListener
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(SinglePoolStrategy)
SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
~SinglePoolStrategy() override;

View File

@@ -53,14 +53,7 @@ static inline uint8_t hf_bin2hex(uint8_t c)
}
xmrig::Buffer::Buffer() :
m_data(nullptr),
m_size(0)
{
}
xmrig::Buffer::Buffer(Buffer &&other) :
xmrig::Buffer::Buffer(Buffer &&other) noexcept :
m_data(other.m_data),
m_size(other.m_size)
{
@@ -138,11 +131,13 @@ bool xmrig::Buffer::fromHex(const uint8_t *in, size_t size, uint8_t *out)
xmrig::Buffer xmrig::Buffer::fromHex(const char *data, size_t size)
{
if (data == nullptr || size % 2 != 0) {
return Buffer();
return {};
}
Buffer buf(size / 2);
fromHex(data, size, buf.data());
if (!fromHex(data, size, buf.data())) {
return {};
}
return buf;
}
@@ -157,12 +152,6 @@ void xmrig::Buffer::toHex(const uint8_t *in, size_t size, uint8_t *out)
}
xmrig::String xmrig::Buffer::toHex(const uint8_t *in, size_t size)
{
return Buffer(reinterpret_cast<const char *>(in), size).toHex();
}
xmrig::String xmrig::Buffer::toHex() const
{
if (m_size == 0) {

View File

@@ -35,14 +35,15 @@ namespace xmrig {
class Buffer
{
public:
Buffer();
Buffer(Buffer &&other);
Buffer() = default;
Buffer(Buffer &&other) noexcept;
Buffer(const Buffer &other);
Buffer(const char *data, size_t size);
Buffer(size_t size);
~Buffer();
inline bool isEmpty() const { return size() == 0; }
inline bool isEqual(const Buffer &other) const { return m_size == other.m_size && (m_size == 0 || memcmp(m_data, other.m_data, m_size) == 0); }
inline char *data() { return m_data; }
inline const char *data() const { return m_data; }
@@ -55,7 +56,7 @@ public:
inline bool operator!=(const Buffer &other) const { return !isEqual(other); }
inline bool operator==(const Buffer &other) const { return isEqual(other); }
inline Buffer &operator=(Buffer &&other) { move(std::move(other)); return *this; }
inline Buffer &operator=(Buffer &&other) noexcept { move(std::move(other)); return *this; }
inline Buffer &operator=(const Buffer &other) { from(other); return *this; }
@@ -67,12 +68,13 @@ public:
inline static bool fromHex(const char *in, size_t size, uint8_t *out) { return fromHex(reinterpret_cast<const uint8_t *>(in), size, out); }
inline static Buffer fromHex(const char *data) { return fromHex(data, strlen(data)); }
inline static Buffer fromHex(const String &str) { return fromHex(str.data(), str.size()); }
inline static String toHex(const char *in, size_t size) { return Buffer(in, size).toHex(); }
inline static String toHex(const uint8_t *in, size_t size) { return Buffer(reinterpret_cast<const char *>(in), size).toHex(); }
inline static void toHex(const char *in, size_t size, char *out) { return toHex(reinterpret_cast<const uint8_t *>(in), size, reinterpret_cast<uint8_t *>(out)); }
inline static void toHex(const uint8_t *in, size_t size, char *out) { return toHex(in, size, reinterpret_cast<uint8_t *>(out)); }
static bool fromHex(const uint8_t *in, size_t size, uint8_t *out);
static Buffer fromHex(const char *data, size_t size);
static String toHex(const uint8_t *in, size_t size);
static void toHex(const uint8_t *in, size_t size, uint8_t *out);
String toHex() const;
@@ -80,8 +82,8 @@ private:
void copy(const char *data, size_t size);
void move(Buffer &&other);
char *m_data;
size_t m_size;
char *m_data = nullptr;
size_t m_size = 0;
};

View File

@@ -31,7 +31,6 @@
xmrig::String::String(const char *str) :
m_data(nullptr),
m_size(str == nullptr ? 0 : strlen(str))
{
if (m_size == 0) {
@@ -44,7 +43,6 @@ xmrig::String::String(const char *str) :
xmrig::String::String(const char *str, size_t size) :
m_data(nullptr),
m_size(size)
{
if (str == nullptr) {
@@ -60,7 +58,6 @@ xmrig::String::String(const char *str, size_t size) :
xmrig::String::String(const String &other) :
m_data(nullptr),
m_size(other.m_size)
{
if (other.m_data == nullptr) {
@@ -117,7 +114,7 @@ std::vector<xmrig::String> xmrig::String::split(char sep) const
for (pos = 0; pos < m_size; ++pos) {
if (m_data[pos] == sep) {
if ((pos - start) > 0) {
out.push_back(String(m_data + start, pos - start));
out.emplace_back(m_data + start, pos - start);
}
start = pos + 1;
@@ -125,7 +122,7 @@ std::vector<xmrig::String> xmrig::String::split(char sep) const
}
if ((pos - start) > 0) {
out.push_back(String(m_data + start, pos - start));
out.emplace_back(m_data + start, pos - start);
}
return out;
@@ -146,6 +143,20 @@ xmrig::String &xmrig::String::toLower()
}
xmrig::String &xmrig::String::toUpper()
{
if (isNull() || isEmpty()) {
return *this;
}
for (size_t i = 0; i < size(); ++i) {
m_data[i] = static_cast<char>(toupper(m_data[i]));
}
return *this;
}
xmrig::String xmrig::String::join(const std::vector<xmrig::String> &vec, char sep)
{
if (vec.empty()) {

View File

@@ -46,9 +46,9 @@ namespace xmrig {
class String
{
public:
inline String() : m_data(nullptr), m_size(0) {}
inline String(char *str) : m_data(str), m_size(str == nullptr ? 0 : strlen(str)) {}
inline String(String &&other) : m_data(other.m_data), m_size(other.m_size) { other.m_data = nullptr; other.m_size = 0; }
inline String() = default;
inline String(char *str) : m_data(str), m_size(str == nullptr ? 0 : strlen(str)) {}
inline String(String &&other) noexcept : m_data(other.m_data), m_size(other.m_size) { other.m_data = nullptr; other.m_size = 0; }
String(const char *str);
String(const char *str, size_t size);
@@ -81,12 +81,13 @@ public:
inline String &operator=(const char *str) { copy(str); return *this; }
inline String &operator=(const String &str) { copy(str); return *this; }
inline String &operator=(std::nullptr_t) { delete [] m_data; m_data = nullptr; m_size = 0; return *this; }
inline String &operator=(String &&other) { move(std::move(other)); return *this; }
inline String &operator=(String &&other) noexcept { move(std::move(other)); return *this; }
rapidjson::Value toJSON() const;
rapidjson::Value toJSON(rapidjson::Document &doc) const;
std::vector<xmrig::String> split(char sep) const;
String &toLower();
String &toUpper();
static String join(const std::vector<xmrig::String> &vec, char sep);
@@ -96,8 +97,8 @@ private:
void move(char *str);
void move(String &&other);
char *m_data;
size_t m_size;
char *m_data = nullptr;
size_t m_size = 0;
};

View File

@@ -29,10 +29,13 @@
#include "version.h"
#include <string>
namespace xmrig {
static char const usage[] = "\
static char const usage_raw[] = "\
Usage: " APP_ID " [OPTIONS]\n\
Options:\n\
-b, --bind=ADDR bind to specified address, example \"0.0.0.0:3333\"\n\
@@ -91,6 +94,18 @@ Options:\n\
";
static inline const std::string &usage()
{
static std::string u;
if (u.empty()) {
u = usage_raw;
}
return u;
}
} /* namespace xmrig */
#endif /* XMRIG_USAGE_H */

View File

@@ -27,8 +27,8 @@
#define XMRIG_CN_ALGO_H
#include <stddef.h>
#include <stdint.h>
#include <cstddef>
#include <cstdint>
#include "crypto/common/Algorithm.h"
@@ -42,20 +42,14 @@ template<Algorithm::Id ALGO = Algorithm::INVALID>
class CnAlgo
{
public:
constexpr inline CnAlgo()
{
static_assert(ALGO != Algorithm::INVALID && m_memory[ALGO] > 0, "invalid CRYPTONIGHT algorithm");
static_assert(sizeof(m_memory) / sizeof(m_memory)[0] == Algorithm::MAX, "memory table size mismatch");
static_assert(sizeof(m_iterations) / sizeof(m_iterations)[0] == Algorithm::MAX, "iterations table size mismatch");
static_assert(sizeof(m_base) / sizeof(m_base)[0] == Algorithm::MAX, "iterations table size mismatch");
}
constexpr CnAlgo() {};
constexpr inline Algorithm::Id base() const { return m_base[ALGO]; }
constexpr inline Algorithm::Id base() const { static_assert(ALGO > Algorithm::INVALID && ALGO < Algorithm::RX_0, "invalid CRYPTONIGHT algorithm"); return Algorithm::CN_2; }
constexpr inline bool isHeavy() const { return memory() == CN_MEMORY * 2; }
constexpr inline bool isR() const { return ALGO == Algorithm::CN_R || ALGO == Algorithm::CN_WOW; }
constexpr inline size_t memory() const { return m_memory[ALGO]; }
constexpr inline uint32_t iterations() const { return m_iterations[ALGO]; }
constexpr inline uint32_t mask() const { return ((memory() - 1) / 16) * 16; }
constexpr inline bool isR() const { return ALGO == Algorithm::CN_R; }
constexpr inline size_t memory() const { static_assert(ALGO > Algorithm::INVALID && ALGO < Algorithm::RX_0, "invalid CRYPTONIGHT algorithm"); return CN_MEMORY; }
constexpr inline uint32_t iterations() const { static_assert(ALGO > Algorithm::INVALID && ALGO < Algorithm::RX_0, "invalid CRYPTONIGHT algorithm"); return CN_ITER; }
constexpr inline uint32_t mask() const { return static_cast<uint32_t>(((memory() - 1) / 16) * 16); }
inline static size_t memory(Algorithm::Id algo)
{
@@ -79,6 +73,54 @@ public:
return 0;
}
inline static uint32_t iterations(Algorithm::Id algo)
{
switch (algo) {
case Algorithm::CN_0:
case Algorithm::CN_1:
case Algorithm::CN_2:
case Algorithm::CN_R:
case Algorithm::CN_RTO:
return CN_ITER;
case Algorithm::CN_FAST:
case Algorithm::CN_HALF:
# ifdef XMRIG_ALGO_CN_LITE
case Algorithm::CN_LITE_0:
case Algorithm::CN_LITE_1:
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
case Algorithm::CN_HEAVY_0:
case Algorithm::CN_HEAVY_TUBE:
case Algorithm::CN_HEAVY_XHV:
# endif
return CN_ITER / 2;
case Algorithm::CN_RWZ:
case Algorithm::CN_ZLS:
return 0x60000;
case Algorithm::CN_XAO:
case Algorithm::CN_DOUBLE:
return CN_ITER * 2;
# ifdef XMRIG_ALGO_CN_GPU
case Algorithm::CN_GPU:
return 0xC000;
# endif
# ifdef XMRIG_ALGO_CN_PICO
case Algorithm::CN_PICO_0:
return CN_ITER / 8;
# endif
default:
break;
}
return 0;
}
inline static uint32_t mask(Algorithm::Id algo)
{
# ifdef XMRIG_ALGO_CN_GPU
@@ -96,124 +138,97 @@ public:
return ((memory(algo) - 1) / 16) * 16;
}
inline static Algorithm::Id base(Algorithm::Id algo)
{
switch (algo) {
case Algorithm::CN_0:
case Algorithm::CN_XAO:
# ifdef XMRIG_ALGO_CN_LITE
case Algorithm::CN_LITE_0:
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
case Algorithm::CN_HEAVY_0:
case Algorithm::CN_HEAVY_XHV:
# endif
return Algorithm::CN_0;
case Algorithm::CN_1:
case Algorithm::CN_FAST:
case Algorithm::CN_RTO:
# ifdef XMRIG_ALGO_CN_LITE
case Algorithm::CN_LITE_1:
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
case Algorithm::CN_HEAVY_TUBE:
return Algorithm::CN_1;
# endif
case Algorithm::CN_2:
case Algorithm::CN_R:
case Algorithm::CN_HALF:
case Algorithm::CN_RWZ:
case Algorithm::CN_ZLS:
case Algorithm::CN_DOUBLE:
# ifdef XMRIG_ALGO_CN_PICO
case Algorithm::CN_PICO_0:
# endif
return Algorithm::CN_2;
# ifdef XMRIG_ALGO_CN_GPU
case Algorithm::CN_GPU:
return Algorithm::CN_GPU;
# endif
default:
break;
}
return Algorithm::INVALID;
}
private:
constexpr const static size_t CN_MEMORY = 0x200000;
constexpr const static uint32_t CN_ITER = 0x80000;
constexpr const static size_t m_memory[] = {
CN_MEMORY, // CN_0
CN_MEMORY, // CN_1
CN_MEMORY, // CN_2
CN_MEMORY, // CN_R
CN_MEMORY, // CN_WOW
CN_MEMORY, // CN_FAST
CN_MEMORY, // CN_HALF
CN_MEMORY, // CN_XAO
CN_MEMORY, // CN_RTO
CN_MEMORY, // CN_RWZ
CN_MEMORY, // CN_ZLS
CN_MEMORY, // CN_DOUBLE
# ifdef XMRIG_ALGO_CN_GPU
CN_MEMORY, // CN_GPU
# endif
# ifdef XMRIG_ALGO_CN_LITE
CN_MEMORY / 2, // CN_LITE_0
CN_MEMORY / 2, // CN_LITE_1
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
CN_MEMORY * 2, // CN_HEAVY_0
CN_MEMORY * 2, // CN_HEAVY_TUBE
CN_MEMORY * 2, // CN_HEAVY_XHV
# endif
# ifdef XMRIG_ALGO_CN_PICO
CN_MEMORY / 8, // CN_PICO_0
# endif
# ifdef XMRIG_ALGO_RANDOMX
0, // RX_0
0, // RX_WOW
0, // RX_LOKI
# endif
};
constexpr const static uint32_t m_iterations[] = {
CN_ITER, // CN_0
CN_ITER, // CN_1
CN_ITER, // CN_2
CN_ITER, // CN_R
CN_ITER, // CN_WOW
CN_ITER / 2, // CN_FAST
CN_ITER / 2, // CN_HALF
CN_ITER * 2, // CN_XAO
CN_ITER, // CN_RTO
0x60000, // CN_RWZ
0x60000, // CN_ZLS
CN_ITER * 2, // CN_DOUBLE
# ifdef XMRIG_ALGO_CN_GPU
0xC000, // CN_GPU
# endif
# ifdef XMRIG_ALGO_CN_LITE
CN_ITER / 2, // CN_LITE_0
CN_ITER / 2, // CN_LITE_1
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
CN_ITER / 2, // CN_HEAVY_0
CN_ITER / 2, // CN_HEAVY_TUBE
CN_ITER / 2, // CN_HEAVY_XHV
# endif
# ifdef XMRIG_ALGO_CN_PICO
CN_ITER / 8, // CN_PICO_0
# endif
# ifdef XMRIG_ALGO_RANDOMX
0, // RX_0
0, // RX_WOW
0, // RX_LOKI
# endif
};
constexpr const static Algorithm::Id m_base[] = {
Algorithm::CN_0, // CN_0
Algorithm::CN_1, // CN_1
Algorithm::CN_2, // CN_2
Algorithm::CN_2, // CN_R
Algorithm::CN_2, // CN_WOW
Algorithm::CN_1, // CN_FAST
Algorithm::CN_2, // CN_HALF
Algorithm::CN_0, // CN_XAO
Algorithm::CN_1, // CN_RTO
Algorithm::CN_2, // CN_RWZ
Algorithm::CN_2, // CN_ZLS
Algorithm::CN_2, // CN_DOUBLE
# ifdef XMRIG_ALGO_CN_GPU
Algorithm::CN_GPU, // CN_GPU
# endif
# ifdef XMRIG_ALGO_CN_LITE
Algorithm::CN_0, // CN_LITE_0
Algorithm::CN_1, // CN_LITE_1
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
Algorithm::CN_0, // CN_HEAVY_0
Algorithm::CN_1, // CN_HEAVY_TUBE
Algorithm::CN_0, // CN_HEAVY_XHV
# endif
# ifdef XMRIG_ALGO_CN_PICO
Algorithm::CN_2, // CN_PICO_0,
# endif
# ifdef XMRIG_ALGO_RANDOMX
Algorithm::INVALID, // RX_0
Algorithm::INVALID, // RX_WOW
Algorithm::INVALID, // RX_LOKI
# endif
};
};
#ifdef XMRIG_ALGO_CN_GPU
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_GPU>::mask() const { return 0x1FFFC0; }
#endif
template<> constexpr inline Algorithm::Id CnAlgo<Algorithm::CN_0>::base() const { return Algorithm::CN_0; }
template<> constexpr inline Algorithm::Id CnAlgo<Algorithm::CN_XAO>::base() const { return Algorithm::CN_0; }
template<> constexpr inline Algorithm::Id CnAlgo<Algorithm::CN_LITE_0>::base() const { return Algorithm::CN_0; }
template<> constexpr inline Algorithm::Id CnAlgo<Algorithm::CN_HEAVY_0>::base() const { return Algorithm::CN_0; }
template<> constexpr inline Algorithm::Id CnAlgo<Algorithm::CN_HEAVY_XHV>::base() const { return Algorithm::CN_0; }
template<> constexpr inline Algorithm::Id CnAlgo<Algorithm::CN_1>::base() const { return Algorithm::CN_1; }
template<> constexpr inline Algorithm::Id CnAlgo<Algorithm::CN_FAST>::base() const { return Algorithm::CN_1; }
template<> constexpr inline Algorithm::Id CnAlgo<Algorithm::CN_RTO>::base() const { return Algorithm::CN_1; }
template<> constexpr inline Algorithm::Id CnAlgo<Algorithm::CN_LITE_1>::base() const { return Algorithm::CN_1; }
template<> constexpr inline Algorithm::Id CnAlgo<Algorithm::CN_HEAVY_TUBE>::base() const { return Algorithm::CN_1; }
#ifdef XMRIG_ALGO_CN_PICO
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_PICO_0>::mask() const { return 0x1FFF0; }
#endif
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_FAST>::iterations() const { return CN_ITER / 2; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_HALF>::iterations() const { return CN_ITER / 2; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_LITE_0>::iterations() const { return CN_ITER / 2; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_LITE_1>::iterations() const { return CN_ITER / 2; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_HEAVY_0>::iterations() const { return CN_ITER / 2; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_HEAVY_TUBE>::iterations() const { return CN_ITER / 2; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_HEAVY_XHV>::iterations() const { return CN_ITER / 2; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_XAO>::iterations() const { return CN_ITER * 2; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_DOUBLE>::iterations() const { return CN_ITER * 2; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_RWZ>::iterations() const { return 0x60000; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_ZLS>::iterations() const { return 0x60000; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_GPU>::iterations() const { return 0xC000; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_PICO_0>::iterations() const { return CN_ITER / 8; }
template<> constexpr inline size_t CnAlgo<Algorithm::CN_LITE_0>::memory() const { return CN_MEMORY / 2; }
template<> constexpr inline size_t CnAlgo<Algorithm::CN_LITE_1>::memory() const { return CN_MEMORY / 2; }
template<> constexpr inline size_t CnAlgo<Algorithm::CN_HEAVY_0>::memory() const { return CN_MEMORY * 2; }
template<> constexpr inline size_t CnAlgo<Algorithm::CN_HEAVY_TUBE>::memory() const { return CN_MEMORY * 2; }
template<> constexpr inline size_t CnAlgo<Algorithm::CN_HEAVY_XHV>::memory() const { return CN_MEMORY * 2; }
template<> constexpr inline size_t CnAlgo<Algorithm::CN_PICO_0>::memory() const { return CN_MEMORY / 8; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_GPU>::mask() const { return 0x1FFFC0; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_PICO_0>::mask() const { return 0x1FFF0; }
} /* namespace xmrig */

View File

@@ -24,27 +24,24 @@
*/
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "crypto/common/Algorithm.h"
#include "crypto/cn/CnAlgo.h"
#include "crypto/common/Algorithm.h"
#include "rapidjson/document.h"
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#ifdef _MSC_VER
# define strcasecmp _stricmp
#endif
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
namespace xmrig {
@@ -67,7 +64,6 @@ static AlgoName const algorithm_names[] = {
{ "cryptonight_v8", nullptr, Algorithm::CN_2 },
{ "cryptonight/r", "cn/r", Algorithm::CN_R },
{ "cryptonight_r", nullptr, Algorithm::CN_R },
{ "cryptonight/wow", "cn/wow", Algorithm::CN_WOW },
{ "cryptonight/fast", "cn/fast", Algorithm::CN_FAST },
{ "cryptonight/msr", "cn/msr", Algorithm::CN_FAST },
{ "cryptonight/half", "cn/half", Algorithm::CN_HALF },
@@ -114,6 +110,8 @@ static AlgoName const algorithm_names[] = {
{ "RandomWOW", nullptr, Algorithm::RX_WOW },
{ "randomx/loki", "rx/loki", Algorithm::RX_LOKI },
{ "RandomXL", nullptr, Algorithm::RX_LOKI },
{ "randomx/arq", "rx/arq", Algorithm::RX_ARQ },
{ "RandomARQ", nullptr, Algorithm::RX_ARQ },
# endif
# ifdef XMRIG_ALGO_ARGON2
{ "argon2/chukwa", nullptr, Algorithm::AR2_CHUKWA },
@@ -145,6 +143,9 @@ size_t xmrig::Algorithm::l2() const
case RX_WOW:
return 0x20000;
case RX_ARQ:
return 0x10000;
default:
break;
}
@@ -175,6 +176,9 @@ size_t xmrig::Algorithm::l3() const
case RX_WOW:
return oneMiB;
case RX_ARQ:
return oneMiB / 4;
default:
break;
}
@@ -231,7 +235,6 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
case CN_1:
case CN_2:
case CN_R:
case CN_WOW:
case CN_FAST:
case CN_HALF:
case CN_XAO:
@@ -266,6 +269,7 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
case RX_0:
case RX_WOW:
case RX_LOKI:
case RX_ARQ:
return RANDOM_X;
# endif
@@ -275,9 +279,8 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
return ARGON2;
# endif
case INVALID:
case MAX:
return UNKNOWN;
default:
break;
}
return UNKNOWN;
@@ -290,9 +293,9 @@ xmrig::Algorithm::Id xmrig::Algorithm::parse(const char *name)
return INVALID;
}
for (size_t i = 0; i < ARRAY_SIZE(algorithm_names); i++) {
if ((strcasecmp(name, algorithm_names[i].name) == 0) || (algorithm_names[i].shortName != nullptr && strcasecmp(name, algorithm_names[i].shortName) == 0)) {
return algorithm_names[i].id;
for (const AlgoName &item : algorithm_names) {
if ((strcasecmp(name, item.name) == 0) || (item.shortName != nullptr && strcasecmp(name, item.shortName) == 0)) {
return item.id;
}
}
@@ -302,9 +305,9 @@ xmrig::Algorithm::Id xmrig::Algorithm::parse(const char *name)
const char *xmrig::Algorithm::name(bool shortName) const
{
for (size_t i = 0; i < ARRAY_SIZE(algorithm_names); i++) {
if (algorithm_names[i].id == m_id) {
return (shortName && algorithm_names[i].shortName) ? algorithm_names[i].shortName : algorithm_names[i].name;
for (const AlgoName &item : algorithm_names) {
if (item.id == m_id) {
return (shortName && item.shortName) ? item.shortName : item.name;
}
}

View File

@@ -39,13 +39,16 @@ namespace xmrig {
class Algorithm
{
public:
// Changes in following file is required if this enum changed:
//
// src/backend/opencl/cl/cn/algorithm.cl
//
enum Id : int {
INVALID = -1,
CN_0, // "cn/0" CryptoNight (original).
CN_1, // "cn/1" CryptoNight variant 1 also known as Monero7 and CryptoNightV7.
CN_2, // "cn/2" CryptoNight variant 2.
CN_R, // "cn/r" CryptoNightR (Monero's variant 4).
CN_WOW, // "cn/wow" CryptoNightR (Wownero).
CN_FAST, // "cn/fast" CryptoNight variant 1 with half iterations.
CN_HALF, // "cn/half" CryptoNight variant 2 with half iterations (Masari/Torque).
CN_XAO, // "cn/xao" CryptoNight variant 0 (modified, Alloy only).
@@ -53,30 +56,19 @@ public:
CN_RWZ, // "cn/rwz" CryptoNight variant 2 with 3/4 iterations and reversed shuffle operation (Graft).
CN_ZLS, // "cn/zls" CryptoNight variant 2 with 3/4 iterations (Zelerius).
CN_DOUBLE, // "cn/double" CryptoNight variant 2 with double iterations (X-CASH).
# ifdef XMRIG_ALGO_CN_GPU
CN_GPU, // "cn/gpu" CryptoNight-GPU (Ryo).
# endif
# ifdef XMRIG_ALGO_CN_LITE
CN_LITE_0, // "cn-lite/0" CryptoNight-Lite variant 0.
CN_LITE_1, // "cn-lite/1" CryptoNight-Lite variant 1.
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
CN_HEAVY_0, // "cn-heavy/0" CryptoNight-Heavy (4 MB).
CN_HEAVY_TUBE, // "cn-heavy/tube" CryptoNight-Heavy (modified, TUBE only).
CN_HEAVY_XHV, // "cn-heavy/xhv" CryptoNight-Heavy (modified, Haven Protocol only).
# endif
# ifdef XMRIG_ALGO_CN_PICO
CN_PICO_0, // "cn-pico" CryptoNight Turtle (TRTL)
# endif
# ifdef XMRIG_ALGO_RANDOMX
RX_0, // "rx/0" RandomX (reference configuration).
RX_WOW, // "rx/wow" RandomWOW (Wownero).
RX_LOKI, // "rx/loki" RandomXL (Loki).
# endif
# ifdef XMRIG_ALGO_ARGON2
AR2_CHUKWA, // "argon2/chukwa"
AR2_WRKZ, // "argon2/wrkz"
# endif
RX_ARQ, // "rx/arq" RandomARQ (Arqma).
AR2_CHUKWA, // "argon2/chukwa" Argon2id (Chukwa).
AR2_WRKZ, // "argon2/wrkz" Argon2id (WRKZ)
MAX
};
@@ -90,10 +82,11 @@ public:
ARGON2
};
inline Algorithm() {}
inline Algorithm() = default;
inline Algorithm(const char *algo) : m_id(parse(algo)) {}
inline Algorithm(Id id) : m_id(id) {}
inline bool isCN() const { auto f = family(); return f == CN || f == CN_LITE || f == CN_HEAVY || f == CN_PICO; }
inline bool isEqual(const Algorithm &other) const { return m_id == other.m_id; }
inline bool isValid() const { return m_id != INVALID; }
inline const char *name() const { return name(false); }
@@ -122,7 +115,7 @@ private:
};
typedef std::vector<Algorithm> Algorithms;
using Algorithms = std::vector<Algorithm>;
} /* namespace xmrig */

View File

@@ -49,6 +49,8 @@ struct CoinName
static CoinName const coin_names[] = {
{ "monero", Coin::MONERO },
{ "xmr", Coin::MONERO },
{ "arqma", Coin::ARQMA },
{ "arq", Coin::ARQMA }
};
@@ -58,8 +60,15 @@ static CoinName const coin_names[] = {
xmrig::Algorithm::Id xmrig::Coin::algorithm(uint8_t blobVersion) const
{
if (id() == MONERO) {
switch (id()) {
case MONERO:
return (blobVersion >= 12) ? Algorithm::RX_0 : Algorithm::CN_R;
case ARQMA:
return (blobVersion >= 15) ? Algorithm::RX_ARQ : Algorithm::CN_PICO_0;
case INVALID:
break;
}
return Algorithm::INVALID;

View File

@@ -40,6 +40,7 @@ public:
enum Id : int {
INVALID = -1,
MONERO,
ARQMA
};

View File

@@ -28,15 +28,15 @@
#define APP_ID "xmrig-proxy"
#define APP_NAME "xmrig-proxy"
#define APP_DESC "XMRig Stratum proxy"
#define APP_VERSION "3.2.1-dev"
#define APP_VERSION "4.5.0-beta"
#define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com"
#define APP_KIND "proxy"
#define APP_VER_MAJOR 3
#define APP_VER_MINOR 2
#define APP_VER_PATCH 1
#define APP_VER_MAJOR 4
#define APP_VER_MINOR 5
#define APP_VER_PATCH 0
#ifdef _MSC_VER
# if (_MSC_VER >= 1920)