mirror of
https://github.com/xmrig/xmrig.git
synced 2024-11-17 00:07:44 +00:00
Merge branch 'dev'
This commit is contained in:
commit
6605e1f6f2
138 changed files with 7329 additions and 6093 deletions
34
CHANGELOG.md
34
CHANGELOG.md
|
@ -1,3 +1,37 @@
|
|||
# v2.6.1-beta
|
||||
- [#168](https://github.com/xmrig/xmrig-proxy/issues/168) Added support for [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/blob/dev/doc/STRATUM_EXT.md#1-mining-algorithm-negotiation).
|
||||
- Added IPBC coin support, base algorithm `cn-lite` variant `ipbc`.
|
||||
- [#581](https://github.com/xmrig/xmrig/issues/581) Added support for upcoming Stellite (XTL) fork, base algorithm `cn` variant `xtl`, variant can set now, no need do it after fork.
|
||||
- Added support for **rig-id** stratum protocol extensions, compatible with xmr-stak.
|
||||
- Changed behavior for option `variant=-1` for `cryptonight`, now variant is `1` by default, if you mine old coins need change `variant` to `0`.
|
||||
- A lot of small fixes and better unification with proxy code.
|
||||
|
||||
# v2.6.0-beta3
|
||||
- [#563](https://github.com/xmrig/xmrig/issues/563) **Added [advanced threads mode](https://github.com/xmrig/xmrig/issues/563), now possible configure each thread individually.**
|
||||
- [#255](https://github.com/xmrig/xmrig/issues/563) Low power mode extended to **triple**, **quard** and **penta** modes.
|
||||
- [#519](https://github.com/xmrig/xmrig/issues/519) Fixed high donation levels, improved donation start time randomization.
|
||||
- [#554](https://github.com/xmrig/xmrig/issues/554) Fixed regression with `print-time` option.
|
||||
|
||||
# v2.6.0-beta2
|
||||
- Improved performance for `cryptonight v7` especially in double hash mode.
|
||||
- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was causing issues on some systems.
|
||||
- Added short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`.
|
||||
- Fixed regressions (v2.6.0-beta1 affected)
|
||||
- [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken.
|
||||
- [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken.
|
||||
- Fixed nonce calculation for `--av 4` (software AES, double hash) was causing reduction of effective hashrate and rejected shares on nicehash.
|
||||
|
||||
# v2.6.0-beta1
|
||||
- [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.**
|
||||
- HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization.
|
||||
- Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested.
|
||||
- Added API endpoint `PUT /1/config` to update current config.
|
||||
- Added API endpoint `GET /1/config` to get current active config.
|
||||
- Added API endpoint `GET /1/threads` to get current active threads configuration.
|
||||
- API endpoint `GET /` now deprecated, use `GET /1/summary` instead.
|
||||
- Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API.
|
||||
- Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified.
|
||||
|
||||
# v2.5.3
|
||||
- Fixed critical bug, in some cases miner was can't recovery connection and switch to failover pool, version 2.5.2 affected. If you use v2.6.0-beta3 this issue doesn't concern you.
|
||||
- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 support disabled for internal HTTP API.
|
||||
|
|
120
CMakeLists.txt
120
CMakeLists.txt
|
@ -3,6 +3,8 @@ project(xmrig)
|
|||
|
||||
option(WITH_LIBCPUID "Use Libcpuid" ON)
|
||||
option(WITH_AEON "CryptoNight-Lite support" ON)
|
||||
option(WITH_SUMO "CryptoNight-Heavy support" ON)
|
||||
option(WITH_IPBC "CryptoNight-IPBC support" ON)
|
||||
option(WITH_HTTPD "HTTP REST API" ON)
|
||||
option(BUILD_STATIC "Build static binary" OFF)
|
||||
|
||||
|
@ -11,53 +13,66 @@ include (cmake/cpu.cmake)
|
|||
|
||||
|
||||
set(HEADERS
|
||||
src/api/Api.h
|
||||
src/api/ApiState.h
|
||||
src/api/NetworkState.h
|
||||
src/App.h
|
||||
src/Console.h
|
||||
src/common/config/CommonConfig.h
|
||||
src/common/config/ConfigLoader.h
|
||||
src/common/config/ConfigWatcher.h
|
||||
src/common/Console.h
|
||||
src/common/crypto/Algorithm.h
|
||||
src/common/crypto/keccak.h
|
||||
src/common/log/ConsoleLog.h
|
||||
src/common/log/FileLog.h
|
||||
src/common/log/Log.h
|
||||
src/common/net/Client.h
|
||||
src/common/net/Id.h
|
||||
src/common/net/Job.h
|
||||
src/common/net/Pool.h
|
||||
src/common/net/Storage.h
|
||||
src/common/net/strategies/FailoverStrategy.h
|
||||
src/common/net/strategies/SinglePoolStrategy.h
|
||||
src/common/net/SubmitResult.h
|
||||
src/common/Platform.h
|
||||
src/common/utils/c_str.h
|
||||
src/common/utils/mm_malloc.h
|
||||
src/common/xmrig.h
|
||||
src/core/Config.cpp
|
||||
src/core/ConfigLoader_platform.h
|
||||
src/core/Controller.h
|
||||
src/Cpu.h
|
||||
src/interfaces/IClientListener.h
|
||||
src/interfaces/IConfig.h
|
||||
src/interfaces/IConfigCreator.h
|
||||
src/interfaces/IConsoleListener.h
|
||||
src/interfaces/IControllerListener.h
|
||||
src/interfaces/IJobResultListener.h
|
||||
src/interfaces/ILogBackend.h
|
||||
src/interfaces/IStrategy.h
|
||||
src/interfaces/IStrategyListener.h
|
||||
src/interfaces/IThread.h
|
||||
src/interfaces/IWatcherListener.h
|
||||
src/interfaces/IWorker.h
|
||||
src/log/ConsoleLog.h
|
||||
src/log/FileLog.h
|
||||
src/log/Log.h
|
||||
src/Mem.h
|
||||
src/net/Client.h
|
||||
src/net/Id.h
|
||||
src/net/Job.h
|
||||
src/net/JobResult.h
|
||||
src/net/Network.h
|
||||
src/net/strategies/DonateStrategy.h
|
||||
src/net/strategies/FailoverStrategy.h
|
||||
src/net/strategies/SinglePoolStrategy.h
|
||||
src/net/SubmitResult.h
|
||||
src/net/Url.h
|
||||
src/Options.h
|
||||
src/Platform.h
|
||||
src/Summary.h
|
||||
src/version.h
|
||||
src/workers/DoubleWorker.h
|
||||
src/workers/CpuThread.h
|
||||
src/workers/Handle.h
|
||||
src/workers/Hashrate.h
|
||||
src/workers/SingleWorker.h
|
||||
src/workers/MultiWorker.h
|
||||
src/workers/Worker.h
|
||||
src/workers/Workers.h
|
||||
src/xmrig.h
|
||||
)
|
||||
|
||||
set(HEADERS_CRYPTO
|
||||
src/crypto/c_blake256.h
|
||||
src/crypto/c_groestl.h
|
||||
src/crypto/c_jh.h
|
||||
src/crypto/c_keccak.h
|
||||
src/crypto/c_skein.h
|
||||
src/crypto/CryptoNight.h
|
||||
src/crypto/CryptoNight_constants.h
|
||||
src/crypto/CryptoNight_monero.h
|
||||
src/crypto/CryptoNight_test.h
|
||||
src/crypto/groestl_tables.h
|
||||
|
@ -73,51 +88,53 @@ else()
|
|||
endif()
|
||||
|
||||
set(SOURCES
|
||||
src/api/Api.cpp
|
||||
src/api/ApiState.cpp
|
||||
src/api/NetworkState.cpp
|
||||
src/App.cpp
|
||||
src/Console.cpp
|
||||
src/log/ConsoleLog.cpp
|
||||
src/log/FileLog.cpp
|
||||
src/log/Log.cpp
|
||||
src/common/config/CommonConfig.cpp
|
||||
src/common/config/ConfigLoader.cpp
|
||||
src/common/config/ConfigWatcher.cpp
|
||||
src/common/Console.cpp
|
||||
src/common/crypto/Algorithm.cpp
|
||||
src/common/crypto/keccak.cpp
|
||||
src/common/log/ConsoleLog.cpp
|
||||
src/common/log/FileLog.cpp
|
||||
src/common/log/Log.cpp
|
||||
src/common/net/Client.cpp
|
||||
src/common/net/Job.cpp
|
||||
src/common/net/Pool.cpp
|
||||
src/common/net/strategies/FailoverStrategy.cpp
|
||||
src/common/net/strategies/SinglePoolStrategy.cpp
|
||||
src/common/net/SubmitResult.cpp
|
||||
src/common/Platform.cpp
|
||||
src/core/Config.cpp
|
||||
src/core/Controller.cpp
|
||||
src/Mem.cpp
|
||||
src/net/Client.cpp
|
||||
src/net/Job.cpp
|
||||
src/net/Network.cpp
|
||||
src/net/strategies/DonateStrategy.cpp
|
||||
src/net/strategies/FailoverStrategy.cpp
|
||||
src/net/strategies/SinglePoolStrategy.cpp
|
||||
src/net/SubmitResult.cpp
|
||||
src/net/Url.cpp
|
||||
src/Options.cpp
|
||||
src/Platform.cpp
|
||||
src/Summary.cpp
|
||||
src/workers/DoubleWorker.cpp
|
||||
src/workers/CpuThread.cpp
|
||||
src/workers/Handle.cpp
|
||||
src/workers/Hashrate.cpp
|
||||
src/workers/SingleWorker.cpp
|
||||
src/workers/MultiWorker.cpp
|
||||
src/workers/Worker.cpp
|
||||
src/workers/Workers.cpp
|
||||
src/xmrig.cpp
|
||||
)
|
||||
|
||||
set(SOURCES_CRYPTO
|
||||
src/crypto/c_keccak.c
|
||||
src/crypto/c_groestl.c
|
||||
src/crypto/c_blake256.c
|
||||
src/crypto/c_jh.c
|
||||
src/crypto/c_skein.c
|
||||
src/crypto/CryptoNight.cpp
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
set(SOURCES_OS
|
||||
res/app.rc
|
||||
src/App_win.cpp
|
||||
src/common/Platform_win.cpp
|
||||
src/Cpu_win.cpp
|
||||
src/Mem_win.cpp
|
||||
src/Platform_win.cpp
|
||||
)
|
||||
|
||||
add_definitions(/DWIN32)
|
||||
|
@ -125,16 +142,16 @@ if (WIN32)
|
|||
elseif (APPLE)
|
||||
set(SOURCES_OS
|
||||
src/App_unix.cpp
|
||||
src/common/Platform_mac.cpp
|
||||
src/Cpu_mac.cpp
|
||||
src/Mem_unix.cpp
|
||||
src/Platform_mac.cpp
|
||||
)
|
||||
else()
|
||||
set(SOURCES_OS
|
||||
src/App_unix.cpp
|
||||
src/common/Platform_unix.cpp
|
||||
src/Cpu_unix.cpp
|
||||
src/Mem_unix.cpp
|
||||
src/Platform_unix.cpp
|
||||
)
|
||||
|
||||
set(EXTRA_LIBS pthread rt)
|
||||
|
@ -180,19 +197,38 @@ endif()
|
|||
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
|
||||
if (HAVE_SYSLOG_H)
|
||||
add_definitions(/DHAVE_SYSLOG_H)
|
||||
set(SOURCES_SYSLOG src/log/SysLog.h src/log/SysLog.cpp)
|
||||
set(SOURCES_SYSLOG src/common/log/SysLog.h src/common/log/SysLog.cpp)
|
||||
endif()
|
||||
|
||||
if (NOT WITH_AEON)
|
||||
add_definitions(/DXMRIG_NO_AEON)
|
||||
endif()
|
||||
|
||||
if (NOT WITH_SUMO)
|
||||
add_definitions(/DXMRIG_NO_SUMO)
|
||||
endif()
|
||||
|
||||
if (NOT WITH_IPBC)
|
||||
add_definitions(/DXMRIG_NO_IPBC)
|
||||
endif()
|
||||
|
||||
if (WITH_HTTPD)
|
||||
find_package(MHD)
|
||||
|
||||
if (MHD_FOUND)
|
||||
include_directories(${MHD_INCLUDE_DIRS})
|
||||
set(HTTPD_SOURCES src/api/Httpd.h src/api/Httpd.cpp)
|
||||
set(HTTPD_SOURCES
|
||||
src/api/Api.h
|
||||
src/api/ApiRouter.h
|
||||
src/common/api/HttpBody.h
|
||||
src/common/api/Httpd.h
|
||||
src/common/api/HttpReply.h
|
||||
src/common/api/HttpRequest.h
|
||||
src/api/Api.cpp
|
||||
src/api/ApiRouter.cpp
|
||||
src/common/api/Httpd.cpp
|
||||
src/common/api/HttpRequest.cpp
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
|
||||
endif()
|
||||
|
|
10
README.md
10
README.md
|
@ -1,6 +1,6 @@
|
|||
# XMRig
|
||||
|
||||
:warning: **If you mine Monero, Aeon, Sumokoin, Turtlecoin, Stellite, GRAFT, Haven Protocol, IPBC, [PLEASE READ](https://github.com/xmrig/xmrig/issues/482)!** :warning:
|
||||
:warning: **You must update miners to version 2.5 before April 6 due [Monero PoW change](https://getmonero.org/2018/02/11/PoW-change-and-key-reuse.html).**
|
||||
|
||||
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases)
|
||||
[![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases)
|
||||
|
@ -124,10 +124,10 @@ Please note performance is highly dependent on system load. The numbers above ar
|
|||
## Release checksums
|
||||
### SHA-256
|
||||
```
|
||||
5ae25d05b7735dd6e2482e8dba0cf0f5d10f9738855c4ad4eaf449b8ccd2e5be xmrig-2.5.3-xenial-amd64.tar.gz/xmrig-2.5.3/xmrig
|
||||
f11f3b381425ca4181c425d5b693407431f964759bb903f66b7cd2345fcdd786 xmrig-2.5.3-gcc-win32.zip/xmrig.exe
|
||||
67df8b89714e2921931092861361dbae4716c4ab872c767c92adae24dca01514 xmrig-2.5.3-gcc-win64.zip/xmrig.exe
|
||||
52bf6e0ef72c84282f4df411125384444c521ed9143e5d8c7e7e445d7d55e143 xmrig-2.5.3-msvc-win64.zip/xmrig.exe
|
||||
6b32fefb356b27caa2180be17755d09639f0654096a1a0c61e8f10f4f2ac1626 xmrig-2.6.0-beta3-xenial-amd64.tar.gz/xmrig-2.6.0-beta3/xmrig
|
||||
c8b40f4d7aac9d0cc7c3d02cadeac91b0bdb034aae2fb6b415d503272eabb987 xmrig-2.6.0-beta3-gcc-win32.zip/xmrig.exe
|
||||
32cf7958f97a23296186e38a4addb9cf234adcbd9c7914b15e4209a87fe272e7 xmrig-2.6.0-beta3-gcc-win64.zip/xmrig.exe
|
||||
4f176ee4c4be52701edc0d573cf9647c4aacbb4ff14975b80b98e6fe63068542 xmrig-2.6.0-beta3-msvc-win64.zip/xmrig.exe
|
||||
```
|
||||
|
||||
## Contacts
|
||||
|
|
|
@ -13,10 +13,10 @@ endif()
|
|||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -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_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s")
|
||||
|
||||
if (XMRIG_ARMv8)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto")
|
||||
|
|
44
doc/ALGORITHMS.md
Normal file
44
doc/ALGORITHMS.md
Normal file
|
@ -0,0 +1,44 @@
|
|||
# Algorithms
|
||||
|
||||
XMRig uses a different way to specify algorithms, compared to other miners.
|
||||
|
||||
Algorithm selection splitted to 2 parts:
|
||||
|
||||
* Global base algorithm per miner or proxy instance, `algo` option. Possible values: `cryptonight`, `cryptonight-lite`, `cryptonight-heavy`.
|
||||
* Algorithm variant specified separately for each pool, `variant` option.
|
||||
|
||||
Possible variants for `cryptonight`:
|
||||
|
||||
* `0` Original cryptonight.
|
||||
* `1` cryptonight variant 1, also known as cryptonight v7 or monero7.
|
||||
* `"xtl"` Stellite coin variant.
|
||||
|
||||
Possible variants for `cryptonight-lite`:
|
||||
|
||||
* `0` Original cryptonight-lite.
|
||||
* `1` cryptonight-lite variant 1, also known as cryptonight-lite v7 or aeon7.
|
||||
* `"ipbc"` IPBC coin variant.
|
||||
|
||||
For `cryptonight-heavy` currently no variants.
|
||||
|
||||
|
||||
### Cheatsheet
|
||||
|
||||
You mine **Sumokoin** or **Haven Protocol**?
|
||||
Your algorithm is `cryptonight-heavy` no variant option need.
|
||||
|
||||
You mine **Aeon**, **TurtleCoin** or **IPBC**?
|
||||
Your base algorithm is `cryptonight-lite`:
|
||||
|
||||
Variants:
|
||||
* Aeon: `-1` autodetect. `0` right now, `1` after fork.
|
||||
* TurtleCoin: `1`.
|
||||
* IPBC: `"ipbc"`.
|
||||
|
||||
In all other cases base algorithm is `cryptonight`.
|
||||
|
||||
### Mining algorithm negotiation
|
||||
If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) miner will choice proper variant automaticaly and if you choice wrong base algorithm you will see error message.
|
||||
|
||||
Pools with mining algorithm negotiation support.
|
||||
* [www.hashvault.pro](https://www.hashvault.pro/)
|
53
doc/API.md
Normal file
53
doc/API.md
Normal file
|
@ -0,0 +1,53 @@
|
|||
# HTTP API
|
||||
|
||||
If you want use API you need choice a port where is internal HTTP server will listen for incoming connections. API will not available if miner built without `libmicrohttpd`.
|
||||
|
||||
Example configuration:
|
||||
|
||||
```json
|
||||
"api": {
|
||||
"port": 44444,
|
||||
"access-token": "TOKEN",
|
||||
"worker-id": null,
|
||||
"ipv6": false,
|
||||
"restricted": false
|
||||
},
|
||||
```
|
||||
|
||||
* **port** Port for incoming connections `http://<miner ip>:<port>`.
|
||||
* **access-token** [Bearer](https://gist.github.com/xmrig/c75fdd1f8e0f3bac05500be2ab718f8e#file-api-html-L54) access token to secure access to API.
|
||||
* **worker-id** Optional worker name, if not set will be detected automatically.
|
||||
* **ipv6** Enable (`true`) or disable (`false`) IPv6 for API.
|
||||
* **restricted** Use `false` to allow remote configuration.
|
||||
|
||||
If you prefer use command line options instead of config file, you can use options: `--api-port`, `--api-access-token`, `--api-worker-id`, `--api-ipv6` and `api-no-restricted`.
|
||||
|
||||
## Endpoints
|
||||
|
||||
### GET /1/summary
|
||||
|
||||
Get miner summary information. [Example](api/1/summary.json).
|
||||
|
||||
### GET /1/threads
|
||||
|
||||
Get detailed information about miner threads. [Example](api/1/threads.json).
|
||||
|
||||
|
||||
## Restricted endpoints
|
||||
|
||||
All API endpoints below allow access to sensitive information and remote configure miner. You should set `access-token` and allow unrestricted access (`"restricted": false`).
|
||||
|
||||
### GET /1/config
|
||||
|
||||
Get current miner configuration. [Example](api/1/config.json).
|
||||
|
||||
|
||||
### PUT /1/config
|
||||
|
||||
Update current miner configuration. Common use case, get current configuration, make changes, and upload it to miner.
|
||||
|
||||
Curl example:
|
||||
|
||||
```
|
||||
curl -v --data-binary @config.json -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer SECRET" http://127.0.0.1:44444/1/config
|
||||
```
|
63
doc/api/1/config.json
Normal file
63
doc/api/1/config.json
Normal file
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"algo": "cryptonight",
|
||||
"api": {
|
||||
"port": 44444,
|
||||
"access-token": "TOKEN",
|
||||
"worker-id": null,
|
||||
"ipv6": false,
|
||||
"restricted": false
|
||||
},
|
||||
"av": 1,
|
||||
"background": false,
|
||||
"colors": true,
|
||||
"cpu-affinity": null,
|
||||
"cpu-priority": null,
|
||||
"donate-level": 5,
|
||||
"huge-pages": true,
|
||||
"hw-aes": null,
|
||||
"log-file": null,
|
||||
"max-cpu-usage": 75,
|
||||
"pools": [
|
||||
{
|
||||
"url": "pool.monero.hashvault.pro:3333",
|
||||
"user": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD",
|
||||
"pass": "x",
|
||||
"keepalive": false,
|
||||
"nicehash": false,
|
||||
"variant": -1
|
||||
},
|
||||
{
|
||||
"url": "pool.supportxmr.com:3333",
|
||||
"user": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD",
|
||||
"pass": "x",
|
||||
"keepalive": false,
|
||||
"nicehash": false,
|
||||
"variant": -1
|
||||
}
|
||||
],
|
||||
"print-time": 60,
|
||||
"retries": 5,
|
||||
"retry-pause": 5,
|
||||
"safe": false,
|
||||
"threads": [
|
||||
{
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 0
|
||||
},
|
||||
{
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 1
|
||||
},
|
||||
{
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 2
|
||||
},
|
||||
{
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 3
|
||||
}
|
||||
],
|
||||
"user-agent": null,
|
||||
"syslog": false,
|
||||
"watch": false
|
||||
}
|
73
doc/api/1/summary.json
Normal file
73
doc/api/1/summary.json
Normal file
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"id": "92f3104f9a2ee78c",
|
||||
"worker_id": "Ubuntu-1604-xenial-64-minimal",
|
||||
"version": "2.6.0-beta3",
|
||||
"kind": "cpu",
|
||||
"ua": "XMRig/2.6.0-beta3 (Linux x86_64) libuv/1.8.0 gcc/5.4.0",
|
||||
"cpu": {
|
||||
"brand": "Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz",
|
||||
"aes": true,
|
||||
"x64": true,
|
||||
"sockets": 1
|
||||
},
|
||||
"algo": "cryptonight",
|
||||
"hugepages": true,
|
||||
"donate_level": 5,
|
||||
"hashrate": {
|
||||
"total": [
|
||||
296.24,
|
||||
296.23,
|
||||
295.97
|
||||
],
|
||||
"highest": 296.5,
|
||||
"threads": [
|
||||
[
|
||||
73.39,
|
||||
73.39,
|
||||
73.28
|
||||
],
|
||||
[
|
||||
74.72,
|
||||
74.72,
|
||||
74.71
|
||||
],
|
||||
[
|
||||
74.72,
|
||||
74.72,
|
||||
74.71
|
||||
],
|
||||
[
|
||||
73.39,
|
||||
73.39,
|
||||
73.27
|
||||
]
|
||||
]
|
||||
},
|
||||
"results": {
|
||||
"diff_current": 9990,
|
||||
"shares_good": 30,
|
||||
"shares_total": 30,
|
||||
"avg_time": 31,
|
||||
"hashes_total": 311833,
|
||||
"best": [
|
||||
278199,
|
||||
181923,
|
||||
103717,
|
||||
96632,
|
||||
56154,
|
||||
51580,
|
||||
45667,
|
||||
33159,
|
||||
29581,
|
||||
29514
|
||||
],
|
||||
"error_log": []
|
||||
},
|
||||
"connection": {
|
||||
"pool": "pool.monero.hashvault.pro:3333",
|
||||
"uptime": 953,
|
||||
"ping": 35,
|
||||
"failures": 0,
|
||||
"error_log": []
|
||||
}
|
||||
}
|
65
doc/api/1/threads.json
Normal file
65
doc/api/1/threads.json
Normal file
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"hugepages": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"memory": 8388608,
|
||||
"threads": [
|
||||
{
|
||||
"type": "cpu",
|
||||
"algo": "cryptonight",
|
||||
"av": 1,
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 0,
|
||||
"priority": -1,
|
||||
"soft_aes": false,
|
||||
"hashrate": [
|
||||
73.39,
|
||||
73.4,
|
||||
73.28
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"algo": "cryptonight",
|
||||
"av": 1,
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 1,
|
||||
"priority": -1,
|
||||
"soft_aes": false,
|
||||
"hashrate": [
|
||||
74.72,
|
||||
74.72,
|
||||
74.7
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"algo": "cryptonight",
|
||||
"av": 1,
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 2,
|
||||
"priority": -1,
|
||||
"soft_aes": false,
|
||||
"hashrate": [
|
||||
74.71,
|
||||
74.72,
|
||||
74.7
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"algo": "cryptonight",
|
||||
"av": 1,
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 3,
|
||||
"priority": -1,
|
||||
"soft_aes": false,
|
||||
"hashrate": [
|
||||
73.39,
|
||||
73.4,
|
||||
73.28
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -4,8 +4,8 @@
|
|||
IDI_ICON1 ICON DISCARDABLE "app.ico"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_BUILD,APP_VER_REV
|
||||
PRODUCTVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_BUILD,APP_VER_REV
|
||||
FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0
|
||||
PRODUCTVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
|
|
94
src/App.cpp
94
src/App.cpp
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -28,27 +28,22 @@
|
|||
|
||||
#include "api/Api.h"
|
||||
#include "App.h"
|
||||
#include "Console.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "Cpu.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "log/ConsoleLog.h"
|
||||
#include "log/FileLog.h"
|
||||
#include "log/Log.h"
|
||||
#include "Mem.h"
|
||||
#include "net/Network.h"
|
||||
#include "Options.h"
|
||||
#include "Platform.h"
|
||||
#include "Summary.h"
|
||||
#include "version.h"
|
||||
#include "workers/Workers.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
# include "log/SysLog.h"
|
||||
#endif
|
||||
|
||||
#ifndef XMRIG_NO_HTTPD
|
||||
# include "api/Httpd.h"
|
||||
# include "common/api/Httpd.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -58,40 +53,19 @@ App *App::m_self = nullptr;
|
|||
|
||||
App::App(int argc, char **argv) :
|
||||
m_console(nullptr),
|
||||
m_httpd(nullptr),
|
||||
m_network(nullptr),
|
||||
m_options(nullptr)
|
||||
m_httpd(nullptr)
|
||||
{
|
||||
m_self = this;
|
||||
|
||||
Cpu::init();
|
||||
m_options = Options::parse(argc, argv);
|
||||
if (!m_options) {
|
||||
m_controller = new xmrig::Controller();
|
||||
if (m_controller->init(argc, argv) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::init();
|
||||
|
||||
if (!m_options->background()) {
|
||||
Log::add(new ConsoleLog(m_options->colors()));
|
||||
if (!m_controller->config()->isBackground()) {
|
||||
m_console = new Console(this);
|
||||
}
|
||||
|
||||
if (m_options->logFile()) {
|
||||
Log::add(new FileLog(m_options->logFile()));
|
||||
}
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
if (m_options->syslog()) {
|
||||
Log::add(new SysLog());
|
||||
}
|
||||
# endif
|
||||
|
||||
Platform::init(m_options->userAgent());
|
||||
Platform::setProcessPriority(m_options->priority());
|
||||
|
||||
m_network = new Network(m_options);
|
||||
|
||||
uv_signal_init(uv_default_loop(), &m_sigHUP);
|
||||
uv_signal_init(uv_default_loop(), &m_sigINT);
|
||||
uv_signal_init(uv_default_loop(), &m_sigTERM);
|
||||
|
@ -102,17 +76,18 @@ App::~App()
|
|||
{
|
||||
uv_tty_reset_mode();
|
||||
|
||||
delete m_console;
|
||||
delete m_controller;
|
||||
|
||||
# ifndef XMRIG_NO_HTTPD
|
||||
delete m_httpd;
|
||||
# endif
|
||||
|
||||
delete m_console;
|
||||
}
|
||||
|
||||
|
||||
int App::exec()
|
||||
{
|
||||
if (!m_options) {
|
||||
if (!m_controller->isReady()) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -122,15 +97,11 @@ int App::exec()
|
|||
|
||||
background();
|
||||
|
||||
if (!CryptoNight::init(m_options->algo(), m_options->algoVariant())) {
|
||||
LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName());
|
||||
return 1;
|
||||
}
|
||||
Mem::init(m_controller->config()->isHugePages());
|
||||
|
||||
Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash(), m_options->hugePages());
|
||||
Summary::print();
|
||||
Summary::print(m_controller);
|
||||
|
||||
if (m_options->dryRun()) {
|
||||
if (m_controller->config()->isDryRun()) {
|
||||
LOG_NOTICE("OK");
|
||||
release();
|
||||
|
||||
|
@ -138,17 +109,23 @@ int App::exec()
|
|||
}
|
||||
|
||||
# ifndef XMRIG_NO_API
|
||||
Api::start();
|
||||
Api::start(m_controller);
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_HTTPD
|
||||
m_httpd = new Httpd(m_options->apiPort(), m_options->apiToken());
|
||||
m_httpd = new Httpd(
|
||||
m_controller->config()->apiPort(),
|
||||
m_controller->config()->apiToken(),
|
||||
m_controller->config()->isApiIPv6(),
|
||||
m_controller->config()->isApiRestricted()
|
||||
);
|
||||
|
||||
m_httpd->start();
|
||||
# endif
|
||||
|
||||
Workers::start(m_options->affinity(), m_options->priority());
|
||||
Workers::start(m_controller);
|
||||
|
||||
m_network->connect();
|
||||
m_controller->network()->connect();
|
||||
|
||||
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
uv_loop_close(uv_default_loop());
|
||||
|
@ -169,7 +146,7 @@ void App::onConsoleCommand(char command)
|
|||
case 'p':
|
||||
case 'P':
|
||||
if (Workers::isEnabled()) {
|
||||
LOG_INFO(m_options->colors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" : "paused, press 'r' to resume");
|
||||
LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" : "paused, press 'r' to resume");
|
||||
Workers::setEnabled(false);
|
||||
}
|
||||
break;
|
||||
|
@ -177,7 +154,7 @@ void App::onConsoleCommand(char command)
|
|||
case 'r':
|
||||
case 'R':
|
||||
if (!Workers::isEnabled()) {
|
||||
LOG_INFO(m_options->colors() ? "\x1B[01;32mresumed" : "resumed");
|
||||
LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;32mresumed" : "resumed");
|
||||
Workers::setEnabled(true);
|
||||
}
|
||||
break;
|
||||
|
@ -195,7 +172,7 @@ void App::onConsoleCommand(char command)
|
|||
|
||||
void App::close()
|
||||
{
|
||||
m_network->stop();
|
||||
m_controller->network()->stop();
|
||||
Workers::stop();
|
||||
|
||||
uv_stop(uv_default_loop());
|
||||
|
@ -204,13 +181,6 @@ void App::close()
|
|||
|
||||
void App::release()
|
||||
{
|
||||
if (m_network) {
|
||||
delete m_network;
|
||||
}
|
||||
|
||||
Options::release();
|
||||
Mem::release();
|
||||
Platform::release();
|
||||
}
|
||||
|
||||
|
||||
|
|
12
src/App.h
12
src/App.h
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -37,6 +37,11 @@ class Network;
|
|||
class Options;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class App : public IConsoleListener
|
||||
{
|
||||
public:
|
||||
|
@ -59,11 +64,10 @@ private:
|
|||
|
||||
Console *m_console;
|
||||
Httpd *m_httpd;
|
||||
Network *m_network;
|
||||
Options *m_options;
|
||||
uv_signal_t m_sigHUP;
|
||||
uv_signal_t m_sigINT;
|
||||
uv_signal_t m_sigTERM;
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -29,20 +29,16 @@
|
|||
|
||||
|
||||
#include "App.h"
|
||||
#include "Cpu.h"
|
||||
#include "log/Log.h"
|
||||
#include "Options.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
|
||||
|
||||
void App::background()
|
||||
{
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
if (m_options->affinity() != -1L) {
|
||||
Cpu::setAffinity(-1, m_options->affinity());
|
||||
}
|
||||
|
||||
if (!m_options->background()) {
|
||||
if (!m_controller->config()->isBackground()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -27,17 +27,13 @@
|
|||
|
||||
|
||||
#include "App.h"
|
||||
#include "Options.h"
|
||||
#include "Cpu.h"
|
||||
#include "core/Controller.h"
|
||||
#include "core/Config.h"
|
||||
|
||||
|
||||
void App::background()
|
||||
{
|
||||
if (m_options->affinity() != -1L) {
|
||||
Cpu::setAffinity(-1, m_options->affinity());
|
||||
}
|
||||
|
||||
if (!m_options->background()) {
|
||||
if (!m_controller->config()->isBackground()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
32
src/Cpu.cpp
32
src/Cpu.cpp
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -26,26 +26,27 @@
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "Cpu.h"
|
||||
|
||||
|
||||
bool Cpu::m_l2_exclusive = false;
|
||||
char Cpu::m_brand[64] = { 0 };
|
||||
int Cpu::m_flags = 0;
|
||||
int Cpu::m_l2_cache = 0;
|
||||
int Cpu::m_l3_cache = 0;
|
||||
int Cpu::m_sockets = 1;
|
||||
int Cpu::m_totalCores = 0;
|
||||
int Cpu::m_totalThreads = 0;
|
||||
bool Cpu::m_l2_exclusive = false;
|
||||
char Cpu::m_brand[64] = { 0 };
|
||||
int Cpu::m_flags = 0;
|
||||
int Cpu::m_l2_cache = 0;
|
||||
int Cpu::m_l3_cache = 0;
|
||||
int Cpu::m_sockets = 1;
|
||||
int Cpu::m_totalCores = 0;
|
||||
size_t Cpu::m_totalThreads = 0;
|
||||
|
||||
|
||||
int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage)
|
||||
size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage)
|
||||
{
|
||||
if (m_totalThreads == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cache = 0;
|
||||
size_t cache = 0;
|
||||
if (m_l3_cache) {
|
||||
cache = m_l2_exclusive ? (m_l2_cache + m_l3_cache) : m_l3_cache;
|
||||
}
|
||||
|
@ -53,11 +54,14 @@ int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage)
|
|||
cache = m_l2_cache;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
const int size = (algo ? 1024 : 2048) * (doubleHash ? 2 : 1);
|
||||
size_t count = 0;
|
||||
|
||||
if (cache) {
|
||||
count = cache / size;
|
||||
|
||||
if (cache % size >= size / 2) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
count = m_totalThreads / 2;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -37,9 +37,8 @@ public:
|
|||
BMI2 = 4
|
||||
};
|
||||
|
||||
static int optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage);
|
||||
static size_t optimalThreadsCount(size_t size, int maxCpuUsage);
|
||||
static void init();
|
||||
static void setAffinity(int id, uint64_t mask);
|
||||
|
||||
static inline bool hasAES() { return (m_flags & AES) != 0; }
|
||||
static inline bool isX64() { return (m_flags & X86_64) != 0; }
|
||||
|
@ -60,7 +59,7 @@ private:
|
|||
static int m_l3_cache;
|
||||
static int m_sockets;
|
||||
static int m_totalCores;
|
||||
static int m_totalThreads;
|
||||
static size_t m_totalThreads;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -28,16 +28,16 @@
|
|||
#include "Cpu.h"
|
||||
|
||||
|
||||
char Cpu::m_brand[64] = { 0 };
|
||||
int Cpu::m_flags = 0;
|
||||
int Cpu::m_l2_cache = 0;
|
||||
int Cpu::m_l3_cache = 0;
|
||||
int Cpu::m_sockets = 1;
|
||||
int Cpu::m_totalCores = 0;
|
||||
int Cpu::m_totalThreads = 0;
|
||||
char Cpu::m_brand[64] = { 0 };
|
||||
int Cpu::m_flags = 0;
|
||||
int Cpu::m_l2_cache = 0;
|
||||
int Cpu::m_l3_cache = 0;
|
||||
int Cpu::m_sockets = 1;
|
||||
int Cpu::m_totalCores = 0;
|
||||
size_t Cpu::m_totalThreads = 0;
|
||||
|
||||
|
||||
int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage)
|
||||
size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage)
|
||||
{
|
||||
return m_totalThreads;
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -38,8 +38,3 @@ void Cpu::init()
|
|||
|
||||
initCommon();
|
||||
}
|
||||
|
||||
|
||||
void Cpu::setAffinity(int id, uint64_t mask)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -52,28 +52,3 @@ void Cpu::init()
|
|||
|
||||
initCommon();
|
||||
}
|
||||
|
||||
|
||||
void Cpu::setAffinity(int id, uint64_t mask)
|
||||
{
|
||||
cpu_set_t set;
|
||||
CPU_ZERO(&set);
|
||||
|
||||
for (int i = 0; i < m_totalThreads; i++) {
|
||||
if (mask & (1UL << i)) {
|
||||
CPU_SET(i, &set);
|
||||
}
|
||||
}
|
||||
|
||||
if (id == -1) {
|
||||
# ifndef __FreeBSD__
|
||||
sched_setaffinity(0, sizeof(&set), &set);
|
||||
# endif
|
||||
} else {
|
||||
# ifndef __ANDROID__
|
||||
pthread_setaffinity_np(pthread_self(), sizeof(&set), &set);
|
||||
# else
|
||||
sched_setaffinity(gettid(), sizeof(&set), &set);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,14 +39,3 @@ void Cpu::init()
|
|||
|
||||
initCommon();
|
||||
}
|
||||
|
||||
|
||||
void Cpu::setAffinity(int id, uint64_t mask)
|
||||
{
|
||||
if (id == -1) {
|
||||
SetProcessAffinityMask(GetCurrentProcess(), mask);
|
||||
}
|
||||
else {
|
||||
SetThreadAffinityMask(GetCurrentThread(), mask);
|
||||
}
|
||||
}
|
||||
|
|
79
src/Mem.cpp
79
src/Mem.cpp
|
@ -23,68 +23,49 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
|
||||
#include "common/utils/mm_malloc.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "Mem.h"
|
||||
#include "Options.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
bool Mem::m_doubleHash = false;
|
||||
int Mem::m_algo = 0;
|
||||
int Mem::m_flags = 0;
|
||||
int Mem::m_threads = 0;
|
||||
size_t Mem::m_offset = 0;
|
||||
size_t Mem::m_size = 0;
|
||||
alignas(16) uint8_t *Mem::m_memory = nullptr;
|
||||
bool Mem::m_enabled = true;
|
||||
int Mem::m_flags = 0;
|
||||
|
||||
|
||||
cryptonight_ctx *Mem::create(int threadId)
|
||||
|
||||
MemInfo Mem::create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count)
|
||||
{
|
||||
using namespace xmrig;
|
||||
|
||||
MemInfo info;
|
||||
info.size = cn_select_memory(algorithm) * count;
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
if (m_algo == xmrig::ALGO_CRYPTONIGHT_LITE) {
|
||||
return createLite(threadId);
|
||||
}
|
||||
info.size += info.size % cn_select_memory<CRYPTONIGHT>();
|
||||
# endif
|
||||
|
||||
cryptonight_ctx *ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[MONERO_MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
|
||||
info.pages = info.size / cn_select_memory<CRYPTONIGHT>();
|
||||
|
||||
const int ratio = m_doubleHash ? 2 : 1;
|
||||
ctx->memory = &m_memory[MONERO_MEMORY * (threadId * ratio + 1)];
|
||||
allocate(info, m_enabled);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
cryptonight_ctx *c = static_cast<cryptonight_ctx *>(_mm_malloc(sizeof(cryptonight_ctx), 4096));
|
||||
c->memory = info.memory + (i * cn_select_memory(algorithm));
|
||||
|
||||
|
||||
|
||||
void *Mem::calloc(size_t num, size_t size)
|
||||
{
|
||||
void *mem = &m_memory[m_offset];
|
||||
m_offset += (num * size);
|
||||
|
||||
memset(mem, 0, num * size);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_AEON
|
||||
cryptonight_ctx *Mem::createLite(int threadId) {
|
||||
cryptonight_ctx *ctx;
|
||||
|
||||
if (!m_doubleHash) {
|
||||
const size_t offset = MONERO_MEMORY * (threadId + 1);
|
||||
|
||||
ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[offset + AEON_MEMORY]);
|
||||
ctx->memory = &m_memory[offset];
|
||||
return ctx;
|
||||
ctx[i] = c;
|
||||
}
|
||||
|
||||
ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[MONERO_MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
|
||||
ctx->memory = &m_memory[MONERO_MEMORY * (threadId + 1)];
|
||||
|
||||
return ctx;
|
||||
return info;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Mem::release(cryptonight_ctx **ctx, size_t count, MemInfo &info)
|
||||
{
|
||||
release(info);
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
_mm_free(ctx[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
38
src/Mem.h
38
src/Mem.h
|
@ -30,9 +30,22 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "common/xmrig.h"
|
||||
|
||||
|
||||
struct cryptonight_ctx;
|
||||
|
||||
|
||||
struct MemInfo
|
||||
{
|
||||
alignas(16) uint8_t *memory;
|
||||
|
||||
size_t hugePages;
|
||||
size_t pages;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
|
||||
class Mem
|
||||
{
|
||||
public:
|
||||
|
@ -42,29 +55,18 @@ public:
|
|||
Lock = 4
|
||||
};
|
||||
|
||||
static bool allocate(int algo, int threads, bool doubleHash, bool enabled);
|
||||
static cryptonight_ctx *create(int threadId);
|
||||
static void *calloc(size_t num, size_t size);
|
||||
static void release();
|
||||
static MemInfo create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count);
|
||||
static void init(bool enabled);
|
||||
static void release(cryptonight_ctx **ctx, size_t count, MemInfo &info);
|
||||
|
||||
static inline bool isDoubleHash() { return m_doubleHash; }
|
||||
static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; }
|
||||
static inline bool isHugepagesEnabled() { return (m_flags & HugepagesEnabled) != 0; }
|
||||
static inline int flags() { return m_flags; }
|
||||
static inline int threads() { return m_threads; }
|
||||
|
||||
private:
|
||||
static bool m_doubleHash;
|
||||
static int m_algo;
|
||||
static int m_flags;
|
||||
static int m_threads;
|
||||
static size_t m_offset;
|
||||
static size_t m_size;
|
||||
alignas(16) static uint8_t *m_memory;
|
||||
static void allocate(MemInfo &info, bool enabled);
|
||||
static void release(MemInfo &info);
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
static cryptonight_ctx *createLite(int threadId);
|
||||
# endif
|
||||
static int m_flags;
|
||||
static bool m_enabled;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,72 +27,63 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
|
||||
#if defined(XMRIG_ARM) && !defined(__clang__)
|
||||
# include "aligned_malloc.h"
|
||||
#else
|
||||
# include <mm_malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "common/log/Log.h"
|
||||
#include "common/utils/mm_malloc.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "log/Log.h"
|
||||
#include "Mem.h"
|
||||
#include "Options.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
|
||||
void Mem::init(bool enabled)
|
||||
{
|
||||
m_algo = algo;
|
||||
m_threads = threads;
|
||||
m_doubleHash = doubleHash;
|
||||
m_enabled = enabled;
|
||||
}
|
||||
|
||||
const int ratio = (doubleHash && algo != xmrig::ALGO_CRYPTONIGHT_LITE) ? 2 : 1;
|
||||
m_size = MONERO_MEMORY * (threads * ratio + 1);
|
||||
|
||||
void Mem::allocate(MemInfo &info, bool enabled)
|
||||
{
|
||||
info.hugePages = 0;
|
||||
|
||||
if (!enabled) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
|
||||
return true;
|
||||
}
|
||||
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
|
||||
|
||||
m_flags |= HugepagesAvailable;
|
||||
return;
|
||||
}
|
||||
|
||||
# if defined(__APPLE__)
|
||||
m_memory = static_cast<uint8_t*>(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
|
||||
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
|
||||
# elif defined(__FreeBSD__)
|
||||
m_memory = static_cast<uint8_t*>(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
|
||||
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
|
||||
# else
|
||||
m_memory = static_cast<uint8_t*>(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
|
||||
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
|
||||
# endif
|
||||
if (m_memory == MAP_FAILED) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
|
||||
return true;
|
||||
|
||||
if (info.memory == MAP_FAILED) {
|
||||
return allocate(info, false);;
|
||||
}
|
||||
|
||||
m_flags |= HugepagesEnabled;
|
||||
info.hugePages = info.pages;
|
||||
|
||||
if (madvise(m_memory, m_size, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
||||
if (madvise(info.memory, info.size, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
||||
LOG_ERR("madvise failed");
|
||||
}
|
||||
|
||||
if (mlock(m_memory, m_size) == 0) {
|
||||
if (mlock(info.memory, info.size) == 0) {
|
||||
m_flags |= Lock;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Mem::release()
|
||||
void Mem::release(MemInfo &info)
|
||||
{
|
||||
if (m_flags & HugepagesEnabled) {
|
||||
if (info.hugePages) {
|
||||
if (m_flags & Lock) {
|
||||
munlock(m_memory, m_size);
|
||||
munlock(info.memory, info.size);
|
||||
}
|
||||
|
||||
munmap(m_memory, m_size);
|
||||
munmap(info.memory, info.size);
|
||||
}
|
||||
else {
|
||||
_mm_free(m_memory);
|
||||
_mm_free(info.memory);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,17 +28,13 @@
|
|||
#include <ntsecapi.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
# include <mm_malloc.h>
|
||||
#else
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "log/Log.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "common/utils/mm_malloc.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "Mem.h"
|
||||
#include "Options.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
|
@ -146,42 +142,43 @@ static BOOL TrySetLockPagesPrivilege() {
|
|||
}
|
||||
|
||||
|
||||
bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
|
||||
void Mem::init(bool enabled)
|
||||
{
|
||||
m_algo = algo;
|
||||
m_threads = threads;
|
||||
m_doubleHash = doubleHash;
|
||||
m_enabled = enabled;
|
||||
|
||||
const int ratio = (doubleHash && algo != xmrig::ALGO_CRYPTONIGHT_LITE) ? 2 : 1;
|
||||
m_size = MONERO_MEMORY * (threads * ratio + 1);
|
||||
|
||||
if (!enabled) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TrySetLockPagesPrivilege()) {
|
||||
if (enabled && TrySetLockPagesPrivilege()) {
|
||||
m_flags |= HugepagesAvailable;
|
||||
}
|
||||
|
||||
m_memory = static_cast<uint8_t*>(VirtualAlloc(NULL, m_size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
|
||||
if (!m_memory) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
|
||||
}
|
||||
else {
|
||||
m_flags |= HugepagesEnabled;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Mem::release()
|
||||
void Mem::allocate(MemInfo &info, bool enabled)
|
||||
{
|
||||
if (m_flags & HugepagesEnabled) {
|
||||
VirtualFree(m_memory, 0, MEM_RELEASE);
|
||||
info.hugePages = 0;
|
||||
|
||||
if (!enabled) {
|
||||
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
info.memory = static_cast<uint8_t*>(VirtualAlloc(nullptr, info.size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
|
||||
if (info.memory) {
|
||||
info.hugePages = info.pages;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
allocate(info, false);
|
||||
}
|
||||
|
||||
|
||||
void Mem::release(MemInfo &info)
|
||||
{
|
||||
if (info.hugePages) {
|
||||
VirtualFree(info.memory, 0, MEM_RELEASE);
|
||||
}
|
||||
else {
|
||||
_mm_free(m_memory);
|
||||
_mm_free(info.memory);
|
||||
}
|
||||
}
|
||||
|
|
761
src/Options.cpp
761
src/Options.cpp
|
@ -1,761 +0,0 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include "getopt/getopt.h"
|
||||
#else
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_HTTPD
|
||||
# include <microhttpd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "Cpu.h"
|
||||
#include "donate.h"
|
||||
#include "net/Url.h"
|
||||
#include "Options.h"
|
||||
#include "Platform.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
#include "rapidjson/filereadstream.h"
|
||||
#include "version.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
|
||||
|
||||
Options *Options::m_self = nullptr;
|
||||
|
||||
|
||||
static char const usage[] = "\
|
||||
Usage: " APP_ID " [OPTIONS]\n\
|
||||
Options:\n\
|
||||
-a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\
|
||||
-o, --url=URL URL of 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\
|
||||
-t, --threads=N number of miner threads\n\
|
||||
-v, --av=N algorithm variation, 0 auto select\n\
|
||||
-k, --keepalive send keepalived for prevent timeout (need pool support)\n\
|
||||
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
|
||||
-R, --retry-pause=N time to pause between retries (default: 5)\n\
|
||||
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
|
||||
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\
|
||||
--no-huge-pages disable huge pages support\n\
|
||||
--no-color disable colored output\n\
|
||||
--variant algorithm PoW variant\n\
|
||||
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\
|
||||
--user-agent set custom user-agent string for pool\n\
|
||||
-B, --background run the miner in the background\n\
|
||||
-c, --config=FILE load a JSON-format configuration file\n\
|
||||
-l, --log-file=FILE log all output to a file\n"
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
"\
|
||||
-S, --syslog use system log for output messages\n"
|
||||
# endif
|
||||
"\
|
||||
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\
|
||||
--safe safe adjust threads and av settings for current CPU\n\
|
||||
--nicehash enable nicehash/xmrig-proxy support\n\
|
||||
--print-time=N print hashrate report every N seconds\n\
|
||||
--api-port=N port for the miner API\n\
|
||||
--api-access-token=T access token for API\n\
|
||||
--api-worker-id=ID custom worker-id for API\n\
|
||||
-h, --help display this help and exit\n\
|
||||
-V, --version output version information and exit\n\
|
||||
";
|
||||
|
||||
|
||||
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' },
|
||||
{ "api-access-token", 1, nullptr, 4001 },
|
||||
{ "api-port", 1, nullptr, 4000 },
|
||||
{ "api-worker-id", 1, nullptr, 4002 },
|
||||
{ "av", 1, nullptr, 'v' },
|
||||
{ "background", 0, nullptr, 'B' },
|
||||
{ "config", 1, nullptr, 'c' },
|
||||
{ "cpu-affinity", 1, nullptr, 1020 },
|
||||
{ "cpu-priority", 1, nullptr, 1021 },
|
||||
{ "donate-level", 1, nullptr, 1003 },
|
||||
{ "dry-run", 0, nullptr, 5000 },
|
||||
{ "help", 0, nullptr, 'h' },
|
||||
{ "keepalive", 0, nullptr ,'k' },
|
||||
{ "log-file", 1, nullptr, 'l' },
|
||||
{ "max-cpu-usage", 1, nullptr, 1004 },
|
||||
{ "nicehash", 0, nullptr, 1006 },
|
||||
{ "no-color", 0, nullptr, 1002 },
|
||||
{ "no-huge-pages", 0, nullptr, 1009 },
|
||||
{ "variant", 1, nullptr, 1010 },
|
||||
{ "pass", 1, nullptr, 'p' },
|
||||
{ "print-time", 1, nullptr, 1007 },
|
||||
{ "retries", 1, nullptr, 'r' },
|
||||
{ "retry-pause", 1, nullptr, 'R' },
|
||||
{ "safe", 0, nullptr, 1005 },
|
||||
{ "syslog", 0, nullptr, 'S' },
|
||||
{ "threads", 1, nullptr, 't' },
|
||||
{ "url", 1, nullptr, 'o' },
|
||||
{ "user", 1, nullptr, 'u' },
|
||||
{ "user-agent", 1, nullptr, 1008 },
|
||||
{ "userpass", 1, nullptr, 'O' },
|
||||
{ "version", 0, nullptr, 'V' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct option const config_options[] = {
|
||||
{ "algo", 1, nullptr, 'a' },
|
||||
{ "av", 1, nullptr, 'v' },
|
||||
{ "background", 0, nullptr, 'B' },
|
||||
{ "colors", 0, nullptr, 2000 },
|
||||
{ "cpu-affinity", 1, nullptr, 1020 },
|
||||
{ "cpu-priority", 1, nullptr, 1021 },
|
||||
{ "donate-level", 1, nullptr, 1003 },
|
||||
{ "dry-run", 0, nullptr, 5000 },
|
||||
{ "huge-pages", 0, nullptr, 1009 },
|
||||
{ "log-file", 1, nullptr, 'l' },
|
||||
{ "max-cpu-usage", 1, nullptr, 1004 },
|
||||
{ "print-time", 1, nullptr, 1007 },
|
||||
{ "retries", 1, nullptr, 'r' },
|
||||
{ "retry-pause", 1, nullptr, 'R' },
|
||||
{ "safe", 0, nullptr, 1005 },
|
||||
{ "syslog", 0, nullptr, 'S' },
|
||||
{ "threads", 1, nullptr, 't' },
|
||||
{ "user-agent", 1, nullptr, 1008 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct option const pool_options[] = {
|
||||
{ "url", 1, nullptr, 'o' },
|
||||
{ "pass", 1, nullptr, 'p' },
|
||||
{ "user", 1, nullptr, 'u' },
|
||||
{ "userpass", 1, nullptr, 'O' },
|
||||
{ "keepalive", 0, nullptr ,'k' },
|
||||
{ "variant", 1, nullptr, 1010 },
|
||||
{ "nicehash", 0, nullptr, 1006 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct option const api_options[] = {
|
||||
{ "port", 1, nullptr, 4000 },
|
||||
{ "access-token", 1, nullptr, 4001 },
|
||||
{ "worker-id", 1, nullptr, 4002 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static const char *algo_names[] = {
|
||||
"cryptonight",
|
||||
# ifndef XMRIG_NO_AEON
|
||||
"cryptonight-lite"
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
Options *Options::parse(int argc, char **argv)
|
||||
{
|
||||
Options *options = new Options(argc, argv);
|
||||
if (options->isReady()) {
|
||||
m_self = options;
|
||||
return m_self;
|
||||
}
|
||||
|
||||
delete options;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
const char *Options::algoName() const
|
||||
{
|
||||
return algo_names[m_algo];
|
||||
}
|
||||
|
||||
|
||||
Options::Options(int argc, char **argv) :
|
||||
m_background(false),
|
||||
m_colors(true),
|
||||
m_doubleHash(false),
|
||||
m_dryRun(false),
|
||||
m_hugePages(true),
|
||||
m_ready(false),
|
||||
m_safe(false),
|
||||
m_syslog(false),
|
||||
m_apiToken(nullptr),
|
||||
m_apiWorkerId(nullptr),
|
||||
m_logFile(nullptr),
|
||||
m_userAgent(nullptr),
|
||||
m_algo(0),
|
||||
m_algoVariant(0),
|
||||
m_apiPort(0),
|
||||
m_donateLevel(kDonateLevel),
|
||||
m_maxCpuUsage(75),
|
||||
m_printTime(60),
|
||||
m_priority(-1),
|
||||
m_retries(5),
|
||||
m_retryPause(5),
|
||||
m_threads(0),
|
||||
m_affinity(-1L)
|
||||
{
|
||||
m_pools.push_back(new Url());
|
||||
|
||||
int key;
|
||||
|
||||
while (1) {
|
||||
key = getopt_long(argc, argv, short_options, options, NULL);
|
||||
if (key < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!parseArg(key, optarg)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_pools[0]->isValid()) {
|
||||
parseConfig(Platform::defaultConfigName());
|
||||
}
|
||||
|
||||
if (!m_pools[0]->isValid()) {
|
||||
fprintf(stderr, "No pool URL supplied. Exiting.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_algoVariant = getAlgoVariant();
|
||||
if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) {
|
||||
m_doubleHash = true;
|
||||
}
|
||||
|
||||
if (!m_threads) {
|
||||
m_threads = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage);
|
||||
}
|
||||
else if (m_safe) {
|
||||
const int count = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage);
|
||||
if (m_threads > count) {
|
||||
m_threads = count;
|
||||
}
|
||||
}
|
||||
|
||||
adjust();
|
||||
|
||||
m_ready = true;
|
||||
}
|
||||
|
||||
|
||||
Options::~Options()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool Options::getJSON(const char *fileName, rapidjson::Document &doc)
|
||||
{
|
||||
uv_fs_t req;
|
||||
const int fd = uv_fs_open(uv_default_loop(), &req, fileName, O_RDONLY, 0644, nullptr);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "unable to open %s: %s\n", fileName, uv_strerror(fd));
|
||||
return false;
|
||||
}
|
||||
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
FILE *fp = fdopen(fd, "rb");
|
||||
char buf[8192];
|
||||
rapidjson::FileReadStream is(fp, buf, sizeof(buf));
|
||||
|
||||
doc.ParseStream(is);
|
||||
|
||||
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
if (doc.HasParseError()) {
|
||||
printf("%s:%d: %s\n", fileName, (int) doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return doc.IsObject();
|
||||
}
|
||||
|
||||
|
||||
bool Options::parseArg(int key, const char *arg)
|
||||
{
|
||||
switch (key) {
|
||||
case 'a': /* --algo */
|
||||
if (!setAlgo(arg)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o': /* --url */
|
||||
if (m_pools.size() > 1 || m_pools[0]->isValid()) {
|
||||
Url *url = new Url(arg);
|
||||
if (url->isValid()) {
|
||||
m_pools.push_back(url);
|
||||
}
|
||||
else {
|
||||
delete url;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_pools[0]->parse(arg);
|
||||
}
|
||||
|
||||
if (!m_pools.back()->isValid()) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'O': /* --userpass */
|
||||
if (!m_pools.back()->setUserpass(arg)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u': /* --user */
|
||||
m_pools.back()->setUser(arg);
|
||||
break;
|
||||
|
||||
case 'p': /* --pass */
|
||||
m_pools.back()->setPassword(arg);
|
||||
break;
|
||||
|
||||
case 'l': /* --log-file */
|
||||
free(m_logFile);
|
||||
m_logFile = strdup(arg);
|
||||
m_colors = false;
|
||||
break;
|
||||
|
||||
case 4001: /* --access-token */
|
||||
free(m_apiToken);
|
||||
m_apiToken = strdup(arg);
|
||||
break;
|
||||
|
||||
case 4002: /* --worker-id */
|
||||
free(m_apiWorkerId);
|
||||
m_apiWorkerId = strdup(arg);
|
||||
break;
|
||||
|
||||
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 */
|
||||
case 4000: /* --api-port */
|
||||
case 1010: /* --variant */
|
||||
return parseArg(key, strtol(arg, nullptr, 10));
|
||||
|
||||
case 'B': /* --background */
|
||||
case 'k': /* --keepalive */
|
||||
case 'S': /* --syslog */
|
||||
case 1005: /* --safe */
|
||||
case 1006: /* --nicehash */
|
||||
case 5000: /* --dry-run */
|
||||
return parseBoolean(key, true);
|
||||
|
||||
case 1002: /* --no-color */
|
||||
case 1009: /* --no-huge-pages */
|
||||
return parseBoolean(key, false);
|
||||
|
||||
case 't': /* --threads */
|
||||
if (strncmp(arg, "all", 3) == 0) {
|
||||
m_threads = Cpu::threads();
|
||||
return true;
|
||||
}
|
||||
|
||||
return parseArg(key, strtol(arg, nullptr, 10));
|
||||
|
||||
case 'V': /* --version */
|
||||
showVersion();
|
||||
return false;
|
||||
|
||||
case 'h': /* --help */
|
||||
showUsage(0);
|
||||
return false;
|
||||
|
||||
case 'c': /* --config */
|
||||
parseConfig(arg);
|
||||
break;
|
||||
|
||||
case 1020: { /* --cpu-affinity */
|
||||
const char *p = strstr(arg, "0x");
|
||||
return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
|
||||
}
|
||||
|
||||
case 1008: /* --user-agent */
|
||||
free(m_userAgent);
|
||||
m_userAgent = strdup(arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Options::parseArg(int key, uint64_t arg)
|
||||
{
|
||||
switch (key) {
|
||||
case 'r': /* --retries */
|
||||
if (arg < 1 || arg > 1000) {
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_retries = (int) arg;
|
||||
break;
|
||||
|
||||
case 'R': /* --retry-pause */
|
||||
if (arg < 1 || arg > 3600) {
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_retryPause = (int) arg;
|
||||
break;
|
||||
|
||||
case 't': /* --threads */
|
||||
if (arg < 1 || arg > 1024) {
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_threads = (int) arg;
|
||||
break;
|
||||
|
||||
case 'v': /* --av */
|
||||
if (arg > 1000) {
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_algoVariant = (int) arg;
|
||||
break;
|
||||
|
||||
case 1003: /* --donate-level */
|
||||
if (arg < 1 || arg > 99) {
|
||||
return true;
|
||||
}
|
||||
|
||||
m_donateLevel = (int) arg;
|
||||
break;
|
||||
|
||||
case 1004: /* --max-cpu-usage */
|
||||
if (arg < 1 || arg > 100) {
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_maxCpuUsage = (int) arg;
|
||||
break;
|
||||
|
||||
case 1007: /* --print-time */
|
||||
if (arg > 1000) {
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_printTime = (int) arg;
|
||||
break;
|
||||
|
||||
case 1010: /* --variant */
|
||||
m_pools.back()->setVariant((int) arg);
|
||||
break;
|
||||
|
||||
case 1020: /* --cpu-affinity */
|
||||
if (arg) {
|
||||
m_affinity = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1021: /* --cpu-priority */
|
||||
if (arg <= 5) {
|
||||
m_priority = (int) arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4000: /* --api-port */
|
||||
if (arg <= 65536) {
|
||||
m_apiPort = (int) arg;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Options::parseBoolean(int key, bool enable)
|
||||
{
|
||||
switch (key) {
|
||||
case 'k': /* --keepalive */
|
||||
m_pools.back()->setKeepAlive(enable);
|
||||
break;
|
||||
|
||||
case 'B': /* --background */
|
||||
m_background = enable;
|
||||
m_colors = enable ? false : m_colors;
|
||||
break;
|
||||
|
||||
case 'S': /* --syslog */
|
||||
m_syslog = enable;
|
||||
m_colors = enable ? false : m_colors;
|
||||
break;
|
||||
|
||||
case 1002: /* --no-color */
|
||||
m_colors = enable;
|
||||
break;
|
||||
|
||||
case 1005: /* --safe */
|
||||
m_safe = enable;
|
||||
break;
|
||||
|
||||
case 1006: /* --nicehash */
|
||||
m_pools.back()->setNicehash(enable);
|
||||
break;
|
||||
|
||||
case 1009: /* --no-huge-pages */
|
||||
m_hugePages = enable;
|
||||
break;
|
||||
|
||||
case 2000: /* colors */
|
||||
m_colors = enable;
|
||||
break;
|
||||
|
||||
case 5000: /* --dry-run */
|
||||
m_dryRun = enable;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Url *Options::parseUrl(const char *arg) const
|
||||
{
|
||||
auto url = new Url(arg);
|
||||
if (!url->isValid()) {
|
||||
delete url;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
void Options::adjust()
|
||||
{
|
||||
for (Url *url : m_pools) {
|
||||
url->adjust(m_algo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Options::parseConfig(const char *fileName)
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
if (!getJSON(fileName, doc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) {
|
||||
parseJSON(&config_options[i], doc);
|
||||
}
|
||||
|
||||
const rapidjson::Value &pools = doc["pools"];
|
||||
if (pools.IsArray()) {
|
||||
for (const rapidjson::Value &value : pools.GetArray()) {
|
||||
if (!value.IsObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(pool_options); i++) {
|
||||
parseJSON(&pool_options[i], value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rapidjson::Value &api = doc["api"];
|
||||
if (api.IsObject()) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) {
|
||||
parseJSON(&api_options[i], api);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Options::parseJSON(const struct option *option, const rapidjson::Value &object)
|
||||
{
|
||||
if (!option->name || !object.HasMember(option->name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rapidjson::Value &value = object[option->name];
|
||||
|
||||
if (option->has_arg && value.IsString()) {
|
||||
parseArg(option->val, value.GetString());
|
||||
}
|
||||
else if (option->has_arg && value.IsInt64()) {
|
||||
parseArg(option->val, value.GetUint64());
|
||||
}
|
||||
else if (!option->has_arg && value.IsBool()) {
|
||||
parseBoolean(option->val, value.IsTrue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Options::showUsage(int status) const
|
||||
{
|
||||
if (status) {
|
||||
fprintf(stderr, "Try \"" APP_ID "\" --help' for more information.\n");
|
||||
}
|
||||
else {
|
||||
printf(usage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Options::showVersion()
|
||||
{
|
||||
printf(APP_NAME " " APP_VERSION "\n built on " __DATE__
|
||||
|
||||
# if defined(__clang__)
|
||||
" with clang " __clang_version__);
|
||||
# elif defined(__GNUC__)
|
||||
" with GCC");
|
||||
printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
|
||||
# elif defined(_MSC_VER)
|
||||
" with MSVC");
|
||||
printf(" %d", MSVC_VERSION);
|
||||
# else
|
||||
);
|
||||
# endif
|
||||
|
||||
printf("\n features:"
|
||||
# if defined(__i386__) || defined(_M_IX86)
|
||||
" i386"
|
||||
# elif defined(__x86_64__) || defined(_M_AMD64)
|
||||
" x86_64"
|
||||
# endif
|
||||
|
||||
# if defined(__AES__) || defined(_MSC_VER)
|
||||
" AES-NI"
|
||||
# endif
|
||||
"\n");
|
||||
|
||||
printf("\nlibuv/%s\n", uv_version_string());
|
||||
|
||||
# ifndef XMRIG_NO_HTTPD
|
||||
printf("libmicrohttpd/%s\n", MHD_get_version());
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
bool Options::setAlgo(const char *algo)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(algo_names); i++) {
|
||||
if (algo_names[i] && !strcmp(algo, algo_names[i])) {
|
||||
m_algo = (int) i;
|
||||
break;
|
||||
}
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
if (i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-light")) {
|
||||
m_algo = xmrig::ALGO_CRYPTONIGHT_LITE;
|
||||
break;
|
||||
}
|
||||
# endif
|
||||
|
||||
if (i == ARRAY_SIZE(algo_names) - 1) {
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int Options::getAlgoVariant() const
|
||||
{
|
||||
# ifndef XMRIG_NO_AEON
|
||||
if (m_algo == xmrig::ALGO_CRYPTONIGHT_LITE) {
|
||||
return getAlgoVariantLite();
|
||||
}
|
||||
# endif
|
||||
|
||||
if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) {
|
||||
return Cpu::hasAES() ? AV1_AESNI : AV3_SOFT_AES;
|
||||
}
|
||||
|
||||
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) {
|
||||
return m_algoVariant + 2;
|
||||
}
|
||||
|
||||
return m_algoVariant;
|
||||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_AEON
|
||||
int Options::getAlgoVariantLite() const
|
||||
{
|
||||
if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) {
|
||||
return Cpu::hasAES() ? AV2_AESNI_DOUBLE : AV4_SOFT_AES_DOUBLE;
|
||||
}
|
||||
|
||||
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) {
|
||||
return m_algoVariant + 2;
|
||||
}
|
||||
|
||||
return m_algoVariant;
|
||||
}
|
||||
#endif
|
133
src/Options.h
133
src/Options.h
|
@ -1,133 +0,0 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __OPTIONS_H__
|
||||
#define __OPTIONS_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
class Url;
|
||||
struct option;
|
||||
|
||||
|
||||
class Options
|
||||
{
|
||||
public:
|
||||
enum AlgoVariant {
|
||||
AV0_AUTO,
|
||||
AV1_AESNI,
|
||||
AV2_AESNI_DOUBLE,
|
||||
AV3_SOFT_AES,
|
||||
AV4_SOFT_AES_DOUBLE,
|
||||
AV_MAX
|
||||
};
|
||||
|
||||
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 dryRun() const { return m_dryRun; }
|
||||
inline bool hugePages() const { return m_hugePages; }
|
||||
inline bool syslog() const { return m_syslog; }
|
||||
inline const char *apiToken() const { return m_apiToken; }
|
||||
inline const char *apiWorkerId() const { return m_apiWorkerId; }
|
||||
inline const char *logFile() const { return m_logFile; }
|
||||
inline const char *userAgent() const { return m_userAgent; }
|
||||
inline const std::vector<Url*> &pools() const { return m_pools; }
|
||||
inline int algo() const { return m_algo; }
|
||||
inline int algoVariant() const { return m_algoVariant; }
|
||||
inline int apiPort() const { return m_apiPort; }
|
||||
inline int donateLevel() const { return m_donateLevel; }
|
||||
inline int printTime() const { return m_printTime; }
|
||||
inline int priority() const { return m_priority; }
|
||||
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 void setColors(bool colors) { m_colors = colors; }
|
||||
|
||||
inline static void release() { delete m_self; }
|
||||
|
||||
const char *algoName() const;
|
||||
|
||||
private:
|
||||
Options(int argc, char **argv);
|
||||
~Options();
|
||||
|
||||
inline bool isReady() const { return m_ready; }
|
||||
|
||||
static Options *m_self;
|
||||
|
||||
bool getJSON(const char *fileName, rapidjson::Document &doc);
|
||||
bool parseArg(int key, const char *arg);
|
||||
bool parseArg(int key, uint64_t arg);
|
||||
bool parseBoolean(int key, bool enable);
|
||||
Url *parseUrl(const char *arg) const;
|
||||
void adjust();
|
||||
void parseConfig(const char *fileName);
|
||||
void parseJSON(const struct option *option, const rapidjson::Value &object);
|
||||
void showUsage(int status) const;
|
||||
void showVersion(void);
|
||||
|
||||
bool setAlgo(const char *algo);
|
||||
|
||||
int getAlgoVariant() const;
|
||||
# ifndef XMRIG_NO_AEON
|
||||
int getAlgoVariantLite() const;
|
||||
# endif
|
||||
|
||||
bool m_background;
|
||||
bool m_colors;
|
||||
bool m_doubleHash;
|
||||
bool m_dryRun;
|
||||
bool m_hugePages;
|
||||
bool m_ready;
|
||||
bool m_safe;
|
||||
bool m_syslog;
|
||||
char *m_apiToken;
|
||||
char *m_apiWorkerId;
|
||||
char *m_logFile;
|
||||
char *m_userAgent;
|
||||
int m_algo;
|
||||
int m_algoVariant;
|
||||
int m_apiPort;
|
||||
int m_donateLevel;
|
||||
int m_maxCpuUsage;
|
||||
int m_printTime;
|
||||
int m_priority;
|
||||
int m_retries;
|
||||
int m_retryPause;
|
||||
int m_threads;
|
||||
int64_t m_affinity;
|
||||
std::vector<Url*> m_pools;
|
||||
};
|
||||
|
||||
#endif /* __OPTIONS_H__ */
|
109
src/Summary.cpp
109
src/Summary.cpp
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -27,16 +27,17 @@
|
|||
#include <uv.h>
|
||||
|
||||
|
||||
#include "common/log/Log.h"
|
||||
#include "common/net/Pool.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "Cpu.h"
|
||||
#include "log/Log.h"
|
||||
#include "Mem.h"
|
||||
#include "net/Url.h"
|
||||
#include "Options.h"
|
||||
#include "Summary.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
static void print_versions()
|
||||
static void print_versions(xmrig::Config *config)
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
|
@ -51,26 +52,27 @@ static void print_versions()
|
|||
# endif
|
||||
|
||||
|
||||
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" : " * VERSIONS: XMRig/%s libuv/%s%s",
|
||||
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" : " * VERSIONS: XMRig/%s libuv/%s%s",
|
||||
APP_VERSION, uv_version_string(), buf);
|
||||
}
|
||||
|
||||
|
||||
static void print_memory() {
|
||||
if (Options::i()->colors()) {
|
||||
Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s",
|
||||
Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable",
|
||||
Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled");
|
||||
static void print_memory(xmrig::Config *config) {
|
||||
# ifdef _WIN32
|
||||
if (config->isColors()) {
|
||||
Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s",
|
||||
Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable");
|
||||
}
|
||||
else {
|
||||
Log::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable", Mem::isHugepagesEnabled() ? "enabled" : "disabled");
|
||||
Log::i()->text(" * HUGE PAGES: %s", Mem::isHugepagesAvailable() ? "available" : "unavailable");
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
static void print_cpu()
|
||||
static void print_cpu(xmrig::Config *config)
|
||||
{
|
||||
if (Options::i()->colors()) {
|
||||
if (config->isColors()) {
|
||||
Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI",
|
||||
Cpu::brand(),
|
||||
Cpu::sockets(),
|
||||
|
@ -89,60 +91,71 @@ static void print_cpu()
|
|||
}
|
||||
|
||||
|
||||
static void print_threads()
|
||||
static void print_threads(xmrig::Config *config)
|
||||
{
|
||||
char buf[32];
|
||||
if (Options::i()->affinity() != -1L) {
|
||||
snprintf(buf, 32, ", affinity=0x%" PRIX64, Options::i()->affinity());
|
||||
if (config->threadsMode() != xmrig::Config::Advanced) {
|
||||
char buf[32];
|
||||
if (config->affinity() != -1L) {
|
||||
snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity());
|
||||
}
|
||||
else {
|
||||
buf[0] = '\0';
|
||||
}
|
||||
|
||||
Log::i()->text(config->isColors() ? "\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",
|
||||
config->threadsCount(),
|
||||
config->algorithm().name(),
|
||||
config->algoVariant(),
|
||||
config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "",
|
||||
config->donateLevel(),
|
||||
buf);
|
||||
}
|
||||
else {
|
||||
buf[0] = '\0';
|
||||
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, %sdonate=%d%%" : " * THREADS: %d, %s, %sdonate=%d%%",
|
||||
config->threadsCount(),
|
||||
config->algorithm().name(),
|
||||
config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "",
|
||||
config->donateLevel());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
static void print_pools()
|
||||
static void print_pools(xmrig::Config *config)
|
||||
{
|
||||
const std::vector<Url*> &pools = Options::i()->pools();
|
||||
const std::vector<Pool> &pools = config->pools();
|
||||
|
||||
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",
|
||||
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s" : " * POOL #%d: %s",
|
||||
i + 1,
|
||||
pools[i]->host(),
|
||||
pools[i]->port());
|
||||
pools[i].url()
|
||||
);
|
||||
}
|
||||
|
||||
# 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());
|
||||
for (const Pool &pool : pools) {
|
||||
pool.print();
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_API
|
||||
static void print_api()
|
||||
static void print_api(xmrig::Config *config)
|
||||
{
|
||||
if (Options::i()->apiPort() == 0) {
|
||||
const int port = config->apiPort();
|
||||
if (port == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT: \x1B[01;36m%d" : " * API PORT: %d", Options::i()->apiPort());
|
||||
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mAPI BIND: \x1B[01;36m%s:%d" : " * API BIND: %s:%d",
|
||||
config->isApiIPv6() ? "[::]" : "0.0.0.0", port);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void print_commands()
|
||||
static void print_commands(xmrig::Config *config)
|
||||
{
|
||||
if (Options::i()->colors()) {
|
||||
if (config->isColors()) {
|
||||
Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mh\x1B[01;37mashrate, \x1B[01;35mp\x1B[01;37mause, \x1B[01;35mr\x1B[01;37mesume");
|
||||
}
|
||||
else {
|
||||
|
@ -151,19 +164,19 @@ static void print_commands()
|
|||
}
|
||||
|
||||
|
||||
void Summary::print()
|
||||
void Summary::print(xmrig::Controller *controller)
|
||||
{
|
||||
print_versions();
|
||||
print_memory();
|
||||
print_cpu();
|
||||
print_threads();
|
||||
print_pools();
|
||||
print_versions(controller->config());
|
||||
print_memory(controller->config());
|
||||
print_cpu(controller->config());
|
||||
print_threads(controller->config());
|
||||
print_pools(controller->config());
|
||||
|
||||
# ifndef XMRIG_NO_API
|
||||
print_api();
|
||||
print_api(controller->config());
|
||||
# endif
|
||||
|
||||
print_commands();
|
||||
print_commands(controller->config());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,10 +25,15 @@
|
|||
#define __SUMMARY_H__
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class Summary
|
||||
{
|
||||
public:
|
||||
static void print();
|
||||
static void print(xmrig::Controller *controller);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,17 +25,17 @@
|
|||
|
||||
|
||||
#include "api/Api.h"
|
||||
#include "api/ApiState.h"
|
||||
#include "api/ApiRouter.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
|
||||
|
||||
ApiState *Api::m_state = nullptr;
|
||||
uv_mutex_t Api::m_mutex;
|
||||
ApiRouter *Api::m_router = nullptr;
|
||||
|
||||
|
||||
bool Api::start()
|
||||
bool Api::start(xmrig::Controller *controller)
|
||||
{
|
||||
uv_mutex_init(&m_mutex);
|
||||
m_state = new ApiState();
|
||||
m_router = new ApiRouter(controller);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -43,43 +43,30 @@ bool Api::start()
|
|||
|
||||
void Api::release()
|
||||
{
|
||||
delete m_state;
|
||||
delete m_router;
|
||||
}
|
||||
|
||||
|
||||
char *Api::get(const char *url, int *status)
|
||||
void Api::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
|
||||
{
|
||||
if (!m_state) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uv_mutex_lock(&m_mutex);
|
||||
char *buf = m_state->get(url, status);
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
void Api::tick(const Hashrate *hashrate)
|
||||
{
|
||||
if (!m_state) {
|
||||
if (!m_router) {
|
||||
reply.status = 500;
|
||||
return;
|
||||
}
|
||||
|
||||
uv_mutex_lock(&m_mutex);
|
||||
m_state->tick(hashrate);
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
if (req.method() == xmrig::HttpRequest::Get) {
|
||||
return m_router->get(req, reply);
|
||||
}
|
||||
|
||||
m_router->exec(req, reply);
|
||||
}
|
||||
|
||||
|
||||
void Api::tick(const NetworkState &network)
|
||||
{
|
||||
if (!m_state) {
|
||||
if (!m_router) {
|
||||
return;
|
||||
}
|
||||
|
||||
uv_mutex_lock(&m_mutex);
|
||||
m_state->tick(network);
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
m_router->tick(network);
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -28,24 +28,29 @@
|
|||
#include <uv.h>
|
||||
|
||||
|
||||
class ApiState;
|
||||
class ApiRouter;
|
||||
class Hashrate;
|
||||
class NetworkState;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
class HttpReply;
|
||||
class HttpRequest;
|
||||
}
|
||||
|
||||
|
||||
class Api
|
||||
{
|
||||
public:
|
||||
static bool start();
|
||||
static bool start(xmrig::Controller *controller);
|
||||
static void release();
|
||||
|
||||
static char *get(const char *url, int *status);
|
||||
static void tick(const Hashrate *hashrate);
|
||||
static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
||||
static void tick(const NetworkState &results);
|
||||
|
||||
private:
|
||||
static ApiState *m_state;
|
||||
static uv_mutex_t m_mutex;
|
||||
static ApiRouter *m_router;
|
||||
};
|
||||
|
||||
#endif /* __API_H__ */
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -32,23 +32,23 @@
|
|||
#endif
|
||||
|
||||
|
||||
#include "api/ApiState.h"
|
||||
#include "api/ApiRouter.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
#include "common/crypto/keccak.h"
|
||||
#include "common/net/Job.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "Cpu.h"
|
||||
#include "interfaces/IThread.h"
|
||||
#include "Mem.h"
|
||||
#include "net/Job.h"
|
||||
#include "Options.h"
|
||||
#include "Platform.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "version.h"
|
||||
#include "workers/Hashrate.h"
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "crypto/c_keccak.h"
|
||||
}
|
||||
#include "workers/Workers.h"
|
||||
|
||||
|
||||
static inline double normalize(double d)
|
||||
|
@ -61,34 +61,42 @@ static inline double normalize(double d)
|
|||
}
|
||||
|
||||
|
||||
ApiState::ApiState()
|
||||
ApiRouter::ApiRouter(xmrig::Controller *controller) :
|
||||
m_controller(controller)
|
||||
{
|
||||
m_threads = Options::i()->threads();
|
||||
m_hashrate = new double[m_threads * 3]();
|
||||
|
||||
memset(m_totalHashrate, 0, sizeof(m_totalHashrate));
|
||||
memset(m_workerId, 0, sizeof(m_workerId));
|
||||
|
||||
if (Options::i()->apiWorkerId()) {
|
||||
strncpy(m_workerId, Options::i()->apiWorkerId(), sizeof(m_workerId) - 1);
|
||||
}
|
||||
else {
|
||||
gethostname(m_workerId, sizeof(m_workerId) - 1);
|
||||
}
|
||||
|
||||
setWorkerId(controller->config()->apiWorkerId());
|
||||
genId();
|
||||
}
|
||||
|
||||
|
||||
ApiState::~ApiState()
|
||||
ApiRouter::~ApiRouter()
|
||||
{
|
||||
delete [] m_hashrate;
|
||||
}
|
||||
|
||||
|
||||
char *ApiState::get(const char *url, int *status) const
|
||||
void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
|
||||
if (req.match("/1/config")) {
|
||||
if (req.isRestricted()) {
|
||||
reply.status = 403;
|
||||
return;
|
||||
}
|
||||
|
||||
m_controller->config()->getJSON(doc);
|
||||
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
if (req.match("/1/threads")) {
|
||||
getThreads(doc);
|
||||
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
doc.SetObject();
|
||||
|
||||
getIdentify(doc);
|
||||
|
@ -97,43 +105,47 @@ char *ApiState::get(const char *url, int *status) const
|
|||
getResults(doc);
|
||||
getConnection(doc);
|
||||
|
||||
return finalize(doc);
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
|
||||
void ApiState::tick(const Hashrate *hashrate)
|
||||
void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
|
||||
{
|
||||
for (int i = 0; i < m_threads; ++i) {
|
||||
m_hashrate[i * 3] = hashrate->calc((size_t) i, Hashrate::ShortInterval);
|
||||
m_hashrate[i * 3 + 1] = hashrate->calc((size_t) i, Hashrate::MediumInterval);
|
||||
m_hashrate[i * 3 + 2] = hashrate->calc((size_t) i, Hashrate::LargeInterval);
|
||||
if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) {
|
||||
m_controller->config()->reload(req.body());
|
||||
return;
|
||||
}
|
||||
|
||||
m_totalHashrate[0] = hashrate->calc(Hashrate::ShortInterval);
|
||||
m_totalHashrate[1] = hashrate->calc(Hashrate::MediumInterval);
|
||||
m_totalHashrate[2] = hashrate->calc(Hashrate::LargeInterval);
|
||||
m_highestHashrate = hashrate->highest();
|
||||
reply.status = 404;
|
||||
}
|
||||
|
||||
|
||||
void ApiState::tick(const NetworkState &network)
|
||||
void ApiRouter::tick(const NetworkState &network)
|
||||
{
|
||||
m_network = network;
|
||||
}
|
||||
|
||||
|
||||
char *ApiState::finalize(rapidjson::Document &doc) const
|
||||
void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
|
||||
{
|
||||
updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId());
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
rapidjson::StringBuffer buffer(0, 4096);
|
||||
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
|
||||
writer.SetMaxDecimalPlaces(10);
|
||||
doc.Accept(writer);
|
||||
|
||||
return strdup(buffer.GetString());
|
||||
reply.status = 200;
|
||||
reply.buf = strdup(buffer.GetString());
|
||||
reply.size = buffer.GetSize();
|
||||
}
|
||||
|
||||
|
||||
void ApiState::genId()
|
||||
void ApiRouter::genId()
|
||||
{
|
||||
memset(m_id, 0, sizeof(m_id));
|
||||
|
||||
|
@ -154,7 +166,7 @@ void ApiState::genId()
|
|||
memcpy(input, interfaces[i].phys_addr, addrSize);
|
||||
memcpy(input + addrSize, APP_KIND, strlen(APP_KIND));
|
||||
|
||||
keccak(input, static_cast<int>(inSize), hash, sizeof(hash));
|
||||
xmrig::keccak(input, inSize, hash);
|
||||
Job::toHex(hash, 8, m_id);
|
||||
|
||||
delete [] input;
|
||||
|
@ -166,7 +178,7 @@ void ApiState::genId()
|
|||
}
|
||||
|
||||
|
||||
void ApiState::getConnection(rapidjson::Document &doc) const
|
||||
void ApiRouter::getConnection(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
|
@ -181,7 +193,7 @@ void ApiState::getConnection(rapidjson::Document &doc) const
|
|||
}
|
||||
|
||||
|
||||
void ApiState::getHashrate(rapidjson::Document &doc) const
|
||||
void ApiRouter::getHashrate(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
|
@ -189,34 +201,36 @@ void ApiState::getHashrate(rapidjson::Document &doc) const
|
|||
rapidjson::Value total(rapidjson::kArrayType);
|
||||
rapidjson::Value threads(rapidjson::kArrayType);
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
total.PushBack(normalize(m_totalHashrate[i]), allocator);
|
||||
}
|
||||
const Hashrate *hr = Workers::hashrate();
|
||||
|
||||
for (int i = 0; i < m_threads * 3; i += 3) {
|
||||
total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator);
|
||||
total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator);
|
||||
total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator);
|
||||
|
||||
for (size_t i = 0; i < Workers::threads(); i++) {
|
||||
rapidjson::Value thread(rapidjson::kArrayType);
|
||||
thread.PushBack(normalize(m_hashrate[i]), allocator);
|
||||
thread.PushBack(normalize(m_hashrate[i + 1]), allocator);
|
||||
thread.PushBack(normalize(m_hashrate[i + 2]), allocator);
|
||||
thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
||||
thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
||||
thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
|
||||
|
||||
threads.PushBack(thread, allocator);
|
||||
}
|
||||
|
||||
hashrate.AddMember("total", total, allocator);
|
||||
hashrate.AddMember("highest", normalize(m_highestHashrate), allocator);
|
||||
hashrate.AddMember("total", total, allocator);
|
||||
hashrate.AddMember("highest", normalize(hr->highest()), allocator);
|
||||
hashrate.AddMember("threads", threads, allocator);
|
||||
doc.AddMember("hashrate", hashrate, allocator);
|
||||
}
|
||||
|
||||
|
||||
void ApiState::getIdentify(rapidjson::Document &doc) const
|
||||
void ApiRouter::getIdentify(rapidjson::Document &doc) const
|
||||
{
|
||||
doc.AddMember("id", rapidjson::StringRef(m_id), doc.GetAllocator());
|
||||
doc.AddMember("worker_id", rapidjson::StringRef(m_workerId), doc.GetAllocator());
|
||||
}
|
||||
|
||||
|
||||
void ApiState::getMiner(rapidjson::Document &doc) const
|
||||
void ApiRouter::getMiner(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
|
@ -230,13 +244,13 @@ void ApiState::getMiner(rapidjson::Document &doc) const
|
|||
doc.AddMember("kind", APP_KIND, allocator);
|
||||
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
|
||||
doc.AddMember("cpu", cpu, allocator);
|
||||
doc.AddMember("algo", rapidjson::StringRef(Options::i()->algoName()), allocator);
|
||||
doc.AddMember("hugepages", Mem::isHugepagesEnabled(), allocator);
|
||||
doc.AddMember("donate_level", Options::i()->donateLevel(), allocator);
|
||||
doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), allocator);
|
||||
doc.AddMember("hugepages", Workers::hugePages() > 0, allocator);
|
||||
doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator);
|
||||
}
|
||||
|
||||
|
||||
void ApiState::getResults(rapidjson::Document &doc) const
|
||||
void ApiRouter::getResults(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
|
@ -258,3 +272,57 @@ void ApiState::getResults(rapidjson::Document &doc) const
|
|||
|
||||
doc.AddMember("results", results, allocator);
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::getThreads(rapidjson::Document &doc) const
|
||||
{
|
||||
doc.SetObject();
|
||||
auto &allocator = doc.GetAllocator();
|
||||
const Hashrate *hr = Workers::hashrate();
|
||||
|
||||
Workers::threadsSummary(doc);
|
||||
|
||||
const std::vector<xmrig::IThread *> &threads = m_controller->config()->threads();
|
||||
rapidjson::Value list(rapidjson::kArrayType);
|
||||
|
||||
for (const xmrig::IThread *thread : threads) {
|
||||
rapidjson::Value value = thread->toAPI(doc);
|
||||
|
||||
rapidjson::Value hashrate(rapidjson::kArrayType);
|
||||
hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::ShortInterval)), allocator);
|
||||
hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::MediumInterval)), allocator);
|
||||
hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::LargeInterval)), allocator);
|
||||
|
||||
value.AddMember("hashrate", hashrate, allocator);
|
||||
list.PushBack(value, allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("threads", list, allocator);
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::setWorkerId(const char *id)
|
||||
{
|
||||
memset(m_workerId, 0, sizeof(m_workerId));
|
||||
|
||||
if (id && strlen(id) > 0) {
|
||||
strncpy(m_workerId, id, sizeof(m_workerId) - 1);
|
||||
}
|
||||
else {
|
||||
gethostname(m_workerId, sizeof(m_workerId) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::updateWorkerId(const char *id, const char *previousId)
|
||||
{
|
||||
if (id == previousId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (id != nullptr && previousId != nullptr && strcmp(id, previousId) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
setWorkerId(id);
|
||||
}
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,43 +21,55 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __APISTATE_H__
|
||||
#define __APISTATE_H__
|
||||
#ifndef __APIROUTER_H__
|
||||
#define __APIROUTER_H__
|
||||
|
||||
|
||||
#include "api/NetworkState.h"
|
||||
#include "interfaces/IControllerListener.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
class Hashrate;
|
||||
|
||||
|
||||
class ApiState
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
class HttpReply;
|
||||
class HttpRequest;
|
||||
}
|
||||
|
||||
|
||||
class ApiRouter : public xmrig::IControllerListener
|
||||
{
|
||||
public:
|
||||
ApiState();
|
||||
~ApiState();
|
||||
ApiRouter(xmrig::Controller *controller);
|
||||
~ApiRouter();
|
||||
|
||||
void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const;
|
||||
void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
||||
|
||||
char *get(const char *url, int *status) const;
|
||||
void tick(const Hashrate *hashrate);
|
||||
void tick(const NetworkState &results);
|
||||
|
||||
protected:
|
||||
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
|
||||
|
||||
private:
|
||||
char *finalize(rapidjson::Document &doc) const;
|
||||
void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const;
|
||||
void genId();
|
||||
void getConnection(rapidjson::Document &doc) const;
|
||||
void getHashrate(rapidjson::Document &doc) const;
|
||||
void getIdentify(rapidjson::Document &doc) const;
|
||||
void getMiner(rapidjson::Document &doc) const;
|
||||
void getResults(rapidjson::Document &doc) const;
|
||||
void getThreads(rapidjson::Document &doc) const;
|
||||
void setWorkerId(const char *id);
|
||||
void updateWorkerId(const char *id, const char *previousId);
|
||||
|
||||
char m_id[17];
|
||||
char m_workerId[128];
|
||||
double *m_hashrate;
|
||||
double m_highestHashrate;
|
||||
double m_totalHashrate[3];
|
||||
int m_threads;
|
||||
NetworkState m_network;
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
||||
#endif /* __APISTATE_H__ */
|
||||
#endif /* __APIROUTER_H__ */
|
|
@ -1,124 +0,0 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <microhttpd.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "api/Api.h"
|
||||
#include "api/Httpd.h"
|
||||
#include "log/Log.h"
|
||||
|
||||
|
||||
Httpd::Httpd(int port, const char *accessToken) :
|
||||
m_accessToken(accessToken),
|
||||
m_port(port),
|
||||
m_daemon(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool Httpd::start()
|
||||
{
|
||||
if (!m_port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int flags = MHD_USE_SELECT_INTERNALLY;
|
||||
|
||||
# if MHD_VERSION >= 0x00093500
|
||||
if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
|
||||
flags = MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY;
|
||||
}
|
||||
# endif
|
||||
|
||||
m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
|
||||
if (!m_daemon) {
|
||||
LOG_ERR("HTTP Daemon failed to start.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int Httpd::auth(const char *header)
|
||||
{
|
||||
if (!m_accessToken) {
|
||||
return MHD_HTTP_OK;
|
||||
}
|
||||
|
||||
if (m_accessToken && !header) {
|
||||
return MHD_HTTP_UNAUTHORIZED;
|
||||
}
|
||||
|
||||
const size_t size = strlen(header);
|
||||
if (size < 8 || strlen(m_accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) {
|
||||
return MHD_HTTP_FORBIDDEN;
|
||||
}
|
||||
|
||||
return strncmp(m_accessToken, header + 7, strlen(m_accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
|
||||
}
|
||||
|
||||
|
||||
int Httpd::done(MHD_Connection *connection, int status, MHD_Response *rsp)
|
||||
{
|
||||
if (!rsp) {
|
||||
rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);
|
||||
}
|
||||
|
||||
MHD_add_response_header(rsp, "Content-Type", "application/json");
|
||||
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*");
|
||||
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET");
|
||||
MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization");
|
||||
|
||||
const int ret = MHD_queue_response(connection, status, rsp);
|
||||
MHD_destroy_response(rsp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
|
||||
{
|
||||
if (strcmp(method, "OPTIONS") == 0) {
|
||||
return done(connection, MHD_HTTP_OK, nullptr);
|
||||
}
|
||||
|
||||
if (strcmp(method, "GET") != 0) {
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
int status = static_cast<Httpd*>(cls)->auth(MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Authorization"));
|
||||
if (status != MHD_HTTP_OK) {
|
||||
return done(connection, status, nullptr);
|
||||
}
|
||||
|
||||
char *buf = Api::get(url, &status);
|
||||
if (buf == nullptr) {
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
MHD_Response *rsp = MHD_create_response_from_buffer(strlen(buf), (void*) buf, MHD_RESPMEM_MUST_FREE);
|
||||
return done(connection, status, rsp);
|
||||
}
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -29,7 +29,7 @@
|
|||
|
||||
|
||||
#include "api/NetworkState.h"
|
||||
#include "net/SubmitResult.h"
|
||||
#include "common/net/SubmitResult.h"
|
||||
|
||||
|
||||
NetworkState::NetworkState() :
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -22,7 +22,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "Console.h"
|
||||
#include "common/Console.h"
|
||||
#include "interfaces/IConsoleListener.h"
|
||||
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
|
@ -29,16 +29,16 @@
|
|||
#include "Platform.h"
|
||||
|
||||
|
||||
char *Platform::m_defaultConfigName = nullptr;
|
||||
char *Platform::m_userAgent = nullptr;
|
||||
char Platform::m_defaultConfigName[520] = { 0 };
|
||||
xmrig::c_str Platform::m_userAgent;
|
||||
|
||||
|
||||
const char *Platform::defaultConfigName()
|
||||
{
|
||||
size_t size = 520;
|
||||
|
||||
if (m_defaultConfigName == nullptr) {
|
||||
m_defaultConfigName = new char[size];
|
||||
if (*m_defaultConfigName) {
|
||||
return m_defaultConfigName;
|
||||
}
|
||||
|
||||
if (uv_exepath(m_defaultConfigName, &size) < 0) {
|
||||
|
@ -58,5 +58,6 @@ const char *Platform::defaultConfigName()
|
|||
}
|
||||
}
|
||||
|
||||
*m_defaultConfigName = '\0';
|
||||
return nullptr;
|
||||
}
|
|
@ -25,20 +25,26 @@
|
|||
#define __PLATFORM_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "common/utils/c_str.h"
|
||||
|
||||
|
||||
class Platform
|
||||
{
|
||||
public:
|
||||
static bool setThreadAffinity(uint64_t cpu_id);
|
||||
static const char *defaultConfigName();
|
||||
static void init(const char *userAgent);
|
||||
static void release();
|
||||
static void setProcessPriority(int priority);
|
||||
static void setThreadPriority(int priority);
|
||||
|
||||
static inline const char *userAgent() { return m_userAgent; }
|
||||
static inline const char *userAgent() { return m_userAgent.data(); }
|
||||
|
||||
private:
|
||||
static char *m_defaultConfigName;
|
||||
static char *m_userAgent;
|
||||
static char m_defaultConfigName[520];
|
||||
static xmrig::c_str m_userAgent;
|
||||
};
|
||||
|
||||
|
|
@ -22,6 +22,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <mach/thread_act.h>
|
||||
#include <mach/thread_policy.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/resource.h>
|
||||
|
@ -53,15 +55,24 @@ static inline char *createUserAgent()
|
|||
}
|
||||
|
||||
|
||||
void Platform::init(const char *userAgent)
|
||||
bool Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
{
|
||||
m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
|
||||
thread_port_t mach_thread;
|
||||
thread_affinity_policy_data_t policy = { static_cast<integer_t>(cpu_id) };
|
||||
mach_thread = pthread_mach_thread_np(pthread_self());
|
||||
|
||||
return thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1) == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void Platform::release()
|
||||
void Platform::init(const char *userAgent)
|
||||
{
|
||||
delete [] m_userAgent;
|
||||
if (userAgent) {
|
||||
m_userAgent = userAgent;
|
||||
}
|
||||
else {
|
||||
m_userAgent = createUserAgent();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,6 +21,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# include <sys/types.h>
|
||||
# include <sys/param.h>
|
||||
# include <sys/cpuset.h>
|
||||
# include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -37,6 +45,11 @@
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
typedef cpuset_t cpu_set_t;
|
||||
#endif
|
||||
|
||||
|
||||
static inline char *createUserAgent()
|
||||
{
|
||||
const size_t max = 160;
|
||||
|
@ -63,15 +76,28 @@ static inline char *createUserAgent()
|
|||
}
|
||||
|
||||
|
||||
void Platform::init(const char *userAgent)
|
||||
bool Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
{
|
||||
m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
|
||||
cpu_set_t mn;
|
||||
CPU_ZERO(&mn);
|
||||
CPU_SET(cpu_id, &mn);
|
||||
|
||||
# ifndef __ANDROID__
|
||||
return pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mn) == 0;
|
||||
# else
|
||||
return sched_setaffinity(gettid(), sizeof(cpu_set_t), &mn) == 0;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void Platform::release()
|
||||
void Platform::init(const char *userAgent)
|
||||
{
|
||||
delete [] m_userAgent;
|
||||
if (userAgent) {
|
||||
m_userAgent = userAgent;
|
||||
}
|
||||
else {
|
||||
m_userAgent = createUserAgent();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -27,9 +27,11 @@
|
|||
#include <uv.h>
|
||||
|
||||
|
||||
#include "log/Log.h"
|
||||
#include "Platform.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_NVIDIA_PROJECT
|
||||
# include "nvidia/cryptonight.h"
|
||||
#endif
|
||||
|
@ -82,16 +84,24 @@ static inline char *createUserAgent()
|
|||
}
|
||||
|
||||
|
||||
void Platform::init(const char *userAgent)
|
||||
bool Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
{
|
||||
m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
|
||||
if (cpu_id >= 64) {
|
||||
LOG_ERR("Unable to set affinity. Windows supports only affinity up to 63.");
|
||||
}
|
||||
|
||||
return SetThreadAffinityMask(GetCurrentThread(), 1ULL << cpu_id) != 0;
|
||||
}
|
||||
|
||||
|
||||
void Platform::release()
|
||||
void Platform::init(const char *userAgent)
|
||||
{
|
||||
delete [] m_defaultConfigName;
|
||||
delete [] m_userAgent;
|
||||
if (userAgent) {
|
||||
m_userAgent = userAgent;
|
||||
}
|
||||
else {
|
||||
m_userAgent = createUserAgent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,7 +141,6 @@ void Platform::setProcessPriority(int priority)
|
|||
}
|
||||
|
||||
|
||||
|
||||
void Platform::setThreadPriority(int priority)
|
||||
{
|
||||
if (priority == -1) {
|
69
src/common/api/HttpBody.h
Normal file
69
src/common/api/HttpBody.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __HTTPBODY_H__
|
||||
#define __HTTPBODY_H__
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpBody
|
||||
{
|
||||
public:
|
||||
inline HttpBody() :
|
||||
m_pos(0)
|
||||
{}
|
||||
|
||||
|
||||
inline bool write(const char *data, size_t size)
|
||||
{
|
||||
if (size > (sizeof(m_data) - m_pos - 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(m_data + m_pos, data, size);
|
||||
|
||||
m_pos += size;
|
||||
m_data[m_pos] = '\0';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline const char *data() const { return m_data; }
|
||||
|
||||
private:
|
||||
char m_data[32768];
|
||||
size_t m_pos;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __HTTPBODY_H__ */
|
|
@ -7,6 +7,7 @@
|
|||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
|
@ -21,27 +22,32 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __XMRIG_H__
|
||||
#define __XMRIG_H__
|
||||
#ifndef __HTTPREPLY_H__
|
||||
#define __HTTPREPLY_H__
|
||||
|
||||
|
||||
namespace xmrig
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpReply
|
||||
{
|
||||
public:
|
||||
HttpReply() :
|
||||
buf(nullptr),
|
||||
status(200),
|
||||
size(0)
|
||||
{}
|
||||
|
||||
|
||||
enum Algo {
|
||||
ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */
|
||||
ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
|
||||
char *buf;
|
||||
int status;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
|
||||
enum Variant {
|
||||
VARIANT_AUTO = -1,
|
||||
VARIANT_NONE = 0,
|
||||
VARIANT_V1 = 1
|
||||
};
|
||||
|
||||
} /* xmrig */
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __XMRIG_H__ */
|
||||
#endif /* __HTTPREPLY_H__ */
|
175
src/common/api/HttpRequest.cpp
Normal file
175
src/common/api/HttpRequest.cpp
Normal file
|
@ -0,0 +1,175 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <microhttpd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common/api/HttpBody.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
|
||||
|
||||
#ifndef MHD_HTTP_PAYLOAD_TOO_LARGE
|
||||
# define MHD_HTTP_PAYLOAD_TOO_LARGE 413
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::HttpRequest::HttpRequest(MHD_Connection *connection, const char *url, const char *method, const char *uploadData, size_t *uploadSize, void **cls) :
|
||||
m_fulfilled(true),
|
||||
m_restricted(true),
|
||||
m_uploadData(uploadData),
|
||||
m_url(url),
|
||||
m_body(static_cast<HttpBody*>(*cls)),
|
||||
m_method(Unsupported),
|
||||
m_connection(connection),
|
||||
m_uploadSize(uploadSize),
|
||||
m_cls(cls)
|
||||
{
|
||||
if (strcmp(method, MHD_HTTP_METHOD_OPTIONS) == 0) {
|
||||
m_method = Options;
|
||||
}
|
||||
else if (strcmp(method, MHD_HTTP_METHOD_GET) == 0) {
|
||||
m_method = Get;
|
||||
}
|
||||
else if (strcmp(method, MHD_HTTP_METHOD_PUT) == 0) {
|
||||
m_method = Put;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpRequest::~HttpRequest()
|
||||
{
|
||||
if (m_fulfilled) {
|
||||
delete m_body;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpRequest::match(const char *path) const
|
||||
{
|
||||
return strcmp(m_url, path) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpRequest::process(const char *accessToken, bool restricted, xmrig::HttpReply &reply)
|
||||
{
|
||||
m_restricted = restricted || !accessToken;
|
||||
|
||||
if (m_body) {
|
||||
if (*m_uploadSize != 0) {
|
||||
if (!m_body->write(m_uploadData, *m_uploadSize)) {
|
||||
*m_cls = nullptr;
|
||||
m_fulfilled = true;
|
||||
reply.status = MHD_HTTP_PAYLOAD_TOO_LARGE;
|
||||
return false;
|
||||
}
|
||||
|
||||
*m_uploadSize = 0;
|
||||
m_fulfilled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
m_fulfilled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
reply.status = auth(accessToken);
|
||||
if (reply.status != MHD_HTTP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_restricted && m_method != Get) {
|
||||
reply.status = MHD_HTTP_FORBIDDEN;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_method == Get) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *contentType = MHD_lookup_connection_value(m_connection, MHD_HEADER_KIND, "Content-Type");
|
||||
if (!contentType || strcmp(contentType, "application/json") != 0) {
|
||||
reply.status = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_body = new xmrig::HttpBody();
|
||||
m_fulfilled = false;
|
||||
*m_cls = m_body;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::HttpRequest::body() const
|
||||
{
|
||||
return m_body ? m_body->data() : nullptr;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::HttpRequest::end(const HttpReply &reply)
|
||||
{
|
||||
if (reply.buf) {
|
||||
return end(reply.status, MHD_create_response_from_buffer(reply.size ? reply.size : strlen(reply.buf), (void*) reply.buf, MHD_RESPMEM_MUST_FREE));
|
||||
}
|
||||
|
||||
return end(reply.status, nullptr);
|
||||
}
|
||||
|
||||
|
||||
int xmrig::HttpRequest::end(int status, MHD_Response *rsp)
|
||||
{
|
||||
if (!rsp) {
|
||||
rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);
|
||||
}
|
||||
|
||||
MHD_add_response_header(rsp, "Content-Type", "application/json");
|
||||
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*");
|
||||
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET, PUT");
|
||||
MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization");
|
||||
|
||||
const int ret = MHD_queue_response(m_connection, status, rsp);
|
||||
MHD_destroy_response(rsp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::HttpRequest::auth(const char *accessToken)
|
||||
{
|
||||
if (!accessToken) {
|
||||
return MHD_HTTP_OK;
|
||||
}
|
||||
|
||||
const char *header = MHD_lookup_connection_value(m_connection, MHD_HEADER_KIND, "Authorization");
|
||||
if (accessToken && !header) {
|
||||
return MHD_HTTP_UNAUTHORIZED;
|
||||
}
|
||||
|
||||
const size_t size = strlen(header);
|
||||
if (size < 8 || strlen(accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) {
|
||||
return MHD_HTTP_FORBIDDEN;
|
||||
}
|
||||
|
||||
return strncmp(accessToken, header + 7, strlen(accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
|
||||
}
|
84
src/common/api/HttpRequest.h
Normal file
84
src/common/api/HttpRequest.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __HTTPREQUEST_H__
|
||||
#define __HTTPREQUEST_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
struct MHD_Connection;
|
||||
struct MHD_Response;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpBody;
|
||||
class HttpReply;
|
||||
|
||||
|
||||
class HttpRequest
|
||||
{
|
||||
public:
|
||||
enum Method {
|
||||
Unsupported,
|
||||
Options,
|
||||
Get,
|
||||
Put
|
||||
};
|
||||
|
||||
HttpRequest(MHD_Connection *connection, const char *url, const char *method, const char *uploadData, size_t *uploadSize, void **cls);
|
||||
~HttpRequest();
|
||||
|
||||
inline bool isFulfilled() const { return m_fulfilled; }
|
||||
inline bool isRestricted() const { return m_restricted; }
|
||||
inline Method method() const { return m_method; }
|
||||
|
||||
bool match(const char *path) const;
|
||||
bool process(const char *accessToken, bool restricted, xmrig::HttpReply &reply);
|
||||
const char *body() const;
|
||||
int end(const HttpReply &reply);
|
||||
int end(int status, MHD_Response *rsp);
|
||||
|
||||
private:
|
||||
int auth(const char *accessToken);
|
||||
|
||||
bool m_fulfilled;
|
||||
bool m_restricted;
|
||||
const char *m_uploadData;
|
||||
const char *m_url;
|
||||
HttpBody *m_body;
|
||||
Method m_method;
|
||||
MHD_Connection *m_connection;
|
||||
size_t *m_uploadSize;
|
||||
void **m_cls;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __HTTPREQUEST_H__ */
|
148
src/common/api/Httpd.cpp
Normal file
148
src/common/api/Httpd.cpp
Normal file
|
@ -0,0 +1,148 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <microhttpd.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "api/Api.h"
|
||||
#include "common/api/Httpd.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
#include "common/log/Log.h"
|
||||
|
||||
|
||||
Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) :
|
||||
m_idle(true),
|
||||
m_IPv6(IPv6),
|
||||
m_restricted(restricted),
|
||||
m_accessToken(accessToken ? strdup(accessToken) : nullptr),
|
||||
m_port(port),
|
||||
m_daemon(nullptr)
|
||||
{
|
||||
uv_timer_init(uv_default_loop(), &m_timer);
|
||||
m_timer.data = this;
|
||||
}
|
||||
|
||||
|
||||
Httpd::~Httpd()
|
||||
{
|
||||
uv_timer_stop(&m_timer);
|
||||
|
||||
if (m_daemon) {
|
||||
MHD_stop_daemon(m_daemon);
|
||||
}
|
||||
|
||||
delete m_accessToken;
|
||||
}
|
||||
|
||||
|
||||
bool Httpd::start()
|
||||
{
|
||||
if (!m_port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int flags = 0;
|
||||
# if MHD_VERSION >= 0x00093500
|
||||
if (m_IPv6 && MHD_is_feature_supported(MHD_FEATURE_IPv6)) {
|
||||
flags |= MHD_USE_DUAL_STACK;
|
||||
}
|
||||
|
||||
if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
|
||||
flags |= MHD_USE_EPOLL_LINUX_ONLY;
|
||||
}
|
||||
# endif
|
||||
|
||||
m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
|
||||
if (!m_daemon) {
|
||||
LOG_ERR("HTTP Daemon failed to start.");
|
||||
return false;
|
||||
}
|
||||
|
||||
# if MHD_VERSION >= 0x00093900
|
||||
uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval);
|
||||
# else
|
||||
uv_timer_start(&m_timer, Httpd::onTimer, kActiveInterval, kActiveInterval);
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int Httpd::process(xmrig::HttpRequest &req)
|
||||
{
|
||||
xmrig::HttpReply reply;
|
||||
if (!req.process(m_accessToken, m_restricted, reply)) {
|
||||
return req.end(reply);
|
||||
}
|
||||
|
||||
if (!req.isFulfilled()) {
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
Api::exec(req, reply);
|
||||
|
||||
return req.end(reply);
|
||||
}
|
||||
|
||||
|
||||
void Httpd::run()
|
||||
{
|
||||
MHD_run(m_daemon);
|
||||
|
||||
# if MHD_VERSION >= 0x00093900
|
||||
const MHD_DaemonInfo *info = MHD_get_daemon_info(m_daemon, MHD_DAEMON_INFO_CURRENT_CONNECTIONS);
|
||||
if (m_idle && info->num_connections) {
|
||||
uv_timer_set_repeat(&m_timer, kActiveInterval);
|
||||
m_idle = false;
|
||||
}
|
||||
else if (!m_idle && !info->num_connections) {
|
||||
uv_timer_set_repeat(&m_timer, kIdleInterval);
|
||||
m_idle = true;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls)
|
||||
{
|
||||
xmrig::HttpRequest req(connection, url, method, uploadData, uploadSize, con_cls);
|
||||
|
||||
if (req.method() == xmrig::HttpRequest::Options) {
|
||||
return req.end(MHD_HTTP_OK, nullptr);
|
||||
}
|
||||
|
||||
if (req.method() == xmrig::HttpRequest::Unsupported) {
|
||||
return req.end(MHD_HTTP_METHOD_NOT_ALLOWED, nullptr);
|
||||
}
|
||||
|
||||
return static_cast<Httpd*>(cls)->process(req);
|
||||
}
|
||||
|
||||
|
||||
void Httpd::onTimer(uv_timer_t *handle)
|
||||
{
|
||||
static_cast<Httpd*>(handle->data)->run();
|
||||
}
|
|
@ -33,21 +33,38 @@ struct MHD_Daemon;
|
|||
struct MHD_Response;
|
||||
|
||||
|
||||
class UploadCtx;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class HttpRequest;
|
||||
}
|
||||
|
||||
|
||||
class Httpd
|
||||
{
|
||||
public:
|
||||
Httpd(int port, const char *accessToken);
|
||||
Httpd(int port, const char *accessToken, bool IPv6, bool restricted);
|
||||
~Httpd();
|
||||
bool start();
|
||||
|
||||
private:
|
||||
int auth(const char *header);
|
||||
constexpr static const int kIdleInterval = 200;
|
||||
constexpr static const int kActiveInterval = 25;
|
||||
|
||||
static int done(MHD_Connection *connection, int status, MHD_Response *rsp);
|
||||
static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls);
|
||||
int process(xmrig::HttpRequest &req);
|
||||
void run();
|
||||
|
||||
static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls);
|
||||
static void onTimer(uv_timer_t *handle);
|
||||
|
||||
bool m_idle;
|
||||
bool m_IPv6;
|
||||
bool m_restricted;
|
||||
const char *m_accessToken;
|
||||
const int m_port;
|
||||
MHD_Daemon *m_daemon;
|
||||
uv_timer_t m_timer;
|
||||
};
|
||||
|
||||
#endif /* __HTTPD_H__ */
|
343
src/common/config/CommonConfig.cpp
Normal file
343
src/common/config/CommonConfig.cpp
Normal file
|
@ -0,0 +1,343 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "common/config/CommonConfig.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "donate.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
|
||||
|
||||
xmrig::CommonConfig::CommonConfig() :
|
||||
m_adjusted(false),
|
||||
m_apiIPv6(false),
|
||||
m_apiRestricted(true),
|
||||
m_background(false),
|
||||
m_colors(true),
|
||||
m_syslog(false),
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
m_watch(true),
|
||||
# else
|
||||
m_watch(false), // TODO: enable config file watch by default when this feature propertly handled and tested.
|
||||
# endif
|
||||
|
||||
m_apiPort(0),
|
||||
m_donateLevel(kDefaultDonateLevel),
|
||||
m_printTime(60),
|
||||
m_retries(5),
|
||||
m_retryPause(5),
|
||||
m_state(NoneState)
|
||||
{
|
||||
m_pools.push_back(Pool());
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
m_retries = 2;
|
||||
m_retryPause = 1;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
xmrig::CommonConfig::~CommonConfig()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CommonConfig::finalize()
|
||||
{
|
||||
if (m_state == ReadyState) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_state == ErrorState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_algorithm.isValid()) {
|
||||
m_algorithm.setAlgo(CRYPTONIGHT);
|
||||
}
|
||||
|
||||
for (Pool &pool : m_pools) {
|
||||
pool.adjust(m_algorithm.algo());
|
||||
|
||||
if (pool.isValid() && pool.algorithm().isValid()) {
|
||||
m_activePools.push_back(std::move(pool));
|
||||
}
|
||||
}
|
||||
|
||||
m_pools.clear();
|
||||
|
||||
if (m_activePools.empty()) {
|
||||
m_state = ErrorState;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_state = ReadyState;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
|
||||
{
|
||||
switch (key) {
|
||||
case BackgroundKey: /* --background */
|
||||
m_background = enable;
|
||||
break;
|
||||
|
||||
case SyslogKey: /* --syslog */
|
||||
m_syslog = enable;
|
||||
break;
|
||||
|
||||
case KeepAliveKey: /* --keepalive */
|
||||
m_pools.back().setKeepAlive(enable ? Pool::kKeepAliveTimeout : 0);
|
||||
break;
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
case NicehashKey: /* --nicehash */
|
||||
m_pools.back().setNicehash(enable);
|
||||
break;
|
||||
# endif
|
||||
|
||||
case ColorKey: /* --no-color */
|
||||
m_colors = enable;
|
||||
break;
|
||||
|
||||
case WatchKey: /* watch */
|
||||
m_watch = enable;
|
||||
break;
|
||||
|
||||
case ApiIPv6Key: /* ipv6 */
|
||||
m_apiIPv6 = enable;
|
||||
|
||||
case ApiRestrictedKey: /* restricted */
|
||||
m_apiRestricted = enable;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CommonConfig::parseString(int key, const char *arg)
|
||||
{
|
||||
switch (key) {
|
||||
case AlgorithmKey: /* --algo */
|
||||
m_algorithm.parseAlgorithm(arg);
|
||||
break;
|
||||
|
||||
case UserpassKey: /* --userpass */
|
||||
if (!m_pools.back().setUserpass(arg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UrlKey: /* --url */
|
||||
if (m_pools.size() > 1 || m_pools[0].isValid()) {
|
||||
Pool pool(arg);
|
||||
|
||||
if (pool.isValid()) {
|
||||
m_pools.push_back(std::move(pool));
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_pools[0].parse(arg);
|
||||
}
|
||||
|
||||
if (!m_pools.back().isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UserKey: /* --user */
|
||||
m_pools.back().setUser(arg);
|
||||
break;
|
||||
|
||||
case PasswordKey: /* --pass */
|
||||
m_pools.back().setPassword(arg);
|
||||
break;
|
||||
|
||||
case RigIdKey: /* --rig-id */
|
||||
m_pools.back().setRigId(arg);
|
||||
break;
|
||||
|
||||
case VariantKey: /* --variant */
|
||||
m_pools.back().algorithm().parseVariant(arg);
|
||||
break;
|
||||
|
||||
case LogFileKey: /* --log-file */
|
||||
m_logFile = arg;
|
||||
break;
|
||||
|
||||
case ApiAccessTokenKey: /* --api-access-token */
|
||||
m_apiToken = arg;
|
||||
break;
|
||||
|
||||
case ApiWorkerIdKey: /* --api-worker-id */
|
||||
m_apiWorkerId = arg;
|
||||
break;
|
||||
|
||||
case UserAgentKey: /* --user-agent */
|
||||
m_userAgent = arg;
|
||||
break;
|
||||
|
||||
case RetriesKey: /* --retries */
|
||||
case RetryPauseKey: /* --retry-pause */
|
||||
case ApiPort: /* --api-port */
|
||||
case PrintTimeKey: /* --cpu-priority */
|
||||
return parseUint64(key, strtol(arg, nullptr, 10));
|
||||
|
||||
case BackgroundKey: /* --background */
|
||||
case SyslogKey: /* --syslog */
|
||||
case KeepAliveKey: /* --keepalive */
|
||||
case NicehashKey: /* --nicehash */
|
||||
case ApiIPv6Key: /* --api-ipv6 */
|
||||
return parseBoolean(key, true);
|
||||
|
||||
case ColorKey: /* --no-color */
|
||||
case WatchKey: /* --no-watch */
|
||||
case ApiRestrictedKey: /* --api-no-restricted */
|
||||
return parseBoolean(key, false);
|
||||
|
||||
case DonateLevelKey: /* --donate-level */
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
if (strncmp(arg, "minemonero.pro", 14) == 0) {
|
||||
m_donateLevel = 0;
|
||||
return true;
|
||||
}
|
||||
# endif
|
||||
return parseUint64(key, strtol(arg, nullptr, 10));
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg)
|
||||
{
|
||||
return parseInt(key, static_cast<int>(arg));
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CommonConfig::save()
|
||||
{
|
||||
if (m_fileName.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uv_fs_t req;
|
||||
const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName.data(), O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr);
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
rapidjson::Document doc;
|
||||
getJSON(doc);
|
||||
|
||||
FILE *fp = fdopen(fd, "w");
|
||||
|
||||
char buf[4096];
|
||||
rapidjson::FileWriteStream os(fp, buf, sizeof(buf));
|
||||
rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os);
|
||||
doc.Accept(writer);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CommonConfig::setFileName(const char *fileName)
|
||||
{
|
||||
m_fileName = fileName;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CommonConfig::parseInt(int key, int arg)
|
||||
{
|
||||
switch (key) {
|
||||
case RetriesKey: /* --retries */
|
||||
if (arg > 0 && arg <= 1000) {
|
||||
m_retries = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case RetryPauseKey: /* --retry-pause */
|
||||
if (arg > 0 && arg <= 3600) {
|
||||
m_retryPause = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeepAliveKey: /* --keepalive */
|
||||
m_pools.back().setKeepAlive(arg);
|
||||
break;
|
||||
|
||||
case VariantKey: /* --variant */
|
||||
m_pools.back().algorithm().parseVariant(arg);
|
||||
break;
|
||||
|
||||
case DonateLevelKey: /* --donate-level */
|
||||
if (arg >= kMinimumDonateLevel && arg <= 99) {
|
||||
m_donateLevel = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case ApiPort: /* --api-port */
|
||||
if (arg > 0 && arg <= 65536) {
|
||||
m_apiPort = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case PrintTimeKey: /* --print-time */
|
||||
if (arg >= 0 && arg <= 3600) {
|
||||
m_printTime = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
110
src/common/config/CommonConfig.h
Normal file
110
src/common/config/CommonConfig.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __COMMONCONFIG_H__
|
||||
#define __COMMONCONFIG_H__
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "common/net/Pool.h"
|
||||
#include "common/utils/c_str.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "interfaces/IConfig.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class CommonConfig : public IConfig
|
||||
{
|
||||
public:
|
||||
CommonConfig();
|
||||
~CommonConfig();
|
||||
|
||||
inline bool isApiIPv6() const { return m_apiIPv6; }
|
||||
inline bool isApiRestricted() const { return m_apiRestricted; }
|
||||
inline bool isBackground() const { return m_background; }
|
||||
inline bool isColors() const { return m_colors; }
|
||||
inline bool isSyslog() const { return m_syslog; }
|
||||
inline const Algorithm &algorithm() const { return m_algorithm; }
|
||||
inline const char *apiToken() const { return m_apiToken.data(); }
|
||||
inline const char *apiWorkerId() const { return m_apiWorkerId.data(); }
|
||||
inline const char *logFile() const { return m_logFile.data(); }
|
||||
inline const char *userAgent() const { return m_userAgent.data(); }
|
||||
inline const std::vector<Pool> &pools() const { return m_activePools; }
|
||||
inline int apiPort() const { return m_apiPort; }
|
||||
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 void setColors(bool colors) { m_colors = colors; }
|
||||
|
||||
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
|
||||
inline const char *fileName() const override { return m_fileName.data(); }
|
||||
|
||||
protected:
|
||||
enum State {
|
||||
NoneState,
|
||||
ReadyState,
|
||||
ErrorState
|
||||
};
|
||||
|
||||
bool finalize() override;
|
||||
bool parseBoolean(int key, bool enable) override;
|
||||
bool parseString(int key, const char *arg) override;
|
||||
bool parseUint64(int key, uint64_t arg) override;
|
||||
bool save() override;
|
||||
void setFileName(const char *fileName) override;
|
||||
|
||||
Algorithm m_algorithm;
|
||||
bool m_adjusted;
|
||||
bool m_apiIPv6;
|
||||
bool m_apiRestricted;
|
||||
bool m_background;
|
||||
bool m_colors;
|
||||
bool m_syslog;
|
||||
bool m_watch;
|
||||
int m_apiPort;
|
||||
int m_donateLevel;
|
||||
int m_printTime;
|
||||
int m_retries;
|
||||
int m_retryPause;
|
||||
State m_state;
|
||||
std::vector<Pool> m_activePools;
|
||||
std::vector<Pool> m_pools;
|
||||
xmrig::c_str m_apiToken;
|
||||
xmrig::c_str m_apiWorkerId;
|
||||
xmrig::c_str m_fileName;
|
||||
xmrig::c_str m_logFile;
|
||||
xmrig::c_str m_userAgent;
|
||||
|
||||
private:
|
||||
bool parseInt(int key, int arg);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __COMMONCONFIG_H__ */
|
312
src/common/config/ConfigLoader.cpp
Normal file
312
src/common/config/ConfigLoader.cpp
Normal file
|
@ -0,0 +1,312 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_HTTPD
|
||||
# include <microhttpd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "common/config/ConfigWatcher.h"
|
||||
#include "common/net/Pool.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/ConfigCreator.h"
|
||||
#include "core/ConfigLoader_platform.h"
|
||||
#include "interfaces/IConfig.h"
|
||||
#include "interfaces/IWatcherListener.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
#include "rapidjson/filereadstream.h"
|
||||
|
||||
|
||||
xmrig::ConfigWatcher *xmrig::ConfigLoader::m_watcher = nullptr;
|
||||
xmrig::IConfigCreator *xmrig::ConfigLoader::m_creator = nullptr;
|
||||
xmrig::IWatcherListener *xmrig::ConfigLoader::m_listener = nullptr;
|
||||
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::loadFromFile(xmrig::IConfig *config, const char *fileName)
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
if (!getJSON(fileName, doc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
config->setFileName(fileName);
|
||||
|
||||
return loadFromJSON(config, doc);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const char *json)
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
doc.Parse(json);
|
||||
|
||||
if (doc.HasParseError() || !doc.IsObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return loadFromJSON(config, doc);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson::Document &doc)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) {
|
||||
parseJSON(config, &config_options[i], doc);
|
||||
}
|
||||
|
||||
const rapidjson::Value &pools = doc["pools"];
|
||||
if (pools.IsArray()) {
|
||||
for (const rapidjson::Value &value : pools.GetArray()) {
|
||||
if (!value.IsObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(pool_options); i++) {
|
||||
parseJSON(config, &pool_options[i], value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rapidjson::Value &api = doc["api"];
|
||||
if (api.IsObject()) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) {
|
||||
parseJSON(config, &api_options[i], api);
|
||||
}
|
||||
}
|
||||
|
||||
config->parseJSON(doc);
|
||||
|
||||
return config->finalize();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::reload(xmrig::IConfig *oldConfig, const char *json)
|
||||
{
|
||||
xmrig::IConfig *config = m_creator->create();
|
||||
if (!loadFromJSON(config, json)) {
|
||||
delete config;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
config->setFileName(oldConfig->fileName());
|
||||
const bool saved = config->save();
|
||||
|
||||
if (config->isWatch() && m_watcher && saved) {
|
||||
delete config;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
m_listener->onNewConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator *creator, IWatcherListener *listener)
|
||||
{
|
||||
m_creator = creator;
|
||||
m_listener = listener;
|
||||
|
||||
xmrig::IConfig *config = m_creator->create();
|
||||
int key;
|
||||
|
||||
while (1) {
|
||||
key = getopt_long(argc, argv, short_options, options, NULL);
|
||||
if (key < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!parseArg(config, key, optarg)) {
|
||||
delete config;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]);
|
||||
delete config;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!config->finalize()) {
|
||||
delete config;
|
||||
|
||||
config = m_creator->create();
|
||||
loadFromFile(config, Platform::defaultConfigName());
|
||||
}
|
||||
|
||||
if (!config->finalize()) {
|
||||
fprintf(stderr, "No valid configuration found. Exiting.\n");
|
||||
delete config;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (config->isWatch()) {
|
||||
m_watcher = new xmrig::ConfigWatcher(config->fileName(), creator, listener);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigLoader::release()
|
||||
{
|
||||
delete m_watcher;
|
||||
delete m_creator;
|
||||
|
||||
m_watcher = nullptr;
|
||||
m_creator = nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::getJSON(const char *fileName, rapidjson::Document &doc)
|
||||
{
|
||||
uv_fs_t req;
|
||||
const int fd = uv_fs_open(uv_default_loop(), &req, fileName, O_RDONLY, 0644, nullptr);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "unable to open %s: %s\n", fileName, uv_strerror(fd));
|
||||
return false;
|
||||
}
|
||||
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
FILE *fp = fdopen(fd, "rb");
|
||||
char buf[8192];
|
||||
rapidjson::FileReadStream is(fp, buf, sizeof(buf));
|
||||
|
||||
doc.ParseStream(is);
|
||||
|
||||
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
if (doc.HasParseError()) {
|
||||
printf("%s<%d>: %s\n", fileName, (int) doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return doc.IsObject();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::parseArg(xmrig::IConfig *config, int key, const char *arg)
|
||||
{
|
||||
switch (key) {
|
||||
case xmrig::IConfig::VersionKey: /* --version */
|
||||
showVersion();
|
||||
return false;
|
||||
|
||||
case xmrig::IConfig::HelpKey: /* --help */
|
||||
showUsage();
|
||||
return false;
|
||||
|
||||
case xmrig::IConfig::ConfigKey: /* --config */
|
||||
loadFromFile(config, arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
return config->parseString(key, arg);;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigLoader::parseJSON(xmrig::IConfig *config, const struct option *option, const rapidjson::Value &object)
|
||||
{
|
||||
if (!option->name || !object.HasMember(option->name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rapidjson::Value &value = object[option->name];
|
||||
|
||||
if (option->has_arg) {
|
||||
if (value.IsString()) {
|
||||
config->parseString(option->val, value.GetString());
|
||||
}
|
||||
else if (value.IsInt64()) {
|
||||
config->parseUint64(option->val, value.GetUint64());
|
||||
}
|
||||
else if (value.IsBool()) {
|
||||
config->parseBoolean(option->val, value.IsTrue());
|
||||
}
|
||||
}
|
||||
else if (value.IsBool()) {
|
||||
config->parseBoolean(option->val, value.IsTrue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigLoader::showUsage()
|
||||
{
|
||||
printf(usage);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigLoader::showVersion()
|
||||
{
|
||||
printf(APP_NAME " " APP_VERSION "\n built on " __DATE__
|
||||
|
||||
# if defined(__clang__)
|
||||
" with clang " __clang_version__);
|
||||
# elif defined(__GNUC__)
|
||||
" with GCC");
|
||||
printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
|
||||
# elif defined(_MSC_VER)
|
||||
" with MSVC");
|
||||
printf(" %d", MSVC_VERSION);
|
||||
# else
|
||||
);
|
||||
# endif
|
||||
|
||||
printf("\n features:"
|
||||
# if defined(__i386__) || defined(_M_IX86)
|
||||
" 32-bit"
|
||||
# elif defined(__x86_64__) || defined(_M_AMD64)
|
||||
" 64-bit"
|
||||
# endif
|
||||
|
||||
# if defined(__AES__) || defined(_MSC_VER)
|
||||
" AES"
|
||||
# endif
|
||||
"\n");
|
||||
|
||||
printf("\nlibuv/%s\n", uv_version_string());
|
||||
|
||||
# ifndef XMRIG_NO_HTTPD
|
||||
printf("libmicrohttpd/%s\n", MHD_get_version());
|
||||
# endif
|
||||
}
|
71
src/common/config/ConfigLoader.h
Normal file
71
src/common/config/ConfigLoader.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIGLOADER_H__
|
||||
#define __CONFIGLOADER_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
struct option;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ConfigWatcher;
|
||||
class IConfigCreator;
|
||||
class IWatcherListener;
|
||||
class IConfig;
|
||||
|
||||
|
||||
class ConfigLoader
|
||||
{
|
||||
public:
|
||||
static bool loadFromFile(IConfig *config, const char *fileName);
|
||||
static bool loadFromJSON(IConfig *config, const char *json);
|
||||
static bool loadFromJSON(IConfig *config, const rapidjson::Document &doc);
|
||||
static bool reload(IConfig *oldConfig, const char *json);
|
||||
static IConfig *load(int argc, char **argv, IConfigCreator *creator, IWatcherListener *listener);
|
||||
static void release();
|
||||
|
||||
private:
|
||||
static bool getJSON(const char *fileName, rapidjson::Document &doc);
|
||||
static bool parseArg(IConfig *config, int key, const char *arg);
|
||||
static void parseJSON(IConfig *config, const struct option *option, const rapidjson::Value &object);
|
||||
static void showUsage();
|
||||
static void showVersion();
|
||||
|
||||
static ConfigWatcher *m_watcher;
|
||||
static IConfigCreator *m_creator;
|
||||
static IWatcherListener *m_listener;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONFIGLOADER_H__ */
|
105
src/common/config/ConfigWatcher.cpp
Normal file
105
src/common/config/ConfigWatcher.cpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "common/config/ConfigWatcher.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "core/ConfigCreator.h"
|
||||
#include "interfaces/IWatcherListener.h"
|
||||
|
||||
|
||||
xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) :
|
||||
m_creator(creator),
|
||||
m_listener(listener),
|
||||
m_path(path)
|
||||
{
|
||||
uv_fs_event_init(uv_default_loop(), &m_fsEvent);
|
||||
uv_timer_init(uv_default_loop(), &m_timer);
|
||||
|
||||
m_fsEvent.data = m_timer.data = this;
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
xmrig::ConfigWatcher::~ConfigWatcher()
|
||||
{
|
||||
uv_timer_stop(&m_timer);
|
||||
uv_fs_event_stop(&m_fsEvent);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigWatcher::onTimer(uv_timer_t* handle)
|
||||
{
|
||||
static_cast<xmrig::ConfigWatcher *>(handle->data)->reload();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigWatcher::onFsEvent(uv_fs_event_t* handle, const char *filename, int events, int status)
|
||||
{
|
||||
if (!filename) {
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<xmrig::ConfigWatcher *>(handle->data)->queueUpdate();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigWatcher::queueUpdate()
|
||||
{
|
||||
uv_timer_stop(&m_timer);
|
||||
uv_timer_start(&m_timer, xmrig::ConfigWatcher::onTimer, kDelay, 0);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigWatcher::reload()
|
||||
{
|
||||
LOG_WARN("\"%s\" was changed, reloading configuration", m_path.data());
|
||||
|
||||
IConfig *config = m_creator->create();
|
||||
ConfigLoader::loadFromFile(config, m_path.data());
|
||||
|
||||
if (!config->finalize()) {
|
||||
LOG_ERR("reloading failed");
|
||||
|
||||
delete config;
|
||||
return;
|
||||
}
|
||||
|
||||
m_listener->onNewConfig(config);
|
||||
|
||||
# ifndef _WIN32
|
||||
uv_fs_event_stop(&m_fsEvent);
|
||||
start();
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigWatcher::start()
|
||||
{
|
||||
uv_fs_event_start(&m_fsEvent, xmrig::ConfigWatcher::onFsEvent, m_path.data(), 0);
|
||||
}
|
71
src/common/config/ConfigWatcher.h
Normal file
71
src/common/config/ConfigWatcher.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIGWATCHER_H__
|
||||
#define __CONFIGWATCHER_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "common/utils/c_str.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
struct option;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConfigCreator;
|
||||
class IWatcherListener;
|
||||
|
||||
|
||||
class ConfigWatcher
|
||||
{
|
||||
public:
|
||||
ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener);
|
||||
~ConfigWatcher();
|
||||
|
||||
private:
|
||||
constexpr static int kDelay = 500;
|
||||
|
||||
static void onFsEvent(uv_fs_event_t* handle, const char *filename, int events, int status);
|
||||
static void onTimer(uv_timer_t* handle);
|
||||
void queueUpdate();
|
||||
void reload();
|
||||
void start();
|
||||
|
||||
IConfigCreator *m_creator;
|
||||
IWatcherListener *m_listener;
|
||||
uv_fs_event_t m_fsEvent;
|
||||
uv_timer_t m_timer;
|
||||
xmrig::c_str m_path;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONFIGWATCHER_H__ */
|
219
src/common/crypto/Algorithm.cpp
Normal file
219
src/common/crypto/Algorithm.cpp
Normal file
|
@ -0,0 +1,219 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "common/crypto/Algorithm.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define strncasecmp _strnicmp
|
||||
# define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
|
||||
|
||||
struct AlgoData
|
||||
{
|
||||
const char *name;
|
||||
const char *shortName;
|
||||
xmrig::Algo algo;
|
||||
xmrig::Variant variant;
|
||||
};
|
||||
|
||||
|
||||
static AlgoData const algorithms[] = {
|
||||
{ "cryptonight", "cn", xmrig::CRYPTONIGHT, xmrig::VARIANT_AUTO },
|
||||
{ "cryptonight/0", "cn/0", xmrig::CRYPTONIGHT, xmrig::VARIANT_0 },
|
||||
{ "cryptonight/1", "cn/1", xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
|
||||
{ "cryptonight/xtl", "cn/xtl", xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL },
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
{ "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO },
|
||||
{ "cryptonight-lite/0", "cn-lite/0", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 },
|
||||
{ "cryptonight-lite/1", "cn-lite/1", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 },
|
||||
{ "cryptonight-lite/ipbc", "cn-lite/ipbc", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IPBC },
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_SUMO
|
||||
{ "cryptonight-heavy", "cn-heavy", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 },
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef XMRIG_PROXY_PROJECT
|
||||
static AlgoData const xmrStakAlgorithms[] = {
|
||||
{ "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
|
||||
{ "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
|
||||
{ "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL },
|
||||
{ "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 },
|
||||
{ "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 },
|
||||
{ "cryptonight_lite_v7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 },
|
||||
{ "cryptonight_lite_v7_xor", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IPBC },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static const char *variants[] = {
|
||||
"0",
|
||||
"1",
|
||||
"ipbc",
|
||||
"xtl"
|
||||
};
|
||||
|
||||
|
||||
bool xmrig::Algorithm::isValid() const
|
||||
{
|
||||
if (m_algo == INVALID_ALGO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) {
|
||||
if (algorithms[i].algo == m_algo && algorithms[i].variant == m_variant) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Algorithm::variantName() const
|
||||
{
|
||||
if (m_variant == VARIANT_AUTO) {
|
||||
return "auto";
|
||||
}
|
||||
|
||||
return variants[m_variant];
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Algorithm::parseAlgorithm(const char *algo)
|
||||
{
|
||||
m_algo = INVALID_ALGO;
|
||||
m_variant = VARIANT_AUTO;
|
||||
|
||||
assert(algo != nullptr);
|
||||
if (algo == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) {
|
||||
if ((strcasecmp(algo, algorithms[i].name) == 0) || (strcasecmp(algo, algorithms[i].shortName) == 0)) {
|
||||
m_algo = algorithms[i].algo;
|
||||
m_variant = algorithms[i].variant;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_algo == INVALID_ALGO) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Algorithm::parseVariant(const char *variant)
|
||||
{
|
||||
if (m_algo == CRYPTONIGHT_HEAVY) {
|
||||
m_variant = VARIANT_0;
|
||||
return;
|
||||
}
|
||||
|
||||
m_variant = VARIANT_AUTO;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(variants); i++) {
|
||||
if (strcasecmp(variant, variants[i]) == 0) {
|
||||
m_variant = static_cast<Variant>(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Algorithm::parseVariant(int variant)
|
||||
{
|
||||
if (variant >= VARIANT_AUTO && variant <= VARIANT_XTL) {
|
||||
m_variant = static_cast<Variant>(variant);
|
||||
}
|
||||
else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Algorithm::setAlgo(Algo algo)
|
||||
{
|
||||
m_algo = algo;
|
||||
|
||||
if (m_algo == CRYPTONIGHT_HEAVY) {
|
||||
m_variant = VARIANT_0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_PROXY_PROJECT
|
||||
void xmrig::Algorithm::parseXmrStakAlgorithm(const char *algo)
|
||||
{
|
||||
m_algo = INVALID_ALGO;
|
||||
m_variant = VARIANT_AUTO;
|
||||
|
||||
assert(algo != nullptr);
|
||||
if (algo == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(xmrStakAlgorithms); i++) {
|
||||
if (strcasecmp(algo, xmrStakAlgorithms[i].name) == 0) {
|
||||
m_algo = xmrStakAlgorithms[i].algo;
|
||||
m_variant = xmrStakAlgorithms[i].variant;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_algo == INVALID_ALGO) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
const char *xmrig::Algorithm::name(bool shortName) const
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) {
|
||||
if (algorithms[i].algo == m_algo && algorithms[i].variant == m_variant) {
|
||||
return shortName ? algorithms[i].shortName : algorithms[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return "invalid";
|
||||
}
|
91
src/common/crypto/Algorithm.h
Normal file
91
src/common/crypto/Algorithm.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ALGORITHM_H__
|
||||
#define __ALGORITHM_H__
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "common/xmrig.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Algorithm
|
||||
{
|
||||
public:
|
||||
inline Algorithm() :
|
||||
m_algo(INVALID_ALGO),
|
||||
m_variant(VARIANT_AUTO)
|
||||
{}
|
||||
|
||||
inline Algorithm(Algo algo, Variant variant) :
|
||||
m_variant(variant)
|
||||
{
|
||||
setAlgo(algo);
|
||||
}
|
||||
|
||||
inline Algorithm(const char *algo)
|
||||
{
|
||||
parseAlgorithm(algo);
|
||||
}
|
||||
|
||||
bool isEqual(const Algorithm &other) const { return m_algo == other.m_algo && m_variant == other.m_variant; }
|
||||
inline Algo algo() const { return m_algo; }
|
||||
inline const char *name() const { return name(false); }
|
||||
inline const char *shortName() const { return name(true); }
|
||||
inline Variant variant() const { return m_variant; }
|
||||
inline void setVariant(Variant variant) { m_variant = variant; }
|
||||
|
||||
inline bool operator!=(const Algorithm &other) const { return !isEqual(other); }
|
||||
inline bool operator==(const Algorithm &other) const { return isEqual(other); }
|
||||
|
||||
bool isValid() const;
|
||||
const char *variantName() const;
|
||||
void parseAlgorithm(const char *algo);
|
||||
void parseVariant(const char *variant);
|
||||
void parseVariant(int variant);
|
||||
void setAlgo(Algo algo);
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
void parseXmrStakAlgorithm(const char *algo);
|
||||
# endif
|
||||
|
||||
private:
|
||||
const char *name(bool shortName) const;
|
||||
|
||||
Algo m_algo;
|
||||
Variant m_variant;
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<xmrig::Algorithm> Algorithms;
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __ALGORITHM_H__ */
|
|
@ -1,10 +1,35 @@
|
|||
// keccak.c
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
// A baseline Keccak (3rd round) implementation.
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2011 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <memory.h>
|
||||
|
||||
|
||||
#include "common/crypto/keccak.h"
|
||||
|
||||
|
||||
#define HASH_DATA_AREA 136
|
||||
#define KECCAK_ROUNDS 24
|
||||
|
||||
|
@ -26,7 +51,7 @@ const uint64_t keccakf_rndc[24] =
|
|||
|
||||
// update the state with given number of rounds
|
||||
|
||||
void keccakf(uint64_t st[25], int rounds)
|
||||
void xmrig::keccakf(uint64_t st[25], int rounds)
|
||||
{
|
||||
int i, j, round;
|
||||
uint64_t t, bc[5];
|
||||
|
@ -139,7 +164,8 @@ void keccakf(uint64_t st[25], int rounds)
|
|||
// compute a keccak hash (md) of given byte length from "in"
|
||||
typedef uint64_t state_t[25];
|
||||
|
||||
void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen)
|
||||
|
||||
void xmrig::keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen)
|
||||
{
|
||||
state_t st;
|
||||
uint8_t temp[144];
|
||||
|
@ -151,26 +177,24 @@ void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen)
|
|||
memset(st, 0, sizeof(st));
|
||||
|
||||
for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) {
|
||||
for (i = 0; i < rsizw; i++)
|
||||
for (i = 0; i < rsizw; i++) {
|
||||
st[i] ^= ((uint64_t *) in)[i];
|
||||
keccakf(st, KECCAK_ROUNDS);
|
||||
}
|
||||
|
||||
xmrig::keccakf(st, KECCAK_ROUNDS);
|
||||
}
|
||||
|
||||
|
||||
// last block and padding
|
||||
memcpy(temp, in, inlen);
|
||||
temp[inlen++] = 1;
|
||||
memset(temp + inlen, 0, rsiz - inlen);
|
||||
temp[rsiz - 1] |= 0x80;
|
||||
|
||||
for (i = 0; i < rsizw; i++)
|
||||
for (i = 0; i < rsizw; i++) {
|
||||
st[i] ^= ((uint64_t *) temp)[i];
|
||||
}
|
||||
|
||||
keccakf(st, KECCAK_ROUNDS);
|
||||
|
||||
memcpy(md, st, mdlen);
|
||||
}
|
||||
|
||||
void keccak1600(const uint8_t *in, int inlen, uint8_t *md)
|
||||
{
|
||||
keccak(in, inlen, md, sizeof(state_t));
|
||||
}
|
49
src/common/crypto/keccak.h
Normal file
49
src/common/crypto/keccak.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2011 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef KECCAK_H_
|
||||
#define KECCAK_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
// compute a keccak hash (md) of given byte length from "in"
|
||||
void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen);
|
||||
|
||||
|
||||
inline void keccak(const uint8_t *in, size_t inlen, uint8_t *md)
|
||||
{
|
||||
keccak(in, static_cast<int>(inlen), md, 200);
|
||||
}
|
||||
|
||||
// update the state
|
||||
void keccakf(uint64_t st[25], int norounds);
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* KECCAK_H_ */
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -34,18 +34,18 @@
|
|||
#endif
|
||||
|
||||
|
||||
#include "log/ConsoleLog.h"
|
||||
#include "log/Log.h"
|
||||
#include "Options.h"
|
||||
#include "common/log/ConsoleLog.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
|
||||
|
||||
ConsoleLog::ConsoleLog(bool colors) :
|
||||
m_colors(colors),
|
||||
m_stream(nullptr)
|
||||
ConsoleLog::ConsoleLog(xmrig::Controller *controller) :
|
||||
m_stream(nullptr),
|
||||
m_controller(controller)
|
||||
{
|
||||
if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) {
|
||||
Options::i()->setColors(false);
|
||||
m_colors = false;
|
||||
controller->config()->setColors(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,9 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
|
|||
# endif
|
||||
|
||||
const char* color = nullptr;
|
||||
if (m_colors) {
|
||||
const bool colors = m_controller->config()->isColors();
|
||||
|
||||
if (colors) {
|
||||
switch (level) {
|
||||
case Log::ERR:
|
||||
color = Log::kCL_RED;
|
||||
|
@ -109,9 +111,9 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
|
|||
stime.tm_hour,
|
||||
stime.tm_min,
|
||||
stime.tm_sec,
|
||||
m_colors ? color : "",
|
||||
colors ? color : "",
|
||||
fmt,
|
||||
m_colors ? Log::kCL_N : ""
|
||||
colors ? Log::kCL_N : ""
|
||||
);
|
||||
|
||||
print(args);
|
||||
|
@ -120,7 +122,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
|
|||
|
||||
void ConsoleLog::text(const char* fmt, va_list args)
|
||||
{
|
||||
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_colors ? Log::kCL_N : "");
|
||||
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_controller->config()->isColors() ? Log::kCL_N : "");
|
||||
|
||||
print(args);
|
||||
}
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -31,10 +31,15 @@
|
|||
#include "interfaces/ILogBackend.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class ConsoleLog : public ILogBackend
|
||||
{
|
||||
public:
|
||||
ConsoleLog(bool colors);
|
||||
ConsoleLog(xmrig::Controller *controller);
|
||||
|
||||
void message(int level, const char *fmt, va_list args) override;
|
||||
void text(const char *fmt, va_list args) override;
|
||||
|
@ -43,12 +48,12 @@ private:
|
|||
bool isWritable() const;
|
||||
void print(va_list args);
|
||||
|
||||
bool m_colors;
|
||||
char m_buf[512];
|
||||
char m_fmt[256];
|
||||
uv_buf_t m_uvBuf;
|
||||
uv_stream_t *m_stream;
|
||||
uv_tty_t m_tty;
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
||||
#endif /* __CONSOLELOG_H__ */
|
|
@ -29,7 +29,7 @@
|
|||
#include <time.h>
|
||||
|
||||
|
||||
#include "log/FileLog.h"
|
||||
#include "common/log/FileLog.h"
|
||||
|
||||
|
||||
FileLog::FileLog(const char *fileName)
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -29,8 +29,8 @@
|
|||
#include <time.h>
|
||||
|
||||
|
||||
#include "common/log/Log.h"
|
||||
#include "interfaces/ILogBackend.h"
|
||||
#include "log/Log.h"
|
||||
|
||||
|
||||
Log *Log::m_self = nullptr;
|
||||
|
@ -38,6 +38,8 @@ Log *Log::m_self = nullptr;
|
|||
|
||||
void Log::message(Log::Level level, const char* fmt, ...)
|
||||
{
|
||||
uv_mutex_lock(&m_mutex);
|
||||
|
||||
va_list args;
|
||||
va_list copy;
|
||||
va_start(args, fmt);
|
||||
|
@ -49,11 +51,15 @@ void Log::message(Log::Level level, const char* fmt, ...)
|
|||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
|
||||
void Log::text(const char* fmt, ...)
|
||||
{
|
||||
uv_mutex_lock(&m_mutex);
|
||||
|
||||
va_list args;
|
||||
va_list copy;
|
||||
va_start(args, fmt);
|
||||
|
@ -65,6 +71,8 @@ void Log::text(const char* fmt, ...)
|
|||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,6 +25,7 @@
|
|||
#define __LOG_H__
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
|
||||
|
@ -54,23 +55,43 @@ public:
|
|||
constexpr static const char* kCL_GRAY = "\x1B[90m";
|
||||
# endif
|
||||
|
||||
static inline Log* i() { return m_self; }
|
||||
static inline Log* i() { assert(m_self != nullptr); return m_self; }
|
||||
static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); }
|
||||
static inline void init() { if (!m_self) { m_self = new Log();} }
|
||||
static inline void release() { delete m_self; }
|
||||
static inline void init() { if (!m_self) { new Log(); } }
|
||||
static inline void release() { assert(m_self != nullptr); delete m_self; }
|
||||
|
||||
void message(Level level, const char* fmt, ...);
|
||||
void text(const char* fmt, ...);
|
||||
|
||||
private:
|
||||
inline Log() {}
|
||||
inline Log() {
|
||||
assert(m_self == nullptr);
|
||||
|
||||
uv_mutex_init(&m_mutex);
|
||||
|
||||
m_self = this;
|
||||
}
|
||||
|
||||
~Log();
|
||||
|
||||
static Log *m_self;
|
||||
std::vector<ILogBackend*> m_backends;
|
||||
uv_mutex_t m_mutex;
|
||||
};
|
||||
|
||||
|
||||
#define RED_BOLD(x) "\x1B[1;31m" x "\x1B[0m"
|
||||
#define RED(x) "\x1B[0;31m" x "\x1B[0m"
|
||||
#define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m"
|
||||
#define GREEN(x) "\x1B[0;32m" x "\x1B[0m"
|
||||
#define MAGENTA_BOLD(x) "\x1B[1;35m" x "\x1B[0m"
|
||||
#define MAGENTA(x) "\x1B[0;35m" x "\x1B[0m"
|
||||
#define CYAN_BOLD(x) "\x1B[1;36m" x "\x1B[0m"
|
||||
#define CYAN(x) "\x1B[0;36m" x "\x1B[0m"
|
||||
#define WHITE_BOLD(x) "\x1B[1;37m" x "\x1B[0m"
|
||||
#define WHITE(x) "\x1B[0;37m" x "\x1B[0m"
|
||||
|
||||
|
||||
#define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__)
|
||||
#define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__)
|
||||
#define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__)
|
|
@ -25,7 +25,7 @@
|
|||
#include <syslog.h>
|
||||
|
||||
|
||||
#include "log/SysLog.h"
|
||||
#include "common/log/SysLog.h"
|
||||
#include "version.h"
|
||||
|
||||
|
|
@ -29,29 +29,23 @@
|
|||
#include <utility>
|
||||
|
||||
|
||||
#include "common/log/Log.h"
|
||||
#include "common/net/Client.h"
|
||||
#include "interfaces/IClientListener.h"
|
||||
#include "log/Log.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/Url.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "rapidjson/writer.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_PROXY_PROJECT
|
||||
# include "proxy/JobResult.h"
|
||||
#else
|
||||
# include "net/JobResult.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||
#endif
|
||||
|
||||
|
||||
int64_t Client::m_sequence = 1;
|
||||
xmrig::Storage<Client> Client::m_storage;
|
||||
|
||||
|
||||
Client::Client(int id, const char *agent, IClientListener *listener) :
|
||||
|
@ -60,20 +54,26 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
|
|||
m_quiet(false),
|
||||
m_agent(agent),
|
||||
m_listener(listener),
|
||||
m_extensions(0),
|
||||
m_id(id),
|
||||
m_retries(5),
|
||||
m_retryPause(5000),
|
||||
m_failures(0),
|
||||
m_recvBufPos(0),
|
||||
m_state(UnconnectedState),
|
||||
m_expire(0),
|
||||
m_jobs(0),
|
||||
m_keepAlive(0),
|
||||
m_key(0),
|
||||
m_stream(nullptr),
|
||||
m_socket(nullptr)
|
||||
{
|
||||
m_key = m_storage.add(this);
|
||||
|
||||
memset(m_ip, 0, sizeof(m_ip));
|
||||
memset(&m_hints, 0, sizeof(m_hints));
|
||||
|
||||
m_resolver.data = this;
|
||||
m_resolver.data = m_storage.ptr(m_key);
|
||||
|
||||
m_hints.ai_family = AF_UNSPEC;
|
||||
m_hints.ai_socktype = SOCK_STREAM;
|
||||
|
@ -81,11 +81,6 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
|
|||
|
||||
m_recvBuf.base = m_buf;
|
||||
m_recvBuf.len = sizeof(m_buf);
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
m_keepAliveTimer.data = this;
|
||||
uv_timer_init(uv_default_loop(), &m_keepAliveTimer);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,7 +92,7 @@ Client::~Client()
|
|||
|
||||
void Client::connect()
|
||||
{
|
||||
resolve(m_url.host());
|
||||
resolve(m_pool.host());
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,10 +101,10 @@ void Client::connect()
|
|||
*
|
||||
* @param url
|
||||
*/
|
||||
void Client::connect(const Url *url)
|
||||
void Client::connect(const Pool &url)
|
||||
{
|
||||
setUrl(url);
|
||||
resolve(m_url.host());
|
||||
setPool(url);
|
||||
connect();
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,34 +117,34 @@ void Client::deleteLater()
|
|||
m_listener = nullptr;
|
||||
|
||||
if (!disconnect()) {
|
||||
delete this;
|
||||
m_storage.remove(m_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::setUrl(const Url *url)
|
||||
void Client::setPool(const Pool &pool)
|
||||
{
|
||||
if (!url || !url->isValid()) {
|
||||
if (!pool.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_url = url;
|
||||
m_pool = pool;
|
||||
}
|
||||
|
||||
|
||||
void Client::tick(uint64_t now)
|
||||
{
|
||||
if (m_expire == 0 || now < m_expire) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_state == ConnectedState) {
|
||||
LOG_DEBUG_ERR("[%s:%u] timeout", m_url.host(), m_url.port());
|
||||
close();
|
||||
if (m_expire && now > m_expire) {
|
||||
LOG_DEBUG_ERR("[%s] timeout", m_pool.url());
|
||||
close();
|
||||
}
|
||||
else if (m_keepAlive && now > m_keepAlive) {
|
||||
ping();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_state == ConnectingState) {
|
||||
if (m_expire && now > m_expire && m_state == ConnectingState) {
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
@ -157,12 +152,9 @@ void Client::tick(uint64_t now)
|
|||
|
||||
bool Client::disconnect()
|
||||
{
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
uv_timer_stop(&m_keepAliveTimer);
|
||||
# endif
|
||||
|
||||
m_expire = 0;
|
||||
m_failures = -1;
|
||||
m_keepAlive = 0;
|
||||
m_expire = 0;
|
||||
m_failures = -1;
|
||||
|
||||
return close();
|
||||
}
|
||||
|
@ -170,12 +162,14 @@ bool Client::disconnect()
|
|||
|
||||
int64_t Client::submit(const JobResult &result)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
const char *nonce = result.nonce;
|
||||
const char *data = result.result;
|
||||
# else
|
||||
char nonce[9];
|
||||
char data[65];
|
||||
char *nonce = m_sendBuf;
|
||||
char *data = m_sendBuf + 16;
|
||||
|
||||
Job::toHex(reinterpret_cast<const unsigned char*>(&result.nonce), 4, nonce);
|
||||
nonce[8] = '\0';
|
||||
|
@ -184,8 +178,24 @@ int64_t Client::submit(const JobResult &result)
|
|||
data[64] = '\0';
|
||||
# endif
|
||||
|
||||
const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRIu64 ",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
|
||||
m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data);
|
||||
Document doc(kObjectType);
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
doc.AddMember("id", m_sequence, allocator);
|
||||
doc.AddMember("jsonrpc", "2.0", allocator);
|
||||
doc.AddMember("method", "submit", allocator);
|
||||
|
||||
Value params(kObjectType);
|
||||
params.AddMember("id", StringRef(m_rpcId.data()), allocator);
|
||||
params.AddMember("job_id", StringRef(result.jobId.data()), allocator);
|
||||
params.AddMember("nonce", StringRef(nonce), allocator);
|
||||
params.AddMember("result", StringRef(data), allocator);
|
||||
|
||||
if (m_extensions & AlgoExt) {
|
||||
params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("params", params, allocator);
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
|
||||
|
@ -193,7 +203,7 @@ int64_t Client::submit(const JobResult &result)
|
|||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
|
||||
# endif
|
||||
|
||||
return send(size);
|
||||
return send(doc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -242,13 +252,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
return false;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
Job job(m_id, m_url.variant());
|
||||
job.setClientId(m_rpcId);
|
||||
job.setCoin(m_url.coin());
|
||||
# else
|
||||
Job job(m_id, m_nicehash, m_url.algo(), m_url.variant());
|
||||
# endif
|
||||
Job job(m_id, m_nicehash, m_pool.algorithm(), m_rpcId);
|
||||
|
||||
if (!job.setId(params["job_id"].GetString())) {
|
||||
*code = 3;
|
||||
|
@ -265,12 +269,26 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (params.HasMember("coin")) {
|
||||
job.setCoin(params["coin"].GetString());
|
||||
if (params.HasMember("algo")) {
|
||||
job.algorithm().parseAlgorithm(params["algo"].GetString());
|
||||
}
|
||||
|
||||
if (params.HasMember("variant")) {
|
||||
job.setVariant(params["variant"].GetInt());
|
||||
const rapidjson::Value &variant = params["variant"];
|
||||
|
||||
if (variant.IsInt()) {
|
||||
job.algorithm().parseVariant(variant.GetInt());
|
||||
}
|
||||
else if (variant.IsString()){
|
||||
job.algorithm().parseVariant(variant.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
if (!verifyAlgorithm(job.algorithm())) {
|
||||
*code = 6;
|
||||
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_job != job) {
|
||||
|
@ -283,8 +301,8 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!m_quiet) {
|
||||
LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
|
||||
if (!isQuiet()) {
|
||||
LOG_WARN("[%s] duplicate job received, reconnect", m_pool.url());
|
||||
}
|
||||
|
||||
close();
|
||||
|
@ -299,9 +317,7 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code)
|
|||
return false;
|
||||
}
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
m_nicehash = m_url.isNicehash();
|
||||
# endif
|
||||
m_nicehash = m_pool.isNicehash();
|
||||
|
||||
if (result.HasMember("extensions")) {
|
||||
parseExtensions(result["extensions"]);
|
||||
|
@ -314,6 +330,27 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code)
|
|||
}
|
||||
|
||||
|
||||
bool Client::verifyAlgorithm(const xmrig::Algorithm &algorithm) const
|
||||
{
|
||||
if (m_pool.isCompatible(algorithm)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isQuiet()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (algorithm.isValid()) {
|
||||
LOG_ERR("Incompatible algorithm \"%s\" detected, reconnect", algorithm.name());
|
||||
}
|
||||
else {
|
||||
LOG_ERR("Unknown/unsupported algorithm detected, reconnect");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int Client::resolve(const char *host)
|
||||
{
|
||||
setState(HostLookupState);
|
||||
|
@ -327,8 +364,8 @@ int Client::resolve(const char *host)
|
|||
|
||||
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, nullptr, &m_hints);
|
||||
if (r) {
|
||||
if (!m_quiet) {
|
||||
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r));
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_pool.port(), uv_strerror(r));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -337,11 +374,32 @@ int Client::resolve(const char *host)
|
|||
}
|
||||
|
||||
|
||||
int64_t Client::send(const rapidjson::Document &doc)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
StringBuffer buffer(0, 512);
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
doc.Accept(writer);
|
||||
|
||||
const size_t size = buffer.GetSize();
|
||||
if (size > (sizeof(m_buf) - 2)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(m_sendBuf, buffer.GetString(), size);
|
||||
m_sendBuf[size] = '\n';
|
||||
m_sendBuf[size + 1] = '\0';
|
||||
|
||||
return send(size + 1);
|
||||
}
|
||||
|
||||
|
||||
int64_t Client::send(size_t size)
|
||||
{
|
||||
LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), size, m_sendBuf);
|
||||
LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf);
|
||||
if (state() != ConnectedState || !uv_is_writable(m_stream)) {
|
||||
LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state);
|
||||
LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -379,14 +437,14 @@ void Client::connect(sockaddr *addr)
|
|||
{
|
||||
setState(ConnectingState);
|
||||
|
||||
reinterpret_cast<struct sockaddr_in*>(addr)->sin_port = htons(m_url.port());
|
||||
reinterpret_cast<sockaddr_in*>(addr)->sin_port = htons(m_pool.port());
|
||||
delete m_socket;
|
||||
|
||||
uv_connect_t *req = new uv_connect_t;
|
||||
req->data = this;
|
||||
req->data = m_storage.ptr(m_key);
|
||||
|
||||
m_socket = new uv_tcp_t;
|
||||
m_socket->data = this;
|
||||
m_socket->data = m_storage.ptr(m_key);
|
||||
|
||||
uv_tcp_init(uv_default_loop(), m_socket);
|
||||
uv_tcp_nodelay(m_socket, 1);
|
||||
|
@ -401,38 +459,35 @@ void Client::connect(sockaddr *addr)
|
|||
|
||||
void Client::login()
|
||||
{
|
||||
using namespace rapidjson;
|
||||
m_results.clear();
|
||||
|
||||
rapidjson::Document doc;
|
||||
doc.SetObject();
|
||||
|
||||
Document doc(kObjectType);
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
doc.AddMember("id", 1, allocator);
|
||||
doc.AddMember("jsonrpc", "2.0", allocator);
|
||||
doc.AddMember("method", "login", allocator);
|
||||
|
||||
rapidjson::Value params(rapidjson::kObjectType);
|
||||
params.AddMember("login", rapidjson::StringRef(m_url.user()), allocator);
|
||||
params.AddMember("pass", rapidjson::StringRef(m_url.password()), allocator);
|
||||
params.AddMember("agent", rapidjson::StringRef(m_agent), allocator);
|
||||
Value params(kObjectType);
|
||||
params.AddMember("login", StringRef(m_pool.user()), allocator);
|
||||
params.AddMember("pass", StringRef(m_pool.password()), allocator);
|
||||
params.AddMember("agent", StringRef(m_agent), allocator);
|
||||
|
||||
doc.AddMember("params", params, allocator);
|
||||
|
||||
rapidjson::StringBuffer buffer(0, 512);
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
doc.Accept(writer);
|
||||
|
||||
const size_t size = buffer.GetSize();
|
||||
if (size > (sizeof(m_buf) - 2)) {
|
||||
return;
|
||||
if (m_pool.rigId()) {
|
||||
params.AddMember("rigid", StringRef(m_pool.rigId()), allocator);
|
||||
}
|
||||
|
||||
memcpy(m_sendBuf, buffer.GetString(), size);
|
||||
m_sendBuf[size] = '\n';
|
||||
m_sendBuf[size + 1] = '\0';
|
||||
Value algo(kArrayType);
|
||||
|
||||
send(size + 1);
|
||||
for (const auto &a : m_pool.algorithms()) {
|
||||
algo.PushBack(StringRef(a.shortName()), allocator);
|
||||
}
|
||||
|
||||
params.AddMember("algo", algo, allocator);
|
||||
doc.AddMember("params", params, allocator);
|
||||
|
||||
send(doc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -454,11 +509,11 @@ void Client::parse(char *line, size_t len)
|
|||
|
||||
line[len - 1] = '\0';
|
||||
|
||||
LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
|
||||
LOG_DEBUG("[%s] received (%d bytes): \"%s\"", m_pool.url(), len, line);
|
||||
|
||||
if (len < 32 || line[0] != '{') {
|
||||
if (!m_quiet) {
|
||||
LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port());
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] JSON decode failed", m_pool.url());
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -466,8 +521,8 @@ void Client::parse(char *line, size_t len)
|
|||
|
||||
rapidjson::Document doc;
|
||||
if (doc.ParseInsitu(line).HasParseError()) {
|
||||
if (!m_quiet) {
|
||||
LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] JSON decode failed: \"%s\"", m_pool.url(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -489,6 +544,8 @@ void Client::parse(char *line, size_t len)
|
|||
|
||||
void Client::parseExtensions(const rapidjson::Value &value)
|
||||
{
|
||||
m_extensions = 0;
|
||||
|
||||
if (!value.IsArray()) {
|
||||
return;
|
||||
}
|
||||
|
@ -498,8 +555,15 @@ void Client::parseExtensions(const rapidjson::Value &value)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(ext.GetString(), "algo") == 0) {
|
||||
m_extensions |= AlgoExt;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(ext.GetString(), "nicehash") == 0) {
|
||||
m_extensions |= NicehashExt;
|
||||
m_nicehash = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -508,8 +572,8 @@ void Client::parseExtensions(const rapidjson::Value &value)
|
|||
void Client::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error)
|
||||
{
|
||||
if (error.IsObject()) {
|
||||
if (!m_quiet) {
|
||||
LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), error["message"].GetString(), error["code"].GetInt());
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), error["message"].GetString(), error["code"].GetInt());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -527,7 +591,7 @@ void Client::parseNotification(const char *method, const rapidjson::Value ¶m
|
|||
return;
|
||||
}
|
||||
|
||||
LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_url.host(), m_url.port(), method);
|
||||
LOG_WARN("[%s] unsupported method: \"%s\"", m_pool.url(), method);
|
||||
}
|
||||
|
||||
|
||||
|
@ -542,11 +606,11 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
|
|||
m_listener->onResultAccepted(this, it->second, message);
|
||||
m_results.erase(it);
|
||||
}
|
||||
else if (!m_quiet) {
|
||||
LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), message, error["code"].GetInt());
|
||||
else if (!isQuiet()) {
|
||||
LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), message, error["code"].GetInt());
|
||||
}
|
||||
|
||||
if (id == 1 || isCriticalError(message)) {
|
||||
if (isCriticalError(message)) {
|
||||
close();
|
||||
}
|
||||
|
||||
|
@ -560,8 +624,8 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
|
|||
if (id == 1) {
|
||||
int code = -1;
|
||||
if (!parseLogin(result, &code)) {
|
||||
if (!m_quiet) {
|
||||
LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code);
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] login error code: %d", m_pool.url(), code);
|
||||
}
|
||||
|
||||
close();
|
||||
|
@ -592,18 +656,13 @@ void Client::ping()
|
|||
void Client::reconnect()
|
||||
{
|
||||
if (!m_listener) {
|
||||
delete this;
|
||||
m_storage.remove(m_key);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setState(ConnectingState);
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
if (m_url.isKeepAlive()) {
|
||||
uv_timer_stop(&m_keepAliveTimer);
|
||||
}
|
||||
# endif
|
||||
m_keepAlive = 0;
|
||||
|
||||
if (m_failures == -1) {
|
||||
return m_listener->onClose(this, -1);
|
||||
|
@ -618,7 +677,7 @@ void Client::reconnect()
|
|||
|
||||
void Client::setState(SocketState state)
|
||||
{
|
||||
LOG_DEBUG("[%s:%u] state: %d", m_url.host(), m_url.port(), state);
|
||||
LOG_DEBUG("[%s] state: %d", m_pool.url(), state);
|
||||
|
||||
if (m_state == state) {
|
||||
return;
|
||||
|
@ -632,13 +691,9 @@ void Client::startTimeout()
|
|||
{
|
||||
m_expire = 0;
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
if (!m_url.isKeepAlive()) {
|
||||
return;
|
||||
if (m_pool.keepAlive()) {
|
||||
m_keepAlive = uv_now(uv_default_loop()) + (m_pool.keepAlive() * 1000);
|
||||
}
|
||||
|
||||
uv_timer_start(&m_keepAliveTimer, [](uv_timer_t *handle) { getClient(handle->data)->ping(); }, kKeepAliveTimeout, 0);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -669,12 +724,13 @@ void Client::onConnect(uv_connect_t *req, int status)
|
|||
{
|
||||
auto client = getClient(req->data);
|
||||
if (!client) {
|
||||
delete req;
|
||||
return;
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
if (!client->m_quiet) {
|
||||
LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
|
||||
if (!client->isQuiet()) {
|
||||
LOG_ERR("[%s] connect error: \"%s\"", client->m_pool.url(), uv_strerror(status));
|
||||
}
|
||||
|
||||
delete req;
|
||||
|
@ -701,8 +757,8 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
|||
}
|
||||
|
||||
if (nread < 0) {
|
||||
if (nread != UV_EOF && !client->m_quiet) {
|
||||
LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror((int) nread));
|
||||
if (nread != UV_EOF && !client->isQuiet()) {
|
||||
LOG_ERR("[%s] read error: \"%s\"", client->m_pool.url(), uv_strerror((int) nread));
|
||||
}
|
||||
|
||||
client->close();
|
||||
|
@ -714,6 +770,11 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
|||
return;
|
||||
}
|
||||
|
||||
assert(client->m_listener != nullptr);
|
||||
if (!client->m_listener) {
|
||||
return client->reconnect();
|
||||
}
|
||||
|
||||
client->m_recvBufPos += nread;
|
||||
|
||||
char* end;
|
||||
|
@ -750,9 +811,14 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
|
|||
return;
|
||||
}
|
||||
|
||||
assert(client->m_listener != nullptr);
|
||||
if (!client->m_listener) {
|
||||
return client->reconnect();
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
if (!client->m_quiet) {
|
||||
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
|
||||
if (!client->isQuiet()) {
|
||||
LOG_ERR("[%s] DNS error: \"%s\"", client->m_pool.url(), uv_strerror(status));
|
||||
}
|
||||
|
||||
return client->reconnect();
|
||||
|
@ -775,8 +841,8 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
|
|||
}
|
||||
|
||||
if (ipv4.empty() && ipv6.empty()) {
|
||||
if (!client->m_quiet) {
|
||||
LOG_ERR("[%s:%u] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_url.host(), client->m_url.port());
|
||||
if (!client->isQuiet()) {
|
||||
LOG_ERR("[%s] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_pool.url());
|
||||
}
|
||||
|
||||
uv_freeaddrinfo(res);
|
|
@ -30,10 +30,11 @@
|
|||
#include <vector>
|
||||
|
||||
|
||||
#include "net/Id.h"
|
||||
#include "net/Job.h"
|
||||
#include "net/SubmitResult.h"
|
||||
#include "net/Url.h"
|
||||
#include "common/net/Id.h"
|
||||
#include "common/net/Job.h"
|
||||
#include "common/net/Pool.h"
|
||||
#include "common/net/Storage.h"
|
||||
#include "common/net/SubmitResult.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
|
@ -53,36 +54,42 @@ public:
|
|||
};
|
||||
|
||||
constexpr static int kResponseTimeout = 20 * 1000;
|
||||
constexpr static int kKeepAliveTimeout = 60 * 1000;
|
||||
|
||||
Client(int id, const char *agent, IClientListener *listener);
|
||||
~Client();
|
||||
|
||||
bool disconnect();
|
||||
int64_t submit(const JobResult &result);
|
||||
void connect();
|
||||
void connect(const Url *url);
|
||||
void connect(const Pool &pool);
|
||||
void deleteLater();
|
||||
void setUrl(const Url *url);
|
||||
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_url.host(); }
|
||||
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_url.port(); }
|
||||
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; }
|
||||
|
||||
private:
|
||||
~Client();
|
||||
enum Extensions {
|
||||
NicehashExt = 1,
|
||||
AlgoExt = 2
|
||||
};
|
||||
|
||||
bool close();
|
||||
bool isCriticalError(const char *message);
|
||||
bool parseJob(const rapidjson::Value ¶ms, int *code);
|
||||
bool parseLogin(const rapidjson::Value &result, int *code);
|
||||
bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const;
|
||||
int resolve(const char *host);
|
||||
int64_t send(const rapidjson::Document &doc);
|
||||
int64_t send(size_t size);
|
||||
void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6);
|
||||
void connect(sockaddr *addr);
|
||||
|
@ -97,13 +104,15 @@ private:
|
|||
void setState(SocketState state);
|
||||
void startTimeout();
|
||||
|
||||
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
|
||||
|
||||
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
|
||||
static void onClose(uv_handle_t *handle);
|
||||
static void onConnect(uv_connect_t *req, int status);
|
||||
static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
|
||||
static void onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res);
|
||||
|
||||
static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
|
||||
static inline Client *getClient(void *data) { return m_storage.get(data); }
|
||||
|
||||
addrinfo m_hints;
|
||||
bool m_ipv6;
|
||||
|
@ -114,26 +123,28 @@ private:
|
|||
char m_sendBuf[768];
|
||||
const char *m_agent;
|
||||
IClientListener *m_listener;
|
||||
int m_extensions;
|
||||
int m_id;
|
||||
int m_retries;
|
||||
int m_retryPause;
|
||||
int64_t m_failures;
|
||||
Job m_job;
|
||||
Pool m_pool;
|
||||
size_t m_recvBufPos;
|
||||
SocketState m_state;
|
||||
static int64_t m_sequence;
|
||||
std::map<int64_t, SubmitResult> m_results;
|
||||
uint64_t m_expire;
|
||||
uint64_t m_jobs;
|
||||
Url m_url;
|
||||
uint64_t m_keepAlive;
|
||||
uintptr_t m_key;
|
||||
uv_buf_t m_recvBuf;
|
||||
uv_getaddrinfo_t m_resolver;
|
||||
uv_stream_t *m_stream;
|
||||
uv_tcp_t *m_socket;
|
||||
xmrig::Id m_rpcId;
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
uv_timer_t m_keepAliveTimer;
|
||||
# endif
|
||||
static int64_t m_sequence;
|
||||
static xmrig::Storage<Client> m_storage;
|
||||
};
|
||||
|
||||
|
|
@ -23,10 +23,11 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "net/Job.h"
|
||||
#include "common/net/Job.h"
|
||||
|
||||
|
||||
static inline unsigned char hf_hex2bin(char c, bool &err)
|
||||
|
@ -58,11 +59,8 @@ static inline char hf_bin2hex(unsigned char c)
|
|||
|
||||
Job::Job() :
|
||||
m_nicehash(false),
|
||||
m_coin(),
|
||||
m_algo(xmrig::ALGO_CRYPTONIGHT),
|
||||
m_poolId(-2),
|
||||
m_threadId(-1),
|
||||
m_variant(xmrig::VARIANT_AUTO),
|
||||
m_size(0),
|
||||
m_diff(0),
|
||||
m_target(0),
|
||||
|
@ -71,17 +69,16 @@ Job::Job() :
|
|||
}
|
||||
|
||||
|
||||
Job::Job(int poolId, bool nicehash, int algo, int variant) :
|
||||
Job::Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId) :
|
||||
m_nicehash(nicehash),
|
||||
m_coin(),
|
||||
m_algo(algo),
|
||||
m_poolId(poolId),
|
||||
m_threadId(-1),
|
||||
m_variant(variant),
|
||||
m_size(0),
|
||||
m_diff(0),
|
||||
m_target(0),
|
||||
m_blob()
|
||||
m_blob(),
|
||||
m_algorithm(algorithm),
|
||||
m_clientId(clientId)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -115,6 +112,11 @@ bool Job::setBlob(const char *blob)
|
|||
m_nicehash = true;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
memset(m_rawBlob, 0, sizeof(m_rawBlob));
|
||||
memcpy(m_rawBlob, blob, m_size * 2);
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -151,35 +153,35 @@ bool Job::setTarget(const char *target)
|
|||
return false;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
memset(m_rawTarget, 0, sizeof(m_rawTarget));
|
||||
memcpy(m_rawTarget, target, len);
|
||||
# endif
|
||||
|
||||
m_diff = toDiff(m_target);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Job::setCoin(const char *coin)
|
||||
xmrig::Variant Job::variant() const
|
||||
{
|
||||
if (!coin || strlen(coin) > 4) {
|
||||
memset(m_coin, 0, sizeof(m_coin));
|
||||
return;
|
||||
if (m_algorithm.algo() == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
return xmrig::VARIANT_0;
|
||||
}
|
||||
|
||||
strncpy(m_coin, coin, sizeof(m_coin));
|
||||
m_algo = strcmp(m_coin, "AEON") == 0 ? xmrig::ALGO_CRYPTONIGHT_LITE : xmrig::ALGO_CRYPTONIGHT;
|
||||
}
|
||||
|
||||
|
||||
void Job::setVariant(int variant)
|
||||
{
|
||||
switch (variant) {
|
||||
case xmrig::VARIANT_AUTO:
|
||||
case xmrig::VARIANT_NONE:
|
||||
case xmrig::VARIANT_V1:
|
||||
m_variant = variant;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
if (m_algorithm.variant() == xmrig::VARIANT_XTL && m_blob[0] < 4) {
|
||||
return xmrig::VARIANT_1;
|
||||
}
|
||||
|
||||
if (m_algorithm.variant() == xmrig::VARIANT_AUTO) {
|
||||
if (m_algorithm.algo() == xmrig::CRYPTONIGHT) {
|
||||
return xmrig::VARIANT_1;
|
||||
}
|
||||
|
||||
return (m_blob[0] > 6 ? xmrig::VARIANT_1 : xmrig::VARIANT_0);
|
||||
}
|
||||
|
||||
return m_algorithm.variant();
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,6 +208,17 @@ void Job::toHex(const unsigned char* in, unsigned int len, char* out)
|
|||
}
|
||||
|
||||
|
||||
#ifdef APP_DEBUG
|
||||
char *Job::toHex(const unsigned char* in, unsigned int len)
|
||||
{
|
||||
char *out = new char[len * 2 + 1]();
|
||||
toHex(in, len, out);
|
||||
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool Job::operator==(const Job &other) const
|
||||
{
|
||||
return m_id == other.m_id && memcmp(m_blob, other.m_blob, sizeof(m_blob)) == 0;
|
|
@ -30,60 +30,74 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "net/Id.h"
|
||||
#include "xmrig.h"
|
||||
#include "common/crypto/Algorithm.h"
|
||||
#include "common/net/Id.h"
|
||||
|
||||
|
||||
class Job
|
||||
{
|
||||
public:
|
||||
Job();
|
||||
Job(int poolId, bool nicehash, int algo, int variant);
|
||||
Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId);
|
||||
~Job();
|
||||
|
||||
bool setBlob(const char *blob);
|
||||
bool setTarget(const char *target);
|
||||
void setCoin(const char *coin);
|
||||
void setVariant(int variant);
|
||||
xmrig::Variant variant() const;
|
||||
|
||||
inline bool isNicehash() const { return m_nicehash; }
|
||||
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
|
||||
inline bool setId(const char *id) { return m_id.setId(id); }
|
||||
inline const char *coin() const { return m_coin; }
|
||||
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
|
||||
inline const uint8_t *blob() const { return m_blob; }
|
||||
inline const xmrig::Id &id() const { return m_id; }
|
||||
inline int poolId() const { return m_poolId; }
|
||||
inline int threadId() const { return m_threadId; }
|
||||
inline int variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? 1 : 0) : m_variant); }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
|
||||
inline uint32_t diff() const { return (uint32_t) m_diff; }
|
||||
inline uint64_t target() const { return m_target; }
|
||||
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
|
||||
inline void setPoolId(int poolId) { m_poolId = poolId; }
|
||||
inline void setThreadId(int threadId) { m_threadId = threadId; }
|
||||
inline bool isNicehash() const { return m_nicehash; }
|
||||
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
|
||||
inline bool setId(const char *id) { return m_id.setId(id); }
|
||||
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
|
||||
inline const uint8_t *blob() const { return m_blob; }
|
||||
inline const xmrig::Algorithm &algorithm() const { return m_algorithm; }
|
||||
inline const xmrig::Id &clientId() const { return m_clientId; }
|
||||
inline const xmrig::Id &id() const { return m_id; }
|
||||
inline int poolId() const { return m_poolId; }
|
||||
inline int threadId() const { return m_threadId; }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
|
||||
inline uint32_t diff() const { return static_cast<uint32_t>(m_diff); }
|
||||
inline uint64_t target() const { return m_target; }
|
||||
inline void reset() { m_size = 0; m_diff = 0; }
|
||||
inline void setClientId(const xmrig::Id &id) { m_clientId = id; }
|
||||
inline void setPoolId(int poolId) { m_poolId = poolId; }
|
||||
inline void setThreadId(int threadId) { m_threadId = threadId; }
|
||||
inline xmrig::Algorithm &algorithm() { return m_algorithm; }
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
inline char *rawBlob() { return m_rawBlob; }
|
||||
inline const char *rawTarget() const { return m_rawTarget; }
|
||||
# endif
|
||||
|
||||
static bool fromHex(const char* in, unsigned int len, unsigned char* out);
|
||||
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
|
||||
static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; }
|
||||
static void toHex(const unsigned char* in, unsigned int len, char* out);
|
||||
|
||||
# ifdef APP_DEBUG
|
||||
static char *toHex(const unsigned char* in, unsigned int len);
|
||||
# endif
|
||||
|
||||
bool operator==(const Job &other) const;
|
||||
bool operator!=(const Job &other) const;
|
||||
|
||||
private:
|
||||
bool m_nicehash;
|
||||
char m_coin[5];
|
||||
int m_algo;
|
||||
int m_poolId;
|
||||
int m_threadId;
|
||||
int m_variant;
|
||||
size_t m_size;
|
||||
uint64_t m_diff;
|
||||
uint64_t m_target;
|
||||
uint8_t m_blob[96]; // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
|
||||
xmrig::Algorithm m_algorithm;
|
||||
xmrig::Id m_clientId;
|
||||
xmrig::Id m_id;
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
char m_rawBlob[176];
|
||||
char m_rawTarget[24];
|
||||
# endif
|
||||
};
|
||||
|
||||
#endif /* __JOB_H__ */
|
307
src/common/net/Pool.cpp
Normal file
307
src/common/net/Pool.cpp
Normal file
|
@ -0,0 +1,307 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "common/net/Pool.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
#ifdef APP_DEBUG
|
||||
# include "common/log/Log.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define strncasecmp _strnicmp
|
||||
# define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
|
||||
Pool::Pool() :
|
||||
m_nicehash(false),
|
||||
m_keepAlive(0),
|
||||
m_port(kDefaultPort)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Parse url.
|
||||
*
|
||||
* Valid urls:
|
||||
* example.com
|
||||
* example.com:3333
|
||||
* stratum+tcp://example.com
|
||||
* stratum+tcp://example.com:3333
|
||||
*
|
||||
* @param url
|
||||
*/
|
||||
Pool::Pool(const char *url) :
|
||||
m_nicehash(false),
|
||||
m_keepAlive(0),
|
||||
m_port(kDefaultPort)
|
||||
{
|
||||
parse(url);
|
||||
}
|
||||
|
||||
|
||||
Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash) :
|
||||
m_nicehash(nicehash),
|
||||
m_keepAlive(keepAlive),
|
||||
m_port(port),
|
||||
m_host(host),
|
||||
m_password(password),
|
||||
m_user(user)
|
||||
{
|
||||
const size_t size = m_host.size() + 8;
|
||||
assert(size > 8);
|
||||
|
||||
char *url = new char[size]();
|
||||
snprintf(url, size - 1, "%s:%d", m_host.data(), m_port);
|
||||
|
||||
m_url = url;
|
||||
}
|
||||
|
||||
|
||||
bool Pool::isCompatible(const xmrig::Algorithm &algorithm) const
|
||||
{
|
||||
for (const auto &a : m_algorithms) {
|
||||
if (algorithm == a) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Pool::isEqual(const Pool &other) const
|
||||
{
|
||||
return (m_nicehash == other.m_nicehash
|
||||
&& m_keepAlive == other.m_keepAlive
|
||||
&& m_port == other.m_port
|
||||
&& m_algorithm == other.m_algorithm
|
||||
&& m_host == other.m_host
|
||||
&& m_password == other.m_password
|
||||
&& m_rigId == other.m_rigId
|
||||
&& m_url == other.m_url
|
||||
&& m_user == other.m_user);
|
||||
}
|
||||
|
||||
|
||||
bool Pool::parse(const char *url)
|
||||
{
|
||||
assert(url != nullptr);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
m_url = url;
|
||||
if (base[0] == '[') {
|
||||
return parseIPv6(base);
|
||||
}
|
||||
|
||||
const char *port = strchr(base, ':');
|
||||
if (!port) {
|
||||
m_host = base;
|
||||
return true;
|
||||
}
|
||||
|
||||
const size_t size = port++ - base + 1;
|
||||
char *host = new char[size]();
|
||||
memcpy(host, base, size - 1);
|
||||
|
||||
m_host = host;
|
||||
m_port = static_cast<uint16_t>(strtol(port, nullptr, 10));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Pool::setUserpass(const char *userpass)
|
||||
{
|
||||
const char *p = strchr(userpass, ':');
|
||||
if (!p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char *user = new char[p - userpass + 1]();
|
||||
strncpy(user, userpass, p - userpass);
|
||||
|
||||
m_user = user;
|
||||
m_password = p + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
rapidjson::Value Pool::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value obj(kObjectType);
|
||||
|
||||
obj.AddMember("url", StringRef(url()), allocator);
|
||||
obj.AddMember("user", StringRef(user()), allocator);
|
||||
obj.AddMember("pass", StringRef(password()), allocator);
|
||||
obj.AddMember("rig-id", rigId() ? Value(StringRef(rigId())).Move() : Value(kNullType).Move(), allocator);
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
obj.AddMember("nicehash", isNicehash(), allocator);
|
||||
# endif
|
||||
|
||||
if (m_keepAlive == 0 || m_keepAlive == kKeepAliveTimeout) {
|
||||
obj.AddMember("keepalive", m_keepAlive > 0, allocator);
|
||||
}
|
||||
else {
|
||||
obj.AddMember("keepalive", m_keepAlive, allocator);
|
||||
}
|
||||
|
||||
switch (m_algorithm.variant()) {
|
||||
case xmrig::VARIANT_AUTO:
|
||||
case xmrig::VARIANT_0:
|
||||
case xmrig::VARIANT_1:
|
||||
obj.AddMember("variant", m_algorithm.variant(), allocator);
|
||||
break;
|
||||
|
||||
default:
|
||||
obj.AddMember("variant", StringRef(m_algorithm.variantName()), allocator);
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
void Pool::adjust(xmrig::Algo algorithm)
|
||||
{
|
||||
if (!isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_algorithm.isValid()) {
|
||||
m_algorithm.setAlgo(algorithm);
|
||||
|
||||
if (m_algorithm.variant() == xmrig::VARIANT_AUTO) {
|
||||
if (algorithm == xmrig::CRYPTONIGHT) {
|
||||
m_algorithm.setVariant(xmrig::VARIANT_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strstr(m_host.data(), ".nicehash.com")) {
|
||||
m_keepAlive = false;
|
||||
m_nicehash = true;
|
||||
|
||||
if (strstr(m_host.data(), "cryptonightv7.")) {
|
||||
m_algorithm.setVariant(xmrig::VARIANT_1);
|
||||
}
|
||||
}
|
||||
|
||||
if (strstr(m_host.data(), ".minergate.com")) {
|
||||
m_keepAlive = false;
|
||||
m_algorithm.setVariant(xmrig::VARIANT_1);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
#ifdef APP_DEBUG
|
||||
void Pool::print() const
|
||||
{
|
||||
LOG_NOTICE("url: %s", m_url.data());
|
||||
LOG_DEBUG ("host: %s", m_host.data());
|
||||
LOG_DEBUG ("port: %d", static_cast<int>(m_port));
|
||||
LOG_DEBUG ("user: %s", m_user.data());
|
||||
LOG_DEBUG ("pass: %s", m_password.data());
|
||||
LOG_DEBUG ("rig-id %s", m_rigId.data());
|
||||
LOG_DEBUG ("algo: %s", m_algorithm.name());
|
||||
LOG_DEBUG ("nicehash: %d", static_cast<int>(m_nicehash));
|
||||
LOG_DEBUG ("keepAlive: %d", m_keepAlive);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool Pool::parseIPv6(const char *addr)
|
||||
{
|
||||
const char *end = strchr(addr, ']');
|
||||
if (!end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *port = strchr(end, ':');
|
||||
if (!port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t size = end - addr;
|
||||
char *host = new char[size]();
|
||||
memcpy(host, addr + 1, size - 1);
|
||||
|
||||
m_host = host;
|
||||
m_port = static_cast<uint16_t>(strtol(port + 1, nullptr, 10));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Pool::addVariant(xmrig::Variant variant)
|
||||
{
|
||||
const xmrig::Algorithm algorithm(m_algorithm.algo(), variant);
|
||||
if (!algorithm.isValid() || m_algorithm == algorithm) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_algorithms.push_back(algorithm);
|
||||
}
|
105
src/common/net/Pool.h
Normal file
105
src/common/net/Pool.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __POOL_H__
|
||||
#define __POOL_H__
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "common/crypto/Algorithm.h"
|
||||
#include "common/utils/c_str.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
class Pool
|
||||
{
|
||||
public:
|
||||
constexpr static const char *kDefaultPassword = "x";
|
||||
constexpr static const char *kDefaultUser = "x";
|
||||
constexpr static uint16_t kDefaultPort = 3333;
|
||||
constexpr static int kKeepAliveTimeout = 60;
|
||||
|
||||
Pool();
|
||||
Pool(const char *url);
|
||||
Pool(const char *host,
|
||||
uint16_t port,
|
||||
const char *user = nullptr,
|
||||
const char *password = nullptr,
|
||||
int keepAlive = 0,
|
||||
bool nicehash = false
|
||||
);
|
||||
|
||||
inline bool isNicehash() const { return m_nicehash; }
|
||||
inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
|
||||
inline const char *host() const { return m_host.data(); }
|
||||
inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; }
|
||||
inline const char *rigId() const { return m_rigId.data(); }
|
||||
inline const char *url() const { return m_url.data(); }
|
||||
inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; }
|
||||
inline const xmrig::Algorithm &algorithm() const { return m_algorithm; }
|
||||
inline const xmrig::Algorithms &algorithms() const { return m_algorithms; }
|
||||
inline int keepAlive() const { return m_keepAlive; }
|
||||
inline uint16_t port() const { return m_port; }
|
||||
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
|
||||
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
|
||||
inline void setPassword(const char *password) { m_password = password; }
|
||||
inline void setRigId(const char *rigId) { m_rigId = rigId; }
|
||||
inline void setUser(const char *user) { m_user = user; }
|
||||
inline xmrig::Algorithm &algorithm() { return m_algorithm; }
|
||||
|
||||
inline bool operator!=(const Pool &other) const { return !isEqual(other); }
|
||||
inline bool operator==(const Pool &other) const { return isEqual(other); }
|
||||
|
||||
bool isCompatible(const xmrig::Algorithm &algorithm) const;
|
||||
bool isEqual(const Pool &other) const;
|
||||
bool parse(const char *url);
|
||||
bool setUserpass(const char *userpass);
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
void adjust(xmrig::Algo algorithm);
|
||||
|
||||
# ifdef APP_DEBUG
|
||||
void print() const;
|
||||
# endif
|
||||
|
||||
private:
|
||||
bool parseIPv6(const char *addr);
|
||||
void addVariant(xmrig::Variant variant);
|
||||
|
||||
bool m_nicehash;
|
||||
int m_keepAlive;
|
||||
uint16_t m_port;
|
||||
xmrig::Algorithm m_algorithm;
|
||||
xmrig::Algorithms m_algorithms;
|
||||
xmrig::c_str m_host;
|
||||
xmrig::c_str m_password;
|
||||
xmrig::c_str m_rigId;
|
||||
xmrig::c_str m_url;
|
||||
xmrig::c_str m_user;
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<Pool> Pools;
|
||||
|
||||
#endif /* __POOL_H__ */
|
95
src/common/net/Storage.h
Normal file
95
src/common/net/Storage.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __STORAGE_H__
|
||||
#define __STORAGE_H__
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
template <class TYPE>
|
||||
class Storage
|
||||
{
|
||||
public:
|
||||
inline Storage() :
|
||||
m_counter(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline uintptr_t add(TYPE *ptr)
|
||||
{
|
||||
m_data[m_counter] = ptr;
|
||||
|
||||
return m_counter++;
|
||||
}
|
||||
|
||||
|
||||
inline static void *ptr(uintptr_t id) { return reinterpret_cast<void *>(id); }
|
||||
|
||||
|
||||
inline TYPE *get(void *id) const { return get(reinterpret_cast<uintptr_t>(id)); }
|
||||
inline TYPE *get(uintptr_t id) const
|
||||
{
|
||||
assert(m_data.count(id) > 0);
|
||||
|
||||
if (m_data.count(id) == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_data.at(id);
|
||||
}
|
||||
|
||||
|
||||
inline void remove(void *id) { remove(reinterpret_cast<uintptr_t>(id)); }
|
||||
inline void remove(uintptr_t id)
|
||||
{
|
||||
TYPE *obj = get(id);
|
||||
if (obj == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = m_data.find(id);
|
||||
if (it != m_data.end()) {
|
||||
m_data.erase(it);
|
||||
}
|
||||
|
||||
delete obj;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::map<uintptr_t, TYPE *> m_data;
|
||||
uint64_t m_counter;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __STORAGE_H__ */
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,10 +25,11 @@
|
|||
#include <uv.h>
|
||||
|
||||
|
||||
#include "net/SubmitResult.h"
|
||||
#include "common/net/SubmitResult.h"
|
||||
|
||||
|
||||
SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff) :
|
||||
SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId) :
|
||||
reqId(reqId),
|
||||
seq(seq),
|
||||
diff(diff),
|
||||
actualDiff(actualDiff),
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -31,11 +31,12 @@
|
|||
class SubmitResult
|
||||
{
|
||||
public:
|
||||
inline SubmitResult() : seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {}
|
||||
SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff);
|
||||
inline SubmitResult() : reqId(0), seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {}
|
||||
SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId = 0);
|
||||
|
||||
void done();
|
||||
|
||||
int64_t reqId;
|
||||
int64_t seq;
|
||||
uint32_t diff;
|
||||
uint64_t actualDiff;
|
|
@ -22,13 +22,13 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "common/net/Client.h"
|
||||
#include "common/net/strategies/FailoverStrategy.h"
|
||||
#include "common/Platform.h"
|
||||
#include "interfaces/IStrategyListener.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/strategies/FailoverStrategy.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
|
||||
FailoverStrategy::FailoverStrategy(const std::vector<Pool> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
|
||||
m_quiet(quiet),
|
||||
m_retries(retries),
|
||||
m_retryPause(retryPause),
|
||||
|
@ -36,7 +36,7 @@ FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, int retryPause
|
|||
m_index(0),
|
||||
m_listener(listener)
|
||||
{
|
||||
for (const Url *url : urls) {
|
||||
for (const Pool &url : urls) {
|
||||
add(url);
|
||||
}
|
||||
}
|
||||
|
@ -153,10 +153,11 @@ void FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &resu
|
|||
}
|
||||
|
||||
|
||||
void FailoverStrategy::add(const Url *url)
|
||||
void FailoverStrategy::add(const Pool &pool)
|
||||
{
|
||||
Client *client = new Client((int) m_pools.size(), Platform::userAgent(), this);
|
||||
client->setUrl(url);
|
||||
client->setPool(pool);
|
||||
client->setRetries(m_retries);
|
||||
client->setRetryPause(m_retryPause * 1000);
|
||||
client->setQuiet(m_quiet);
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include <vector>
|
||||
|
||||
|
||||
#include "common/net/Pool.h"
|
||||
#include "interfaces/IClientListener.h"
|
||||
#include "interfaces/IStrategy.h"
|
||||
|
||||
|
@ -40,7 +41,7 @@ class Url;
|
|||
class FailoverStrategy : public IStrategy, public IClientListener
|
||||
{
|
||||
public:
|
||||
FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
|
||||
FailoverStrategy(const std::vector<Pool> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
|
||||
~FailoverStrategy();
|
||||
|
||||
public:
|
||||
|
@ -59,7 +60,7 @@ protected:
|
|||
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
|
||||
|
||||
private:
|
||||
void add(const Url *url);
|
||||
void add(const Pool &pool);
|
||||
|
||||
const bool m_quiet;
|
||||
const int m_retries;
|
|
@ -22,18 +22,19 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "common/net/Client.h"
|
||||
#include "common/net/strategies/SinglePoolStrategy.h"
|
||||
#include "common/Platform.h"
|
||||
#include "interfaces/IStrategyListener.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/strategies/SinglePoolStrategy.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
SinglePoolStrategy::SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet) :
|
||||
SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
|
||||
m_active(false),
|
||||
m_listener(listener)
|
||||
{
|
||||
m_client = new Client(0, Platform::userAgent(), this);
|
||||
m_client->setUrl(url);
|
||||
m_client->setPool(pool);
|
||||
m_client->setRetries(retries);
|
||||
m_client->setRetryPause(retryPause * 1000);
|
||||
m_client->setQuiet(quiet);
|
||||
}
|
|
@ -37,7 +37,7 @@ class Url;
|
|||
class SinglePoolStrategy : public IStrategy, public IClientListener
|
||||
{
|
||||
public:
|
||||
SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet = false);
|
||||
SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
|
||||
~SinglePoolStrategy();
|
||||
|
||||
public:
|
96
src/common/utils/c_str.h
Normal file
96
src/common/utils/c_str.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __C_STR_H__
|
||||
#define __C_STR_H__
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
/**
|
||||
* @brief Simple C string wrapper.
|
||||
*
|
||||
* 1. I know about std:string.
|
||||
* 2. For some reason I prefer don't use std:string in miner, eg because of file size of MSYS2 builds.
|
||||
*/
|
||||
class c_str
|
||||
{
|
||||
public:
|
||||
inline c_str() : m_data(nullptr) {}
|
||||
inline c_str(c_str &&other) { m_data = other.m_data; other.m_data = nullptr; }
|
||||
inline c_str(const c_str &other) : m_data(nullptr) { set(other.data()); }
|
||||
inline c_str(const char *str) : m_data(nullptr) { set(str); }
|
||||
inline ~c_str() { free(m_data); }
|
||||
|
||||
|
||||
inline void set(const char *str)
|
||||
{
|
||||
free(m_data);
|
||||
|
||||
m_data = str != nullptr ? strdup(str) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
inline void set(char *str)
|
||||
{
|
||||
free(m_data);
|
||||
|
||||
m_data = str;
|
||||
}
|
||||
|
||||
|
||||
inline bool isEqual(const char *str) const
|
||||
{
|
||||
return (m_data != nullptr && str != nullptr && strcmp(m_data, str) == 0) || (m_data == nullptr && m_data == nullptr);
|
||||
}
|
||||
|
||||
|
||||
inline bool isNull() const { return m_data == nullptr; }
|
||||
inline const char *data() const { return m_data; }
|
||||
inline size_t size() const { return m_data == nullptr ? 0 : strlen(m_data); }
|
||||
|
||||
|
||||
inline bool operator!=(const c_str &str) const { return !isEqual(str.data()); }
|
||||
inline bool operator!=(const char *str) const { return !isEqual(str); }
|
||||
inline bool operator==(const c_str &str) const { return isEqual(str.data()); }
|
||||
inline bool operator==(const char *str) const { return isEqual(str); }
|
||||
inline c_str &operator=(char *str) { set(str); return *this; }
|
||||
inline c_str &operator=(const c_str &str) { set(str.data()); return *this; }
|
||||
inline c_str &operator=(const char *str) { set(str); return *this; }
|
||||
|
||||
|
||||
private:
|
||||
char *m_data;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __C_STR_H__ */
|
43
src/common/utils/mm_malloc.h
Normal file
43
src/common/utils/mm_malloc.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __MM_MALLOC_PORTABLE_H__
|
||||
#define __MM_MALLOC_PORTABLE_H__
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef __GNUC__
|
||||
# include <mm_malloc.h>
|
||||
# else
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#else
|
||||
# if defined(XMRIG_ARM) && !defined(__clang__)
|
||||
# include "aligned_malloc.h"
|
||||
# else
|
||||
# include <mm_malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __MM_MALLOC_PORTABLE_H__ */
|
79
src/common/xmrig.h
Normal file
79
src/common/xmrig.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __XMRIG_H__
|
||||
#define __XMRIG_H__
|
||||
|
||||
|
||||
namespace xmrig
|
||||
{
|
||||
|
||||
|
||||
enum Algo {
|
||||
INVALID_ALGO = -1,
|
||||
CRYPTONIGHT, /* CryptoNight (Monero) */
|
||||
CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
|
||||
CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (SUMO) */
|
||||
};
|
||||
|
||||
|
||||
//--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.
|
||||
enum AlgoVariant {
|
||||
AV_AUTO, // --av=0 Automatic mode.
|
||||
AV_SINGLE, // --av=1 Single hash mode
|
||||
AV_DOUBLE, // --av=2 Double hash mode
|
||||
AV_SINGLE_SOFT, // --av=3 Single hash mode (Software AES)
|
||||
AV_DOUBLE_SOFT, // --av=4 Double hash mode (Software AES)
|
||||
AV_TRIPLE, // --av=5 Triple hash mode
|
||||
AV_QUAD, // --av=6 Quard hash mode
|
||||
AV_PENTA, // --av=7 Penta hash mode
|
||||
AV_TRIPLE_SOFT, // --av=8 Triple hash mode (Software AES)
|
||||
AV_QUAD_SOFT, // --av=9 Quard hash mode (Software AES)
|
||||
AV_PENTA_SOFT, // --av=10 Penta hash mode (Software AES)
|
||||
AV_MAX
|
||||
};
|
||||
|
||||
|
||||
enum Variant {
|
||||
VARIANT_AUTO = -1, // Autodetect
|
||||
VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy
|
||||
VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7
|
||||
VARIANT_IPBC = 2, // CryptoNight Lite variant 1 with XOR (IPBC only)
|
||||
VARIANT_XTL = 3 // CryptoNight variant 1 (Stellite only)
|
||||
};
|
||||
|
||||
|
||||
enum AesMode {
|
||||
AES_AUTO,
|
||||
AES_HW,
|
||||
AES_SOFT
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __XMRIG_H__ */
|
|
@ -1,32 +1,38 @@
|
|||
{
|
||||
"algo": "cryptonight", // cryptonight (default) or cryptonight-lite
|
||||
"av": 0, // algorithm variation, 0 auto select
|
||||
"background": false, // true to run the miner in the background
|
||||
"colors": true, // false to disable 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%
|
||||
"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.
|
||||
"print-time": 60, // print hashrate report every N seconds
|
||||
"retries": 5, // number of times to retry before switch to backup server
|
||||
"retry-pause": 5, // time to pause between retries
|
||||
"safe": false, // true to safe adjust threads and av settings for current CPU
|
||||
"syslog": false, // use system log for output messages
|
||||
"threads": null, // number of miner threads
|
||||
"algo": "cryptonight",
|
||||
"api": {
|
||||
"port": 0,
|
||||
"access-token": null,
|
||||
"worker-id": null,
|
||||
"ipv6": false,
|
||||
"restricted": true
|
||||
},
|
||||
"av": 0,
|
||||
"background": false,
|
||||
"colors": true,
|
||||
"cpu-affinity": null,
|
||||
"cpu-priority": null,
|
||||
"donate-level": 5,
|
||||
"huge-pages": true,
|
||||
"hw-aes": null,
|
||||
"log-file": null,
|
||||
"max-cpu-usage": 75,
|
||||
"pools": [
|
||||
{
|
||||
"url": "failover.xmrig.com:443", // URL of mining server
|
||||
"user": "YOUR_WALLET", // username for mining server
|
||||
"pass": "x", // password for mining server
|
||||
"keepalive": true, // send keepalived for prevent timeout (need pool support)
|
||||
"nicehash": false, // enable nicehash/xmrig-proxy support
|
||||
"variant": -1 // algorithm PoW variant
|
||||
"url": "proxy.fee.xmrig.com:9999",
|
||||
"user": "YOUR_WALLET",
|
||||
"pass": "x",
|
||||
"rig-id": null,
|
||||
"nicehash": false,
|
||||
"keepalive": false,
|
||||
"variant": 1
|
||||
}
|
||||
],
|
||||
"api": {
|
||||
"port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API
|
||||
"access-token": null, // access token for API
|
||||
"worker-id": null // custom worker-id for API
|
||||
}
|
||||
"print-time": 60,
|
||||
"retries": 5,
|
||||
"retry-pause": 5,
|
||||
"safe": false,
|
||||
"threads": null,
|
||||
"user-agent": null,
|
||||
"watch": false
|
||||
}
|
371
src/core/Config.cpp
Normal file
371
src/core/Config.cpp
Normal file
|
@ -0,0 +1,371 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/ConfigCreator.h"
|
||||
#include "Cpu.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "workers/CpuThread.h"
|
||||
|
||||
|
||||
static char affinity_tmp[20] = { 0 };
|
||||
|
||||
|
||||
xmrig::Config::Config() : xmrig::CommonConfig(),
|
||||
m_aesMode(AES_AUTO),
|
||||
m_algoVariant(AV_AUTO),
|
||||
m_dryRun(false),
|
||||
m_hugePages(true),
|
||||
m_safe(false),
|
||||
m_maxCpuUsage(75),
|
||||
m_priority(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::Config::~Config()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Config::reload(const char *json)
|
||||
{
|
||||
return xmrig::ConfigLoader::reload(this, json);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
doc.SetObject();
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
doc.AddMember("algo", StringRef(algorithm().name()), allocator);
|
||||
|
||||
Value api(kObjectType);
|
||||
api.AddMember("port", apiPort(), allocator);
|
||||
api.AddMember("access-token", apiToken() ? Value(StringRef(apiToken())).Move() : Value(kNullType).Move(), allocator);
|
||||
api.AddMember("worker-id", apiWorkerId() ? Value(StringRef(apiWorkerId())).Move() : Value(kNullType).Move(), allocator);
|
||||
api.AddMember("ipv6", isApiIPv6(), allocator);
|
||||
api.AddMember("restricted", isApiRestricted(), allocator);
|
||||
doc.AddMember("api", api, allocator);
|
||||
|
||||
doc.AddMember("av", algoVariant(), allocator);
|
||||
doc.AddMember("background", isBackground(), allocator);
|
||||
doc.AddMember("colors", isColors(), allocator);
|
||||
|
||||
if (affinity() != -1L) {
|
||||
snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, affinity());
|
||||
doc.AddMember("cpu-affinity", StringRef(affinity_tmp), allocator);
|
||||
}
|
||||
else {
|
||||
doc.AddMember("cpu-affinity", kNullType, allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("cpu-priority", priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
|
||||
doc.AddMember("donate-level", donateLevel(), allocator);
|
||||
doc.AddMember("huge-pages", isHugePages(), allocator);
|
||||
doc.AddMember("hw-aes", m_aesMode == AES_AUTO ? Value(kNullType) : Value(m_aesMode == AES_HW), allocator);
|
||||
doc.AddMember("log-file", logFile() ? Value(StringRef(logFile())).Move() : Value(kNullType).Move(), allocator);
|
||||
doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator);
|
||||
|
||||
Value pools(kArrayType);
|
||||
|
||||
for (const Pool &pool : m_activePools) {
|
||||
pools.PushBack(pool.toJSON(doc), allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("pools", pools, allocator);
|
||||
doc.AddMember("print-time", printTime(), allocator);
|
||||
doc.AddMember("retries", retries(), allocator);
|
||||
doc.AddMember("retry-pause", retryPause(), allocator);
|
||||
doc.AddMember("safe", m_safe, allocator);
|
||||
|
||||
if (threadsMode() == Advanced) {
|
||||
Value threads(kArrayType);
|
||||
|
||||
for (const IThread *thread : m_threads.list) {
|
||||
threads.PushBack(thread->toConfig(doc), doc.GetAllocator());
|
||||
}
|
||||
|
||||
doc.AddMember("threads", threads, allocator);
|
||||
}
|
||||
else {
|
||||
doc.AddMember("threads", threadsMode() == Automatic ? Value(kNullType) : Value(threadsCount()), allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator);
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
doc.AddMember("syslog", isSyslog(), allocator);
|
||||
# endif
|
||||
|
||||
doc.AddMember("watch", m_watch, allocator);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Config *xmrig::Config::load(int argc, char **argv, IWatcherListener *listener)
|
||||
{
|
||||
return static_cast<Config*>(ConfigLoader::load(argc, argv, new ConfigCreator(), listener));
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Config::finalize()
|
||||
{
|
||||
if (m_state != NoneState) {
|
||||
return CommonConfig::finalize();
|
||||
}
|
||||
|
||||
if (!CommonConfig::finalize()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_threads.cpu.empty()) {
|
||||
m_threads.mode = Advanced;
|
||||
const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT;
|
||||
|
||||
for (size_t i = 0; i < m_threads.cpu.size(); ++i) {
|
||||
m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const AlgoVariant av = getAlgoVariant();
|
||||
m_threads.mode = m_threads.count ? Simple : Automatic;
|
||||
|
||||
const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024;
|
||||
|
||||
if (!m_threads.count) {
|
||||
m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage);
|
||||
}
|
||||
else if (m_safe) {
|
||||
const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage);
|
||||
if (m_threads.count > count) {
|
||||
m_threads.count = count;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_threads.count; ++i) {
|
||||
m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Config::parseBoolean(int key, bool enable)
|
||||
{
|
||||
if (!CommonConfig::parseBoolean(key, enable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case IConfig::SafeKey: /* --safe */
|
||||
m_safe = enable;
|
||||
break;
|
||||
|
||||
case IConfig::HugePagesKey: /* --no-huge-pages */
|
||||
m_hugePages = enable;
|
||||
break;
|
||||
|
||||
case IConfig::DryRunKey: /* --dry-run */
|
||||
m_dryRun = enable;
|
||||
break;
|
||||
|
||||
case IConfig::HardwareAESKey: /* hw-aes config only */
|
||||
m_aesMode = enable ? AES_HW : AES_SOFT;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Config::parseString(int key, const char *arg)
|
||||
{
|
||||
if (!CommonConfig::parseString(key, arg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case xmrig::IConfig::AVKey: /* --av */
|
||||
case xmrig::IConfig::MaxCPUUsageKey: /* --max-cpu-usage */
|
||||
case xmrig::IConfig::CPUPriorityKey: /* --cpu-priority */
|
||||
return parseUint64(key, strtol(arg, nullptr, 10));
|
||||
|
||||
case xmrig::IConfig::SafeKey: /* --safe */
|
||||
case xmrig::IConfig::DryRunKey: /* --dry-run */
|
||||
return parseBoolean(key, true);
|
||||
|
||||
case xmrig::IConfig::HugePagesKey: /* --no-huge-pages */
|
||||
return parseBoolean(key, false);
|
||||
|
||||
case xmrig::IConfig::ThreadsKey: /* --threads */
|
||||
if (strncmp(arg, "all", 3) == 0) {
|
||||
m_threads.count = Cpu::threads();
|
||||
return true;
|
||||
}
|
||||
|
||||
return parseUint64(key, strtol(arg, nullptr, 10));
|
||||
|
||||
case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */
|
||||
{
|
||||
const char *p = strstr(arg, "0x");
|
||||
return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Config::parseUint64(int key, uint64_t arg)
|
||||
{
|
||||
if (!CommonConfig::parseUint64(key, arg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */
|
||||
if (arg) {
|
||||
m_threads.mask = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return parseInt(key, static_cast<int>(arg));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Config::parseJSON(const rapidjson::Document &doc)
|
||||
{
|
||||
const rapidjson::Value &threads = doc["threads"];
|
||||
|
||||
if (threads.IsArray()) {
|
||||
for (const rapidjson::Value &value : threads.GetArray()) {
|
||||
if (!value.IsObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value.HasMember("low_power_mode")) {
|
||||
auto data = CpuThread::parse(value);
|
||||
|
||||
if (data.valid) {
|
||||
m_threads.cpu.push_back(std::move(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Config::parseInt(int key, int arg)
|
||||
{
|
||||
switch (key) {
|
||||
case xmrig::IConfig::ThreadsKey: /* --threads */
|
||||
if (arg >= 0 && arg < 1024) {
|
||||
m_threads.count = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case xmrig::IConfig::AVKey: /* --av */
|
||||
if (arg >= AV_AUTO && arg < AV_MAX) {
|
||||
m_algoVariant = static_cast<AlgoVariant>(arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case xmrig::IConfig::MaxCPUUsageKey: /* --max-cpu-usage */
|
||||
if (m_maxCpuUsage > 0 && arg <= 100) {
|
||||
m_maxCpuUsage = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case xmrig::IConfig::CPUPriorityKey: /* --cpu-priority */
|
||||
if (arg >= 0 && arg <= 5) {
|
||||
m_priority = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const
|
||||
{
|
||||
# ifndef XMRIG_NO_AEON
|
||||
if (m_algorithm.algo() == xmrig::CRYPTONIGHT_LITE) {
|
||||
return getAlgoVariantLite();
|
||||
}
|
||||
# endif
|
||||
|
||||
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) {
|
||||
return Cpu::hasAES() ? AV_SINGLE : AV_SINGLE_SOFT;
|
||||
}
|
||||
|
||||
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) {
|
||||
return static_cast<AlgoVariant>(m_algoVariant + 2);
|
||||
}
|
||||
|
||||
return m_algoVariant;
|
||||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_AEON
|
||||
xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const
|
||||
{
|
||||
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) {
|
||||
return Cpu::hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT;
|
||||
}
|
||||
|
||||
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) {
|
||||
return static_cast<AlgoVariant>(m_algoVariant + 2);
|
||||
}
|
||||
|
||||
return m_algoVariant;
|
||||
}
|
||||
#endif
|
131
src/core/Config.h
Normal file
131
src/core/Config.h
Normal file
|
@ -0,0 +1,131 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "common/config/CommonConfig.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
#include "workers/CpuThread.h"
|
||||
|
||||
|
||||
class Addr;
|
||||
class Url;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ConfigLoader;
|
||||
class IThread;
|
||||
class IWatcherListener;
|
||||
|
||||
|
||||
/**
|
||||
* @brief The Config class
|
||||
*
|
||||
* Options with dynamic reload:
|
||||
* colors
|
||||
* debug
|
||||
* verbose
|
||||
* custom-diff (only for new connections)
|
||||
* api/worker-id
|
||||
* pools/
|
||||
*/
|
||||
class Config : public CommonConfig
|
||||
{
|
||||
public:
|
||||
enum ThreadsMode {
|
||||
Automatic,
|
||||
Simple,
|
||||
Advanced
|
||||
};
|
||||
|
||||
|
||||
Config();
|
||||
~Config();
|
||||
|
||||
bool reload(const char *json);
|
||||
|
||||
void getJSON(rapidjson::Document &doc) const override;
|
||||
|
||||
inline AesMode aesMode() const { return m_aesMode; }
|
||||
inline AlgoVariant algoVariant() const { return m_algoVariant; }
|
||||
inline bool isDryRun() const { return m_dryRun; }
|
||||
inline bool isHugePages() const { return m_hugePages; }
|
||||
inline const std::vector<IThread *> &threads() const { return m_threads.list; }
|
||||
inline int priority() const { return m_priority; }
|
||||
inline int threadsCount() const { return m_threads.list.size(); }
|
||||
inline int64_t affinity() const { return m_threads.mask; }
|
||||
inline ThreadsMode threadsMode() const { return m_threads.mode; }
|
||||
|
||||
static Config *load(int argc, char **argv, IWatcherListener *listener);
|
||||
|
||||
protected:
|
||||
bool finalize() override;
|
||||
bool parseBoolean(int key, bool enable) override;
|
||||
bool parseString(int key, const char *arg) override;
|
||||
bool parseUint64(int key, uint64_t arg) override;
|
||||
void parseJSON(const rapidjson::Document &doc) override;
|
||||
|
||||
private:
|
||||
bool parseInt(int key, int arg);
|
||||
|
||||
AlgoVariant getAlgoVariant() const;
|
||||
# ifndef XMRIG_NO_AEON
|
||||
AlgoVariant getAlgoVariantLite() const;
|
||||
# endif
|
||||
|
||||
|
||||
struct Threads
|
||||
{
|
||||
inline Threads() : mask(-1L), count(0), mode(Automatic) {}
|
||||
|
||||
int64_t mask;
|
||||
size_t count;
|
||||
std::vector<CpuThread::Data> cpu;
|
||||
std::vector<IThread *> list;
|
||||
ThreadsMode mode;
|
||||
};
|
||||
|
||||
|
||||
AesMode m_aesMode;
|
||||
AlgoVariant m_algoVariant;
|
||||
bool m_dryRun;
|
||||
bool m_hugePages;
|
||||
bool m_safe;
|
||||
int m_maxCpuUsage;
|
||||
int m_priority;
|
||||
Threads m_threads;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONFIG_H__ */
|
50
src/core/ConfigCreator.h
Normal file
50
src/core/ConfigCreator.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIGCREATOR_H__
|
||||
#define __CONFIGCREATOR_H__
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "interfaces/IConfigCreator.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConfig;
|
||||
|
||||
|
||||
class ConfigCreator : public IConfigCreator
|
||||
{
|
||||
public:
|
||||
inline IConfig *create() const override
|
||||
{
|
||||
return new Config();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // __CONFIGCREATOR_H__
|
187
src/core/ConfigLoader_platform.h
Normal file
187
src/core/ConfigLoader_platform.h
Normal file
|
@ -0,0 +1,187 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIGLOADER_PLATFORM_H__
|
||||
#define __CONFIGLOADER_PLATFORM_H__
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include "getopt/getopt.h"
|
||||
#else
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "version.h"
|
||||
#include "interfaces/IConfig.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static char const usage[] = "\
|
||||
Usage: " APP_ID " [OPTIONS]\n\
|
||||
Options:\n\
|
||||
-a, --algo=ALGO specify the algorithm to use\n\
|
||||
cryptonight\n"
|
||||
#ifndef XMRIG_NO_AEON
|
||||
"\
|
||||
cryptonight-lite\n"
|
||||
#endif
|
||||
#ifndef XMRIG_NO_SUMO
|
||||
"\
|
||||
cryptonight-heavy\n"
|
||||
#endif
|
||||
"\
|
||||
-o, --url=URL URL of 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\
|
||||
--rig-id=ID rig identifier for pool-side statistics (needs pool support)\n\
|
||||
-t, --threads=N number of miner threads\n\
|
||||
-v, --av=N algorithm variation, 0 auto select\n\
|
||||
-k, --keepalive send keepalived for prevent timeout (need pool support)\n\
|
||||
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
|
||||
-R, --retry-pause=N time to pause between retries (default: 5)\n\
|
||||
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
|
||||
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\
|
||||
--no-huge-pages disable huge pages support\n\
|
||||
--no-color disable colored output\n\
|
||||
--variant algorithm PoW variant\n\
|
||||
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\
|
||||
--user-agent set custom user-agent string for pool\n\
|
||||
-B, --background run the miner in the background\n\
|
||||
-c, --config=FILE load a JSON-format configuration file\n\
|
||||
-l, --log-file=FILE log all output to a file\n"
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
"\
|
||||
-S, --syslog use system log for output messages\n"
|
||||
# endif
|
||||
"\
|
||||
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\
|
||||
--safe safe adjust threads and av settings for current CPU\n\
|
||||
--nicehash enable nicehash/xmrig-proxy support\n\
|
||||
--print-time=N print hashrate report every N seconds\n\
|
||||
--api-port=N port for the miner API\n\
|
||||
--api-access-token=T access token for API\n\
|
||||
--api-worker-id=ID custom worker-id for API\n\
|
||||
--api-ipv6 enable IPv6 support for API\n\
|
||||
--api-no-restricted enable full remote access (only if API token set)\n\
|
||||
-h, --help display this help and exit\n\
|
||||
-V, --version output version information and exit\n\
|
||||
";
|
||||
|
||||
|
||||
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, xmrig::IConfig::AlgorithmKey },
|
||||
{ "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey },
|
||||
{ "api-port", 1, nullptr, xmrig::IConfig::ApiPort },
|
||||
{ "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
|
||||
{ "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
|
||||
{ "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
|
||||
{ "av", 1, nullptr, xmrig::IConfig::AVKey },
|
||||
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey },
|
||||
{ "config", 1, nullptr, xmrig::IConfig::ConfigKey },
|
||||
{ "cpu-affinity", 1, nullptr, xmrig::IConfig::CPUAffinityKey },
|
||||
{ "cpu-priority", 1, nullptr, xmrig::IConfig::CPUPriorityKey },
|
||||
{ "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey },
|
||||
{ "dry-run", 0, nullptr, xmrig::IConfig::DryRunKey },
|
||||
{ "help", 0, nullptr, xmrig::IConfig::HelpKey },
|
||||
{ "keepalive", 0, nullptr, xmrig::IConfig::KeepAliveKey },
|
||||
{ "log-file", 1, nullptr, xmrig::IConfig::LogFileKey },
|
||||
{ "max-cpu-usage", 1, nullptr, xmrig::IConfig::MaxCPUUsageKey },
|
||||
{ "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey },
|
||||
{ "no-color", 0, nullptr, xmrig::IConfig::ColorKey },
|
||||
{ "no-huge-pages", 0, nullptr, xmrig::IConfig::HugePagesKey },
|
||||
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey },
|
||||
{ "pass", 1, nullptr, xmrig::IConfig::PasswordKey },
|
||||
{ "print-time", 1, nullptr, xmrig::IConfig::PrintTimeKey },
|
||||
{ "retries", 1, nullptr, xmrig::IConfig::RetriesKey },
|
||||
{ "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey },
|
||||
{ "safe", 0, nullptr, xmrig::IConfig::SafeKey },
|
||||
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey },
|
||||
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey },
|
||||
{ "url", 1, nullptr, xmrig::IConfig::UrlKey },
|
||||
{ "user", 1, nullptr, xmrig::IConfig::UserKey },
|
||||
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
|
||||
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
|
||||
{ "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey },
|
||||
{ "version", 0, nullptr, xmrig::IConfig::VersionKey },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct option const config_options[] = {
|
||||
{ "algo", 1, nullptr, xmrig::IConfig::AlgorithmKey },
|
||||
{ "av", 1, nullptr, xmrig::IConfig::AVKey },
|
||||
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey },
|
||||
{ "colors", 0, nullptr, xmrig::IConfig::ColorKey },
|
||||
{ "cpu-affinity", 1, nullptr, xmrig::IConfig::CPUAffinityKey },
|
||||
{ "cpu-priority", 1, nullptr, xmrig::IConfig::CPUPriorityKey },
|
||||
{ "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey },
|
||||
{ "dry-run", 0, nullptr, xmrig::IConfig::DryRunKey },
|
||||
{ "huge-pages", 0, nullptr, xmrig::IConfig::HugePagesKey },
|
||||
{ "log-file", 1, nullptr, xmrig::IConfig::LogFileKey },
|
||||
{ "max-cpu-usage", 1, nullptr, xmrig::IConfig::MaxCPUUsageKey },
|
||||
{ "print-time", 1, nullptr, xmrig::IConfig::PrintTimeKey },
|
||||
{ "retries", 1, nullptr, xmrig::IConfig::RetriesKey },
|
||||
{ "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey },
|
||||
{ "safe", 0, nullptr, xmrig::IConfig::SafeKey },
|
||||
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey },
|
||||
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey },
|
||||
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
|
||||
{ "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct option const pool_options[] = {
|
||||
{ "url", 1, nullptr, xmrig::IConfig::UrlKey },
|
||||
{ "pass", 1, nullptr, xmrig::IConfig::PasswordKey },
|
||||
{ "user", 1, nullptr, xmrig::IConfig::UserKey },
|
||||
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
|
||||
{ "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey },
|
||||
{ "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey },
|
||||
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey },
|
||||
{ "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct option const api_options[] = {
|
||||
{ "port", 1, nullptr, xmrig::IConfig::ApiPort },
|
||||
{ "access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey },
|
||||
{ "worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
|
||||
{ "ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
|
||||
{ "restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONFIGLOADER_PLATFORM_H__ */
|
151
src/core/Controller.cpp
Normal file
151
src/core/Controller.cpp
Normal file
|
@ -0,0 +1,151 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "common/log/ConsoleLog.h"
|
||||
#include "common/log/FileLog.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "Cpu.h"
|
||||
#include "interfaces/IControllerListener.h"
|
||||
#include "net/Network.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
# include "common/log/SysLog.h"
|
||||
#endif
|
||||
|
||||
|
||||
class xmrig::ControllerPrivate
|
||||
{
|
||||
public:
|
||||
inline ControllerPrivate() :
|
||||
network(nullptr),
|
||||
config(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
inline ~ControllerPrivate()
|
||||
{
|
||||
delete network;
|
||||
delete config;
|
||||
}
|
||||
|
||||
|
||||
Network *network;
|
||||
std::vector<xmrig::IControllerListener *> listeners;
|
||||
xmrig::Config *config;
|
||||
};
|
||||
|
||||
|
||||
xmrig::Controller::Controller()
|
||||
: d_ptr(new ControllerPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::Controller::~Controller()
|
||||
{
|
||||
ConfigLoader::release();
|
||||
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Controller::isReady() const
|
||||
{
|
||||
return d_ptr->config && d_ptr->network;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Config *xmrig::Controller::config() const
|
||||
{
|
||||
assert(d_ptr->config != nullptr);
|
||||
|
||||
return d_ptr->config;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::Controller::init(int argc, char **argv)
|
||||
{
|
||||
Cpu::init();
|
||||
|
||||
d_ptr->config = xmrig::Config::load(argc, argv, this);
|
||||
if (!d_ptr->config) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Log::init();
|
||||
Platform::init(config()->userAgent());
|
||||
Platform::setProcessPriority(d_ptr->config->priority());
|
||||
|
||||
if (!config()->isBackground()) {
|
||||
Log::add(new ConsoleLog(this));
|
||||
}
|
||||
|
||||
if (config()->logFile()) {
|
||||
Log::add(new FileLog(config()->logFile()));
|
||||
}
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
if (config()->isSyslog()) {
|
||||
Log::add(new SysLog());
|
||||
}
|
||||
# endif
|
||||
|
||||
d_ptr->network = new Network(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Network *xmrig::Controller::network() const
|
||||
{
|
||||
assert(d_ptr->network != nullptr);
|
||||
|
||||
return d_ptr->network;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Controller::addListener(IControllerListener *listener)
|
||||
{
|
||||
d_ptr->listeners.push_back(listener);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Controller::onNewConfig(IConfig *config)
|
||||
{
|
||||
Config *previousConfig = d_ptr->config;
|
||||
d_ptr->config = static_cast<Config*>(config);
|
||||
|
||||
for (xmrig::IControllerListener *listener : d_ptr->listeners) {
|
||||
listener->onConfigChanged(d_ptr->config, previousConfig);
|
||||
}
|
||||
|
||||
delete previousConfig;
|
||||
}
|
64
src/core/Controller.h
Normal file
64
src/core/Controller.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CONTROLLER_H__
|
||||
#define __CONTROLLER_H__
|
||||
|
||||
|
||||
#include "interfaces/IWatcherListener.h"
|
||||
|
||||
|
||||
class Network;
|
||||
class StatsData;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Config;
|
||||
class ControllerPrivate;
|
||||
class IControllerListener;
|
||||
|
||||
|
||||
class Controller : public IWatcherListener
|
||||
{
|
||||
public:
|
||||
Controller();
|
||||
~Controller();
|
||||
|
||||
bool isReady() const;
|
||||
Config *config() const;
|
||||
int init(int argc, char **argv);
|
||||
Network *network() const;
|
||||
void addListener(IControllerListener *listener);
|
||||
|
||||
protected:
|
||||
void onNewConfig(IConfig *config) override;
|
||||
|
||||
private:
|
||||
ControllerPrivate *d_ptr;
|
||||
};
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONTROLLER_H__ */
|
|
@ -1,192 +0,0 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto/CryptoNight.h"
|
||||
|
||||
|
||||
#if defined(XMRIG_ARM)
|
||||
# include "crypto/CryptoNight_arm.h"
|
||||
#else
|
||||
# include "crypto/CryptoNight_x86.h"
|
||||
#endif
|
||||
|
||||
#include "crypto/CryptoNight_test.h"
|
||||
#include "net/Job.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "Options.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
void (*cryptonight_hash_ctx)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = nullptr;
|
||||
|
||||
|
||||
#define CRYPTONIGHT_HASH(NAME, ITERATIONS, MEM, MASK, SOFT_AES) \
|
||||
switch (variant) { \
|
||||
case xmrig::VARIANT_V1: \
|
||||
return cryptonight_##NAME##_hash<ITERATIONS, MEM, MASK, SOFT_AES, xmrig::VARIANT_V1>(input, size, output, ctx); \
|
||||
\
|
||||
case xmrig::VARIANT_NONE: \
|
||||
return cryptonight_##NAME##_hash<ITERATIONS, MEM, MASK, SOFT_AES, xmrig::VARIANT_NONE>(input, size, output, ctx); \
|
||||
\
|
||||
default: \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
static void cryptonight_av1_aesni(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx *ctx, int variant) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
CRYPTONIGHT_HASH(single, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, false)
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
static void cryptonight_av2_aesni_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
CRYPTONIGHT_HASH(double, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, false)
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
static void cryptonight_av3_softaes(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) {
|
||||
CRYPTONIGHT_HASH(single, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, true)
|
||||
}
|
||||
|
||||
|
||||
static void cryptonight_av4_softaes_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) {
|
||||
CRYPTONIGHT_HASH(double, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, true)
|
||||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_AEON
|
||||
static void cryptonight_lite_av1_aesni(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
CRYPTONIGHT_HASH(single, AEON_ITER, AEON_MEMORY, AEON_MASK, false)
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
static void cryptonight_lite_av2_aesni_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
CRYPTONIGHT_HASH(double, AEON_ITER, AEON_MEMORY, AEON_MASK, false)
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
static void cryptonight_lite_av3_softaes(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) {
|
||||
CRYPTONIGHT_HASH(single, AEON_ITER, AEON_MEMORY, AEON_MASK, true)
|
||||
}
|
||||
|
||||
|
||||
static void cryptonight_lite_av4_softaes_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) {
|
||||
CRYPTONIGHT_HASH(double, AEON_ITER, AEON_MEMORY, AEON_MASK, true)
|
||||
}
|
||||
|
||||
void (*cryptonight_variations[8])(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = {
|
||||
cryptonight_av1_aesni,
|
||||
cryptonight_av2_aesni_double,
|
||||
cryptonight_av3_softaes,
|
||||
cryptonight_av4_softaes_double,
|
||||
cryptonight_lite_av1_aesni,
|
||||
cryptonight_lite_av2_aesni_double,
|
||||
cryptonight_lite_av3_softaes,
|
||||
cryptonight_lite_av4_softaes_double
|
||||
};
|
||||
#else
|
||||
void (*cryptonight_variations[4])(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = {
|
||||
cryptonight_av1_aesni,
|
||||
cryptonight_av2_aesni_double,
|
||||
cryptonight_av3_softaes,
|
||||
cryptonight_av4_softaes_double
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx)
|
||||
{
|
||||
cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx, job.variant());
|
||||
|
||||
return *reinterpret_cast<uint64_t*>(result.result + 24) < job.target();
|
||||
}
|
||||
|
||||
|
||||
bool CryptoNight::init(int algo, int variant)
|
||||
{
|
||||
if (variant < 1 || variant > 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
const int index = algo == xmrig::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1);
|
||||
# else
|
||||
const int index = variant - 1;
|
||||
# endif
|
||||
|
||||
cryptonight_hash_ctx = cryptonight_variations[index];
|
||||
|
||||
return selfTest(algo);
|
||||
}
|
||||
|
||||
|
||||
void CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant)
|
||||
{
|
||||
cryptonight_hash_ctx(input, size, output, ctx, variant);
|
||||
}
|
||||
|
||||
|
||||
bool CryptoNight::selfTest(int algo) {
|
||||
if (cryptonight_hash_ctx == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t output[64];
|
||||
|
||||
struct cryptonight_ctx *ctx = static_cast<cryptonight_ctx *>(_mm_malloc(sizeof(cryptonight_ctx), 16));
|
||||
ctx->memory = static_cast<uint8_t *>(_mm_malloc(MONERO_MEMORY * 2, 16));
|
||||
|
||||
cryptonight_hash_ctx(test_input, 76, output, ctx, 0);
|
||||
|
||||
const bool doubleHash = Options::i()->doubleHash();
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
bool rc = memcmp(output, algo == xmrig::ALGO_CRYPTONIGHT_LITE ? test_output_v0_lite : test_output_v0, (doubleHash ? 64 : 32)) == 0;
|
||||
# else
|
||||
bool rc = memcmp(output, test_output_v0, (doubleHash ? 64 : 32)) == 0;
|
||||
# endif
|
||||
|
||||
if (rc) {
|
||||
cryptonight_hash_ctx(test_input, 76, output, ctx, 1);
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
rc = memcmp(output, algo == xmrig::ALGO_CRYPTONIGHT_LITE ? test_output_v1_lite : test_output_v1, (doubleHash ? 64 : 32)) == 0;
|
||||
# else
|
||||
rc = memcmp(output, test_output_v1, (doubleHash ? 64 : 32)) == 0;
|
||||
# endif
|
||||
}
|
||||
|
||||
_mm_free(ctx->memory);
|
||||
_mm_free(ctx);
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -30,35 +30,10 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
#define AEON_MEMORY 1048576
|
||||
#define AEON_MASK 0xFFFF0
|
||||
#define AEON_ITER 0x40000
|
||||
|
||||
#define MONERO_MEMORY 2097152
|
||||
#define MONERO_MASK 0x1FFFF0
|
||||
#define MONERO_ITER 0x80000
|
||||
|
||||
|
||||
struct cryptonight_ctx {
|
||||
alignas(16) uint8_t state0[200];
|
||||
alignas(16) uint8_t state1[200];
|
||||
alignas(16) uint8_t state[200];
|
||||
alignas(16) uint8_t* memory;
|
||||
};
|
||||
|
||||
|
||||
class Job;
|
||||
class JobResult;
|
||||
|
||||
|
||||
class CryptoNight
|
||||
{
|
||||
public:
|
||||
static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx);
|
||||
static bool init(int algo, int variant);
|
||||
static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant);
|
||||
|
||||
private:
|
||||
static bool selfTest(int algo);
|
||||
};
|
||||
|
||||
#endif /* __CRYPTONIGHT_H__ */
|
||||
|
|
|
@ -27,14 +27,9 @@
|
|||
#define __CRYPTONIGHT_ARM_H__
|
||||
|
||||
|
||||
#if defined(XMRIG_ARM) && !defined(__clang__)
|
||||
# include "aligned_malloc.h"
|
||||
#else
|
||||
# include <mm_malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "common/utils/mm_malloc.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "crypto/CryptoNight_monero.h"
|
||||
#include "crypto/soft_aes.h"
|
||||
|
||||
|
@ -78,6 +73,19 @@ static inline __attribute__((always_inline)) __m128i _mm_set_epi64x(const uint64
|
|||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_ARMv8
|
||||
static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey)
|
||||
{
|
||||
alignas(16) const __m128i zero = { 0 };
|
||||
return veorq_u8(vaesmcq_u8(vaeseq_u8(v, zero)), rkey );
|
||||
}
|
||||
#else
|
||||
static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* this one was not implemented yet so here it is */
|
||||
static inline __attribute__((always_inline)) uint64_t _mm_cvtsi128_si64(__m128i a)
|
||||
{
|
||||
|
@ -160,19 +168,19 @@ static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, _
|
|||
*k0 = xout0;
|
||||
*k1 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x01>(&xout0, &xout2) : soft_aes_genkey_sub<0x01>(&xout0, &xout2);
|
||||
soft_aes_genkey_sub<0x01>(&xout0, &xout2);
|
||||
*k2 = xout0;
|
||||
*k3 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x02>(&xout0, &xout2) : soft_aes_genkey_sub<0x02>(&xout0, &xout2);
|
||||
soft_aes_genkey_sub<0x02>(&xout0, &xout2);
|
||||
*k4 = xout0;
|
||||
*k5 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x04>(&xout0, &xout2) : soft_aes_genkey_sub<0x04>(&xout0, &xout2);
|
||||
soft_aes_genkey_sub<0x04>(&xout0, &xout2);
|
||||
*k6 = xout0;
|
||||
*k7 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x08>(&xout0, &xout2) : soft_aes_genkey_sub<0x08>(&xout0, &xout2);
|
||||
soft_aes_genkey_sub<0x08>(&xout0, &xout2);
|
||||
*k8 = xout0;
|
||||
*k9 = xout2;
|
||||
}
|
||||
|
@ -191,22 +199,34 @@ static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2,
|
|||
*x6 = soft_aesenc((uint32_t*)x6, key);
|
||||
*x7 = soft_aesenc((uint32_t*)x7, key);
|
||||
}
|
||||
# ifndef XMRIG_ARMv7
|
||||
else {
|
||||
*x0 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x0), key));
|
||||
*x1 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x1), key));
|
||||
*x2 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x2), key));
|
||||
*x3 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x3), key));
|
||||
*x4 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x4), key));
|
||||
*x5 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x5), key));
|
||||
*x6 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x6), key));
|
||||
*x7 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x7), key));
|
||||
*x0 = _mm_aesenc_si128(*x0, key);
|
||||
*x1 = _mm_aesenc_si128(*x1, key);
|
||||
*x2 = _mm_aesenc_si128(*x2, key);
|
||||
*x3 = _mm_aesenc_si128(*x3, key);
|
||||
*x4 = _mm_aesenc_si128(*x4, key);
|
||||
*x5 = _mm_aesenc_si128(*x5, key);
|
||||
*x6 = _mm_aesenc_si128(*x6, key);
|
||||
*x7 = _mm_aesenc_si128(*x7, key);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
template<size_t MEM, bool SOFT_AES>
|
||||
inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3, __m128i& x4, __m128i& x5, __m128i& x6, __m128i& x7)
|
||||
{
|
||||
__m128i tmp0 = x0;
|
||||
x0 = _mm_xor_si128(x0, x1);
|
||||
x1 = _mm_xor_si128(x1, x2);
|
||||
x2 = _mm_xor_si128(x2, x3);
|
||||
x3 = _mm_xor_si128(x3, x4);
|
||||
x4 = _mm_xor_si128(x4, x5);
|
||||
x5 = _mm_xor_si128(x5, x6);
|
||||
x6 = _mm_xor_si128(x6, x7);
|
||||
x7 = _mm_xor_si128(x7, tmp0);
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, size_t MEM, bool SOFT_AES>
|
||||
static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
||||
{
|
||||
__m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7;
|
||||
|
@ -223,11 +243,24 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
|||
xin6 = _mm_load_si128(input + 10);
|
||||
xin7 = _mm_load_si128(input + 11);
|
||||
|
||||
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
|
||||
if (!SOFT_AES) {
|
||||
aes_round<SOFT_AES>(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
}
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
||||
mix_and_propagate(xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
|
||||
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
@ -237,20 +270,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
|||
aes_round<SOFT_AES>(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
xin0 ^= k9;
|
||||
xin1 ^= k9;
|
||||
xin2 ^= k9;
|
||||
xin3 ^= k9;
|
||||
xin4 ^= k9;
|
||||
xin5 ^= k9;
|
||||
xin6 ^= k9;
|
||||
xin7 ^= k9;
|
||||
}
|
||||
else {
|
||||
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
}
|
||||
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
||||
_mm_store_si128(output + i + 0, xin0);
|
||||
_mm_store_si128(output + i + 1, xin1);
|
||||
|
@ -264,7 +284,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
|||
}
|
||||
|
||||
|
||||
template<size_t MEM, bool SOFT_AES>
|
||||
template<xmrig::Algo ALGO, size_t MEM, bool SOFT_AES>
|
||||
static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
||||
{
|
||||
__m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7;
|
||||
|
@ -292,10 +312,6 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
|
||||
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
aes_round<SOFT_AES>(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
}
|
||||
|
||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
@ -305,19 +321,51 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
xout0 ^= k9;
|
||||
xout1 ^= k9;
|
||||
xout2 ^= k9;
|
||||
xout3 ^= k9;
|
||||
xout4 ^= k9;
|
||||
xout5 ^= k9;
|
||||
xout6 ^= k9;
|
||||
xout7 ^= k9;
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||
}
|
||||
else {
|
||||
}
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
|
||||
xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0);
|
||||
xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1);
|
||||
xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2);
|
||||
xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3);
|
||||
xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4);
|
||||
xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5);
|
||||
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
|
||||
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
|
||||
|
||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,17 +380,41 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
}
|
||||
|
||||
|
||||
template<size_t ITERATIONS, size_t MEM, size_t MASK, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx)
|
||||
static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp)
|
||||
{
|
||||
keccak(input, (int) size, ctx->state0, 200);
|
||||
mem_out[0] = EXTRACT64(tmp);
|
||||
|
||||
uint64_t vh = vgetq_lane_u64(tmp, 1);
|
||||
|
||||
uint8_t x = vh >> 24;
|
||||
static const uint16_t table = 0x7531;
|
||||
const uint8_t index = (((x >> 3) & 6) | (x & 1)) << 1;
|
||||
vh ^= ((table >> index) & 0x3) << 28;
|
||||
|
||||
mem_out[1] = vh;
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
|
||||
|
||||
if (VARIANT > 0 && size < 43) {
|
||||
memset(output, 0, 32);
|
||||
return;
|
||||
}
|
||||
|
||||
keccak(input, (int) size, ctx[0]->state, 200);
|
||||
|
||||
VARIANT1_INIT(0);
|
||||
|
||||
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) ctx->state0, (__m128i*) ctx->memory);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory);
|
||||
|
||||
const uint8_t* l0 = ctx->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
|
||||
const uint8_t* l0 = ctx[0]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
|
||||
uint64_t al0 = h0[0] ^ h0[4];
|
||||
uint64_t ah0 = h0[1] ^ h0[5];
|
||||
|
@ -358,13 +430,15 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||
}
|
||||
else {
|
||||
cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
|
||||
# ifndef XMRIG_ARMv7
|
||||
cx = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
|
||||
# endif
|
||||
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0));
|
||||
}
|
||||
|
||||
if (VARIANT > 0) {
|
||||
cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
|
||||
} else {
|
||||
_mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
|
||||
}
|
||||
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
|
||||
VARIANT1_1(&l0[idx0 & MASK]);
|
||||
idx0 = EXTRACT64(cx);
|
||||
bx0 = cx;
|
||||
|
||||
|
@ -384,31 +458,49 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||
ah0 ^= ch;
|
||||
al0 ^= cl;
|
||||
idx0 = al0;
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0];
|
||||
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2];
|
||||
int64_t q = n / (d | 0x5);
|
||||
|
||||
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
|
||||
idx0 = d ^ q;
|
||||
}
|
||||
}
|
||||
|
||||
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) ctx->memory, (__m128i*) ctx->state0);
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state);
|
||||
|
||||
keccakf(h0, 24);
|
||||
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
|
||||
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
|
||||
}
|
||||
|
||||
|
||||
template<size_t ITERATIONS, size_t MEM, size_t MASK, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
keccak(input, (int) size, ctx->state0, 200);
|
||||
keccak(input + size, (int) size, ctx->state1, 200);
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
|
||||
|
||||
if (VARIANT > 0 && size < 43) {
|
||||
memset(output, 0, 64);
|
||||
return;
|
||||
}
|
||||
|
||||
keccak(input, (int) size, ctx[0]->state, 200);
|
||||
keccak(input + size, (int) size, ctx[1]->state, 200);
|
||||
|
||||
VARIANT1_INIT(0);
|
||||
VARIANT1_INIT(1);
|
||||
|
||||
const uint8_t* l0 = ctx->memory;
|
||||
const uint8_t* l1 = ctx->memory + MEM;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state1);
|
||||
const uint8_t* l0 = ctx[0]->memory;
|
||||
const uint8_t* l1 = ctx[1]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
|
||||
|
||||
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
|
||||
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
|
||||
|
||||
uint64_t al0 = h0[0] ^ h0[4];
|
||||
uint64_t al1 = h1[0] ^ h1[4];
|
||||
|
@ -431,16 +523,17 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
else {
|
||||
cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
|
||||
cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]);
|
||||
# ifndef XMRIG_ARMv7
|
||||
cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
|
||||
cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1);
|
||||
# endif
|
||||
cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0));
|
||||
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1));
|
||||
}
|
||||
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
|
||||
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
|
||||
VARIANT1_1(&l0[idx0 & MASK]);
|
||||
VARIANT1_1(&l1[idx1 & MASK]);
|
||||
if (VARIANT > 0) {
|
||||
cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
|
||||
cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
|
||||
} else {
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
|
||||
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
|
||||
};
|
||||
|
||||
idx0 = EXTRACT64(cx0);
|
||||
idx1 = EXTRACT64(cx1);
|
||||
|
@ -465,6 +558,15 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
al0 ^= cl;
|
||||
idx0 = al0;
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0];
|
||||
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2];
|
||||
int64_t q = n / (d | 0x5);
|
||||
|
||||
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
|
||||
idx0 = d ^ q;
|
||||
}
|
||||
|
||||
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
|
||||
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
|
||||
lo = __umul128(idx1, cl, &hi);
|
||||
|
@ -480,16 +582,43 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
ah1 ^= ch;
|
||||
al1 ^= cl;
|
||||
idx1 = al1;
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
int64_t n = ((int64_t*)&l1[idx1 & MASK])[0];
|
||||
int32_t d = ((int32_t*)&l1[idx1 & MASK])[2];
|
||||
int64_t q = n / (d | 0x5);
|
||||
|
||||
((int64_t*)&l1[idx1 & MASK])[0] = n ^ q;
|
||||
idx1 = d ^ q;
|
||||
}
|
||||
}
|
||||
|
||||
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
|
||||
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
|
||||
|
||||
keccakf(h0, 24);
|
||||
keccakf(h1, 24);
|
||||
|
||||
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
|
||||
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32);
|
||||
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
|
||||
extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32);
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* __CRYPTONIGHT_ARM_H__ */
|
||||
|
|
135
src/crypto/CryptoNight_constants.h
Normal file
135
src/crypto/CryptoNight_constants.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CRYPTONIGHT_CONSTANTS_H__
|
||||
#define __CRYPTONIGHT_CONSTANTS_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "common/xmrig.h"
|
||||
|
||||
|
||||
namespace xmrig
|
||||
{
|
||||
|
||||
constexpr const size_t CRYPTONIGHT_MEMORY = 2 * 1024 * 1024;
|
||||
constexpr const uint32_t CRYPTONIGHT_MASK = 0x1FFFF0;
|
||||
constexpr const uint32_t CRYPTONIGHT_ITER = 0x80000;
|
||||
|
||||
constexpr const size_t CRYPTONIGHT_LITE_MEMORY = 1 * 1024 * 1024;
|
||||
constexpr const uint32_t CRYPTONIGHT_LITE_MASK = 0xFFFF0;
|
||||
constexpr const uint32_t CRYPTONIGHT_LITE_ITER = 0x40000;
|
||||
|
||||
constexpr const size_t CRYPTONIGHT_HEAVY_MEMORY = 4 * 1024 * 1024;
|
||||
constexpr const uint32_t CRYPTONIGHT_HEAVY_MASK = 0x3FFFF0;
|
||||
constexpr const uint32_t CRYPTONIGHT_HEAVY_ITER = 0x40000;
|
||||
|
||||
|
||||
template<Algo ALGO> inline constexpr size_t cn_select_memory() { return 0; }
|
||||
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT>() { return CRYPTONIGHT_MEMORY; }
|
||||
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_MEMORY; }
|
||||
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_MEMORY; }
|
||||
|
||||
|
||||
inline size_t cn_select_memory(Algo algorithm)
|
||||
{
|
||||
switch(algorithm)
|
||||
{
|
||||
case CRYPTONIGHT:
|
||||
return CRYPTONIGHT_MEMORY;
|
||||
|
||||
case CRYPTONIGHT_LITE:
|
||||
return CRYPTONIGHT_LITE_MEMORY;
|
||||
|
||||
case CRYPTONIGHT_HEAVY:
|
||||
return CRYPTONIGHT_HEAVY_MEMORY;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template<Algo ALGO> inline constexpr uint32_t cn_select_mask() { return 0; }
|
||||
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT>() { return CRYPTONIGHT_MASK; }
|
||||
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_MASK; }
|
||||
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_MASK; }
|
||||
|
||||
|
||||
inline uint32_t cn_select_mask(Algo algorithm)
|
||||
{
|
||||
switch(algorithm)
|
||||
{
|
||||
case CRYPTONIGHT:
|
||||
return CRYPTONIGHT_MASK;
|
||||
|
||||
case CRYPTONIGHT_LITE:
|
||||
return CRYPTONIGHT_LITE_MASK;
|
||||
|
||||
case CRYPTONIGHT_HEAVY:
|
||||
return CRYPTONIGHT_HEAVY_MASK;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template<Algo ALGO> inline constexpr uint32_t cn_select_iter() { return 0; }
|
||||
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT>() { return CRYPTONIGHT_ITER; }
|
||||
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_ITER; }
|
||||
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_ITER; }
|
||||
|
||||
|
||||
inline uint32_t cn_select_iter(Algo algorithm)
|
||||
{
|
||||
switch(algorithm)
|
||||
{
|
||||
case CRYPTONIGHT:
|
||||
return CRYPTONIGHT_ITER;
|
||||
|
||||
case CRYPTONIGHT_LITE:
|
||||
return CRYPTONIGHT_LITE_ITER;
|
||||
|
||||
case CRYPTONIGHT_HEAVY:
|
||||
return CRYPTONIGHT_HEAVY_ITER;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __CRYPTONIGHT_CONSTANTS_H__ */
|
|
@ -32,14 +32,14 @@
|
|||
uint64_t tweak1_2_##part = 0; \
|
||||
if (VARIANT > 0) { \
|
||||
tweak1_2_##part = (*reinterpret_cast<const uint64_t*>(input + 35 + part * size) ^ \
|
||||
*(reinterpret_cast<const uint64_t*>(ctx->state##part) + 24)); \
|
||||
*(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24)); \
|
||||
}
|
||||
#else
|
||||
# define VARIANT1_INIT(part) \
|
||||
uint64_t tweak1_2_##part = 0; \
|
||||
if (VARIANT > 0) { \
|
||||
volatile const uint64_t a = *reinterpret_cast<const uint64_t*>(input + 35 + part * size); \
|
||||
volatile const uint64_t b = *(reinterpret_cast<const uint64_t*>(ctx->state##part) + 24); \
|
||||
volatile const uint64_t b = *(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24); \
|
||||
tweak1_2_##part = a ^ b; \
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,52 +26,137 @@
|
|||
#define __CRYPTONIGHT_TEST_H__
|
||||
|
||||
|
||||
const static uint8_t test_input[152] = {
|
||||
const static uint8_t test_input[380] = {
|
||||
0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00,
|
||||
0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B,
|
||||
0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62,
|
||||
0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92,
|
||||
0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01,
|
||||
0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19,
|
||||
0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9,
|
||||
0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F,
|
||||
0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46,
|
||||
0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02,
|
||||
0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00,
|
||||
0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B,
|
||||
0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62,
|
||||
0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92,
|
||||
0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01
|
||||
0x07, 0x07, 0xB4, 0x87, 0xD0, 0xD6, 0x05, 0x26, 0xE0, 0xC6, 0xDD, 0x9B, 0xC7, 0x18, 0xC3, 0xCF,
|
||||
0x52, 0x04, 0xBD, 0x4F, 0x9B, 0x27, 0xF6, 0x73, 0xB9, 0x3F, 0xEF, 0x7B, 0xB2, 0xF7, 0x2B, 0xBB,
|
||||
0x3F, 0x3E, 0x9C, 0x3E, 0x9D, 0x33, 0x1E, 0xDE, 0xAD, 0xBE, 0xEF, 0x4E, 0x00, 0x91, 0x81, 0x29,
|
||||
0x74, 0xB2, 0x70, 0xE7, 0x6D, 0xD2, 0x2A, 0x5F, 0x52, 0x04, 0x93, 0xE6, 0x18, 0x89, 0x40, 0xD8,
|
||||
0xC6, 0xE3, 0x90, 0x6E, 0xAA, 0x6A, 0xB7, 0xE2, 0x08, 0x7E, 0x78, 0x0E,
|
||||
0x01, 0x00, 0xEE, 0xB2, 0xD1, 0xD6, 0x05, 0xFF, 0x27, 0x7F, 0x26, 0xDB, 0xAA, 0xB2, 0xC9, 0x26,
|
||||
0x30, 0xC6, 0xCF, 0x11, 0x64, 0xEA, 0x6C, 0x8A, 0xE0, 0x98, 0x01, 0xF8, 0x75, 0x4B, 0x49, 0xAF,
|
||||
0x79, 0x70, 0xAE, 0xEE, 0xA7, 0x62, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x47, 0x8C, 0x63, 0xE7, 0xD8,
|
||||
0x40, 0x02, 0x3C, 0xDA, 0xEA, 0x92, 0x52, 0x53, 0xAC, 0xFD, 0xC7, 0x8A, 0x4C, 0x31, 0xB2, 0xF2,
|
||||
0xEC, 0x72, 0x7B, 0xFF, 0xCE, 0xC0, 0xE7, 0x12, 0xD4, 0xE9, 0x2A, 0x01,
|
||||
0x07, 0x07, 0xA9, 0xB7, 0xD1, 0xD6, 0x05, 0x3F, 0x0D, 0x5E, 0xFD, 0xC7, 0x03, 0xFC, 0xFC, 0xD2,
|
||||
0xCE, 0xBC, 0x44, 0xD8, 0xAB, 0x44, 0xA6, 0xA0, 0x3A, 0xE4, 0x4D, 0x8F, 0x15, 0xAF, 0x62, 0x17,
|
||||
0xD1, 0xE0, 0x92, 0x85, 0xE4, 0x73, 0xF9, 0x00, 0x00, 0x00, 0xA0, 0xFC, 0x09, 0xDE, 0xAB, 0xF5,
|
||||
0x8B, 0x6F, 0x1D, 0xCA, 0xA8, 0xBA, 0xAC, 0x74, 0xDD, 0x74, 0x19, 0xD5, 0xD6, 0x10, 0xEC, 0x38,
|
||||
0xCF, 0x50, 0x29, 0x6A, 0x07, 0x0B, 0x93, 0x8F, 0x8F, 0xA8, 0x10, 0x04
|
||||
};
|
||||
|
||||
|
||||
const static uint8_t test_output_v0[64] = {
|
||||
const static uint8_t test_output_v0[160] = {
|
||||
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
|
||||
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00,
|
||||
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
|
||||
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
|
||||
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
|
||||
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00
|
||||
0xA1, 0xB4, 0xFA, 0xE3, 0xE5, 0x76, 0xCE, 0xCF, 0xB7, 0x9C, 0xAF, 0x3E, 0x29, 0x92, 0xE4, 0xE0,
|
||||
0x31, 0x24, 0x05, 0x48, 0xBF, 0x8D, 0x5F, 0x7B, 0x11, 0x03, 0x60, 0xAA, 0xD7, 0x50, 0x3F, 0x0C,
|
||||
0x2D, 0x30, 0xF3, 0x87, 0x4F, 0x86, 0xA1, 0x4A, 0xB5, 0xA2, 0x1A, 0x08, 0xD0, 0x44, 0x2C, 0x9D,
|
||||
0x16, 0xE9, 0x28, 0x49, 0xA1, 0xFF, 0x85, 0x6F, 0x12, 0xBB, 0x7D, 0xAB, 0x11, 0x1C, 0xE7, 0xF7,
|
||||
0x2D, 0x9D, 0x19, 0xE4, 0xD2, 0x26, 0x44, 0x1E, 0xCD, 0x22, 0x08, 0x24, 0xA8, 0x97, 0x46, 0x62,
|
||||
0x04, 0x84, 0x90, 0x4A, 0xEE, 0x99, 0x14, 0xED, 0xB8, 0xC6, 0x0D, 0x37, 0xA1, 0x66, 0x17, 0xB0
|
||||
};
|
||||
|
||||
|
||||
// Monero v7
|
||||
const static uint8_t test_output_v1[64] = {
|
||||
0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D,
|
||||
0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22,
|
||||
const static uint8_t test_output_v1[160] = {
|
||||
0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9,
|
||||
0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9
|
||||
0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9,
|
||||
0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D,
|
||||
0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22,
|
||||
0xE7, 0x8C, 0x5A, 0x6E, 0x38, 0x30, 0x68, 0x4A, 0x73, 0xFC, 0x1B, 0xC6, 0x6D, 0xFC, 0x8D, 0x98,
|
||||
0xB4, 0xC2, 0x23, 0x39, 0xAD, 0xE0, 0x9D, 0xF6, 0x6D, 0x8C, 0x6A, 0xAA, 0xF9, 0xB2, 0xE3, 0x4C,
|
||||
0xB6, 0x90, 0x6C, 0xE6, 0x15, 0x5E, 0x46, 0x07, 0x9C, 0xB2, 0x6B, 0xAC, 0x3B, 0xAC, 0x1A, 0xDE,
|
||||
0x92, 0x2C, 0xD6, 0x0C, 0x46, 0x9D, 0x9B, 0xC2, 0x84, 0x52, 0x65, 0xF6, 0xBD, 0xFA, 0x0D, 0x74,
|
||||
0x00, 0x66, 0x10, 0x07, 0xF1, 0x19, 0x06, 0x3A, 0x6C, 0xFF, 0xEE, 0xB2, 0x40, 0xE5, 0x88, 0x2B,
|
||||
0x6C, 0xAB, 0x6B, 0x1D, 0x88, 0xB8, 0x44, 0x25, 0xF4, 0xEA, 0xB7, 0xEC, 0xBA, 0x12, 0x8A, 0x24
|
||||
};
|
||||
|
||||
|
||||
// Stellite (XTL)
|
||||
const static uint8_t test_output_xtl[160] = {
|
||||
0x8F, 0xE5, 0xF0, 0x5F, 0x02, 0x2A, 0x61, 0x7D, 0xE5, 0x3F, 0x79, 0x36, 0x4B, 0x25, 0xCB, 0xC3,
|
||||
0xC0, 0x8E, 0x0E, 0x1F, 0xE3, 0xBE, 0x48, 0x57, 0x07, 0x03, 0xFE, 0xE1, 0xEC, 0x0E, 0xB0, 0xB1,
|
||||
0x21, 0x26, 0xFF, 0x98, 0xE6, 0x86, 0x08, 0x5B, 0xC9, 0x96, 0x44, 0xA3, 0xB8, 0x4E, 0x28, 0x90,
|
||||
0x76, 0xED, 0xAD, 0xB9, 0xAA, 0xAC, 0x01, 0x94, 0x1D, 0xBE, 0x3E, 0xEA, 0xAD, 0xEE, 0xB2, 0xCF,
|
||||
0xB0, 0x43, 0x4B, 0x88, 0xFC, 0xB2, 0xF3, 0x82, 0x9D, 0xD7, 0xDF, 0x51, 0x97, 0x2C, 0x5A, 0xE3,
|
||||
0xC7, 0x16, 0x0B, 0xC8, 0x7C, 0xB7, 0x2F, 0x1C, 0x55, 0x33, 0xCA, 0xE1, 0xEE, 0x08, 0xA4, 0x86,
|
||||
0x60, 0xED, 0x6E, 0x9D, 0x2D, 0x05, 0x0D, 0x7D, 0x02, 0x49, 0x23, 0x39, 0x7C, 0xC3, 0x6D, 0x3D,
|
||||
0x05, 0x51, 0x28, 0xF1, 0x9B, 0x3C, 0xDF, 0xC4, 0xEA, 0x8A, 0xA6, 0x6A, 0x3C, 0x8B, 0xE2, 0xAF,
|
||||
0x47, 0x00, 0xFC, 0x36, 0xED, 0x50, 0xBB, 0xD2, 0x2E, 0x63, 0x4B, 0x93, 0x11, 0x0C, 0xA7, 0xBA,
|
||||
0x32, 0x6E, 0x47, 0x4D, 0xCE, 0xCC, 0x82, 0x54, 0x1D, 0x06, 0xF8, 0x06, 0x86, 0xBD, 0x22, 0x48
|
||||
};
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_AEON
|
||||
const static uint8_t test_output_v0_lite[64] = {
|
||||
const static uint8_t test_output_v0_lite[160] = {
|
||||
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
|
||||
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88,
|
||||
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
|
||||
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
|
||||
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
|
||||
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88
|
||||
0x38, 0x08, 0xE1, 0x17, 0x0B, 0x99, 0x8D, 0x1A, 0x3C, 0xCE, 0x35, 0xC5, 0xC7, 0x3A, 0x00, 0x2E,
|
||||
0xCB, 0x54, 0xF0, 0x78, 0x2E, 0x9E, 0xDB, 0xC7, 0xDF, 0x2E, 0x71, 0x9A, 0x16, 0x97, 0xC4, 0x18,
|
||||
0x4B, 0x97, 0x07, 0xFE, 0x5D, 0x98, 0x9A, 0xD6, 0xD8, 0xE5, 0x92, 0x66, 0x87, 0x7F, 0x19, 0x37,
|
||||
0xA2, 0x5E, 0xE6, 0x96, 0xB5, 0x97, 0x33, 0x89, 0xE0, 0xA7, 0xC9, 0xDD, 0x4A, 0x7E, 0x9E, 0x53,
|
||||
0xBE, 0x91, 0x2B, 0xF5, 0xF5, 0xAF, 0xDD, 0x09, 0xA2, 0xF4, 0xA4, 0x56, 0xEB, 0x96, 0x22, 0xC9,
|
||||
0x94, 0xFB, 0x7B, 0x28, 0xC9, 0x97, 0x65, 0x04, 0xAC, 0x4F, 0x84, 0x71, 0xDA, 0x6E, 0xD8, 0xC5
|
||||
};
|
||||
|
||||
|
||||
// AEON v2
|
||||
const static uint8_t test_output_v1_lite[64] = {
|
||||
// AEON v7
|
||||
const static uint8_t test_output_v1_lite[160] = {
|
||||
0x6D, 0x8C, 0xDC, 0x44, 0x4E, 0x9B, 0xBB, 0xFD, 0x68, 0xFC, 0x43, 0xFC, 0xD4, 0x85, 0x5B, 0x22,
|
||||
0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41,
|
||||
0x87, 0xC4, 0xE5, 0x70, 0x65, 0x3E, 0xB4, 0xC2, 0xB4, 0x2B, 0x7A, 0x0D, 0x54, 0x65, 0x59, 0x45,
|
||||
0x2D, 0xFA, 0xB5, 0x73, 0xB8, 0x2E, 0xC5, 0x2F, 0x15, 0x2B, 0x7F, 0xF9, 0x8E, 0x79, 0x44, 0x6F,
|
||||
0x6D, 0x8C, 0xDC, 0x44, 0x4E, 0x9B, 0xBB, 0xFD, 0x68, 0xFC, 0x43, 0xFC, 0xD4, 0x85, 0x5B, 0x22,
|
||||
0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41
|
||||
0x16, 0x08, 0x74, 0xC7, 0xA2, 0xD2, 0xA3, 0x97, 0x95, 0x76, 0xCA, 0x4D, 0x06, 0x39, 0x7A, 0xAB,
|
||||
0x6C, 0x87, 0x58, 0x33, 0x4D, 0xC8, 0x5A, 0xAB, 0x04, 0x27, 0xFE, 0x8B, 0x1C, 0x23, 0x2F, 0x32,
|
||||
0xC0, 0x44, 0xFF, 0x0D, 0xB5, 0x3B, 0x27, 0x96, 0x06, 0x89, 0x7B, 0xA3, 0x0B, 0xD0, 0xCE, 0x9E,
|
||||
0x90, 0x22, 0x77, 0x5A, 0xAD, 0xA1, 0xE5, 0xB6, 0xFC, 0xCB, 0x39, 0x7E, 0x2B, 0x10, 0xEE, 0xB4,
|
||||
0x8C, 0x2B, 0xA4, 0x1F, 0x60, 0x76, 0x39, 0xD7, 0xF6, 0x46, 0x77, 0x18, 0x20, 0xAD, 0xD4, 0xC9,
|
||||
0x87, 0xF7, 0x37, 0xDA, 0xFD, 0xBA, 0xBA, 0xD2, 0xF2, 0x68, 0xDC, 0x26, 0x8D, 0x1B, 0x08, 0xC6
|
||||
};
|
||||
|
||||
|
||||
// IPBC
|
||||
const static uint8_t test_output_ipbc_lite[160] = {
|
||||
0xE4, 0x93, 0x8C, 0xAA, 0x59, 0x8D, 0x02, 0x8A, 0xB8, 0x6F, 0x25, 0xD2, 0xB1, 0x23, 0xD0, 0xD5,
|
||||
0x33, 0xE3, 0x9F, 0x37, 0xAC, 0xE5, 0xF8, 0xEB, 0x7A, 0xE8, 0x40, 0xEB, 0x5D, 0xB1, 0x35, 0x5F,
|
||||
0xB2, 0x47, 0x86, 0xF0, 0x7F, 0x6F, 0x4B, 0x55, 0x3E, 0xA1, 0xBB, 0xE8, 0xA1, 0x75, 0x00, 0x2D,
|
||||
0x07, 0x9A, 0x21, 0x0E, 0xBD, 0x06, 0x6A, 0xB0, 0xFD, 0x96, 0x9E, 0xE6, 0xE4, 0x69, 0x67, 0xBB,
|
||||
0x88, 0x45, 0x0B, 0x91, 0x0B, 0x7B, 0xCB, 0x21, 0x3C, 0x3C, 0x09, 0x30, 0x07, 0x71, 0x07, 0xD5,
|
||||
0xB8, 0x2D, 0x83, 0x09, 0xAF, 0x7E, 0xB2, 0xA8, 0xAC, 0x25, 0xDC, 0x10, 0xF8, 0x63, 0x6A, 0xBC,
|
||||
0x73, 0x01, 0x4E, 0xA8, 0x1C, 0xDA, 0x9A, 0x86, 0x17, 0xEC, 0xA8, 0xFB, 0xAA, 0x23, 0x23, 0x17,
|
||||
0xE1, 0x32, 0x68, 0x9C, 0x4C, 0xF4, 0x08, 0xED, 0xB0, 0x15, 0xC3, 0xA9, 0x0F, 0xF0, 0xA2, 0x7E,
|
||||
0xD9, 0xE4, 0x23, 0xA7, 0x9E, 0x91, 0xD8, 0x73, 0x94, 0xD6, 0x6C, 0x70, 0x9B, 0x8B, 0x72, 0x92,
|
||||
0xA3, 0xA4, 0x0A, 0xE2, 0x3C, 0x0A, 0x34, 0x88, 0xA1, 0x6D, 0xFE, 0x02, 0x44, 0x60, 0x7B, 0x3D
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_SUMO
|
||||
const static uint8_t test_output_heavy[160] = {
|
||||
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
|
||||
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2,
|
||||
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
|
||||
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
|
||||
0x3E, 0xE1, 0x23, 0x03, 0x5A, 0x63, 0x7B, 0x66, 0xF6, 0xD7, 0xC2, 0x2A, 0x34, 0x5E, 0x88, 0xE7,
|
||||
0xFA, 0xC4, 0x25, 0x36, 0x54, 0xCB, 0xD2, 0x5C, 0x2F, 0x80, 0x2A, 0xF9, 0xCC, 0x43, 0xF7, 0xCD,
|
||||
0xE5, 0x18, 0xA8, 0x05, 0x60, 0x18, 0xA5, 0x73, 0x72, 0x9B, 0x32, 0xDC, 0x69, 0x83, 0xC1, 0xE1,
|
||||
0x1F, 0xDB, 0xDA, 0x6B, 0xAC, 0xEC, 0x9F, 0x67, 0xF8, 0x27, 0x1D, 0xC7, 0xE6, 0x46, 0x42, 0xF9,
|
||||
0x53, 0x62, 0x0A, 0x54, 0x7D, 0x43, 0xEA, 0x18, 0x94, 0xED, 0xD8, 0x92, 0x06, 0x6A, 0xA1, 0x51,
|
||||
0xAD, 0xB1, 0xFD, 0x89, 0xFB, 0x5C, 0xB4, 0x25, 0x6A, 0xDD, 0xB0, 0x09, 0xC5, 0x72, 0x87, 0xEB
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -34,14 +34,15 @@
|
|||
#endif
|
||||
|
||||
|
||||
#include "common/crypto/keccak.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "crypto/CryptoNight_monero.h"
|
||||
#include "crypto/soft_aes.h"
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "crypto/c_keccak.h"
|
||||
#include "crypto/c_groestl.h"
|
||||
#include "crypto/c_blake256.h"
|
||||
#include "crypto/c_jh.h"
|
||||
|
@ -217,7 +218,21 @@ static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2,
|
|||
}
|
||||
|
||||
|
||||
template<size_t MEM, bool SOFT_AES>
|
||||
inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3, __m128i& x4, __m128i& x5, __m128i& x6, __m128i& x7)
|
||||
{
|
||||
__m128i tmp0 = x0;
|
||||
x0 = _mm_xor_si128(x0, x1);
|
||||
x1 = _mm_xor_si128(x1, x2);
|
||||
x2 = _mm_xor_si128(x2, x3);
|
||||
x3 = _mm_xor_si128(x3, x4);
|
||||
x4 = _mm_xor_si128(x4, x5);
|
||||
x5 = _mm_xor_si128(x5, x6);
|
||||
x6 = _mm_xor_si128(x6, x7);
|
||||
x7 = _mm_xor_si128(x7, tmp0);
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, size_t MEM, bool SOFT_AES>
|
||||
static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
||||
{
|
||||
__m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7;
|
||||
|
@ -234,6 +249,23 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
|||
xin6 = _mm_load_si128(input + 10);
|
||||
xin7 = _mm_load_si128(input + 11);
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
||||
mix_and_propagate(xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
|
||||
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
@ -258,7 +290,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
|||
}
|
||||
|
||||
|
||||
template<size_t MEM, bool SOFT_AES>
|
||||
template<xmrig::Algo ALGO, size_t MEM, bool SOFT_AES>
|
||||
static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
||||
{
|
||||
__m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7;
|
||||
|
@ -296,6 +328,51 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||
}
|
||||
}
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
|
||||
xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0);
|
||||
xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1);
|
||||
xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2);
|
||||
xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3);
|
||||
xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4);
|
||||
xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5);
|
||||
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
|
||||
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
|
||||
|
||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||
}
|
||||
}
|
||||
|
||||
_mm_store_si128(output + 4, xout0);
|
||||
|
@ -309,23 +386,49 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
}
|
||||
|
||||
|
||||
template<size_t ITERATIONS, size_t MEM, size_t MASK, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx)
|
||||
template<int SHIFT>
|
||||
static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp)
|
||||
{
|
||||
keccak(input, (int) size, ctx->state0, 200);
|
||||
mem_out[0] = EXTRACT64(tmp);
|
||||
|
||||
VARIANT1_INIT(0);
|
||||
tmp = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(tmp), _mm_castsi128_ps(tmp)));
|
||||
uint64_t vh = EXTRACT64(tmp);
|
||||
|
||||
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) ctx->state0, (__m128i*) ctx->memory);
|
||||
uint8_t x = vh >> 24;
|
||||
static const uint16_t table = 0x7531;
|
||||
const uint8_t index = (((x >> SHIFT) & 6) | (x & 1)) << 1;
|
||||
vh ^= ((table >> index) & 0x3) << 28;
|
||||
|
||||
const uint8_t* l0 = ctx->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
|
||||
mem_out[1] = vh;
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
|
||||
|
||||
if (VARIANT > 0 && size < 43) {
|
||||
memset(output, 0, 32);
|
||||
return;
|
||||
}
|
||||
|
||||
xmrig::keccak(input, size, ctx[0]->state);
|
||||
|
||||
VARIANT1_INIT(0)
|
||||
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory);
|
||||
|
||||
const uint8_t* l0 = ctx[0]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
|
||||
uint64_t al0 = h0[0] ^ h0[4];
|
||||
uint64_t ah0 = h0[1] ^ h0[5];
|
||||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
|
||||
uint64_t idx0 = h0[0] ^ h0[4];
|
||||
uint64_t idx0 = al0;
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS; i++) {
|
||||
__m128i cx;
|
||||
|
@ -337,8 +440,13 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||
cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
|
||||
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0));
|
||||
}
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
|
||||
VARIANT1_1(&l0[idx0 & MASK]);
|
||||
|
||||
if (VARIANT > 0) {
|
||||
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
|
||||
} else {
|
||||
_mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
|
||||
}
|
||||
|
||||
idx0 = EXTRACT64(cx);
|
||||
bx0 = cx;
|
||||
|
||||
|
@ -350,39 +458,66 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||
al0 += hi;
|
||||
ah0 += lo;
|
||||
|
||||
VARIANT1_2(ah0, 0);
|
||||
((uint64_t*)&l0[idx0 & MASK])[0] = al0;
|
||||
((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
|
||||
VARIANT1_2(ah0, 0);
|
||||
|
||||
ah0 ^= ch;
|
||||
if (VARIANT > 0) {
|
||||
if (VARIANT == xmrig::VARIANT_IPBC) {
|
||||
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0;
|
||||
}
|
||||
else {
|
||||
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
|
||||
}
|
||||
|
||||
al0 ^= cl;
|
||||
ah0 ^= ch;
|
||||
idx0 = al0;
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0];
|
||||
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2];
|
||||
int64_t q = n / (d | 0x5);
|
||||
|
||||
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
|
||||
idx0 = d ^ q;
|
||||
}
|
||||
}
|
||||
|
||||
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) ctx->memory, (__m128i*) ctx->state0);
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state);
|
||||
|
||||
keccakf(h0, 24);
|
||||
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
|
||||
xmrig::keccakf(h0, 24);
|
||||
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
|
||||
}
|
||||
|
||||
|
||||
template<size_t ITERATIONS, size_t MEM, size_t MASK, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
keccak(input, (int) size, ctx->state0, 200);
|
||||
keccak(input + size, (int) size, ctx->state1, 200);
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
|
||||
|
||||
if (VARIANT > 0 && size < 43) {
|
||||
memset(output, 0, 64);
|
||||
return;
|
||||
}
|
||||
|
||||
xmrig::keccak(input, size, ctx[0]->state);
|
||||
xmrig::keccak(input + size, size, ctx[1]->state);
|
||||
|
||||
VARIANT1_INIT(0);
|
||||
VARIANT1_INIT(1);
|
||||
|
||||
const uint8_t* l0 = ctx->memory;
|
||||
const uint8_t* l1 = ctx->memory + MEM;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state1);
|
||||
const uint8_t* l0 = ctx[0]->memory;
|
||||
const uint8_t* l1 = ctx[1]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
|
||||
|
||||
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
|
||||
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
|
||||
|
||||
uint64_t al0 = h0[0] ^ h0[4];
|
||||
uint64_t al1 = h1[0] ^ h1[4];
|
||||
|
@ -392,8 +527,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
|
||||
|
||||
uint64_t idx0 = h0[0] ^ h0[4];
|
||||
uint64_t idx1 = h1[0] ^ h1[4];
|
||||
uint64_t idx0 = al0;
|
||||
uint64_t idx1 = al1;
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS; i++) {
|
||||
__m128i cx0, cx1;
|
||||
|
@ -409,10 +544,13 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1));
|
||||
}
|
||||
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
|
||||
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
|
||||
VARIANT1_1(&l0[idx0 & MASK]);
|
||||
VARIANT1_1(&l1[idx1 & MASK]);
|
||||
if (VARIANT > 0) {
|
||||
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
|
||||
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
|
||||
} else {
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
|
||||
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
|
||||
}
|
||||
|
||||
idx0 = EXTRACT64(cx0);
|
||||
idx1 = EXTRACT64(cx1);
|
||||
|
@ -428,15 +566,33 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
al0 += hi;
|
||||
ah0 += lo;
|
||||
|
||||
VARIANT1_2(ah0, 0);
|
||||
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
|
||||
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
|
||||
VARIANT1_2(ah0, 0);
|
||||
((uint64_t*)&l0[idx0 & MASK])[0] = al0;
|
||||
|
||||
if (VARIANT > 0) {
|
||||
if (VARIANT == xmrig::VARIANT_IPBC) {
|
||||
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0;
|
||||
}
|
||||
else {
|
||||
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
|
||||
}
|
||||
|
||||
ah0 ^= ch;
|
||||
al0 ^= cl;
|
||||
ah0 ^= ch;
|
||||
idx0 = al0;
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0];
|
||||
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2];
|
||||
int64_t q = n / (d | 0x5);
|
||||
|
||||
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
|
||||
idx0 = d ^ q;
|
||||
}
|
||||
|
||||
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
|
||||
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
|
||||
lo = __umul128(idx1, cl, &hi);
|
||||
|
@ -444,24 +600,420 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
al1 += hi;
|
||||
ah1 += lo;
|
||||
|
||||
VARIANT1_2(ah1, 1);
|
||||
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
|
||||
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
|
||||
VARIANT1_2(ah1, 1);
|
||||
((uint64_t*)&l1[idx1 & MASK])[0] = al1;
|
||||
|
||||
if (VARIANT > 0) {
|
||||
if (VARIANT == xmrig::VARIANT_IPBC) {
|
||||
((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1;
|
||||
}
|
||||
else {
|
||||
((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
((uint64_t*)&l1[idx1 & MASK])[1] = ah1;
|
||||
}
|
||||
|
||||
ah1 ^= ch;
|
||||
al1 ^= cl;
|
||||
ah1 ^= ch;
|
||||
idx1 = al1;
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
int64_t n = ((int64_t*)&l1[idx1 & MASK])[0];
|
||||
int32_t d = ((int32_t*)&l1[idx1 & MASK])[2];
|
||||
int64_t q = n / (d | 0x5);
|
||||
|
||||
((int64_t*)&l1[idx1 & MASK])[0] = n ^ q;
|
||||
idx1 = d ^ q;
|
||||
}
|
||||
}
|
||||
|
||||
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
|
||||
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
|
||||
|
||||
keccakf(h0, 24);
|
||||
keccakf(h1, 24);
|
||||
xmrig::keccakf(h0, 24);
|
||||
xmrig::keccakf(h1, 24);
|
||||
|
||||
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
|
||||
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32);
|
||||
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
|
||||
extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32);
|
||||
}
|
||||
|
||||
|
||||
#define CN_STEP1(a, b, c, l, ptr, idx) \
|
||||
ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \
|
||||
c = _mm_load_si128(ptr);
|
||||
|
||||
|
||||
#define CN_STEP2(a, b, c, l, ptr, idx) \
|
||||
if (SOFT_AES) { \
|
||||
c = soft_aesenc(c, a); \
|
||||
} else { \
|
||||
c = _mm_aesenc_si128(c, a); \
|
||||
} \
|
||||
\
|
||||
b = _mm_xor_si128(b, c); \
|
||||
\
|
||||
if (VARIANT > 0) { \
|
||||
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>(reinterpret_cast<uint64_t*>(ptr), b); \
|
||||
} else { \
|
||||
_mm_store_si128(ptr, b); \
|
||||
}
|
||||
|
||||
|
||||
#define CN_STEP3(a, b, c, l, ptr, idx) \
|
||||
idx = EXTRACT64(c); \
|
||||
ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \
|
||||
b = _mm_load_si128(ptr);
|
||||
|
||||
|
||||
#define CN_STEP4(a, b, c, l, mc, ptr, idx) \
|
||||
lo = __umul128(idx, EXTRACT64(b), &hi); \
|
||||
a = _mm_add_epi64(a, _mm_set_epi64x(lo, hi)); \
|
||||
\
|
||||
if (VARIANT > 0) { \
|
||||
_mm_store_si128(ptr, _mm_xor_si128(a, mc)); \
|
||||
\
|
||||
if (VARIANT == xmrig::VARIANT_IPBC) { \
|
||||
((uint64_t*)ptr)[1] ^= ((uint64_t*)ptr)[0]; \
|
||||
} \
|
||||
} else { \
|
||||
_mm_store_si128(ptr, a); \
|
||||
} \
|
||||
\
|
||||
a = _mm_xor_si128(a, b); \
|
||||
idx = EXTRACT64(a); \
|
||||
\
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { \
|
||||
int64_t n = ((int64_t*)&l[idx & MASK])[0]; \
|
||||
int32_t d = ((int32_t*)&l[idx & MASK])[2]; \
|
||||
int64_t q = n / (d | 0x5); \
|
||||
((int64_t*)&l[idx & MASK])[0] = n ^ q; \
|
||||
idx = d ^ q; \
|
||||
}
|
||||
|
||||
|
||||
#define CONST_INIT(ctx, n) \
|
||||
__m128i mc##n; \
|
||||
if (VARIANT > 0) { \
|
||||
mc##n = _mm_set_epi64x(*reinterpret_cast<const uint64_t*>(input + n * size + 35) ^ \
|
||||
*(reinterpret_cast<const uint64_t*>((ctx)->state) + 24), 0); \
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
|
||||
|
||||
if (VARIANT > 0 && size < 43) {
|
||||
memset(output, 0, 32 * 3);
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
xmrig::keccak(input + size * i, size, ctx[i]->state);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
||||
}
|
||||
|
||||
CONST_INIT(ctx[0], 0);
|
||||
CONST_INIT(ctx[1], 1);
|
||||
CONST_INIT(ctx[2], 2);
|
||||
|
||||
uint8_t* l0 = ctx[0]->memory;
|
||||
uint8_t* l1 = ctx[1]->memory;
|
||||
uint8_t* l2 = ctx[2]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
|
||||
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx[2]->state);
|
||||
|
||||
__m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]);
|
||||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
__m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]);
|
||||
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
|
||||
__m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]);
|
||||
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
|
||||
__m128i cx0 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx1 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx2 = _mm_set_epi64x(0, 0);
|
||||
|
||||
uint64_t idx0, idx1, idx2;
|
||||
idx0 = EXTRACT64(ax0);
|
||||
idx1 = EXTRACT64(ax1);
|
||||
idx2 = EXTRACT64(ax2);
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS / 2; i++) {
|
||||
uint64_t hi, lo;
|
||||
__m128i *ptr0, *ptr1, *ptr2;
|
||||
|
||||
// EVEN ROUND
|
||||
CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2);
|
||||
|
||||
// ODD ROUND
|
||||
CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
||||
xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
||||
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
|
||||
|
||||
if (VARIANT > 0 && size < 43) {
|
||||
memset(output, 0, 32 * 4);
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
xmrig::keccak(input + size * i, size, ctx[i]->state);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
||||
}
|
||||
|
||||
CONST_INIT(ctx[0], 0);
|
||||
CONST_INIT(ctx[1], 1);
|
||||
CONST_INIT(ctx[2], 2);
|
||||
CONST_INIT(ctx[3], 3);
|
||||
|
||||
uint8_t* l0 = ctx[0]->memory;
|
||||
uint8_t* l1 = ctx[1]->memory;
|
||||
uint8_t* l2 = ctx[2]->memory;
|
||||
uint8_t* l3 = ctx[3]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
|
||||
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx[2]->state);
|
||||
uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx[3]->state);
|
||||
|
||||
__m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]);
|
||||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
__m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]);
|
||||
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
|
||||
__m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]);
|
||||
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
|
||||
__m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]);
|
||||
__m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]);
|
||||
__m128i cx0 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx1 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx2 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx3 = _mm_set_epi64x(0, 0);
|
||||
|
||||
uint64_t idx0, idx1, idx2, idx3;
|
||||
idx0 = EXTRACT64(ax0);
|
||||
idx1 = EXTRACT64(ax1);
|
||||
idx2 = EXTRACT64(ax2);
|
||||
idx3 = EXTRACT64(ax3);
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS / 2; i++)
|
||||
{
|
||||
uint64_t hi, lo;
|
||||
__m128i *ptr0, *ptr1, *ptr2, *ptr3;
|
||||
|
||||
// EVEN ROUND
|
||||
CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2);
|
||||
CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3);
|
||||
|
||||
// ODD ROUND
|
||||
CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2);
|
||||
CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
||||
xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
||||
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
|
||||
|
||||
if (VARIANT > 0 && size < 43) {
|
||||
memset(output, 0, 32 * 5);
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
xmrig::keccak(input + size * i, size, ctx[i]->state);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
||||
}
|
||||
|
||||
CONST_INIT(ctx[0], 0);
|
||||
CONST_INIT(ctx[1], 1);
|
||||
CONST_INIT(ctx[2], 2);
|
||||
CONST_INIT(ctx[3], 3);
|
||||
CONST_INIT(ctx[4], 4);
|
||||
|
||||
uint8_t* l0 = ctx[0]->memory;
|
||||
uint8_t* l1 = ctx[1]->memory;
|
||||
uint8_t* l2 = ctx[2]->memory;
|
||||
uint8_t* l3 = ctx[3]->memory;
|
||||
uint8_t* l4 = ctx[4]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
|
||||
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx[2]->state);
|
||||
uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx[3]->state);
|
||||
uint64_t* h4 = reinterpret_cast<uint64_t*>(ctx[4]->state);
|
||||
|
||||
__m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]);
|
||||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
__m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]);
|
||||
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
|
||||
__m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]);
|
||||
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
|
||||
__m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]);
|
||||
__m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]);
|
||||
__m128i ax4 = _mm_set_epi64x(h4[1] ^ h4[5], h4[0] ^ h4[4]);
|
||||
__m128i bx4 = _mm_set_epi64x(h4[3] ^ h4[7], h4[2] ^ h4[6]);
|
||||
__m128i cx0 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx1 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx2 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx3 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx4 = _mm_set_epi64x(0, 0);
|
||||
|
||||
uint64_t idx0, idx1, idx2, idx3, idx4;
|
||||
idx0 = EXTRACT64(ax0);
|
||||
idx1 = EXTRACT64(ax1);
|
||||
idx2 = EXTRACT64(ax2);
|
||||
idx3 = EXTRACT64(ax3);
|
||||
idx4 = EXTRACT64(ax4);
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS / 2; i++)
|
||||
{
|
||||
uint64_t hi, lo;
|
||||
__m128i *ptr0, *ptr1, *ptr2, *ptr3, *ptr4;
|
||||
|
||||
// EVEN ROUND
|
||||
CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
CN_STEP1(ax4, bx4, cx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
CN_STEP2(ax4, bx4, cx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
CN_STEP3(ax4, bx4, cx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2);
|
||||
CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3);
|
||||
CN_STEP4(ax4, bx4, cx4, l4, mc4, ptr4, idx4);
|
||||
|
||||
// ODD ROUND
|
||||
CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
CN_STEP1(ax4, cx4, bx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
CN_STEP2(ax4, cx4, bx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
CN_STEP3(ax4, cx4, bx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2);
|
||||
CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3);
|
||||
CN_STEP4(ax4, cx4, bx4, l4, mc4, ptr4, idx4);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
||||
xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
||||
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __CRYPTONIGHT_X86_H__ */
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
// keccak.h
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
|
||||
#ifndef KECCAK_H
|
||||
#define KECCAK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef KECCAK_ROUNDS
|
||||
#define KECCAK_ROUNDS 24
|
||||
#endif
|
||||
|
||||
#ifndef ROTL64
|
||||
#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
|
||||
#endif
|
||||
|
||||
// compute a keccak hash (md) of given byte length from "in"
|
||||
int keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen);
|
||||
|
||||
// update the state
|
||||
void keccakf(uint64_t st[25], int norounds);
|
||||
|
||||
void keccak1600(const uint8_t *in, int inlen, uint8_t *md);
|
||||
|
||||
#endif
|
|
@ -105,6 +105,23 @@ static inline __m128i soft_aesenc(const uint32_t* in, __m128i key)
|
|||
return _mm_xor_si128(out, key);
|
||||
}
|
||||
|
||||
static inline __m128i soft_aesenc(__m128i in, __m128i key)
|
||||
{
|
||||
uint32_t x0, x1, x2, x3;
|
||||
x0 = _mm_cvtsi128_si32(in);
|
||||
x1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0x55));
|
||||
x2 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xAA));
|
||||
x3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xFF));
|
||||
|
||||
__m128i out = _mm_set_epi32(
|
||||
(saes_table[0][x3 & 0xff] ^ saes_table[1][(x0 >> 8) & 0xff] ^ saes_table[2][(x1 >> 16) & 0xff] ^ saes_table[3][x2 >> 24]),
|
||||
(saes_table[0][x2 & 0xff] ^ saes_table[1][(x3 >> 8) & 0xff] ^ saes_table[2][(x0 >> 16) & 0xff] ^ saes_table[3][x1 >> 24]),
|
||||
(saes_table[0][x1 & 0xff] ^ saes_table[1][(x2 >> 8) & 0xff] ^ saes_table[2][(x3 >> 16) & 0xff] ^ saes_table[3][x0 >> 24]),
|
||||
(saes_table[0][x0 & 0xff] ^ saes_table[1][(x1 >> 8) & 0xff] ^ saes_table[2][(x2 >> 16) & 0xff] ^ saes_table[3][x3 >> 24]));
|
||||
|
||||
return _mm_xor_si128(out, key);
|
||||
}
|
||||
|
||||
static inline uint32_t sub_word(uint32_t key)
|
||||
{
|
||||
return (saes_sbox[key >> 24 ] << 24) |
|
||||
|
|
14
src/donate.h
14
src/donate.h
|
@ -29,16 +29,22 @@
|
|||
* 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.
|
||||
* Since v2.5.1 start time randomized in range from 50 to 150 minutes minus donation time.
|
||||
*
|
||||
* Example of how it works for the setting of 1%:
|
||||
* You miner will mine into your usual pool for random time (in range from 49.5 to 148.5 minutes),
|
||||
* then switch to the developer's pool for 1 minute, then switch again to your pool for 99 minutes
|
||||
* and then switch agaiin to developer's pool for 1 minute, these rounds will continue until miner working.
|
||||
*
|
||||
* Randomised only first round, to prevent waves on the donation pool.
|
||||
*
|
||||
* Switching is instant, and only happens after a successful connection, so you never loose any hashes.
|
||||
*
|
||||
* If you plan on changing this setting to 0 please consider making a one off donation to my wallet:
|
||||
* XMR: 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD
|
||||
* BTC: 1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT
|
||||
*/
|
||||
constexpr const int kDonateLevel = 5;
|
||||
constexpr const int kDefaultDonateLevel = 5;
|
||||
constexpr const int kMinimumDonateLevel = 1;
|
||||
|
||||
|
||||
#endif /* __DONATE_H__ */
|
||||
|
|
110
src/interfaces/IConfig.h
Normal file
110
src/interfaces/IConfig.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ICONFIG_H__
|
||||
#define __ICONFIG_H__
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConfig
|
||||
{
|
||||
public:
|
||||
enum Keys {
|
||||
// common
|
||||
AlgorithmKey = 'a',
|
||||
ApiAccessTokenKey = 4001,
|
||||
ApiIPv6Key = 4003,
|
||||
ApiPort = 4000,
|
||||
ApiRestrictedKey = 4004,
|
||||
ApiWorkerIdKey = 4002,
|
||||
BackgroundKey = 'B',
|
||||
ColorKey = 1002,
|
||||
ConfigKey = 'c',
|
||||
DonateLevelKey = 1003,
|
||||
HelpKey = 'h',
|
||||
KeepAliveKey = 'k',
|
||||
LogFileKey = 'l',
|
||||
PasswordKey = 'p',
|
||||
RetriesKey = 'r',
|
||||
RetryPauseKey = 'R',
|
||||
RigIdKey = 1012,
|
||||
SyslogKey = 'S',
|
||||
UrlKey = 'o',
|
||||
UserAgentKey = 1008,
|
||||
UserKey = 'u',
|
||||
UserpassKey = 'O',
|
||||
VariantKey = 1010,
|
||||
VerboseKey = 1100,
|
||||
VersionKey = 'V',
|
||||
WatchKey = 1105,
|
||||
|
||||
// xmrig common
|
||||
CPUPriorityKey = 1021,
|
||||
NicehashKey = 1006,
|
||||
PrintTimeKey = 1007,
|
||||
|
||||
// xmrig cpu
|
||||
AVKey = 'v',
|
||||
CPUAffinityKey = 1020,
|
||||
DryRunKey = 5000,
|
||||
HugePagesKey = 1009,
|
||||
MaxCPUUsageKey = 1004,
|
||||
SafeKey = 1005,
|
||||
ThreadsKey = 't',
|
||||
HardwareAESKey = 1011,
|
||||
|
||||
// xmrig-proxy
|
||||
AccessLogFileKey = 'A',
|
||||
BindKey = 'b',
|
||||
CoinKey = 1104,
|
||||
CustomDiffKey = 1102,
|
||||
DebugKey = 1101,
|
||||
ModeKey = 'm',
|
||||
PoolCoinKey = 'C',
|
||||
ReuseTimeoutKey = 1106,
|
||||
WorkersKey = 1103,
|
||||
};
|
||||
|
||||
virtual ~IConfig() {}
|
||||
|
||||
virtual bool finalize() = 0;
|
||||
virtual bool isWatch() const = 0;
|
||||
virtual bool parseBoolean(int key, bool enable) = 0;
|
||||
virtual bool parseString(int key, const char *arg) = 0;
|
||||
virtual bool parseUint64(int key, uint64_t arg) = 0;
|
||||
virtual bool save() = 0;
|
||||
virtual const char *fileName() const = 0;
|
||||
virtual void getJSON(rapidjson::Document &doc) const = 0;
|
||||
virtual void parseJSON(const rapidjson::Document &doc) = 0;
|
||||
virtual void setFileName(const char *fileName) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // __ICONFIG_H__
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue