mirror of
https://github.com/xmrig/xmrig-proxy.git
synced 2026-02-16 22:42:25 +08:00
Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1080379350 | ||
|
|
ffe5fa7af9 | ||
|
|
8036e3dfa9 | ||
|
|
1b573ba99d | ||
|
|
3b82aad213 | ||
|
|
dc42d4b862 | ||
|
|
b52c3effa1 | ||
|
|
f35e1fbbb8 | ||
|
|
a5672912e6 | ||
|
|
48c72526a7 | ||
|
|
cde94e04c5 | ||
|
|
2ad6ff8acf | ||
|
|
35f4eff2db | ||
|
|
c0d3e2306d | ||
|
|
1ea7ce452f | ||
|
|
344f59d4a0 | ||
|
|
da967ced1b | ||
|
|
0263beb009 | ||
|
|
79f580df4b | ||
|
|
4fb3ea6e60 | ||
|
|
9efeb4a9b0 | ||
|
|
883ac25b03 | ||
|
|
4b8b045d6c | ||
|
|
2b190c30b9 | ||
|
|
bb9bfd970f | ||
|
|
2e392069c2 | ||
|
|
636800fdac | ||
|
|
7738b54de5 | ||
|
|
d8333c0ce8 | ||
|
|
84041c8ef5 | ||
|
|
f2c14e9425 | ||
|
|
e5ba679fe2 | ||
|
|
f04995f67c | ||
|
|
47153da760 | ||
|
|
1bad050ec1 | ||
|
|
c32f5ca12a | ||
|
|
880f777f4a | ||
|
|
747c6087be | ||
|
|
385eef78ac | ||
|
|
f7907829ce | ||
|
|
2689016a45 | ||
|
|
2f937eada6 | ||
|
|
c1e3f72b5b | ||
|
|
22071348de | ||
|
|
a64cfb0d94 | ||
|
|
c9ae1b91bd | ||
|
|
fd813fff4b | ||
|
|
669d45e575 | ||
|
|
e03005a85f | ||
|
|
537d5ae28e | ||
|
|
3c7077130d | ||
|
|
6dfb662d0a | ||
|
|
8d5f4b63d2 | ||
|
|
0d342aed29 | ||
|
|
4bd95cad19 | ||
|
|
c8da934297 | ||
|
|
b26d8001a3 | ||
|
|
ee59665c21 | ||
|
|
ca95a45773 | ||
|
|
dcca3fd7f6 | ||
|
|
d681854964 | ||
|
|
64628e41ac | ||
|
|
437909e4e9 | ||
|
|
3e7f690387 | ||
|
|
81b08fbcc7 | ||
|
|
3fdc2f4af6 | ||
|
|
63d5431d00 | ||
|
|
23b8d9e6fa | ||
|
|
1ea65898e7 |
70
.travis.yml
70
.travis.yml
@@ -1,70 +0,0 @@
|
||||
dist: trusty
|
||||
|
||||
osx_image: xcode8.3
|
||||
|
||||
sudo: false
|
||||
|
||||
language: cpp
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages: &default_packages
|
||||
- cmake
|
||||
- libuv-dev
|
||||
- uuid-dev
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- *default_packages
|
||||
- gcc-5
|
||||
- g++-5
|
||||
env:
|
||||
- CMAKE_CXX_COMPILER=g++-5
|
||||
- CMAKE_C_COMPILER=gcc-5
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- *default_packages
|
||||
- gcc-6
|
||||
- g++-6
|
||||
env:
|
||||
- CMAKE_CXX_COMPILER=g++-6
|
||||
- CMAKE_C_COMPILER=gcc-6
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- *default_packages
|
||||
- gcc-7
|
||||
- g++-7
|
||||
env:
|
||||
- CMAKE_CXX_COMPILER=g++-7
|
||||
- CMAKE_C_COMPILER=gcc-7
|
||||
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
|
||||
script:
|
||||
- if [ $TRAVIS_OS_NAME = osx ]; then
|
||||
brew install libuv;
|
||||
cmake .;
|
||||
else
|
||||
cmake -D CMAKE_C_COMPILER=${CMAKE_C_COMPILER} -D CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} .;
|
||||
fi;
|
||||
- make
|
||||
39
CHANGELOG.md
39
CHANGELOG.md
@@ -1,3 +1,42 @@
|
||||
# v2.5.2
|
||||
- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect.
|
||||
|
||||
# v2.5.0
|
||||
- [#119](https://github.com/xmrig/xmrig-proxy/issues/119) Added graceful reload support, pools and some other settings now can changed without proxy restart.
|
||||
- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/miner was parsed incorrectly.
|
||||
- [#40](https://github.com/xmrig/xmrig-proxy/issues/40#issuecomment-370202169) Added API endpoint `PUT /1/config` to update current config.
|
||||
- [#118](https://github.com/xmrig/xmrig-proxy/issues/118#issuecomment-375172833) Added alternative working mode, in that mode proxy support chaining and nicehash.com but lose ability to reduce connection count.
|
||||
- Added API endpoint `GET /1/config` to get current active config.
|
||||
- Messages `use pool` now shown only in verbose mode.
|
||||
- Added IPv6 support:
|
||||
- IPv6 now fully supported for connections to upstream pools.
|
||||
- `bind` now accept IPv6 addresses, for example, use `[::]:3333` to bind on all IPv6 interfaces and port 3333.
|
||||
- Internal HTTP server now support IPv6 for incoming connections.
|
||||
- New command line options (with equivalent config file options):
|
||||
- Added `--mode` to switch working mode.
|
||||
- Added `--reuse-timeout` to set timeout in seconds for reuse pool connections in simple mode.
|
||||
- Added `--no-watch` and config option `watch` to disable config file watching.
|
||||
- Added `--variant` to override PoW settings on xmrig miners.
|
||||
- Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API.
|
||||
- Added `--algo` to specify algorithm cryptonight or cryptonight-lite.
|
||||
- Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified.
|
||||
- Deprecations:
|
||||
- Option `coin` now deprecated, use `algo` instead.
|
||||
- API endpoint `GET /` now deprecated, use `GET /1/summary` instead.
|
||||
- API endpoint `GET /workers.json`, use `GET /1/workers` instead.
|
||||
|
||||
# v2.4.5
|
||||
- [#109](https://github.com/xmrig/xmrig-proxy/issues/109) Hashrate reports now more detailed for low speed workers.
|
||||
- [#200](https://github.com/xmrig/xmrig/issues/200) In some cases proxy was doesn't write log to stdout.
|
||||
|
||||
# v2.4.4
|
||||
- Added libmicrohttpd version to --version output.
|
||||
- Fixed bug in singal handler, in some cases proxy wasn't shutdown properly.
|
||||
- Fixed recent MSVC 2017 version detection.
|
||||
- Fixed in default `config.json` was missing option `colors`.
|
||||
- [#37](https://github.com/xmrig/xmrig-proxy/issues/37) Fixed ARM build.
|
||||
- [#70](https://github.com/xmrig/xmrig-proxy/issues/70) Now used kH/s instead of KH/s.
|
||||
|
||||
# v2.4.2
|
||||
- [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(xmrig-proxy)
|
||||
|
||||
|
||||
@@ -11,31 +11,36 @@ include (CheckIncludeFile)
|
||||
|
||||
set(HEADERS
|
||||
src/3rdparty/align.h
|
||||
src/api/Api.h
|
||||
src/api/ApiState.h
|
||||
src/App.h
|
||||
src/Console.h
|
||||
src/core/Config.h
|
||||
src/core/ConfigLoader.h
|
||||
src/core/ConfigLoader_static.h
|
||||
src/core/ConfigWatcher.h
|
||||
src/core/Controller.h
|
||||
src/donate.h
|
||||
src/interfaces/IClientListener.h
|
||||
src/interfaces/IConsoleListener.h
|
||||
src/interfaces/IControllerListener.h
|
||||
src/interfaces/IEvent.h
|
||||
src/interfaces/IEventListener.h
|
||||
src/interfaces/ILogBackend.h
|
||||
src/interfaces/ISplitter.h
|
||||
src/interfaces/IStrategy.h
|
||||
src/interfaces/IStrategyListener.h
|
||||
src/interfaces/IWatcherListener.h
|
||||
src/log/AccessLog.h
|
||||
src/log/ConsoleLog.h
|
||||
src/log/FileLog.h
|
||||
src/log/Log.h
|
||||
src/log/ShareLog.h
|
||||
src/net/Client.h
|
||||
src/net/Id.h
|
||||
src/net/Job.h
|
||||
src/net/JobId.h
|
||||
src/net/strategies/DonateStrategy.h
|
||||
src/net/strategies/FailoverStrategy.h
|
||||
src/net/strategies/SinglePoolStrategy.h
|
||||
src/net/Url.h
|
||||
src/Options.h
|
||||
src/Platform.h
|
||||
src/proxy/Addr.h
|
||||
src/proxy/Counters.h
|
||||
@@ -55,9 +60,12 @@ set(HEADERS
|
||||
src/proxy/Proxy.h
|
||||
src/proxy/ProxyDebug.h
|
||||
src/proxy/Server.h
|
||||
src/proxy/splitters/NonceMapper.h
|
||||
src/proxy/splitters/NonceSplitter.h
|
||||
src/proxy/splitters/NonceStorage.h
|
||||
src/proxy/splitters/nicehash/NonceMapper.h
|
||||
src/proxy/splitters/nicehash/NonceSplitter.h
|
||||
src/proxy/splitters/nicehash/NonceStorage.h
|
||||
src/proxy/splitters/simple/SimpleMapper.h
|
||||
src/proxy/splitters/simple/SimpleSplitter.h
|
||||
src/proxy/splitters/Splitter.h
|
||||
src/proxy/Stats.h
|
||||
src/proxy/StatsData.h
|
||||
src/proxy/TickingCounter.h
|
||||
@@ -66,13 +74,16 @@ set(HEADERS
|
||||
src/proxy/workers/Workers.h
|
||||
src/Summary.h
|
||||
src/version.h
|
||||
src/xmrig.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
src/api/Api.cpp
|
||||
src/api/ApiState.cpp
|
||||
src/App.cpp
|
||||
src/Console.cpp
|
||||
src/core/Config.cpp
|
||||
src/core/ConfigLoader.cpp
|
||||
src/core/ConfigWatcher.cpp
|
||||
src/core/Controller.cpp
|
||||
src/crypto/c_keccak.c
|
||||
src/crypto/c_keccak.h
|
||||
src/log/AccessLog.cpp
|
||||
@@ -87,7 +98,6 @@ set(SOURCES
|
||||
src/net/strategies/SinglePoolStrategy.cpp
|
||||
src/net/SubmitResult.cpp
|
||||
src/net/Url.cpp
|
||||
src/Options.cpp
|
||||
src/Platform.cpp
|
||||
src/proxy/Counters.cpp
|
||||
src/proxy/CustomDiff.cpp
|
||||
@@ -95,6 +105,7 @@ set(SOURCES
|
||||
src/proxy/Events.cpp
|
||||
src/proxy/events/ConnectionEvent.h
|
||||
src/proxy/events/Event.cpp
|
||||
src/proxy/events/MinerEvent.cpp
|
||||
src/proxy/JobResult.cpp
|
||||
src/proxy/LoginRequest.cpp
|
||||
src/proxy/Miner.cpp
|
||||
@@ -102,9 +113,12 @@ set(SOURCES
|
||||
src/proxy/Proxy.cpp
|
||||
src/proxy/ProxyDebug.cpp
|
||||
src/proxy/Server.cpp
|
||||
src/proxy/splitters/NonceMapper.cpp
|
||||
src/proxy/splitters/NonceSplitter.cpp
|
||||
src/proxy/splitters/NonceStorage.cpp
|
||||
src/proxy/splitters/nicehash/NonceMapper.cpp
|
||||
src/proxy/splitters/nicehash/NonceSplitter.cpp
|
||||
src/proxy/splitters/nicehash/NonceStorage.cpp
|
||||
src/proxy/splitters/simple/SimpleMapper.cpp
|
||||
src/proxy/splitters/simple/SimpleSplitter.cpp
|
||||
src/proxy/splitters/Splitter.cpp
|
||||
src/proxy/Stats.cpp
|
||||
src/proxy/workers/Worker.cpp
|
||||
src/proxy/workers/Workers.cpp
|
||||
@@ -145,10 +159,13 @@ add_definitions(/DXMRIG_PROXY_PROJECT)
|
||||
add_definitions(/DUNICODE)
|
||||
add_definitions(/D__STDC_FORMAT_MACROS)
|
||||
add_definitions(/DAPP_DEVEL)
|
||||
add_definitions(/DRAPIDJSON_SSE2)
|
||||
add_definitions(/DNDEBUG)
|
||||
#add_definitions(/DAPP_DEBUG)
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_definitions(/DRAPIDJSON_SSE2)
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
find_package(UV REQUIRED)
|
||||
@@ -215,7 +232,18 @@ if (WITH_HTTPD)
|
||||
|
||||
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/api/HttpBody.h
|
||||
src/api/Httpd.h
|
||||
src/api/HttpReply.h
|
||||
src/api/HttpRequest.h
|
||||
src/api/Api.cpp
|
||||
src/api/ApiRouter.cpp
|
||||
src/api/Httpd.cpp
|
||||
src/api/HttpRequest.cpp
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
|
||||
endif()
|
||||
|
||||
41
README.md
41
README.md
@@ -1,11 +1,17 @@
|
||||
# XMRig Proxy
|
||||
[](https://github.com/xmrig/xmrig-proxy/releases)
|
||||
[](https://github.com/xmrig/xmrig-proxy/releases)
|
||||
[](https://github.com/xmrig/xmrig-proxy/releases)
|
||||
[](https://github.com/xmrig/xmrig-proxy/blob/master/LICENSE)
|
||||
[](https://github.com/xmrig/xmrig-proxy/stargazers)
|
||||
[](https://github.com/xmrig/xmrig-proxy/network)
|
||||
|
||||
Extremely high performance Monero (XMR) Stratum protocol proxy, can easily handle over 100K connections on cheap $5 (1024 MB) virtual machine. Reduce number of pool connections up to 256 times, 100K workers become just 391 worker on pool side. Written on C++/libuv same as [XMRig](https://github.com/xmrig/xmrig) miner.
|
||||
|
||||
## Compatibility
|
||||
:warning: :warning: :warning: **Nicehash support must be enabled on miner side, it mandatory.** :warning: :warning: :warning:
|
||||
|
||||
* Compatible with any Monero and AEON pools, strongly recommended use pool with fixed diff feature.
|
||||
* Compatible with any Monero, Electroneum, Sumokoin and AEON pools, except **nicehash.com**.
|
||||
* Any miner with nicehash support, `--nicehash` option for [XMRig](https://github.com/xmrig/xmrig), `"nicehash_nonce": true,` for xmr-stak-cpu.
|
||||
* [Comparison](https://github.com/xmrig/xmrig-proxy/wiki/Comparison) with other proxies.
|
||||
|
||||
@@ -19,52 +25,57 @@ This proxy designed and created for handle donation traffic from XMRig. No one o
|
||||
|
||||
## Usage
|
||||
:boom: If you use Linux and want handle more than **1000 connections**, you need [increase limits of open files](https://github.com/xmrig/xmrig-proxy/wiki/Ubuntu-setup).
|
||||
### Basic example
|
||||
```
|
||||
xmrig-proxy.exe -o pool.minemonero.pro:5555 -u YOUR_WALLET -p x --bind 0.0.0.0:3333 --bind 0.0.0.0:5555
|
||||
```
|
||||
|
||||
### Failover
|
||||
```
|
||||
xmrig-proxy.exe -o pool.minemonero.pro:5555 -u YOUR_WALLET1 -o pool.supportxmr.com:5555 -u YOUR_WALLET2 -p x --bind 0.0.0.0:5555
|
||||
```
|
||||
For failover you can add multiple pools, maximum count not limited.
|
||||
Use [config.xmrig.com](https://config.xmrig.com/proxy) to generate, edit or share configurations.
|
||||
|
||||
### Options
|
||||
```
|
||||
-b, --bind=ADDR bind to specified address, example "0.0.0.0:3333"
|
||||
-a, --algo=ALGO cryptonight (default) or cryptonight-lite
|
||||
-m, --mode=MODE proxy mode, nicehash (default) or simple
|
||||
-o, --url=URL URL of mining server
|
||||
-O, --userpass=U:P username:password pair for mining server
|
||||
-u, --user=USERNAME username for mining server
|
||||
-p, --pass=PASSWORD password for mining server
|
||||
-r, --retries=N number of times to retry before switch to backup server (default: 5)
|
||||
-R, --retry-pause=N time to pause between retries (default: 5)
|
||||
-r, --retries=N number of times to retry before switch to backup server (default: 1)
|
||||
-R, --retry-pause=N time to pause between retries (default: 1 second)
|
||||
--custom-diff=N override pool diff
|
||||
--reuse-timeout=N timeout in seconds for reuse pool connections in simple mode
|
||||
--verbose verbose output
|
||||
--user-agent=AGENT set custom user-agent string for pool
|
||||
--coin=COIN xmr for all cryptonight coins or aeon
|
||||
--no-color disable colored output
|
||||
--no-workers disable per worker statistics
|
||||
--variant algorithm PoW variant
|
||||
--donate-level=N donate level, default 2%
|
||||
-B, --background run the miner in the background
|
||||
-c, --config=FILE load a JSON-format configuration file
|
||||
--no-watch disable configuration file watching
|
||||
-l, --log-file=FILE log all output to a file
|
||||
-S, --syslog use system log for output messages
|
||||
-A --access-log-file=N log all workers access to a file
|
||||
--api-port=N port for the miner API
|
||||
--api-access-token=T access token for API
|
||||
--api-access-token=T use Bearer access token for API
|
||||
--api-worker-id=ID custom worker-id for API
|
||||
--api-no-ipv6 disable IPv6 support for API
|
||||
--api-no-restricted enable full remote access (only if API token set)
|
||||
-h, --help display this help and exit
|
||||
-V, --version output version information and exit
|
||||
```
|
||||
|
||||
## Donations
|
||||
|
||||
Default donation fee is 2% can be reduced to 1% via `donate-level` option. Donation fee applyed only for second and more pool connection. If you use only one pool connection (up to 256 workers) there is no fee.
|
||||
Default donation fee is 2% can be reduced to 1% or disabled via `donate-level` option. Donation fee applies only if you use more than 256 miners.
|
||||
|
||||
* XMR: `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD`
|
||||
* BTC: `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT`
|
||||
|
||||
## Release checksums
|
||||
### SHA-256
|
||||
```
|
||||
005a90c13d0f1f37f5f1bafb41a5c20149df6e42e6a6991621335ccae9215c29 xmrig-proxy-2.5.2-win32/xmrig-proxy.exe
|
||||
58d1a6f03485a4ba7b3ab048831ac4886de8adf2e4f2448dab0d28ac29251d4c xmrig-proxy-2.5.2-win64/xmrig-proxy.exe
|
||||
```
|
||||
|
||||
## Contacts
|
||||
* support@xmrig.com
|
||||
* [reddit](https://www.reddit.com/user/XMRig/)
|
||||
|
||||
@@ -8,15 +8,25 @@
|
||||
find_path(
|
||||
MHD_INCLUDE_DIR
|
||||
NAMES microhttpd.h
|
||||
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
|
||||
PATH_SUFFIXES "include"
|
||||
DOC "microhttpd include dir"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
find_path(MHD_INCLUDE_DIR NAMES microhttpd.h)
|
||||
|
||||
find_library(
|
||||
MHD_LIBRARY
|
||||
NAMES microhttpd microhttpd-10 libmicrohttpd libmicrohttpd-dll
|
||||
NAMES libmicrohttpd.a microhttpd libmicrohttpd
|
||||
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
|
||||
PATH_SUFFIXES "lib"
|
||||
DOC "microhttpd library"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
find_library(MHD_LIBRARY NAMES microhttpd libmicrohttpd)
|
||||
|
||||
set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR})
|
||||
set(MHD_LIBRARIES ${MHD_LIBRARY})
|
||||
|
||||
@@ -34,6 +44,6 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(mhd DEFAULT_MSG MHD_INCLUDE_DIR MHD_LIBRARY)
|
||||
find_package_handle_standard_args(MHD DEFAULT_MSG MHD_LIBRARY MHD_INCLUDE_DIR)
|
||||
mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY)
|
||||
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
find_path(
|
||||
UV_INCLUDE_DIR
|
||||
NAMES uv.h
|
||||
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
|
||||
PATH_SUFFIXES "include"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
find_path(UV_INCLUDE_DIR NAMES uv.h)
|
||||
find_library(UV_LIBRARY NAMES uv libuv)
|
||||
|
||||
find_library(
|
||||
UV_LIBRARY
|
||||
NAMES libuv.a uv libuv
|
||||
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
|
||||
PATH_SUFFIXES "lib"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
find_library(UV_LIBRARY NAMES libuv.a uv libuv)
|
||||
|
||||
set(UV_LIBRARIES ${UV_LIBRARY})
|
||||
set(UV_INCLUDE_DIRS ${UV_INCLUDE_DIR})
|
||||
|
||||
BIN
res/app.ico
BIN
res/app.ico
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 21 KiB |
88
src/App.cpp
88
src/App.cpp
@@ -4,7 +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
|
||||
@@ -30,61 +31,37 @@
|
||||
#include "api/Api.h"
|
||||
#include "App.h"
|
||||
#include "Console.h"
|
||||
#include "log/ConsoleLog.h"
|
||||
#include "log/FileLog.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/Log.h"
|
||||
#include "Options.h"
|
||||
#include "Platform.h"
|
||||
#include "proxy/Proxy.h"
|
||||
#include "Summary.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
# include "log/SysLog.h"
|
||||
#endif
|
||||
|
||||
#ifndef XMRIG_NO_HTTPD
|
||||
# include "api/Httpd.h"
|
||||
#endif
|
||||
|
||||
App *App::m_self = nullptr;
|
||||
|
||||
|
||||
|
||||
App::App(int argc, char **argv) :
|
||||
m_console(nullptr),
|
||||
m_proxy(nullptr),
|
||||
m_options(nullptr)
|
||||
m_httpd(nullptr)
|
||||
{
|
||||
m_self = this;
|
||||
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()->background()) {
|
||||
m_console = new Console(this);
|
||||
}
|
||||
|
||||
if (m_options->logFile()) {
|
||||
Log::add(new FileLog(m_options->logFile()));
|
||||
}
|
||||
uv_signal_init(uv_default_loop(), &m_sigHUP);
|
||||
uv_signal_init(uv_default_loop(), &m_sigINT);
|
||||
uv_signal_init(uv_default_loop(), &m_sigTERM);
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
if (m_options->syslog()) {
|
||||
Log::add(new SysLog());
|
||||
}
|
||||
# endif
|
||||
|
||||
Platform::init(m_options->userAgent());
|
||||
|
||||
m_proxy = new Proxy(m_options);
|
||||
|
||||
uv_signal_init(uv_default_loop(), &m_signal);
|
||||
m_sigHUP.data = m_sigINT.data = m_sigTERM.data = this;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +70,7 @@ App::~App()
|
||||
uv_tty_reset_mode();
|
||||
|
||||
delete m_console;
|
||||
delete m_proxy;
|
||||
delete m_controller;
|
||||
|
||||
# ifndef XMRIG_NO_HTTPD
|
||||
delete m_httpd;
|
||||
@@ -105,33 +82,38 @@ App::~App()
|
||||
|
||||
int App::exec()
|
||||
{
|
||||
if (!m_options) {
|
||||
if (!m_controller->config()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uv_signal_start(&m_signal, App::onSignal, SIGHUP);
|
||||
uv_signal_start(&m_signal, App::onSignal, SIGTERM);
|
||||
uv_signal_start(&m_signal, App::onSignal, SIGINT);
|
||||
uv_signal_start(&m_sigHUP, App::onSignal, SIGHUP);
|
||||
uv_signal_start(&m_sigINT, App::onSignal, SIGINT);
|
||||
uv_signal_start(&m_sigTERM, App::onSignal, SIGTERM);
|
||||
|
||||
background();
|
||||
|
||||
Summary::print();
|
||||
Summary::print(m_controller);
|
||||
|
||||
# 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()->apiIPv6(),
|
||||
m_controller->config()->apiRestricted()
|
||||
);
|
||||
|
||||
m_httpd->start();
|
||||
# endif
|
||||
|
||||
m_proxy->connect();
|
||||
m_controller->proxy()->connect();
|
||||
|
||||
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
uv_loop_close(uv_default_loop());
|
||||
|
||||
Options::release();
|
||||
Platform::release();
|
||||
|
||||
return r;
|
||||
@@ -144,34 +126,34 @@ void App::onConsoleCommand(char command)
|
||||
# ifdef APP_DEVEL
|
||||
case 's':
|
||||
case 'S':
|
||||
m_proxy->printState();
|
||||
m_controller->proxy()->printState();
|
||||
break;
|
||||
# endif
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
Options::i()->toggleVerbose();
|
||||
LOG_NOTICE("verbose: %d", Options::i()->verbose());
|
||||
m_controller->config()->toggleVerbose();
|
||||
LOG_NOTICE("verbose: %d", m_controller->config()->verbose());
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case 'H':
|
||||
m_proxy->printHashrate();
|
||||
m_controller->proxy()->printHashrate();
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
m_proxy->printConnections();
|
||||
m_controller->proxy()->printConnections();
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'D':
|
||||
m_proxy->toggleDebug();
|
||||
m_controller->proxy()->toggleDebug();
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
case 'W':
|
||||
m_proxy->printWorkers();
|
||||
m_controller->proxy()->printWorkers();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@@ -212,5 +194,5 @@ void App::onSignal(uv_signal_t *handle, int signum)
|
||||
return;
|
||||
}
|
||||
|
||||
m_self->close();
|
||||
static_cast<App*>(handle->data)->close();
|
||||
}
|
||||
|
||||
17
src/App.h
17
src/App.h
@@ -4,7 +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
|
||||
@@ -37,6 +38,11 @@ class Proxy;
|
||||
class Options;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class App : public IConsoleListener
|
||||
{
|
||||
public:
|
||||
@@ -54,13 +60,12 @@ private:
|
||||
|
||||
static void onSignal(uv_signal_t *handle, int signum);
|
||||
|
||||
static App *m_self;
|
||||
|
||||
Console *m_console;
|
||||
Httpd *m_httpd;
|
||||
Proxy *m_proxy;
|
||||
Options *m_options;
|
||||
uv_signal_t m_signal;
|
||||
uv_signal_t m_sigHUP;
|
||||
uv_signal_t m_sigINT;
|
||||
uv_signal_t m_sigTERM;
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -29,15 +29,16 @@
|
||||
|
||||
|
||||
#include "App.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/Log.h"
|
||||
#include "Options.h"
|
||||
|
||||
|
||||
void App::background()
|
||||
{
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
if (!m_options->background()) {
|
||||
if (!m_controller->config()->background()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,13 @@
|
||||
|
||||
|
||||
#include "App.h"
|
||||
#include "Options.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
|
||||
|
||||
void App::background()
|
||||
{
|
||||
if (!m_options->background()) {
|
||||
if (!m_controller->config()->background()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
616
src/Options.cpp
616
src/Options.cpp
@@ -1,616 +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 2016-2017 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 <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include "getopt/getopt.h"
|
||||
#else
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
#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\
|
||||
-b, --bind=ADDR bind to specified address, example \"0.0.0.0:3333\"\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\
|
||||
-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\
|
||||
--custom-diff=N override pool diff\n\
|
||||
--verbose verbose output\n\
|
||||
--user-agent=AGENT set custom user-agent string for pool\n\
|
||||
--coin=COIN xmr for all cryptonight coins or aeon\n\
|
||||
--no-color disable colored output\n\
|
||||
--no-workers disable per worker statistics\n\
|
||||
--donate-level=N donate level, default 2%%\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
|
||||
"\
|
||||
-A --access-log-file=N log all workers access to a file\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[] = "c:khBp:Px:r:R:s:T:o:u:O:Vl:Sb:A:";
|
||||
|
||||
|
||||
static struct option const options[] = {
|
||||
{ "access-log-file", 1, nullptr, 'A' },
|
||||
{ "api-access-token", 1, nullptr, 4001 },
|
||||
{ "api-port", 1, nullptr, 4000 },
|
||||
{ "api-worker-id", 1, nullptr, 4002 },
|
||||
{ "background", 0, nullptr, 'B' },
|
||||
{ "bind", 1, nullptr, 'b' },
|
||||
{ "coin", 1, nullptr, 1104 },
|
||||
{ "config", 1, nullptr, 'c' },
|
||||
{ "custom-diff", 1, nullptr, 1102 },
|
||||
{ "debug", 0, nullptr, 1101 },
|
||||
{ "donate-level", 1, nullptr, 1003 },
|
||||
{ "help", 0, nullptr, 'h' },
|
||||
{ "keepalive", 0, nullptr ,'k' },
|
||||
{ "log-file", 1, nullptr, 'l' },
|
||||
{ "no-color", 0, nullptr, 1002 },
|
||||
{ "no-workers", 0, nullptr, 1103 },
|
||||
{ "pass", 1, nullptr, 'p' },
|
||||
{ "retries", 1, nullptr, 'r' },
|
||||
{ "retry-pause", 1, nullptr, 'R' },
|
||||
{ "syslog", 0, nullptr, 'S' },
|
||||
{ "url", 1, nullptr, 'o' },
|
||||
{ "user", 1, nullptr, 'u' },
|
||||
{ "user-agent", 1, nullptr, 1008 },
|
||||
{ "userpass", 1, nullptr, 'O' },
|
||||
{ "verbose", 0, nullptr, 1100 },
|
||||
{ "version", 0, nullptr, 'V' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct option const config_options[] = {
|
||||
{ "access-log-file", 1, nullptr, 'A' },
|
||||
{ "background", 0, nullptr, 'B' },
|
||||
{ "coin", 1, nullptr, 1104 },
|
||||
{ "colors", 0, nullptr, 2000 },
|
||||
{ "custom-diff", 1, nullptr, 1102 },
|
||||
{ "debug", 0, nullptr, 1101 },
|
||||
{ "donate-level", 1, nullptr, 1003 },
|
||||
{ "log-file", 1, nullptr, 'l' },
|
||||
{ "retries", 1, nullptr, 'r' },
|
||||
{ "retry-pause", 1, nullptr, 'R' },
|
||||
{ "syslog", 0, nullptr, 'S' },
|
||||
{ "user-agent", 1, nullptr, 1008 },
|
||||
{ "verbose", 0, nullptr, 1100 },
|
||||
{ "workers", 0, nullptr, 1103 },
|
||||
{ 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' },
|
||||
{ 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 }
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Options::Options(int argc, char **argv) :
|
||||
m_background(false),
|
||||
m_colors(true),
|
||||
m_debug(false),
|
||||
m_ready(false),
|
||||
m_syslog(false),
|
||||
m_verbose(false),
|
||||
m_workers(true),
|
||||
m_accessLog(nullptr),
|
||||
m_apiToken(nullptr),
|
||||
m_apiWorkerId(nullptr),
|
||||
m_coin(nullptr),
|
||||
m_logFile(nullptr),
|
||||
m_userAgent(nullptr),
|
||||
m_apiPort(0),
|
||||
m_donateLevel(kDonateLevel),
|
||||
m_retries(5),
|
||||
m_retryPause(5),
|
||||
m_diff(0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (m_addrs.empty()) {
|
||||
m_addrs.push_back(new Addr("0.0.0.0:3333"));
|
||||
}
|
||||
|
||||
m_ready = true;
|
||||
}
|
||||
|
||||
|
||||
Options::~Options()
|
||||
{
|
||||
for (Addr *addr : m_addrs) {
|
||||
delete addr;
|
||||
}
|
||||
|
||||
for (Url *url : m_pools) {
|
||||
delete url;
|
||||
}
|
||||
|
||||
m_addrs.clear();
|
||||
m_pools.clear();
|
||||
|
||||
free(m_accessLog);
|
||||
free(m_apiToken);
|
||||
free(m_apiWorkerId);
|
||||
free(m_coin);
|
||||
free(m_logFile);
|
||||
free(m_userAgent);
|
||||
}
|
||||
|
||||
|
||||
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 'b': /* --bind */
|
||||
{
|
||||
Addr *addr = new Addr(arg);
|
||||
if (addr->isValid()) {
|
||||
m_addrs.push_back(addr);
|
||||
}
|
||||
else {
|
||||
delete addr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'O': /* --userpass */
|
||||
if (!m_pools.back()->setUserpass(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 '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);
|
||||
break;
|
||||
|
||||
case 'A': /* --access-log-file **/
|
||||
free(m_accessLog);
|
||||
m_accessLog = strdup(arg);
|
||||
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 1102: /* --custom-diff */
|
||||
case 4000: /* --api-port */
|
||||
return parseArg(key, strtol(arg, nullptr, 10));
|
||||
|
||||
case 'B': /* --background */
|
||||
case 'k': /* --keepalive */
|
||||
case 'S': /* --syslog */
|
||||
case 1100: /* --verbose */
|
||||
case 1101: /* --debug */
|
||||
return parseBoolean(key, true);
|
||||
|
||||
case 1002: /* --no-color */
|
||||
case 1103: /* --no-workers */
|
||||
return parseBoolean(key, false);
|
||||
|
||||
case 1003: /* --donate-level */
|
||||
if (strncmp(arg, "minemonero.pro", 14) == 0) {
|
||||
m_donateLevel = 0;
|
||||
}
|
||||
else {
|
||||
parseArg(key, strtol(arg, nullptr, 10));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1104: /* --coin */
|
||||
free(m_coin);
|
||||
m_coin = strdup(arg);
|
||||
break;
|
||||
|
||||
case 'V': /* --version */
|
||||
showVersion();
|
||||
return false;
|
||||
|
||||
case 'h': /* --help */
|
||||
showUsage(0);
|
||||
return false;
|
||||
|
||||
case 'c': /* --config */
|
||||
parseConfig(arg);
|
||||
break;
|
||||
|
||||
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 1003: /* --donate-level */
|
||||
if (arg < 1 || arg > 99) {
|
||||
return true;
|
||||
}
|
||||
|
||||
m_donateLevel = (int) arg;
|
||||
break;
|
||||
|
||||
case 4000: /* --api-port */
|
||||
if (arg <= 65536) {
|
||||
m_apiPort = (int) arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1102: /* --custom-diff */
|
||||
if (arg >= 100 && arg < INT_MAX) {
|
||||
m_diff = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Options::parseBoolean(int key, bool enable)
|
||||
{
|
||||
switch (key) {
|
||||
case 'B': /* --background */
|
||||
m_background = enable;
|
||||
break;
|
||||
|
||||
case 'k': /* --keepalive */
|
||||
m_pools.back()->setKeepAlive(enable);
|
||||
break;
|
||||
|
||||
case 'S': /* --syslog */
|
||||
m_syslog = enable;
|
||||
break;
|
||||
|
||||
case 1002: /* --no-color */
|
||||
m_colors = enable;
|
||||
break;
|
||||
|
||||
case 1100: /* --verbose */
|
||||
m_verbose = enable;
|
||||
break;
|
||||
|
||||
case 1101: /* --debug */
|
||||
m_debug = enable;
|
||||
break;
|
||||
|
||||
case 2000: /* colors */
|
||||
m_colors = enable;
|
||||
break;
|
||||
|
||||
case 1103: /* workers */
|
||||
m_workers = 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::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 &bind = doc["bind"];
|
||||
if (bind.IsArray()) {
|
||||
for (const rapidjson::Value &value : bind.GetArray()) {
|
||||
if (!value.IsString()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
parseArg('b', value.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
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.IsUint64()) {
|
||||
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());
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/resource.h>
|
||||
#include <uv.h>
|
||||
@@ -41,11 +42,11 @@ static inline char *createUserAgent()
|
||||
|
||||
char *buf = new char[max];
|
||||
|
||||
# ifdef XMRIG_NVIDIA_PROJECT
|
||||
const int cudaVersion = cuda_get_runtime_version();
|
||||
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s CUDA/%d.%d clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), cudaVersion / 1000, cudaVersion % 100, __clang_major__, __clang_minor__, __clang_patchlevel__);
|
||||
# else
|
||||
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), __clang_major__, __clang_minor__, __clang_patchlevel__);
|
||||
# ifdef XMRIG_NVIDIA_PROJECT
|
||||
const int cudaVersion = cuda_get_runtime_version();
|
||||
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s CUDA/%d.%d clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), cudaVersion / 1000, cudaVersion % 100, __clang_major__, __clang_minor__, __clang_patchlevel__);
|
||||
# else
|
||||
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), __clang_major__, __clang_minor__, __clang_patchlevel__);
|
||||
# endif
|
||||
|
||||
return buf;
|
||||
|
||||
@@ -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,14 +26,16 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/Log.h"
|
||||
#include "net/Url.h"
|
||||
#include "Options.h"
|
||||
#include "proxy/Addr.h"
|
||||
#include "Summary.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
static void print_versions()
|
||||
static void print_versions(xmrig::Controller *controller)
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
@@ -48,7 +50,7 @@ static void print_versions()
|
||||
# endif
|
||||
|
||||
|
||||
if (Options::i()->colors()) {
|
||||
if (controller->config()->colors()) {
|
||||
Log::i()->text("\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mxmrig-proxy/%s\x1B[01;37m libuv/%s%s", APP_VERSION, uv_version_string(), buf);
|
||||
} else {
|
||||
Log::i()->text(" * VERSIONS: xmrig-proxy/%s libuv/%s%s", APP_VERSION, uv_version_string(), buf);
|
||||
@@ -56,53 +58,45 @@ static void print_versions()
|
||||
}
|
||||
|
||||
|
||||
static void print_pools()
|
||||
static void print_mode(xmrig::Controller *controller)
|
||||
{
|
||||
const std::vector<Url*> &pools = Options::i()->pools();
|
||||
|
||||
for (size_t i = 0; i < pools.size(); ++i) {
|
||||
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d:\x1B[0m \x1B[36m%s:%d" : " * POOL #%d: %s:%d",
|
||||
i + 1,
|
||||
pools[i]->host(),
|
||||
pools[i]->port());
|
||||
}
|
||||
|
||||
# ifdef APP_DEBUG
|
||||
for (size_t i = 0; i < pools.size(); ++i) {
|
||||
Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i]->host(), pools[i]->port(), pools[i]->user(), pools[i]->password(), pools[i]->isKeepAlive(), pools[i]->isNicehash());
|
||||
}
|
||||
# endif
|
||||
Log::i()->text(controller->config()->colors() ? "\x1B[01;32m * \x1B[01;37mMODE:\x1B[0m \x1B[01;37m%s" : " * MODE: %s",
|
||||
controller->config()->modeName());
|
||||
}
|
||||
|
||||
|
||||
static void print_bind()
|
||||
static void print_bind(xmrig::Controller *controller)
|
||||
{
|
||||
const std::vector<Addr*> &addrs = Options::i()->addrs();
|
||||
const std::vector<Addr*> &addrs = controller->config()->addrs();
|
||||
|
||||
for (size_t i = 0; i < addrs.size(); ++i) {
|
||||
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mBIND #%d:\x1B[0m \x1B[36m%s:%d" : " * BIND #%d: %s:%d",
|
||||
Log::i()->text(controller->config()->colors() ? "\x1B[01;32m * \x1B[01;37mBIND #%d:\x1B[0m \x1B[36m%s%s%s:%d" : " * BIND #%d: %s%s%s:%d",
|
||||
i + 1,
|
||||
addrs[i]->host(),
|
||||
addrs[i]->isIPv6() ? "[" : "",
|
||||
addrs[i]->ip(),
|
||||
addrs[i]->isIPv6() ? "]" : "",
|
||||
addrs[i]->port());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_API
|
||||
static void print_api()
|
||||
static void print_api(xmrig::Controller *controller)
|
||||
{
|
||||
if (Options::i()->apiPort() == 0) {
|
||||
const int port = controller->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(controller->config()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI BIND: \x1B[01;36m%s:%d" : " * API BIND: %s:%d",
|
||||
controller->config()->apiIPv6() ? "[::]" : "0.0.0.0", port);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void print_commands()
|
||||
static void print_commands(xmrig::Controller *controller)
|
||||
{
|
||||
if (Options::i()->colors()) {
|
||||
if (controller->config()->colors()) {
|
||||
Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mh\x1B[01;37mashrate, \x1B[01;35mc\x1B[01;37monnections, \x1B[01;35mv\x1B[01;37merbose, \x1B[01;35mw\x1B[01;37morkers");
|
||||
}
|
||||
else {
|
||||
@@ -111,17 +105,37 @@ static void print_commands()
|
||||
}
|
||||
|
||||
|
||||
void Summary::print()
|
||||
void Summary::print(xmrig::Controller *controller)
|
||||
{
|
||||
print_versions();
|
||||
print_pools();
|
||||
print_bind();
|
||||
print_versions(controller);
|
||||
print_mode(controller);
|
||||
printPools(controller->config());
|
||||
print_bind(controller);
|
||||
|
||||
# ifndef XMRIG_NO_API
|
||||
print_api();
|
||||
print_api(controller);
|
||||
# endif
|
||||
|
||||
print_commands();
|
||||
print_commands(controller);
|
||||
}
|
||||
|
||||
|
||||
void Summary::printPools(xmrig::Config *config)
|
||||
{
|
||||
const std::vector<Url*> &pools = config->pools();
|
||||
|
||||
for (size_t i = 0; i < pools.size(); ++i) {
|
||||
Log::i()->text(config->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d:\x1B[0m \x1B[36m%s:%d" : " * POOL #%d: %s:%d",
|
||||
i + 1,
|
||||
pools[i]->host(),
|
||||
pools[i]->port());
|
||||
}
|
||||
|
||||
# ifdef APP_DEBUG
|
||||
for (size_t i = 0; i < pools.size(); ++i) {
|
||||
Log::i()->text("%s:%d, user: %s, pass: %s", pools[i]->host(), pools[i]->port(), pools[i]->user(), pools[i]->password());
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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,17 @@
|
||||
#define __SUMMARY_H__
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Config;
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class Summary
|
||||
{
|
||||
public:
|
||||
static void print();
|
||||
static void print(xmrig::Controller *controller);
|
||||
static void printPools(xmrig::Config *config);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +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
|
||||
@@ -25,17 +26,17 @@
|
||||
|
||||
|
||||
#include "api/Api.h"
|
||||
#include "api/ApiState.h"
|
||||
#include "api/ApiRouter.h"
|
||||
#include "api/HttpReply.h"
|
||||
#include "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 +44,20 @@ 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 StatsData &data)
|
||||
{
|
||||
if (!m_state) {
|
||||
if (!m_router) {
|
||||
reply.status = 500;
|
||||
return;
|
||||
}
|
||||
|
||||
uv_mutex_lock(&m_mutex);
|
||||
m_state->tick(data);
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
|
||||
void Api::tick(const std::vector<Worker> &workers)
|
||||
{
|
||||
if (!m_state) {
|
||||
return;
|
||||
if (req.method() == xmrig::HttpRequest::Get) {
|
||||
return m_router->get(req, reply);
|
||||
}
|
||||
|
||||
uv_mutex_lock(&m_mutex);
|
||||
m_state->tick(workers);
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
m_router->exec(req, reply);
|
||||
}
|
||||
|
||||
@@ -4,7 +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
|
||||
@@ -25,31 +26,26 @@
|
||||
#define __API_H__
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
class ApiRouter;
|
||||
|
||||
|
||||
#include "proxy/workers/Worker.h"
|
||||
|
||||
|
||||
class ApiState;
|
||||
class Hashrate;
|
||||
class StatsData;
|
||||
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 StatsData &data);
|
||||
static void tick(const std::vector<Worker> &workers);
|
||||
static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
||||
|
||||
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,13 +32,16 @@
|
||||
#endif
|
||||
|
||||
|
||||
#include "api/ApiState.h"
|
||||
#include "api/ApiRouter.h"
|
||||
#include "api/HttpReply.h"
|
||||
#include "api/HttpRequest.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.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"
|
||||
|
||||
|
||||
@@ -58,78 +61,90 @@ static inline double normalize(double d)
|
||||
}
|
||||
|
||||
|
||||
ApiState::ApiState()
|
||||
ApiRouter::ApiRouter(xmrig::Controller *controller) :
|
||||
m_controller(controller)
|
||||
{
|
||||
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();
|
||||
|
||||
controller->addListener(this);
|
||||
}
|
||||
|
||||
|
||||
ApiState::~ApiState()
|
||||
ApiRouter::~ApiRouter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
char *ApiState::get(const char *url, int *status) const
|
||||
void ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
doc.SetObject();
|
||||
|
||||
if (strncmp(url, "/workers.json", 13) == 0) {
|
||||
if (req.match("/1/workers") || req.match("/workers.json")) {
|
||||
getHashrate(doc);
|
||||
getWorkers(doc);
|
||||
|
||||
return finalize(doc);
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
if (strncmp(url, "/resources.json", 15) == 0) {
|
||||
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/resources") || req.match("/resources.json")) {
|
||||
getResources(doc);
|
||||
|
||||
return finalize(doc);
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
getIdentify(doc);
|
||||
getMiner(doc);
|
||||
getHashrate(doc);
|
||||
getMinersSummary(doc);
|
||||
getMinersSummary(doc, req.match("/1/summary"));
|
||||
getResults(doc);
|
||||
|
||||
return finalize(doc);
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
|
||||
void ApiState::tick(const StatsData &data)
|
||||
void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
|
||||
{
|
||||
m_stats = data;
|
||||
if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) {
|
||||
m_controller->config()->reload(req.body());
|
||||
return;
|
||||
}
|
||||
|
||||
reply.status = 404;
|
||||
}
|
||||
|
||||
|
||||
void ApiState::tick(const std::vector<Worker> &workers)
|
||||
void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
|
||||
{
|
||||
m_workers = workers;
|
||||
updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId());
|
||||
}
|
||||
|
||||
|
||||
char *ApiState::finalize(rapidjson::Document &doc) const
|
||||
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));
|
||||
|
||||
@@ -162,15 +177,17 @@ void ApiState::genId()
|
||||
}
|
||||
|
||||
|
||||
void ApiState::getHashrate(rapidjson::Document &doc) const
|
||||
void ApiRouter::getHashrate(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
rapidjson::Value hashrate(rapidjson::kObjectType);
|
||||
rapidjson::Value total(rapidjson::kArrayType);
|
||||
|
||||
for (size_t i = 0; i < sizeof(m_stats.hashrate) / sizeof(m_stats.hashrate[0]); i++) {
|
||||
total.PushBack(normalize(m_stats.hashrate[i]), allocator);
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
for (size_t i = 0; i < sizeof(stats.hashrate) / sizeof(stats.hashrate[0]); i++) {
|
||||
total.PushBack(normalize(stats.hashrate[i]), allocator);
|
||||
}
|
||||
|
||||
hashrate.AddMember("total", total, allocator);
|
||||
@@ -178,25 +195,27 @@ void ApiState::getHashrate(rapidjson::Document &doc) const
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
doc.AddMember("version", APP_VERSION, allocator);
|
||||
doc.AddMember("kind", APP_KIND, allocator);
|
||||
doc.AddMember("mode", rapidjson::StringRef(m_controller->config()->modeName()), allocator);
|
||||
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
|
||||
doc.AddMember("uptime", m_stats.uptime(), allocator);
|
||||
doc.AddMember("donate_level", Options::i()->donateLevel(), allocator);
|
||||
doc.AddMember("uptime", stats.uptime(), allocator);
|
||||
doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator);
|
||||
|
||||
if (m_stats.hashes && m_stats.donateHashes) {
|
||||
doc.AddMember("donated", normalize((double) m_stats.donateHashes / m_stats.hashes * 100.0), allocator);
|
||||
if (stats.hashes && stats.donateHashes) {
|
||||
doc.AddMember("donated", normalize((double) stats.donateHashes / stats.hashes * 100.0), allocator);
|
||||
}
|
||||
else {
|
||||
doc.AddMember("donated", 0.0, allocator);
|
||||
@@ -204,22 +223,37 @@ void ApiState::getMiner(rapidjson::Document &doc) const
|
||||
}
|
||||
|
||||
|
||||
void ApiState::getMinersSummary(rapidjson::Document &doc) const
|
||||
void ApiRouter::getMinersSummary(rapidjson::Document &doc, bool advanced) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
rapidjson::Value miners(rapidjson::kObjectType);
|
||||
|
||||
miners.AddMember("now", m_stats.miners, allocator);
|
||||
miners.AddMember("max", m_stats.maxMiners, allocator);
|
||||
miners.AddMember("now", stats.miners, allocator);
|
||||
miners.AddMember("max", stats.maxMiners, allocator);
|
||||
|
||||
doc.AddMember("miners", miners, allocator);
|
||||
doc.AddMember("upstreams", m_stats.upstreams, allocator);
|
||||
doc.AddMember("miners", miners, allocator);
|
||||
|
||||
if (advanced) {
|
||||
rapidjson::Value upstreams(rapidjson::kObjectType);
|
||||
|
||||
upstreams.AddMember("active", stats.upstreams.active, allocator);
|
||||
upstreams.AddMember("sleep", stats.upstreams.sleep, allocator);
|
||||
upstreams.AddMember("error", stats.upstreams.error, allocator);
|
||||
upstreams.AddMember("total", stats.upstreams.total, allocator);
|
||||
upstreams.AddMember("ratio", normalize(stats.upstreams.ratio), allocator);
|
||||
|
||||
doc.AddMember("upstreams", upstreams, allocator);
|
||||
}
|
||||
else {
|
||||
doc.AddMember("upstreams", stats.upstreams.active, allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ApiState::getResources(rapidjson::Document &doc) const
|
||||
void ApiRouter::getResources(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
size_t rss = 0;
|
||||
@@ -230,24 +264,25 @@ void ApiState::getResources(rapidjson::Document &doc) const
|
||||
}
|
||||
|
||||
|
||||
void ApiState::getResults(rapidjson::Document &doc) const
|
||||
void ApiRouter::getResults(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
rapidjson::Value results(rapidjson::kObjectType);
|
||||
|
||||
results.AddMember("accepted", m_stats.accepted, allocator);
|
||||
results.AddMember("rejected", m_stats.rejected, allocator);
|
||||
results.AddMember("invalid", m_stats.invalid, allocator);
|
||||
results.AddMember("expired", m_stats.expired, allocator);
|
||||
results.AddMember("avg_time", m_stats.avgTime(), allocator);
|
||||
results.AddMember("latency", m_stats.avgLatency(), allocator);
|
||||
results.AddMember("hashes_total", m_stats.hashes, allocator);
|
||||
results.AddMember("hashes_donate", m_stats.donateHashes, allocator);
|
||||
results.AddMember("accepted", stats.accepted, allocator);
|
||||
results.AddMember("rejected", stats.rejected, allocator);
|
||||
results.AddMember("invalid", stats.invalid, allocator);
|
||||
results.AddMember("expired", stats.expired, allocator);
|
||||
results.AddMember("avg_time", stats.avgTime(), allocator);
|
||||
results.AddMember("latency", stats.avgLatency(), allocator);
|
||||
results.AddMember("hashes_total", stats.hashes, allocator);
|
||||
results.AddMember("hashes_donate", stats.donateHashes, allocator);
|
||||
|
||||
rapidjson::Value best(rapidjson::kArrayType);
|
||||
for (size_t i = 0; i < m_stats.topDiff.size(); ++i) {
|
||||
best.PushBack(m_stats.topDiff[i], allocator);
|
||||
for (size_t i = 0; i < stats.topDiff.size(); ++i) {
|
||||
best.PushBack(stats.topDiff[i], allocator);
|
||||
}
|
||||
|
||||
results.AddMember("best", best, allocator);
|
||||
@@ -256,12 +291,14 @@ void ApiState::getResults(rapidjson::Document &doc) const
|
||||
}
|
||||
|
||||
|
||||
void ApiState::getWorkers(rapidjson::Document &doc) const
|
||||
void ApiRouter::getWorkers(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &list = m_controller->workers();
|
||||
|
||||
rapidjson::Value workers(rapidjson::kArrayType);
|
||||
|
||||
for (const Worker &worker : m_workers) {
|
||||
for (const Worker &worker : list) {
|
||||
if (worker.connections() == 0 && worker.lastHash() == 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -286,3 +323,30 @@ void ApiState::getWorkers(rapidjson::Document &doc) const
|
||||
|
||||
doc.AddMember("workers", workers, 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,53 @@
|
||||
* 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 "interfaces/IControllerListener.h"
|
||||
#include "proxy/StatsData.h"
|
||||
#include "proxy/workers/Worker.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();
|
||||
|
||||
char *get(const char *url, int *status) const;
|
||||
void tick(const StatsData &data);
|
||||
void tick(const std::vector<Worker> &workers);
|
||||
void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const;
|
||||
void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
||||
|
||||
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 getHashrate(rapidjson::Document &doc) const;
|
||||
void getIdentify(rapidjson::Document &doc) const;
|
||||
void getMiner(rapidjson::Document &doc) const;
|
||||
void getMinersSummary(rapidjson::Document &doc) const;
|
||||
void getMinersSummary(rapidjson::Document &doc, bool advanced) const;
|
||||
void getResources(rapidjson::Document &doc) const;
|
||||
void getResults(rapidjson::Document &doc) const;
|
||||
void getWorkers(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];
|
||||
StatsData m_stats;
|
||||
std::vector<Worker> m_workers;
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
||||
#endif /* __APISTATE_H__ */
|
||||
#endif /* __APIROUTER_H__ */
|
||||
69
src/api/HttpBody.h
Normal file
69
src/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__ */
|
||||
53
src/api/HttpReply.h
Normal file
53
src/api/HttpReply.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 __HTTPREPLY_H__
|
||||
#define __HTTPREPLY_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpReply
|
||||
{
|
||||
public:
|
||||
HttpReply() :
|
||||
buf(nullptr),
|
||||
status(200),
|
||||
size(0)
|
||||
{}
|
||||
|
||||
char *buf;
|
||||
int status;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __HTTPREPLY_H__ */
|
||||
175
src/api/HttpRequest.cpp
Normal file
175
src/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 "api/HttpBody.h"
|
||||
#include "api/HttpRequest.h"
|
||||
#include "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/api/HttpRequest.h
Normal file
84
src/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__ */
|
||||
@@ -4,7 +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
|
||||
@@ -28,14 +29,64 @@
|
||||
|
||||
#include "api/Api.h"
|
||||
#include "api/Httpd.h"
|
||||
#include "api/HttpReply.h"
|
||||
#include "api/HttpRequest.h"
|
||||
#include "log/Log.h"
|
||||
|
||||
|
||||
Httpd::Httpd(int port, const char *accessToken) :
|
||||
m_accessToken(accessToken),
|
||||
class UploadCtx
|
||||
{
|
||||
public:
|
||||
inline UploadCtx() :
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,11 +97,12 @@ bool Httpd::start()
|
||||
}
|
||||
|
||||
unsigned int flags = 0;
|
||||
if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
|
||||
flags = MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY;
|
||||
if (m_IPv6 && MHD_is_feature_supported(MHD_FEATURE_IPv6)) {
|
||||
flags |= MHD_USE_DUAL_STACK;
|
||||
}
|
||||
else {
|
||||
flags = MHD_USE_SELECT_INTERNALLY;
|
||||
|
||||
if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
|
||||
flags |= MHD_USE_EPOLL_LINUX_ONLY;
|
||||
}
|
||||
|
||||
m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
|
||||
@@ -59,66 +111,61 @@ bool Httpd::start()
|
||||
return false;
|
||||
}
|
||||
|
||||
uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int Httpd::auth(const char *header)
|
||||
int Httpd::process(xmrig::HttpRequest &req)
|
||||
{
|
||||
if (!m_accessToken) {
|
||||
return MHD_HTTP_OK;
|
||||
xmrig::HttpReply reply;
|
||||
if (!req.process(m_accessToken, m_restricted, reply)) {
|
||||
return req.end(reply);
|
||||
}
|
||||
|
||||
if (m_accessToken && !header) {
|
||||
return MHD_HTTP_UNAUTHORIZED;
|
||||
if (!req.isFulfilled()) {
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
const size_t size = strlen(header);
|
||||
if (size < 8 || strlen(m_accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) {
|
||||
return MHD_HTTP_FORBIDDEN;
|
||||
}
|
||||
Api::exec(req, reply);
|
||||
|
||||
return strncmp(m_accessToken, header + 7, strlen(m_accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
|
||||
return req.end(reply);
|
||||
}
|
||||
|
||||
|
||||
int Httpd::done(MHD_Connection *connection, int status, MHD_Response *rsp)
|
||||
void Httpd::run()
|
||||
{
|
||||
if (!rsp) {
|
||||
rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);
|
||||
MHD_run(m_daemon);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
if (strcmp(method, "OPTIONS") == 0) {
|
||||
return done(connection, MHD_HTTP_OK, nullptr);
|
||||
xmrig::HttpRequest req(connection, url, method, uploadData, uploadSize, con_cls);
|
||||
|
||||
if (req.method() == xmrig::HttpRequest::Options) {
|
||||
return req.end(MHD_HTTP_OK, nullptr);
|
||||
}
|
||||
|
||||
if (strcmp(method, "GET") != 0) {
|
||||
return MHD_NO;
|
||||
if (req.method() == xmrig::HttpRequest::Unsupported) {
|
||||
return req.end(MHD_HTTP_METHOD_NOT_ALLOWED, nullptr);
|
||||
}
|
||||
|
||||
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);
|
||||
return static_cast<Httpd*>(cls)->process(req);
|
||||
}
|
||||
|
||||
|
||||
void Httpd::onTimer(uv_timer_t *handle)
|
||||
{
|
||||
static_cast<Httpd*>(handle->data)->run();
|
||||
}
|
||||
|
||||
@@ -4,7 +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
|
||||
@@ -33,21 +34,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__ */
|
||||
|
||||
@@ -1,28 +1,36 @@
|
||||
{
|
||||
"background": false,
|
||||
"log-file": null,
|
||||
"access-log-file": null,
|
||||
"retries": 5,
|
||||
"retry-pause": 5,
|
||||
"donate-level": 2,
|
||||
"coin": "xmr",
|
||||
"custom-diff": 0,
|
||||
"syslog": false,
|
||||
"verbose": false,
|
||||
"workers": true,
|
||||
"pools": [
|
||||
{
|
||||
"url": "pool.minemonero.pro:5555",
|
||||
"user": "",
|
||||
"pass": "x"
|
||||
}
|
||||
],
|
||||
"bind": [
|
||||
"0.0.0.0:3333"
|
||||
],
|
||||
"algo": "cryptonight",
|
||||
"api": {
|
||||
"port": 0,
|
||||
"access-token": null,
|
||||
"worker-id": null
|
||||
}
|
||||
"worker-id": null,
|
||||
"ipv6": true,
|
||||
"restricted": true
|
||||
},
|
||||
"background": false,
|
||||
"bind": [
|
||||
"0.0.0.0:3333",
|
||||
"[::]:3333"
|
||||
],
|
||||
"colors": true,
|
||||
"custom-diff": 0,
|
||||
"donate-level": 2,
|
||||
"log-file": null,
|
||||
"mode": "nicehash",
|
||||
"pools": [
|
||||
{
|
||||
"url": "failover.xmrig.com:443",
|
||||
"user": "YOUR_WALLET",
|
||||
"pass": "x",
|
||||
"variant": -1
|
||||
}
|
||||
],
|
||||
"retries": 2,
|
||||
"retry-pause": 1,
|
||||
"reuse-timeout": 0,
|
||||
"user-agent": null,
|
||||
"verbose": false,
|
||||
"watch": true,
|
||||
"workers": true
|
||||
}
|
||||
298
src/core/Config.cpp
Normal file
298
src/core/Config.cpp
Normal file
@@ -0,0 +1,298 @@
|
||||
/* 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 "core/Config.h"
|
||||
#include "core/ConfigLoader.h"
|
||||
#include "donate.h"
|
||||
#include "log/Log.h"
|
||||
#include "net/Url.h"
|
||||
#include "proxy/Addr.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
|
||||
|
||||
static const char *algoNames[] = {
|
||||
"cryptonight",
|
||||
"cryptonight-lite"
|
||||
};
|
||||
|
||||
|
||||
static const char *modeNames[] = {
|
||||
"nicehash",
|
||||
"simple"
|
||||
};
|
||||
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
# define strncasecmp _strnicmp
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::Config::Config() :
|
||||
m_adjusted(false),
|
||||
m_apiIPv6(true),
|
||||
m_apiRestricted(true),
|
||||
m_background(false),
|
||||
m_colors(true),
|
||||
m_debug(false),
|
||||
m_ready(false),
|
||||
m_syslog(false),
|
||||
m_verbose(false),
|
||||
m_watch(true),
|
||||
m_workers(true),
|
||||
m_accessLog(nullptr),
|
||||
m_apiToken(nullptr),
|
||||
m_apiWorkerId(nullptr),
|
||||
m_fileName(nullptr),
|
||||
m_logFile(nullptr),
|
||||
m_userAgent(nullptr),
|
||||
m_algorithm(CRYPTONIGHT),
|
||||
m_apiPort(0),
|
||||
m_donateLevel(kDonateLevel),
|
||||
m_mode(NICEHASH_MODE),
|
||||
m_retries(2),
|
||||
m_retryPause(1),
|
||||
m_reuseTimeout(0),
|
||||
m_diff(0)
|
||||
{
|
||||
m_pools.push_back(new Url());
|
||||
}
|
||||
|
||||
|
||||
xmrig::Config::~Config()
|
||||
{
|
||||
for (Addr *addr : m_addrs) {
|
||||
delete addr;
|
||||
}
|
||||
|
||||
for (Url *url : m_pools) {
|
||||
delete url;
|
||||
}
|
||||
|
||||
m_addrs.clear();
|
||||
m_pools.clear();
|
||||
|
||||
free(m_fileName);
|
||||
free(m_accessLog);
|
||||
free(m_apiToken);
|
||||
free(m_apiWorkerId);
|
||||
free(m_logFile);
|
||||
free(m_userAgent);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Config::isValid() const
|
||||
{
|
||||
return m_pools[0]->isValid();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Config::reload(const char *json)
|
||||
{
|
||||
return xmrig::ConfigLoader::reload(this, json);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Config::save()
|
||||
{
|
||||
if (!m_fileName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uv_fs_t req;
|
||||
const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName, 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);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Config::algoName() const
|
||||
{
|
||||
return algoNames[m_algorithm];
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Config::modeName() const
|
||||
{
|
||||
return modeNames[m_mode];
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Config::getJSON(rapidjson::Document &doc)
|
||||
{
|
||||
doc.SetObject();
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
doc.AddMember("access-log-file", accessLog() ? rapidjson::Value(rapidjson::StringRef(accessLog())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
|
||||
doc.AddMember("algo", rapidjson::StringRef(algoName()), allocator);
|
||||
|
||||
rapidjson::Value api(rapidjson::kObjectType);
|
||||
api.AddMember("port", apiPort(), allocator);
|
||||
api.AddMember("access-token", apiToken() ? rapidjson::Value(rapidjson::StringRef(apiToken())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
|
||||
api.AddMember("worker-id", apiWorkerId() ? rapidjson::Value(rapidjson::StringRef(apiWorkerId())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
|
||||
api.AddMember("ipv6", apiIPv6(), allocator);
|
||||
api.AddMember("restricted", apiRestricted(), allocator);
|
||||
doc.AddMember("api", api, allocator);
|
||||
|
||||
doc.AddMember("background", background(), allocator);
|
||||
|
||||
rapidjson::Value bind(rapidjson::kArrayType);
|
||||
for (const Addr *addr : m_addrs) {
|
||||
bind.PushBack(rapidjson::StringRef(addr->addr()), allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("bind", bind, allocator);
|
||||
doc.AddMember("colors", colors(), allocator);
|
||||
doc.AddMember("custom-diff", diff(), allocator);
|
||||
doc.AddMember("donate-level", donateLevel(), allocator);
|
||||
doc.AddMember("log-file", logFile() ? rapidjson::Value(rapidjson::StringRef(logFile())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
|
||||
doc.AddMember("mode", rapidjson::StringRef(modeName()), allocator);
|
||||
|
||||
rapidjson::Value pools(rapidjson::kArrayType);
|
||||
|
||||
for (const Url *url : m_pools) {
|
||||
rapidjson::Value obj(rapidjson::kObjectType);
|
||||
|
||||
obj.AddMember("url", rapidjson::StringRef(url->url()), allocator);
|
||||
obj.AddMember("user", rapidjson::StringRef(url->user()), allocator);
|
||||
obj.AddMember("pass", rapidjson::StringRef(url->password()), allocator);
|
||||
obj.AddMember("coin", rapidjson::StringRef(url->coin()), allocator);
|
||||
obj.AddMember("variant", url->variant(), allocator);
|
||||
|
||||
pools.PushBack(obj, allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("pools", pools, allocator);
|
||||
|
||||
doc.AddMember("retries", retries(), allocator);
|
||||
doc.AddMember("retry-pause", retryPause(), allocator);
|
||||
doc.AddMember("reuse-timeout", reuseTimeout(), allocator);
|
||||
doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
doc.AddMember("syslog", syslog(), allocator);
|
||||
# endif
|
||||
|
||||
doc.AddMember("verbose", verbose(), allocator);
|
||||
doc.AddMember("watch", m_watch, allocator);
|
||||
doc.AddMember("workers", workers(), allocator);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Config *xmrig::Config::load(int argc, char **argv, IWatcherListener *listener)
|
||||
{
|
||||
return xmrig::ConfigLoader::load(argc, argv, listener);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Config::adjust()
|
||||
{
|
||||
if (m_adjusted) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_adjusted = true;
|
||||
|
||||
for (Url *url : m_pools) {
|
||||
url->adjust(algorithm());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Config::setAlgo(const char *algo)
|
||||
{
|
||||
const size_t size = sizeof(algoNames) / sizeof((algoNames)[0]);
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (algoNames[i] && !strcmp(algo, algoNames[i])) {
|
||||
m_algorithm = (int) i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == size - 1 && !strcmp(algo, "cryptonight-light")) {
|
||||
m_algorithm = CRYPTONIGHT_LITE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Config::setCoin(const char *coin)
|
||||
{
|
||||
if (strncasecmp(coin, "aeon", 4) == 0) {
|
||||
m_algorithm = CRYPTONIGHT_LITE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Config::setFileName(const char *fileName)
|
||||
{
|
||||
free(m_fileName);
|
||||
m_fileName = fileName ? strdup(fileName) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Config::setMode(const char *mode)
|
||||
{
|
||||
const size_t size = sizeof(modeNames) / sizeof((modeNames)[0]);
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (modeNames[i] && !strcmp(mode, modeNames[i])) {
|
||||
m_mode = (int) i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +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
|
||||
@@ -21,90 +22,132 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __OPTIONS_H__
|
||||
#define __OPTIONS_H__
|
||||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "proxy/Addr.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
class Addr;
|
||||
class Url;
|
||||
struct option;
|
||||
|
||||
|
||||
class Options
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ConfigLoader;
|
||||
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:
|
||||
static inline Options* i() { return m_self; }
|
||||
static Options *parse(int argc, char **argv);
|
||||
friend class ConfigLoader;
|
||||
|
||||
public:
|
||||
enum Algorithm {
|
||||
CRYPTONIGHT, /* CryptoNight (Monero) */
|
||||
CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
|
||||
};
|
||||
|
||||
enum Mode {
|
||||
NICEHASH_MODE,
|
||||
SIMPLE_MODE
|
||||
};
|
||||
|
||||
Config();
|
||||
~Config();
|
||||
|
||||
bool isValid() const;
|
||||
bool reload(const char *json);
|
||||
bool save();
|
||||
const char *algoName() const;
|
||||
const char *modeName() const;
|
||||
void getJSON(rapidjson::Document &doc);
|
||||
|
||||
static Config *load(int argc, char **argv, IWatcherListener *listener);
|
||||
|
||||
inline bool apiIPv6() const { return m_apiIPv6; }
|
||||
inline bool apiRestricted() const { return m_apiRestricted; }
|
||||
inline bool background() const { return m_background; }
|
||||
inline bool colors() const { return m_colors; }
|
||||
inline bool isDebug() const { return m_debug; }
|
||||
inline bool syslog() const { return m_syslog; }
|
||||
inline bool verbose() const { return m_verbose; }
|
||||
inline bool watch() const { return m_watch && m_fileName; }
|
||||
inline bool workers() const { return m_workers; }
|
||||
inline const char *accessLog() const { return m_accessLog; }
|
||||
inline const char *apiToken() const { return m_apiToken; }
|
||||
inline const char *apiWorkerId() const { return m_apiWorkerId; }
|
||||
inline const char *coin() const { return m_userAgent; }
|
||||
inline const char *fileName() const { return m_fileName; }
|
||||
inline const char *logFile() const { return m_logFile; }
|
||||
inline const char *userAgent() const { return m_userAgent; }
|
||||
inline const std::vector<Addr*> &addrs() const { return m_addrs; }
|
||||
inline const std::vector<Url*> &pools() const { return m_pools; }
|
||||
inline int algorithm() const { return m_algorithm; }
|
||||
inline int apiPort() const { return m_apiPort; }
|
||||
inline int donateLevel() const { return m_donateLevel; }
|
||||
inline int mode() const { return m_mode; }
|
||||
inline int retries() const { return m_retries; }
|
||||
inline int retryPause() const { return m_retryPause; }
|
||||
inline int reuseTimeout() const { return m_reuseTimeout; }
|
||||
inline uint64_t diff() const { return m_diff; }
|
||||
inline void setColors(bool colors) { m_colors = colors; }
|
||||
inline void setVerbose(bool verbose) { m_verbose = verbose; }
|
||||
inline void toggleVerbose() { m_verbose = !m_verbose; }
|
||||
|
||||
inline static void release() { delete m_self; }
|
||||
|
||||
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 parseConfig(const char *fileName);
|
||||
void parseJSON(const struct option *option, const rapidjson::Value &object);
|
||||
void showUsage(int status) const;
|
||||
void showVersion(void);
|
||||
void adjust();
|
||||
void setAlgo(const char *algo);
|
||||
void setCoin(const char *coin);
|
||||
void setFileName(const char *fileName);
|
||||
void setMode(const char *mode);
|
||||
|
||||
bool m_adjusted;
|
||||
bool m_apiIPv6;
|
||||
bool m_apiRestricted;
|
||||
bool m_background;
|
||||
bool m_colors;
|
||||
bool m_debug;
|
||||
bool m_ready;
|
||||
bool m_syslog;
|
||||
bool m_verbose;
|
||||
bool m_watch;
|
||||
bool m_workers;
|
||||
char *m_accessLog;
|
||||
char *m_apiToken;
|
||||
char *m_apiWorkerId;
|
||||
char *m_coin;
|
||||
char *m_fileName;
|
||||
char *m_logFile;
|
||||
char *m_userAgent;
|
||||
int m_algorithm;
|
||||
int m_apiPort;
|
||||
int m_donateLevel;
|
||||
int m_mode;
|
||||
int m_retries;
|
||||
int m_retryPause;
|
||||
int m_reuseTimeout;
|
||||
std::vector<Addr*> m_addrs;
|
||||
std::vector<Url*> m_pools;
|
||||
uint64_t m_diff;
|
||||
};
|
||||
|
||||
#endif /* __OPTIONS_H__ */
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONFIG_H__ */
|
||||
539
src/core/ConfigLoader.cpp
Normal file
539
src/core/ConfigLoader.cpp
Normal file
@@ -0,0 +1,539 @@
|
||||
/* 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 "core/Config.h"
|
||||
#include "core/ConfigLoader.h"
|
||||
#include "core/ConfigLoader_static.h"
|
||||
#include "core/ConfigWatcher.h"
|
||||
#include "interfaces/IWatcherListener.h"
|
||||
#include "net/Url.h"
|
||||
#include "Platform.h"
|
||||
#include "proxy/Addr.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
#include "rapidjson/filereadstream.h"
|
||||
|
||||
|
||||
xmrig::ConfigWatcher *xmrig::ConfigLoader::m_watcher = nullptr;
|
||||
xmrig::IWatcherListener *xmrig::ConfigLoader::m_listener = nullptr;
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::loadFromFile(xmrig::Config *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::Config *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::Config *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 &bind = doc["bind"];
|
||||
if (bind.IsArray()) {
|
||||
for (const rapidjson::Value &value : bind.GetArray()) {
|
||||
if (!value.IsString()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
parseArg(config, 'b', value.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
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->adjust();
|
||||
return config->isValid();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::reload(xmrig::Config *oldConfig, const char *json)
|
||||
{
|
||||
xmrig::Config *config = new xmrig::Config();
|
||||
if (!loadFromJSON(config, json)) {
|
||||
delete config;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
config->setFileName(oldConfig->fileName());
|
||||
const bool saved = config->save();
|
||||
|
||||
if (config->watch() && m_watcher && saved) {
|
||||
delete config;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
m_listener->onNewConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Config *xmrig::ConfigLoader::load(int argc, char **argv, IWatcherListener *listener)
|
||||
{
|
||||
m_listener = listener;
|
||||
|
||||
xmrig::Config *config = new xmrig::Config();
|
||||
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->isValid()) {
|
||||
loadFromFile(config, Platform::defaultConfigName());
|
||||
}
|
||||
|
||||
if (!config->isValid()) {
|
||||
fprintf(stderr, "No pool URL supplied. Exiting.\n");
|
||||
delete config;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (config->m_addrs.empty()) {
|
||||
config->m_addrs.push_back(new Addr("0.0.0.0:3333"));
|
||||
config->m_addrs.push_back(new Addr("[::]:3333"));
|
||||
}
|
||||
|
||||
if (config->watch()) {
|
||||
m_watcher = new xmrig::ConfigWatcher(config->fileName(), listener);
|
||||
}
|
||||
|
||||
config->adjust();
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigLoader::release()
|
||||
{
|
||||
delete m_watcher;
|
||||
}
|
||||
|
||||
|
||||
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::Config *config, int key, const char *arg)
|
||||
{
|
||||
switch (key) {
|
||||
case 'a': /* --algo */
|
||||
config->setAlgo(arg);
|
||||
break;
|
||||
|
||||
case 'm': /* --mode */
|
||||
config->setMode(arg);
|
||||
break;
|
||||
|
||||
case 'b': /* --bind */
|
||||
{
|
||||
Addr *addr = new Addr(arg);
|
||||
if (addr->isValid()) {
|
||||
config->m_addrs.push_back(addr);
|
||||
}
|
||||
else {
|
||||
delete addr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'O': /* --userpass */
|
||||
if (!config->m_pools.back()->setUserpass(arg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'o': /* --url */
|
||||
if (config->m_pools.size() > 1 || config->m_pools[0]->isValid()) {
|
||||
Url *url = new Url(arg);
|
||||
if (url->isValid()) {
|
||||
config->m_pools.push_back(url);
|
||||
}
|
||||
else {
|
||||
delete url;
|
||||
}
|
||||
}
|
||||
else {
|
||||
config->m_pools[0]->parse(arg);
|
||||
}
|
||||
|
||||
if (!config->m_pools.back()->isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'u': /* --user */
|
||||
config->m_pools.back()->setUser(arg);
|
||||
break;
|
||||
|
||||
case 'p': /* --pass */
|
||||
config->m_pools.back()->setPassword(arg);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
config->m_pools.back()->setCoin(arg);
|
||||
break;
|
||||
|
||||
case 'l': /* --log-file */
|
||||
free(config->m_logFile);
|
||||
config->m_logFile = strdup(arg);
|
||||
break;
|
||||
|
||||
case 'A': /* --access-log-file **/
|
||||
free(config->m_accessLog);
|
||||
config->m_accessLog = strdup(arg);
|
||||
break;
|
||||
|
||||
case 4001: /* --access-token */
|
||||
free(config->m_apiToken);
|
||||
config->m_apiToken = strdup(arg);
|
||||
break;
|
||||
|
||||
case 4002: /* --worker-id */
|
||||
free(config->m_apiWorkerId);
|
||||
config->m_apiWorkerId = strdup(arg);
|
||||
break;
|
||||
|
||||
case 'r': /* --retries */
|
||||
case 'R': /* --retry-pause */
|
||||
case 1010: /* --variant */
|
||||
case 1102: /* --custom-diff */
|
||||
case 4000: /* --api-port */
|
||||
return parseArg(config, key, strtol(arg, nullptr, 10));
|
||||
|
||||
case 'B': /* --background */
|
||||
case 'S': /* --syslog */
|
||||
case 1100: /* --verbose */
|
||||
case 1101: /* --debug */
|
||||
return parseBoolean(config, key, true);
|
||||
|
||||
case 1002: /* --no-color */
|
||||
case 1103: /* --no-workers */
|
||||
case 1105: /* --no-watch */
|
||||
case 4004: /* ----api-no-restricted */
|
||||
case 4003: /* --api-no-ipv6 */
|
||||
return parseBoolean(config, key, false);
|
||||
|
||||
case 1003: /* --donate-level */
|
||||
if (strncmp(arg, "minemonero.pro", 14) == 0) {
|
||||
config->m_donateLevel = 0;
|
||||
}
|
||||
else {
|
||||
parseArg(config, key, strtol(arg, nullptr, 10));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1104: /* --coin */
|
||||
config->setCoin(arg);
|
||||
break;
|
||||
|
||||
case 'V': /* --version */
|
||||
showVersion();
|
||||
return false;
|
||||
|
||||
case 'h': /* --help */
|
||||
showUsage(0);
|
||||
return false;
|
||||
|
||||
case 'c': /* --config */
|
||||
loadFromFile(config, arg);
|
||||
break;
|
||||
|
||||
case 1008: /* --user-agent */
|
||||
free(config->m_userAgent);
|
||||
config->m_userAgent = strdup(arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::parseArg(xmrig::Config *config, int key, uint64_t arg)
|
||||
{
|
||||
switch (key) {
|
||||
case 'r': /* --retries */
|
||||
if (arg < 1 || arg > 1000) {
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
config->m_retries = (int) arg;
|
||||
break;
|
||||
|
||||
case 'R': /* --retry-pause */
|
||||
if (arg < 1 || arg > 3600) {
|
||||
showUsage(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
config->m_retryPause = (int) arg;
|
||||
break;
|
||||
|
||||
case 1003: /* --donate-level */
|
||||
if ((int) arg < 0 || arg > 99) {
|
||||
return true;
|
||||
}
|
||||
|
||||
config->m_donateLevel = (int) arg;
|
||||
break;
|
||||
|
||||
case 1010: /* --variant */
|
||||
config->m_pools.back()->setVariant((int) arg);
|
||||
break;
|
||||
|
||||
case 4000: /* --api-port */
|
||||
if (arg <= 65536) {
|
||||
config->m_apiPort = (int) arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1102: /* --custom-diff */
|
||||
if (arg >= 100 && arg < INT_MAX) {
|
||||
config->m_diff = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1106: /* --reuse-timeout */
|
||||
config->m_reuseTimeout = (int) arg;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::parseBoolean(xmrig::Config *config, int key, bool enable)
|
||||
{
|
||||
switch (key) {
|
||||
case 'B': /* --background */
|
||||
config->m_background = enable;
|
||||
break;
|
||||
|
||||
case 'S': /* --syslog */
|
||||
config->m_syslog = enable;
|
||||
break;
|
||||
|
||||
case 1002: /* --no-color */
|
||||
config->m_colors = enable;
|
||||
break;
|
||||
|
||||
case 1100: /* --verbose */
|
||||
config->m_verbose = enable;
|
||||
break;
|
||||
|
||||
case 1101: /* --debug */
|
||||
config->m_debug = enable;
|
||||
break;
|
||||
|
||||
case 2000: /* colors */
|
||||
config->m_colors = enable;
|
||||
break;
|
||||
|
||||
case 1103: /* workers */
|
||||
config->m_workers = enable;
|
||||
break;
|
||||
|
||||
case 1105: /* watch */
|
||||
config->m_watch = enable;
|
||||
break;
|
||||
|
||||
case 4003: /* ipv6 */
|
||||
config->m_apiIPv6 = enable;
|
||||
|
||||
case 4004: /* restricted */
|
||||
config->m_apiRestricted = enable;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigLoader::parseJSON(xmrig::Config *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 && value.IsString()) {
|
||||
parseArg(config, option->val, value.GetString());
|
||||
}
|
||||
else if (option->has_arg && value.IsInt64()) {
|
||||
parseArg(config, option->val, value.GetUint64());
|
||||
}
|
||||
else if (!option->has_arg && value.IsBool()) {
|
||||
parseBoolean(config, option->val, value.IsTrue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConfigLoader::showUsage(int status)
|
||||
{
|
||||
if (status) {
|
||||
fprintf(stderr, "Try \"" APP_ID "\" --help' for more information.\n");
|
||||
}
|
||||
else {
|
||||
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)
|
||||
" 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
|
||||
}
|
||||
72
src/core/ConfigLoader.h
Normal file
72
src/core/ConfigLoader.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* 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 Config;
|
||||
class ConfigWatcher;
|
||||
class IWatcherListener;
|
||||
|
||||
|
||||
class ConfigLoader
|
||||
{
|
||||
public:
|
||||
static bool loadFromFile(Config *config, const char *fileName);
|
||||
static bool loadFromJSON(Config *config, const char *json);
|
||||
static bool loadFromJSON(Config *config, const rapidjson::Document &doc);
|
||||
static bool reload(Config *oldConfig, const char *json);
|
||||
static Config *load(int argc, char **argv, IWatcherListener *listener);
|
||||
static void release();
|
||||
|
||||
private:
|
||||
static bool getJSON(const char *fileName, rapidjson::Document &doc);
|
||||
static bool parseArg(Config *config, int key, const char *arg);
|
||||
static bool parseArg(Config *config, int key, uint64_t arg);
|
||||
static bool parseBoolean(Config *config, int key, bool enable);
|
||||
static void parseJSON(Config *config, const struct option *option, const rapidjson::Value &object);
|
||||
static void showUsage(int status);
|
||||
static void showVersion();
|
||||
|
||||
static ConfigWatcher *m_watcher;
|
||||
static IWatcherListener *m_listener;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONFIGLOADER_H__ */
|
||||
175
src/core/ConfigLoader_static.h
Normal file
175
src/core/ConfigLoader_static.h
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/>.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIGLOADER_STATIC_H__
|
||||
#define __CONFIGLOADER_STATIC_H__
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include "getopt/getopt.h"
|
||||
#else
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static char const usage[] = "\
|
||||
Usage: " APP_ID " [OPTIONS]\n\
|
||||
Options:\n\
|
||||
-b, --bind=ADDR bind to specified address, example \"0.0.0.0:3333\"\n\
|
||||
-a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\
|
||||
-m, --mode=MODE proxy mode, nicehash (default) or simple\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\
|
||||
-r, --retries=N number of times to retry before switch to backup server (default: 1)\n\
|
||||
-R, --retry-pause=N time to pause between retries (default: 1 second)\n\
|
||||
--custom-diff=N override pool diff\n\
|
||||
--reuse-timeout=N timeout in seconds for reuse pool connections in simple mode\n\
|
||||
--verbose verbose output\n\
|
||||
--user-agent=AGENT set custom user-agent string for pool\n\
|
||||
--no-color disable colored output\n\
|
||||
--no-workers disable per worker statistics\n\
|
||||
--variant algorithm PoW variant\n\
|
||||
--donate-level=N donate level, default 2%%\n\
|
||||
-B, --background run the miner in the background\n\
|
||||
-c, --config=FILE load a JSON-format configuration file\n\
|
||||
--no-watch disable configuration file watching\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
|
||||
"\
|
||||
-A --access-log-file=N log all workers access to a file\n\
|
||||
--api-port=N port for the miner API\n\
|
||||
--api-access-token=T use Bearer access token for API\n\
|
||||
--api-worker-id=ID custom worker-id for API\n\
|
||||
--api-no-ipv6 disable 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[] = "c:khBp:Px:r:R:s:T:o:u:O:Vl:Sb:A:a:C:m:";
|
||||
|
||||
|
||||
static struct option const options[] = {
|
||||
{ "access-log-file", 1, nullptr, 'A' },
|
||||
{ "algo", 1, nullptr, 'a' },
|
||||
{ "api-access-token", 1, nullptr, 4001 },
|
||||
{ "api-no-ipv6", 0, nullptr, 4003 },
|
||||
{ "api-no-restricted", 0, nullptr, 4004 },
|
||||
{ "api-port", 1, nullptr, 4000 },
|
||||
{ "api-worker-id", 1, nullptr, 4002 },
|
||||
{ "background", 0, nullptr, 'B' },
|
||||
{ "bind", 1, nullptr, 'b' },
|
||||
{ "coin", 1, nullptr, 1104 },
|
||||
{ "config", 1, nullptr, 'c' },
|
||||
{ "custom-diff", 1, nullptr, 1102 },
|
||||
{ "debug", 0, nullptr, 1101 },
|
||||
{ "donate-level", 1, nullptr, 1003 },
|
||||
{ "help", 0, nullptr, 'h' },
|
||||
{ "keepalive", 0, nullptr ,'k' },
|
||||
{ "log-file", 1, nullptr, 'l' },
|
||||
{ "no-color", 0, nullptr, 1002 },
|
||||
{ "no-watch", 0, nullptr, 1105 },
|
||||
{ "no-workers", 0, nullptr, 1103 },
|
||||
{ "pass", 1, nullptr, 'p' },
|
||||
{ "pool-coin", 1, nullptr, 'C' },
|
||||
{ "retries", 1, nullptr, 'r' },
|
||||
{ "retry-pause", 1, nullptr, 'R' },
|
||||
{ "syslog", 0, nullptr, 'S' },
|
||||
{ "url", 1, nullptr, 'o' },
|
||||
{ "user", 1, nullptr, 'u' },
|
||||
{ "user-agent", 1, nullptr, 1008 },
|
||||
{ "userpass", 1, nullptr, 'O' },
|
||||
{ "verbose", 0, nullptr, 1100 },
|
||||
{ "version", 0, nullptr, 'V' },
|
||||
{ "variant", 1, nullptr, 1010 },
|
||||
{ "reuse-timeout", 1, nullptr, 1106 },
|
||||
{ "mode", 1, nullptr, 'm' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct option const config_options[] = {
|
||||
{ "access-log-file", 1, nullptr, 'A' },
|
||||
{ "algo", 1, nullptr, 'a' },
|
||||
{ "background", 0, nullptr, 'B' },
|
||||
{ "coin", 1, nullptr, 1104 },
|
||||
{ "colors", 0, nullptr, 2000 },
|
||||
{ "custom-diff", 1, nullptr, 1102 },
|
||||
{ "debug", 0, nullptr, 1101 },
|
||||
{ "donate-level", 1, nullptr, 1003 },
|
||||
{ "log-file", 1, nullptr, 'l' },
|
||||
{ "retries", 1, nullptr, 'r' },
|
||||
{ "retry-pause", 1, nullptr, 'R' },
|
||||
{ "syslog", 0, nullptr, 'S' },
|
||||
{ "user-agent", 1, nullptr, 1008 },
|
||||
{ "verbose", 0, nullptr, 1100 },
|
||||
{ "watch", 0, nullptr, 1105 },
|
||||
{ "workers", 0, nullptr, 1103 },
|
||||
{ "reuse-timeout", 1, nullptr, 1106 },
|
||||
{ "mode", 1, nullptr, 'm' },
|
||||
{ 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' },
|
||||
{ "coin", 1, nullptr, 'C' },
|
||||
{ "variant", 1, nullptr, 1010 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct option const api_options[] = {
|
||||
{ "port", 1, nullptr, 4000 },
|
||||
{ "access-token", 1, nullptr, 4001 },
|
||||
{ "worker-id", 1, nullptr, 4002 },
|
||||
{ "ipv6", 0, nullptr, 4003 },
|
||||
{ "restricted", 0, nullptr, 4004 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONFIGLOADER_STATIC_H__ */
|
||||
106
src/core/ConfigWatcher.cpp
Normal file
106
src/core/ConfigWatcher.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/* 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 "core/Config.h"
|
||||
#include "core/ConfigLoader.h"
|
||||
#include "core/ConfigWatcher.h"
|
||||
#include "interfaces/IWatcherListener.h"
|
||||
#include "log/Log.h"
|
||||
|
||||
|
||||
xmrig::ConfigWatcher::ConfigWatcher(const char *path, IWatcherListener *listener) :
|
||||
m_path(strdup(path)),
|
||||
m_listener(listener)
|
||||
{
|
||||
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);
|
||||
|
||||
free(m_path);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
xmrig::Config *config = new xmrig::Config();
|
||||
ConfigLoader::loadFromFile(config, m_path);
|
||||
|
||||
if (!config->isValid()) {
|
||||
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, 0);
|
||||
}
|
||||
68
src/core/ConfigWatcher.h
Normal file
68
src/core/ConfigWatcher.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 "rapidjson/fwd.h"
|
||||
|
||||
|
||||
struct option;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Config;
|
||||
class IWatcherListener;
|
||||
|
||||
|
||||
class ConfigWatcher
|
||||
{
|
||||
public:
|
||||
ConfigWatcher(const char *path, 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();
|
||||
|
||||
char *m_path;
|
||||
IWatcherListener *m_listener;
|
||||
uv_fs_event_t m_fsEvent;
|
||||
uv_timer_t m_timer;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONFIGWATCHER_H__ */
|
||||
147
src/core/Controller.cpp
Normal file
147
src/core/Controller.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/ConfigLoader.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/ConsoleLog.h"
|
||||
#include "log/FileLog.h"
|
||||
#include "log/Log.h"
|
||||
#include "Platform.h"
|
||||
#include "proxy/Proxy.h"
|
||||
#include "interfaces/IControllerListener.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
# include "log/SysLog.h"
|
||||
#endif
|
||||
|
||||
|
||||
class xmrig::ControllerPrivate
|
||||
{
|
||||
public:
|
||||
inline ControllerPrivate() :
|
||||
proxy(nullptr),
|
||||
config(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
inline ~ControllerPrivate()
|
||||
{
|
||||
delete proxy;
|
||||
delete config;
|
||||
}
|
||||
|
||||
|
||||
Proxy *proxy;
|
||||
xmrig::Config *config;
|
||||
std::vector<xmrig::IControllerListener *> listeners;
|
||||
};
|
||||
|
||||
|
||||
xmrig::Controller::Controller()
|
||||
: d_ptr(new ControllerPrivate())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
xmrig::Controller::~Controller()
|
||||
{
|
||||
ConfigLoader::release();
|
||||
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Config *xmrig::Controller::config() const
|
||||
{
|
||||
return d_ptr->config;
|
||||
}
|
||||
|
||||
|
||||
const StatsData &xmrig::Controller::statsData() const
|
||||
{
|
||||
return proxy()->statsData();
|
||||
}
|
||||
|
||||
|
||||
const std::vector<Worker> &xmrig::Controller::workers() const
|
||||
{
|
||||
return proxy()->workers();
|
||||
}
|
||||
|
||||
|
||||
int xmrig::Controller::init(int argc, char **argv)
|
||||
{
|
||||
d_ptr->config = xmrig::Config::load(argc, argv, this);
|
||||
if (!d_ptr->config) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Log::init();
|
||||
Platform::init(config()->userAgent());
|
||||
|
||||
if (!config()->background()) {
|
||||
Log::add(new ConsoleLog(this));
|
||||
}
|
||||
|
||||
if (config()->logFile()) {
|
||||
Log::add(new FileLog(config()->logFile()));
|
||||
}
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
if (config()->syslog()) {
|
||||
Log::add(new SysLog());
|
||||
}
|
||||
# endif
|
||||
|
||||
d_ptr->proxy = new Proxy(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Proxy *xmrig::Controller::proxy() const
|
||||
{
|
||||
return d_ptr->proxy;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Controller::addListener(IControllerListener *listener)
|
||||
{
|
||||
d_ptr->listeners.push_back(listener);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Controller::onNewConfig(Config *config)
|
||||
{
|
||||
xmrig::Config *previousConfig = d_ptr->config;
|
||||
d_ptr->config = config;
|
||||
|
||||
for (xmrig::IControllerListener *listener : d_ptr->listeners) {
|
||||
listener->onConfigChanged(config, previousConfig);
|
||||
}
|
||||
|
||||
delete previousConfig;
|
||||
}
|
||||
66
src/core/Controller.h
Normal file
66
src/core/Controller.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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 __CONTROLLER_H__
|
||||
#define __CONTROLLER_H__
|
||||
|
||||
|
||||
#include "interfaces/IWatcherListener.h"
|
||||
#include "proxy/workers/Worker.h"
|
||||
|
||||
|
||||
class Proxy;
|
||||
class StatsData;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Config;
|
||||
class ControllerPrivate;
|
||||
class IControllerListener;
|
||||
|
||||
|
||||
class Controller : public IWatcherListener
|
||||
{
|
||||
public:
|
||||
Controller();
|
||||
~Controller();
|
||||
|
||||
Config *config() const;
|
||||
const StatsData &statsData() const;
|
||||
const std::vector<Worker> &workers() const;
|
||||
int init(int argc, char **argv);
|
||||
Proxy *proxy() const;
|
||||
void addListener(IControllerListener *listener);
|
||||
|
||||
protected:
|
||||
void onNewConfig(Config *config) override;
|
||||
|
||||
private:
|
||||
ControllerPrivate *d_ptr;
|
||||
};
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONTROLLER_H__ */
|
||||
46
src/interfaces/IControllerListener.h
Normal file
46
src/interfaces/IControllerListener.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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 __ICONTROLLERLISTENER_H__
|
||||
#define __ICONTROLLERLISTENER_H__
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Config;
|
||||
|
||||
|
||||
class IControllerListener
|
||||
{
|
||||
public:
|
||||
virtual ~IControllerListener() {}
|
||||
|
||||
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // __ICONTROLLERLISTENER_H__
|
||||
71
src/interfaces/ISplitter.h
Normal file
71
src/interfaces/ISplitter.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 __ISPLITTER_H__
|
||||
#define __ISPLITTER_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
class Upstreams
|
||||
{
|
||||
public:
|
||||
inline Upstreams() : active(0), sleep(0), total(0), error(0), ratio(0.0) {}
|
||||
|
||||
|
||||
inline Upstreams(uint64_t active, uint64_t sleep, uint64_t total, uint64_t miners) :
|
||||
active(active),
|
||||
sleep(sleep),
|
||||
total(total),
|
||||
error(total - active - sleep),
|
||||
ratio(active > 0 ? ((double) miners / active) : 0.0)
|
||||
{}
|
||||
|
||||
|
||||
uint64_t active;
|
||||
uint64_t sleep;
|
||||
uint64_t total;
|
||||
uint64_t error;
|
||||
double ratio;
|
||||
};
|
||||
|
||||
|
||||
class ISplitter
|
||||
{
|
||||
public:
|
||||
virtual ~ISplitter() {}
|
||||
|
||||
virtual Upstreams upstreams() const = 0;
|
||||
virtual void connect() = 0;
|
||||
virtual void gc() = 0;
|
||||
virtual void printConnections() = 0;
|
||||
virtual void tick(uint64_t ticks) = 0;
|
||||
|
||||
# ifdef APP_DEVEL
|
||||
virtual void printState() = 0;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
#endif // __ISPLITTER_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
|
||||
|
||||
@@ -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
|
||||
@@ -39,10 +39,10 @@ class IStrategyListener
|
||||
public:
|
||||
virtual ~IStrategyListener() {}
|
||||
|
||||
virtual void onActive(Client *client) = 0;
|
||||
virtual void onJob(Client *client, const Job &job) = 0;
|
||||
virtual void onPause(IStrategy *strategy) = 0;
|
||||
virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
|
||||
virtual void onActive(IStrategy *strategy, Client *client) = 0;
|
||||
virtual void onJob(IStrategy *strategy, Client *client, const Job &job) = 0;
|
||||
virtual void onPause(IStrategy *strategy) = 0;
|
||||
virtual void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
46
src/interfaces/IWatcherListener.h
Normal file
46
src/interfaces/IWatcherListener.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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 __IWATCHERLISTENER_H__
|
||||
#define __IWATCHERLISTENER_H__
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Config;
|
||||
|
||||
|
||||
class IWatcherListener
|
||||
{
|
||||
public:
|
||||
virtual ~IWatcherListener() {}
|
||||
|
||||
virtual void onNewConfig(Config *config) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // __IWATCHERLISTENER_H__
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -28,8 +28,9 @@
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/AccessLog.h"
|
||||
#include "Options.h"
|
||||
#include "proxy/Counters.h"
|
||||
#include "proxy/events/CloseEvent.h"
|
||||
#include "proxy/events/LoginEvent.h"
|
||||
@@ -38,15 +39,16 @@
|
||||
#include "proxy/Stats.h"
|
||||
|
||||
|
||||
AccessLog::AccessLog() :
|
||||
AccessLog::AccessLog(xmrig::Controller *controller) :
|
||||
m_file(-1)
|
||||
{
|
||||
if (!Options::i()->accessLog()) {
|
||||
const char *fileName = controller->config()->accessLog();
|
||||
if (!fileName) {
|
||||
return;
|
||||
}
|
||||
|
||||
uv_fs_t req;
|
||||
m_file = uv_fs_open(uv_default_loop(), &req, Options::i()->accessLog(), O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
|
||||
m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
|
||||
uv_fs_req_cleanup(&req);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -34,10 +34,15 @@
|
||||
class Stats;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class AccessLog : public IEventListener
|
||||
{
|
||||
public:
|
||||
AccessLog();
|
||||
AccessLog(xmrig::Controller *controller);
|
||||
~AccessLog();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -34,15 +34,18 @@
|
||||
#endif
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/ConsoleLog.h"
|
||||
#include "log/Log.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) {
|
||||
controller->config()->setColors(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -65,10 +68,6 @@ ConsoleLog::ConsoleLog(bool colors) :
|
||||
|
||||
void ConsoleLog::message(int level, const char* fmt, va_list args)
|
||||
{
|
||||
if (!isWritable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
time_t now = time(nullptr);
|
||||
tm stime;
|
||||
|
||||
@@ -79,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()->colors();
|
||||
|
||||
if (colors) {
|
||||
switch (level) {
|
||||
case Log::ERR:
|
||||
color = Log::kCL_RED;
|
||||
@@ -110,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);
|
||||
@@ -121,11 +122,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
|
||||
|
||||
void ConsoleLog::text(const char* fmt, va_list args)
|
||||
{
|
||||
if (!isWritable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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()->colors() ? Log::kCL_N : "");
|
||||
|
||||
print(args);
|
||||
}
|
||||
@@ -149,5 +146,11 @@ void ConsoleLog::print(va_list args)
|
||||
return;
|
||||
}
|
||||
|
||||
uv_try_write(m_stream, &m_uvBuf, 1);
|
||||
if (!isWritable()) {
|
||||
fputs(m_buf, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
else {
|
||||
uv_try_write(m_stream, &m_uvBuf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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,16 +25,19 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/Log.h"
|
||||
#include "log/ShareLog.h"
|
||||
#include "net/SubmitResult.h"
|
||||
#include "Options.h"
|
||||
#include "proxy/events/AcceptEvent.h"
|
||||
#include "proxy/Miner.h"
|
||||
#include "proxy/Stats.h"
|
||||
|
||||
|
||||
ShareLog::ShareLog(const Stats &stats) :
|
||||
m_stats(stats)
|
||||
ShareLog::ShareLog(xmrig::Controller *controller, const Stats &stats) :
|
||||
m_stats(stats),
|
||||
m_controller(controller)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -72,15 +75,21 @@ void ShareLog::onRejectedEvent(IEvent *event)
|
||||
}
|
||||
|
||||
|
||||
bool ShareLog::isColors() const
|
||||
{
|
||||
return m_controller->config()->colors();
|
||||
}
|
||||
|
||||
|
||||
void ShareLog::accept(const AcceptEvent *event)
|
||||
{
|
||||
if (!Options::i()->verbose()) {
|
||||
if (!m_controller->config()->verbose()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(Options::i()->colors() ? "#%03u \x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
|
||||
: "#%03u accepted (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff %u (%" PRIu64 " ms)",
|
||||
event->mapperId(), m_stats.data().accepted, m_stats.data().rejected, m_stats.data().invalid, event->result.diff, event->result.elapsed);
|
||||
LOG_INFO(isColors() ? "#%03u \x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m ip \x1B[01;37m%s \x1B[01;30m(%" PRIu64 " ms)"
|
||||
: "#%03u accepted (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff %u ip %s (%" PRIu64 " ms)",
|
||||
event->mapperId(), m_stats.data().accepted, m_stats.data().rejected, m_stats.data().invalid, event->result.diff, event->ip(), event->result.elapsed);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +99,7 @@ void ShareLog::reject(const AcceptEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(Options::i()->colors() ? "#%03u \x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRId64 " ms)"
|
||||
: "#%03u rejected (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff %u \"%s\" (%" PRId64 " ms)",
|
||||
event->mapperId(), m_stats.data().accepted, m_stats.data().rejected, m_stats.data().invalid, event->result.diff, event->error(), event->result.elapsed);
|
||||
LOG_INFO(isColors() ? "#%03u \x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m ip \x1B[01;37m%s \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRId64 " ms)"
|
||||
: "#%03u rejected (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff %u ip %s \"%s\" (%" PRId64 " ms)",
|
||||
event->mapperId(), m_stats.data().accepted, m_stats.data().rejected, m_stats.data().invalid, event->result.diff, event->ip(), event->error(), event->result.elapsed);
|
||||
}
|
||||
|
||||
@@ -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,10 +32,15 @@ class AcceptEvent;
|
||||
class Stats;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class ShareLog : public IEventListener
|
||||
{
|
||||
public:
|
||||
ShareLog(const Stats &stats);
|
||||
ShareLog(xmrig::Controller *controller, const Stats &stats);
|
||||
~ShareLog();
|
||||
|
||||
protected:
|
||||
@@ -43,10 +48,12 @@ protected:
|
||||
void onRejectedEvent(IEvent *event) override;
|
||||
|
||||
private:
|
||||
bool isColors() const;
|
||||
void accept(const AcceptEvent *event);
|
||||
void reject(const AcceptEvent *event);
|
||||
|
||||
const Stats &m_stats;
|
||||
xmrig::Controller *m_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
|
||||
@@ -21,6 +21,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <iterator>
|
||||
#include <stdio.h>
|
||||
@@ -54,6 +55,8 @@ int64_t Client::m_sequence = 1;
|
||||
|
||||
|
||||
Client::Client(int id, const char *agent, IClientListener *listener) :
|
||||
m_ipv6(false),
|
||||
m_nicehash(false),
|
||||
m_quiet(false),
|
||||
m_agent(agent),
|
||||
m_listener(listener),
|
||||
@@ -63,6 +66,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
|
||||
m_recvBufPos(0),
|
||||
m_state(UnconnectedState),
|
||||
m_expire(0),
|
||||
m_jobs(0),
|
||||
m_stream(nullptr),
|
||||
m_socket(nullptr)
|
||||
{
|
||||
@@ -71,7 +75,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
|
||||
|
||||
m_resolver.data = this;
|
||||
|
||||
m_hints.ai_family = PF_INET;
|
||||
m_hints.ai_family = AF_UNSPEC;
|
||||
m_hints.ai_socktype = SOCK_STREAM;
|
||||
m_hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
@@ -109,16 +113,17 @@ void Client::connect(const Url *url)
|
||||
}
|
||||
|
||||
|
||||
void Client::disconnect()
|
||||
void Client::deleteLater()
|
||||
{
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
uv_timer_stop(&m_keepAliveTimer);
|
||||
# endif
|
||||
if (!m_listener) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_expire = 0;
|
||||
m_failures = -1;
|
||||
m_listener = nullptr;
|
||||
|
||||
close();
|
||||
if (!disconnect()) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,6 +155,19 @@ 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;
|
||||
|
||||
return close();
|
||||
}
|
||||
|
||||
|
||||
int64_t Client::submit(const JobResult &result)
|
||||
{
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
@@ -167,13 +185,55 @@ int64_t Client::submit(const JobResult &result)
|
||||
# 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, result.jobId.data(), nonce, data);
|
||||
m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data);
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
|
||||
# else
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
|
||||
# endif
|
||||
|
||||
return send(size);
|
||||
}
|
||||
|
||||
|
||||
bool Client::close()
|
||||
{
|
||||
if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setState(ClosingState);
|
||||
|
||||
uv_stream_t *stream = reinterpret_cast<uv_stream_t*>(m_socket);
|
||||
|
||||
if (uv_is_readable(stream) == 1) {
|
||||
uv_read_stop(stream);
|
||||
}
|
||||
|
||||
if (uv_is_writable(stream) == 1) {
|
||||
const int rc = uv_shutdown(new uv_shutdown_t, stream, [](uv_shutdown_t* req, int status) {
|
||||
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(req->handle)) == 0) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(req->handle), Client::onClose);
|
||||
}
|
||||
|
||||
delete req;
|
||||
});
|
||||
|
||||
assert(rc == 0);
|
||||
|
||||
if (rc != 0) {
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
else {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Client::isCriticalError(const char *message)
|
||||
{
|
||||
if (!message) {
|
||||
@@ -203,7 +263,14 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
||||
return false;
|
||||
}
|
||||
|
||||
Job job(m_id, m_url.isNicehash());
|
||||
# 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
|
||||
|
||||
if (!job.setId(params["job_id"].GetString())) {
|
||||
*code = 3;
|
||||
return false;
|
||||
@@ -219,32 +286,52 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_job == job) {
|
||||
if (!m_quiet) {
|
||||
LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
|
||||
}
|
||||
if (params.HasMember("coin")) {
|
||||
job.setCoin(params["coin"].GetString());
|
||||
}
|
||||
|
||||
close();
|
||||
if (params.HasMember("variant")) {
|
||||
job.setVariant(params["variant"].GetInt());
|
||||
}
|
||||
|
||||
if (m_job != job) {
|
||||
m_jobs++;
|
||||
m_job = std::move(job);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_jobs == 0) { // https://github.com/xmrig/xmrig/issues/459
|
||||
return false;
|
||||
}
|
||||
|
||||
m_job = std::move(job);
|
||||
return true;
|
||||
if (!m_quiet) {
|
||||
LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
|
||||
}
|
||||
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Client::parseLogin(const rapidjson::Value &result, int *code)
|
||||
{
|
||||
const char *id = result["id"].GetString();
|
||||
if (!id || strlen(id) >= sizeof(m_rpcId)) {
|
||||
if (!m_rpcId.setId(result["id"].GetString())) {
|
||||
*code = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(m_rpcId, 0, sizeof(m_rpcId));
|
||||
memcpy(m_rpcId, id, strlen(id));
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
m_nicehash = m_url.isNicehash();
|
||||
# endif
|
||||
|
||||
return parseJob(result["job"], code);
|
||||
if (result.HasMember("extensions")) {
|
||||
parseExtensions(result["extensions"]);
|
||||
}
|
||||
|
||||
const bool rc = parseJob(result["job"], code);
|
||||
m_jobs = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -259,7 +346,7 @@ int Client::resolve(const char *host)
|
||||
m_failures = 0;
|
||||
}
|
||||
|
||||
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints);
|
||||
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));
|
||||
@@ -291,21 +378,25 @@ int64_t Client::send(size_t size)
|
||||
}
|
||||
|
||||
|
||||
void Client::close()
|
||||
void Client::connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6)
|
||||
{
|
||||
if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) {
|
||||
return;
|
||||
addrinfo *addr = nullptr;
|
||||
m_ipv6 = ipv4.empty() && !ipv6.empty();
|
||||
|
||||
if (m_ipv6) {
|
||||
addr = ipv6[ipv6.size() == 1 ? 0 : rand() % ipv6.size()];
|
||||
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), m_ip, 45);
|
||||
}
|
||||
else {
|
||||
addr = ipv4[ipv4.size() == 1 ? 0 : rand() % ipv4.size()];
|
||||
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), m_ip, 16);
|
||||
}
|
||||
|
||||
setState(ClosingState);
|
||||
|
||||
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_socket)) == 0) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
|
||||
}
|
||||
connect(addr->ai_addr);
|
||||
}
|
||||
|
||||
|
||||
void Client::connect(struct sockaddr *addr)
|
||||
void Client::connect(sockaddr *addr)
|
||||
{
|
||||
setState(ConnectingState);
|
||||
|
||||
@@ -366,6 +457,18 @@ void Client::login()
|
||||
}
|
||||
|
||||
|
||||
void Client::onClose()
|
||||
{
|
||||
delete m_socket;
|
||||
|
||||
m_stream = nullptr;
|
||||
m_socket = nullptr;
|
||||
setState(UnconnectedState);
|
||||
|
||||
reconnect();
|
||||
}
|
||||
|
||||
|
||||
void Client::parse(char *line, size_t len)
|
||||
{
|
||||
startTimeout();
|
||||
@@ -374,6 +477,14 @@ void Client::parse(char *line, size_t len)
|
||||
|
||||
LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
|
||||
|
||||
if (len < 32 || line[0] != '{') {
|
||||
if (!m_quiet) {
|
||||
LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rapidjson::Document doc;
|
||||
if (doc.ParseInsitu(line).HasParseError()) {
|
||||
if (!m_quiet) {
|
||||
@@ -397,6 +508,24 @@ void Client::parse(char *line, size_t len)
|
||||
}
|
||||
|
||||
|
||||
void Client::parseExtensions(const rapidjson::Value &value)
|
||||
{
|
||||
if (!value.IsArray()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const rapidjson::Value &ext : value.GetArray()) {
|
||||
if (!ext.IsString()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(ext.GetString(), "nicehash") == 0) {
|
||||
m_nicehash = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error)
|
||||
{
|
||||
if (error.IsObject()) {
|
||||
@@ -456,7 +585,8 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
|
||||
LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code);
|
||||
}
|
||||
|
||||
return close();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
m_failures = 0;
|
||||
@@ -476,12 +606,18 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
|
||||
|
||||
void Client::ping()
|
||||
{
|
||||
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId));
|
||||
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId.data()));
|
||||
}
|
||||
|
||||
|
||||
void Client::reconnect()
|
||||
{
|
||||
if (!m_listener) {
|
||||
delete this;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setState(ConnectingState);
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
@@ -530,6 +666,9 @@ void Client::startTimeout()
|
||||
void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
|
||||
{
|
||||
auto client = getClient(handle->data);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
buf->base = &client->m_recvBuf.base[client->m_recvBufPos];
|
||||
buf->len = client->m_recvBuf.len - client->m_recvBufPos;
|
||||
@@ -539,20 +678,21 @@ void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t
|
||||
void Client::onClose(uv_handle_t *handle)
|
||||
{
|
||||
auto client = getClient(handle->data);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete client->m_socket;
|
||||
|
||||
client->m_stream = nullptr;
|
||||
client->m_socket = nullptr;
|
||||
client->setState(UnconnectedState);
|
||||
|
||||
client->reconnect();
|
||||
client->onClose();
|
||||
}
|
||||
|
||||
|
||||
void Client::onConnect(uv_connect_t *req, int status)
|
||||
{
|
||||
auto client = getClient(req->data);
|
||||
if (!client) {
|
||||
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));
|
||||
@@ -577,22 +717,28 @@ void Client::onConnect(uv_connect_t *req, int status)
|
||||
void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
||||
{
|
||||
auto client = getClient(stream->data);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
return client->close();;
|
||||
client->close();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size_t) nread > (sizeof(m_buf) - 8 - client->m_recvBufPos)) {
|
||||
return client->close();;
|
||||
client->close();
|
||||
return;
|
||||
}
|
||||
|
||||
client->m_recvBufPos += nread;
|
||||
|
||||
char* end;
|
||||
char* start = buf->base;
|
||||
char* start = client->m_recvBuf.base;
|
||||
size_t remaining = client->m_recvBufPos;
|
||||
|
||||
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
|
||||
@@ -609,11 +755,11 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
||||
return;
|
||||
}
|
||||
|
||||
if (start == buf->base) {
|
||||
if (start == client->m_recvBuf.base) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(buf->base, start, remaining);
|
||||
memcpy(client->m_recvBuf.base, start, remaining);
|
||||
client->m_recvBufPos = remaining;
|
||||
}
|
||||
|
||||
@@ -621,31 +767,43 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
||||
void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
|
||||
{
|
||||
auto client = getClient(req->data);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
|
||||
return client->reconnect();;
|
||||
if (!client->m_quiet) {
|
||||
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
|
||||
}
|
||||
|
||||
return client->reconnect();
|
||||
}
|
||||
|
||||
addrinfo *ptr = res;
|
||||
std::vector<addrinfo*> ipv4;
|
||||
std::vector<addrinfo*> ipv6;
|
||||
|
||||
while (ptr != nullptr) {
|
||||
if (ptr->ai_family == AF_INET) {
|
||||
ipv4.push_back(ptr);
|
||||
}
|
||||
|
||||
if (ptr->ai_family == AF_INET6) {
|
||||
ipv6.push_back(ptr);
|
||||
}
|
||||
|
||||
ptr = ptr->ai_next;
|
||||
}
|
||||
|
||||
if (ipv4.empty()) {
|
||||
LOG_ERR("[%s:%u] DNS error: \"No IPv4 records found\"", client->m_url.host(), client->m_url.port());
|
||||
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());
|
||||
}
|
||||
|
||||
uv_freeaddrinfo(res);
|
||||
return client->reconnect();
|
||||
}
|
||||
|
||||
ptr = ipv4[rand() % ipv4.size()];
|
||||
|
||||
uv_ip4_name(reinterpret_cast<sockaddr_in*>(ptr->ai_addr), client->m_ip, 16);
|
||||
|
||||
client->connect(ptr->ai_addr);
|
||||
client->connect(ipv4, ipv6);
|
||||
uv_freeaddrinfo(res);
|
||||
}
|
||||
|
||||
@@ -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,8 +27,10 @@
|
||||
|
||||
#include <map>
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "net/Id.h"
|
||||
#include "net/Job.h"
|
||||
#include "net/SubmitResult.h"
|
||||
#include "net/Url.h"
|
||||
@@ -54,12 +56,12 @@ public:
|
||||
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 disconnect();
|
||||
void deleteLater();
|
||||
void setUrl(const Url *url);
|
||||
void tick(uint64_t now);
|
||||
|
||||
@@ -74,15 +76,20 @@ public:
|
||||
inline void setRetryPause(int ms) { m_retryPause = ms; }
|
||||
|
||||
private:
|
||||
~Client();
|
||||
|
||||
bool close();
|
||||
bool isCriticalError(const char *message);
|
||||
bool parseJob(const rapidjson::Value ¶ms, int *code);
|
||||
bool parseLogin(const rapidjson::Value &result, int *code);
|
||||
int resolve(const char *host);
|
||||
int64_t send(size_t size);
|
||||
void close();
|
||||
void connect(struct sockaddr *addr);
|
||||
void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6);
|
||||
void connect(sockaddr *addr);
|
||||
void login();
|
||||
void onClose();
|
||||
void parse(char *line, size_t len);
|
||||
void parseExtensions(const rapidjson::Value &value);
|
||||
void parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error);
|
||||
void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
|
||||
void ping();
|
||||
@@ -99,10 +106,11 @@ private:
|
||||
static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
|
||||
|
||||
addrinfo m_hints;
|
||||
bool m_ipv6;
|
||||
bool m_nicehash;
|
||||
bool m_quiet;
|
||||
char m_buf[2048];
|
||||
char m_ip[17];
|
||||
char m_rpcId[64];
|
||||
char m_ip[46];
|
||||
char m_sendBuf[768];
|
||||
const char *m_agent;
|
||||
IClientListener *m_listener;
|
||||
@@ -115,11 +123,13 @@ private:
|
||||
static int64_t m_sequence;
|
||||
std::map<int64_t, SubmitResult> m_results;
|
||||
uint64_t m_expire;
|
||||
uint64_t m_jobs;
|
||||
Url m_url;
|
||||
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;
|
||||
|
||||
@@ -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,40 +21,51 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __JOBID_H__
|
||||
#define __JOBID_H__
|
||||
#ifndef __ID_H__
|
||||
#define __ID_H__
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
class JobId
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Id
|
||||
{
|
||||
public:
|
||||
inline JobId()
|
||||
inline Id()
|
||||
{
|
||||
memset(m_data, 0, sizeof(m_data));
|
||||
}
|
||||
|
||||
|
||||
inline JobId(const char *id, size_t sizeFix = 0)
|
||||
inline Id(const char *id, size_t sizeFix = 0)
|
||||
{
|
||||
setId(id, sizeFix);
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const JobId &other) const
|
||||
inline bool operator==(const Id &other) const
|
||||
{
|
||||
return memcmp(m_data, other.m_data, sizeof(m_data)) == 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool operator!=(const JobId &other) const
|
||||
inline bool operator!=(const Id &other) const
|
||||
{
|
||||
return memcmp(m_data, other.m_data, sizeof(m_data)) != 0;
|
||||
}
|
||||
|
||||
|
||||
Id &operator=(const Id &other)
|
||||
{
|
||||
memcpy(m_data, other.m_data, sizeof(m_data));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline bool setId(const char *id, size_t sizeFix = 0)
|
||||
{
|
||||
memset(m_data, 0, sizeof(m_data));
|
||||
@@ -80,4 +91,8 @@ private:
|
||||
char m_data[64];
|
||||
};
|
||||
|
||||
#endif /* __JOBID_H__ */
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __ID_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
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
|
||||
#include "net/Job.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
static inline unsigned char hf_hex2bin(char c, bool &err)
|
||||
@@ -55,14 +56,25 @@ static inline char hf_bin2hex(unsigned char c)
|
||||
}
|
||||
|
||||
|
||||
Job::Job(int poolId, bool nicehash) :
|
||||
m_nicehash(nicehash),
|
||||
m_poolId(poolId),
|
||||
m_threadId(-1),
|
||||
Job::Job() :
|
||||
m_poolId(-2),
|
||||
m_variant(xmrig::VARIANT_AUTO),
|
||||
m_size(0),
|
||||
m_diff(0),
|
||||
m_target(0)
|
||||
{
|
||||
memset(m_coin, 0, sizeof(m_coin));
|
||||
}
|
||||
|
||||
|
||||
Job::Job(int poolId, int variant) :
|
||||
m_poolId(poolId),
|
||||
m_variant(variant),
|
||||
m_size(0),
|
||||
m_diff(0),
|
||||
m_target(0)
|
||||
{
|
||||
memset(m_coin, 0, sizeof(m_coin));
|
||||
}
|
||||
|
||||
|
||||
@@ -91,10 +103,6 @@ bool Job::setBlob(const char *blob)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*nonce() != 0 && !m_nicehash) {
|
||||
m_nicehash = true;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
memset(m_rawBlob, 0, sizeof(m_rawBlob));
|
||||
memcpy(m_rawBlob, blob, m_size * 2);
|
||||
@@ -146,6 +154,16 @@ bool Job::setTarget(const char *target)
|
||||
}
|
||||
|
||||
|
||||
void Job::setCoin(const char *coin)
|
||||
{
|
||||
if (strlen(coin) > 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(m_coin, coin, sizeof(m_coin));
|
||||
}
|
||||
|
||||
|
||||
bool Job::fromHex(const char* in, unsigned int len, unsigned char* out)
|
||||
{
|
||||
bool error = false;
|
||||
@@ -156,6 +174,7 @@ bool Job::fromHex(const char* in, unsigned int len, unsigned char* out)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -173,3 +192,9 @@ bool Job::operator==(const Job &other) const
|
||||
{
|
||||
return m_id == other.m_id && memcmp(m_blob, other.m_blob, sizeof(m_blob)) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool Job::operator!=(const Job &other) const
|
||||
{
|
||||
return m_id != other.m_id || memcmp(m_blob, other.m_blob, sizeof(m_blob)) != 0;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -30,32 +30,36 @@
|
||||
|
||||
|
||||
#include "align.h"
|
||||
#include "net/JobId.h"
|
||||
#include "net/Id.h"
|
||||
|
||||
|
||||
class Job
|
||||
{
|
||||
public:
|
||||
Job(int poolId = -2, bool nicehash = false);
|
||||
Job();
|
||||
Job(int poolId, int variant);
|
||||
~Job();
|
||||
|
||||
bool setBlob(const char *blob);
|
||||
bool setTarget(const char *target);
|
||||
void setCoin(const char *coin);
|
||||
|
||||
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 JobId &id() const { return m_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 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 (uint32_t) m_diff; }
|
||||
inline uint64_t target() const { return m_target; }
|
||||
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
|
||||
inline void setThreadId(int threadId) { m_threadId = threadId; }
|
||||
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 &clientId() const { return m_clientId; }
|
||||
inline const xmrig::Id &id() const { return m_id; }
|
||||
inline int poolId() const { return m_poolId; }
|
||||
inline int variant() const { return 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 reset() { m_size = 0; m_diff = 0; }
|
||||
inline void setClientId(const xmrig::Id &id) { m_clientId = id; }
|
||||
inline void setVariant(int variant) { m_variant = variant; }
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
inline char *rawBlob() { return m_rawBlob; }
|
||||
@@ -68,17 +72,19 @@ public:
|
||||
static void toHex(const unsigned char* in, unsigned int len, char* out);
|
||||
|
||||
bool operator==(const Job &other) const;
|
||||
bool operator!=(const Job &other) const;
|
||||
|
||||
private:
|
||||
VAR_ALIGN(16, uint8_t m_blob[84]); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
|
||||
|
||||
bool m_nicehash;
|
||||
char m_coin[5];
|
||||
int m_poolId;
|
||||
int m_threadId;
|
||||
JobId m_id;
|
||||
int m_variant;
|
||||
size_t m_size;
|
||||
uint64_t m_diff;
|
||||
uint64_t m_target;
|
||||
xmrig::Id m_clientId;
|
||||
xmrig::Id m_id;
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
VAR_ALIGN(16, char m_rawBlob[169]);
|
||||
|
||||
@@ -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,7 +28,8 @@
|
||||
#include "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;
|
||||
|
||||
151
src/net/Url.cpp
151
src/net/Url.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
|
||||
@@ -22,11 +22,15 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "net/Url.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -35,11 +39,12 @@
|
||||
|
||||
|
||||
Url::Url() :
|
||||
m_keepAlive(false),
|
||||
m_nicehash(false),
|
||||
m_host(nullptr),
|
||||
m_password(nullptr),
|
||||
m_user(nullptr),
|
||||
m_coin(""),
|
||||
m_variant(xmrig::VARIANT_AUTO),
|
||||
m_url(nullptr),
|
||||
m_port(kDefaultPort)
|
||||
{
|
||||
}
|
||||
@@ -57,22 +62,24 @@ Url::Url() :
|
||||
* @param url
|
||||
*/
|
||||
Url::Url(const char *url) :
|
||||
m_keepAlive(false),
|
||||
m_nicehash(false),
|
||||
m_host(nullptr),
|
||||
m_password(nullptr),
|
||||
m_user(nullptr),
|
||||
m_coin(""),
|
||||
m_variant(xmrig::VARIANT_AUTO),
|
||||
m_url(nullptr),
|
||||
m_port(kDefaultPort)
|
||||
{
|
||||
parse(url);
|
||||
}
|
||||
|
||||
|
||||
Url::Url(const char *host, uint16_t port, const char *user, const char *password, bool keepAlive, bool nicehash) :
|
||||
m_keepAlive(keepAlive),
|
||||
m_nicehash(nicehash),
|
||||
Url::Url(const char *host, uint16_t port, const char *user, const char *password) :
|
||||
m_password(password ? strdup(password) : nullptr),
|
||||
m_user(user ? strdup(user) : nullptr),
|
||||
m_coin(""),
|
||||
m_variant(xmrig::VARIANT_AUTO),
|
||||
m_url(nullptr),
|
||||
m_port(port)
|
||||
{
|
||||
m_host = strdup(host);
|
||||
@@ -84,12 +91,10 @@ Url::~Url()
|
||||
free(m_host);
|
||||
free(m_password);
|
||||
free(m_user);
|
||||
}
|
||||
|
||||
|
||||
bool Url::isNicehash() const
|
||||
{
|
||||
return isValid() && (m_nicehash || strstr(m_host, ".nicehash.com"));
|
||||
if (m_url) {
|
||||
delete [] m_url;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +115,10 @@ bool Url::parse(const char *url)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (base[0] == '[') {
|
||||
return parseIPv6(base);
|
||||
}
|
||||
|
||||
const char *port = strchr(base, ':');
|
||||
if (!port) {
|
||||
m_host = strdup(base);
|
||||
@@ -117,9 +126,8 @@ bool Url::parse(const char *url)
|
||||
}
|
||||
|
||||
const size_t size = port++ - base + 1;
|
||||
m_host = static_cast<char*>(malloc(size));
|
||||
m_host = new char[size]();
|
||||
memcpy(m_host, base, size - 1);
|
||||
m_host[size - 1] = '\0';
|
||||
|
||||
m_port = (uint16_t) strtol(port, nullptr, 10);
|
||||
return true;
|
||||
@@ -144,6 +152,52 @@ bool Url::setUserpass(const char *userpass)
|
||||
}
|
||||
|
||||
|
||||
const char *Url::url() const
|
||||
{
|
||||
if (!m_url) {
|
||||
const size_t size = strlen(m_host) + 8;
|
||||
m_url = new char[size];
|
||||
|
||||
snprintf(m_url, size - 1, "%s:%d", m_host, m_port);
|
||||
}
|
||||
|
||||
return m_url;
|
||||
}
|
||||
|
||||
|
||||
void Url::adjust(int algorithm)
|
||||
{
|
||||
if (!isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strlen(m_coin) == 0) {
|
||||
if (algorithm == xmrig::Config::CRYPTONIGHT) {
|
||||
memcpy(m_coin, "XMR", 4);
|
||||
}
|
||||
else {
|
||||
memcpy(m_coin, "AEON", 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Url::setCoin(const char *coin)
|
||||
{
|
||||
if (!coin || strlen(coin) > 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(m_coin, coin, sizeof(m_coin));
|
||||
|
||||
char *s = m_coin;
|
||||
while (*s) {
|
||||
*s = toupper((unsigned char) *s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Url::setPassword(const char *password)
|
||||
{
|
||||
if (!password) {
|
||||
@@ -166,11 +220,39 @@ void Url::setUser(const char *user)
|
||||
}
|
||||
|
||||
|
||||
void Url::setVariant(int variant)
|
||||
{
|
||||
switch (variant) {
|
||||
case xmrig::VARIANT_AUTO:
|
||||
case xmrig::VARIANT_NONE:
|
||||
case xmrig::VARIANT_V1:
|
||||
m_variant = variant;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Url::operator==(const Url &other) const
|
||||
{
|
||||
if (m_port != other.m_port || m_variant != other.m_variant) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp(host(), other.host()) != 0 || strcmp(user(), other.user()) != 0 || strcmp(password(), other.password()) != 0 || strcmp(coin(), other.coin()) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Url &Url::operator=(const Url *other)
|
||||
{
|
||||
m_keepAlive = other->m_keepAlive;
|
||||
m_nicehash = other->m_nicehash;
|
||||
m_port = other->m_port;
|
||||
m_port = other->m_port;
|
||||
m_variant = other->m_variant;
|
||||
|
||||
free(m_host);
|
||||
m_host = strdup(other->m_host);
|
||||
@@ -178,5 +260,34 @@ Url &Url::operator=(const Url *other)
|
||||
setPassword(other->m_password);
|
||||
setUser(other->m_user);
|
||||
|
||||
memcpy(m_coin, other->coin(), sizeof(m_coin));
|
||||
|
||||
if (m_url) {
|
||||
delete [] m_url;
|
||||
m_url = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool Url::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;
|
||||
m_host = new char[size]();
|
||||
memcpy(m_host, addr + 1, size - 1);
|
||||
|
||||
m_port = (uint16_t) strtol(port + 1, nullptr, 10);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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,32 +37,38 @@ public:
|
||||
|
||||
Url();
|
||||
Url(const char *url);
|
||||
Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, bool keepAlive = false, bool nicehash = false );
|
||||
Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr);
|
||||
~Url();
|
||||
|
||||
inline bool isKeepAlive() const { return m_keepAlive; }
|
||||
inline bool isValid() const { return m_host && m_port > 0; }
|
||||
inline const char *coin() const { return m_coin; }
|
||||
inline const char *host() const { return m_host; }
|
||||
inline const char *password() const { return m_password ? m_password : kDefaultPassword; }
|
||||
inline const char *user() const { return m_user ? m_user : kDefaultUser; }
|
||||
inline int variant() const { return m_variant; }
|
||||
inline uint16_t port() const { return m_port; }
|
||||
inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; }
|
||||
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
|
||||
|
||||
bool isNicehash() const;
|
||||
bool parse(const char *url);
|
||||
bool setUserpass(const char *userpass);
|
||||
const char *url() const;
|
||||
void adjust(int algorithm);
|
||||
void setCoin(const char *coin);
|
||||
void setPassword(const char *password);
|
||||
void setUser(const char *user);
|
||||
void setVariant(int variant);
|
||||
|
||||
bool operator==(const Url &other) const;
|
||||
Url &operator=(const Url *other);
|
||||
|
||||
private:
|
||||
bool m_keepAlive;
|
||||
bool m_nicehash;
|
||||
bool parseIPv6(const char *addr);
|
||||
|
||||
char *m_host;
|
||||
char *m_password;
|
||||
char *m_user;
|
||||
char m_coin[5];
|
||||
int m_variant;
|
||||
mutable char *m_url;
|
||||
uint16_t m_port;
|
||||
};
|
||||
|
||||
|
||||
@@ -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,10 +22,13 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "interfaces/IStrategyListener.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/strategies/DonateStrategy.h"
|
||||
#include "Options.h"
|
||||
#include "Platform.h"
|
||||
#include "proxy/StatsData.h"
|
||||
|
||||
|
||||
extern "C"
|
||||
@@ -39,26 +42,28 @@ static inline int random(int min, int max){
|
||||
}
|
||||
|
||||
|
||||
DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
|
||||
DonateStrategy::DonateStrategy(size_t id, xmrig::Controller *controller, IStrategyListener *listener) :
|
||||
m_active(false),
|
||||
m_suspended(false),
|
||||
m_listener(listener),
|
||||
m_id(id),
|
||||
m_donateTicks(0),
|
||||
m_target(0),
|
||||
m_ticks(0)
|
||||
m_ticks(0),
|
||||
m_controller(controller)
|
||||
{
|
||||
uint8_t hash[200];
|
||||
char userId[65] = { 0 };
|
||||
const char *user = Options::i()->pools().front()->user();
|
||||
const char *user = controller->config()->pools().front()->user();
|
||||
|
||||
keccak(reinterpret_cast<const uint8_t *>(user), static_cast<int>(strlen(user)), hash, sizeof(hash));
|
||||
Job::toHex(hash, 32, userId);
|
||||
|
||||
Url *url = new Url("proxy-fee.xmrig.com", Options::i()->coin() && strncmp(Options::i()->coin(), "aeon", 4) ? 3333 : 443, userId, nullptr, false, true);
|
||||
Url *url = new Url("proxy.fee.xmrig.com", controller->config()->algorithm() == xmrig::Config::CRYPTONIGHT_LITE ? 7777 : 4444, userId, nullptr);
|
||||
|
||||
m_client = new Client(-1, agent, this);
|
||||
m_client = new Client(-1, Platform::userAgent(), this);
|
||||
m_client->setUrl(url);
|
||||
m_client->setRetryPause(Options::i()->retryPause() * 1000);
|
||||
m_client->setRetryPause(1000);
|
||||
|
||||
delete url;
|
||||
|
||||
@@ -66,9 +71,15 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
|
||||
}
|
||||
|
||||
|
||||
DonateStrategy::~DonateStrategy()
|
||||
{
|
||||
m_client->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
bool DonateStrategy::reschedule()
|
||||
{
|
||||
const uint64_t level = Options::i()->donateLevel() * 60;
|
||||
const uint64_t level = m_controller->config()->donateLevel() * 60;
|
||||
if (m_donateTicks < level) {
|
||||
return false;
|
||||
}
|
||||
@@ -112,6 +123,11 @@ void DonateStrategy::tick(uint64_t now)
|
||||
m_ticks++;
|
||||
|
||||
if (m_ticks == m_target) {
|
||||
if (m_id == 0 && m_controller->statsData().upstreams.active == 1) {
|
||||
m_target += 600;
|
||||
return;
|
||||
}
|
||||
|
||||
m_client->connect();
|
||||
}
|
||||
|
||||
@@ -136,10 +152,10 @@ void DonateStrategy::onJobReceived(Client *client, const Job &job)
|
||||
{
|
||||
if (!isActive()) {
|
||||
m_active = true;
|
||||
m_listener->onActive(client);
|
||||
m_listener->onActive(this, client);
|
||||
}
|
||||
|
||||
m_listener->onJob(client, job);
|
||||
m_listener->onJob(this, client, job);
|
||||
}
|
||||
|
||||
|
||||
@@ -150,5 +166,5 @@ void DonateStrategy::onLoginSuccess(Client *client)
|
||||
|
||||
void DonateStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
|
||||
{
|
||||
m_listener->onResultAccepted(client, result, error);
|
||||
m_listener->onResultAccepted(this, client, result, error);
|
||||
}
|
||||
|
||||
@@ -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,10 +34,17 @@ class IStrategyListener;
|
||||
class Url;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class DonateStrategy : public IStrategy, public IClientListener
|
||||
{
|
||||
public:
|
||||
DonateStrategy(const char *agent, IStrategyListener *listener);
|
||||
DonateStrategy(size_t id, xmrig::Controller *controller, IStrategyListener *listener);
|
||||
~DonateStrategy();
|
||||
|
||||
bool reschedule();
|
||||
|
||||
inline bool isActive() const override { return m_active; }
|
||||
@@ -59,9 +66,11 @@ private:
|
||||
bool m_suspended;
|
||||
Client *m_client;
|
||||
IStrategyListener *m_listener;
|
||||
size_t m_id;
|
||||
uint64_t m_donateTicks;
|
||||
uint64_t m_target;
|
||||
uint64_t m_ticks;
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
||||
#endif /* __SINGLEPOOLSTRATEGY_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,22 +25,37 @@
|
||||
#include "interfaces/IStrategyListener.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/strategies/FailoverStrategy.h"
|
||||
#include "Options.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, const char *agent, IStrategyListener *listener) :
|
||||
FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
|
||||
m_quiet(quiet),
|
||||
m_retries(retries),
|
||||
m_retryPause(retryPause),
|
||||
m_active(-1),
|
||||
m_index(0),
|
||||
m_listener(listener)
|
||||
{
|
||||
for (const Url *url : urls) {
|
||||
add(url, agent);
|
||||
add(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FailoverStrategy::~FailoverStrategy()
|
||||
{
|
||||
for (Client *client : m_pools) {
|
||||
client->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int64_t FailoverStrategy::submit(const JobResult &result)
|
||||
{
|
||||
if (m_active == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return m_pools[m_active]->submit(result);
|
||||
}
|
||||
|
||||
@@ -57,7 +72,7 @@ void FailoverStrategy::resume()
|
||||
return;
|
||||
}
|
||||
|
||||
m_listener->onJob( m_pools[m_active], m_pools[m_active]->job());
|
||||
m_listener->onJob(this, m_pools[m_active], m_pools[m_active]->job());
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +108,7 @@ void FailoverStrategy::onClose(Client *client, int failures)
|
||||
m_listener->onPause(this);
|
||||
}
|
||||
|
||||
if (m_index == 0 && failures < Options::i()->retries()) {
|
||||
if (m_index == 0 && failures < m_retries) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -106,7 +121,7 @@ void FailoverStrategy::onClose(Client *client, int failures)
|
||||
void FailoverStrategy::onJobReceived(Client *client, const Job &job)
|
||||
{
|
||||
if (m_active == client->id()) {
|
||||
m_listener->onJob(client, job);
|
||||
m_listener->onJob(this, client, job);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,22 +142,23 @@ void FailoverStrategy::onLoginSuccess(Client *client)
|
||||
|
||||
if (active >= 0 && active != m_active) {
|
||||
m_index = m_active = active;
|
||||
m_listener->onActive(client);
|
||||
m_listener->onActive(this, client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
|
||||
{
|
||||
m_listener->onResultAccepted(client, result, error);
|
||||
m_listener->onResultAccepted(this, client, result, error);
|
||||
}
|
||||
|
||||
|
||||
void FailoverStrategy::add(const Url *url, const char *agent)
|
||||
void FailoverStrategy::add(const Url *url)
|
||||
{
|
||||
Client *client = new Client((int) m_pools.size(), agent, this);
|
||||
Client *client = new Client((int) m_pools.size(), Platform::userAgent(), this);
|
||||
client->setUrl(url);
|
||||
client->setRetryPause(Options::i()->retryPause() * 1000);
|
||||
client->setRetryPause(m_retryPause * 1000);
|
||||
client->setQuiet(m_quiet);
|
||||
|
||||
m_pools.push_back(client);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -40,7 +40,8 @@ class Url;
|
||||
class FailoverStrategy : public IStrategy, public IClientListener
|
||||
{
|
||||
public:
|
||||
FailoverStrategy(const std::vector<Url*> &urls, const char *agent, IStrategyListener *listener);
|
||||
FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
|
||||
~FailoverStrategy();
|
||||
|
||||
public:
|
||||
inline bool isActive() const override { return m_active >= 0; }
|
||||
@@ -58,8 +59,11 @@ protected:
|
||||
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
|
||||
|
||||
private:
|
||||
void add(const Url *url, const char *agent);
|
||||
void add(const Url *url);
|
||||
|
||||
const bool m_quiet;
|
||||
const int m_retries;
|
||||
const int m_retryPause;
|
||||
int m_active;
|
||||
int m_index;
|
||||
IStrategyListener *m_listener;
|
||||
|
||||
@@ -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,16 +25,23 @@
|
||||
#include "interfaces/IStrategyListener.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/strategies/SinglePoolStrategy.h"
|
||||
#include "Options.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener) :
|
||||
SinglePoolStrategy::SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet) :
|
||||
m_active(false),
|
||||
m_listener(listener)
|
||||
{
|
||||
m_client = new Client(0, agent, this);
|
||||
m_client = new Client(0, Platform::userAgent(), this);
|
||||
m_client->setUrl(url);
|
||||
m_client->setRetryPause(Options::i()->retryPause() * 1000);
|
||||
m_client->setRetryPause(retryPause * 1000);
|
||||
m_client->setQuiet(quiet);
|
||||
}
|
||||
|
||||
|
||||
SinglePoolStrategy::~SinglePoolStrategy()
|
||||
{
|
||||
m_client->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +63,7 @@ void SinglePoolStrategy::resume()
|
||||
return;
|
||||
}
|
||||
|
||||
m_listener->onJob(m_client, m_client->job());
|
||||
m_listener->onJob(this, m_client, m_client->job());
|
||||
}
|
||||
|
||||
|
||||
@@ -85,18 +92,18 @@ void SinglePoolStrategy::onClose(Client *client, int failures)
|
||||
|
||||
void SinglePoolStrategy::onJobReceived(Client *client, const Job &job)
|
||||
{
|
||||
m_listener->onJob(client, job);
|
||||
m_listener->onJob(this, client, job);
|
||||
}
|
||||
|
||||
|
||||
void SinglePoolStrategy::onLoginSuccess(Client *client)
|
||||
{
|
||||
m_active = true;
|
||||
m_listener->onActive(client);
|
||||
m_listener->onActive(this, client);
|
||||
}
|
||||
|
||||
|
||||
void SinglePoolStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
|
||||
{
|
||||
m_listener->onResultAccepted(client, result, error);
|
||||
m_listener->onResultAccepted(this, client, result, error);
|
||||
}
|
||||
|
||||
@@ -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,7 +37,8 @@ class Url;
|
||||
class SinglePoolStrategy : public IStrategy, public IClientListener
|
||||
{
|
||||
public:
|
||||
SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener);
|
||||
SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet = false);
|
||||
~SinglePoolStrategy();
|
||||
|
||||
public:
|
||||
inline bool isActive() const override { return m_active; }
|
||||
|
||||
@@ -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,46 +37,86 @@ public:
|
||||
|
||||
|
||||
inline Addr() :
|
||||
m_host(nullptr),
|
||||
m_port(kDefaultPort)
|
||||
m_addr(nullptr),
|
||||
m_ip(nullptr),
|
||||
m_version(0),
|
||||
m_port(0)
|
||||
{}
|
||||
|
||||
|
||||
inline Addr(const char *addr) :
|
||||
m_host(nullptr),
|
||||
m_port(kDefaultPort)
|
||||
m_addr(strdup(addr)),
|
||||
m_ip(nullptr),
|
||||
m_version(0),
|
||||
m_port(0)
|
||||
{
|
||||
if (!addr) {
|
||||
if (!addr || strlen(addr) < 5) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *port = strchr(addr, ':');
|
||||
if (!port) {
|
||||
m_host = strdup(addr);
|
||||
if (addr[0] == '[') {
|
||||
parseIPv6(addr);
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t size = port++ - addr + 1;
|
||||
m_host = static_cast<char*>(malloc(size));
|
||||
memcpy(m_host, addr, size - 1);
|
||||
m_host[size - 1] = '\0';
|
||||
|
||||
m_port = (uint16_t) strtol(port, nullptr, 10);
|
||||
parseIPv4(addr);
|
||||
}
|
||||
|
||||
|
||||
inline ~Addr()
|
||||
{
|
||||
free(m_host);
|
||||
delete [] m_addr;
|
||||
delete [] m_ip;
|
||||
}
|
||||
|
||||
|
||||
inline bool isValid() const { return m_host && m_port > 0; }
|
||||
inline const char *host() const { return m_host; }
|
||||
inline bool isIPv6() const { return m_version == 6; }
|
||||
inline bool isValid() const { return m_version && m_ip && m_port > 0; }
|
||||
inline const char *addr() const { return m_addr; }
|
||||
inline const char *ip() const { return m_ip; }
|
||||
inline uint16_t port() const { return m_port; }
|
||||
|
||||
private:
|
||||
char *m_host;
|
||||
void parseIPv4(const char *addr)
|
||||
{
|
||||
const char *port = strchr(addr, ':');
|
||||
if (!port) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_version = 4;
|
||||
const size_t size = port++ - addr + 1;
|
||||
m_ip = new char[size]();
|
||||
memcpy(m_ip, addr, size - 1);
|
||||
|
||||
m_port = (uint16_t) strtol(port, nullptr, 10);
|
||||
}
|
||||
|
||||
|
||||
void parseIPv6(const char *addr)
|
||||
{
|
||||
const char *end = strchr(addr, ']');
|
||||
if (!end) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *port = strchr(end, ':');
|
||||
if (!port) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_version = 6;
|
||||
const size_t size = end - addr;
|
||||
m_ip = new char[size]();
|
||||
memcpy(m_ip, addr + 1, size - 1);
|
||||
|
||||
m_port = (uint16_t) strtol(port + 1, nullptr, 10);
|
||||
}
|
||||
|
||||
|
||||
char *m_addr;
|
||||
char *m_ip;
|
||||
int m_version;
|
||||
uint16_t m_port;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -27,14 +27,16 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "Options.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "proxy/CustomDiff.h"
|
||||
#include "proxy/events/LoginEvent.h"
|
||||
#include "proxy/LoginRequest.h"
|
||||
#include "proxy/Miner.h"
|
||||
|
||||
|
||||
CustomDiff::CustomDiff()
|
||||
CustomDiff::CustomDiff(xmrig::Controller *controller) :
|
||||
m_controller(controller)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -61,7 +63,7 @@ void CustomDiff::onEvent(IEvent *event)
|
||||
|
||||
void CustomDiff::login(LoginEvent *event)
|
||||
{
|
||||
event->miner()->setCustomDiff(Options::i()->diff());
|
||||
event->miner()->setCustomDiff(m_controller->config()->diff());
|
||||
|
||||
if (!event->request.login()) {
|
||||
return;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -31,10 +31,15 @@
|
||||
class LoginEvent;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class CustomDiff : public IEventListener
|
||||
{
|
||||
public:
|
||||
CustomDiff();
|
||||
CustomDiff(xmrig::Controller *controller);
|
||||
~CustomDiff();
|
||||
|
||||
protected:
|
||||
@@ -43,6 +48,8 @@ protected:
|
||||
|
||||
private:
|
||||
void login(LoginEvent *event);
|
||||
|
||||
xmrig::Controller *m_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
|
||||
@@ -33,8 +33,8 @@ JobResult::JobResult(int64_t id, const char *jobId, const char *nonce, const cha
|
||||
nonce(nonce),
|
||||
result(result),
|
||||
id(id),
|
||||
jobId(jobId, 3),
|
||||
diff(0),
|
||||
jobId(jobId, 3),
|
||||
m_actualDiff(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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 <string.h>
|
||||
|
||||
|
||||
#include "net/JobId.h"
|
||||
#include "net/Id.h"
|
||||
|
||||
|
||||
class JobResult
|
||||
@@ -52,8 +52,8 @@ public:
|
||||
const char *nonce;
|
||||
const char *result;
|
||||
const int64_t id;
|
||||
JobId jobId;
|
||||
uint32_t diff;
|
||||
xmrig::Id jobId;
|
||||
|
||||
private:
|
||||
mutable uint64_t m_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
|
||||
@@ -45,7 +45,9 @@
|
||||
static int64_t nextId = 0;
|
||||
|
||||
|
||||
Miner::Miner() :
|
||||
Miner::Miner(bool nicehash, bool ipv6) :
|
||||
m_ipv6(ipv6),
|
||||
m_nicehash(nicehash),
|
||||
m_id(++nextId),
|
||||
m_loginId(0),
|
||||
m_recvBufPos(0),
|
||||
@@ -92,7 +94,12 @@ bool Miner::accept(uv_stream_t *server)
|
||||
int size = sizeof(addr);
|
||||
|
||||
uv_tcp_getpeername(&m_socket, reinterpret_cast<sockaddr*>(&addr), &size);
|
||||
uv_ip4_name(reinterpret_cast<sockaddr_in*>(&addr), m_ip, 16);
|
||||
|
||||
if (m_ipv6) {
|
||||
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(&addr), m_ip, 45);
|
||||
} else {
|
||||
uv_ip4_name(reinterpret_cast<sockaddr_in*>(&addr), m_ip, 16);
|
||||
}
|
||||
|
||||
uv_read_start(reinterpret_cast<uv_stream_t*>(&m_socket), Miner::onAllocBuffer, Miner::onRead);
|
||||
|
||||
@@ -108,9 +115,10 @@ void Miner::replyWithError(int64_t id, const char *message)
|
||||
|
||||
void Miner::setJob(Job &job)
|
||||
{
|
||||
snprintf(m_sendBuf, 4, "%02hhx", m_fixedByte);
|
||||
|
||||
memcpy(job.rawBlob() + 84, m_sendBuf, 2);
|
||||
if (m_nicehash) {
|
||||
snprintf(m_sendBuf, 4, "%02hhx", m_fixedByte);
|
||||
memcpy(job.rawBlob() + 84, m_sendBuf, 2);
|
||||
}
|
||||
|
||||
m_diff = job.diff();
|
||||
bool customDiff = false;
|
||||
@@ -126,12 +134,14 @@ void Miner::setJob(Job &job)
|
||||
int size = 0;
|
||||
if (m_state == WaitReadyState) {
|
||||
setState(ReadyState);
|
||||
size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"result\":{\"id\":\"%s\",\"job\":{\"blob\":\"%s\",\"job_id\":\"%s%02hhx0\",\"target\":\"%s\"},\"status\":\"OK\"}}\n",
|
||||
m_loginId, m_rpcId, job.rawBlob(), job.id().data(), m_fixedByte, customDiff ? target : job.rawTarget());
|
||||
size = snprintf(m_sendBuf, sizeof(m_sendBuf),
|
||||
"{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"result\":{\"id\":\"%s\",\"job\":{\"blob\":\"%s\",\"job_id\":\"%s%02hhx0\",\"target\":\"%s\",\"coin\":\"%s\",\"variant\":%d}%s,\"status\":\"OK\"}}\n",
|
||||
m_loginId, m_rpcId, job.rawBlob(), job.id().data(), m_fixedByte, customDiff ? target : job.rawTarget(), job.coin(), job.variant(), m_nicehash ? ",\"extensions\":[\"nicehash\"]" : "");
|
||||
}
|
||||
else {
|
||||
size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"jsonrpc\":\"2.0\",\"method\":\"job\",\"params\":{\"blob\":\"%s\",\"job_id\":\"%s%02hhx0\",\"target\":\"%s\"}}\n",
|
||||
job.rawBlob(), job.id().data(), m_fixedByte, customDiff ? target : job.rawTarget());
|
||||
size = snprintf(m_sendBuf, sizeof(m_sendBuf),
|
||||
"{\"jsonrpc\":\"2.0\",\"method\":\"job\",\"params\":{\"blob\":\"%s\",\"job_id\":\"%s%02hhx0\",\"target\":\"%s\",\"coin\":\"%s\",\"variant\":%d}}\n",
|
||||
job.rawBlob(), job.id().data(), m_fixedByte, customDiff ? target : job.rawTarget(), job.coin(), job.variant());
|
||||
}
|
||||
|
||||
send(size);
|
||||
@@ -180,11 +190,11 @@ bool Miner::parseRequest(int64_t id, const char *method, const rapidjson::Value
|
||||
if (!event->request.isValid() || event->request.actualDiff() < diff()) {
|
||||
event->reject(Error::LowDifficulty);
|
||||
}
|
||||
else if (!event->request.isCompatible(m_fixedByte)) {
|
||||
else if (m_nicehash && !event->request.isCompatible(m_fixedByte)) {
|
||||
event->reject(Error::InvalidNonce);
|
||||
}
|
||||
|
||||
if (m_customDiff && event->request.actualDiff() < m_diff) {
|
||||
if (event->error() == Error::NoError && m_customDiff && event->request.actualDiff() < m_diff) {
|
||||
success(id, "OK");
|
||||
return true;
|
||||
}
|
||||
@@ -193,7 +203,7 @@ bool Miner::parseRequest(int64_t id, const char *method, const rapidjson::Value
|
||||
replyWithError(id, event->message());
|
||||
}
|
||||
|
||||
return true;
|
||||
return event->error() != Error::InvalidNonce;
|
||||
}
|
||||
|
||||
if (strcmp(method, "keepalived") == 0) {
|
||||
@@ -296,8 +306,13 @@ void Miner::shutdown(bool had_error)
|
||||
|
||||
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(req->handle)) == 0) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(req->handle), [](uv_handle_t *handle) {
|
||||
CloseEvent::start(getMiner(handle->data));
|
||||
delete static_cast<Miner*>(handle->data);
|
||||
Miner *miner = getMiner(handle->data);
|
||||
if (!miner) {
|
||||
return;
|
||||
}
|
||||
|
||||
CloseEvent::start(miner);
|
||||
delete miner;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -309,6 +324,9 @@ void Miner::shutdown(bool had_error)
|
||||
void Miner::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
|
||||
{
|
||||
auto miner = getMiner(handle->data);
|
||||
if (!miner) {
|
||||
return;
|
||||
}
|
||||
|
||||
buf->base = &miner->m_recvBuf.base[miner->m_recvBufPos];
|
||||
buf->len = miner->m_recvBuf.len - miner->m_recvBufPos;
|
||||
@@ -318,6 +336,10 @@ void Miner::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *
|
||||
void Miner::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
||||
{
|
||||
auto miner = getMiner(stream->data);
|
||||
if (!miner) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nread < 0 || (size_t) nread > (sizeof(m_buf) - 8 - miner->m_recvBufPos)) {
|
||||
return miner->shutdown(nread != UV_EOF);;
|
||||
}
|
||||
@@ -326,7 +348,7 @@ void Miner::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
||||
miner->m_recvBufPos += nread;
|
||||
|
||||
char* end;
|
||||
char* start = buf->base;
|
||||
char* start = miner->m_recvBuf.base;
|
||||
size_t remaining = miner->m_recvBufPos;
|
||||
|
||||
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
|
||||
@@ -343,11 +365,11 @@ void Miner::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
||||
return;
|
||||
}
|
||||
|
||||
if (start == buf->base) {
|
||||
if (start == miner->m_recvBuf.base) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(buf->base, start, remaining);
|
||||
memcpy(miner->m_recvBuf.base, start, remaining);
|
||||
miner->m_recvBufPos = remaining;
|
||||
}
|
||||
|
||||
@@ -355,6 +377,10 @@ void Miner::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
||||
void Miner::onTimeout(uv_timer_t *handle)
|
||||
{
|
||||
auto miner = getMiner(handle->data);
|
||||
if (!miner) {
|
||||
return;
|
||||
}
|
||||
|
||||
miner->m_recvBuf.base[sizeof(m_buf) - 1] = '\0';
|
||||
|
||||
miner->shutdown(true);
|
||||
|
||||
@@ -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,7 +32,6 @@
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
class IMinerListener;
|
||||
class Job;
|
||||
class RejectEvent;
|
||||
|
||||
@@ -47,7 +46,7 @@ public:
|
||||
ClosingState
|
||||
};
|
||||
|
||||
Miner();
|
||||
Miner(bool nicehash, bool ipv6);
|
||||
~Miner();
|
||||
bool accept(uv_stream_t *server);
|
||||
void replyWithError(int64_t id, const char *message);
|
||||
@@ -88,8 +87,10 @@ private:
|
||||
|
||||
static inline Miner *getMiner(void *data) { return static_cast<Miner*>(data); }
|
||||
|
||||
bool m_ipv6;
|
||||
bool m_nicehash;
|
||||
char m_buf[2048];
|
||||
char m_ip[17];
|
||||
char m_ip[46];
|
||||
char m_rpcId[37];
|
||||
char m_sendBuf[768];
|
||||
int64_t m_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
|
||||
@@ -30,12 +30,14 @@
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "Counters.h"
|
||||
#include "log/AccessLog.h"
|
||||
#include "log/Log.h"
|
||||
#include "log/ShareLog.h"
|
||||
#include "Options.h"
|
||||
#include "Platform.h"
|
||||
#include "proxy/Addr.h"
|
||||
#include "proxy/Events.h"
|
||||
#include "proxy/events/ConnectionEvent.h"
|
||||
#include "proxy/Miner.h"
|
||||
@@ -43,21 +45,34 @@
|
||||
#include "proxy/Proxy.h"
|
||||
#include "proxy/ProxyDebug.h"
|
||||
#include "proxy/Server.h"
|
||||
#include "proxy/splitters/NonceSplitter.h"
|
||||
#include "proxy/splitters/nicehash/NonceSplitter.h"
|
||||
#include "proxy/splitters/simple/SimpleSplitter.h"
|
||||
#include "proxy/Stats.h"
|
||||
#include "proxy/workers/Workers.h"
|
||||
|
||||
|
||||
Proxy::Proxy(const Options *options) :
|
||||
m_ticks(0)
|
||||
Proxy::Proxy(xmrig::Controller *controller) :
|
||||
m_customDiff(controller),
|
||||
m_ticks(0),
|
||||
m_controller(controller)
|
||||
{
|
||||
srand(time(0) ^ (uintptr_t) this);
|
||||
|
||||
m_miners = new Miners();
|
||||
m_splitter = new NonceSplitter();
|
||||
m_shareLog = new ShareLog(m_stats);
|
||||
m_accessLog = new AccessLog();
|
||||
m_workers = new Workers();
|
||||
m_miners = new Miners();
|
||||
|
||||
Splitter *splitter = nullptr;
|
||||
if (controller->config()->mode() == xmrig::Config::NICEHASH_MODE) {
|
||||
splitter = new NonceSplitter(controller);
|
||||
}
|
||||
else {
|
||||
splitter = new SimpleSplitter(controller);
|
||||
}
|
||||
|
||||
m_splitter = splitter;
|
||||
|
||||
m_shareLog = new ShareLog(controller, m_stats);
|
||||
m_accessLog = new AccessLog(controller);
|
||||
m_workers = new Workers(controller);
|
||||
|
||||
m_timer.data = this;
|
||||
uv_timer_init(uv_default_loop(), &m_timer);
|
||||
@@ -66,18 +81,18 @@ Proxy::Proxy(const Options *options) :
|
||||
Events::subscribe(IEvent::ConnectionType, &m_stats);
|
||||
|
||||
Events::subscribe(IEvent::CloseType, m_miners);
|
||||
Events::subscribe(IEvent::CloseType, m_splitter);
|
||||
Events::subscribe(IEvent::CloseType, splitter);
|
||||
Events::subscribe(IEvent::CloseType, &m_stats);
|
||||
Events::subscribe(IEvent::CloseType, m_accessLog);
|
||||
Events::subscribe(IEvent::CloseType, m_workers);
|
||||
|
||||
Events::subscribe(IEvent::LoginType, &m_customDiff);
|
||||
Events::subscribe(IEvent::LoginType, m_splitter);
|
||||
Events::subscribe(IEvent::LoginType, splitter);
|
||||
Events::subscribe(IEvent::LoginType, &m_stats);
|
||||
Events::subscribe(IEvent::LoginType, m_accessLog);
|
||||
Events::subscribe(IEvent::LoginType, m_workers);
|
||||
|
||||
Events::subscribe(IEvent::SubmitType, m_splitter);
|
||||
Events::subscribe(IEvent::SubmitType, splitter);
|
||||
Events::subscribe(IEvent::SubmitType, &m_stats);
|
||||
Events::subscribe(IEvent::SubmitType, m_workers);
|
||||
|
||||
@@ -85,7 +100,9 @@ Proxy::Proxy(const Options *options) :
|
||||
Events::subscribe(IEvent::AcceptType, m_shareLog);
|
||||
Events::subscribe(IEvent::AcceptType, m_workers);
|
||||
|
||||
m_debug = new ProxyDebug(options->isDebug());
|
||||
m_debug = new ProxyDebug(controller->config()->isDebug());
|
||||
|
||||
controller->addListener(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,9 +123,9 @@ void Proxy::connect()
|
||||
{
|
||||
m_splitter->connect();
|
||||
|
||||
const std::vector<Addr*> &addrs = Options::i()->addrs();
|
||||
const std::vector<Addr*> &addrs = m_controller->config()->addrs();
|
||||
for (const Addr *addr : addrs) {
|
||||
bind(addr->host(), addr->port());
|
||||
bind(addr);
|
||||
}
|
||||
|
||||
uv_timer_start(&m_timer, Proxy::onTick, 1000, 1000);
|
||||
@@ -123,8 +140,8 @@ void Proxy::printConnections()
|
||||
|
||||
void Proxy::printHashrate()
|
||||
{
|
||||
LOG_INFO(Options::i()->colors() ? "\x1B[01;32m* \x1B[01;37mspeed\x1B[0m \x1B[01;30m(1m) \x1B[01;36m%03.1f\x1B[0m, \x1B[01;30m(10m) \x1B[01;36m%03.1f\x1B[0m, \x1B[01;30m(1h) \x1B[01;36m%03.1f\x1B[0m, \x1B[01;30m(12h) \x1B[01;36m%03.1f\x1B[0m, \x1B[01;30m(24h) \x1B[01;36m%03.1f KH/s"
|
||||
: "* speed (1m) %03.1f, (10m) %03.1f, (1h) %03.1f, (12h) %03.1f, (24h) %03.1f KH/s",
|
||||
LOG_INFO(isColors() ? "\x1B[01;32m* \x1B[01;37mspeed\x1B[0m \x1B[01;30m(1m) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(10m) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(1h) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(12h) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(24h) \x1B[01;36m%03.2f kH/s"
|
||||
: "* speed (1m) %03.2f, (10m) %03.2f, (1h) %03.2f, (12h) %03.2f, (24h) %03.2f kH/s",
|
||||
m_stats.hashrate(60), m_stats.hashrate(600), m_stats.hashrate(3600), m_stats.hashrate(3600 * 12), m_stats.hashrate(3600 * 24));
|
||||
}
|
||||
|
||||
@@ -141,6 +158,18 @@ void Proxy::toggleDebug()
|
||||
}
|
||||
|
||||
|
||||
const StatsData &Proxy::statsData() const
|
||||
{
|
||||
return m_stats.data();
|
||||
}
|
||||
|
||||
|
||||
const std::vector<Worker> &Proxy::workers() const
|
||||
{
|
||||
return m_workers->workers();
|
||||
}
|
||||
|
||||
|
||||
#ifdef APP_DEVEL
|
||||
void Proxy::printState()
|
||||
{
|
||||
@@ -153,9 +182,21 @@ void Proxy::printState()
|
||||
#endif
|
||||
|
||||
|
||||
void Proxy::bind(const char *ip, uint16_t port)
|
||||
void Proxy::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
|
||||
{
|
||||
auto server = new Server(ip, port);
|
||||
m_debug->setEnabled(config->isDebug());
|
||||
}
|
||||
|
||||
|
||||
bool Proxy::isColors() const
|
||||
{
|
||||
return m_controller->config()->colors();
|
||||
}
|
||||
|
||||
|
||||
void Proxy::bind(const Addr *addr)
|
||||
{
|
||||
auto server = new Server(addr, m_controller->config()->mode() == xmrig::Config::NICEHASH_MODE);
|
||||
|
||||
if (server->bind()) {
|
||||
m_servers.push_back(server);
|
||||
@@ -174,10 +215,10 @@ void Proxy::gc()
|
||||
|
||||
void Proxy::print()
|
||||
{
|
||||
LOG_INFO(Options::i()->colors() ? "\x1B[01;36m%03.1f KH/s\x1B[0m, shares: \x1B[01;37m%" PRIu64 "\x1B[0m/%s%" PRIu64 "\x1B[0m +%" PRIu64 ", upstreams: \x1B[01;37m%u\x1B[0m, miners: \x1B[01;37m%" PRIu64 "\x1B[0m (max \x1B[01;37m%" PRIu64 "\x1B[0m) +%u/-%u"
|
||||
: "%03.1f KH/s, shares: %" PRIu64 "/%s%" PRIu64 " +%" PRIu64 ", upstreams: %u, miners: %" PRIu64 " (max %" PRIu64 " +%u/-%u",
|
||||
m_stats.hashrate(60), m_stats.data().accepted, Options::i()->colors() ? (m_stats.data().rejected ? "\x1B[31m" : "\x1B[01;37m") : "", m_stats.data().rejected,
|
||||
Counters::accepted, m_splitter->activeUpstreams(), Counters::miners(), Counters::maxMiners(), Counters::added(), Counters::removed());
|
||||
LOG_INFO(isColors() ? "\x1B[01;36m%03.2f kH/s\x1B[0m, shares: \x1B[01;37m%" PRIu64 "\x1B[0m/%s%" PRIu64 "\x1B[0m +%" PRIu64 ", upstreams: \x1B[01;37m%u\x1B[0m, miners: \x1B[01;37m%" PRIu64 "\x1B[0m (max \x1B[01;37m%" PRIu64 "\x1B[0m) +%u/-%u"
|
||||
: "%03.2f kH/s, shares: %" PRIu64 "/%s%" PRIu64 " +%" PRIu64 ", upstreams: %u, miners: %" PRIu64 " (max %" PRIu64 " +%u/-%u",
|
||||
m_stats.hashrate(60), m_stats.data().accepted, isColors() ? (m_stats.data().rejected ? "\x1B[31m" : "\x1B[01;37m") : "", m_stats.data().rejected,
|
||||
Counters::accepted, m_splitter->upstreams().active, Counters::miners(), Counters::maxMiners(), Counters::added(), Counters::removed());
|
||||
|
||||
Counters::reset();
|
||||
}
|
||||
@@ -185,7 +226,7 @@ void Proxy::print()
|
||||
|
||||
void Proxy::tick()
|
||||
{
|
||||
m_stats.tick(m_ticks, *m_splitter);
|
||||
m_stats.tick(m_ticks, m_splitter);
|
||||
|
||||
m_ticks++;
|
||||
|
||||
|
||||
@@ -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,13 +29,16 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "interfaces/IControllerListener.h"
|
||||
#include "proxy/CustomDiff.h"
|
||||
#include "proxy/Stats.h"
|
||||
#include "proxy/workers/Worker.h"
|
||||
|
||||
|
||||
class AccessLog;
|
||||
class Addr;
|
||||
class Miners;
|
||||
class NonceSplitter;
|
||||
class ISplitter;
|
||||
class Options;
|
||||
class ProxyDebug;
|
||||
class Server;
|
||||
@@ -44,10 +47,15 @@ class Url;
|
||||
class Workers;
|
||||
|
||||
|
||||
class Proxy
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class Proxy : public xmrig::IControllerListener
|
||||
{
|
||||
public:
|
||||
Proxy(const Options *options);
|
||||
Proxy(xmrig::Controller *controller);
|
||||
~Proxy();
|
||||
|
||||
void connect();
|
||||
@@ -56,15 +64,23 @@ public:
|
||||
void printWorkers();
|
||||
void toggleDebug();
|
||||
|
||||
const StatsData &statsData() const;
|
||||
const std::vector<Worker> &workers() const;
|
||||
|
||||
# ifdef APP_DEVEL
|
||||
void printState();
|
||||
# endif
|
||||
|
||||
protected:
|
||||
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
|
||||
|
||||
private:
|
||||
constexpr static int kPrintInterval = 60;
|
||||
constexpr static int kGCInterval = 60;
|
||||
|
||||
void bind(const char *ip, uint16_t port);
|
||||
bool isColors() const;
|
||||
void bind(const Addr *addr);
|
||||
void bind(const char *ip, uint16_t port, bool ipv6);
|
||||
void gc();
|
||||
void print();
|
||||
void tick();
|
||||
@@ -74,8 +90,8 @@ private:
|
||||
|
||||
AccessLog *m_accessLog;
|
||||
CustomDiff m_customDiff;
|
||||
ISplitter *m_splitter;
|
||||
Miners *m_miners;
|
||||
NonceSplitter *m_splitter;
|
||||
ProxyDebug *m_debug;
|
||||
ShareLog *m_shareLog;
|
||||
Stats m_stats;
|
||||
@@ -83,6 +99,7 @@ private:
|
||||
uint64_t m_ticks;
|
||||
uv_timer_t m_timer;
|
||||
Workers *m_workers;
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -34,7 +34,8 @@ public:
|
||||
ProxyDebug(bool enabled);
|
||||
~ProxyDebug();
|
||||
|
||||
inline void toggle() { m_enabled = !m_enabled; }
|
||||
inline void setEnabled(bool enabled) { m_enabled = enabled; }
|
||||
inline void toggle() { m_enabled = !m_enabled; }
|
||||
|
||||
protected:
|
||||
void onEvent(IEvent *event) override;
|
||||
|
||||
@@ -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
|
||||
@@ -23,26 +23,48 @@
|
||||
|
||||
|
||||
#include "log/Log.h"
|
||||
#include "proxy/Addr.h"
|
||||
#include "proxy/events/ConnectionEvent.h"
|
||||
#include "proxy/Miner.h"
|
||||
#include "proxy/Server.h"
|
||||
|
||||
|
||||
Server::Server(const char *ip, uint16_t port) :
|
||||
m_ip(ip),
|
||||
m_port(port)
|
||||
Server::Server(const Addr *addr, bool nicehash) :
|
||||
m_nicehash(nicehash),
|
||||
m_ip(strdup(addr->ip())),
|
||||
m_version(0),
|
||||
m_port(addr->port())
|
||||
{
|
||||
uv_tcp_init(uv_default_loop(), &m_server);
|
||||
m_server.data = this;
|
||||
|
||||
uv_ip4_addr(ip, port, &m_addr);
|
||||
uv_tcp_nodelay(&m_server, 1);
|
||||
|
||||
if (addr->isIPv6() && uv_ip6_addr(m_ip, m_port, &m_addr6) == 0) {
|
||||
m_version = 6;
|
||||
return;
|
||||
}
|
||||
|
||||
if (uv_ip4_addr(m_ip, m_port, &m_addr) == 0) {
|
||||
m_version = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Server::~Server()
|
||||
{
|
||||
free(m_ip);
|
||||
}
|
||||
|
||||
|
||||
bool Server::bind()
|
||||
{
|
||||
uv_tcp_bind(&m_server, reinterpret_cast<const sockaddr*>(&m_addr), 0);
|
||||
if (!m_version) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const sockaddr *addr = m_version == 6 ? reinterpret_cast<const sockaddr*>(&m_addr6) : reinterpret_cast<const sockaddr*>(&m_addr);
|
||||
uv_tcp_bind(&m_server, addr, m_version == 6 ? UV_TCP_IPV6ONLY : 0);
|
||||
|
||||
const int r = uv_listen(reinterpret_cast<uv_stream_t*>(&m_server), 511, Server::onConnection);
|
||||
if (r) {
|
||||
@@ -54,18 +76,15 @@ bool Server::bind()
|
||||
}
|
||||
|
||||
|
||||
void Server::onConnection(uv_stream_t *server, int status)
|
||||
void Server::create(uv_stream_t *server, int status)
|
||||
{
|
||||
auto instance = static_cast<Server*>(server->data);
|
||||
|
||||
if (status < 0) {
|
||||
LOG_ERR("[%s:%u] new connection error: \"%s\"", instance->m_ip, instance->m_port, uv_strerror(status));
|
||||
LOG_ERR("[%s:%u] new connection error: \"%s\"", m_ip, m_port, uv_strerror(status));
|
||||
return;
|
||||
}
|
||||
|
||||
Miner *miner = new Miner();
|
||||
Miner *miner = new Miner(m_nicehash, m_version == 6);
|
||||
if (!miner) {
|
||||
LOG_ERR("NEW FAILED");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -74,5 +93,11 @@ void Server::onConnection(uv_stream_t *server, int status)
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectionEvent::start(miner, instance->m_port);
|
||||
ConnectionEvent::start(miner, m_port);
|
||||
}
|
||||
|
||||
|
||||
void Server::onConnection(uv_stream_t *server, int status)
|
||||
{
|
||||
static_cast<Server*>(server->data)->create(server, status);
|
||||
}
|
||||
|
||||
@@ -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,17 +28,26 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
class Addr;
|
||||
|
||||
|
||||
class Server
|
||||
{
|
||||
public:
|
||||
Server(const char *ip, uint16_t port);
|
||||
Server(const Addr *addr, bool nicehash);
|
||||
~Server();
|
||||
bool bind();
|
||||
|
||||
private:
|
||||
void create(uv_stream_t *server, int status);
|
||||
|
||||
static void onConnection(uv_stream_t *server, int status);
|
||||
|
||||
const char *m_ip;
|
||||
struct sockaddr_in m_addr;
|
||||
bool m_nicehash;
|
||||
char *m_ip;
|
||||
int m_version;
|
||||
sockaddr_in m_addr;
|
||||
sockaddr_in6 m_addr6;
|
||||
uint16_t m_port;
|
||||
uv_tcp_t m_server;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
#include "api/Api.h"
|
||||
#include "Counters.h"
|
||||
#include "interfaces/ISplitter.h"
|
||||
#include "net/SubmitResult.h"
|
||||
#include "proxy/events/AcceptEvent.h"
|
||||
#include "proxy/splitters/NonceSplitter.h"
|
||||
#include "proxy/Stats.h"
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ Stats::~Stats()
|
||||
}
|
||||
|
||||
|
||||
void Stats::tick(uint64_t ticks, const NonceSplitter &splitter)
|
||||
void Stats::tick(uint64_t ticks, const ISplitter *splitter)
|
||||
{
|
||||
ticks++;
|
||||
|
||||
@@ -55,12 +55,12 @@ void Stats::tick(uint64_t ticks, const NonceSplitter &splitter)
|
||||
m_data.hashrate[2] = hashrate(3600);
|
||||
m_data.hashrate[3] = hashrate(3600 * 12);
|
||||
m_data.hashrate[4] = hashrate(3600 * 24);
|
||||
m_data.hashrate[5] = hashrate(m_data.uptime());
|
||||
|
||||
m_data.upstreams = splitter.activeUpstreams();
|
||||
m_data.upstreams = splitter->upstreams();
|
||||
m_data.miners = Counters::miners();
|
||||
m_data.maxMiners = Counters::maxMiners();
|
||||
m_data.expired = Counters::expired;
|
||||
Api::tick(m_data);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,7 +34,7 @@
|
||||
|
||||
|
||||
class AcceptEvent;
|
||||
class NonceSplitter;
|
||||
class ISplitter;
|
||||
|
||||
|
||||
class Stats : public IEventListener
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
Stats();
|
||||
~Stats();
|
||||
|
||||
void tick(uint64_t ticks, const NonceSplitter &splitter);
|
||||
void tick(uint64_t ticks, const ISplitter *splitter);
|
||||
|
||||
inline const StatsData &data() const { return m_data; }
|
||||
inline double hashrate(int seconds) const { return m_hashrate.calc(seconds); }
|
||||
|
||||
@@ -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,6 +31,9 @@
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "interfaces/ISplitter.h"
|
||||
|
||||
|
||||
class StatsData
|
||||
{
|
||||
public:
|
||||
@@ -44,8 +47,7 @@ public:
|
||||
maxMiners(0),
|
||||
miners(0),
|
||||
rejected(0),
|
||||
startTime(0),
|
||||
upstreams(0)
|
||||
startTime(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -84,7 +86,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
double hashrate[5] { 0.0 };
|
||||
double hashrate[6] { 0.0 };
|
||||
std::array<uint64_t, 10> topDiff { { } };
|
||||
std::vector<uint16_t> latency;
|
||||
uint64_t accepted;
|
||||
@@ -97,7 +99,7 @@ public:
|
||||
uint64_t miners;
|
||||
uint64_t rejected;
|
||||
uint64_t startTime;
|
||||
uint64_t upstreams;
|
||||
Upstreams upstreams;
|
||||
};
|
||||
|
||||
|
||||
|
||||
35
src/proxy/events/MinerEvent.cpp
Normal file
35
src/proxy/events/MinerEvent.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/* 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 "proxy/events/MinerEvent.h"
|
||||
#include "proxy/Miner.h"
|
||||
|
||||
|
||||
static const char *kDefaultIP = "0.0.0.0";
|
||||
|
||||
|
||||
const char *MinerEvent::ip() const
|
||||
{
|
||||
return m_miner ? m_miner->ip() : kDefaultIP;
|
||||
}
|
||||
@@ -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,6 +34,9 @@ class Miner;
|
||||
class MinerEvent : public Event
|
||||
{
|
||||
public:
|
||||
const char *ip() const;
|
||||
|
||||
|
||||
inline Miner *miner() const { return m_miner; }
|
||||
|
||||
|
||||
|
||||
33
src/proxy/splitters/Splitter.cpp
Normal file
33
src/proxy/splitters/Splitter.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/* 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 "core/Controller.h"
|
||||
#include "proxy/splitters/Splitter.h"
|
||||
|
||||
|
||||
Splitter::Splitter(xmrig::Controller *controller) :
|
||||
m_controller(controller)
|
||||
{
|
||||
controller->addListener(this);
|
||||
}
|
||||
48
src/proxy/splitters/Splitter.h
Normal file
48
src/proxy/splitters/Splitter.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* 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 __SPLITTER_H__
|
||||
#define __SPLITTER_H__
|
||||
|
||||
|
||||
#include "interfaces/IControllerListener.h"
|
||||
#include "interfaces/IEventListener.h"
|
||||
#include "interfaces/ISplitter.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class Splitter : public IEventListener, public ISplitter, public xmrig::IControllerListener
|
||||
{
|
||||
public:
|
||||
Splitter(xmrig::Controller *controller);
|
||||
|
||||
protected:
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __SPLITTER_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
|
||||
@@ -27,48 +27,43 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/Log.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/strategies/DonateStrategy.h"
|
||||
#include "net/strategies/FailoverStrategy.h"
|
||||
#include "net/strategies/SinglePoolStrategy.h"
|
||||
#include "net/Url.h"
|
||||
#include "Options.h"
|
||||
#include "proxy/Counters.h"
|
||||
#include "proxy/Error.h"
|
||||
#include "proxy/events/AcceptEvent.h"
|
||||
#include "proxy/events/SubmitEvent.h"
|
||||
#include "proxy/JobResult.h"
|
||||
#include "proxy/Miner.h"
|
||||
#include "proxy/splitters/NonceMapper.h"
|
||||
#include "proxy/splitters/NonceStorage.h"
|
||||
#include "proxy/splitters/nicehash/NonceMapper.h"
|
||||
#include "proxy/splitters/nicehash/NonceStorage.h"
|
||||
|
||||
|
||||
NonceMapper::NonceMapper(size_t id, const Options *options, const char *agent) :
|
||||
m_suspended(false),
|
||||
m_agent(agent),
|
||||
m_options(options),
|
||||
NonceMapper::NonceMapper(size_t id, xmrig::Controller *controller) :
|
||||
m_donate(nullptr),
|
||||
m_id(id)
|
||||
m_suspended(0),
|
||||
m_pending(nullptr),
|
||||
m_id(id),
|
||||
m_controller(controller)
|
||||
{
|
||||
m_storage = new NonceStorage();
|
||||
const std::vector<Url*> &pools = options->pools();
|
||||
m_storage = new NonceStorage();
|
||||
m_strategy = createStrategy(controller->config()->pools());
|
||||
|
||||
if (pools.size() > 1) {
|
||||
m_strategy = new FailoverStrategy(pools, m_agent, this);
|
||||
}
|
||||
else {
|
||||
m_strategy = new SinglePoolStrategy(pools.front(), m_agent, this);
|
||||
}
|
||||
|
||||
if (id != 0 && m_options->donateLevel() > 0) {
|
||||
m_donate = new DonateStrategy(m_agent, this);
|
||||
if (controller->config()->donateLevel() > 0) {
|
||||
m_donate = new DonateStrategy(id, controller, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NonceMapper::~NonceMapper()
|
||||
{
|
||||
delete m_pending;
|
||||
delete m_strategy;
|
||||
delete m_storage;
|
||||
delete m_donate;
|
||||
@@ -81,7 +76,7 @@ bool NonceMapper::add(Miner *miner, const LoginRequest &request)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_suspended) {
|
||||
if (isSuspended()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
@@ -92,13 +87,18 @@ bool NonceMapper::add(Miner *miner, const LoginRequest &request)
|
||||
|
||||
bool NonceMapper::isActive() const
|
||||
{
|
||||
return m_storage->isActive() && !m_suspended;
|
||||
return m_storage->isActive() && !isSuspended();
|
||||
}
|
||||
|
||||
|
||||
void NonceMapper::gc()
|
||||
{
|
||||
if (m_suspended || m_id == 0 || m_storage->isUsed()) {
|
||||
if (isSuspended()) {
|
||||
m_suspended++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_id == 0 || m_storage->isUsed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,15 @@ void NonceMapper::gc()
|
||||
}
|
||||
|
||||
|
||||
void NonceMapper::reload(const std::vector<Url*> &pools)
|
||||
{
|
||||
delete m_pending;
|
||||
|
||||
m_pending = createStrategy(pools);
|
||||
m_pending->connect();
|
||||
}
|
||||
|
||||
|
||||
void NonceMapper::remove(const Miner *miner)
|
||||
{
|
||||
m_storage->remove(miner);
|
||||
@@ -150,7 +159,7 @@ void NonceMapper::tick(uint64_t ticks, uint64_t now)
|
||||
#ifdef APP_DEVEL
|
||||
void NonceMapper::printState()
|
||||
{
|
||||
if (m_suspended) {
|
||||
if (isSuspended()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -159,7 +168,7 @@ void NonceMapper::printState()
|
||||
#endif
|
||||
|
||||
|
||||
void NonceMapper::onActive(Client *client)
|
||||
void NonceMapper::onActive(IStrategy *strategy, Client *client)
|
||||
{
|
||||
m_storage->setActive(true);
|
||||
|
||||
@@ -167,15 +176,24 @@ void NonceMapper::onActive(Client *client)
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(m_options->colors() ? "#%03u \x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "#%03u use pool %s:%d %s",
|
||||
m_id, client->host(), client->port(), client->ip());
|
||||
if (m_pending && strategy == m_pending) {
|
||||
delete m_strategy;
|
||||
|
||||
m_strategy = strategy;
|
||||
m_pending = nullptr;
|
||||
}
|
||||
|
||||
if (m_controller->config()->verbose()) {
|
||||
LOG_INFO(isColors() ? "#%03u \x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "#%03u use pool %s:%d %s",
|
||||
m_id, client->host(), client->port(), client->ip());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NonceMapper::onJob(Client *client, const Job &job)
|
||||
void NonceMapper::onJob(IStrategy *strategy, Client *client, const Job &job)
|
||||
{
|
||||
if (m_options->verbose()) {
|
||||
LOG_INFO(m_options->colors() ? "#%03u \x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d" : "#%03u new job from %s:%d diff %d",
|
||||
if (m_controller->config()->verbose()) {
|
||||
LOG_INFO(isColors() ? "#%03u \x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d" : "#%03u new job from %s:%d diff %d",
|
||||
m_id, client->host(), client->port(), job.diff());
|
||||
}
|
||||
|
||||
@@ -191,13 +209,13 @@ void NonceMapper::onPause(IStrategy *strategy)
|
||||
{
|
||||
m_storage->setActive(false);
|
||||
|
||||
if (!m_suspended) {
|
||||
if (!isSuspended()) {
|
||||
LOG_ERR("#%03u no active pools, stop", m_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NonceMapper::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
|
||||
void NonceMapper::onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error)
|
||||
{
|
||||
const SubmitCtx ctx = submitCtx(result.seq);
|
||||
|
||||
@@ -216,6 +234,22 @@ void NonceMapper::onResultAccepted(Client *client, const SubmitResult &result, c
|
||||
}
|
||||
|
||||
|
||||
bool NonceMapper::isColors() const
|
||||
{
|
||||
return m_controller->config()->colors();
|
||||
}
|
||||
|
||||
|
||||
IStrategy *NonceMapper::createStrategy(const std::vector<Url*> &pools)
|
||||
{
|
||||
if (pools.size() > 1) {
|
||||
return new FailoverStrategy(pools, m_controller->config()->retryPause(), m_controller->config()->retries(), this);
|
||||
}
|
||||
|
||||
return new SinglePoolStrategy(pools.front(), m_controller->config()->retryPause(), this);
|
||||
}
|
||||
|
||||
|
||||
SubmitCtx NonceMapper::submitCtx(int64_t seq)
|
||||
{
|
||||
if (!m_results.count(seq)) {
|
||||
@@ -236,7 +270,7 @@ SubmitCtx NonceMapper::submitCtx(int64_t seq)
|
||||
|
||||
void NonceMapper::connect()
|
||||
{
|
||||
m_suspended = false;
|
||||
m_suspended = 0;
|
||||
m_strategy->connect();
|
||||
|
||||
if (m_donate) {
|
||||
@@ -247,7 +281,7 @@ void NonceMapper::connect()
|
||||
|
||||
void NonceMapper::suspend()
|
||||
{
|
||||
m_suspended = true;
|
||||
m_suspended = 1;
|
||||
m_storage->setActive(false);
|
||||
m_storage->reset();
|
||||
m_strategy->stop();
|
||||
@@ -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
|
||||
@@ -45,6 +45,11 @@ class SubmitEvent;
|
||||
class Url;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class SubmitCtx
|
||||
{
|
||||
public:
|
||||
@@ -60,42 +65,46 @@ public:
|
||||
class NonceMapper : public IStrategyListener
|
||||
{
|
||||
public:
|
||||
NonceMapper(size_t id, const Options *options, const char *agent);
|
||||
NonceMapper(size_t id, xmrig::Controller *controller);
|
||||
~NonceMapper();
|
||||
|
||||
bool add(Miner *miner, const LoginRequest &request);
|
||||
bool isActive() const;
|
||||
void gc();
|
||||
void reload(const std::vector<Url*> &pools);
|
||||
void remove(const Miner *miner);
|
||||
void start();
|
||||
void submit(SubmitEvent *event);
|
||||
void tick(uint64_t ticks, uint64_t now);
|
||||
|
||||
inline bool isSuspended() const { return m_suspended; }
|
||||
inline bool isSuspended() const { return m_suspended > 0; }
|
||||
inline int suspended() const { return m_suspended; }
|
||||
|
||||
# ifdef APP_DEVEL
|
||||
void printState();
|
||||
# endif
|
||||
|
||||
protected:
|
||||
void onActive(Client *client) override;
|
||||
void onJob(Client *client, const Job &job) override;
|
||||
void onActive(IStrategy *strategy, Client *client) override;
|
||||
void onJob(IStrategy *strategy, Client *client, const Job &job) override;
|
||||
void onPause(IStrategy *strategy) override;
|
||||
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
|
||||
void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
|
||||
|
||||
private:
|
||||
bool isColors() const;
|
||||
IStrategy *createStrategy(const std::vector<Url*> &pools);
|
||||
SubmitCtx submitCtx(int64_t seq);
|
||||
void connect();
|
||||
void suspend();
|
||||
|
||||
bool m_suspended;
|
||||
const char *m_agent;
|
||||
const Options *m_options;
|
||||
DonateStrategy *m_donate;
|
||||
int m_suspended;
|
||||
IStrategy *m_pending;
|
||||
IStrategy *m_strategy;
|
||||
NonceStorage *m_storage;
|
||||
size_t m_id;
|
||||
std::map<int64_t, SubmitCtx> m_results;
|
||||
xmrig::Controller *m_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
|
||||
@@ -21,27 +21,32 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/Log.h"
|
||||
#include "Options.h"
|
||||
#include "Platform.h"
|
||||
#include "net/Url.h"
|
||||
#include "proxy/Counters.h"
|
||||
#include "proxy/events/CloseEvent.h"
|
||||
#include "proxy/events/LoginEvent.h"
|
||||
#include "proxy/events/SubmitEvent.h"
|
||||
#include "proxy/Miner.h"
|
||||
#include "proxy/splitters/NonceMapper.h"
|
||||
#include "proxy/splitters/NonceSplitter.h"
|
||||
#include "proxy/Stats.h"
|
||||
#include "proxy/splitters/nicehash/NonceMapper.h"
|
||||
#include "proxy/splitters/nicehash/NonceSplitter.h"
|
||||
#include "Summary.h"
|
||||
|
||||
|
||||
#define LABEL(x) " \x1B[01;30m" x ":\x1B[0m "
|
||||
|
||||
|
||||
NonceSplitter::NonceSplitter()
|
||||
static bool compare(Url *i, Url *j) {
|
||||
return *i == *j;
|
||||
}
|
||||
|
||||
|
||||
NonceSplitter::NonceSplitter(xmrig::Controller *controller) : Splitter(controller)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -51,23 +56,30 @@ NonceSplitter::~NonceSplitter()
|
||||
}
|
||||
|
||||
|
||||
uint32_t NonceSplitter::activeUpstreams() const
|
||||
Upstreams NonceSplitter::upstreams() const
|
||||
{
|
||||
uint32_t active = 0;
|
||||
uint64_t active = 0;
|
||||
uint64_t sleep = 0;
|
||||
|
||||
for (const NonceMapper *mapper : m_upstreams) {
|
||||
if (mapper->isActive()) {
|
||||
active++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mapper->isSuspended()) {
|
||||
sleep++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return active;
|
||||
return Upstreams(active, sleep, m_upstreams.size(), Counters::miners());
|
||||
}
|
||||
|
||||
|
||||
void NonceSplitter::connect()
|
||||
{
|
||||
auto upstream = new NonceMapper(m_upstreams.size(), Options::i(), Platform::userAgent());
|
||||
auto upstream = new NonceMapper(m_upstreams.size(), m_controller);
|
||||
m_upstreams.push_back(upstream);
|
||||
|
||||
upstream->start();
|
||||
@@ -79,42 +91,32 @@ void NonceSplitter::gc()
|
||||
for (NonceMapper *mapper : m_upstreams) {
|
||||
mapper->gc();
|
||||
}
|
||||
|
||||
while (m_upstreams.back()->suspended() >= 2) {
|
||||
delete m_upstreams.back();
|
||||
|
||||
m_upstreams.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NonceSplitter::printConnections()
|
||||
{
|
||||
int active = 0;
|
||||
int suspended = 0;
|
||||
const Upstreams info = upstreams();
|
||||
|
||||
for (const NonceMapper *mapper : m_upstreams) {
|
||||
if (mapper->isActive()) {
|
||||
active++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mapper->isSuspended()) {
|
||||
suspended++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const int error = (int) m_upstreams.size() - active - suspended;
|
||||
const double ratio = active > 0 ? ((double) Counters::miners() / active) : 0;
|
||||
|
||||
if (Options::i()->colors()) {
|
||||
LOG_INFO("\x1B[01;32m* \x1B[01;37mupstreams\x1B[0m" LABEL("active") "%s%d\x1B[0m" LABEL("sleep") "\x1B[01;37m%d\x1B[0m" LABEL("error") "%s%d\x1B[0m" LABEL("total") "\x1B[01;37m%d",
|
||||
active ? "\x1B[01;32m" : "\x1B[01;31m", active, suspended, error ? "\x1B[01;31m" : "\x1B[01;37m", error, m_upstreams.size());
|
||||
if (m_controller->config()->colors()) {
|
||||
LOG_INFO("\x1B[01;32m* \x1B[01;37mupstreams\x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("sleep") "\x1B[01;37m%" PRIu64 "\x1B[0m" LABEL("error") "%s%" PRIu64 "\x1B[0m" LABEL("total") "\x1B[01;37m%" PRIu64,
|
||||
info.active ? "\x1B[01;32m" : "\x1B[01;31m", info.active, info.sleep, info.error ? "\x1B[01;31m" : "\x1B[01;37m", info.error, info.total);
|
||||
|
||||
LOG_INFO("\x1B[01;32m* \x1B[01;37mminers \x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("max") "\x1B[01;37m%" PRIu64 "\x1B[0m" LABEL("ratio") "%s1:%3.1f",
|
||||
Counters::miners() ? "\x1B[01;32m" : "\x1B[01;31m", Counters::miners(), Counters::maxMiners(), (ratio > 200 ? "\x1B[01;32m" : "\x1B[01;33m"), ratio);
|
||||
Counters::miners() ? "\x1B[01;32m" : "\x1B[01;31m", Counters::miners(), Counters::maxMiners(), (info.ratio > 200 ? "\x1B[01;32m" : "\x1B[01;33m"), info.ratio);
|
||||
}
|
||||
else {
|
||||
LOG_INFO("* upstreams: active %d sleep %d error %d total %d",
|
||||
active, suspended, error, m_upstreams.size());
|
||||
LOG_INFO("* upstreams: active %" PRIu64 " sleep %" PRIu64 " error %" PRIu64 " total %" PRIu64,
|
||||
info.active, info.sleep, info.error, info.total);
|
||||
|
||||
LOG_INFO("* miners: active %" PRIu64 " max %" PRIu64 " ratio 1:%3.1f",
|
||||
Counters::miners(), Counters::maxMiners(), ratio);
|
||||
Counters::miners(), Counters::maxMiners(), info.ratio);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +141,21 @@ void NonceSplitter::printState()
|
||||
#endif
|
||||
|
||||
|
||||
void NonceSplitter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
|
||||
{
|
||||
const std::vector<Url*> &pools = config->pools();
|
||||
const std::vector<Url*> &previousPools = previousConfig->pools();
|
||||
|
||||
if (pools.size() != previousPools.size() || !std::equal(pools.begin(), pools.end(), previousPools.begin(), compare)) {
|
||||
Summary::printPools(config);
|
||||
|
||||
for (NonceMapper *mapper : m_upstreams) {
|
||||
mapper->reload(pools);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NonceSplitter::onEvent(IEvent *event)
|
||||
{
|
||||
switch (event->type())
|
||||
@@ -194,7 +211,5 @@ void NonceSplitter::remove(Miner *miner)
|
||||
|
||||
void NonceSplitter::submit(SubmitEvent *event)
|
||||
{
|
||||
assert(event->miner()->mapperId() >= 0);
|
||||
|
||||
m_upstreams[event->miner()->mapperId()]->submit(event);
|
||||
}
|
||||
@@ -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 <vector>
|
||||
|
||||
|
||||
#include "interfaces/IEventListener.h"
|
||||
#include "proxy/splitters/Splitter.h"
|
||||
|
||||
|
||||
class LoginEvent;
|
||||
@@ -40,25 +40,31 @@ class Stats;
|
||||
class SubmitEvent;
|
||||
|
||||
|
||||
class NonceSplitter : public IEventListener
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class NonceSplitter : public Splitter
|
||||
{
|
||||
public:
|
||||
NonceSplitter();
|
||||
NonceSplitter(xmrig::Controller *controller);
|
||||
~NonceSplitter();
|
||||
|
||||
uint32_t activeUpstreams() const;
|
||||
void connect();
|
||||
void gc();
|
||||
void printConnections();
|
||||
void tick(uint64_t ticks);
|
||||
protected:
|
||||
Upstreams upstreams() const override;
|
||||
void connect() override;
|
||||
void gc() override;
|
||||
void printConnections() override;
|
||||
void tick(uint64_t ticks) override;
|
||||
|
||||
# ifdef APP_DEVEL
|
||||
void printState();
|
||||
void printState() override;
|
||||
# endif
|
||||
|
||||
protected:
|
||||
void onEvent(IEvent *event) override;
|
||||
inline void onRejectedEvent(IEvent *event) override {}
|
||||
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
|
||||
void onEvent(IEvent *event) override;
|
||||
|
||||
private:
|
||||
void login(LoginEvent *event);
|
||||
@@ -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,7 +28,7 @@
|
||||
#include "proxy/Counters.h"
|
||||
#include "proxy/LoginRequest.h"
|
||||
#include "proxy/Miner.h"
|
||||
#include "proxy/splitters/NonceStorage.h"
|
||||
#include "proxy/splitters/nicehash/NonceStorage.h"
|
||||
|
||||
|
||||
NonceStorage::NonceStorage() :
|
||||
@@ -77,7 +77,7 @@ bool NonceStorage::isUsed() const
|
||||
}
|
||||
|
||||
|
||||
bool NonceStorage::isValidJobId(const JobId &id)
|
||||
bool NonceStorage::isValidJobId(const xmrig::Id &id) const
|
||||
{
|
||||
if (m_job.id() == id) {
|
||||
return true;
|
||||
@@ -127,8 +127,14 @@ void NonceStorage::setJob(const Job &job)
|
||||
}
|
||||
}
|
||||
|
||||
m_prevJob = m_job;
|
||||
m_job = job;
|
||||
if (m_job.clientId() == job.clientId()) {
|
||||
m_prevJob = m_job;
|
||||
}
|
||||
else {
|
||||
m_prevJob.reset();
|
||||
}
|
||||
|
||||
m_job = job;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i) {
|
||||
const int64_t index = m_used[i];
|
||||
@@ -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
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
|
||||
bool add(Miner *miner, const LoginRequest &request);
|
||||
bool isUsed() const;
|
||||
bool isValidJobId(const JobId &id);
|
||||
bool isValidJobId(const xmrig::Id &id) const;
|
||||
Miner *miner(int64_t id);
|
||||
void remove(const Miner *miner);
|
||||
void reset();
|
||||
258
src/proxy/splitters/simple/SimpleMapper.cpp
Normal file
258
src/proxy/splitters/simple/SimpleMapper.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/* 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 <inttypes.h>
|
||||
#include <memory>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/Log.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/strategies/DonateStrategy.h"
|
||||
#include "net/strategies/FailoverStrategy.h"
|
||||
#include "net/strategies/SinglePoolStrategy.h"
|
||||
#include "net/Url.h"
|
||||
#include "proxy/Counters.h"
|
||||
#include "proxy/Error.h"
|
||||
#include "proxy/events/AcceptEvent.h"
|
||||
#include "proxy/events/SubmitEvent.h"
|
||||
#include "proxy/JobResult.h"
|
||||
#include "proxy/Miner.h"
|
||||
#include "proxy/splitters/simple/SimpleMapper.h"
|
||||
|
||||
|
||||
SimpleMapper::SimpleMapper(uint64_t id, xmrig::Controller *controller) :
|
||||
m_active(false),
|
||||
m_donate(nullptr),
|
||||
m_pending(nullptr),
|
||||
m_miner(nullptr),
|
||||
m_id(id),
|
||||
m_idleTime(0),
|
||||
m_controller(controller)
|
||||
{
|
||||
m_strategy = createStrategy(controller->config()->pools());
|
||||
|
||||
// if (controller->config()->donateLevel() > 0) {
|
||||
// m_donate = new DonateStrategy(id, controller, this);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
SimpleMapper::~SimpleMapper()
|
||||
{
|
||||
delete m_pending;
|
||||
delete m_strategy;
|
||||
delete m_donate;
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::add(Miner *miner, const LoginRequest &request)
|
||||
{
|
||||
m_miner = miner;
|
||||
m_miner->setMapperId(m_id);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::reload(const std::vector<Url*> &pools)
|
||||
{
|
||||
delete m_pending;
|
||||
|
||||
m_pending = createStrategy(pools);
|
||||
m_pending->connect();
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::remove(const Miner *miner)
|
||||
{
|
||||
m_miner = nullptr;
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::reuse(Miner *miner, const LoginRequest &request)
|
||||
{
|
||||
m_idleTime = 0;
|
||||
m_miner = miner;
|
||||
m_miner->setMapperId(m_id);
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::submit(SubmitEvent *event)
|
||||
{
|
||||
if (!isActive()) {
|
||||
return event->reject(Error::BadGateway);
|
||||
}
|
||||
|
||||
if (!isValidJobId(event->request.jobId)) {
|
||||
return event->reject(Error::InvalidJobId);
|
||||
}
|
||||
|
||||
JobResult req = event->request;
|
||||
req.diff = m_job.diff();
|
||||
|
||||
IStrategy *strategy = m_donate && m_donate->isActive() ? m_donate : m_strategy;
|
||||
|
||||
if (strategy) {
|
||||
strategy->submit(req);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::tick(uint64_t ticks, uint64_t now)
|
||||
{
|
||||
m_strategy->tick(now);
|
||||
|
||||
if (!m_miner) {
|
||||
m_idleTime++;
|
||||
}
|
||||
|
||||
if (m_donate) {
|
||||
m_donate->tick(now);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::onActive(IStrategy *strategy, Client *client)
|
||||
{
|
||||
m_active = true;
|
||||
|
||||
if (client->id() == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pending && strategy == m_pending) {
|
||||
delete m_strategy;
|
||||
|
||||
m_strategy = strategy;
|
||||
m_pending = nullptr;
|
||||
}
|
||||
|
||||
if (m_controller->config()->verbose()) {
|
||||
LOG_INFO(isColors() ? "#%03u \x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "#%03u use pool %s:%d %s",
|
||||
m_id, client->host(), client->port(), client->ip());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::onJob(IStrategy *strategy, Client *client, const Job &job)
|
||||
{
|
||||
if (m_controller->config()->verbose()) {
|
||||
LOG_INFO(isColors() ? "#%03u \x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d" : "#%03u new job from %s:%d diff %d",
|
||||
m_id, client->host(), client->port(), job.diff());
|
||||
}
|
||||
|
||||
if (m_donate && m_donate->isActive() && client->id() != -1 && !m_donate->reschedule()) {
|
||||
return;
|
||||
}
|
||||
|
||||
setJob(job);
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::onPause(IStrategy *strategy)
|
||||
{
|
||||
if (m_strategy == strategy) {
|
||||
m_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error)
|
||||
{
|
||||
AcceptEvent::start(m_id, m_miner, result, client->id() == -1, error);
|
||||
|
||||
if (!m_miner) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
m_miner->replyWithError(result.reqId, error);
|
||||
}
|
||||
else {
|
||||
m_miner->success(result.reqId, "OK");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SimpleMapper::isColors() const
|
||||
{
|
||||
return m_controller->config()->colors();
|
||||
}
|
||||
|
||||
|
||||
bool SimpleMapper::isValidJobId(const xmrig::Id &id) const
|
||||
{
|
||||
if (m_job.id() == id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_prevJob.isValid() && m_prevJob.id() == id) {
|
||||
Counters::expired++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
IStrategy *SimpleMapper::createStrategy(const std::vector<Url*> &pools)
|
||||
{
|
||||
if (pools.size() > 1) {
|
||||
return new FailoverStrategy(pools, m_controller->config()->retryPause(), m_controller->config()->retries(), this);
|
||||
}
|
||||
|
||||
return new SinglePoolStrategy(pools.front(), m_controller->config()->retryPause(), this);
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::connect()
|
||||
{
|
||||
m_strategy->connect();
|
||||
|
||||
if (m_donate) {
|
||||
m_donate->connect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleMapper::setJob(const Job &job)
|
||||
{
|
||||
if (m_job.clientId() == job.clientId()) {
|
||||
m_prevJob = m_job;
|
||||
}
|
||||
else {
|
||||
m_prevJob.reset();
|
||||
}
|
||||
|
||||
m_job = job;
|
||||
m_dirty = false;
|
||||
|
||||
if (m_miner) {
|
||||
m_miner->setJob(m_job);
|
||||
}
|
||||
}
|
||||
98
src/proxy/splitters/simple/SimpleMapper.h
Normal file
98
src/proxy/splitters/simple/SimpleMapper.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/* 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 __SIMPLEMAPPER_H__
|
||||
#define __SIMPLEMAPPER_H__
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "interfaces/IStrategyListener.h"
|
||||
#include "net/Job.h"
|
||||
|
||||
|
||||
class DonateStrategy;
|
||||
class IStrategy;
|
||||
class JobResult;
|
||||
class LoginRequest;
|
||||
class Miner;
|
||||
class NonceStorage;
|
||||
class Options;
|
||||
class SubmitEvent;
|
||||
class Url;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class SimpleMapper : public IStrategyListener
|
||||
{
|
||||
public:
|
||||
SimpleMapper(uint64_t id, xmrig::Controller *controller);
|
||||
~SimpleMapper();
|
||||
|
||||
void add(Miner *miner, const LoginRequest &request);
|
||||
void reload(const std::vector<Url*> &pools);
|
||||
void remove(const Miner *miner);
|
||||
void reuse(Miner *miner, const LoginRequest &request);
|
||||
void submit(SubmitEvent *event);
|
||||
void tick(uint64_t ticks, uint64_t now);
|
||||
|
||||
inline bool isActive() const { return m_active && m_miner; }
|
||||
inline bool isReusable() const { return m_active && !m_miner && !m_dirty; }
|
||||
inline uint64_t id() const { return m_id; }
|
||||
inline uint64_t idleTime() const { return m_idleTime; }
|
||||
|
||||
protected:
|
||||
void onActive(IStrategy *strategy, Client *client) override;
|
||||
void onJob(IStrategy *strategy, Client *client, const Job &job) override;
|
||||
void onPause(IStrategy *strategy) override;
|
||||
void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
|
||||
|
||||
private:
|
||||
bool isColors() const;
|
||||
bool isValidJobId(const xmrig::Id &id) const;
|
||||
IStrategy *createStrategy(const std::vector<Url*> &pools);
|
||||
void connect();
|
||||
void setJob(const Job &job);
|
||||
|
||||
bool m_active;
|
||||
bool m_dirty;
|
||||
DonateStrategy *m_donate;
|
||||
IStrategy *m_pending;
|
||||
IStrategy *m_strategy;
|
||||
Job m_job;
|
||||
Job m_prevJob;
|
||||
Miner *m_miner;
|
||||
uint64_t m_id;
|
||||
uint64_t m_idleTime;
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __SIMPLEMAPPER_H__ */
|
||||
246
src/proxy/splitters/simple/SimpleSplitter.cpp
Normal file
246
src/proxy/splitters/simple/SimpleSplitter.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
/* 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 <inttypes.h>
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/Log.h"
|
||||
#include "net/Url.h"
|
||||
#include "Platform.h"
|
||||
#include "proxy/Counters.h"
|
||||
#include "proxy/events/CloseEvent.h"
|
||||
#include "proxy/events/LoginEvent.h"
|
||||
#include "proxy/events/SubmitEvent.h"
|
||||
#include "proxy/Miner.h"
|
||||
#include "proxy/splitters/simple/SimpleMapper.h"
|
||||
#include "proxy/splitters/simple/SimpleSplitter.h"
|
||||
#include "Summary.h"
|
||||
|
||||
|
||||
#define LABEL(x) " \x1B[01;30m" x ":\x1B[0m "
|
||||
|
||||
|
||||
static bool compare(Url *i, Url *j) {
|
||||
return *i == *j;
|
||||
}
|
||||
|
||||
|
||||
SimpleSplitter::SimpleSplitter(xmrig::Controller *controller) : Splitter(controller),
|
||||
m_reuseTimeout(controller->config()->reuseTimeout()),
|
||||
m_sequence(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SimpleSplitter::~SimpleSplitter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Upstreams SimpleSplitter::upstreams() const
|
||||
{
|
||||
uint64_t active = 0;
|
||||
|
||||
for (auto const &kv : m_upstreams) {
|
||||
if (kv.second->isActive()) {
|
||||
active++;
|
||||
}
|
||||
}
|
||||
|
||||
return Upstreams(active, m_idles.size(), m_upstreams.size(), Counters::miners());
|
||||
}
|
||||
|
||||
|
||||
void SimpleSplitter::connect()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SimpleSplitter::gc()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SimpleSplitter::printConnections()
|
||||
{
|
||||
const Upstreams info = upstreams();
|
||||
|
||||
if (m_controller->config()->colors()) {
|
||||
LOG_INFO("\x1B[01;32m* \x1B[01;37mupstreams\x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("sleep") "\x1B[01;37m%" PRIu64 "\x1B[0m" LABEL("error") "%s%" PRIu64 "\x1B[0m" LABEL("total") "\x1B[01;37m%" PRIu64,
|
||||
info.active ? "\x1B[01;32m" : "\x1B[01;31m", info.active, info.sleep, info.error ? "\x1B[01;31m" : "\x1B[01;37m", info.error, m_upstreams.size());
|
||||
|
||||
LOG_INFO("\x1B[01;32m* \x1B[01;37mminers \x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("max") "\x1B[01;37m%" PRIu64 "\x1B[0m",
|
||||
Counters::miners() ? "\x1B[01;32m" : "\x1B[01;31m", Counters::miners(), Counters::maxMiners());
|
||||
}
|
||||
else {
|
||||
LOG_INFO("* upstreams: active %" PRIu64 " sleep %" PRIu64 " error %" PRIu64 " total %" PRIu64,
|
||||
info.active, info.sleep, info.error, m_upstreams.size());
|
||||
|
||||
LOG_INFO("* miners: active %" PRIu64 " max %" PRIu64,
|
||||
Counters::miners(), Counters::maxMiners());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleSplitter::tick(uint64_t ticks)
|
||||
{
|
||||
const uint64_t now = uv_now(uv_default_loop());
|
||||
std::vector<SimpleMapper *> released;
|
||||
|
||||
for (auto const &kv : m_upstreams) {
|
||||
if (kv.second->idleTime() > m_reuseTimeout) {
|
||||
released.push_back(kv.second);
|
||||
continue;
|
||||
}
|
||||
|
||||
kv.second->tick(ticks, now);
|
||||
}
|
||||
|
||||
if (released.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (SimpleMapper *mapper : released) {
|
||||
removeIdle(mapper->id());
|
||||
removeUpstream(mapper->id());
|
||||
|
||||
delete mapper;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef APP_DEVEL
|
||||
void SimpleSplitter::printState()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void SimpleSplitter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
|
||||
{
|
||||
m_reuseTimeout = config->reuseTimeout();
|
||||
|
||||
const std::vector<Url*> &pools = config->pools();
|
||||
const std::vector<Url*> &previousPools = previousConfig->pools();
|
||||
|
||||
if (pools.size() != previousPools.size() || !std::equal(pools.begin(), pools.end(), previousPools.begin(), compare)) {
|
||||
Summary::printPools(config);
|
||||
|
||||
for (auto const &kv : m_upstreams) {
|
||||
kv.second->reload(pools);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleSplitter::onEvent(IEvent *event)
|
||||
{
|
||||
switch (event->type())
|
||||
{
|
||||
case IEvent::CloseType:
|
||||
remove(static_cast<CloseEvent*>(event)->miner());
|
||||
break;
|
||||
|
||||
case IEvent::LoginType:
|
||||
login(static_cast<LoginEvent*>(event));
|
||||
break;
|
||||
|
||||
case IEvent::SubmitType:
|
||||
submit(static_cast<SubmitEvent*>(event));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleSplitter::login(LoginEvent *event)
|
||||
{
|
||||
if (!m_idles.empty()) {
|
||||
for (auto const &kv : m_idles) {
|
||||
if (kv.second->isReusable()) {
|
||||
removeIdle(kv.first);
|
||||
kv.second->reuse(event->miner(), event->request);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SimpleMapper *mapper = new SimpleMapper(m_sequence++, m_controller);
|
||||
m_upstreams[mapper->id()] = mapper;
|
||||
|
||||
mapper->add(event->miner(), event->request);
|
||||
}
|
||||
|
||||
|
||||
void SimpleSplitter::remove(Miner *miner)
|
||||
{
|
||||
const ssize_t id = miner->mapperId();
|
||||
|
||||
if (id < 0 || m_upstreams.count(id) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleMapper *mapper = m_upstreams[id];
|
||||
mapper->remove(miner);
|
||||
|
||||
if (m_reuseTimeout == 0) {
|
||||
removeUpstream(id);
|
||||
|
||||
delete mapper;
|
||||
}
|
||||
else {
|
||||
m_idles[id] = mapper;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleSplitter::removeIdle(uint64_t id)
|
||||
{
|
||||
auto it = m_idles.find(id);
|
||||
if (it != m_idles.end()) {
|
||||
m_idles.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleSplitter::removeUpstream(uint64_t id)
|
||||
{
|
||||
auto it = m_upstreams.find(id);
|
||||
if (it != m_upstreams.end()) {
|
||||
m_upstreams.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimpleSplitter::submit(SubmitEvent *event)
|
||||
{
|
||||
SimpleMapper *mapper = m_upstreams[event->miner()->mapperId()];
|
||||
if (mapper) {
|
||||
mapper->submit(event);
|
||||
}
|
||||
}
|
||||
83
src/proxy/splitters/simple/SimpleSplitter.h
Normal file
83
src/proxy/splitters/simple/SimpleSplitter.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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 __SIMPLESPLITTER_H__
|
||||
#define __SIMPLESPLITTER_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
|
||||
|
||||
#include "proxy/splitters/Splitter.h"
|
||||
|
||||
|
||||
class LoginEvent;
|
||||
class Miner;
|
||||
class Options;
|
||||
class SimpleMapper;
|
||||
class Stats;
|
||||
class SubmitEvent;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class SimpleSplitter : public Splitter
|
||||
{
|
||||
public:
|
||||
SimpleSplitter(xmrig::Controller *controller);
|
||||
~SimpleSplitter();
|
||||
|
||||
protected:
|
||||
Upstreams upstreams() const override;
|
||||
void connect() override;
|
||||
void gc() override;
|
||||
void printConnections() override;
|
||||
void tick(uint64_t ticks) override;
|
||||
|
||||
# ifdef APP_DEVEL
|
||||
void printState() override;
|
||||
# endif
|
||||
|
||||
inline void onRejectedEvent(IEvent *event) override {}
|
||||
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
|
||||
void onEvent(IEvent *event) override;
|
||||
|
||||
private:
|
||||
void login(LoginEvent *event);
|
||||
void remove(Miner *miner);
|
||||
void removeIdle(uint64_t id);
|
||||
void removeUpstream(uint64_t id);
|
||||
void submit(SubmitEvent *event);
|
||||
|
||||
std::map<uint64_t, SimpleMapper *> m_idles;
|
||||
std::map<uint64_t, SimpleMapper *> m_upstreams;
|
||||
uint64_t m_reuseTimeout;
|
||||
uint64_t m_sequence;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __SIMPLESPLITTER_H__ */
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -25,9 +25,9 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
#include "api/Api.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/Log.h"
|
||||
#include "Options.h"
|
||||
#include "proxy/events/AcceptEvent.h"
|
||||
#include "proxy/events/CloseEvent.h"
|
||||
#include "proxy/events/LoginEvent.h"
|
||||
@@ -37,8 +37,9 @@
|
||||
#include "proxy/workers/Workers.h"
|
||||
|
||||
|
||||
Workers::Workers() :
|
||||
m_enabled(Options::i()->workers())
|
||||
Workers::Workers(xmrig::Controller *controller) :
|
||||
m_enabled(controller->config()->workers()),
|
||||
m_controller(controller)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -59,8 +60,8 @@ void Workers::printWorkers()
|
||||
char workerName[24];
|
||||
size_t size = 0;
|
||||
|
||||
Log::i()->text(Options::i()->colors() ? "\x1B[01;37m%-23s | %-15s | %-5s | %-8s | %-3s | %10s |" : "%-23s | %-15s | %-5s | %-8s | %-3s | %10s |",
|
||||
"WORKER NAME", "LAST IP", "COUNT", "ACCEPTED", "REJ", "10 MIN");
|
||||
Log::i()->text(m_controller->config()->colors() ? "\x1B[01;37m%-23s | %-15s | %-5s | %-8s | %-3s | %11s | %11s |" : "%-23s | %-15s | %-5s | %-8s | %-3s | %11s | %11s |",
|
||||
"WORKER NAME", "LAST IP", "COUNT", "ACCEPTED", "REJ", "10 MINUTES", "24 HOURS");
|
||||
|
||||
for (const Worker &worker : m_workers) {
|
||||
const char *name = worker.name();
|
||||
@@ -76,8 +77,8 @@ void Workers::printWorkers()
|
||||
strncpy(workerName, name, sizeof(workerName) - 1);
|
||||
}
|
||||
|
||||
Log::i()->text("%-23s | %-15s | %5" PRIu64 " | %8" PRIu64 " | %3" PRIu64 " | %5.1f KH/s |",
|
||||
workerName, worker.ip(), worker.connections(), worker.accepted(), worker.rejected(), worker.hashrate(600));
|
||||
Log::i()->text("%-23s | %-15s | %5" PRIu64 " | %8" PRIu64 " | %3" PRIu64 " | %6.2f kH/s | %6.2f kH/s |",
|
||||
workerName, worker.ip(), worker.connections(), worker.accepted(), worker.rejected(), worker.hashrate(600), worker.hashrate(86400));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,8 +92,6 @@ void Workers::tick(uint64_t ticks)
|
||||
for (Worker &worker : m_workers) {
|
||||
worker.tick(ticks);
|
||||
}
|
||||
|
||||
Api::tick(m_workers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -41,15 +41,22 @@ class Miner;
|
||||
class SubmitEvent;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class Workers : public IEventListener
|
||||
{
|
||||
public:
|
||||
Workers();
|
||||
Workers(xmrig::Controller *controller);
|
||||
~Workers();
|
||||
|
||||
void printWorkers();
|
||||
void tick(uint64_t ticks);
|
||||
|
||||
inline const std::vector<Worker> &workers() const { return m_workers; }
|
||||
|
||||
protected:
|
||||
void onEvent(IEvent *event) override;
|
||||
void onRejectedEvent(IEvent *event) override;
|
||||
@@ -65,6 +72,7 @@ private:
|
||||
std::map<int64_t, size_t> m_miners;
|
||||
std::map<std::string, size_t> m_map;
|
||||
std::vector<Worker> m_workers;
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -27,19 +27,19 @@
|
||||
#define APP_ID "xmrig-proxy"
|
||||
#define APP_NAME "xmrig-proxy"
|
||||
#define APP_DESC "XMRig Stratum proxy"
|
||||
#define APP_VERSION "2.4.2"
|
||||
#define APP_VERSION "2.5.2"
|
||||
#define APP_DOMAIN "xmrig.com"
|
||||
#define APP_SITE "www.xmrig.com"
|
||||
#define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com"
|
||||
#define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com"
|
||||
#define APP_KIND "proxy"
|
||||
|
||||
#define APP_VER_MAJOR 2
|
||||
#define APP_VER_MINOR 4
|
||||
#define APP_VER_MINOR 5
|
||||
#define APP_VER_BUILD 2
|
||||
#define APP_VER_REV 0
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER == 1910 || _MSC_VER == 1911)
|
||||
# if (_MSC_VER >= 1910)
|
||||
# define MSVC_VERSION 2017
|
||||
# elif _MSC_VER == 1900
|
||||
# define MSVC_VERSION 2015
|
||||
|
||||
47
src/xmrig.h
Normal file
47
src/xmrig.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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 {
|
||||
ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */
|
||||
ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
|
||||
};
|
||||
|
||||
|
||||
enum Variant {
|
||||
VARIANT_AUTO = -1,
|
||||
VARIANT_NONE = 0,
|
||||
VARIANT_V1 = 1
|
||||
};
|
||||
|
||||
} /* xmrig */
|
||||
|
||||
|
||||
#endif /* __XMRIG_H__ */
|
||||
Reference in New Issue
Block a user