Merge branch 'feature-daemon' into evo

This commit is contained in:
XMRig 2019-04-12 19:08:30 +07:00
commit 60f6817d21
37 changed files with 1142 additions and 364 deletions

View file

@ -11,6 +11,7 @@ set(HEADERS_BASE
src/base/kernel/config/BaseTransform.h
src/base/kernel/Entry.h
src/base/kernel/interfaces/IBaseListener.h
src/base/kernel/interfaces/IClient.h
src/base/kernel/interfaces/IClientListener.h
src/base/kernel/interfaces/IConfig.h
src/base/kernel/interfaces/IConfigListener.h
@ -29,6 +30,7 @@ set(HEADERS_BASE
src/base/net/dns/Dns.h
src/base/net/dns/DnsRecord.h
src/base/net/http/Http.h
src/base/net/stratum/BaseClient.h
src/base/net/stratum/Client.h
src/base/net/stratum/Job.h
src/base/net/stratum/Pool.h
@ -64,6 +66,7 @@ set(SOURCES_BASE
src/base/net/dns/Dns.cpp
src/base/net/dns/DnsRecord.cpp
src/base/net/http/Http.cpp
src/base/net/stratum/BaseClient.cpp
src/base/net/stratum/Client.cpp
src/base/net/stratum/Job.cpp
src/base/net/stratum/Pool.cpp
@ -105,6 +108,7 @@ if (WITH_HTTP)
src/base/net/http/HttpData.h
src/base/net/http/HttpResponse.h
src/base/net/http/HttpServer.h
src/base/net/stratum/DaemonClient.h
src/base/net/tools/TcpServer.h
)
@ -115,6 +119,7 @@ if (WITH_HTTP)
src/base/net/http/HttpContext.cpp
src/base/net/http/HttpResponse.cpp
src/base/net/http/HttpServer.cpp
src/base/net/stratum/DaemonClient.cpp
src/base/net/tools/TcpServer.cpp
)

View file

@ -161,6 +161,7 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
case IConfig::PrintTimeKey: /* --print-time */
case IConfig::HttpPort: /* --http-port */
case IConfig::DonateLevelKey: /* --donate-level */
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
# ifdef XMRIG_DEPRECATED
case IConfig::ApiPort: /* --api-port */
# endif
@ -173,6 +174,7 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
case IConfig::TlsKey: /* --tls */
case IConfig::DryRunKey: /* --dry-run */
case IConfig::HttpEnabledKey: /* --http-enabled */
case IConfig::DaemonKey: /* --daemon */
return transformBoolean(doc, key, true);
case IConfig::ColorKey: /* --no-color */
@ -204,6 +206,9 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
case IConfig::TlsKey: /* --tls */
return add(doc, kPools, "tls", enable);
case IConfig::DaemonKey: /* --daemon */
return add(doc, kPools, "daemon", enable);
# ifndef XMRIG_PROXY_PROJECT
case IConfig::NicehashKey: /* --nicehash */
return add<bool>(doc, kPools, "nicehash", enable);
@ -265,6 +270,9 @@ void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, ui
case IConfig::PrintTimeKey: /* --print-time */
return set(doc, "print-time", arg);
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
return add(doc, kPools, "daemon-poll-interval", arg);
default:
break;
}

View file

@ -0,0 +1,85 @@
/* 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 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_ICLIENT_H
#define XMRIG_ICLIENT_H
#include <stdint.h>
namespace xmrig {
class Algorithm;
class Job;
class JobResult;
class Pool;
class String;
class IClient
{
public:
enum Extension {
EXT_ALGO,
EXT_NICEHASH,
EXT_CONNECT,
EXT_TLS,
EXT_KEEPALIVE,
EXT_MAX
};
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;
};
} /* namespace xmrig */
#endif // XMRIG_ICLIENT_H

View file

@ -35,7 +35,7 @@
namespace xmrig {
class Client;
class IClient;
class Job;
class SubmitResult;
@ -45,11 +45,11 @@ class IClientListener
public:
virtual ~IClientListener() = default;
virtual void onClose(Client *client, int failures) = 0;
virtual void onJobReceived(Client *client, const Job &job, const rapidjson::Value &params) = 0;
virtual void onLogin(Client *client, rapidjson::Document &doc, rapidjson::Value &params) = 0;
virtual void onLoginSuccess(Client *client) = 0;
virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
virtual void onClose(IClient *client, int failures) = 0;
virtual void onJobReceived(IClient *client, const Job &job, const rapidjson::Value &params) = 0;
virtual void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value &params) = 0;
virtual void onLoginSuccess(IClient *client) = 0;
virtual void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) = 0;
};

View file

@ -70,6 +70,8 @@ public:
TlsKey = 1013,
FingerprintKey = 1014,
ProxyDonateKey = 1017,
DaemonKey = 1018,
DaemonPollKey = 1019,
# ifdef XMRIG_DEPRECATED
ApiPort = 4000,

View file

@ -33,7 +33,7 @@ namespace xmrig {
class Algorithm;
class Client;
class IClient;
class JobResult;
@ -43,7 +43,7 @@ public:
virtual ~IStrategy() = default;
virtual bool isActive() const = 0;
virtual Client *client() const = 0;
virtual IClient *client() const = 0;
virtual int64_t submit(const JobResult &result) = 0;
virtual void connect() = 0;
virtual void resume() = 0;

View file

@ -32,7 +32,7 @@
namespace xmrig {
class Client;
class IClient;
class IStrategy;
class Job;
class SubmitResult;
@ -43,10 +43,10 @@ class IStrategyListener
public:
virtual ~IStrategyListener() = default;
virtual void onActive(IStrategy *strategy, Client *client) = 0;
virtual void onJob(IStrategy *strategy, Client *client, const Job &job) = 0;
virtual void onActive(IStrategy *strategy, IClient *client) = 0;
virtual void onJob(IStrategy *strategy, IClient *client, const Job &job) = 0;
virtual void onPause(IStrategy *strategy) = 0;
virtual void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) = 0;
virtual void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) = 0;
};

View file

@ -40,11 +40,11 @@ namespace xmrig {
static const char *kCRLF = "\r\n";
class WriteBaton : public Baton<uv_write_t>
class ClientWriteBaton : public Baton<uv_write_t>
{
public:
inline WriteBaton(const std::string &header, std::string &&body) :
m_body(body),
inline ClientWriteBaton(const std::string &header, std::string &&body) :
m_body(std::move(body)),
m_header(header)
{
bufs[0].len = m_header.size();
@ -63,7 +63,7 @@ public:
inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; }
inline size_t size() const { return bufs[0].len + bufs[1].len; }
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<WriteBaton *>(req->data); }
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<ClientWriteBaton *>(req->data); }
uv_buf_t bufs[2];
@ -79,6 +79,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)
{
this->method = method;
@ -117,7 +118,9 @@ void xmrig::HttpClient::onResolved(const Dns &dns, int status)
this->status = status;
if (status < 0 && dns.isEmpty()) {
if (!m_quiet) {
LOG_ERR("[%s:%d] DNS error: \"%s\"", dns.host().data(), m_port, uv_strerror(status));
}
return;
}
@ -159,15 +162,15 @@ void xmrig::HttpClient::handshake()
void xmrig::HttpClient::read(const char *data, size_t size)
{
if (parse(data, size) < size) {
close();
close(UV_EPROTO);
}
}
void xmrig::HttpClient::write(const std::string &header)
{
WriteBaton *baton = new WriteBaton(header, std::move(body));
uv_write(&baton->req, stream(), baton->bufs, baton->count(), WriteBaton::onWrite);
ClientWriteBaton *baton = new ClientWriteBaton(header, std::move(body));
uv_write(&baton->req, stream(), baton->bufs, baton->count(), ClientWriteBaton::onWrite);
}
@ -180,10 +183,12 @@ void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
}
if (status < 0) {
if (!client->m_quiet) {
LOG_ERR("[%s:%d] connect error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(status));
}
delete req;
client->close();
client->close(status);
return;
}
@ -205,11 +210,11 @@ void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
if (nread >= 0) {
client->read(buf->base, static_cast<size_t>(nread));
} else {
if (nread != UV_EOF) {
if (!client->m_quiet && nread != UV_EOF) {
LOG_ERR("[%s:%d] read error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(static_cast<int>(nread)));
}
client->close();
client->close(static_cast<int>(nread));
}
delete [] buf->base;

View file

@ -45,6 +45,7 @@ public:
~HttpClient() override;
inline uint16_t port() const { return m_port; }
inline void setQuiet(bool quiet) { m_quiet = quiet; }
bool connect(const String &host, uint16_t port);
const String &host() const;
@ -56,6 +57,8 @@ protected:
virtual void read(const char *data, size_t size);
virtual void write(const std::string &header);
bool m_quiet;
private:
static void onConnect(uv_connect_t *req, int status);

View file

@ -96,8 +96,13 @@ std::string xmrig::HttpContext::ip() const
}
void xmrig::HttpContext::close()
void xmrig::HttpContext::close(int status)
{
if (status < 0 && m_listener) {
this->status = status;
m_listener->onHttpData(*this);
}
auto it = storage.find(id());
if (it != storage.end()) {
storage.erase(it);
@ -203,8 +208,9 @@ void xmrig::HttpContext::attach(http_parser_settings *settings)
settings->on_message_complete = [](http_parser *parser) -> int
{
const HttpContext *ctx = static_cast<const HttpContext*>(parser->data);
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
ctx->m_listener->onHttpData(*ctx);
ctx->m_listener = nullptr;
return 0;
};

View file

@ -56,7 +56,7 @@ public:
size_t parse(const char *data, size_t size);
std::string ip() const;
void close();
void close(int status = 0);
static HttpContext *get(uint64_t id);
static void closeAll();

View file

@ -29,15 +29,22 @@
#include <uv.h>
#include "base/io/log/Log.h"
#include "base/net/http/HttpsClient.h"
#include "base/tools/String.h"
#include "base/tools/Buffer.h"
xmrig::HttpsClient::HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) :
#ifdef _MSC_VER
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif
xmrig::HttpsClient::HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint) :
HttpClient(method, url, listener, data, size),
m_ready(false),
m_buf(),
m_ssl(nullptr)
m_ssl(nullptr),
m_fp(fingerprint)
{
m_ctx = SSL_CTX_new(SSLv23_method());
assert(m_ctx != nullptr);
@ -64,6 +71,18 @@ xmrig::HttpsClient::~HttpsClient()
}
const char *xmrig::HttpsClient::fingerprint() const
{
return m_ready ? m_fingerprint : nullptr;
}
const char *xmrig::HttpsClient::version() const
{
return m_ready ? SSL_get_version(m_ssl) : nullptr;
}
void xmrig::HttpsClient::handshake()
{
m_ssl = SSL_new(m_ctx);
@ -96,7 +115,7 @@ void xmrig::HttpsClient::read(const char *data, size_t size)
X509 *cert = SSL_get_peer_certificate(m_ssl);
if (!verify(cert)) {
X509_free(cert);
return close();
return close(UV_EPROTO);
}
X509_free(cert);
@ -118,13 +137,52 @@ void xmrig::HttpsClient::read(const char *data, size_t size)
void xmrig::HttpsClient::write(const std::string &header)
{
SSL_write(m_ssl, (header + body).c_str(), header.size() + body.size());
body.clear();
flush();
}
bool xmrig::HttpsClient::verify(X509 *cert) const
bool xmrig::HttpsClient::verify(X509 *cert)
{
return cert != nullptr;
if (cert == nullptr) {
return false;
}
if (!verifyFingerprint(cert)) {
if (!m_quiet) {
LOG_ERR("[%s:%d] Failed to verify server certificate fingerprint", host().data(), port());
if (strlen(m_fingerprint) == 64 && !m_fp.isNull()) {
LOG_ERR("\"%s\" was given", m_fingerprint);
LOG_ERR("\"%s\" was configured", m_fp.data());
}
}
return false;
}
return true;
}
bool xmrig::HttpsClient::verifyFingerprint(X509 *cert)
{
const EVP_MD *digest = EVP_get_digestbyname("sha256");
if (digest == nullptr) {
return false;
}
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int dlen;
if (X509_digest(cert, digest, md, &dlen) != 1) {
return false;
}
Buffer::toHex(md, 32, m_fingerprint);
return m_fp.isNull() || strncasecmp(m_fingerprint, m_fp.data(), 64) == 0;
}
@ -139,10 +197,10 @@ void xmrig::HttpsClient::flush()
bool result = false;
if (uv_is_writable(stream())) {
result = uv_try_write(stream(), &buf, 1) == buf.len;
result = uv_try_write(stream(), &buf, 1) == static_cast<int>(buf.len);
if (!result) {
close();
close(UV_EIO);
}
}

View file

@ -35,6 +35,7 @@ typedef struct x509_st X509;
#include "base/net/http/HttpClient.h"
#include "base/tools/String.h"
namespace xmrig {
@ -43,24 +44,30 @@ namespace xmrig {
class HttpsClient : public HttpClient
{
public:
HttpsClient(int method, const String &url, IHttpListener *listener, const char *data = nullptr, size_t size = 0);
HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint);
~HttpsClient() override;
const char *fingerprint() const;
const char *version() const;
protected:
void handshake() override;
void read(const char *data, size_t size) override;
void write(const std::string &header) override;
private:
bool verify(X509 *cert) const;
bool verify(X509 *cert);
bool verifyFingerprint(X509 *cert);
void flush();
BIO *m_readBio;
BIO *m_writeBio;
bool m_ready;
char m_buf[1024 * 2];
char m_fingerprint[32 * 2 + 8];
SSL *m_ssl;
SSL_CTX *m_ctx;
String m_fp;
};

View file

@ -0,0 +1,62 @@
/* 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 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/interfaces/IClientListener.h"
#include "base/net/stratum/BaseClient.h"
#include "base/net/stratum/SubmitResult.h"
namespace xmrig {
int64_t BaseClient::m_sequence = 1;
} /* namespace xmrig */
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)
{
}
bool xmrig::BaseClient::handleSubmitResponse(int64_t id, const char *error)
{
auto it = m_results.find(id);
if (it != m_results.end()) {
it->second.done();
m_listener->onResultAccepted(this, it->second, error);
m_results.erase(it);
return true;
}
return false;
}

View file

@ -0,0 +1,96 @@
/* 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 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_BASECLIENT_H
#define XMRIG_BASECLIENT_H
#include <map>
#include "base/kernel/interfaces/IClient.h"
#include "base/net/stratum/Job.h"
#include "base/net/stratum/Pool.h"
namespace xmrig {
class IClientListener;
class SubmitResult;
class BaseClient : public IClient
{
public:
BaseClient(int id, IClientListener *listener);
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 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; } }
inline void setQuiet(bool quiet) override { m_quiet = quiet; }
inline void setRetries(int retries) override { m_retries = retries; }
inline void setRetryPause(uint64_t ms) override { m_retryPause = ms; }
protected:
enum SocketState {
UnconnectedState,
HostLookupState,
ConnectingState,
ConnectedState,
ClosingState
};
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
bool handleSubmitResponse(int64_t id, const char *error = nullptr);
bool m_quiet;
IClientListener *m_listener;
int m_id;
int m_retries;
int64_t m_failures;
Job m_job;
Pool m_pool;
SocketState m_state;
std::map<int64_t, SubmitResult> m_results;
String m_ip;
uint64_t m_retryPause;
static int64_t m_sequence;
private:
bool m_enabled;
};
} /* namespace xmrig */
#endif /* XMRIG_BASECLIENT_H */

View file

@ -57,7 +57,6 @@
namespace xmrig {
int64_t Client::m_sequence = 1;
Storage<Client> Client::m_storage;
} /* namespace xmrig */
@ -75,16 +74,8 @@ static const char *states[] = {
xmrig::Client::Client(int id, const char *agent, IClientListener *listener) :
m_enabled(true),
m_ipv6(false),
m_quiet(false),
BaseClient(id, listener),
m_agent(agent),
m_listener(listener),
m_id(id),
m_retries(5),
m_retryPause(5000),
m_failures(0),
m_state(UnconnectedState),
m_tls(nullptr),
m_expire(0),
m_jobs(0),
@ -105,73 +96,6 @@ xmrig::Client::~Client()
}
void xmrig::Client::connect()
{
# ifdef XMRIG_FEATURE_TLS
if (m_pool.isTLS()) {
m_tls = new Tls(this);
}
# endif
resolve(m_pool.host());
}
/**
* @brief Connect to server.
*
* @param url
*/
void xmrig::Client::connect(const Pool &url)
{
setPool(url);
connect();
}
void xmrig::Client::deleteLater()
{
if (!m_listener) {
return;
}
m_listener = nullptr;
if (!disconnect()) {
m_storage.remove(m_key);
}
}
void xmrig::Client::setPool(const Pool &pool)
{
if (!pool.isValid()) {
return;
}
m_pool = pool;
}
void xmrig::Client::tick(uint64_t now)
{
if (m_state == ConnectedState) {
if (m_expire && now > m_expire) {
LOG_DEBUG_ERR("[%s] timeout", url());
close();
}
else if (m_keepAlive && now > m_keepAlive) {
ping();
}
}
if (m_expire && now > m_expire && m_state == ConnectingState) {
connect();
}
}
bool xmrig::Client::disconnect()
{
m_keepAlive = 0;
@ -269,6 +193,57 @@ int64_t xmrig::Client::submit(const JobResult &result)
}
void xmrig::Client::connect()
{
# ifdef XMRIG_FEATURE_TLS
if (m_pool.isTLS()) {
m_tls = new Tls(this);
}
# endif
resolve(m_pool.host());
}
void xmrig::Client::connect(const Pool &pool)
{
setPool(pool);
connect();
}
void xmrig::Client::deleteLater()
{
if (!m_listener) {
return;
}
m_listener = nullptr;
if (!disconnect()) {
m_storage.remove(m_key);
}
}
void xmrig::Client::tick(uint64_t now)
{
if (m_state == ConnectedState) {
if (m_expire && now > m_expire) {
LOG_DEBUG_ERR("[%s] timeout", url());
close();
}
else if (m_keepAlive && now > m_keepAlive) {
ping();
}
}
if (m_expire && now > m_expire && m_state == ConnectingState) {
connect();
}
}
void xmrig::Client::onResolved(const Dns &dns, int status)
{
assert(m_listener != nullptr);
@ -771,14 +746,8 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
if (error.IsObject()) {
const char *message = error["message"].GetString();
auto it = m_results.find(id);
if (it != m_results.end()) {
it->second.done();
m_listener->onResultAccepted(this, it->second, message);
m_results.erase(it);
}
else if (!isQuiet()) {
LOG_ERR("[%s] error: \"%s\", code: %d", url(), message, error["code"].GetInt());
if (!handleSubmitResponse(id, message) && !isQuiet()) {
LOG_ERR("[%s] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", url(), message, error["code"].GetInt());
}
if (isCriticalError(message)) {
@ -809,12 +778,7 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
return;
}
auto it = m_results.find(id);
if (it != m_results.end()) {
it->second.done();
m_listener->onResultAccepted(this, it->second, nullptr);
m_results.erase(it);
}
handleSubmitResponse(id);
}

View file

@ -34,6 +34,7 @@
#include "base/kernel/interfaces/IDnsListener.h"
#include "base/kernel/interfaces/ILineListener.h"
#include "base/net/stratum/BaseClient.h"
#include "base/net/stratum/Job.h"
#include "base/net/stratum/Pool.h"
#include "base/net/stratum/SubmitResult.h"
@ -42,7 +43,6 @@
#include "common/crypto/Algorithm.h"
typedef struct bio_st BIO;
@ -53,26 +53,9 @@ class IClientListener;
class JobResult;
class Client : public IDnsListener, public ILineListener
class Client : public BaseClient, public IDnsListener, public ILineListener
{
public:
enum SocketState {
UnconnectedState,
HostLookupState,
ConnectingState,
ConnectedState,
ClosingState
};
enum Extension {
EXT_ALGO,
EXT_NICEHASH,
EXT_CONNECT,
EXT_TLS,
EXT_KEEPALIVE,
EXT_MAX
};
constexpr static int kResponseTimeout = 20 * 1000;
# ifdef XMRIG_FEATURE_TLS
@ -84,39 +67,23 @@ public:
Client(int id, const char *agent, IClientListener *listener);
~Client() override;
bool disconnect();
bool isTLS() const;
const char *tlsFingerprint() const;
const char *tlsVersion() const;
int64_t submit(const JobResult &result);
void connect();
void connect(const Pool &pool);
void deleteLater();
void setPool(const Pool &pool);
void tick(uint64_t now);
inline bool isEnabled() const { return m_enabled; }
inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; }
inline const char *host() const { return m_pool.host(); }
inline const char *ip() const { return m_ip; }
inline const Job &job() const { return m_job; }
inline const Pool &pool() const { return m_pool; }
inline int id() const { return m_id; }
inline SocketState state() const { return m_state; }
inline uint16_t port() const { return m_pool.port(); }
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 setRetries(int retries) { m_retries = retries; }
inline void setRetryPause(int ms) { m_retryPause = ms; }
template<Extension ext> inline bool has() const noexcept { return m_extensions.test(ext); }
protected:
inline void onLine(char *line, size_t size) override { parse(line, size); }
bool disconnect() override;
bool isTLS() const override;
const char *tlsFingerprint() const override;
const char *tlsVersion() const override;
int64_t submit(const JobResult &result) override;
void connect() override;
void connect(const Pool &pool) override;
void deleteLater() override;
void tick(uint64_t now) override;
void onResolved(const Dns &dns, int status) override;
inline bool hasExtension(Extension extension) const noexcept override { return m_extensions.test(extension); }
inline const char *mode() const override { return "pool"; }
inline void onLine(char *line, size_t size) override { parse(line, size); }
private:
class Tls;
@ -143,9 +110,10 @@ private:
void setState(SocketState state);
void startTimeout();
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
inline const char *url() const { return m_pool.url(); }
inline SocketState state() const { return m_state; }
inline void setExtension(Extension ext, bool enable) noexcept { m_extensions.set(ext, enable); }
template<Extension ext> inline bool has() const noexcept { return m_extensions.test(ext); }
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
static void onClose(uv_handle_t *handle);
@ -154,24 +122,11 @@ private:
static inline Client *getClient(void *data) { return m_storage.get(data); }
bool m_enabled;
bool m_ipv6;
bool m_quiet;
char m_sendBuf[2048];
const char *m_agent;
Dns *m_dns;
IClientListener *m_listener;
int m_id;
int m_retries;
int m_retryPause;
int64_t m_failures;
Job m_job;
Pool m_pool;
RecvBuf<kInputBufferSize> m_recvBuf;
SocketState m_state;
std::bitset<EXT_MAX> m_extensions;
std::map<int64_t, SubmitResult> m_results;
String m_ip;
String m_rpcId;
Tls *m_tls;
uint64_t m_expire;
@ -181,7 +136,6 @@ private:
uv_stream_t *m_stream;
uv_tcp_t *m_socket;
static int64_t m_sequence;
static Storage<Client> m_storage;
};

View file

@ -0,0 +1,347 @@
/* 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/>.
*/
#include <algorithm>
#include <assert.h>
#include "3rdparty/http-parser/http_parser.h"
#include "base/io/Json.h"
#include "base/io/log/Log.h"
#include "base/kernel/interfaces/IClientListener.h"
#include "base/net/http/HttpClient.h"
#include "base/net/stratum/DaemonClient.h"
#include "base/net/stratum/SubmitResult.h"
#include "base/tools/Buffer.h"
#include "base/tools/Timer.h"
#include "net/JobResult.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
xmrig::DaemonClient::DaemonClient(int id, IClientListener *listener) :
BaseClient(id, listener)
{
m_timer = new Timer(this);
}
xmrig::DaemonClient::~DaemonClient()
{
delete m_timer;
}
bool xmrig::DaemonClient::disconnect()
{
setState(UnconnectedState);
return true;
}
bool xmrig::DaemonClient::isTLS() const
{
# ifdef XMRIG_FEATURE_TLS
return m_pool.isTLS();
# else
return false;
# endif
}
int64_t xmrig::DaemonClient::submit(const JobResult &result)
{
if (result.jobId != (m_blocktemplate.data() + m_blocktemplate.size() - 48)) {
return -1;
}
Buffer::toHex(reinterpret_cast<const uint8_t *>(&result.nonce), 4, m_blocktemplate.data() + 78);
using namespace rapidjson;
Document doc(kObjectType);
auto &allocator = doc.GetAllocator();
doc.AddMember("id", m_sequence, allocator);
doc.AddMember("jsonrpc", "2.0", allocator);
doc.AddMember("method", "submitblock", allocator);
Value params(kArrayType);
params.PushBack(m_blocktemplate.toJSON(), allocator);
doc.AddMember("params", params, allocator);
# ifdef XMRIG_PROXY_PROJECT
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
# else
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
# endif
send(HTTP_POST, "/json_rpc", doc);
return m_sequence++;
}
void xmrig::DaemonClient::connect()
{
setState(ConnectingState);
getBlockTemplate();
}
void xmrig::DaemonClient::connect(const Pool &pool)
{
setPool(pool);
connect();
}
void xmrig::DaemonClient::onHttpData(const HttpData &data)
{
if (data.status != HTTP_STATUS_OK) {
return retry();
}
LOG_DEBUG("[%s:%d] received (%d bytes): \"%.*s\"", m_pool.host().data(), m_pool.port(), static_cast<int>(data.body.size()), static_cast<int>(data.body.size()), data.body.c_str());
m_ip = static_cast<const HttpContext &>(data).ip().c_str();
if (isTLS()) {
m_tlsVersion = static_cast<const HttpsClient &>(data).version();
m_tlsFingerprint = static_cast<const HttpsClient &>(data).fingerprint();
}
rapidjson::Document doc;
if (doc.Parse(data.body.c_str()).HasParseError()) {
if (!isQuiet()) {
LOG_ERR("[%s:%d] JSON decode failed: \"%s\"", m_pool.host().data(), m_pool.port(), rapidjson::GetParseError_En(doc.GetParseError()));
}
return retry();
}
if (data.method == HTTP_GET && data.url == "/getheight") {
if (m_job.height() != Json::getUint64(doc, "height")) {
getBlockTemplate();
}
return;
}
if (!parseResponse(Json::getInt64(doc, "id", -1), Json::getObject(doc, "result"), Json::getObject(doc, "error"))) {
retry();
}
}
void xmrig::DaemonClient::onTimer(const Timer *)
{
if (m_state == ConnectingState) {
getBlockTemplate();
}
else if (m_state == ConnectedState) {
send(HTTP_GET, "/getheight");
}
}
bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
{
Job job(m_id, false, m_pool.algorithm(), String());
String blocktemplate = Json::getString(params, "blocktemplate_blob");
if (blocktemplate.isNull() || !job.setBlob(Json::getString(params, "blockhashing_blob"))) {
*code = 4;
return false;
}
job.setHeight(Json::getUint64(params, "height"));
job.setDiff(Json::getUint64(params, "difficulty"));
job.setId(blocktemplate.data() + blocktemplate.size() - 48);
m_job = std::move(job);
m_blocktemplate = std::move(blocktemplate);
if (m_state == ConnectingState) {
setState(ConnectedState);
}
m_listener->onJobReceived(this, m_job, params);
return true;
}
bool xmrig::DaemonClient::parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error)
{
if (id == -1) {
return false;
}
if (error.IsObject()) {
const char *message = error["message"].GetString();
if (!handleSubmitResponse(id, message) && !isQuiet()) {
LOG_ERR("[%s:%d] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", m_pool.host().data(), m_pool.port(), message, error["code"].GetInt());
}
return false;
}
if (!result.IsObject()) {
return false;
}
int code = -1;
if (result.HasMember("blocktemplate_blob") && parseJob(result, &code)) {
return true;
}
if (handleSubmitResponse(id)) {
getBlockTemplate();
return true;
}
return false;
}
int64_t xmrig::DaemonClient::getBlockTemplate()
{
using namespace rapidjson;
Document doc(kObjectType);
auto &allocator = doc.GetAllocator();
doc.AddMember("id", m_sequence, allocator);
doc.AddMember("jsonrpc", "2.0", allocator);
doc.AddMember("method", "getblocktemplate", allocator);
Value params(kObjectType);
params.AddMember("wallet_address", m_pool.user().toJSON(), allocator);
params.AddMember("reserve_size", 8, allocator);
doc.AddMember("params", params, allocator);
send(HTTP_POST, "/json_rpc", doc);
return m_sequence++;
}
void xmrig::DaemonClient::retry()
{
m_failures++;
m_listener->onClose(this, static_cast<int>(m_failures));
if (m_failures == -1) {
return;
}
if (m_state == ConnectedState) {
setState(ConnectingState);
}
m_timer->stop();
m_timer->start(m_retryPause, 0);
}
void xmrig::DaemonClient::send(int method, const char *url, const char *data, size_t size)
{
LOG_DEBUG("[%s:%d] " MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD_S " send (%zu bytes): \"%.*s\"",
m_pool.host().data(),
m_pool.port(),
http_method_str(static_cast<http_method>(method)),
url,
size,
static_cast<int>(size),
data);
HttpClient *client;
# ifdef XMRIG_FEATURE_TLS
if (m_pool.isTLS()) {
client = new HttpsClient(method, url, this, data, size, m_pool.fingerprint());
}
else
# endif
{
client = new HttpClient(method, url, this, data, size);
}
client->setQuiet(isQuiet());
client->connect(m_pool.host(), m_pool.port());
}
void xmrig::DaemonClient::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::DaemonClient::setState(SocketState state)
{
assert(m_state != state);
if (m_state == state) {
return;
}
m_state = state;
switch (state) {
case ConnectedState:
{
m_failures = 0;
m_listener->onLoginSuccess(this);
const uint64_t interval = std::max<uint64_t>(20, m_pool.pollInterval());
m_timer->start(interval, interval);
}
break;
case UnconnectedState:
m_failures = -1;
m_timer->stop();
break;
default:
break;
}
}

View file

@ -0,0 +1,80 @@
/* 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_DAEMONCLIENT_H
#define XMRIG_DAEMONCLIENT_H
#include "base/net/stratum/BaseClient.h"
#include "base/kernel/interfaces/ITimerListener.h"
#include "base/kernel/interfaces/IHttpListener.h"
namespace xmrig {
class DaemonClient : public BaseClient, public ITimerListener, public IHttpListener
{
public:
DaemonClient(int id, IClientListener *listener);
~DaemonClient() override;
protected:
bool disconnect() override;
bool isTLS() const override;
int64_t submit(const JobResult &result) override;
void connect() override;
void connect(const Pool &pool) override;
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 {}
private:
bool parseJob(const rapidjson::Value &params, int *code);
bool parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
int64_t 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(SocketState state);
String m_blocktemplate;
String m_tlsFingerprint;
String m_tlsVersion;
Timer *m_timer;
};
} /* namespace xmrig */
#endif /* XMRIG_DAEMONCLIENT_H */

View file

@ -7,6 +7,7 @@
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 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
@ -180,9 +181,10 @@ void xmrig::Job::setAlgorithm(const char *algo)
}
void xmrig::Job::setHeight(uint64_t height)
void xmrig::Job::setDiff(uint64_t diff)
{
m_height = height;
m_diff = diff;
m_target = toDiff(diff);
}

View file

@ -7,6 +7,7 @@
* 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 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
@ -53,7 +54,7 @@ public:
bool setBlob(const char *blob);
bool setTarget(const char *target);
void setAlgorithm(const char *algo);
void setHeight(uint64_t height);
void setDiff(uint64_t diff);
inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
@ -67,12 +68,13 @@ public:
inline int threadId() const { return m_threadId; }
inline size_t size() const { return m_size; }
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
inline uint32_t diff() const { return static_cast<uint32_t>(m_diff); }
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 void reset() { m_size = 0; m_diff = 0; }
inline void setClientId(const String &id) { m_clientId = id; }
inline void setHeight(uint64_t height) { m_height = height; }
inline void setPoolId(int poolId) { m_poolId = poolId; }
inline void setThreadId(int threadId) { m_threadId = threadId; }
inline void setVariant(const char *variant) { m_algorithm.parseVariant(variant); }

View file

@ -6,6 +6,7 @@
* 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
@ -41,12 +42,13 @@
#ifdef _MSC_VER
# define strncasecmp _strnicmp
# define strcasecmp _stricmp
#endif
namespace xmrig {
static const char *kDaemon = "daemon";
static const char *kDaemonPollInterval = "daemon-poll-interval";
static const char *kEnabled = "enabled";
static const char *kFingerprint = "tls-fingerprint";
static const char *kKeepalive = "keepalive";
@ -61,13 +63,22 @@ static const char *kVariant = "variant";
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_port(kDefaultPort),
m_pollInterval(kDefaultPollInterval)
{
}
@ -86,7 +97,8 @@ xmrig::Pool::Pool() :
xmrig::Pool::Pool(const char *url) :
m_keepAlive(0),
m_flags(1),
m_port(kDefaultPort)
m_port(kDefaultPort),
m_pollInterval(kDefaultPollInterval)
{
parse(url);
}
@ -95,7 +107,8 @@ xmrig::Pool::Pool(const char *url) :
xmrig::Pool::Pool(const rapidjson::Value &object) :
m_keepAlive(0),
m_flags(1),
m_port(kDefaultPort)
m_port(kDefaultPort),
m_pollInterval(kDefaultPollInterval)
{
if (!parse(Json::getString(object, kUrl))) {
return;
@ -105,10 +118,12 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
m_password = Json::getString(object, kPass);
m_rigId = Json::getString(object, kRigId);
m_fingerprint = Json::getString(object, kFingerprint);
m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval);
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)));
const rapidjson::Value &keepalive = Json::getValue(object, kKeepalive);
if (keepalive.IsInt()) {
@ -135,7 +150,8 @@ xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char
m_host(host),
m_password(password),
m_user(user),
m_port(port)
m_port(port),
m_pollInterval(kDefaultPollInterval)
{
const size_t size = m_host.size() + 8;
assert(size > 8);
@ -180,6 +196,12 @@ bool xmrig::Pool::isEnabled() const
}
# endif
# ifndef XMRIG_FEATURE_HTTP
if (isDaemon()) {
return false;
}
# endif
return m_flags.test(FLAG_ENABLED) && isValid() && algorithm().isValid();
}
@ -195,7 +217,8 @@ bool xmrig::Pool::isEqual(const Pool &other) const
&& m_password == other.m_password
&& m_rigId == other.m_rigId
&& m_url == other.m_url
&& m_user == other.m_user);
&& m_user == other.m_user
&& m_pollInterval == other.m_pollInterval);
}
@ -207,17 +230,29 @@ bool xmrig::Pool::parse(const char *url)
const char *base = url;
if (p) {
if (strncasecmp(url, "stratum+tcp://", 14) == 0) {
if (strncasecmp(url, kStratumTcp, sizeof(kStratumTcp) - 1) == 0) {
m_flags.set(FLAG_DAEMON, false);
m_flags.set(FLAG_TLS, false);
}
else if (strncasecmp(url, "stratum+ssl://", 14) == 0) {
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 = url + 14;
base = p + 3;
}
if (!strlen(base) || *base == '/') {
@ -289,6 +324,8 @@ 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(kDaemonPollInterval), m_pollInterval, allocator);
return obj;
}

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 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
@ -45,14 +46,16 @@ public:
FLAG_ENABLED,
FLAG_NICEHASH,
FLAG_TLS,
FLAG_DAEMON,
FLAG_MAX
};
static const String kDefaultPassword;
static const String kDefaultUser;
constexpr static uint16_t kDefaultPort = 3333;
constexpr static int kKeepAliveTimeout = 60;
constexpr static uint16_t kDefaultPort = 3333;
constexpr static uint64_t kDefaultPollInterval = 1000;
Pool();
Pool(const char *url);
@ -67,6 +70,7 @@ public:
);
inline Algorithm &algorithm() { return m_algorithm; }
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; }
@ -80,6 +84,7 @@ public:
inline const String &user() const { return !m_user.isNull() ? m_user : kDefaultUser; }
inline int keepAlive() const { return m_keepAlive; }
inline uint16_t port() const { return m_port; }
inline uint64_t pollInterval() const { return m_pollInterval; }
inline bool operator!=(const Pool &other) const { return !isEqual(other); }
inline bool operator==(const Pool &other) const { return isEqual(other); }
@ -116,6 +121,7 @@ private:
String m_url;
String m_user;
uint16_t m_port;
uint64_t m_pollInterval;
};

View file

@ -38,17 +38,17 @@ public:
inline SubmitResult() :
reqId(0),
seq(0),
diff(0),
actualDiff(0),
diff(0),
elapsed(0),
m_start(0)
{}
inline SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId = 0) :
inline SubmitResult(int64_t seq, uint64_t diff, uint64_t actualDiff, int64_t reqId = 0) :
reqId(reqId),
seq(seq),
diff(diff),
actualDiff(actualDiff),
diff(diff),
elapsed(0),
m_start(Chrono::steadyMSecs())
{}
@ -57,8 +57,8 @@ public:
int64_t reqId;
int64_t seq;
uint32_t diff;
uint64_t actualDiff;
uint64_t diff;
uint64_t elapsed;
private:

View file

@ -29,6 +29,11 @@
#include "common/Platform.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) :
m_quiet(quiet),
m_retries(retries),
@ -56,7 +61,7 @@ xmrig::FailoverStrategy::FailoverStrategy(int retryPause, int retries, IStrategy
xmrig::FailoverStrategy::~FailoverStrategy()
{
for (Client *client : m_pools) {
for (IClient *client : m_pools) {
client->deleteLater();
}
}
@ -64,7 +69,15 @@ xmrig::FailoverStrategy::~FailoverStrategy()
void xmrig::FailoverStrategy::add(const Pool &pool)
{
Client *client = new Client(static_cast<int>(m_pools.size()), Platform::userAgent(), this);
const int id = static_cast<int>(m_pools.size());
# 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);
@ -102,7 +115,7 @@ void xmrig::FailoverStrategy::resume()
void xmrig::FailoverStrategy::setAlgo(const xmrig::Algorithm &algo)
{
for (Client *client : m_pools) {
for (IClient *client : m_pools) {
client->setAlgo(algo);
}
}
@ -123,13 +136,13 @@ void xmrig::FailoverStrategy::stop()
void xmrig::FailoverStrategy::tick(uint64_t now)
{
for (Client *client : m_pools) {
for (IClient *client : m_pools) {
client->tick(now);
}
}
void xmrig::FailoverStrategy::onClose(Client *client, int failures)
void xmrig::FailoverStrategy::onClose(IClient *client, int failures)
{
if (failures == -1) {
return;
@ -150,7 +163,7 @@ void xmrig::FailoverStrategy::onClose(Client *client, int failures)
}
void xmrig::FailoverStrategy::onJobReceived(Client *client, const Job &job, const rapidjson::Value &)
void xmrig::FailoverStrategy::onJobReceived(IClient *client, const Job &job, const rapidjson::Value &)
{
if (m_active == client->id()) {
m_listener->onJob(this, client, job);
@ -158,7 +171,7 @@ void xmrig::FailoverStrategy::onJobReceived(Client *client, const Job &job, cons
}
void xmrig::FailoverStrategy::onLoginSuccess(Client *client)
void xmrig::FailoverStrategy::onLoginSuccess(IClient *client)
{
int active = m_active;
@ -179,7 +192,7 @@ void xmrig::FailoverStrategy::onLoginSuccess(Client *client)
}
void xmrig::FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
void xmrig::FailoverStrategy::onResultAccepted(IClient *client, const SubmitResult &result, const char *error)
{
m_listener->onResultAccepted(this, client, result, error);
}

View file

@ -52,8 +52,8 @@ public:
protected:
inline bool isActive() const override { return m_active >= 0; }
inline Client *client() const override { return active(); }
inline void onLogin(Client *, rapidjson::Document &, rapidjson::Value &) override {}
inline IClient *client() const override { return active(); }
inline void onLogin(IClient *, rapidjson::Document &, rapidjson::Value &) override {}
int64_t submit(const JobResult &result) override;
void connect() override;
@ -62,13 +62,13 @@ protected:
void stop() override;
void tick(uint64_t now) override;
void onClose(Client *client, int failures) override;
void onJobReceived(Client *client, const Job &job, const rapidjson::Value &params) override;
void onLoginSuccess(Client *client) override;
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
void onClose(IClient *client, int failures) override;
void onJobReceived(IClient *client, const Job &job, const rapidjson::Value &params) override;
void onLoginSuccess(IClient *client) override;
void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override;
private:
inline Client *active() const { return m_pools[static_cast<size_t>(m_active)]; }
inline IClient *active() const { return m_pools[static_cast<size_t>(m_active)]; }
const bool m_quiet;
const int m_retries;
@ -76,7 +76,7 @@ private:
int m_active;
IStrategyListener *m_listener;
size_t m_index;
std::vector<Client*> m_pools;
std::vector<IClient*> m_pools;
};

View file

@ -29,11 +29,26 @@
#include "common/Platform.h"
#ifdef XMRIG_FEATURE_HTTP
# include "base/net/stratum/DaemonClient.h"
#endif
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->setRetries(retries);
m_client->setRetryPause(retryPause * 1000);
@ -87,7 +102,7 @@ void xmrig::SinglePoolStrategy::tick(uint64_t now)
}
void xmrig::SinglePoolStrategy::onClose(Client *, int)
void xmrig::SinglePoolStrategy::onClose(IClient *, int)
{
if (!isActive()) {
return;
@ -98,20 +113,20 @@ void xmrig::SinglePoolStrategy::onClose(Client *, int)
}
void xmrig::SinglePoolStrategy::onJobReceived(Client *client, const Job &job, const rapidjson::Value &)
void xmrig::SinglePoolStrategy::onJobReceived(IClient *client, const Job &job, const rapidjson::Value &)
{
m_listener->onJob(this, client, job);
}
void xmrig::SinglePoolStrategy::onLoginSuccess(Client *client)
void xmrig::SinglePoolStrategy::onLoginSuccess(IClient *client)
{
m_active = true;
m_listener->onActive(this, client);
}
void xmrig::SinglePoolStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
void xmrig::SinglePoolStrategy::onResultAccepted(IClient *client, const SubmitResult &result, const char *error)
{
m_listener->onResultAccepted(this, client, result, error);
}

View file

@ -46,8 +46,8 @@ public:
protected:
inline bool isActive() const override { return m_active; }
inline Client *client() const override { return m_client; }
inline void onLogin(Client *, rapidjson::Document &, rapidjson::Value &) override {}
inline IClient *client() const override { return m_client; }
inline void onLogin(IClient *, rapidjson::Document &, rapidjson::Value &) override {}
int64_t submit(const JobResult &result) override;
void connect() override;
@ -56,14 +56,14 @@ protected:
void stop() override;
void tick(uint64_t now) override;
void onClose(Client *client, int failures) override;
void onJobReceived(Client *client, const Job &job, const rapidjson::Value &params) override;
void onLoginSuccess(Client *client) override;
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
void onClose(IClient *client, int failures) override;
void onJobReceived(IClient *client, const Job &job, const rapidjson::Value &params) override;
void onLoginSuccess(IClient *client) override;
void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override;
private:
bool m_active;
Client *m_client;
IClient *m_client;
IStrategyListener *m_listener;
};

View file

@ -82,6 +82,8 @@ static const option options[] = {
{ "tls", 0, nullptr, IConfig::TlsKey },
{ "tls-fingerprint", 1, nullptr, IConfig::FingerprintKey },
{ "asm", 1, nullptr, IConfig::AssemblyKey },
{ "daemon", 0, nullptr, IConfig::DaemonKey },
{ "daemon-poll-interval", 1, nullptr, IConfig::DaemonPollKey },
# ifdef XMRIG_DEPRECATED
{ "api-port", 1, nullptr, IConfig::ApiPort },

View file

@ -45,6 +45,10 @@ Options:\n\
"\
cryptonight-heavy\n"
#endif
#ifndef XMRIG_NO_CN_PICO
"\
cryptonight-pico\n"
#endif
"\
-o, --url=URL URL of mining server\n\
-O, --userpass=U:P username:password pair for mining server\n\
@ -54,9 +58,18 @@ Options:\n\
-t, --threads=N number of miner threads\n\
-v, --av=N algorithm variation, 0 auto select\n\
-k, --keepalive send keepalived packet for prevent timeout (needs pool support)\n\
--nicehash enable nicehash.com support\n\
--nicehash enable nicehash.com support\n"
#ifdef XMRIG_FEATURE_TLS
"\
--tls enable SSL/TLS support (needs pool support)\n\
--tls-fingerprint=F pool TLS certificate fingerprint, if set enable strict certificate pinning\n\
--tls-fingerprint=F pool TLS certificate fingerprint, if set enable strict certificate pinning\n"
#endif
#ifdef XMRIG_FEATURE_HTTP
"\
--daemon use daemon RPC instead of pool for solo mining\n\
--daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)\n"
#endif
"\
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
-R, --retry-pause=N time to pause between retries (default: 5)\n\
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
@ -74,17 +87,21 @@ Options:\n\
-S, --syslog use system log for output messages\n"
# endif
"\
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default: 100)\n\
--safe safe adjust threads and av settings for current CPU\n\
--asm=ASM ASM code for cn/2, possible values: auto, none, intel, ryzen, bulldozer.\n\
--print-time=N print hashrate report every N seconds\n\
--asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer.\n\
--print-time=N print hashrate report every N seconds\n"
#ifdef XMRIG_FEATURE_HTTP
"\
--api-worker-id=ID custom worker-id for API\n\
--api-id=ID custom instance ID for API\n\
--http-enabled enable HTTP API\n\
--http-host=HOST bind host for HTTP API (by default 127.0.0.1)\n\
--http-host=HOST bind host for HTTP API (default: 127.0.0.1)\n\
--http-port=N bind port for HTTP API\n\
--http-access-token=T access token for HTTP API\n\
--http-no-restricted enable full remote access to HTTP API (only if access token set)\n\
--http-no-restricted enable full remote access to HTTP API (only if access token set)\n"
#endif
"\
--dry-run test configuration and exit\n\
-h, --help display this help and exit\n\
-V, --version output version information and exit\n\

View file

@ -41,20 +41,20 @@ namespace xmrig {
class JobResult
{
public:
inline JobResult() : poolId(0), diff(0), nonce(0) {}
inline JobResult(int poolId, const String &jobId, const String &clientId, uint32_t nonce, const uint8_t *result, uint32_t diff, const Algorithm &algorithm) :
inline JobResult() : poolId(0), nonce(0), diff(0) {}
inline JobResult(int poolId, const String &jobId, const String &clientId, uint32_t nonce, const uint8_t *result, uint64_t diff, const Algorithm &algorithm) :
algorithm(algorithm),
poolId(poolId),
clientId(clientId),
jobId(jobId),
diff(diff),
nonce(nonce)
nonce(nonce),
diff(diff)
{
memcpy(this->result, result, sizeof(this->result));
}
inline JobResult(const Job &job) : poolId(0), diff(0), nonce(0)
inline JobResult(const Job &job) : poolId(0), nonce(0), diff(0)
{
jobId = job.id();
clientId = job.clientId();
@ -75,8 +75,8 @@ public:
int poolId;
String clientId;
String jobId;
uint32_t diff;
uint32_t nonce;
uint64_t diff;
uint8_t result[32];
};

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 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
@ -91,18 +92,18 @@ void xmrig::Network::connect()
}
void xmrig::Network::onActive(IStrategy *strategy, Client *client)
void xmrig::Network::onActive(IStrategy *strategy, IClient *client)
{
if (m_donate && m_donate == strategy) {
LOG_NOTICE("dev donate started");
return;
}
m_state.setPool(client->host(), client->port(), client->ip());
m_state.setPool(client->pool().host(), client->pool().port(), client->ip());
const char *tlsVersion = client->tlsVersion();
LOG_INFO(WHITE_BOLD("use pool ") CYAN_BOLD("%s:%d ") GREEN_BOLD("%s") " " BLACK_BOLD("%s"),
client->host(), client->port(), tlsVersion ? tlsVersion : "", client->ip());
LOG_INFO(WHITE_BOLD("use %s ") CYAN_BOLD("%s:%d ") GREEN_BOLD("%s") " " BLACK_BOLD("%s"),
client->mode(), client->pool().host().data(), client->pool().port(), tlsVersion ? tlsVersion : "", client->ip().data());
const char *fingerprint = client->tlsFingerprint();
if (fingerprint != nullptr) {
@ -127,7 +128,7 @@ void xmrig::Network::onConfigChanged(Config *config, Config *previousConfig)
}
void xmrig::Network::onJob(IStrategy *strategy, Client *client, const Job &job)
void xmrig::Network::onJob(IStrategy *strategy, IClient *client, const Job &job)
{
if (m_donate && m_donate->isActive() && m_donate != strategy) {
return;
@ -176,30 +177,30 @@ void xmrig::Network::onRequest(IApiRequest &request)
}
void xmrig::Network::onResultAccepted(IStrategy *, Client *, const SubmitResult &result, const char *error)
void xmrig::Network::onResultAccepted(IStrategy *, IClient *, const SubmitResult &result, const char *error)
{
m_state.add(result, error);
if (error) {
LOG_INFO(RED_BOLD("rejected") " (%" PRId64 "/%" PRId64 ") diff " WHITE_BOLD("%u") " " RED("\"%s\"") " " BLACK_BOLD("(%" PRIu64 " ms)"),
LOG_INFO(RED_BOLD("rejected") " (%" PRId64 "/%" PRId64 ") diff " WHITE_BOLD("%" PRIu64) " " RED("\"%s\"") " " BLACK_BOLD("(%" PRIu64 " ms)"),
m_state.accepted, m_state.rejected, result.diff, error, result.elapsed);
}
else {
LOG_INFO(GREEN_BOLD("accepted") " (%" PRId64 "/%" PRId64 ") diff " WHITE_BOLD("%u") " " BLACK_BOLD("(%" PRIu64 " ms)"),
LOG_INFO(GREEN_BOLD("accepted") " (%" PRId64 "/%" PRId64 ") diff " WHITE_BOLD("%" PRIu64) " " BLACK_BOLD("(%" PRIu64 " ms)"),
m_state.accepted, m_state.rejected, result.diff, result.elapsed);
}
}
void xmrig::Network::setJob(Client *client, const Job &job, bool donate)
void xmrig::Network::setJob(IClient *client, const Job &job, bool donate)
{
if (job.height()) {
LOG_INFO(MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s") " height " WHITE_BOLD("%" PRIu64),
client->host(), client->port(), job.diff(), job.algorithm().shortName(), job.height());
LOG_INFO(MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%" PRIu64) " algo " WHITE_BOLD("%s") " height " WHITE_BOLD("%" PRIu64),
client->pool().host().data(), client->pool().port(), job.diff(), job.algorithm().shortName(), job.height());
}
else {
LOG_INFO(MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s"),
client->host(), client->port(), job.diff(), job.algorithm().shortName());
LOG_INFO(MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%" PRIu64) " algo " WHITE_BOLD("%s"),
client->pool().host().data(), client->pool().port(), job.diff(), job.algorithm().shortName());
}
if (!donate && m_donate) {

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 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
@ -58,18 +59,18 @@ public:
protected:
inline void onTimer(const Timer *) override { tick(); }
void onActive(IStrategy *strategy, Client *client) override;
void onActive(IStrategy *strategy, IClient *client) override;
void onConfigChanged(Config *config, Config *previousConfig) override;
void onJob(IStrategy *strategy, Client *client, const Job &job) override;
void onJob(IStrategy *strategy, IClient *client, const Job &job) override;
void onJobResult(const JobResult &result) override;
void onPause(IStrategy *strategy) override;
void onRequest(IApiRequest &request) override;
void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) override;
private:
constexpr static int kTickInterval = 1 * 1000;
void setJob(Client *client, const Job &job, bool donate);
void setJob(IClient *client, const Job &job, bool donate);
void tick();
# ifdef XMRIG_FEATURE_API

View file

@ -35,14 +35,14 @@
xmrig::NetworkState::NetworkState() :
diff(0),
pool(),
accepted(0),
diff(0),
failures(0),
rejected(0),
total(0),
m_active(false)
{
memset(pool, 0, sizeof(pool));
}

View file

@ -50,8 +50,8 @@ public:
char pool[256];
std::array<uint64_t, 10> topDiff { { } };
uint32_t diff;
uint64_t accepted;
uint64_t diff;
uint64_t failures;
uint64_t rejected;
uint64_t total;

View file

@ -157,7 +157,7 @@ void xmrig::DonateStrategy::tick(uint64_t now)
}
void xmrig::DonateStrategy::onActive(IStrategy *, Client *client)
void xmrig::DonateStrategy::onActive(IStrategy *, IClient *client)
{
if (isActive()) {
return;
@ -173,7 +173,7 @@ void xmrig::DonateStrategy::onPause(IStrategy *)
}
void xmrig::DonateStrategy::onClose(Client *, int failures)
void xmrig::DonateStrategy::onClose(IClient *, int failures)
{
if (failures == 2 && m_controller->config()->pools().proxyDonate() == Pools::PROXY_DONATE_AUTO) {
m_proxy->deleteLater();
@ -184,7 +184,7 @@ void xmrig::DonateStrategy::onClose(Client *, int failures)
}
void xmrig::DonateStrategy::onLogin(Client *, rapidjson::Document &doc, rapidjson::Value &params)
void xmrig::DonateStrategy::onLogin(IClient *, rapidjson::Document &doc, rapidjson::Value &params)
{
auto &allocator = doc.GetAllocator();
@ -203,7 +203,7 @@ void xmrig::DonateStrategy::onLogin(Client *, rapidjson::Document &doc, rapidjso
}
void xmrig::DonateStrategy::onLoginSuccess(Client *client)
void xmrig::DonateStrategy::onLoginSuccess(IClient *client)
{
if (isActive()) {
return;
@ -227,14 +227,14 @@ xmrig::Client *xmrig::DonateStrategy::createProxy()
}
IStrategy *strategy = m_controller->network()->strategy();
if (!strategy->isActive() || !strategy->client()->has<Client::EXT_CONNECT>()) {
if (!strategy->isActive() || !strategy->client()->hasExtension(IClient::EXT_CONNECT)) {
return nullptr;
}
const Client *client = strategy->client();
m_tls = client->has<Client::EXT_TLS>();
const IClient *client = strategy->client();
m_tls = client->hasExtension(IClient::EXT_TLS);
Pool pool(client->ip(), client->port(), m_userId, client->pool().password(), 0, true, client->isTLS());
Pool pool(client->ip(), client->pool().port(), m_userId, client->pool().password(), 0, true, client->isTLS());
pool.setAlgo(client->pool().algorithm());
Client *proxy = new Client(-1, Platform::userAgent(), this);
@ -251,7 +251,7 @@ void xmrig::DonateStrategy::idle(double min, double max)
}
void xmrig::DonateStrategy::setJob(Client *client, const Job &job)
void xmrig::DonateStrategy::setJob(IClient *client, const Job &job)
{
if (isActive()) {
m_listener->onJob(this, client, job);
@ -259,7 +259,7 @@ void xmrig::DonateStrategy::setJob(Client *client, const Job &job)
}
void xmrig::DonateStrategy::setResult(Client *client, const SubmitResult &result, const char *error)
void xmrig::DonateStrategy::setResult(IClient *client, const SubmitResult &result, const char *error)
{
m_listener->onResultAccepted(this, client, result, error);
}

View file

@ -52,11 +52,11 @@ public:
protected:
inline bool isActive() const override { return state() == STATE_ACTIVE; }
inline Client *client() const override { return m_proxy ? m_proxy : m_strategy->client(); }
inline void onJob(IStrategy *, Client *client, const Job &job) override { setJob(client, job); }
inline void onJobReceived(Client *client, const Job &job, const rapidjson::Value &) override { setJob(client, job); }
inline void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); }
inline void onResultAccepted(IStrategy *, Client *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); }
inline IClient *client() const override { return m_proxy ? m_proxy : m_strategy->client(); }
inline void onJob(IStrategy *, IClient *client, const Job &job) override { setJob(client, job); }
inline void onJobReceived(IClient *client, const Job &job, const rapidjson::Value &) override { setJob(client, job); }
inline void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); }
inline void onResultAccepted(IStrategy *, IClient *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); }
inline void resume() override {}
int64_t submit(const JobResult &result) override;
@ -65,12 +65,12 @@ protected:
void stop() override;
void tick(uint64_t now) override;
void onActive(IStrategy *strategy, Client *client) override;
void onActive(IStrategy *strategy, IClient *client) override;
void onPause(IStrategy *strategy) override;
void onClose(Client *client, int failures) override;
void onLogin(Client *client, rapidjson::Document &doc, rapidjson::Value &params) override;
void onLoginSuccess(Client *client) override;
void onClose(IClient *client, int failures) override;
void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value &params) override;
void onLoginSuccess(IClient *client) override;
void onTimer(const Timer *timer) override;
@ -87,13 +87,13 @@ private:
Client *createProxy();
void idle(double min, double max);
void setJob(Client *client, const Job &job);
void setResult(Client *client, const SubmitResult &result, const char *error);
void setJob(IClient *client, const Job &job);
void setResult(IClient *client, const SubmitResult &result, const char *error);
void setState(State state);
bool m_tls;
char m_userId[65];
Client *m_proxy;
IClient *m_proxy;
const uint64_t m_donateTime;
const uint64_t m_idleTime;
Controller *m_controller;