From 952017ae7a3164d76b12af3b1b121a11915d9216 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 26 Jun 2017 21:13:05 +0300 Subject: [PATCH 1/9] Initial multiple pools support [1/2]. --- src/Options.cpp | 73 ++++++++++++++---------------- src/Options.h | 44 +++++++++---------- src/Summary.cpp | 19 ++++---- src/net/Network.cpp | 6 +-- src/net/Url.cpp | 105 +++++++++++++++++++++++++++++++------------- src/net/Url.h | 26 ++++++++--- 6 files changed, 162 insertions(+), 111 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 5929d0627..3c636cece 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -150,7 +150,6 @@ Options::Options(int argc, char **argv) : m_syslog(false), m_logFile(nullptr), m_pass(nullptr), - m_user(nullptr), m_algo(0), m_algoVariant(0), m_donateLevel(kDonateLevel), @@ -159,10 +158,10 @@ Options::Options(int argc, char **argv) : m_retries(5), m_retryPause(5), m_threads(0), - m_affinity(-1L), - m_backupUrl(nullptr), - m_url(nullptr) + m_affinity(-1L) { + m_pools.push_back(new Url()); + int key; while (1) { @@ -181,18 +180,18 @@ Options::Options(int argc, char **argv) : return; } - if (!m_url) { + if (!m_pools[0]->isValid()) { fprintf(stderr, "No pool URL supplied. Exiting."); return; } - if (!m_nicehash && m_url->isNicehash()) { - m_nicehash = true; - } +// if (!m_nicehash && m_url->isNicehash()) { +// m_nicehash = true; +// } - if (!m_user) { - m_user = strdup("x"); - } +// if (!m_user) { +// m_user = strdup("x"); +// } if (!m_pass) { m_pass = strdup("x"); @@ -219,10 +218,6 @@ Options::Options(int argc, char **argv) : Options::~Options() { - delete m_url; - delete m_backupUrl; - - free(m_user); free(m_pass); } @@ -232,7 +227,6 @@ bool Options::parseArg(int key, char *arg) char *p; int v; uint64_t ul; - Url *url; switch (key) { case 'a': /* --algo */ @@ -248,29 +242,26 @@ bool Options::parseArg(int key, char *arg) break; case 'o': /* --url */ - url = parseUrl(arg); - if (url) { - free(m_url); - m_url = url; + if (m_pools[0]->isValid()) { + Url *url = new Url(arg); + if (url->isValid()) { + m_pools.push_back(url); + } + else { + delete url; + } } - break; - - case 'b': /* --backup-url */ - url = parseUrl(arg); - if (url) { - free(m_backupUrl); - m_backupUrl = url; + else { + m_pools[0]->parse(arg); } break; case 'u': /* --user */ - free(m_user); - m_user = strdup(arg); + m_pools.back()->setUser(arg); break; case 'p': /* --pass */ - free(m_pass); - m_pass = strdup(arg); + m_pools.back()->setPassword(arg); break; case 'l': /* --log-file */ @@ -485,18 +476,18 @@ bool Options::setAlgo(const char *algo) bool Options::setUserpass(const char *userpass) { - const char *p = strchr(userpass, ':'); - if (!p) { - showUsage(1); - return false; - } +// const char *p = strchr(userpass, ':'); +// if (!p) { +// showUsage(1); +// return false; +// } - free(m_user); - free(m_pass); +//// free(m_user); +// free(m_pass); - m_user = static_cast(calloc(p - userpass + 1, 1)); - strncpy(m_user, userpass, p - userpass); - m_pass = strdup(p + 1); +//// m_user = static_cast(calloc(p - userpass + 1, 1)); +// strncpy(m_user, userpass, p - userpass); +// m_pass = strdup(p + 1); return true; } diff --git a/src/Options.h b/src/Options.h index 907819b7f..e2e6c9f9b 100644 --- a/src/Options.h +++ b/src/Options.h @@ -25,6 +25,7 @@ #define __OPTIONS_H__ +#include #include @@ -51,26 +52,24 @@ public: static inline Options* i() { return m_self; } static Options *parse(int argc, char **argv); - inline bool background() const { return m_background; } - inline bool colors() const { return m_colors; } - inline bool doubleHash() const { return m_doubleHash; } - inline bool isReady() const { return m_ready; } - inline bool keepAlive() const { return m_keepAlive; } - inline bool nicehash() const { return m_nicehash; } - inline bool syslog() const { return m_syslog; } - inline const char *logFile() const { return m_logFile; } - inline const char *pass() const { return m_pass; } - inline const char *user() const { return m_user; } - inline const Url *backupUrl() const { return m_backupUrl; } - inline const Url *url() const { return m_url; } - inline int algo() const { return m_algo; } - inline int algoVariant() const { return m_algoVariant; } - inline int donateLevel() const { return m_donateLevel; } - inline int printTime() const { return m_printTime; } - inline int retries() const { return m_retries; } - inline int retryPause() const { return m_retryPause; } - inline int threads() const { return m_threads; } - inline int64_t affinity() const { return m_affinity; } + inline bool background() const { return m_background; } + inline bool colors() const { return m_colors; } + inline bool doubleHash() const { return m_doubleHash; } + inline bool isReady() const { return m_ready; } + inline bool keepAlive() const { return m_keepAlive; } + inline bool nicehash() const { return m_nicehash; } + inline bool syslog() const { return m_syslog; } + inline const char *logFile() const { return m_logFile; } + inline const char *pass() const { return m_pass; } + inline const std::vector &pools() const { return m_pools; } + inline int algo() const { return m_algo; } + inline int algoVariant() const { return m_algoVariant; } + inline int donateLevel() const { return m_donateLevel; } + inline int printTime() const { return m_printTime; } + inline int retries() const { return m_retries; } + inline int retryPause() const { return m_retryPause; } + inline int threads() const { return m_threads; } + inline int64_t affinity() const { return m_affinity; } const char *algoName() const; @@ -103,7 +102,7 @@ private: bool m_syslog; char *m_logFile; char *m_pass; - char *m_user; +// char *m_user; int m_algo; int m_algoVariant; int m_donateLevel; @@ -113,8 +112,7 @@ private: int m_retryPause; int m_threads; int64_t m_affinity; - Url *m_backupUrl; - Url *m_url; + std::vector m_pools; }; #endif /* __OPTIONS_H__ */ diff --git a/src/Summary.cpp b/src/Summary.cpp index a243d9deb..54630e8c4 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -111,17 +111,20 @@ static void print_threads() static void print_pools() { - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #1: \x1B[01;36m%s:%d" : " * POOL #1: %s:%d", - Options::i()->url()->host(), - Options::i()->url()->port()); + const std::vector &pools = Options::i()->pools(); - if (!Options::i()->backupUrl()) { - return; + for (size_t i = 0; i < pools.size(); ++i) { + Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s:%d" : " * POOL #%d: %s:%d", + i + 1, + pools[i]->host(), + pools[i]->port()); } - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #2: \x1B[01;36m%s:%d" : " * POOL #2: %s:%d", - Options::i()->backupUrl()->host(), - Options::i()->backupUrl()->port()); +# ifdef APP_DEBUG + for (size_t i = 0; i < pools.size(); ++i) { + Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i]->host(), pools[i]->port(), pools[i]->user(), pools[i]->password(), pools[i]->isKeepAlive(), pools[i]->isNicehash()); + } +# endif } diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 8de785bd9..903ed8268 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -45,8 +45,8 @@ Network::Network(const Options *options) : m_agent = userAgent(); addPool(std::make_unique().get()); - addPool(m_options->url()); - addPool(m_options->backupUrl()); +// addPool(m_options->url()); +// addPool(m_options->backupUrl()); m_timer.data = this; uv_timer_init(uv_default_loop(), &m_timer); @@ -120,7 +120,7 @@ void Network::onJobResult(const JobResult &result) void Network::onLoginCredentialsRequired(Client *client) { - client->login(m_options->user(), m_options->pass(), m_agent); +// client->login(m_options->user(), m_options->pass(), m_agent); } diff --git a/src/net/Url.cpp b/src/net/Url.cpp index d8264c20e..96376d051 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -35,8 +35,12 @@ Url::Url() : + m_keepAlive(false), + m_nicehash(false), m_host(nullptr), - m_port(3333) + m_password(nullptr), + m_user(nullptr), + m_port(kDefaultPort) { } @@ -53,40 +57,22 @@ Url::Url() : * @param url */ Url::Url(const char *url) : + m_keepAlive(false), + m_nicehash(false), m_host(nullptr), - m_port(3333) + m_password(nullptr), + m_user(nullptr), + m_port(kDefaultPort) { - const char *p = strstr(url, "://"); - const char *base = url; - - if (p) { - if (strncasecmp(url, "stratum+tcp://", 14)) { - return; - } - - base = url + 14; - } - - if (!strlen(base) || *base == '/') { - return; - } - - const char *port = strchr(base, ':'); - if (!port) { - m_host = strdup(base); - return; - } - - const size_t size = port++ - base + 1; - m_host = static_cast(malloc(size)); - memcpy(m_host, base, size - 1); - m_host[size - 1] = '\0'; - - m_port = strtol(port, nullptr, 10); + parse(url); } -Url::Url(const char *host, uint16_t port) : +Url::Url(const char *host, uint16_t port, const char *user, const char *password, bool keepAlive, bool nicehash) : + m_keepAlive(false), + m_nicehash(false), + m_password(nullptr), + m_user(nullptr), m_port(port) { m_host = strdup(host); @@ -96,10 +82,67 @@ Url::Url(const char *host, uint16_t port) : Url::~Url() { free(m_host); + free(m_password); + free(m_user); } bool Url::isNicehash() const { - return isValid() && strstr(m_host, ".nicehash.com"); + return isValid() && (m_nicehash || strstr(m_host, ".nicehash.com")); +} + + +bool Url::parse(const char *url) +{ + const char *p = strstr(url, "://"); + const char *base = url; + + if (p) { + if (strncasecmp(url, "stratum+tcp://", 14)) { + return false; + } + + base = url + 14; + } + + if (!strlen(base) || *base == '/') { + return false; + } + + const char *port = strchr(base, ':'); + if (!port) { + m_host = strdup(base); + return false; + } + + const size_t size = port++ - base + 1; + m_host = static_cast(malloc(size)); + memcpy(m_host, base, size - 1); + m_host[size - 1] = '\0'; + + m_port = strtol(port, nullptr, 10); + return true; +} + + +void Url::setPassword(const char *password, bool force) +{ + if (m_password != nullptr && !force) { + return; + } + + free(m_password); + m_password = strdup(password); +} + + +void Url::setUser(const char *user, bool force) +{ + if (m_user != nullptr && !force) { + return; + } + + free(m_user); + m_user = strdup(user); } diff --git a/src/net/Url.h b/src/net/Url.h index 7d44501d2..bac2a564c 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -31,19 +31,35 @@ class Url { public: + constexpr static const char *kDefaultPassword = "x"; + constexpr static const char *kDefaultUser = "x"; + constexpr static uint16_t kDefaultPort = 3333; + Url(); Url(const char *url); - Url(const char *host, uint16_t port); + Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, bool keepAlive = false, bool nicehash = false ); ~Url(); - bool isNicehash() const; + inline bool isKeepAlive() const { return m_keepAlive; } + inline bool isValid() const { return m_host && m_port > 0; } + inline const char *host() const { return m_host; } + inline const char *password() const { return m_password ? m_password : kDefaultPassword; } + inline const char *user() const { return m_user ? m_user : kDefaultUser; } + inline uint16_t port() const { return m_port; } + inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; } + inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } - inline bool isValid() const { return m_host && m_port > 0; } - inline const char *host() const { return m_host; } - inline uint16_t port() const { return m_port; } + bool isNicehash() const; + bool parse(const char *url); + void setPassword(const char *password, bool force = true); + void setUser(const char *user, bool force = true); private: + bool m_keepAlive; + bool m_nicehash; char *m_host; + char *m_password; + char *m_user; uint16_t m_port; }; From c0dcfc2a9737ec9df88102ed583a2042aa7c4136 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 27 Jun 2017 06:32:17 +0300 Subject: [PATCH 2/9] Initial multiple pools support [2/2]. --- src/App.cpp | 2 +- src/Options.cpp | 49 +++++++++------------------------------------ src/Options.h | 8 -------- src/Summary.cpp | 4 ++-- src/net/Network.cpp | 6 +++--- src/net/Url.cpp | 18 +++++++++++++++++ src/net/Url.h | 2 +- 7 files changed, 35 insertions(+), 54 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 58f6c3500..4d3305ff2 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -105,7 +105,7 @@ int App::exec() Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash()); Summary::print(); - Workers::start(m_options->affinity(), m_options->nicehash()); + Workers::start(m_options->affinity(), false); m_network->connect(); diff --git a/src/Options.cpp b/src/Options.cpp index 3c636cece..6230f03cf 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -143,13 +143,10 @@ Options::Options(int argc, char **argv) : m_background(false), m_colors(true), m_doubleHash(false), - m_keepAlive(false), - m_nicehash(false), m_ready(false), m_safe(false), m_syslog(false), m_logFile(nullptr), - m_pass(nullptr), m_algo(0), m_algoVariant(0), m_donateLevel(kDonateLevel), @@ -185,18 +182,6 @@ Options::Options(int argc, char **argv) : return; } -// if (!m_nicehash && m_url->isNicehash()) { -// m_nicehash = true; -// } - -// if (!m_user) { -// m_user = strdup("x"); -// } - - if (!m_pass) { - m_pass = strdup("x"); - } - m_algoVariant = getAlgoVariant(); if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) { m_doubleHash = true; @@ -218,7 +203,6 @@ Options::Options(int argc, char **argv) : Options::~Options() { - free(m_pass); } @@ -236,13 +220,14 @@ bool Options::parseArg(int key, char *arg) break; case 'O': /* --userpass */ - if (!setUserpass(arg)) { + if (!m_pools.back()->setUserpass(arg)) { return false; } + break; case 'o': /* --url */ - if (m_pools[0]->isValid()) { + if (m_pools.size() > 1 || m_pools[0]->isValid()) { Url *url = new Url(arg); if (url->isValid()) { m_pools.push_back(url); @@ -254,6 +239,11 @@ bool Options::parseArg(int key, char *arg) else { m_pools[0]->parse(arg); } + + if (!m_pools.back()->isValid()) { + return false; + } + break; case 'u': /* --user */ @@ -315,7 +305,7 @@ bool Options::parseArg(int key, char *arg) break; case 'k': /* --keepalive */ - m_keepAlive = true; + m_pools.back()->setKeepAlive(true); break; case 'V': /* --version */ @@ -371,7 +361,7 @@ bool Options::parseArg(int key, char *arg) break; case 1006: /* --nicehash */ - m_nicehash = true; + m_pools.back()->setNicehash(true); break; case 1007: /* --print-time */ @@ -474,25 +464,6 @@ bool Options::setAlgo(const char *algo) } -bool Options::setUserpass(const char *userpass) -{ -// const char *p = strchr(userpass, ':'); -// if (!p) { -// showUsage(1); -// return false; -// } - -//// free(m_user); -// free(m_pass); - -//// m_user = static_cast(calloc(p - userpass + 1, 1)); -// strncpy(m_user, userpass, p - userpass); -// m_pass = strdup(p + 1); - - return true; -} - - int Options::getAlgoVariant() const { # ifndef XMRIG_NO_AEON diff --git a/src/Options.h b/src/Options.h index e2e6c9f9b..cefca538f 100644 --- a/src/Options.h +++ b/src/Options.h @@ -56,11 +56,8 @@ public: inline bool colors() const { return m_colors; } inline bool doubleHash() const { return m_doubleHash; } inline bool isReady() const { return m_ready; } - inline bool keepAlive() const { return m_keepAlive; } - inline bool nicehash() const { return m_nicehash; } inline bool syslog() const { return m_syslog; } inline const char *logFile() const { return m_logFile; } - inline const char *pass() const { return m_pass; } inline const std::vector &pools() const { return m_pools; } inline int algo() const { return m_algo; } inline int algoVariant() const { return m_algoVariant; } @@ -85,7 +82,6 @@ private: void showVersion(void); bool setAlgo(const char *algo); - bool setUserpass(const char *userpass); int getAlgoVariant() const; # ifndef XMRIG_NO_AEON @@ -95,14 +91,10 @@ private: bool m_background; bool m_colors; bool m_doubleHash; - bool m_keepAlive; - bool m_nicehash; bool m_ready; bool m_safe; bool m_syslog; char *m_logFile; - char *m_pass; -// char *m_user; int m_algo; int m_algoVariant; int m_donateLevel; diff --git a/src/Summary.cpp b/src/Summary.cpp index 54630e8c4..9eb195d3b 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -100,12 +100,12 @@ static void print_threads() buf[0] = '\0'; } - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s%s" : " * THREADS: %d, %s, av=%d, donate=%d%%%s%s", + Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s" : " * THREADS: %d, %s, av=%d, donate=%d%%%s", Options::i()->threads(), Options::i()->algoName(), Options::i()->algoVariant(), Options::i()->donateLevel(), - Options::i()->nicehash() ? ", nicehash" : "", buf); + buf); } diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 903ed8268..eddfc3bed 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -45,7 +45,7 @@ Network::Network(const Options *options) : m_agent = userAgent(); addPool(std::make_unique().get()); -// addPool(m_options->url()); + addPool(m_options->pools().front()); // addPool(m_options->backupUrl()); m_timer.data = this; @@ -120,7 +120,7 @@ void Network::onJobResult(const JobResult &result) void Network::onLoginCredentialsRequired(Client *client) { -// client->login(m_options->user(), m_options->pass(), m_agent); + client->login(m_options->pools().front()->password(), m_options->pools().front()->password(), m_agent); } @@ -154,7 +154,7 @@ void Network::addPool(const Url *url) Client *client = new Client(m_pools.size(), this); client->setUrl(url); client->setRetryPause(m_options->retryPause() * 1000); - client->setKeepAlive(m_options->keepAlive()); +// client->setKeepAlive(m_options->keepAlive()); m_pools.push_back(client); } diff --git a/src/net/Url.cpp b/src/net/Url.cpp index 96376d051..3f8ca54e3 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -126,6 +126,24 @@ bool Url::parse(const char *url) } +bool Url::setUserpass(const char *userpass) +{ + const char *p = strchr(userpass, ':'); + if (!p) { + return false; + } + + free(m_user); + free(m_password); + + m_user = static_cast(calloc(p - userpass + 1, 1)); + strncpy(m_user, userpass, p - userpass); + m_password = strdup(p + 1); + + return true; +} + + void Url::setPassword(const char *password, bool force) { if (m_password != nullptr && !force) { diff --git a/src/net/Url.h b/src/net/Url.h index bac2a564c..639df7cd5 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -51,9 +51,9 @@ public: bool isNicehash() const; bool parse(const char *url); + bool setUserpass(const char *userpass); void setPassword(const char *password, bool force = true); void setUser(const char *user, bool force = true); - private: bool m_keepAlive; bool m_nicehash; From b2d26eb019b6e812838f6706fc45b7a10d1366b3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 28 Jun 2017 04:04:04 +0300 Subject: [PATCH 3/9] Use Url inside Client. Remove onLoginCredentialsRequired from IClientListener interface. --- src/interfaces/IClientListener.h | 1 - src/net/Client.cpp | 75 +++++++++++++++----------------- src/net/Client.h | 17 +++----- src/net/Network.cpp | 8 +--- src/net/Network.h | 1 - src/net/Url.cpp | 28 +++++++----- src/net/Url.h | 7 ++- 7 files changed, 66 insertions(+), 71 deletions(-) diff --git a/src/interfaces/IClientListener.h b/src/interfaces/IClientListener.h index 570190359..7a5743d2c 100644 --- a/src/interfaces/IClientListener.h +++ b/src/interfaces/IClientListener.h @@ -36,7 +36,6 @@ public: virtual void onClose(Client *client, int failures) = 0; virtual void onJobReceived(Client *client, const Job &job) = 0; - virtual void onLoginCredentialsRequired(Client *client) = 0; virtual void onLoginSuccess(Client *client) = 0; }; diff --git a/src/net/Client.cpp b/src/net/Client.cpp index e56531f19..86928ed0e 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -37,9 +37,8 @@ #endif -Client::Client(int id, IClientListener *listener) : - m_keepAlive(false), - m_host(nullptr), +Client::Client(int id, const char *agent, IClientListener *listener) : + m_agent(agent), m_listener(listener), m_id(id), m_retryPause(5000), @@ -47,7 +46,6 @@ Client::Client(int id, IClientListener *listener) : m_sequence(1), m_recvBufPos(0), m_state(UnconnectedState), - m_port(0), m_stream(nullptr), m_socket(nullptr) { @@ -72,13 +70,12 @@ Client::~Client() { free(m_recvBuf.base); free(m_socket); - free(m_host); } void Client::connect() { - resolve(m_host); + resolve(m_url.host()); } @@ -90,7 +87,7 @@ void Client::connect() void Client::connect(const Url *url) { setUrl(url); - resolve(m_host); + resolve(m_url.host()); } @@ -102,18 +99,6 @@ void Client::disconnect() } -void Client::login(const char *user, const char *pass, const char *agent) -{ - m_sequence = 1; - - const size_t size = 96 + strlen(user) + strlen(pass) + strlen(agent); - char *req = static_cast(malloc(size)); - snprintf(req, size, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"}}\n", m_sequence, user, pass, agent); - - send(req); -} - - /** * @brief Send raw data to server. * @@ -121,9 +106,9 @@ void Client::login(const char *user, const char *pass, const char *agent) */ void Client::send(char *data) { - LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_host, m_port, strlen(data), 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_host, m_port, m_state); + LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state); return; } @@ -148,9 +133,7 @@ void Client::setUrl(const Url *url) return; } - free(m_host); - m_host = strdup(url->host()); - m_port = url->port(); + m_url = url; } @@ -199,7 +182,7 @@ bool Client::parseJob(const json_t *params, int *code) job.setPoolId(m_id); m_job = std::move(job); - LOG_DEBUG("[%s:%u] job: \"%s\", diff: %lld", m_host, m_port, job.id(), job.diff()); + LOG_DEBUG("[%s:%u] job: \"%s\", diff: %lld", m_url.host(), m_url.port(), job.id(), job.diff()); return true; } @@ -227,7 +210,7 @@ int Client::resolve(const char *host) const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints); if (r) { - LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_port, uv_strerror(r)); + LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r)); return 1; } @@ -250,7 +233,7 @@ void Client::connect(struct sockaddr *addr) { setState(ConnectingState); - reinterpret_cast(addr)->sin_port = htons(m_port); + reinterpret_cast(addr)->sin_port = htons(m_url.port()); free(m_socket); uv_connect_t *req = (uv_connect_t*) malloc(sizeof(uv_connect_t)); @@ -270,19 +253,31 @@ void Client::connect(struct sockaddr *addr) } +void Client::login() +{ + m_sequence = 1; + + const size_t size = 96 + strlen(m_url.user()) + strlen(m_url.password()) + strlen(m_agent); + char *req = static_cast(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); + + send(req); +} + + void Client::parse(char *line, size_t len) { startTimeout(); line[len - 1] = '\0'; - LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_host, m_port, len, line); + LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line); json_error_t err; json_t *val = json_loads(line, 0, &err); if (!val) { - LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_host, m_port, err.text); + LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(), err.text); return; } @@ -301,7 +296,7 @@ void Client::parse(char *line, size_t len) void Client::parseNotification(const char *method, const json_t *params, const json_t *error) { if (json_is_object(error)) { - LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_host, m_port, json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); return; } @@ -318,7 +313,7 @@ void Client::parseNotification(const char *method, const json_t *params, const j return; } - LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_host, m_port, method); + LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_url.host(), m_url.port(), method); } @@ -326,7 +321,7 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error { if (json_is_object(error)) { const char *message = json_string_value(json_object_get(error, "message")); - LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_host, m_port, message, json_integer_value(json_object_get(error, "code"))); + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), message, json_integer_value(json_object_get(error, "code"))); if (id == 1 || (message && strncasecmp(message, "Unauthenticated", 15) == 0)) { close(); @@ -342,7 +337,7 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error if (id == 1) { int code = -1; if (!parseLogin(result, &code)) { - LOG_ERR("[%s:%u] login error code: %d", m_host, m_port, code); + LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code); return close(); } @@ -366,7 +361,7 @@ void Client::ping() void Client::reconnect() { uv_timer_stop(&m_responseTimer); - if (m_keepAlive) { + if (m_url.isKeepAlive()) { uv_timer_stop(&m_keepAliveTimer); } @@ -383,7 +378,7 @@ void Client::reconnect() void Client::setState(SocketState state) { - LOG_DEBUG("[%s:%u] state: %d", m_host, m_port, state); + LOG_DEBUG("[%s:%u] state: %d", m_url.host(), m_url.port(), state); if (m_state == state) { return; @@ -396,7 +391,7 @@ void Client::setState(SocketState state) void Client::startTimeout() { uv_timer_stop(&m_responseTimer); - if (!m_keepAlive) { + if (!m_url.isKeepAlive()) { return; } @@ -431,7 +426,7 @@ void Client::onConnect(uv_connect_t *req, int status) { auto client = getClient(req->data); if (status < 0) { - LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); + LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); free(req); client->close(); return; @@ -444,7 +439,7 @@ void Client::onConnect(uv_connect_t *req, int status) uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead); free(req); - client->m_listener->onLoginCredentialsRequired(client); + client->login(); } @@ -453,7 +448,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) auto client = getClient(stream->data); if (nread < 0) { if (nread != UV_EOF) { - LOG_ERR("[%s:%u] read error: \"%s\"", client->m_host, client->m_port, uv_strerror(nread)); + LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(nread)); } return client->close();; @@ -492,7 +487,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) { auto client = getClient(req->data); if (status < 0) { - LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); + LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); return client->reconnect();; } diff --git a/src/net/Client.h b/src/net/Client.h index 75c5b2830..2e5303fb1 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -30,11 +30,11 @@ #include "net/Job.h" +#include "net/Url.h" class IClientListener; class JobResult; -class Url; class Client @@ -51,24 +51,21 @@ public: constexpr static int kResponseTimeout = 15 * 1000; constexpr static int kKeepAliveTimeout = 60 * 1000; - Client(int id, IClientListener *listener); + Client(int id, const char *agent, IClientListener *listener); ~Client(); void connect(); void connect(const Url *url); void disconnect(); - void login(const char *user, const char *pass, const char *agent); void send(char *data); void setUrl(const Url *url); void submit(const JobResult &result); - inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } - inline const char *host() const { return m_host; } + inline const char *host() const { return m_url.host(); } inline const Job &job() const { return m_job; } inline int id() const { return m_id; } inline SocketState state() const { return m_state; } - inline uint16_t port() const { return m_port; } - inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; } + inline uint16_t port() const { return m_url.port(); } inline void setRetryPause(int ms) { m_retryPause = ms; } private: @@ -79,6 +76,7 @@ private: int resolve(const char *host); void close(); void connect(struct sockaddr *addr); + void login(); void parse(char *line, size_t len); void parseNotification(const char *method, const json_t *params, const json_t *error); void parseResponse(int64_t id, const json_t *result, const json_t *error); @@ -95,9 +93,8 @@ private: static Client *getClient(void *data); - bool m_keepAlive; - char *m_host; char m_rpcId[64]; + const char *m_agent; IClientListener *m_listener; int m_id; int m_retryPause; @@ -107,7 +104,7 @@ private: size_t m_recvBufPos; SocketState m_state; struct addrinfo m_hints; - uint16_t m_port; + Url m_url; uv_buf_t m_recvBuf; uv_getaddrinfo_t m_resolver; uv_stream_t *m_stream; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index eddfc3bed..4b186bfd5 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -118,12 +118,6 @@ void Network::onJobResult(const JobResult &result) } -void Network::onLoginCredentialsRequired(Client *client) -{ - client->login(m_options->pools().front()->password(), m_options->pools().front()->password(), m_agent); -} - - void Network::onLoginSuccess(Client *client) { const int id = client->id(); @@ -151,7 +145,7 @@ void Network::addPool(const Url *url) return; } - Client *client = new Client(m_pools.size(), this); + Client *client = new Client(m_pools.size(), m_agent, this); client->setUrl(url); client->setRetryPause(m_options->retryPause() * 1000); // client->setKeepAlive(m_options->keepAlive()); diff --git a/src/net/Network.h b/src/net/Network.h index 2859abc8f..eb20035d6 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -51,7 +51,6 @@ protected: void onClose(Client *client, int failures) override; void onJobReceived(Client *client, const Job &job) override; void onJobResult(const JobResult &result) override; - void onLoginCredentialsRequired(Client *client) override; void onLoginSuccess(Client *client) override; private: diff --git a/src/net/Url.cpp b/src/net/Url.cpp index 3f8ca54e3..1b6d8b0b9 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -144,23 +144,31 @@ bool Url::setUserpass(const char *userpass) } -void Url::setPassword(const char *password, bool force) +void Url::setPassword(const char *password) { - if (m_password != nullptr && !force) { - return; - } - free(m_password); m_password = strdup(password); } -void Url::setUser(const char *user, bool force) +void Url::setUser(const char *user) { - if (m_user != nullptr && !force) { - return; - } - free(m_user); m_user = strdup(user); } + + +Url &Url::operator=(const Url *other) +{ + m_keepAlive = other->m_keepAlive; + m_nicehash = other->m_nicehash; + m_port = other->m_port; + + free(m_host); + m_host = strdup(other->m_host); + + setPassword(other->m_password); + setUser(other->m_user); + + return *this; +} diff --git a/src/net/Url.h b/src/net/Url.h index 639df7cd5..43197195f 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -52,8 +52,11 @@ public: bool isNicehash() const; bool parse(const char *url); bool setUserpass(const char *userpass); - void setPassword(const char *password, bool force = true); - void setUser(const char *user, bool force = true); + void setPassword(const char *password); + void setUser(const char *user); + + Url &operator=(const Url *other); + private: bool m_keepAlive; bool m_nicehash; From bd8776b7eef4659ab45543bb5072be2c38abcefd Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 28 Jun 2017 06:17:02 +0300 Subject: [PATCH 4/9] Add classes SinglePoolStrategy, DonateStrategy, IStrategy, IStrategyListener. --- CMakeLists.txt | 10 +- src/interfaces/IStrategy.h | 37 +++++ src/interfaces/IStrategyListener.h | 35 +++++ src/net/Client.h | 1 + src/net/Network.cpp | 169 ++++++++++------------ src/net/Network.h | 14 +- src/net/Url.cpp | 8 +- src/net/strategies/DonateStrategy.cpp | 73 ++++++++++ src/net/strategies/DonateStrategy.h | 61 ++++++++ src/net/strategies/SinglePoolStrategy.cpp | 59 ++++++++ src/net/strategies/SinglePoolStrategy.h | 55 +++++++ 11 files changed, 414 insertions(+), 108 deletions(-) create mode 100644 src/interfaces/IStrategy.h create mode 100644 src/interfaces/IStrategyListener.h create mode 100644 src/net/strategies/DonateStrategy.cpp create mode 100644 src/net/strategies/DonateStrategy.h create mode 100644 src/net/strategies/SinglePoolStrategy.cpp create mode 100644 src/net/strategies/SinglePoolStrategy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ddcd2e52..63d33455d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,8 @@ set(HEADERS src/interfaces/IClientListener.h src/interfaces/IJobResultListener.h src/interfaces/ILogBackend.h + src/interfaces/IStrategy.h + src/interfaces/IStrategyListener.h src/interfaces/IWorker.h src/log/ConsoleLog.h src/log/FileLog.h @@ -25,6 +27,8 @@ set(HEADERS src/net/JobResult.h src/net/Network.h src/net/Url.h + src/net/strategies/DonateStrategy.h + src/net/strategies/SinglePoolStrategy.h src/Options.h src/Summary.h src/version.h @@ -60,6 +64,8 @@ set(SOURCES src/net/Job.cpp src/net/Network.cpp src/net/Url.cpp + src/net/strategies/DonateStrategy.cpp + src/net/strategies/SinglePoolStrategy.cpp src/Options.cpp src/Summary.cpp src/workers/DoubleWorker.cpp @@ -114,7 +120,7 @@ else() endif() add_definitions(/DUNICODE) -#add_definitions(/DAPP_DEBUG) +add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") @@ -128,7 +134,7 @@ endif() # https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html if (CMAKE_CXX_COMPILER_ID MATCHES GNU) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -Wno-strict-aliasing") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -std=c++14 -fno-exceptions -fno-rtti") diff --git a/src/interfaces/IStrategy.h b/src/interfaces/IStrategy.h new file mode 100644 index 000000000..6b3b9560e --- /dev/null +++ b/src/interfaces/IStrategy.h @@ -0,0 +1,37 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * 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 . + */ + +#ifndef __ISTRATEGY_H__ +#define __ISTRATEGY_H__ + + +class IStrategy +{ +public: + virtual ~IStrategy() {} + + virtual void connect() = 0; +}; + + +#endif // __ISTRATEGY_H__ diff --git a/src/interfaces/IStrategyListener.h b/src/interfaces/IStrategyListener.h new file mode 100644 index 000000000..dd33424ee --- /dev/null +++ b/src/interfaces/IStrategyListener.h @@ -0,0 +1,35 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * 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 . + */ + +#ifndef __ISTRATEGYLISTENER_H__ +#define __ISTRATEGYLISTENER_H__ + + +class IStrategyListener +{ +public: + virtual ~IStrategyListener() {} +}; + + +#endif // __ISTRATEGYLISTENER_H__ diff --git a/src/net/Client.h b/src/net/Client.h index 2e5303fb1..a4ff846d2 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -60,6 +60,7 @@ public: void send(char *data); void setUrl(const Url *url); void submit(const JobResult &result); + inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } inline const char *host() const { return m_url.host(); } inline const Job &job() const { return m_job; } diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 4b186bfd5..b04c035eb 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -28,36 +28,36 @@ #include "log/Log.h" #include "net/Client.h" #include "net/Network.h" +#include "net/strategies/DonateStrategy.h" +#include "net/strategies/SinglePoolStrategy.h" #include "net/Url.h" #include "Options.h" #include "workers/Workers.h" Network::Network(const Options *options) : - m_donate(false), + m_donateActive(false), m_options(options), - m_pool(0), - m_diff(0) + m_donate(nullptr) { Workers::setListener(this); - - m_pools.reserve(2); m_agent = userAgent(); - addPool(std::make_unique().get()); - addPool(m_options->pools().front()); -// addPool(m_options->backupUrl()); + const std::vector &pools = options->pools(); - m_timer.data = this; - uv_timer_init(uv_default_loop(), &m_timer); + m_strategy = new SinglePoolStrategy(pools.front(), m_agent, this); + + if (m_options->donateLevel() > 0) { + m_donate = new DonateStrategy(m_agent, this); + } } Network::~Network() { - for (auto client : m_pools) { - delete client; - } +// for (auto client : m_pools) { +// delete client; +// } free(m_agent); } @@ -65,39 +65,35 @@ Network::~Network() void Network::connect() { - m_pools[1]->connect(); - - if (m_options->donateLevel()) { - uv_timer_start(&m_timer, Network::onTimer, (100 - m_options->donateLevel()) * 60 * 1000, 0); - } + m_strategy->connect(); } void Network::onClose(Client *client, int failures) { - const int id = client->id(); - if (id == 0) { - if (failures == -1) { - stopDonate(); - } +// const int id = client->id(); +// if (id == 0) { +// if (failures == -1) { +// stopDonate(); +// } - return; - } +// return; +// } - if (m_pool == id) { - m_pool = 0; - Workers::pause(); - } +// if (m_pool == id) { +// m_pool = 0; +// Workers::pause(); +// } - if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { - m_pools[2]->connect(); - } +// if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { +// m_pools[2]->connect(); +// } } void Network::onJobReceived(Client *client, const Job &job) { - if (m_donate && client->id() != 0) { + if (m_donateActive && client->id() != 0) { return; } @@ -107,50 +103,35 @@ void Network::onJobReceived(Client *client, const Job &job) void Network::onJobResult(const JobResult &result) { - if (m_options->colors()) { - LOG_NOTICE("\x1B[01;32mSHARE FOUND"); - } - else { - LOG_NOTICE("SHARE FOUND"); - } +// if (m_options->colors()) { +// LOG_NOTICE("\x1B[01;32mSHARE FOUND"); +// } +// else { +// LOG_NOTICE("SHARE FOUND"); +// } - m_pools[result.poolId]->submit(result); +// m_pools[result.poolId]->submit(result); } void Network::onLoginSuccess(Client *client) { - const int id = client->id(); - if (id == 0) { - return startDonate(); - } +// const int id = client->id(); +// if (id == 0) { +// return startDonate(); +// } - if (id == 2 && m_pool) { // primary pool is already active - m_pools[2]->disconnect(); - return; - } +// if (id == 2 && m_pool) { // primary pool is already active +// m_pools[2]->disconnect(); +// return; +// } - LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool: \x1B[01;36m%s:%d" : "use pool: %s:%d", client->host(), client->port()); - m_pool = id; +// LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool: \x1B[01;36m%s:%d" : "use pool: %s:%d", client->host(), client->port()); +// m_pool = id; - if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool - m_pools[2]->disconnect(); - } -} - - -void Network::addPool(const Url *url) -{ - if (!url) { - return; - } - - Client *client = new Client(m_pools.size(), m_agent, this); - client->setUrl(url); - client->setRetryPause(m_options->retryPause() * 1000); -// client->setKeepAlive(m_options->keepAlive()); - - m_pools.push_back(client); +// if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool +// m_pools[2]->disconnect(); +// } } @@ -170,48 +151,48 @@ void Network::setJob(Client *client, const Job &job) void Network::startDonate() { - if (m_donate) { + if (m_donateActive) { return; } LOG_NOTICE("dev donate started"); - m_donate = true; + m_donateActive = true; } void Network::stopDonate() { - if (!m_donate) { - return; - } +// if (!m_donateActive) { +// return; +// } - LOG_NOTICE("dev donate finished"); +// LOG_NOTICE("dev donate finished"); - m_donate = false; - if (!m_pool) { - return; - } +// m_donateActive = false; +// if (!m_pool) { +// return; +// } - Client *client = m_pools[m_pool]; - if (client->isReady()) { - setJob(client, client->job()); - } +// Client *client = m_pools[m_pool]; +// if (client->isReady()) { +// setJob(client, client->job()); +// } } -void Network::onTimer(uv_timer_t *handle) -{ - auto net = static_cast(handle->data); +//void Network::onTimer(uv_timer_t *handle) +//{ +// auto net = static_cast(handle->data); - if (!net->m_donate) { - auto url = std::make_unique("donate.xmrig.com", net->m_options->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443); - net->m_pools[0]->connect(url.get()); +// if (!net->m_donateActive) { +// auto url = std::make_unique("donate.xmrig.com", net->m_options->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443); +// net->m_pools[0]->connect(url.get()); - uv_timer_start(&net->m_timer, Network::onTimer, net->m_options->donateLevel() * 60 * 1000, 0); - return; - } +// uv_timer_start(&net->m_timer, Network::onTimer, net->m_options->donateLevel() * 60 * 1000, 0); +// return; +// } - net->m_pools[0]->disconnect(); - uv_timer_start(&net->m_timer, Network::onTimer, (100 - net->m_options->donateLevel()) * 60 * 1000, 0); -} +// net->m_pools[0]->disconnect(); +// uv_timer_start(&net->m_timer, Network::onTimer, (100 - net->m_options->donateLevel()) * 60 * 1000, 0); +//} diff --git a/src/net/Network.h b/src/net/Network.h index eb20035d6..3fec005af 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -31,13 +31,15 @@ #include "interfaces/IClientListener.h" #include "interfaces/IJobResultListener.h" +#include "interfaces/IStrategyListener.h" +class IStrategy; class Options; class Url; -class Network : public IClientListener, public IJobResultListener +class Network : public IClientListener, public IJobResultListener, public IStrategyListener { public: Network(const Options *options); @@ -59,15 +61,11 @@ private: void startDonate(); void stopDonate(); - static void onTimer(uv_timer_t *handle); - - bool m_donate; + bool m_donateActive; char *m_agent; const Options *m_options; - int m_pool; - std::vector m_pools; - uint64_t m_diff; - uv_timer_t m_timer; + IStrategy *m_donate; + IStrategy *m_strategy; }; diff --git a/src/net/Url.cpp b/src/net/Url.cpp index 1b6d8b0b9..06e44aaae 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -69,10 +69,10 @@ Url::Url(const char *url) : Url::Url(const char *host, uint16_t port, const char *user, const char *password, bool keepAlive, bool nicehash) : - m_keepAlive(false), - m_nicehash(false), - m_password(nullptr), - m_user(nullptr), + m_keepAlive(keepAlive), + m_nicehash(nicehash), + m_password(password ? strdup(password) : nullptr), + m_user(user ? strdup(user) : nullptr), m_port(port) { m_host = strdup(host); diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp new file mode 100644 index 000000000..5cbd319f0 --- /dev/null +++ b/src/net/strategies/DonateStrategy.cpp @@ -0,0 +1,73 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * 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 . + */ + + +#include "net/Client.h" +#include "net/strategies/DonateStrategy.h" +#include "Options.h" + + +DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : + m_listener(listener) +{ + Url *url = new Url("donate.xmrig.com", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443, Options::i()->pools().front()->user()); + + m_client = new Client(-1, agent, this); + m_client->setUrl(url); + m_client->setRetryPause(Options::i()->retryPause() * 1000); + + delete url; + + m_timer.data = this; + uv_timer_init(uv_default_loop(), &m_timer); + + uv_timer_start(&m_timer, DonateStrategy::onTimer, (100 - Options::i()->donateLevel()) * 60 * 1000, 0); +} + + +void DonateStrategy::connect() +{ +} + + +void DonateStrategy::onClose(Client *client, int failures) +{ + +} + + +void DonateStrategy::onJobReceived(Client *client, const Job &job) +{ + +} + + +void DonateStrategy::onLoginSuccess(Client *client) +{ +} + + +void DonateStrategy::onTimer(uv_timer_t *handle) +{ + +} diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h new file mode 100644 index 000000000..c010f7fff --- /dev/null +++ b/src/net/strategies/DonateStrategy.h @@ -0,0 +1,61 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * 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 . + */ + +#ifndef __DONATESTRATEGY_H__ +#define __DONATESTRATEGY_H__ + + +#include + + +#include "interfaces/IClientListener.h" +#include "interfaces/IStrategy.h" + + +class Client; +class IStrategyListener; +class Url; + + +class DonateStrategy : public IStrategy, public IClientListener +{ +public: + DonateStrategy(const char *agent, IStrategyListener *listener); + +public: + void connect() override; + +protected: + void onClose(Client *client, int failures) override; + void onJobReceived(Client *client, const Job &job) override; + void onLoginSuccess(Client *client) override; + +private: + static void onTimer(uv_timer_t *handle); + + Client *m_client; + IStrategyListener *m_listener; + uv_timer_t m_timer; +}; + +#endif /* __DONATESTRATEGY_H__ */ diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp new file mode 100644 index 000000000..677a35183 --- /dev/null +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -0,0 +1,59 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * 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 . + */ + + +#include "net/Client.h" +#include "net/strategies/SinglePoolStrategy.h" +#include "Options.h" + + +SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener) : + m_listener(listener) +{ + m_client = new Client(0, agent, this); + m_client->setUrl(url); + m_client->setRetryPause(Options::i()->retryPause() * 1000); +} + + +void SinglePoolStrategy::connect() +{ + m_client->connect(); +} + + +void SinglePoolStrategy::onClose(Client *client, int failures) +{ + +} + + +void SinglePoolStrategy::onJobReceived(Client *client, const Job &job) +{ + +} + + +void SinglePoolStrategy::onLoginSuccess(Client *client) +{ +} diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/net/strategies/SinglePoolStrategy.h new file mode 100644 index 000000000..ff289ae94 --- /dev/null +++ b/src/net/strategies/SinglePoolStrategy.h @@ -0,0 +1,55 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * 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 . + */ + +#ifndef __SINGLEPOOLSTRATEGY_H__ +#define __SINGLEPOOLSTRATEGY_H__ + + +#include "interfaces/IClientListener.h" +#include "interfaces/IStrategy.h" + + +class Client; +class IStrategyListener; +class Url; + + +class SinglePoolStrategy : public IStrategy, public IClientListener +{ +public: + SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener); + +public: + void connect() override; + +protected: + void onClose(Client *client, int failures) override; + void onJobReceived(Client *client, const Job &job) override; + void onLoginSuccess(Client *client) override; + +private: + Client *m_client; + IStrategyListener *m_listener; +}; + +#endif /* __SINGLEPOOLSTRATEGY_H__ */ From 25faeabd61871435011df9d6046ee1fe73953975 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 29 Jun 2017 01:48:23 +0300 Subject: [PATCH 5/9] Implemented SinglePoolStrategy. --- CMakeLists.txt | 2 +- src/interfaces/IStrategy.h | 7 +++- src/interfaces/IStrategyListener.h | 9 +++++ src/net/Network.cpp | 45 ++++++++++++++++------- src/net/Network.h | 8 ++-- src/net/strategies/DonateStrategy.cpp | 18 ++++++++- src/net/strategies/DonateStrategy.h | 3 ++ src/net/strategies/SinglePoolStrategy.cpp | 23 +++++++++++- src/net/strategies/SinglePoolStrategy.h | 3 ++ src/workers/Workers.h | 2 +- 10 files changed, 98 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63d33455d..cecd78e10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,7 +120,7 @@ else() endif() add_definitions(/DUNICODE) -add_definitions(/DAPP_DEBUG) +#add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/src/interfaces/IStrategy.h b/src/interfaces/IStrategy.h index 6b3b9560e..eddf300b3 100644 --- a/src/interfaces/IStrategy.h +++ b/src/interfaces/IStrategy.h @@ -25,12 +25,17 @@ #define __ISTRATEGY_H__ +class JobResult; + + class IStrategy { public: virtual ~IStrategy() {} - virtual void connect() = 0; + virtual bool isActive() const = 0; + virtual void connect() = 0; + virtual void submit(const JobResult &result) = 0; }; diff --git a/src/interfaces/IStrategyListener.h b/src/interfaces/IStrategyListener.h index dd33424ee..5fbc78c5d 100644 --- a/src/interfaces/IStrategyListener.h +++ b/src/interfaces/IStrategyListener.h @@ -25,10 +25,19 @@ #define __ISTRATEGYLISTENER_H__ +class Client; +class IStrategy; +class Job; + + class IStrategyListener { public: virtual ~IStrategyListener() {} + + virtual void onActive(Client *client) = 0; + virtual void onJob(Client *client, const Job &job) = 0; + virtual void onPause(IStrategy *strategy) = 0; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index b04c035eb..364431046 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -69,8 +69,19 @@ void Network::connect() } -void Network::onClose(Client *client, int failures) +void Network::onActive(Client *client) { + if (client->id() == -1) { + LOG_NOTICE("dev donate started"); + return; + } + + LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool: \x1B[01;36m%s:%d" : "use pool: %s:%d", client->host(), client->port()); +} + + +//void Network::onClose(Client *client, int failures) +//{ // const int id = client->id(); // if (id == 0) { // if (failures == -1) { @@ -88,12 +99,12 @@ void Network::onClose(Client *client, int failures) // if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { // m_pools[2]->connect(); // } -} +//} -void Network::onJobReceived(Client *client, const Job &job) +void Network::onJob(Client *client, const Job &job) { - if (m_donateActive && client->id() != 0) { + if (m_donate && m_donate->isActive() && client->id() != -1) { return; } @@ -103,19 +114,18 @@ void Network::onJobReceived(Client *client, const Job &job) void Network::onJobResult(const JobResult &result) { -// if (m_options->colors()) { -// LOG_NOTICE("\x1B[01;32mSHARE FOUND"); -// } -// else { -// LOG_NOTICE("SHARE FOUND"); -// } + LOG_NOTICE(m_options->colors() ? "\x1B[01;32mSHARE FOUND" : "SHARE FOUND"); -// m_pools[result.poolId]->submit(result); + if (result.poolId == -1 && m_donate) { + return m_donate->submit(result); + } + + m_strategy->submit(result); } -void Network::onLoginSuccess(Client *client) -{ +//void Network::onLoginSuccess(Client *client) +//{ // const int id = client->id(); // if (id == 0) { // return startDonate(); @@ -132,6 +142,15 @@ void Network::onLoginSuccess(Client *client) // if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool // m_pools[2]->disconnect(); // } +//} + + +void Network::onPause(IStrategy *strategy) +{ + if ((m_donate && !m_donate->isActive()) || !m_strategy->isActive()) { + LOG_ERR("no active pools, pause mining"); + Workers::pause(); + } } diff --git a/src/net/Network.h b/src/net/Network.h index 3fec005af..4eb86cc3d 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -39,7 +39,7 @@ class Options; class Url; -class Network : public IClientListener, public IJobResultListener, public IStrategyListener +class Network : public IJobResultListener, public IStrategyListener { public: Network(const Options *options); @@ -50,10 +50,10 @@ public: static char *userAgent(); protected: - void onClose(Client *client, int failures) override; - void onJobReceived(Client *client, const Job &job) override; + void onActive(Client *client) override; + void onJob(Client *client, const Job &job) override; void onJobResult(const JobResult &result) override; - void onLoginSuccess(Client *client) override; + void onPause(IStrategy *strategy) override; private: void addPool(const Url *url); diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 5cbd319f0..9b7fb12ba 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -22,12 +22,14 @@ */ +#include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/strategies/DonateStrategy.h" #include "Options.h" DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : + m_active(false), m_listener(listener) { Url *url = new Url("donate.xmrig.com", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443, Options::i()->pools().front()->user()); @@ -45,11 +47,23 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : } +bool DonateStrategy::isActive() const +{ + return m_active; +} + + void DonateStrategy::connect() { } +void DonateStrategy::submit(const JobResult &result) +{ + m_client->submit(result); +} + + void DonateStrategy::onClose(Client *client, int failures) { @@ -58,12 +72,14 @@ void DonateStrategy::onClose(Client *client, int failures) void DonateStrategy::onJobReceived(Client *client, const Job &job) { - + m_listener->onJob(client, job); } void DonateStrategy::onLoginSuccess(Client *client) { + m_active = true; + m_listener->onActive(client); } diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index c010f7fff..128757cab 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -43,7 +43,9 @@ public: DonateStrategy(const char *agent, IStrategyListener *listener); public: + bool isActive() const override; void connect() override; + void submit(const JobResult &result) override; protected: void onClose(Client *client, int failures) override; @@ -53,6 +55,7 @@ protected: private: static void onTimer(uv_timer_t *handle); + bool m_active; Client *m_client; IStrategyListener *m_listener; uv_timer_t m_timer; diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp index 677a35183..c7d2a8d03 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -22,12 +22,14 @@ */ +#include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/strategies/SinglePoolStrategy.h" #include "Options.h" SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener) : + m_active(false), m_listener(listener) { m_client = new Client(0, agent, this); @@ -36,24 +38,43 @@ SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrat } +bool SinglePoolStrategy::isActive() const +{ + return m_active; +} + + void SinglePoolStrategy::connect() { m_client->connect(); } +void SinglePoolStrategy::submit(const JobResult &result) +{ + m_client->submit(result); +} + + void SinglePoolStrategy::onClose(Client *client, int failures) { + if (!isActive()) { + return; + } + m_active = false; + m_listener->onPause(this); } void SinglePoolStrategy::onJobReceived(Client *client, const Job &job) { - + m_listener->onJob(client, job); } void SinglePoolStrategy::onLoginSuccess(Client *client) { + m_active = true; + m_listener->onActive(client); } diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/net/strategies/SinglePoolStrategy.h index ff289ae94..fb8eca60d 100644 --- a/src/net/strategies/SinglePoolStrategy.h +++ b/src/net/strategies/SinglePoolStrategy.h @@ -40,7 +40,9 @@ public: SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener); public: + bool isActive() const override; void connect() override; + void submit(const JobResult &result) override; protected: void onClose(Client *client, int failures) override; @@ -48,6 +50,7 @@ protected: void onLoginSuccess(Client *client) override; private: + bool m_active; Client *m_client; IStrategyListener *m_listener; }; diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 0990fc45e..ffeddb00c 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -50,7 +50,7 @@ public: static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } - static inline void pause() { m_paused = 1; } + static inline void pause() { m_paused = 1; m_sequence++; } static inline void setListener(IJobResultListener *listener) { m_listener = listener; } private: From 7e17f77c1158fca71cd9ee007fcaf7157fd7d330 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 30 Jun 2017 03:20:50 +0300 Subject: [PATCH 6/9] Implemented DonateStrategy. --- src/interfaces/IStrategy.h | 1 + src/net/Client.cpp | 32 ++++++++++++++---- src/net/Client.h | 2 ++ src/net/Network.cpp | 21 ++++-------- src/net/strategies/DonateStrategy.cpp | 40 ++++++++++++++++++----- src/net/strategies/DonateStrategy.h | 9 ++++- src/net/strategies/SinglePoolStrategy.cpp | 16 +++++---- src/net/strategies/SinglePoolStrategy.h | 4 ++- 8 files changed, 88 insertions(+), 37 deletions(-) diff --git a/src/interfaces/IStrategy.h b/src/interfaces/IStrategy.h index eddf300b3..78f3f6236 100644 --- a/src/interfaces/IStrategy.h +++ b/src/interfaces/IStrategy.h @@ -35,6 +35,7 @@ public: virtual bool isActive() const = 0; virtual void connect() = 0; + virtual void resume() = 0; virtual void submit(const JobResult &result) = 0; }; diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 86928ed0e..e9fcb0a78 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -38,6 +38,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) : + m_quiet(false), m_agent(agent), m_listener(listener), m_id(id), @@ -93,6 +94,7 @@ void Client::connect(const Url *url) void Client::disconnect() { + uv_timer_stop(&m_retriesTimer); m_failures = -1; close(); @@ -207,10 +209,13 @@ int Client::resolve(const char *host) setState(HostLookupState); m_recvBufPos = 0; + m_failures = 0; const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints); if (r) { - LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r)); + if (!m_quiet) { + LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r)); + } return 1; } @@ -277,7 +282,9 @@ void Client::parse(char *line, size_t len) json_t *val = json_loads(line, 0, &err); if (!val) { - LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(), err.text); + if (!m_quiet) { + LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(), err.text); + } return; } @@ -296,7 +303,9 @@ void Client::parse(char *line, size_t len) void Client::parseNotification(const char *method, const json_t *params, const json_t *error) { if (json_is_object(error)) { - LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); + if (!m_quiet) { + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); + } return; } @@ -321,7 +330,10 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error { if (json_is_object(error)) { const char *message = json_string_value(json_object_get(error, "message")); - LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), message, json_integer_value(json_object_get(error, "code"))); + + if (!m_quiet) { + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), message, json_integer_value(json_object_get(error, "code"))); + } if (id == 1 || (message && strncasecmp(message, "Unauthenticated", 15) == 0)) { close(); @@ -337,7 +349,10 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error if (id == 1) { int code = -1; if (!parseLogin(result, &code)) { - LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code); + if (!m_quiet) { + LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code); + } + return close(); } @@ -426,7 +441,10 @@ void Client::onConnect(uv_connect_t *req, int status) { auto client = getClient(req->data); if (status < 0) { - LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); + if (!client->m_quiet) { + LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); + } + free(req); client->close(); return; @@ -447,7 +465,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { auto client = getClient(stream->data); if (nread < 0) { - if (nread != UV_EOF) { + if (nread != UV_EOF && !client->m_quiet) { LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(nread)); } diff --git a/src/net/Client.h b/src/net/Client.h index a4ff846d2..65fdc42a6 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -67,6 +67,7 @@ public: inline int id() const { return m_id; } inline SocketState state() const { return m_state; } inline uint16_t port() const { return m_url.port(); } + inline void setQuiet(bool quiet) { m_quiet = quiet; } inline void setRetryPause(int ms) { m_retryPause = ms; } private: @@ -94,6 +95,7 @@ private: static Client *getClient(void *data); + bool m_quiet; char m_rpcId[64]; const char *m_agent; IClientListener *m_listener; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 364431046..8e064e9a1 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -147,9 +147,14 @@ void Network::onJobResult(const JobResult &result) void Network::onPause(IStrategy *strategy) { - if ((m_donate && !m_donate->isActive()) || !m_strategy->isActive()) { + if (m_donate && m_donate == strategy) { + LOG_NOTICE("dev donate finished"); + m_strategy->resume(); + } + + if (!m_strategy->isActive()) { LOG_ERR("no active pools, pause mining"); - Workers::pause(); + return Workers::pause(); } } @@ -168,18 +173,6 @@ void Network::setJob(Client *client, const Job &job) } -void Network::startDonate() -{ - if (m_donateActive) { - return; - } - - LOG_NOTICE("dev donate started"); - - m_donateActive = true; -} - - void Network::stopDonate() { // if (!m_donateActive) { diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 9b7fb12ba..a3c595ed9 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -30,6 +30,8 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : m_active(false), + m_donateTime(Options::i()->donateLevel() * 60 * 1000), + m_idleTime((100 - Options::i()->donateLevel()) * 60 * 1000), m_listener(listener) { Url *url = new Url("donate.xmrig.com", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443, Options::i()->pools().front()->user()); @@ -37,24 +39,20 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : m_client = new Client(-1, agent, this); m_client->setUrl(url); m_client->setRetryPause(Options::i()->retryPause() * 1000); + m_client->setQuiet(true); delete url; m_timer.data = this; uv_timer_init(uv_default_loop(), &m_timer); - uv_timer_start(&m_timer, DonateStrategy::onTimer, (100 - Options::i()->donateLevel()) * 60 * 1000, 0); -} - - -bool DonateStrategy::isActive() const -{ - return m_active; + idle(); } void DonateStrategy::connect() { + m_client->connect(); } @@ -66,7 +64,6 @@ void DonateStrategy::submit(const JobResult &result) void DonateStrategy::onClose(Client *client, int failures) { - } @@ -78,12 +75,39 @@ void DonateStrategy::onJobReceived(Client *client, const Job &job) void DonateStrategy::onLoginSuccess(Client *client) { + if (!isActive()) { + uv_timer_start(&m_timer, DonateStrategy::onTimer, m_donateTime, 0); + } + m_active = true; m_listener->onActive(client); } +void DonateStrategy::idle() +{ + uv_timer_start(&m_timer, DonateStrategy::onTimer, m_idleTime, 0); +} + + +void DonateStrategy::stop() +{ + m_client->disconnect(); + + m_active = false; + m_listener->onPause(this); + + idle(); +} + + void DonateStrategy::onTimer(uv_timer_t *handle) { + auto strategy = static_cast(handle->data); + if (!strategy->isActive()) { + return strategy->connect(); + } + + strategy->stop(); } diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index 128757cab..33cdf5364 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -43,7 +43,9 @@ public: DonateStrategy(const char *agent, IStrategyListener *listener); public: - bool isActive() const override; + inline bool isActive() const override { return m_active; } + inline void resume() override {} + void connect() override; void submit(const JobResult &result) override; @@ -53,10 +55,15 @@ protected: void onLoginSuccess(Client *client) override; private: + void idle(); + void stop(); + static void onTimer(uv_timer_t *handle); bool m_active; Client *m_client; + const int m_donateTime; + const int m_idleTime; IStrategyListener *m_listener; uv_timer_t m_timer; }; diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp index c7d2a8d03..c1d1a08ff 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -38,18 +38,22 @@ SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrat } -bool SinglePoolStrategy::isActive() const -{ - return m_active; -} - - void SinglePoolStrategy::connect() { m_client->connect(); } +void SinglePoolStrategy::resume() +{ + if (!isActive()) { + return; + } + + m_listener->onJob(m_client, m_client->job()); +} + + void SinglePoolStrategy::submit(const JobResult &result) { m_client->submit(result); diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/net/strategies/SinglePoolStrategy.h index fb8eca60d..b59398593 100644 --- a/src/net/strategies/SinglePoolStrategy.h +++ b/src/net/strategies/SinglePoolStrategy.h @@ -40,8 +40,10 @@ public: SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener); public: - bool isActive() const override; + inline bool isActive() const override { return m_active; } + void connect() override; + void resume() override; void submit(const JobResult &result) override; protected: From 7536663caf9770a55c37448a82f364dbf66e470a Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 30 Jun 2017 13:23:13 +0300 Subject: [PATCH 7/9] Remove option --backup-url. --- src/Options.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 6230f03cf..4f9a291c0 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -54,7 +54,6 @@ Usage: " APP_ID " [OPTIONS]\n\ Options:\n\ -a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\ -o, --url=URL URL of mining server\n\ - -b, --backup-url=URL URL of backup mining server\n\ -O, --userpass=U:P username:password pair for mining server\n\ -u, --user=USERNAME username for mining server\n\ -p, --pass=PASSWORD password for mining server\n\ @@ -83,14 +82,13 @@ Options:\n\ "; -static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vb:l:S"; +static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vl:S"; static struct option const options[] = { { "algo", 1, nullptr, 'a' }, { "av", 1, nullptr, 'v' }, { "background", 0, nullptr, 'B' }, - { "backup-url", 1, nullptr, 'b' }, { "config", 1, nullptr, 'c' }, { "cpu-affinity", 1, nullptr, 1020 }, { "donate-level", 1, nullptr, 1003 }, From 970b5d1964e9e4e01c3e4ab15dba5f625a4abf1b Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 1 Jul 2017 20:53:42 +0300 Subject: [PATCH 8/9] Add FailoverStrategy. --- CMakeLists.txt | 4 +- src/Summary.cpp | 3 +- src/net/Client.cpp | 7 +- src/net/Network.cpp | 92 ++---------------- src/net/strategies/FailoverStrategy.cpp | 121 ++++++++++++++++++++++++ src/net/strategies/FailoverStrategy.h | 66 +++++++++++++ 6 files changed, 205 insertions(+), 88 deletions(-) create mode 100644 src/net/strategies/FailoverStrategy.cpp create mode 100644 src/net/strategies/FailoverStrategy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cecd78e10..3026905e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ set(HEADERS src/net/Network.h src/net/Url.h src/net/strategies/DonateStrategy.h + src/net/strategies/FailoverStrategy.h src/net/strategies/SinglePoolStrategy.h src/Options.h src/Summary.h @@ -65,6 +66,7 @@ set(SOURCES src/net/Network.cpp src/net/Url.cpp src/net/strategies/DonateStrategy.cpp + src/net/strategies/FailoverStrategy.cpp src/net/strategies/SinglePoolStrategy.cpp src/Options.cpp src/Summary.cpp @@ -120,7 +122,7 @@ else() endif() add_definitions(/DUNICODE) -#add_definitions(/DAPP_DEBUG) +add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/src/Summary.cpp b/src/Summary.cpp index 9eb195d3b..08326458b 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -100,10 +100,11 @@ static void print_threads() buf[0] = '\0'; } - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s" : " * THREADS: %d, %s, av=%d, donate=%d%%%s", + Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", Options::i()->threads(), Options::i()->algoName(), Options::i()->algoVariant(), + Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "", Options::i()->donateLevel(), buf); } diff --git a/src/net/Client.cpp b/src/net/Client.cpp index e9fcb0a78..3b9eecbd6 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -209,7 +209,10 @@ int Client::resolve(const char *host) setState(HostLookupState); m_recvBufPos = 0; - m_failures = 0; + + if (m_failures == -1) { + m_failures = 0; + } const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints); if (r) { @@ -375,6 +378,8 @@ void Client::ping() void Client::reconnect() { + setState(ConnectingState); + uv_timer_stop(&m_responseTimer); if (m_url.isKeepAlive()) { uv_timer_stop(&m_keepAliveTimer); diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 8e064e9a1..abd7ed117 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -29,6 +29,7 @@ #include "net/Client.h" #include "net/Network.h" #include "net/strategies/DonateStrategy.h" +#include "net/strategies/FailoverStrategy.h" #include "net/strategies/SinglePoolStrategy.h" #include "net/Url.h" #include "Options.h" @@ -45,7 +46,12 @@ Network::Network(const Options *options) : const std::vector &pools = options->pools(); - m_strategy = new SinglePoolStrategy(pools.front(), m_agent, this); + if (pools.size() > 1) { + m_strategy = new FailoverStrategy(pools, m_agent, this); + } + else { + m_strategy = new SinglePoolStrategy(pools.front(), m_agent, this); + } if (m_options->donateLevel() > 0) { m_donate = new DonateStrategy(m_agent, this); @@ -55,10 +61,6 @@ Network::Network(const Options *options) : Network::~Network() { -// for (auto client : m_pools) { -// delete client; -// } - free(m_agent); } @@ -80,28 +82,6 @@ void Network::onActive(Client *client) } -//void Network::onClose(Client *client, int failures) -//{ -// const int id = client->id(); -// if (id == 0) { -// if (failures == -1) { -// stopDonate(); -// } - -// return; -// } - -// if (m_pool == id) { -// m_pool = 0; -// Workers::pause(); -// } - -// if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { -// m_pools[2]->connect(); -// } -//} - - void Network::onJob(Client *client, const Job &job) { if (m_donate && m_donate->isActive() && client->id() != -1) { @@ -124,27 +104,6 @@ void Network::onJobResult(const JobResult &result) } -//void Network::onLoginSuccess(Client *client) -//{ -// const int id = client->id(); -// if (id == 0) { -// return startDonate(); -// } - -// if (id == 2 && m_pool) { // primary pool is already active -// m_pools[2]->disconnect(); -// return; -// } - -// LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool: \x1B[01;36m%s:%d" : "use pool: %s:%d", client->host(), client->port()); -// m_pool = id; - -// if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool -// m_pools[2]->disconnect(); -// } -//} - - void Network::onPause(IStrategy *strategy) { if (m_donate && m_donate == strategy) { @@ -171,40 +130,3 @@ void Network::setJob(Client *client, const Job &job) Workers::setJob(job); } - - -void Network::stopDonate() -{ -// if (!m_donateActive) { -// return; -// } - -// LOG_NOTICE("dev donate finished"); - -// m_donateActive = false; -// if (!m_pool) { -// return; -// } - -// Client *client = m_pools[m_pool]; -// if (client->isReady()) { -// setJob(client, client->job()); -// } -} - - -//void Network::onTimer(uv_timer_t *handle) -//{ -// auto net = static_cast(handle->data); - -// if (!net->m_donateActive) { -// auto url = std::make_unique("donate.xmrig.com", net->m_options->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443); -// net->m_pools[0]->connect(url.get()); - -// uv_timer_start(&net->m_timer, Network::onTimer, net->m_options->donateLevel() * 60 * 1000, 0); -// return; -// } - -// net->m_pools[0]->disconnect(); -// uv_timer_start(&net->m_timer, Network::onTimer, (100 - net->m_options->donateLevel()) * 60 * 1000, 0); -//} diff --git a/src/net/strategies/FailoverStrategy.cpp b/src/net/strategies/FailoverStrategy.cpp new file mode 100644 index 000000000..07eabcdeb --- /dev/null +++ b/src/net/strategies/FailoverStrategy.cpp @@ -0,0 +1,121 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * 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 . + */ + + +#include "interfaces/IStrategyListener.h" +#include "net/Client.h" +#include "net/strategies/FailoverStrategy.h" +#include "Options.h" + + +FailoverStrategy::FailoverStrategy(const std::vector &urls, const char *agent, IStrategyListener *listener) : + m_active(-1), + m_index(0), + m_listener(listener) +{ + for (const Url *url : urls) { + add(url, agent); + } +} + + +void FailoverStrategy::connect() +{ + m_pools[m_index]->connect(); +} + + +void FailoverStrategy::resume() +{ + if (!isActive()) { + return; + } + + m_listener->onJob( m_pools[m_active], m_pools[m_active]->job()); +} + + +void FailoverStrategy::submit(const JobResult &result) +{ + m_pools[m_active]->submit(result); +} + + +void FailoverStrategy::onClose(Client *client, int failures) +{ + if (failures == -1) { + return; + } + + if (m_active == client->id()) { + m_active = -1; + m_listener->onPause(this); + } + + if (m_index == 0 && failures < Options::i()->retries()) { + return; + } + + if (m_index == client->id() && (m_pools.size() - m_index) > 1) { + m_pools[++m_index]->connect(); + } +} + + +void FailoverStrategy::onJobReceived(Client *client, const Job &job) +{ + if (m_active == client->id()) { + m_listener->onJob(client, job); + } +} + + +void FailoverStrategy::onLoginSuccess(Client *client) +{ + int active = m_active; + + if (client->id() == 0 || !isActive()) { + active = client->id(); + } + + for (size_t i = 1; i < m_pools.size(); ++i) { + if (active != static_cast(i)) { + m_pools[i]->disconnect(); + } + } + + if (active >= 0 && active != m_active) { + m_index = m_active = active; + m_listener->onActive(client); + } +} + + +void FailoverStrategy::add(const Url *url, const char *agent) +{ + Client *client = new Client(m_pools.size(), agent, this); + client->setUrl(url); + client->setRetryPause(Options::i()->retryPause() * 1000); + + m_pools.push_back(client); +} diff --git a/src/net/strategies/FailoverStrategy.h b/src/net/strategies/FailoverStrategy.h new file mode 100644 index 000000000..456ddc66f --- /dev/null +++ b/src/net/strategies/FailoverStrategy.h @@ -0,0 +1,66 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * 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 . + */ + +#ifndef __FAILOVERSTRATEGY_H__ +#define __FAILOVERSTRATEGY_H__ + + +#include + + +#include "interfaces/IClientListener.h" +#include "interfaces/IStrategy.h" + + +class Client; +class IStrategyListener; +class Url; + + +class FailoverStrategy : public IStrategy, public IClientListener +{ +public: + FailoverStrategy(const std::vector &urls, const char *agent, IStrategyListener *listener); + +public: + inline bool isActive() const override { return m_active >= 0; } + + void connect() override; + void resume() override; + void submit(const JobResult &result) override; + +protected: + void onClose(Client *client, int failures) override; + void onJobReceived(Client *client, const Job &job) override; + void onLoginSuccess(Client *client) override; + +private: + void add(const Url *url, const char *agent); + + int m_active; + int m_index; + IStrategyListener *m_listener; + std::vector m_pools; +}; + +#endif /* __FAILOVERSTRATEGY_H__ */ From 152b65b67ce6d452f5129245bf8c97dd3663a188 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 1 Jul 2017 21:11:41 +0300 Subject: [PATCH 9/9] Increase response timeout to 20 seconds. --- src/net/Client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/Client.h b/src/net/Client.h index 65fdc42a6..295718303 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -48,7 +48,7 @@ public: ClosingState }; - constexpr static int kResponseTimeout = 15 * 1000; + constexpr static int kResponseTimeout = 20 * 1000; constexpr static int kKeepAliveTimeout = 60 * 1000; Client(int id, const char *agent, IClientListener *listener);