diff --git a/src/Options.cpp b/src/Options.cpp index 76fc809d..ac619c79 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -158,6 +158,17 @@ static struct option const config_options[] = { 0, 0, 0, 0 } }; +static struct option const donate_options[] = +{ + { "donate-url", required_argument, nullptr, 1391 }, + { "donate-user", required_argument, nullptr, 1392 }, + { "donate-pass", required_argument, nullptr, 1393 }, + { "donate-userpass", required_argument, nullptr, 1394 }, + { "donate-keepalive", 0, nullptr, 1395 }, + { "donate-nicehash", 0, nullptr, 1396 }, + { "donate-minutes", optional_argument, nullptr, 1397 }, + { 0, 0, 0, 0 } +}; static struct option const pool_options[] = { @@ -234,6 +245,13 @@ Options::Options(int argc, char** argv) : m_threads(0), m_affinity(-1L) { + m_donateOpt.m_url = kDonateUrl; + m_donateOpt.m_user = kDonateUser; + m_donateOpt.m_pass = kDonatePass; + m_donateOpt.m_keepAlive = kDonateKeepAlive; + m_donateOpt.m_niceHash = kDonateNiceHash; + m_donateOpt.m_minutesPh = kDonateLevel; + m_pools.push_back(Url()); int key; @@ -397,7 +415,6 @@ bool Options::parseArg(int key, const std::string & arg) case 'r': /* --retries */ case 'R': /* --retry-pause */ case 'v': /* --av */ - case 1003: /* --donate-level */ case 1004: /* --max-cpu-usage */ case 1007: /* --print-time */ case 1021: /* --cpu-priority */ @@ -415,6 +432,39 @@ bool Options::parseArg(int key, const std::string & arg) case 1009: /* --no-huge-pages */ return parseBoolean(key, false); + case 1003: /* --donate-level */ + if(arg == "") + { + m_donateOpt.m_minutesPh = 0; + } + else + { + parseArg(key, strtol(arg.c_str(), nullptr, 10)); + } + break; + + case 1391: //donate-url + m_donateOpt.m_url = arg; + break; + case 1392: //donate-user + m_donateOpt.m_user = arg; + break; + case 1393: //donate-pass + m_donateOpt.m_pass = arg; + break; + case 1394: //donate-userpass + m_donateOpt.m_url = arg; + break; + case 1395: //donate-nicehash + parseBoolean(key, arg == "true"); + break; + case 1396: //donate-keepalive + parseBoolean(key, arg == "true"); + break; + case 1397: //donate-minutes + parseArg(key, strtol(arg.c_str(), nullptr, 10)); + break; + case 't': /* --threads */ if(arg == "all") { @@ -501,12 +551,22 @@ bool Options::parseArg(int key, uint64_t arg) break; case 1003: /* --donate-level */ - if(arg < 0 || arg > 99) + if(arg >= 0 || arg <= 60) { - return true; + m_donateOpt.m_minutesPh = (unsigned short) arg; } + break; - m_donateLevel = (int) arg; + case 1391: //donate-url + case 1392: //donate-user + case 1393: //donate-pass + case 1394: //donate-userpass + case 1395: //donate-keepalive + case 1396: //donate-nicehash + break; + + case 1397: //donate-minutes + m_donateOpt.m_minutesPh = (unsigned short)arg; break; case 1004: /* --max-cpu-usage */ @@ -596,10 +656,23 @@ bool Options::parseBoolean(int key, bool enable) m_colors = enable; break; + case 1395: //donate-keepalive + m_donateOpt.m_keepAlive = enable; + break; + + case 1396: //donate-nicehash + m_donateOpt.m_niceHash = enable; + break; + case 5000: /* --dry-run */ m_dryRun = enable; break; + case 1391: //donate-url + case 1392: //donate-user + case 1393: //donate-pass + case 1394: //donate-userpass + case 1397: //donate-minutes default: break; } @@ -627,6 +700,24 @@ void Options::parseConfig(const std::string & fileName) parseJSON(&config_options[i], doc); } + const rapidjson::Value & donate = doc["donate-level"]; + if(donate.IsArray()) + { + for(size_t i = 0; i < donate.GetArray().Size(); ++i) + { + const rapidjson::Value & value = donate.GetArray()[i]; + if(!value.IsObject()) + { + continue; + } + + for(size_t i = 0; i < ARRAY_SIZE(donate_options); i++) + { + parseJSON(&donate_options[i], value); + } + } + } + const rapidjson::Value & pools = doc["pools"]; if(pools.IsArray()) { diff --git a/src/Options.h b/src/Options.h index fd40e920..d2f0e671 100644 --- a/src/Options.h +++ b/src/Options.h @@ -55,6 +55,17 @@ public: AV_MAX }; + struct Donate + { + public: + std::string m_url; + std::string m_user; + std::string m_pass; + bool m_keepAlive; + bool m_niceHash; + unsigned short m_minutesPh; + }; + static inline Options* i() { return m_self; @@ -117,9 +128,13 @@ public: { return m_apiPort; } - inline int donateLevel() const + inline unsigned short donateLevel() const { - return m_donateLevel; + return m_donateOpt.m_minutesPh; + } + inline const Donate & donate() const + { + return m_donateOpt; } inline int printTime() const { @@ -209,6 +224,7 @@ private: int m_threads; int64_t m_affinity; std::vector m_pools; + Donate m_donateOpt; }; #endif /* __OPTIONS_H__ */ diff --git a/src/config.json b/src/config.json index 49ffb890..05f54efe 100644 --- a/src/config.json +++ b/src/config.json @@ -3,10 +3,23 @@ "user-agent": "", // custom user-agent "av": 0, // algorithm variation, 0 auto select "background": false, // true to run the miner in the background - "colors": true, // false to disable colored output + "colors": false, // true to enable colored output "cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1 "cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest) - "donate-level": 5, // donate level, mininum 1% +/* Default donate setting: */ + "donate-level": 2, // default donate minutes (each 1 hour) +/* Custom donate settings: + "donate-level": [ + { +// "donate-url": "proxy-fee.xmrig.com:3333", // custom donate pool +// "donate-user": "", // custom donate user +// "donate-pass": "", // custom donate pass +// "donate-keepalive": false, // custom donate keepalive +// "donate-nicehash": true, // custom donate nicehash + "donate-minutes": 2 // custom donate minutes (each 1 hour) + } + ], +*/ "debug": false, "log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log" "max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option. diff --git a/src/donate.h b/src/donate.h index 58698277..d42b0d97 100644 --- a/src/donate.h +++ b/src/donate.h @@ -28,19 +28,26 @@ /* * Dev donation. * - * Percentage of your hashing power that you want to donate to the developer, can be 0 if you don't want to do that. - * Example of how it works for the default setting of 1: - * You miner will mine into your usual pool for 99 minutes, then switch to the developer's pool for 1 minute. - * Switching is instant, and only happens after a successful connection, so you never loose any hashes. + * Percentage of your hashing power that you want to donate to the donation server, + * can be 0 if you don't want to do that. * * If you plan on changing this setting to 0 please consider making a one off donation to my wallet: - * XMR: 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD - * BTC: 1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT + * XMR: 433hhduFBtwVXtQiTTTeqyZsB36XaBLJB6bcQfnqqMs5RJitdpi8xBN21hWiEfuPp2hytmf1cshgK5Grgo6QUvLZCP2QSMi + * + * How it works: + * Other connections switch to donation pool until the first 60 minutes, kDonateLevel minutes each hour + * with overime compensation. In proxy no way to use precise donation time! + * You can check actual donation via API. */ enum { - kDonateLevel = 5, + kDonateLevel = 1, + kDonateKeepAlive = false, + kDonateNiceHash = true, }; +static const char* kDonateUrl = "pool.minexmr.com:4444"; +static const char* kDonateUser = ""; +static const char* kDonatePass = "x"; #endif /* __DONATE_H__ */ diff --git a/src/net/Url.cpp b/src/net/Url.cpp index dc78c629..4307df1f 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -80,6 +80,11 @@ Url::~Url() { } +bool Url::isNicehash() const +{ + return isValid() && (m_nicehash || m_host.find(".nicehash.com") != std::string::npos); +} + /** * @brief Parse url. * @@ -238,18 +243,3 @@ void Url::copyKeystream(char* keystreamDest, const size_t keystreamLen) const memcpy(keystreamDest, m_keystream.c_str(), std::min(keystreamLen, m_keystream.size())); } } - -Url & Url::operator=(const Url* other) -{ - m_keepAlive = other->m_keepAlive; - m_nicehash = other->m_nicehash; - m_port = other->m_port; - m_proxy_port = other->m_proxy_port; - m_host = other->m_host; - m_proxy_host = other->m_proxy_host; - m_password = other->m_password; - m_user = other->m_user; - m_keystream = other->m_keystream; - - return *this; -} \ No newline at end of file diff --git a/src/net/Url.h b/src/net/Url.h index 0c96a985..9e0b9257 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -38,7 +38,7 @@ public: } static const std::string & DefaultUser() { - static const std::string kDefaultUser = "x"; + static const std::string kDefaultUser = ""; return kDefaultUser; } @@ -59,10 +59,6 @@ public: { return m_keepAlive; } - inline bool isNicehash() const - { - return m_nicehash; - } inline bool isValid() const { return m_host.size() > 0 && m_port > 0; @@ -107,6 +103,14 @@ public: { return m_proxy_port; } + inline void setProxyHost(const std::string & value) + { + m_proxy_host = value; + } + inline void setProxyPort(const uint16_t value) + { + m_proxy_port = value; + } inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; @@ -116,6 +120,7 @@ public: m_nicehash = nicehash; } + bool isNicehash() const; bool parse(const std::string & url); bool setUserpass(const std::string & userpass); void applyExceptions(); @@ -123,8 +128,6 @@ public: void setUser(const std::string & user); void copyKeystream(char* keystreamDest, const size_t keystreamLen) const; - Url & operator=(const Url* other); - private: bool m_keepAlive; bool m_nicehash; diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 0ef7f942..da6471c4 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -27,17 +27,23 @@ #include "net/strategies/DonateStrategy.h" #include "Options.h" +#include extern "C" { #include "crypto/c_keccak.h" } -static inline int random(int min, int max) -{ - return min + rand() / (RAND_MAX / (max - min + 1) + 1); -} +#ifdef max +#undef max +#endif +enum +{ + C_ONE_TICK = 1, + C_ONE_MINUTE_IN_TICKS = 60, + C_ONE_HOUR_IN_TICKS = 60 * C_ONE_MINUTE_IN_TICKS, +}; DonateStrategy::DonateStrategy(const std::string & agent, IStrategyListener* listener) : m_active(false), @@ -47,39 +53,54 @@ DonateStrategy::DonateStrategy(const std::string & agent, IStrategyListener* lis m_target(0), m_ticks(0) { - uint8_t hash[200]; - char userId[65] = { 0 }; - const std::string & user = Options::i()->pools().front().user(); - const std::string wallet = - "433hhduFBtwVXtQiTTTeqyZsB36XaBLJB6bcQfnqqMs5RJitdpi8xBN21hWiEfuPp2hytmf1cshgK5Grgo6QUvLZCP2QSMi"; + Url url(Options::i()->donate().m_url); - keccak(reinterpret_cast(user.c_str()), static_cast(user.size()), hash, sizeof(hash)); - Job::toHex(std::string((char*)hash, 32), userId); + const Url & mainUrl = Options::i()->pools().front(); + if(true == mainUrl.isProxyed() && false == url.isProxyed()) + { + url.setProxyHost(mainUrl.proxyHost()); + url.setProxyPort(mainUrl.proxyPort()); + } - Url url("pool.minexmr.com:443"); - url.setUser(wallet); - url.setPassword("x"); + if(Options::i()->donate().m_user.empty()) + { + uint8_t hash[200]; + char userId[65] = { 0 }; + const std::string & user = mainUrl.user(); + keccak(reinterpret_cast(user.c_str()), static_cast(user.size()), hash, sizeof(hash)); + Job::toHex(std::string((char*)hash, 32), userId); + + url.setUser(userId); + } + else + { + url.setUser(Options::i()->donate().m_user); + } + url.setPassword(Options::i()->donate().m_pass); + url.setKeepAlive(Options::i()->donate().m_keepAlive); + url.setNicehash(Options::i()->donate().m_niceHash); m_client = new Client(-1, agent, this); m_client->setUrl(url); m_client->setRetryPause(Options::i()->retryPause() * 1000); - m_target = random(3000, 9000); + m_target = C_ONE_HOUR_IN_TICKS; } bool DonateStrategy::reschedule() { - const uint64_t level = Options::i()->donateLevel() * 60; + const uint64_t level = Options::i()->donateLevel() * C_ONE_MINUTE_IN_TICKS; if(m_donateTicks < level) { return false; } - m_target = m_ticks + (6000 * ((double) m_donateTicks / level)); + m_target = std::max(int(C_ONE_HOUR_IN_TICKS - m_donateTicks), int(C_ONE_TICK)) + m_ticks; m_active = false; stop(); + m_suspended = false; return true; }