diff --git a/src/common/net/Client.h b/src/common/net/Client.h index 27273092c..4be8badba 100644 --- a/src/common/net/Client.h +++ b/src/common/net/Client.h @@ -30,6 +30,7 @@ #include +#include "common/crypto/Algorithm.h" #include "common/net/Id.h" #include "common/net/Job.h" #include "common/net/Pool.h" @@ -66,16 +67,17 @@ class Client void setPool(const Pool &pool); void tick(uint64_t now); - 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 int id() const { return m_id; } - inline SocketState state() const { return m_state; } - inline uint16_t port() const { return m_pool.port(); } - inline void setQuiet(bool quiet) { m_quiet = quiet; } - inline void setRetries(int retries) { m_retries = retries; } - inline void setRetryPause(int ms) { m_retryPause = ms; } + 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 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 xmrig::Algorithm &algo) { m_pool.setAlgo(algo); } + inline void setQuiet(bool quiet) { m_quiet = quiet; } + inline void setRetries(int retries) { m_retries = retries; } + inline void setRetryPause(int ms) { m_retryPause = ms; } private: enum Extensions { diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index ca73b3158..c12e05d55 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -247,17 +247,15 @@ void Pool::adjust(xmrig::Algo algorithm) m_algorithm.setVariant(xmrig::VARIANT_1); } - m_algorithms.push_back(m_algorithm); + rebuild(); +} -# ifndef XMRIG_PROXY_PROJECT - if (m_algorithm.algo() != xmrig::CRYPTONIGHT_HEAVY) { - addVariant(xmrig::VARIANT_1); - addVariant(xmrig::VARIANT_0); - addVariant(xmrig::VARIANT_XTL); - addVariant(xmrig::VARIANT_IPBC); - addVariant(xmrig::VARIANT_AUTO); - } -# endif + +void Pool::setAlgo(const xmrig::Algorithm &algorithm) +{ + m_algorithm = algorithm; + + rebuild(); } @@ -309,3 +307,20 @@ void Pool::addVariant(xmrig::Variant variant) m_algorithms.push_back(algorithm); } + + +void Pool::rebuild() +{ + m_algorithms.clear(); + m_algorithms.push_back(m_algorithm); + +# ifndef XMRIG_PROXY_PROJECT + if (m_algorithm.algo() != xmrig::CRYPTONIGHT_HEAVY) { + addVariant(xmrig::VARIANT_1); + addVariant(xmrig::VARIANT_0); + addVariant(xmrig::VARIANT_XTL); + addVariant(xmrig::VARIANT_IPBC); + addVariant(xmrig::VARIANT_AUTO); + } +# endif +} diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index ad015bf2c..eaabe54d3 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -78,6 +78,7 @@ class Pool bool setUserpass(const char *userpass); rapidjson::Value toJSON(rapidjson::Document &doc) const; void adjust(xmrig::Algo algorithm); + void setAlgo(const xmrig::Algorithm &algorithm); # ifdef APP_DEBUG void print() const; @@ -86,6 +87,7 @@ class Pool private: bool parseIPv6(const char *addr); void addVariant(xmrig::Variant variant); + void rebuild(); bool m_nicehash; int m_keepAlive; diff --git a/src/donate.h b/src/donate.h index 388d523d6..731a71f79 100644 --- a/src/donate.h +++ b/src/donate.h @@ -43,6 +43,7 @@ */ constexpr const int kDefaultDonateLevel = 2; constexpr const int kMinimumDonateLevel = 0; +constexpr const uint64_t kFreeThreshold = 256; #endif /* __DONATE_H__ */ diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 6f4c74f2d..5de974677 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -28,20 +28,20 @@ #include "common/xmrig.h" #include "core/Config.h" #include "core/Controller.h" +#include "donate.h" #include "interfaces/IStrategyListener.h" #include "net/strategies/DonateStrategy.h" #include "proxy/Counters.h" #include "proxy/StatsData.h" -static inline int random(int min, int max){ - return min + rand() / (RAND_MAX / (max - min + 1) + 1); +static inline float randomf(float min, float max) { + return (max - min) * ((((float) rand()) / (float) RAND_MAX)) + min; } DonateStrategy::DonateStrategy(xmrig::Controller *controller, IStrategyListener *listener) : m_active(false), - m_suspended(false), m_listener(listener), m_donateTicks(0), m_target(0), @@ -58,9 +58,10 @@ DonateStrategy::DonateStrategy(xmrig::Controller *controller, IStrategyListener m_client = new Client(-1, Platform::userAgent(), this); m_client->setPool(Pool("proxy.fee.xmrig.com", 9999, userId, nullptr)); m_client->setRetryPause(1000); + m_client->setAlgo(controller->config()->algorithm()); m_client->setQuiet(true); - m_target = random(3000, 9000); + m_target = (100 - controller->config()->donateLevel()) * 60 * randomf(0.5, 1.5); } @@ -77,7 +78,7 @@ bool DonateStrategy::reschedule() return false; } - m_target = m_ticks + (6000 * ((double) m_donateTicks / level)); + m_target = m_ticks + ((6000 - level) * ((double) m_donateTicks / level)); m_active = false; stop(); @@ -85,6 +86,20 @@ bool DonateStrategy::reschedule() } +void DonateStrategy::save(const Client *client, const Job &job) +{ + m_pending.job = job; + m_pending.host = client->host(); + m_pending.port = client->port(); +} + + +void DonateStrategy::setAlgo(const xmrig::Algorithm &algorithm) +{ + m_client->setAlgo(algorithm); +} + + int64_t DonateStrategy::submit(const JobResult &result) { return m_client->submit(result); @@ -93,13 +108,11 @@ int64_t DonateStrategy::submit(const JobResult &result) void DonateStrategy::connect() { - m_suspended = false; } void DonateStrategy::stop() { - m_suspended = true; m_donateTicks = 0; m_client->disconnect(); } @@ -109,18 +122,15 @@ void DonateStrategy::tick(uint64_t now) { m_client->tick(now); - if (m_suspended) { - return; - } - m_ticks++; if (m_ticks == m_target) { - if (Counters::miners() < 256) { + if (kFreeThreshold > 0 && Counters::miners() < kFreeThreshold) { m_target += 600; return; } + m_pending.job.reset(); m_client->connect(); } diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index a9e8ec827..f73a3f4c3 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -25,6 +25,7 @@ #define __DONATESTRATEGY_H__ +#include "common/utils/c_str.h" #include "interfaces/IClientListener.h" #include "interfaces/IStrategy.h" @@ -42,13 +43,26 @@ namespace xmrig { class DonateStrategy : public IStrategy, public IClientListener { public: + struct Pending + { + Job job; + xmrig::c_str host; + int port; + }; + + DonateStrategy(xmrig::Controller *controller, IStrategyListener *listener); ~DonateStrategy(); bool reschedule(); + void save(const Client *client, const Job &job); + void setAlgo(const xmrig::Algorithm &algorithm); + + inline bool hasPendingJob() const { return m_pending.job.isValid(); } + inline const Pending &pending() const { return m_pending; } - inline bool isActive() const override { return m_active; } - inline void resume() override {} + inline bool isActive() const override { return m_active; } + inline void resume() override {} int64_t submit(const JobResult &result) override; void connect() override; @@ -63,9 +77,9 @@ class DonateStrategy : public IStrategy, public IClientListener private: bool m_active; - bool m_suspended; Client *m_client; IStrategyListener *m_listener; + Pending m_pending; uint64_t m_donateTicks; uint64_t m_target; uint64_t m_ticks; diff --git a/src/proxy/splitters/nicehash/NonceMapper.cpp b/src/proxy/splitters/nicehash/NonceMapper.cpp index 92bc76b73..e002ab52c 100644 --- a/src/proxy/splitters/nicehash/NonceMapper.cpp +++ b/src/proxy/splitters/nicehash/NonceMapper.cpp @@ -155,6 +155,11 @@ void NonceMapper::tick(uint64_t ticks, uint64_t now) if (m_donate) { m_donate->tick(now); + + if (m_donate->isActive() && m_donate->hasPendingJob() && m_donate->reschedule()) { + const auto &pending = m_donate->pending(); + setJob(pending.host.data(), pending.port, pending.job); + } } } @@ -195,17 +200,16 @@ void NonceMapper::onActive(IStrategy *strategy, Client *client) void NonceMapper::onJob(IStrategy *strategy, Client *client, const Job &job) { - if (m_controller->config()->isVerbose()) { - LOG_INFO(isColors() ? "#%03u " MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s") - : "#%03u new job from %s:%d diff %d algo %s", - m_id, client->host(), client->port(), job.diff(), job.algorithm().shortName()); - } + if (m_donate) { + if (m_donate->isActive() && client->id() != -1 && !m_donate->reschedule()) { + m_donate->save(client, job); + return; + } - if (m_donate && m_donate->isActive() && client->id() != -1 && !m_donate->reschedule()) { - return; + m_donate->setAlgo(job.algorithm()); } - m_storage->setJob(job); + setJob(client->host(), client->port(), job); } @@ -286,6 +290,18 @@ void NonceMapper::connect() } +void NonceMapper::setJob(const char *host, int port, const Job &job) +{ + if (m_controller->config()->isVerbose()) { + LOG_INFO(isColors() ? "#%03u " MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s") + : "#%03u new job from %s:%d diff %d algo %s", + m_id, host, port, job.diff(), job.algorithm().shortName()); + } + + m_storage->setJob(job); +} + + void NonceMapper::suspend() { m_suspended = 1; diff --git a/src/proxy/splitters/nicehash/NonceMapper.h b/src/proxy/splitters/nicehash/NonceMapper.h index 510a031ff..fd8753fca 100644 --- a/src/proxy/splitters/nicehash/NonceMapper.h +++ b/src/proxy/splitters/nicehash/NonceMapper.h @@ -96,6 +96,7 @@ class NonceMapper : public IStrategyListener IStrategy *createStrategy(const std::vector &pools); SubmitCtx submitCtx(int64_t seq); void connect(); + void setJob(const char *host, int port, const Job &job); void suspend(); DonateStrategy *m_donate;