diff --git a/README.md b/README.md index 6ab4b6a2..bea99be5 100644 --- a/README.md +++ b/README.md @@ -1,122 +1,22 @@ -# XMRig -XMRig is a high performance Monero (XMR) CPU miner, with official support for Windows. -Originally based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code, since version 1.0.0 completely rewritten from scratch on C++. +# XMRig (enWILLYado version) +[XMRig](https://github.com/xmrig) is a team that has some high performance Monero (XMR) miners, with official support for Windows. +This fork is originally based on the [CPU-mining](https://github.com/xmrig/xmrig) version with some optimizations/rewrites, interesting features for final users and a little code refactors. -* This is the **CPU-mining** version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd). +* This software is like the [CPU-mining](https://github.com/xmrig/xmrig) version; but there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd). * [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases. - +## Own features -#### Table of contents -* [Features](#features) -* [Download](#download) -* [Usage](#usage) -* [Algorithm variations](#algorithm-variations) -* [Build](https://github.com/xmrig/xmrig/wiki/Build) -* [Common Issues](#common-issues) -* [Other information](#other-information) -* [Donations](#donations) -* [Contacts](#contacts) - -## Features -* High performance. -* Official Windows support. -* Small Windows executable, without dependencies. -* x86/x64 support. -* Support for backup (failover) mining server. -* keepalived support. -* Command line options compatible with cpuminer. -* CryptoNight-Lite support for AEON. -* Smart automatic [CPU configuration](https://github.com/xmrig/xmrig/wiki/Threads). -* Nicehash support -* It's open source software. - -## Download -* Binary releases: https://github.com/xmrig/xmrig/releases -* Git tree: https://github.com/xmrig/xmrig.git - * Clone with `git clone https://github.com/xmrig/xmrig.git` :hammer: [Build instructions](https://github.com/xmrig/xmrig/wiki/Build). - -## Usage -### Basic example -``` -xmrig.exe -o pool.monero.hashvault.pro:5555 -u YOUR_WALLET -p x -k -``` - -### Failover -``` -xmrig.exe -o pool.monero.hashvault.pro:5555 -u YOUR_WALLET1 -p x -k -o pool.supportxmr.com:5555 -u YOUR_WALLET2 -p x -k -``` -For failover you can add multiple pools, maximum count not limited. - -### Options -``` - -a, --algo=ALGO cryptonight (default) or cryptonight-lite - -o, --url=URL URL of mining server - -O, --userpass=U:P username:password pair for mining server - -u, --user=USERNAME username for mining server - -p, --pass=PASSWORD password for mining server - -t, --threads=N number of miner threads - -v, --av=N algorithm variation, 0 auto select - -k, --keepalive send keepalived for prevent timeout (need pool support) - -r, --retries=N number of times to retry before switch to backup server (default: 5) - -R, --retry-pause=N time to pause between retries (default: 5) - --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1 - --cpu-priority set process priority (0 idle, 2 normal to 5 highest) - --no-huge-pages disable huge pages support - --no-color disable colored output - --donate-level=N donate level, default 5% (5 minutes in 100 minutes) - --user-agent set custom user-agent string for pool - -B, --background run the miner in the background - -c, --config=FILE load a JSON-format configuration file - -l, --log-file=FILE log all output to a file - --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75) - --safe safe adjust threads and av settings for current CPU - --nicehash enable nicehash/xmrig-proxy support - --print-time=N print hashrate report every N seconds - --api-port=N port for the miner API - --api-access-token=T access token for API - --api-worker-id=ID custom worker-id for API - -h, --help display this help and exit - -V, --version output version information and exit -``` - -Also you can use configuration via config file, default **config.json**. You can load multiple config files and combine it with command line options. - -## Algorithm variations -Since version 0.8.0. -* `--av=1` For CPUs with hardware AES. -* `--av=2` Lower power mode (double hash) of `1`. -* `--av=3` Software AES implementation. -* `--av=4` Lower power mode (double hash) of `3`. - -## Common Issues -### HUGE PAGES unavailable -* Run XMRig as Administrator. -* Since version 0.8.0 XMRig automatically enables SeLockMemoryPrivilege for current user, but reboot or sign out still required. [Manual instruction](https://msdn.microsoft.com/en-gb/library/ms190730.aspx). - -## Other information -* No HTTP support, only stratum protocol support. -* No TLS support. -* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`. - - -### CPU mining performance -* **Intel i7-7700** - 307 H/s (4 threads) -* **AMD Ryzen 7 1700X** - 560 H/s (8 threads) - -Please note performance is highly dependent on system load. The numbers above are obtained on an idle system. Tasks heavily using a processor cache, such as video playback, can greatly degrade hashrate. Optimal number of threads depends on the size of the L3 cache of a processor, 1 thread requires 2 MB of cache. - -### Maximum performance checklist -* Idle operating system. -* Do not exceed optimal thread count. -* Use modern CPUs with AES-NI instruction set. -* Try setup optimal cpu affinity. -* Enable fast memory (Large/Huge pages). +* Connect to pool or proxies over HTTP PROXY. +* Include basic encrypted communications. ## Donations -* XMR: `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD` -* BTC: `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT` +* XMR: `433hhduFBtwVXtQiTTTeqyZsB36XaBLJB6bcQfnqqMs5RJitdpi8xBN21hWiEfuPp2hytmf1cshgK5Grgo6QUvLZCP2QSMi` +* BTC: `13MTEjDv8JmS4suaRx6CcWNthR1vwPr7Ce` +* DOGE: `DHif8RTy8E6K4b71u3fXXSk7AEyiuN2sUi` ## Contacts -* support@xmrig.com -* [reddit](https://www.reddit.com/user/XMRig/) +* xmrig@enwillyado.com +* [telegram](https://telegram.me/enWILLYado) + +¡Se habla español! diff --git a/src/config.json b/src/config.json index 07570d8b..49ffb890 100644 --- a/src/config.json +++ b/src/config.json @@ -1,5 +1,6 @@ { "algo": "cryptonight", // cryptonight (default) or cryptonight-lite + "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 @@ -17,7 +18,10 @@ "threads": null, // number of miner threads "pools": [ { - "url": "pool.minemonero.pro:5555", // URL of mining server + "url": "pool.minemonero.pro:3333", // --------------- URL of mining server + /* "url": "pool.minemonero.pro:443@localhost:8080",*/ // --------------- URL of mining server over HTTP (CONNECT) proxy + /* "url": "pool.minemonero.pro:7777#secret_keystream",*/ // URL of mining xmrig-proxy with encrypted support + /* "url": "pool.minemonero.pro:8080#secret_keystream@localhost:8080",*/ // URL of mining xmrig-proxy with encrypted support over HTTP (CONNECT) proxy "user": "", // username for mining server "pass": "x", // password for mining server "keepalive": true, // send keepalived for prevent timeout (need pool support) diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 56a47329..d8658e7a 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -55,6 +55,8 @@ int64_t Client::m_sequence = 1; Client::Client(int id, const char *agent, IClientListener *listener) : m_quiet(false), + m_keystream(), + m_encrypted(false), m_agent(agent), m_listener(listener), m_id(id), @@ -68,6 +70,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) : { memset(m_ip, 0, sizeof(m_ip)); memset(&m_hints, 0, sizeof(m_hints)); + memset(m_keystream, 0, sizeof(m_keystream)); m_resolver.data = this; @@ -128,6 +131,16 @@ void Client::setUrl(const Url *url) return; } + if (url->hasKeystream()) + { + url->copyKeystream(m_keystream, sizeof(m_keystream)); + m_encrypted = true; + } + else + { + m_encrypted = false; + } + m_url = url; } @@ -271,7 +284,7 @@ int Client::resolve(const char *host) } -int64_t Client::send(size_t size) +int64_t Client::send(size_t size, const bool encrypted) { LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), size, m_sendBuf); if ((state() != ConnectedState && state() != ProxingState) || !uv_is_writable(m_stream)) { @@ -279,6 +292,22 @@ int64_t Client::send(size_t size) return -1; } + if(encrypted && m_encrypted) + { + // Encrypt + for(size_t i = 0; i < std::min(size, sizeof(m_keystream)); ++i) + { + m_sendBuf[i] ^= m_keystream[i]; + } + + char * send_encr_hex = static_cast(malloc(size * 2 + 1)); + memset(send_encr_hex, 0, size * 2 + 1); + Job::toHex((const unsigned char*)m_sendBuf, size, send_encr_hex); + send_encr_hex[size * 2] = '\0'; + LOG_DEBUG("[%s:%u] send encr. (%d bytes): \"0x%s\"", m_url.host(), m_url.port(), size, send_encr_hex); + free(send_encr_hex); + } + uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size); if (uv_try_write(m_stream, &buf, 1) < 0) { @@ -341,7 +370,7 @@ void Client::prelogin() m_sendBuf[size + 1] = '\0'; LOG_DEBUG("Prelogin send (%d bytes): \"%s\"", size, m_sendBuf); - send (size + 1); + send (size + 1, false); } else { @@ -631,6 +660,21 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) char* start = buf->base; size_t remaining = client->m_recvBufPos; + if(client->m_encrypted) + { + char * read_encr_hex = static_cast(malloc(nread * 2 + 1)); + memset(read_encr_hex, 0, nread * 2 + 1); + Job::toHex((const unsigned char*)start, nread, read_encr_hex); + LOG_DEBUG("[%s] read encr. (%d bytes): \"0x%s\"", client->m_ip, nread, read_encr_hex); + free(read_encr_hex); + + // DeEncrypt + for(int i = 0; i < (int)nread; ++i) + { + start[i] ^= client->m_keystream[i]; + } + } + while ((end = static_cast(memchr(start, '\n', remaining))) != nullptr) { end++; size_t len = end - start; diff --git a/src/net/Client.h b/src/net/Client.h index c61ccd10..9436dc48 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -79,7 +79,7 @@ private: bool parseJob(const rapidjson::Value ¶ms, int *code); bool parseLogin(const rapidjson::Value &result, int *code); int resolve(const char *host); - int64_t send(size_t size); + int64_t send(size_t size, const bool encrypted = true); void close(); void connect(struct sockaddr *addr); void prelogin(); @@ -106,6 +106,8 @@ private: char m_ip[17]; char m_rpcId[64]; char m_sendBuf[768]; + char m_keystream[sizeof(m_sendBuf)]; + bool m_encrypted; const char *m_agent; IClientListener *m_listener; int m_id; diff --git a/src/net/Url.cpp b/src/net/Url.cpp index f45f94bb..edc9ab5e 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "net/Url.h" @@ -43,7 +44,8 @@ Url::Url() : m_user(nullptr), m_port(kDefaultPort), m_proxy_host(nullptr), - m_proxy_port(kDefaultProxyPort) + m_proxy_port(kDefaultProxyPort), + m_keystream(nullptr) { } @@ -66,8 +68,9 @@ Url::Url(const char *url) : m_password(nullptr), m_user(nullptr), m_port(kDefaultPort), - m_proxy_host (nullptr), - m_proxy_port (kDefaultProxyPort) + m_proxy_host(nullptr), + m_proxy_port(kDefaultProxyPort), + m_keystream(nullptr) { parse(url); } @@ -79,8 +82,9 @@ Url::Url(const char *host, uint16_t port, const char *user, const char *password m_password(password ? strdup(password) : nullptr), m_user(user ? strdup(user) : nullptr), m_port(port), - m_proxy_host (nullptr), - m_proxy_port (kDefaultProxyPort) + m_proxy_host(nullptr), + m_proxy_port(kDefaultProxyPort), + m_keystream(nullptr) { m_host = strdup(host); } @@ -91,9 +95,10 @@ Url::~Url() free(m_host); free(m_password); free(m_user); + free(m_proxy_host); + free(m_keystream); } - bool Url::parse(const char *url) { const char *p = strstr(url, "://"); @@ -123,13 +128,30 @@ bool Url::parse(const char *url) m_host[size - 1] = '\0'; const char* proxy = strchr(port, '@'); + const char* keystream = strchr(port, '#'); + if(keystream) + { + ++keystream; + if(!proxy) + { + m_keystream = strdup(keystream); + } + else + { + const size_t keystreamsize = proxy - keystream; + m_keystream = static_cast(malloc (keystreamsize + 1)); + m_keystream[keystreamsize] = '\0'; + memcpy(m_keystream, keystream, keystreamsize); + } + } + m_port = (uint16_t) strtol(port, nullptr, 10); if (!proxy) { m_port = (uint16_t) strtol(port, nullptr, 10); return true; } - - ++proxy; + + ++proxy; const char* proxyport = strchr(proxy, ':'); if (!port) { @@ -203,6 +225,14 @@ void Url::setUser(const char *user) m_user = strdup(user); } +void Url::copyKeystream(char *keystreamDest, const size_t keystreamLen) const +{ + if(hasKeystream()) + { + memset(keystreamDest, 1, keystreamLen); + memcpy(keystreamDest, m_keystream, std::min(keystreamLen, strlen(m_keystream))); + } +} Url &Url::operator=(const Url *other) { @@ -217,7 +247,7 @@ Url &Url::operator=(const Url *other) free (m_proxy_host); if(other->m_proxy_host) { - m_proxy_host = strdup (other->m_proxy_host); + m_proxy_host = strdup (other->m_proxy_host); } else { @@ -227,5 +257,14 @@ Url &Url::operator=(const Url *other) setPassword(other->m_password); setUser(other->m_user); + free (m_keystream); + if(other->m_keystream) + { + m_keystream = strdup (other->m_keystream); + } + else + { + m_keystream = nullptr; + } return *this; } diff --git a/src/net/Url.h b/src/net/Url.h index 4c8b7d16..83f63b56 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -44,13 +44,14 @@ public: inline bool isKeepAlive() const { return m_keepAlive; } inline bool isNicehash() const { return m_nicehash; } inline bool isValid() const { return m_host && m_port > 0; } + inline bool hasKeystream() const { return m_keystream; } inline const char *host() const { return isProxyed() ? proxyHost() : finalHost(); } 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 isProxyed() ? proxyPort() : finalPort(); } inline bool isProxyed() const { return proxyHost(); } inline const char* finalHost() const { return m_host; } - inline uint16_t finalPort() const { return m_port;} + inline uint16_t finalPort() const { return m_port; } inline const char* proxyHost() const { return m_proxy_host; } inline uint16_t proxyPort() const { return m_proxy_port; } inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; } @@ -61,6 +62,7 @@ public: void applyExceptions(); void setPassword(const char *password); void setUser(const char *user); + void copyKeystream(char *keystreamDest, const size_t keystreamLen) const; Url &operator=(const Url *other); @@ -73,6 +75,7 @@ private: uint16_t m_port; char* m_proxy_host; uint16_t m_proxy_port; + char* m_keystream; }; #endif /* __URL_H__ */