Sync changes with upcoming xmrig-proxy project.

This commit is contained in:
XMRig 2017-07-17 21:57:03 +03:00
parent 57be6f94bb
commit 66d3e96a1a
17 changed files with 135 additions and 93 deletions

View file

@ -37,10 +37,10 @@ class IClientListener
public: public:
virtual ~IClientListener() {} virtual ~IClientListener() {}
virtual void onClose(Client *client, int failures) = 0; virtual void onClose(Client *client, int failures) = 0;
virtual void onJobReceived(Client *client, const Job &job) = 0; virtual void onJobReceived(Client *client, const Job &job) = 0;
virtual void onLoginSuccess(Client *client) = 0; virtual void onLoginSuccess(Client *client) = 0;
virtual void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) = 0; virtual void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) = 0;
}; };

View file

@ -25,6 +25,9 @@
#define __ISTRATEGY_H__ #define __ISTRATEGY_H__
#include <stdint.h>
class JobResult; class JobResult;
@ -33,10 +36,10 @@ class IStrategy
public: public:
virtual ~IStrategy() {} virtual ~IStrategy() {}
virtual bool isActive() const = 0; virtual bool isActive() const = 0;
virtual void connect() = 0; virtual int64_t submit(const JobResult &result) = 0;
virtual void resume() = 0; virtual void connect() = 0;
virtual void submit(const JobResult &result) = 0; virtual void resume() = 0;
}; };

View file

@ -38,10 +38,10 @@ class IStrategyListener
public: public:
virtual ~IStrategyListener() {} virtual ~IStrategyListener() {}
virtual void onActive(Client *client) = 0; virtual void onActive(Client *client) = 0;
virtual void onJob(Client *client, const Job &job) = 0; virtual void onJob(Client *client, const Job &job) = 0;
virtual void onPause(IStrategy *strategy) = 0; virtual void onPause(IStrategy *strategy) = 0;
virtual void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) = 0; virtual void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) = 0;
}; };

View file

@ -23,21 +23,31 @@
#include <iterator> #include <iterator>
#include <string.h>
#include <utility> #include <utility>
#include "log/Log.h" #include "log/Log.h"
#include "interfaces/IClientListener.h" #include "interfaces/IClientListener.h"
#include "net/Client.h" #include "net/Client.h"
#include "net/JobResult.h"
#include "net/Url.h" #include "net/Url.h"
#ifdef XMRIG_PROXY_PROJECT
# include "proxy/JobResult.h"
#else
# include "net/JobResult.h"
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
# define strncasecmp(x,y,z) _strnicmp(x,y,z) # define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif #endif
int64_t Client::m_sequence = 1;
Client::Client(int id, const char *agent, IClientListener *listener) : Client::Client(int id, const char *agent, IClientListener *listener) :
m_quiet(false), m_quiet(false),
m_agent(agent), m_agent(agent),
@ -45,7 +55,6 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_id(id), m_id(id),
m_retryPause(5000), m_retryPause(5000),
m_failures(0), m_failures(0),
m_sequence(1),
m_recvBufPos(0), m_recvBufPos(0),
m_state(UnconnectedState), m_state(UnconnectedState),
m_stream(nullptr), m_stream(nullptr),
@ -77,6 +86,35 @@ Client::~Client()
} }
/**
* @brief Send raw data to server.
*
* @param data
*/
int64_t Client::send(char *data)
{
LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), strlen(data), data);
if (state() != ConnectedState) {
LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state);
return -1;
}
uv_buf_t buf = uv_buf_init(data, strlen(data));
uv_write_t *req = static_cast<uv_write_t*>(malloc(sizeof(uv_write_t)));
req->data = buf.base;
uv_write(req, m_stream, &buf, 1, [](uv_write_t *req, int status) {
free(req->data);
free(req);
});
uv_timer_start(&m_responseTimer, [](uv_timer_t *handle) { getClient(handle->data)->close(); }, kResponseTimeout, 0);
return m_sequence++;
}
void Client::connect() void Client::connect()
{ {
resolve(m_url.host()); resolve(m_url.host());
@ -104,34 +142,6 @@ void Client::disconnect()
} }
/**
* @brief Send raw data to server.
*
* @param data
*/
void Client::send(char *data)
{
LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), strlen(data), data);
if (state() != ConnectedState) {
LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state);
return;
}
m_sequence++;
uv_buf_t buf = uv_buf_init(data, strlen(data));
uv_write_t *req = static_cast<uv_write_t*>(malloc(sizeof(uv_write_t)));
req->data = buf.base;
uv_write(req, m_stream, &buf, 1, [](uv_write_t *req, int status) {
free(req->data);
free(req);
});
uv_timer_start(&m_responseTimer, [](uv_timer_t *handle) { getClient(handle->data)->close(); }, kResponseTimeout, 0);
}
void Client::setUrl(const Url *url) void Client::setUrl(const Url *url)
{ {
if (!url || !url->isValid()) { if (!url || !url->isValid()) {
@ -142,9 +152,14 @@ void Client::setUrl(const Url *url)
} }
void Client::submit(const JobResult &result) int64_t Client::submit(const JobResult &result)
{ {
char *req = static_cast<char*>(malloc(345)); char *req = static_cast<char*>(malloc(345));
# ifdef XMRIG_PROXY_PROJECT
const char *nonce = result.nonce;
const char *data = result.result;
# else
char nonce[9]; char nonce[9];
char data[65]; char data[65];
@ -153,12 +168,13 @@ void Client::submit(const JobResult &result)
Job::toHex(result.result, 32, data); Job::toHex(result.result, 32, data);
data[64] = '\0'; data[64] = '\0';
# endif
snprintf(req, 345, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n", snprintf(req, 345, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
m_sequence, m_rpcId, result.jobId, nonce, data); m_sequence, m_rpcId, result.jobId, nonce, data);
m_results[m_sequence] = SubmitResult(result.diff); m_results[m_sequence] = SubmitResult(m_sequence, result.diff);
send(req); return send(req);
} }
@ -186,8 +202,6 @@ bool Client::parseJob(const json_t *params, int *code)
} }
m_job = std::move(job); m_job = std::move(job);
LOG_DEBUG("[%s:%u] job: \"%s\", diff: %lld", m_url.host(), m_url.port(), job.id(), job.diff());
return true; return true;
} }
@ -236,7 +250,10 @@ void Client::close()
} }
setState(ClosingState); setState(ClosingState);
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_socket)) == 0) {
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
}
} }
@ -266,12 +283,11 @@ void Client::connect(struct sockaddr *addr)
void Client::login() void Client::login()
{ {
m_sequence = 1;
m_results.clear(); m_results.clear();
const size_t size = 96 + strlen(m_url.user()) + strlen(m_url.password()) + strlen(m_agent); const size_t size = 96 + strlen(m_url.user()) + strlen(m_url.password()) + strlen(m_agent);
char *req = static_cast<char*>(malloc(size)); char *req = static_cast<char*>(malloc(size));
snprintf(req, size, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"}}\n", m_sequence, m_url.user(), m_url.password(), m_agent); snprintf(req, size, "{\"id\":1,\"jsonrpc\":\"2.0\",\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"}}\n", m_url.user(), m_url.password(), m_agent);
send(req); send(req);
} }
@ -340,7 +356,7 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error
auto it = m_results.find(id); auto it = m_results.find(id);
if (it != m_results.end()) { if (it != m_results.end()) {
m_listener->onResultAccepted(this, it->second.diff, it->second.elapsed(), message); m_listener->onResultAccepted(this, it->second.seq, it->second.diff, it->second.elapsed(), message);
m_results.erase(it); m_results.erase(it);
} }
else if (!m_quiet) { else if (!m_quiet) {
@ -376,7 +392,7 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error
auto it = m_results.find(id); auto it = m_results.find(id);
if (it != m_results.end()) { if (it != m_results.end()) {
m_listener->onResultAccepted(this, it->second.diff, it->second.elapsed(), nullptr); m_listener->onResultAccepted(this, it->second.seq, it->second.diff, it->second.elapsed(), nullptr);
m_results.erase(it); m_results.erase(it);
} }
} }

View file

@ -56,12 +56,12 @@ public:
Client(int id, const char *agent, IClientListener *listener); Client(int id, const char *agent, IClientListener *listener);
~Client(); ~Client();
int64_t send(char *data);
int64_t submit(const JobResult &result);
void connect(); void connect();
void connect(const Url *url); void connect(const Url *url);
void disconnect(); void disconnect();
void send(char *data);
void setUrl(const Url *url); void setUrl(const Url *url);
void submit(const JobResult &result);
inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; }
inline const char *host() const { return m_url.host(); } inline const char *host() const { return m_url.host(); }
@ -98,6 +98,7 @@ private:
static inline Client *getClient(void *data) { return static_cast<Client*>(data); } static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
addrinfo m_hints;
bool m_quiet; bool m_quiet;
char m_ip[17]; char m_ip[17];
char m_rpcId[64]; char m_rpcId[64];
@ -106,12 +107,11 @@ private:
int m_id; int m_id;
int m_retryPause; int m_retryPause;
int64_t m_failures; int64_t m_failures;
int64_t m_sequence;
Job m_job; Job m_job;
size_t m_recvBufPos; size_t m_recvBufPos;
SocketState m_state; SocketState m_state;
static int64_t m_sequence;
std::map<int64_t, SubmitResult> m_results; std::map<int64_t, SubmitResult> m_results;
struct addrinfo m_hints;
Url m_url; Url m_url;
uv_buf_t m_recvBuf; uv_buf_t m_recvBuf;
uv_getaddrinfo_t m_resolver; uv_getaddrinfo_t m_resolver;

View file

@ -90,6 +90,11 @@ bool Job::setBlob(const char *blob)
m_nicehash = true; m_nicehash = true;
} }
# ifdef XMRIG_PROXY_PROJECT
memset(m_rawBlob, 0, sizeof(m_rawBlob));
memcpy(m_rawBlob, blob, m_size * 2);
# endif
return true; return true;
} }
@ -138,6 +143,11 @@ bool Job::setTarget(const char *target)
return false; return false;
} }
# ifdef XMRIG_PROXY_PROJECT
memset(m_rawTarget, 0, sizeof(m_rawTarget));
memcpy(m_rawTarget, target, len);
# endif
m_diff = toDiff(m_target); m_diff = toDiff(m_target);
return true; return true;
} }

View file

@ -50,6 +50,11 @@ public:
inline uint64_t target() const { return m_target; } inline uint64_t target() const { return m_target; }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
# ifdef XMRIG_PROXY_PROJECT
inline char *rawBlob() { return m_rawBlob; }
inline const char *rawTarget() const { return m_rawTarget; }
# endif
static bool fromHex(const char* in, unsigned int len, unsigned char* out); static bool fromHex(const char* in, unsigned int len, unsigned char* out);
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); } static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; } static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; }
@ -65,6 +70,11 @@ private:
uint32_t m_size; uint32_t m_size;
uint64_t m_diff; uint64_t m_diff;
uint64_t m_target; uint64_t m_target;
# ifdef XMRIG_PROXY_PROJECT
VAR_ALIGN(16, char m_rawBlob[169]);
VAR_ALIGN(16, char m_rawTarget[17]);
# endif
}; };
#endif /* __JOB_H__ */ #endif /* __JOB_H__ */

View file

@ -97,7 +97,8 @@ void Network::onJob(Client *client, const Job &job)
void Network::onJobResult(const JobResult &result) void Network::onJobResult(const JobResult &result)
{ {
if (result.poolId == -1 && m_donate) { if (result.poolId == -1 && m_donate) {
return m_donate->submit(result); m_donate->submit(result);
return;
} }
m_strategy->submit(result); m_strategy->submit(result);
@ -118,12 +119,12 @@ void Network::onPause(IStrategy *strategy)
} }
void Network::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) void Network::onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error)
{ {
if (error) { if (error) {
m_rejected++; m_rejected++;
LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%lld/%lld) diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%llu ms)" : "accepted (%lld/%lld) diff %u \"%s\" (%llu ms)", m_accepted, m_rejected, diff, error, ms); LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%lld/%lld) diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%llu ms)" : "rejected (%lld/%lld) diff %u \"%s\" (%llu ms)", m_accepted, m_rejected, diff, error, ms);
} }
else { else {
m_accepted++; m_accepted++;

View file

@ -53,7 +53,7 @@ protected:
void onJob(Client *client, const Job &job) override; void onJob(Client *client, const Job &job) override;
void onJobResult(const JobResult &result) override; void onJobResult(const JobResult &result) override;
void onPause(IStrategy *strategy) override; void onPause(IStrategy *strategy) override;
void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override; void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) override;
private: private:
void setJob(Client *client, const Job &job); void setJob(Client *client, const Job &job);

View file

@ -31,8 +31,9 @@
class SubmitResult class SubmitResult
{ {
public: public:
inline SubmitResult() : diff(0), start(0) {} inline SubmitResult() : seq(0), diff(0), start(0) {}
inline SubmitResult(uint32_t diff) : inline SubmitResult(int64_t seq, uint32_t diff) :
seq(seq),
diff(diff) diff(diff)
{ {
start = uv_hrtime(); start = uv_hrtime();
@ -40,6 +41,7 @@ public:
inline uint64_t elapsed() const { return (uv_hrtime() - start) / 1000000; } inline uint64_t elapsed() const { return (uv_hrtime() - start) / 1000000; }
int64_t seq;
uint32_t diff; uint32_t diff;
uint64_t start; uint64_t start;
}; };

View file

@ -50,15 +50,15 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
} }
void DonateStrategy::connect() int64_t DonateStrategy::submit(const JobResult &result)
{ {
m_client->connect(); return m_client->submit(result);
} }
void DonateStrategy::submit(const JobResult &result) void DonateStrategy::connect()
{ {
m_client->submit(result); m_client->connect();
} }
@ -84,9 +84,9 @@ void DonateStrategy::onLoginSuccess(Client *client)
} }
void DonateStrategy::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) void DonateStrategy::onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error)
{ {
m_listener->onResultAccepted(client, diff, ms, error); m_listener->onResultAccepted(client, seq, diff, ms, error);
} }

View file

@ -46,14 +46,14 @@ public:
inline bool isActive() const override { return m_active; } inline bool isActive() const override { return m_active; }
inline void resume() override {} inline void resume() override {}
int64_t submit(const JobResult &result) override;
void connect() override; void connect() override;
void submit(const JobResult &result) override;
protected: protected:
void onClose(Client *client, int failures) override; void onClose(Client *client, int failures) override;
void onJobReceived(Client *client, const Job &job) override; void onJobReceived(Client *client, const Job &job) override;
void onLoginSuccess(Client *client) override; void onLoginSuccess(Client *client) override;
void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override; void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) override;
private: private:
void idle(); void idle();

View file

@ -39,6 +39,12 @@ FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, const char *ag
} }
int64_t FailoverStrategy::submit(const JobResult &result)
{
return m_pools[m_active]->submit(result);
}
void FailoverStrategy::connect() void FailoverStrategy::connect()
{ {
m_pools[m_index]->connect(); m_pools[m_index]->connect();
@ -55,12 +61,6 @@ void FailoverStrategy::resume()
} }
void FailoverStrategy::submit(const JobResult &result)
{
m_pools[m_active]->submit(result);
}
void FailoverStrategy::onClose(Client *client, int failures) void FailoverStrategy::onClose(Client *client, int failures)
{ {
if (failures == -1) { if (failures == -1) {
@ -111,9 +111,9 @@ void FailoverStrategy::onLoginSuccess(Client *client)
} }
void FailoverStrategy::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) void FailoverStrategy::onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error)
{ {
m_listener->onResultAccepted(client, diff, ms, error); m_listener->onResultAccepted(client, seq, diff, ms, error);
} }

View file

@ -45,15 +45,15 @@ public:
public: public:
inline bool isActive() const override { return m_active >= 0; } inline bool isActive() const override { return m_active >= 0; }
int64_t submit(const JobResult &result) override;
void connect() override; void connect() override;
void resume() override; void resume() override;
void submit(const JobResult &result) override;
protected: protected:
void onClose(Client *client, int failures) override; void onClose(Client *client, int failures) override;
void onJobReceived(Client *client, const Job &job) override; void onJobReceived(Client *client, const Job &job) override;
void onLoginSuccess(Client *client) override; void onLoginSuccess(Client *client) override;
void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override; void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) override;
private: private:
void add(const Url *url, const char *agent); void add(const Url *url, const char *agent);

View file

@ -38,6 +38,12 @@ SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrat
} }
int64_t SinglePoolStrategy::submit(const JobResult &result)
{
return m_client->submit(result);
}
void SinglePoolStrategy::connect() void SinglePoolStrategy::connect()
{ {
m_client->connect(); m_client->connect();
@ -54,12 +60,6 @@ void SinglePoolStrategy::resume()
} }
void SinglePoolStrategy::submit(const JobResult &result)
{
m_client->submit(result);
}
void SinglePoolStrategy::onClose(Client *client, int failures) void SinglePoolStrategy::onClose(Client *client, int failures)
{ {
if (!isActive()) { if (!isActive()) {
@ -84,7 +84,7 @@ void SinglePoolStrategy::onLoginSuccess(Client *client)
} }
void SinglePoolStrategy::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) void SinglePoolStrategy::onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error)
{ {
m_listener->onResultAccepted(client, diff, ms, error); m_listener->onResultAccepted(client, seq, diff, ms, error);
} }

View file

@ -42,15 +42,15 @@ public:
public: public:
inline bool isActive() const override { return m_active; } inline bool isActive() const override { return m_active; }
int64_t submit(const JobResult &result) override;
void connect() override; void connect() override;
void resume() override; void resume() override;
void submit(const JobResult &result) override;
protected: protected:
void onClose(Client *client, int failures) override; void onClose(Client *client, int failures) override;
void onJobReceived(Client *client, const Job &job) override; void onJobReceived(Client *client, const Job &job) override;
void onLoginSuccess(Client *client) override; void onLoginSuccess(Client *client) override;
void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override; void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) override;
private: private:
bool m_active; bool m_active;

View file

@ -27,14 +27,14 @@
#define APP_ID "xmrig" #define APP_ID "xmrig"
#define APP_NAME "XMRig" #define APP_NAME "XMRig"
#define APP_DESC "Monero (XMR) CPU miner" #define APP_DESC "Monero (XMR) CPU miner"
#define APP_VERSION "2.0.1" #define APP_VERSION "2.1.0-dev"
#define APP_DOMAIN "xmrig.com" #define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com" #define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com"
#define APP_VER_MAJOR 2 #define APP_VER_MAJOR 2
#define APP_VER_MINOR 0 #define APP_VER_MINOR 1
#define APP_VER_BUILD 1 #define APP_VER_BUILD 0
#define APP_VER_REV 0 #define APP_VER_REV 0
#ifdef _MSC_VER #ifdef _MSC_VER