Client refactoring.

This commit is contained in:
XMRig 2019-03-15 01:06:10 +07:00
parent d57b41c673
commit be5d609856
6 changed files with 72 additions and 47 deletions

View file

@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -29,6 +30,7 @@
#include "api/NetworkState.h" #include "api/NetworkState.h"
#include "base/tools/Chrono.h"
#include "common/net/SubmitResult.h" #include "common/net/SubmitResult.h"
@ -44,12 +46,6 @@ xmrig::NetworkState::NetworkState() :
} }
int xmrig::NetworkState::connectionTime() const
{
return m_active ? (int)((uv_now(uv_default_loop()) - m_connectionTime) / 1000) : 0;
}
uint32_t xmrig::NetworkState::avgTime() const uint32_t xmrig::NetworkState::avgTime() const
{ {
if (m_latency.empty()) { if (m_latency.empty()) {
@ -74,6 +70,12 @@ uint32_t xmrig::NetworkState::latency() const
} }
uint64_t xmrig::NetworkState::connectionTime() const
{
return m_active ? ((Chrono::steadyMSecs() - m_connectionTime) / 1000) : 0;
}
void xmrig::NetworkState::add(const SubmitResult &result, const char *error) void xmrig::NetworkState::add(const SubmitResult &result, const char *error)
{ {
if (error) { if (error) {
@ -99,7 +101,7 @@ void xmrig::NetworkState::setPool(const char *host, int port, const char *ip)
snprintf(pool, sizeof(pool) - 1, "%s:%d", host, port); snprintf(pool, sizeof(pool) - 1, "%s:%d", host, port);
m_active = true; m_active = true;
m_connectionTime = uv_now(uv_default_loop()); m_connectionTime = Chrono::steadyMSecs();
} }

View file

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

View file

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

View file

@ -37,6 +37,7 @@
#endif #endif
#include "base/tools/Chrono.h"
#include "common/interfaces/IClientListener.h" #include "common/interfaces/IClientListener.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/Client.h" #include "common/net/Client.h"
@ -72,12 +73,11 @@ static const char *states[] = {
xmrig::Client::Client(int id, const char *agent, IClientListener *listener) : xmrig::Client::Client(int id, const char *agent, IClientListener *listener) :
m_enabled(true),
m_ipv6(false), m_ipv6(false),
m_nicehash(false),
m_quiet(false), m_quiet(false),
m_agent(agent), m_agent(agent),
m_listener(listener), m_listener(listener),
m_extensions(0),
m_id(id), m_id(id),
m_retries(5), m_retries(5),
m_retryPause(5000), m_retryPause(5000),
@ -252,7 +252,7 @@ int64_t xmrig::Client::submit(const JobResult &result)
params.AddMember("nonce", StringRef(nonce), allocator); params.AddMember("nonce", StringRef(nonce), allocator);
params.AddMember("result", StringRef(data), allocator); params.AddMember("result", StringRef(data), allocator);
if ((m_extensions & AlgoExt) && result.algorithm.isValid()) { if (has<EXT_ALGO>() && result.algorithm.isValid()) {
params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator); params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator);
} }
@ -327,7 +327,7 @@ bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code)
return false; return false;
} }
Job job(m_id, m_nicehash, m_pool.algorithm(), m_rpcId); Job job(m_id, has<EXT_NICEHASH>(), m_pool.algorithm(), m_rpcId);
if (!job.setId(params["job_id"].GetString())) { if (!job.setId(params["job_id"].GetString())) {
*code = 3; *code = 3;
@ -402,11 +402,7 @@ bool xmrig::Client::parseLogin(const rapidjson::Value &result, int *code)
return false; return false;
} }
m_nicehash = m_pool.isNicehash(); parseExtensions(result);
if (result.HasMember("extensions")) {
parseExtensions(result["extensions"]);
}
const bool rc = parseJob(result["job"], code); const bool rc = parseJob(result["job"], code);
m_jobs = 0; m_jobs = 0;
@ -547,7 +543,7 @@ int64_t xmrig::Client::send(size_t size)
} }
} }
m_expire = uv_now(uv_default_loop()) + kResponseTimeout; m_expire = Chrono::steadyMSecs() + kResponseTimeout;
return m_sequence++; return m_sequence++;
} }
@ -597,7 +593,7 @@ void xmrig::Client::handshake()
{ {
# ifndef XMRIG_NO_TLS # ifndef XMRIG_NO_TLS
if (isTLS()) { if (isTLS()) {
m_expire = uv_now(uv_default_loop()) + kResponseTimeout; m_expire = Chrono::steadyMSecs() + kResponseTimeout;
m_tls->handshake(); m_tls->handshake();
} }
@ -709,28 +705,37 @@ void xmrig::Client::parse(char *line, size_t len)
} }
void xmrig::Client::parseExtensions(const rapidjson::Value &value) void xmrig::Client::parseExtensions(const rapidjson::Value &result)
{ {
m_extensions = 0; m_extensions.reset();
if (!value.IsArray()) { if (!result.HasMember("extensions")) {
return; return;
} }
for (const rapidjson::Value &ext : value.GetArray()) { const rapidjson::Value &extensions = result["extensions"];
if (!extensions.IsArray()) {
return;
}
for (const rapidjson::Value &ext : extensions.GetArray()) {
if (!ext.IsString()) { if (!ext.IsString()) {
continue; continue;
} }
if (strcmp(ext.GetString(), "algo") == 0) { const char *name = ext.GetString();
m_extensions |= AlgoExt;
continue;
}
if (strcmp(ext.GetString(), "nicehash") == 0) { if (strcmp(name, "algo") == 0) {
m_extensions |= NicehashExt; setExtension(EXT_ALGO, true);
m_nicehash = true; }
continue; else if (strcmp(name, "nicehash") == 0) {
setExtension(EXT_NICEHASH, true);
}
else if (strcmp(name, "connect") == 0) {
setExtension(EXT_CONNECT, true);
}
else if (strcmp(name, "keepalive") == 0) {
setExtension(EXT_KEEPALIVE, true);
} }
} }
} }
@ -868,7 +873,7 @@ void xmrig::Client::reconnect()
m_failures++; m_failures++;
m_listener->onClose(this, (int) m_failures); m_listener->onClose(this, (int) m_failures);
m_expire = uv_now(uv_default_loop()) + m_retryPause; m_expire = Chrono::steadyMSecs() + m_retryPause;
} }
@ -888,8 +893,10 @@ void xmrig::Client::startTimeout()
{ {
m_expire = 0; m_expire = 0;
if (m_pool.keepAlive()) { if (has<EXT_KEEPALIVE>()) {
m_keepAlive = uv_now(uv_default_loop()) + (m_pool.keepAlive() * 1000); const uint64_t ms = static_cast<uint64_t>(m_pool.keepAlive() > 0 ? m_pool.keepAlive() : Pool::kKeepAliveTimeout) * 1000;
m_keepAlive = Chrono::steadyMSecs() + ms;
} }
} }

View file

@ -26,6 +26,7 @@
#define XMRIG_CLIENT_H #define XMRIG_CLIENT_H
#include <bitset>
#include <map> #include <map>
#include <uv.h> #include <uv.h>
#include <vector> #include <vector>
@ -61,6 +62,14 @@ public:
ClosingState ClosingState
}; };
enum Extension {
EXT_ALGO,
EXT_NICEHASH,
EXT_CONNECT,
EXT_KEEPALIVE,
EXT_MAX
};
constexpr static int kResponseTimeout = 20 * 1000; constexpr static int kResponseTimeout = 20 * 1000;
# ifndef XMRIG_NO_TLS # ifndef XMRIG_NO_TLS
@ -82,6 +91,7 @@ public:
void setPool(const Pool &pool); void setPool(const Pool &pool);
void tick(uint64_t now); void tick(uint64_t now);
inline bool isEnabled() const { return m_enabled; }
inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; }
inline const char *host() const { return m_pool.host(); } inline const char *host() const { return m_pool.host(); }
inline const char *ip() const { return m_ip; } inline const char *ip() const { return m_ip; }
@ -90,19 +100,16 @@ public:
inline SocketState state() const { return m_state; } inline SocketState state() const { return m_state; }
inline uint16_t port() const { return m_pool.port(); } inline uint16_t port() const { return m_pool.port(); }
inline void setAlgo(const Algorithm &algo) { m_pool.setAlgo(algo); } inline void setAlgo(const Algorithm &algo) { m_pool.setAlgo(algo); }
inline void setEnabled(bool enabled) { m_enabled = enabled; }
inline void setQuiet(bool quiet) { m_quiet = quiet; } inline void setQuiet(bool quiet) { m_quiet = quiet; }
inline void setRetries(int retries) { m_retries = retries; } inline void setRetries(int retries) { m_retries = retries; }
inline void setRetryPause(int ms) { m_retryPause = ms; } inline void setRetryPause(int ms) { m_retryPause = ms; }
template<Extension ext> inline bool has() const noexcept { return m_extensions.test(ext); }
private: private:
class Tls; class Tls;
enum Extensions {
NicehashExt = 1,
AlgoExt = 2
};
bool close(); bool close();
bool isCriticalError(const char *message); bool isCriticalError(const char *message);
bool isTLS() const; bool isTLS() const;
@ -119,7 +126,7 @@ private:
void login(); void login();
void onClose(); void onClose();
void parse(char *line, size_t len); void parse(char *line, size_t len);
void parseExtensions(const rapidjson::Value &value); void parseExtensions(const rapidjson::Value &result);
void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error); void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error);
void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error); void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
void ping(); void ping();
@ -128,7 +135,8 @@ private:
void setState(SocketState state); void setState(SocketState state);
void startTimeout(); void startTimeout();
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; } inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
inline void setExtension(Extension ext, bool enable) noexcept { m_extensions.set(ext, enable); }
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
static void onClose(uv_handle_t *handle); static void onClose(uv_handle_t *handle);
@ -139,15 +147,15 @@ private:
static inline Client *getClient(void *data) { return m_storage.get(data); } static inline Client *getClient(void *data) { return m_storage.get(data); }
addrinfo m_hints; addrinfo m_hints;
bool m_enabled;
bool m_ipv6; bool m_ipv6;
bool m_nicehash;
bool m_quiet; bool m_quiet;
char m_buf[kInputBufferSize]; char m_buf[kInputBufferSize];
char m_ip[46]; char m_ip[46];
char m_sendBuf[2048]; char m_sendBuf[2048];
const char *m_agent; const char *m_agent;
IClientListener *m_listener; IClientListener *m_listener;
int m_extensions; Id m_rpcId;
int m_id; int m_id;
int m_retries; int m_retries;
int m_retryPause; int m_retryPause;
@ -156,6 +164,7 @@ private:
Pool m_pool; Pool m_pool;
size_t m_recvBufPos; size_t m_recvBufPos;
SocketState m_state; SocketState m_state;
std::bitset<EXT_MAX> m_extensions;
std::map<int64_t, SubmitResult> m_results; std::map<int64_t, SubmitResult> m_results;
Tls *m_tls; Tls *m_tls;
uint64_t m_expire; uint64_t m_expire;
@ -166,13 +175,16 @@ private:
uv_getaddrinfo_t m_resolver; uv_getaddrinfo_t m_resolver;
uv_stream_t *m_stream; uv_stream_t *m_stream;
uv_tcp_t *m_socket; uv_tcp_t *m_socket;
Id m_rpcId;
static int64_t m_sequence; static int64_t m_sequence;
static Storage<Client> m_storage; static Storage<Client> m_storage;
}; };
template<> inline bool Client::has<Client::EXT_NICEHASH>() const noexcept { return m_extensions.test(EXT_NICEHASH) || m_pool.isNicehash(); }
template<> inline bool Client::has<Client::EXT_KEEPALIVE>() const noexcept { return m_extensions.test(EXT_KEEPALIVE) || m_pool.keepAlive() > 0; }
} /* namespace xmrig */ } /* namespace xmrig */

View file

@ -32,6 +32,7 @@
#include "api/Api.h" #include "api/Api.h"
#include "base/tools/Chrono.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/Client.h" #include "common/net/Client.h"
#include "common/net/SubmitResult.h" #include "common/net/SubmitResult.h"
@ -204,7 +205,7 @@ void xmrig::Network::setJob(Client *client, const Job &job, bool donate)
void xmrig::Network::tick() void xmrig::Network::tick()
{ {
const uint64_t now = uv_now(uv_default_loop()); const uint64_t now = Chrono::steadyMSecs();
m_strategy->tick(now); m_strategy->tick(now);