mirror of
https://github.com/xmrig/xmrig.git
synced 2025-12-07 07:55:04 -05:00
Compare commits
181 Commits
v2.15.1-be
...
v2.99.1-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a007fae8f1 | ||
|
|
837cf8fa90 | ||
|
|
7200d754c2 | ||
|
|
39948484bd | ||
|
|
02c03b0465 | ||
|
|
741c7c16e8 | ||
|
|
8600d8ee96 | ||
|
|
ac849ea996 | ||
|
|
2d719a28c4 | ||
|
|
9660dfc7b3 | ||
|
|
370be64f30 | ||
|
|
162c3f3d32 | ||
|
|
c7ba4f8f2f | ||
|
|
7119e4c64c | ||
|
|
83f0f2bcad | ||
|
|
d1705a7f74 | ||
|
|
484253bf68 | ||
|
|
c4388fa74c | ||
|
|
e2a5bfa0b4 | ||
|
|
3d7598b28d | ||
|
|
71300fa852 | ||
|
|
31ca1a1b6f | ||
|
|
3fb180f04e | ||
|
|
dc2c0552e0 | ||
|
|
d2ca254789 | ||
|
|
222cebba71 | ||
|
|
2fc54d240a | ||
|
|
ca7fb33848 | ||
|
|
1d78e7d60d | ||
|
|
fa2c9df075 | ||
|
|
d9164c0b7b | ||
|
|
691b2fabbf | ||
|
|
88edde804f | ||
|
|
0ab26a1619 | ||
|
|
f590cf58fb | ||
|
|
871bc3e180 | ||
|
|
6f93b7b38d | ||
|
|
630a5dce67 | ||
|
|
8ce00adda4 | ||
|
|
4f49533e98 | ||
|
|
bcae974ea1 | ||
|
|
2bf5ffb2df | ||
|
|
20313cbc56 | ||
|
|
5699147aab | ||
|
|
27f3008d79 | ||
|
|
dff59fabc2 | ||
|
|
ee434a5708 | ||
|
|
dc87ef6062 | ||
|
|
8b3f2d8fff | ||
|
|
4643742d13 | ||
|
|
be7ff62c48 | ||
|
|
6f27037f07 | ||
|
|
8e2219b7c4 | ||
|
|
270d3ba6a2 | ||
|
|
3bebf778da | ||
|
|
f42adafee0 | ||
|
|
ea1149a971 | ||
|
|
9bf4c2c98f | ||
|
|
9b14caa9f9 | ||
|
|
8c02e20828 | ||
|
|
b92807e8d8 | ||
|
|
ee9538ab22 | ||
|
|
02410fa084 | ||
|
|
915729bec6 | ||
|
|
6eb9d0963b | ||
|
|
83fdbbf29c | ||
|
|
e10671fa51 | ||
|
|
62edb2fc0a | ||
|
|
dd875c7c37 | ||
|
|
66d62de681 | ||
|
|
188338c493 | ||
|
|
0aaf2d38d4 | ||
|
|
baa75569e2 | ||
|
|
f7fe0a9ac3 | ||
|
|
c2d662ff4c | ||
|
|
6813657891 | ||
|
|
ee93095e06 | ||
|
|
b0a1481909 | ||
|
|
f7f2c09e89 | ||
|
|
cf61f49746 | ||
|
|
1a2f9fb160 | ||
|
|
187e55e28e | ||
|
|
41e0be111d | ||
|
|
e743301a79 | ||
|
|
7a6c7aac29 | ||
|
|
53c9e5fe0e | ||
|
|
e8ac01d289 | ||
|
|
2a07cf391d | ||
|
|
3d17ba6af6 | ||
|
|
34e39e9946 | ||
|
|
2b26874f11 | ||
|
|
b38e432647 | ||
|
|
50ace41766 | ||
|
|
d0ce60a73a | ||
|
|
202d44c147 | ||
|
|
ac1b554282 | ||
|
|
6990324681 | ||
|
|
b73c204e73 | ||
|
|
088587fa72 | ||
|
|
1f0e3e501c | ||
|
|
d7f42d54ad | ||
|
|
725c767928 | ||
|
|
b684150336 | ||
|
|
d9eb700e03 | ||
|
|
09cdddc7f6 | ||
|
|
bd8370951f | ||
|
|
d587eebaf2 | ||
|
|
ac43cd4f9c | ||
|
|
f620ffe899 | ||
|
|
242ece7222 | ||
|
|
36fcdf3f9d | ||
|
|
ba94c08bf5 | ||
|
|
8dc586283f | ||
|
|
fc655d1b8d | ||
|
|
4b3592f60f | ||
|
|
cd32677ad4 | ||
|
|
277f188cd5 | ||
|
|
e28c3db019 | ||
|
|
5dde5dbf4e | ||
|
|
9726f8cf9d | ||
|
|
833a532e7a | ||
|
|
3dde8cacff | ||
|
|
84b359f29c | ||
|
|
2d8e8c92ab | ||
|
|
651009e1b9 | ||
|
|
1d4bc030fb | ||
|
|
809efb4700 | ||
|
|
10165da53e | ||
|
|
51b92f66cf | ||
|
|
6fb014d0b1 | ||
|
|
ffb282a11a | ||
|
|
a000544fdc | ||
|
|
378bc504fc | ||
|
|
304d7bd09a | ||
|
|
e9e2d7d152 | ||
|
|
8b0d35b619 | ||
|
|
e46a2a508a | ||
|
|
fe9aa9f3c4 | ||
|
|
552858b9e3 | ||
|
|
ff6544a14c | ||
|
|
d77e404439 | ||
|
|
ff4d54dc4c | ||
|
|
699269bbae | ||
|
|
9137f59ec1 | ||
|
|
f9f7ef26b8 | ||
|
|
32c3d4b9f6 | ||
|
|
ee1d61d117 | ||
|
|
a3b303e885 | ||
|
|
074b3869d2 | ||
|
|
c0e668f36f | ||
|
|
21798edb8b | ||
|
|
23b0e3799e | ||
|
|
83a7a88b11 | ||
|
|
60f6817d21 | ||
|
|
867478b983 | ||
|
|
5e369a5af8 | ||
|
|
62012a1a50 | ||
|
|
54a1c614f7 | ||
|
|
cf7ce13986 | ||
|
|
0d496aaf2f | ||
|
|
9a6944d694 | ||
|
|
1bd8d63508 | ||
|
|
c41889477c | ||
|
|
c823c54f9b | ||
|
|
6812d22d63 | ||
|
|
241383068c | ||
|
|
35d868fb48 | ||
|
|
d6da0652ce | ||
|
|
9561570c50 | ||
|
|
466aad8543 | ||
|
|
db456a3e63 | ||
|
|
09df8c3846 | ||
|
|
5d9648956b | ||
|
|
1774b42345 | ||
|
|
fa2a0b9b79 | ||
|
|
85ee55f309 | ||
|
|
4aa7f01f13 | ||
|
|
496870a59d | ||
|
|
356fd04b0f | ||
|
|
5a4720cf4a | ||
|
|
c0e2a15614 |
39
CHANGELOG.md
39
CHANGELOG.md
@@ -1,3 +1,35 @@
|
||||
# v2.99.1-beta
|
||||
- [#1072](https://github.com/xmrig/xmrig/issues/1072) Fixed RandomX `seed_hash` re-initialization.
|
||||
|
||||
# v2.99.0-beta
|
||||
- [#1050](https://github.com/xmrig/xmrig/pull/1050) Added RandomXL algorithm for [Loki](https://loki.network/), algorithm name used by miner is `randomx/loki` or `rx/loki`.
|
||||
- Added [flexible](https://github.com/xmrig/xmrig/blob/evo/doc/CPU.md) multi algorithm configuration.
|
||||
- Added unlimited switching between incompatible algorithms, all mining options can be changed in runtime.
|
||||
- Breaked backward compatibility with previous configs and command line, `variant` option replaced to `algo`, global option `algo` removed, all CPU related settings moved to `cpu` object.
|
||||
- Options `av`, `safe` and `max-cpu-usage` removed.
|
||||
- Algorithm `cn/msr` renamed to `cn/fast`.
|
||||
- Algorithm `cn/xtl` removed.
|
||||
- API endpoint `GET /1/threads` replaced to `GET /2/backends`.
|
||||
|
||||
# v2.16.0-beta
|
||||
- [#1036](https://github.com/xmrig/xmrig/pull/1036) Added RandomWOW (RandomX with different preferences) algorithm support for [Wownero](http://wownero.org/).
|
||||
- Algorithm name used by miner is `randomx/wow` or `rx/wow`.
|
||||
- Currently runtime algorithm switching NOT supported with other algorithms.
|
||||
|
||||
# v2.15.4-beta
|
||||
- Added global uptime and extended connection information in API.
|
||||
- API now return current algorithm instead of global algorithm specified in config.
|
||||
- This version also include all changes from stable version v2.14.4.
|
||||
|
||||
# v2.15.3-beta
|
||||
- [#1014](https://github.com/xmrig/xmrig/issues/1014) Fixed regression, default value for `algo` option was not applied.
|
||||
|
||||
# v2.15.2-beta
|
||||
- [#1010](https://github.com/xmrig/xmrig/pull/1010#issuecomment-482632107) Added daemon support (solo mining).
|
||||
- [#1012](https://github.com/xmrig/xmrig/pull/1012) Fixed compatibility with clang 9.
|
||||
- Config subsystem was rewritten, internally JSON is primary format now.
|
||||
- Fixed regression, big HTTP responses was truncated.
|
||||
|
||||
# v2.15.1-beta
|
||||
- [#1007](https://github.com/xmrig/xmrig/issues/1007) Old HTTP API backend based on libmicrohttpd, replaced to custom HTTP server (libuv + http_parser).
|
||||
- [#257](https://github.com/xmrig/xmrig-nvidia/pull/257) New logging subsystem, file and syslog now always without colors.
|
||||
@@ -7,6 +39,13 @@
|
||||
- Added new option `donate-over-proxy`.
|
||||
- Added real graceful exit.
|
||||
|
||||
# v2.14.4
|
||||
- [#992](https://github.com/xmrig/xmrig/pull/992) Fixed compilation with Clang 3.5.
|
||||
- [#1012](https://github.com/xmrig/xmrig/pull/1012) Fixed compilation with Clang 9.0.
|
||||
- In HTTP API for unknown hashrate now used `null` instead of `0.0`.
|
||||
- Fixed MSVC 2019 version detection.
|
||||
- Removed obsolete automatic variants.
|
||||
|
||||
# v2.14.1
|
||||
* [#975](https://github.com/xmrig/xmrig/issues/975) Fixed crash on Linux if double thread mode used.
|
||||
|
||||
|
||||
211
CMakeLists.txt
211
CMakeLists.txt
@@ -2,11 +2,12 @@ cmake_minimum_required(VERSION 2.8)
|
||||
project(xmrig)
|
||||
|
||||
option(WITH_LIBCPUID "Use Libcpuid" ON)
|
||||
option(WITH_AEON "CryptoNight-Lite support" ON)
|
||||
option(WITH_SUMO "CryptoNight-Heavy support" ON)
|
||||
option(WITH_CN_LITE "CryptoNight-Lite support" ON)
|
||||
option(WITH_CN_HEAVY "CryptoNight-Heavy support" ON)
|
||||
option(WITH_CN_PICO "CryptoNight-Pico support" ON)
|
||||
option(WITH_CN_GPU "CryptoNight-GPU support" ON)
|
||||
option(WITH_HTTPD "HTTP REST API" ON)
|
||||
option(WITH_RANDOMX "RandomX support" ON)
|
||||
option(WITH_HTTP "HTTP protocol support (client/server)" ON)
|
||||
option(WITH_DEBUG_LOG "Enable debug log output" OFF)
|
||||
option(WITH_TLS "Enable OpenSSL support" ON)
|
||||
option(WITH_ASM "Enable ASM PoW implementations" ON)
|
||||
@@ -17,100 +18,88 @@ option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF)
|
||||
include (CheckIncludeFile)
|
||||
include (cmake/cpu.cmake)
|
||||
include (src/base/base.cmake)
|
||||
include (src/backend/backend.cmake)
|
||||
|
||||
|
||||
set(HEADERS
|
||||
"${HEADERS_BASE}"
|
||||
"${HEADERS_BASE_HTTP}"
|
||||
"${HEADERS_BACKEND}"
|
||||
src/api/interfaces/IApiListener.h
|
||||
src/App.h
|
||||
src/common/config/CommonConfig.h
|
||||
src/common/config/ConfigLoader.h
|
||||
src/common/config/ConfigWatcher.h
|
||||
src/common/cpu/Cpu.h
|
||||
src/common/crypto/Algorithm.h
|
||||
src/common/crypto/keccak.h
|
||||
src/common/interfaces/IConfig.h
|
||||
src/common/interfaces/ICpuInfo.h
|
||||
src/common/Platform.h
|
||||
src/common/utils/mm_malloc.h
|
||||
src/common/xmrig.h
|
||||
src/core/config/Config_default.h
|
||||
src/core/config/Config_platform.h
|
||||
src/core/config/Config.h
|
||||
src/core/config/ConfigLoader_default.h
|
||||
src/core/config/ConfigLoader_platform.h
|
||||
src/core/config/ConfigTransform.h
|
||||
src/core/config/usage.h
|
||||
src/core/Controller.h
|
||||
src/interfaces/IJobResultListener.h
|
||||
src/interfaces/IThread.h
|
||||
src/interfaces/IWorker.h
|
||||
src/Mem.h
|
||||
src/core/Miner.h
|
||||
src/net/interfaces/IJobResultListener.h
|
||||
src/net/JobResult.h
|
||||
src/net/JobResults.h
|
||||
src/net/Network.h
|
||||
src/net/NetworkState.h
|
||||
src/net/strategies/DonateStrategy.h
|
||||
src/Summary.h
|
||||
src/version.h
|
||||
src/workers/CpuThread.h
|
||||
src/workers/Hashrate.h
|
||||
src/workers/MultiWorker.h
|
||||
src/workers/ThreadHandle.h
|
||||
src/workers/Worker.h
|
||||
src/workers/Workers.h
|
||||
)
|
||||
|
||||
set(HEADERS_CRYPTO
|
||||
src/crypto/c_blake256.h
|
||||
src/crypto/c_groestl.h
|
||||
src/crypto/c_jh.h
|
||||
src/crypto/c_skein.h
|
||||
src/crypto/CryptoNight.h
|
||||
src/crypto/CryptoNight_constants.h
|
||||
src/crypto/CryptoNight_monero.h
|
||||
src/crypto/CryptoNight_test.h
|
||||
src/crypto/groestl_tables.h
|
||||
src/crypto/hash.h
|
||||
src/crypto/skein_port.h
|
||||
src/crypto/soft_aes.h
|
||||
src/crypto/asm/CryptonightR_template.h
|
||||
src/crypto/cn/asm/CryptonightR_template.h
|
||||
src/crypto/cn/c_blake256.h
|
||||
src/crypto/cn/c_groestl.h
|
||||
src/crypto/cn/c_jh.h
|
||||
src/crypto/cn/c_skein.h
|
||||
src/crypto/cn/CnAlgo.h
|
||||
src/crypto/cn/CnCtx.h
|
||||
src/crypto/cn/CnHash.h
|
||||
src/crypto/cn/CryptoNight_monero.h
|
||||
src/crypto/cn/CryptoNight_test.h
|
||||
src/crypto/cn/CryptoNight.h
|
||||
src/crypto/cn/groestl_tables.h
|
||||
src/crypto/cn/hash.h
|
||||
src/crypto/cn/skein_port.h
|
||||
src/crypto/cn/soft_aes.h
|
||||
src/crypto/common/Algorithm.h
|
||||
src/crypto/common/keccak.h
|
||||
src/crypto/common/Nonce.h
|
||||
src/crypto/common/portable/mm_malloc.h
|
||||
src/crypto/common/VirtualMemory.h
|
||||
)
|
||||
|
||||
if (XMRIG_ARM)
|
||||
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_arm.h)
|
||||
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/cn/CryptoNight_arm.h)
|
||||
else()
|
||||
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_x86.h)
|
||||
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/cn/CryptoNight_x86.h)
|
||||
endif()
|
||||
|
||||
set(SOURCES
|
||||
"${SOURCES_BASE}"
|
||||
"${SOURCES_BASE_HTTP}"
|
||||
"${SOURCES_BACKEND}"
|
||||
src/App.cpp
|
||||
src/common/config/CommonConfig.cpp
|
||||
src/common/config/ConfigLoader.cpp
|
||||
src/common/config/ConfigWatcher.cpp
|
||||
src/common/crypto/Algorithm.cpp
|
||||
src/common/crypto/keccak.cpp
|
||||
src/common/Platform.cpp
|
||||
src/core/config/Config.cpp
|
||||
src/core/config/ConfigTransform.cpp
|
||||
src/core/Controller.cpp
|
||||
src/Mem.cpp
|
||||
src/core/Miner.cpp
|
||||
src/net/JobResults.cpp
|
||||
src/net/Network.cpp
|
||||
src/net/NetworkState.cpp
|
||||
src/net/strategies/DonateStrategy.cpp
|
||||
src/Summary.cpp
|
||||
src/workers/CpuThread.cpp
|
||||
src/workers/Hashrate.cpp
|
||||
src/workers/MultiWorker.cpp
|
||||
src/workers/ThreadHandle.cpp
|
||||
src/workers/Worker.cpp
|
||||
src/workers/Workers.cpp
|
||||
src/xmrig.cpp
|
||||
)
|
||||
|
||||
set(SOURCES_CRYPTO
|
||||
src/crypto/c_groestl.c
|
||||
src/crypto/c_blake256.c
|
||||
src/crypto/c_jh.c
|
||||
src/crypto/c_skein.c
|
||||
src/crypto/cn/c_blake256.c
|
||||
src/crypto/cn/c_groestl.c
|
||||
src/crypto/cn/c_jh.c
|
||||
src/crypto/cn/c_skein.c
|
||||
src/crypto/cn/CnCtx.cpp
|
||||
src/crypto/cn/CnHash.cpp
|
||||
src/crypto/common/Algorithm.cpp
|
||||
src/crypto/common/keccak.cpp
|
||||
src/crypto/common/Nonce.cpp
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
@@ -118,8 +107,7 @@ if (WIN32)
|
||||
"${SOURCES_OS}"
|
||||
res/app.rc
|
||||
src/App_win.cpp
|
||||
src/common/Platform_win.cpp
|
||||
src/Mem_win.cpp
|
||||
src/crypto/common/VirtualMemory_win.cpp
|
||||
)
|
||||
|
||||
add_definitions(/DWIN32)
|
||||
@@ -128,15 +116,13 @@ elseif (APPLE)
|
||||
set(SOURCES_OS
|
||||
"${SOURCES_OS}"
|
||||
src/App_unix.cpp
|
||||
src/common/Platform_mac.cpp
|
||||
src/Mem_unix.cpp
|
||||
src/crypto/common/VirtualMemory_unix.cpp
|
||||
)
|
||||
else()
|
||||
set(SOURCES_OS
|
||||
"${SOURCES_OS}"
|
||||
src/App_unix.cpp
|
||||
src/common/Platform_unix.cpp
|
||||
src/Mem_unix.cpp
|
||||
src/crypto/common/VirtualMemory_unix.cpp
|
||||
)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
|
||||
@@ -160,51 +146,86 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
find_package(UV REQUIRED)
|
||||
|
||||
include(cmake/flags.cmake)
|
||||
|
||||
if (WITH_LIBCPUID)
|
||||
add_subdirectory(src/3rdparty/libcpuid)
|
||||
|
||||
include_directories(src/3rdparty/libcpuid)
|
||||
set(CPUID_LIB cpuid)
|
||||
set(SOURCES_CPUID src/core/cpu/AdvancedCpuInfo.h src/core/cpu/AdvancedCpuInfo.cpp src/core/cpu/Cpu.cpp)
|
||||
else()
|
||||
add_definitions(/DXMRIG_NO_LIBCPUID)
|
||||
set(SOURCES_CPUID src/common/cpu/BasicCpuInfo.h src/common/cpu/Cpu.cpp)
|
||||
|
||||
if (XMRIG_ARM)
|
||||
set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo_arm.cpp)
|
||||
else()
|
||||
set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo.cpp)
|
||||
if (WITH_RANDOMX)
|
||||
include_directories(src/crypto/randomx)
|
||||
add_definitions(/DXMRIG_ALGO_RANDOMX)
|
||||
set(SOURCES_CRYPTO
|
||||
"${SOURCES_CRYPTO}"
|
||||
src/crypto/randomx/aes_hash.cpp
|
||||
src/crypto/randomx/allocator.cpp
|
||||
src/crypto/randomx/argon2_core.c
|
||||
src/crypto/randomx/argon2_ref.c
|
||||
src/crypto/randomx/blake2_generator.cpp
|
||||
src/crypto/randomx/blake2/blake2b.c
|
||||
src/crypto/randomx/bytecode_machine.cpp
|
||||
src/crypto/randomx/dataset.cpp
|
||||
src/crypto/randomx/instructions_portable.cpp
|
||||
src/crypto/randomx/randomx.cpp
|
||||
src/crypto/randomx/reciprocal.c
|
||||
src/crypto/randomx/soft_aes.cpp
|
||||
src/crypto/randomx/superscalar.cpp
|
||||
src/crypto/randomx/virtual_machine.cpp
|
||||
src/crypto/randomx/virtual_memory.cpp
|
||||
src/crypto/randomx/vm_compiled_light.cpp
|
||||
src/crypto/randomx/vm_compiled.cpp
|
||||
src/crypto/randomx/vm_interpreted_light.cpp
|
||||
src/crypto/randomx/vm_interpreted.cpp
|
||||
src/crypto/rx/Rx.cpp
|
||||
src/crypto/rx/Rx.h
|
||||
src/crypto/rx/RxAlgo.cpp
|
||||
src/crypto/rx/RxAlgo.h
|
||||
src/crypto/rx/RxCache.cpp
|
||||
src/crypto/rx/RxCache.h
|
||||
src/crypto/rx/RxDataset.cpp
|
||||
src/crypto/rx/RxDataset.h
|
||||
src/crypto/rx/RxVm.cpp
|
||||
src/crypto/rx/RxVm.h
|
||||
)
|
||||
if (NOT ARCH_ID)
|
||||
set(ARCH_ID ${CMAKE_HOST_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
|
||||
enable_language(ASM_MASM)
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/randomx/jit_compiler_x86_static.asm
|
||||
src/crypto/randomx/jit_compiler_x86.cpp
|
||||
)
|
||||
elseif (NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/randomx/jit_compiler_x86_static.S
|
||||
src/crypto/randomx/jit_compiler_x86.cpp
|
||||
)
|
||||
# cheat because cmake and ccache hate each other
|
||||
set_property(SOURCE src/crypto/randomx/jit_compiler_x86_static.S PROPERTY LANGUAGE C)
|
||||
endif()
|
||||
else()
|
||||
remove_definitions(/DXMRIG_ALGO_RANDOMX)
|
||||
endif()
|
||||
|
||||
include(cmake/flags.cmake)
|
||||
|
||||
include(cmake/OpenSSL.cmake)
|
||||
include(cmake/asm.cmake)
|
||||
include(cmake/cn-gpu.cmake)
|
||||
|
||||
if (NOT WITH_AEON)
|
||||
add_definitions(/DXMRIG_NO_AEON)
|
||||
if (WITH_CN_LITE)
|
||||
add_definitions(/DXMRIG_ALGO_CN_LITE)
|
||||
endif()
|
||||
|
||||
if (NOT WITH_SUMO)
|
||||
add_definitions(/DXMRIG_NO_SUMO)
|
||||
if (WITH_CN_HEAVY)
|
||||
add_definitions(/DXMRIG_ALGO_CN_HEAVY)
|
||||
endif()
|
||||
|
||||
if (NOT WITH_IPBC)
|
||||
add_definitions(/DXMRIG_NO_IPBC)
|
||||
endif()
|
||||
|
||||
if (NOT WITH_CN_PICO)
|
||||
add_definitions(/DXMRIG_NO_CN_PICO)
|
||||
if (WITH_CN_PICO)
|
||||
add_definitions(/DXMRIG_ALGO_CN_PICO)
|
||||
endif()
|
||||
|
||||
if (WITH_EMBEDDED_CONFIG)
|
||||
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
|
||||
endif()
|
||||
|
||||
if (WITH_HTTPD)
|
||||
set(HTTPD_SOURCES
|
||||
if (WITH_HTTP)
|
||||
set(HTTP_SOURCES
|
||||
src/api/Api.cpp
|
||||
src/api/Api.h
|
||||
src/api/Httpd.cpp
|
||||
@@ -214,11 +235,9 @@ if (WITH_HTTPD)
|
||||
src/api/requests/ApiRequest.h
|
||||
src/api/requests/HttpApiRequest.cpp
|
||||
src/api/requests/HttpApiRequest.h
|
||||
src/api/v1/ApiRouter.cpp
|
||||
src/api/v1/ApiRouter.h
|
||||
)
|
||||
else()
|
||||
set(HTTPD_SOURCES "")
|
||||
set(HTTP_SOURCES "")
|
||||
endif()
|
||||
|
||||
include_directories(src)
|
||||
@@ -233,5 +252,5 @@ if (WITH_DEBUG_LOG)
|
||||
add_definitions(/DAPP_DEBUG)
|
||||
endif()
|
||||
|
||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES} ${CN_GPU_SOURCES})
|
||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTP_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES} ${CN_GPU_SOURCES})
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB})
|
||||
|
||||
@@ -13,7 +13,7 @@ Originally based on cpuminer-multi with heavy optimizations/rewrites and removin
|
||||
* This is the **CPU-mining** version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd).
|
||||
* [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases.
|
||||
|
||||
<img src="http://i.imgur.com/OKZRVDh.png" width="619" >
|
||||
<img src="http://i.imgur.com/Ymumes5.png" width="670" >
|
||||
|
||||
#### Table of contents
|
||||
* [Features](#features)
|
||||
|
||||
@@ -13,6 +13,10 @@ if (WITH_TLS)
|
||||
if (OPENSSL_FOUND)
|
||||
set(TLS_SOURCES src/base/net/stratum/Tls.h src/base/net/stratum/Tls.cpp)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
|
||||
if (WITH_HTTP)
|
||||
set(TLS_SOURCES ${TLS_SOURCES} src/base/net/http/HttpsClient.h src/base/net/http/HttpsClient.cpp)
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
|
||||
endif()
|
||||
|
||||
@@ -6,13 +6,13 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
||||
if (MSVC_TOOLSET_VERSION GREATER_EQUAL 141)
|
||||
set(XMRIG_ASM_FILES
|
||||
"src/crypto/asm/cn_main_loop.asm"
|
||||
"src/crypto/asm/CryptonightR_template.asm"
|
||||
"src/crypto/cn/asm/cn_main_loop.asm"
|
||||
"src/crypto/cn/asm/CryptonightR_template.asm"
|
||||
)
|
||||
else()
|
||||
set(XMRIG_ASM_FILES
|
||||
"src/crypto/asm/win64/cn_main_loop.asm"
|
||||
"src/crypto/asm/win64/CryptonightR_template.asm"
|
||||
"src/crypto/cn/asm/win64/cn_main_loop.asm"
|
||||
"src/crypto/cn/asm/win64/CryptonightR_template.asm"
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -22,13 +22,13 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
||||
if (WIN32 AND CMAKE_C_COMPILER_ID MATCHES GNU)
|
||||
set(XMRIG_ASM_FILES
|
||||
"src/crypto/asm/win64/cn_main_loop.S"
|
||||
"src/crypto/asm/CryptonightR_template.S"
|
||||
"src/crypto/cn/asm/win64/cn_main_loop.S"
|
||||
"src/crypto/cn/asm/CryptonightR_template.S"
|
||||
)
|
||||
else()
|
||||
set(XMRIG_ASM_FILES
|
||||
"src/crypto/asm/cn_main_loop.S"
|
||||
"src/crypto/asm/CryptonightR_template.S"
|
||||
"src/crypto/cn/asm/cn_main_loop.S"
|
||||
"src/crypto/cn/asm/CryptonightR_template.S"
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -36,10 +36,17 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
endif()
|
||||
|
||||
add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILES})
|
||||
set(XMRIG_ASM_SOURCES src/crypto/Asm.h src/crypto/Asm.cpp src/crypto/CryptonightR_gen.cpp)
|
||||
set(XMRIG_ASM_SOURCES
|
||||
src/crypto/common/Assembly.h
|
||||
src/crypto/common/Assembly.cpp
|
||||
src/crypto/cn/r/CryptonightR_gen.cpp
|
||||
)
|
||||
set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C)
|
||||
|
||||
add_definitions(/DXMRIG_FEATURE_ASM)
|
||||
else()
|
||||
set(XMRIG_ASM_SOURCES "")
|
||||
set(XMRIG_ASM_LIBRARY "")
|
||||
add_definitions(/DXMRIG_NO_ASM)
|
||||
|
||||
remove_definitions(/DXMRIG_FEATURE_ASM)
|
||||
endif()
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
if (WITH_CN_GPU AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
||||
if (XMRIG_ARM)
|
||||
set(CN_GPU_SOURCES src/crypto/cn_gpu_arm.cpp)
|
||||
set(CN_GPU_SOURCES src/crypto/cn/gpu/cn_gpu_arm.cpp)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||
set_source_files_properties(src/crypto/cn_gpu_arm.cpp PROPERTIES COMPILE_FLAGS "-O3")
|
||||
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_arm.cpp PROPERTIES COMPILE_FLAGS "-O3")
|
||||
endif()
|
||||
else()
|
||||
set(CN_GPU_SOURCES src/crypto/cn_gpu_avx.cpp src/crypto/cn_gpu_ssse3.cpp)
|
||||
set(CN_GPU_SOURCES src/crypto/cn/gpu/cn_gpu_avx.cpp src/crypto/cn/gpu/cn_gpu_ssse3.cpp)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||
set_source_files_properties(src/crypto/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "-O3 -mavx2")
|
||||
set_source_files_properties(src/crypto/cn_gpu_ssse3.cpp PROPERTIES COMPILE_FLAGS "-O3")
|
||||
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "-O3 -mavx2")
|
||||
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_ssse3.cpp PROPERTIES COMPILE_FLAGS "-O3")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
set_source_files_properties(src/crypto/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "/arch:AVX")
|
||||
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "/arch:AVX")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_definitions(/DXMRIG_ALGO_CN_GPU)
|
||||
else()
|
||||
set(CN_GPU_SOURCES "")
|
||||
|
||||
add_definitions(/DXMRIG_NO_CN_GPU)
|
||||
remove_definitions(/DXMRIG_ALGO_CN_GPU)
|
||||
endif()
|
||||
|
||||
@@ -10,12 +10,14 @@ if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
add_definitions(/DNDEBUG)
|
||||
endif()
|
||||
|
||||
include(CheckSymbolExists)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-class-memaccess")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti -Wno-class-memaccess")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s")
|
||||
|
||||
if (XMRIG_ARMv8)
|
||||
@@ -27,6 +29,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
||||
|
||||
add_definitions(/DHAVE_ROTR)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
@@ -50,13 +54,14 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
||||
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
|
||||
add_definitions(/DNOMINMAX)
|
||||
add_definitions(/DHAVE_ROTR)
|
||||
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-missing-braces")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti -Wno-missing-braces")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
|
||||
|
||||
if (XMRIG_ARMv8)
|
||||
@@ -68,6 +73,18 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
||||
|
||||
check_symbol_exists("_rotr" "x86intrin.h" HAVE_ROTR)
|
||||
if (HAVE_ROTR)
|
||||
add_definitions(/DHAVE_ROTR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if (NOT WIN32)
|
||||
check_symbol_exists("__builtin___clear_cache" "stdlib.h" HAVE_BUILTIN_CLEAR_CACHE)
|
||||
if (HAVE_BUILTIN_CLEAR_CACHE)
|
||||
add_definitions(/DHAVE_BUILTIN_CLEAR_CACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1,22 +1,14 @@
|
||||
# Algorithms
|
||||
|
||||
XMRig uses a different way to specify algorithms, compared to other miners.
|
||||
|
||||
Algorithm selection splitted to 2 parts:
|
||||
|
||||
* Global base algorithm per miner or proxy instance, `algo` option. Possible values: `cryptonight`, `cryptonight-lite`, `cryptonight-heavy`.
|
||||
* Algorithm variant specified separately for each pool, `variant` option.
|
||||
* [Full table for supported algorithm and variants.](https://github.com/xmrig/xmrig-proxy/blob/master/doc/STRATUM_EXT.md#14-algorithm-names-and-variants)
|
||||
Since version 3 mining [algorithm](#algorithm-names) should specified for each pool separately (`algo` option), earlier versions was use one global `algo` option and per pool `variant` option (this option was removed in v3). If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) you may not specify this option at all.
|
||||
|
||||
#### Example
|
||||
```json
|
||||
{
|
||||
"algo": "cryptonight",
|
||||
...
|
||||
"pools": [
|
||||
{
|
||||
"url": "...",
|
||||
"variant": 1,
|
||||
"algo": "cn/r",
|
||||
...
|
||||
}
|
||||
],
|
||||
@@ -24,8 +16,34 @@ Algorithm selection splitted to 2 parts:
|
||||
}
|
||||
```
|
||||
|
||||
## Mining algorithm negotiation
|
||||
If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) miner will choice proper variant automaticaly and if you choice wrong base algorithm you will see error message.
|
||||
#### Pools with mining algorithm negotiation support.
|
||||
|
||||
Pools with mining algorithm negotiation support.
|
||||
* [www.hashvault.pro](https://www.hashvault.pro/)
|
||||
* [moneroocean.stream](https://moneroocean.stream)
|
||||
|
||||
## Algorithm names
|
||||
|
||||
| Name | Memory | Notes |
|
||||
|-----------------|--------|--------------------------------------------------------------------------------------|
|
||||
| `cn/0` | 2 MB | CryptoNight (original) |
|
||||
| `cn/1` | 2 MB | CryptoNight variant 1 also known as `Monero7` and `CryptoNightV7`. |
|
||||
| `cn/2` | 2 MB | CryptoNight variant 2. |
|
||||
| `cn/r` | 2 MB | CryptoNightR (Monero's variant 4). |
|
||||
| `cn/wow` | 2 MB | CryptoNightR (Wownero). |
|
||||
| `cn/fast` | 2 MB | CryptoNight variant 1 with half iterations. |
|
||||
| `cn/half` | 2 MB | CryptoNight variant 2 with half iterations (Masari/Torque) |
|
||||
| `cn/xao` | 2 MB | CryptoNight variant 0 (modified, Alloy only) |
|
||||
| `cn/rto` | 2 MB | CryptoNight variant 1 (modified, Arto only) |
|
||||
| `cn/rwz` | 2 MB | CryptoNight variant 2 with 3/4 iterations and reversed shuffle operation (Graft). |
|
||||
| `cn/zls` | 2 MB | CryptoNight variant 2 with 3/4 iterations (Zelerius). |
|
||||
| `cn/double` | 2 MB | CryptoNight variant 2 with double iterations (X-CASH). |
|
||||
| `cn/gpu` | 2 MB | CryptoNight-GPU (RYO). |
|
||||
| `cn-lite/0` | 1 MB | CryptoNight-Lite variant 0. |
|
||||
| `cn-lite/1` | 1 MB | CryptoNight-Lite variant 1. |
|
||||
| `cn-heavy/0` | 4 MB | CryptoNight-Heavy . |
|
||||
| `cn-heavy/xhv` | 4 MB | CryptoNight-Heavy (modified, TUBE only). |
|
||||
| `cn-heavy/tube` | 4 MB | CryptoNight-Heavy (modified, Haven Protocol only). |
|
||||
| `cn-pico` | 256 KB | TurtleCoin (TRTL) |
|
||||
| `rx/0` | 2 MB | RandomX (reference configuration), reserved for future use. |
|
||||
| `rx/wow` | 1 MB | RandomWOW (Wownero). |
|
||||
| `rx/loki` | 2 MB | RandomXL (Loki). |
|
||||
|
||||
60
doc/CPU.md
Normal file
60
doc/CPU.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# CPU backend
|
||||
|
||||
All CPU related settings contains in one `cpu` object in config file, CPU backend allow specify multiple profiles and allow switch between them without restrictions by pool request or config change. Default auto-configuration create reasonable minimum of profiles which cover all supported algorithms.
|
||||
|
||||
### Example
|
||||
|
||||
Example below demonstrate all primary ideas of flexible profiles configuration:
|
||||
|
||||
* `"rx/wow"` Exact match to algorithm `rx/wow`, defined 4 threads without CPU affinity.
|
||||
* `"cn"` Default failback profile for all `cn/*` algorithms, defined 2 threads with CPU affinity, another failback profiles is `cn-lite`, `cn-heavy` and `rx`.
|
||||
* `"cn-lite"` Default failback profile for all `cn-lite/*` algorithms, defined 2 double threads with CPU affinity.
|
||||
* `"custom-profile"` Custom user defined profile.
|
||||
* `"*"` Failback profile for all unhandled by other profiles algorithms.
|
||||
* `"cn/r"` Exact match, alias to profile `custom-profile`.
|
||||
* `"cn/0"` Exact match, disabled algorithm.
|
||||
|
||||
```json
|
||||
{
|
||||
"cpu": {
|
||||
"enabled": true,
|
||||
"huge-pages": true,
|
||||
"hw-aes": null,
|
||||
"priority": null,
|
||||
"asm": true,
|
||||
"rx/wow": [
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
],
|
||||
"cn": [
|
||||
0,
|
||||
2
|
||||
],
|
||||
"cn-lite": [
|
||||
{
|
||||
"intensity": 2,
|
||||
"affinity": 0
|
||||
},
|
||||
{
|
||||
"intensity": 2,
|
||||
"affinity": 2
|
||||
}
|
||||
],
|
||||
"custom-profile": [
|
||||
0,
|
||||
2,
|
||||
],
|
||||
"*": [
|
||||
-1
|
||||
],
|
||||
"cn/r": "custom-profile",
|
||||
"cn/0": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Intensity
|
||||
This option was known as `low_power_mode`, possible values is range from 1 to 5, for convinient if value 1 used, possible omit this option and specify CPU thread config by only one number: CPU affinity, instead of object.
|
||||
|
||||
65
src/3rdparty/aligned_malloc.h
vendored
65
src/3rdparty/aligned_malloc.h
vendored
@@ -1,65 +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/>.
|
||||
*/
|
||||
|
||||
#ifndef __ALIGNED_MALLOC_H__
|
||||
#define __ALIGNED_MALLOC_H__
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
|
||||
#else
|
||||
// Some systems (e.g. those with GNU libc) declare posix_memalign with an
|
||||
// exception specifier. Via an "egregious workaround" in
|
||||
// Sema::CheckEquivalentExceptionSpec, Clang accepts the following as a valid
|
||||
// redeclaration of glibc's declaration.
|
||||
extern "C" int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
|
||||
#endif
|
||||
|
||||
|
||||
static __inline__ void *__attribute__((__always_inline__, __malloc__)) _mm_malloc(size_t __size, size_t __align)
|
||||
{
|
||||
if (__align == 1) {
|
||||
return malloc(__size);
|
||||
}
|
||||
|
||||
if (!(__align & (__align - 1)) && __align < sizeof(void *))
|
||||
__align = sizeof(void *);
|
||||
|
||||
void *__mallocedMemory;
|
||||
if (posix_memalign(&__mallocedMemory, __align, __size)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return __mallocedMemory;
|
||||
}
|
||||
|
||||
|
||||
static __inline__ void __attribute__((__always_inline__)) _mm_free(void *__p)
|
||||
{
|
||||
free(__p);
|
||||
}
|
||||
|
||||
#endif /* __ALIGNED_MALLOC_H__ */
|
||||
27
src/App.cpp
27
src/App.cpp
@@ -6,7 +6,7 @@
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -30,19 +30,17 @@
|
||||
|
||||
#include "api/Api.h"
|
||||
#include "App.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "base/io/Console.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/Signals.h"
|
||||
#include "common/cpu/Cpu.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "Mem.h"
|
||||
#include "core/Miner.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "net/Network.h"
|
||||
#include "Summary.h"
|
||||
#include "version.h"
|
||||
#include "workers/Workers.h"
|
||||
|
||||
|
||||
xmrig::App::App(Process *process) :
|
||||
@@ -78,7 +76,7 @@ int xmrig::App::exec()
|
||||
|
||||
background();
|
||||
|
||||
Mem::init(m_controller->config()->isHugePages());
|
||||
VirtualMemory::init(m_controller->config()->cpu().isHugePages());
|
||||
|
||||
Summary::print(m_controller);
|
||||
|
||||
@@ -88,8 +86,6 @@ int xmrig::App::exec()
|
||||
return 0;
|
||||
}
|
||||
|
||||
Workers::start(m_controller);
|
||||
|
||||
m_controller->start();
|
||||
|
||||
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
@@ -104,23 +100,17 @@ void xmrig::App::onConsoleCommand(char command)
|
||||
switch (command) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
Workers::printHashrate(true);
|
||||
m_controller->miner()->printHashrate(true);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
case 'P':
|
||||
if (Workers::isEnabled()) {
|
||||
LOG_INFO(YELLOW_BOLD("paused") ", press " MAGENTA_BOLD("r") " to resume");
|
||||
Workers::setEnabled(false);
|
||||
}
|
||||
m_controller->miner()->setEnabled(false);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
case 'R':
|
||||
if (!Workers::isEnabled()) {
|
||||
LOG_INFO(GREEN_BOLD("resumed"));
|
||||
Workers::setEnabled(true);
|
||||
}
|
||||
m_controller->miner()->setEnabled(true);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@@ -164,6 +154,5 @@ void xmrig::App::close()
|
||||
m_console->stop();
|
||||
m_controller->stop();
|
||||
|
||||
Workers::stop();
|
||||
Log::destroy();
|
||||
}
|
||||
|
||||
119
src/Mem_unix.cpp
119
src/Mem_unix.cpp
@@ -1,119 +0,0 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "common/utils/mm_malloc.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "Mem.h"
|
||||
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <mach/vm_statistics.h>
|
||||
#endif
|
||||
|
||||
|
||||
void Mem::init(bool enabled)
|
||||
{
|
||||
m_enabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
void Mem::allocate(MemInfo &info, bool enabled)
|
||||
{
|
||||
info.hugePages = 0;
|
||||
|
||||
if (!enabled) {
|
||||
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# if defined(__APPLE__)
|
||||
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
|
||||
# elif defined(__FreeBSD__)
|
||||
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
|
||||
# else
|
||||
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
|
||||
# endif
|
||||
|
||||
if (info.memory == MAP_FAILED) {
|
||||
return allocate(info, false);;
|
||||
}
|
||||
|
||||
info.hugePages = info.pages;
|
||||
|
||||
if (madvise(info.memory, info.size, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
||||
LOG_ERR("madvise failed");
|
||||
}
|
||||
|
||||
if (mlock(info.memory, info.size) == 0) {
|
||||
m_flags |= Lock;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mem::release(MemInfo &info)
|
||||
{
|
||||
if (info.hugePages) {
|
||||
if (m_flags & Lock) {
|
||||
munlock(info.memory, info.size);
|
||||
}
|
||||
|
||||
munmap(info.memory, info.size);
|
||||
}
|
||||
else {
|
||||
_mm_free(info.memory);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *Mem::allocateExecutableMemory(size_t size)
|
||||
{
|
||||
# if defined(__APPLE__)
|
||||
return mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
# else
|
||||
return mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void Mem::protectExecutableMemory(void *p, size_t size)
|
||||
{
|
||||
mprotect(p, size, PROT_READ | PROT_EXEC);
|
||||
}
|
||||
|
||||
|
||||
void Mem::flushInstructionCache(void *p, size_t size)
|
||||
{
|
||||
# ifndef __FreeBSD__
|
||||
__builtin___clear_cache(reinterpret_cast<char*>(p), reinterpret_cast<char*>(p) + size);
|
||||
# endif
|
||||
}
|
||||
@@ -28,18 +28,18 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/Pool.h"
|
||||
#include "common/cpu/Cpu.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "crypto/Asm.h"
|
||||
#include "Mem.h"
|
||||
#include "crypto/common/Assembly.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "Summary.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_ASM
|
||||
#ifdef XMRIG_FEATURE_ASM
|
||||
static const char *coloredAsmNames[] = {
|
||||
RED_BOLD("none"),
|
||||
"auto",
|
||||
@@ -49,7 +49,7 @@ static const char *coloredAsmNames[] = {
|
||||
};
|
||||
|
||||
|
||||
inline static const char *asmName(xmrig::Assembly assembly)
|
||||
inline static const char *asmName(xmrig::Assembly::Id assembly)
|
||||
{
|
||||
return coloredAsmNames[assembly];
|
||||
}
|
||||
@@ -59,7 +59,7 @@ inline static const char *asmName(xmrig::Assembly assembly)
|
||||
static void print_memory(xmrig::Config *) {
|
||||
# ifdef _WIN32
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
|
||||
"HUGE PAGES", Mem::isHugepagesAvailable() ? GREEN_BOLD("available") : RED_BOLD("unavailable"));
|
||||
"HUGE PAGES", xmrig::VirtualMemory::isHugepagesAvailable() ? GREEN_BOLD("available") : RED_BOLD("unavailable"));
|
||||
# endif
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ static void print_cpu(xmrig::Config *)
|
||||
Cpu::info()->hasAES() ? GREEN_BOLD_S : RED_BOLD_S "-",
|
||||
Cpu::info()->hasAVX2() ? GREEN_BOLD_S : RED_BOLD_S "-"
|
||||
);
|
||||
# ifndef XMRIG_NO_LIBCPUID
|
||||
# ifdef XMRIG_FEATURE_LIBCPUID
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
|
||||
# endif
|
||||
}
|
||||
@@ -84,40 +84,20 @@ static void print_cpu(xmrig::Config *)
|
||||
|
||||
static void print_threads(xmrig::Config *config)
|
||||
{
|
||||
if (config->threadsMode() != xmrig::Config::Advanced) {
|
||||
char buf[32] = { 0 };
|
||||
if (config->affinity() != -1L) {
|
||||
snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity());
|
||||
}
|
||||
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, av=%d, %sdonate=%d%%") WHITE_BOLD("%s"),
|
||||
"THREADS",
|
||||
config->threadsCount(),
|
||||
config->algorithm().shortName(),
|
||||
config->algoVariant(),
|
||||
config->pools().donateLevel() == 0 ? RED_BOLD_S : "",
|
||||
config->pools().donateLevel(),
|
||||
buf
|
||||
);
|
||||
}
|
||||
else {
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, %sdonate=%d%%"),
|
||||
"THREADS",
|
||||
config->threadsCount(),
|
||||
config->algorithm().shortName(),
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s%d%%"),
|
||||
"DONATE",
|
||||
config->pools().donateLevel() == 0 ? RED_BOLD_S : "",
|
||||
config->pools().donateLevel()
|
||||
);
|
||||
}
|
||||
|
||||
# ifndef XMRIG_NO_ASM
|
||||
if (config->assembly() == xmrig::ASM_AUTO) {
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
if (config->cpu().assembly() == xmrig::Assembly::AUTO) {
|
||||
const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly();
|
||||
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s"), "ASSEMBLY", asmName(assembly));
|
||||
}
|
||||
else {
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s"), "ASSEMBLY", asmName(config->assembly()));
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s"), "ASSEMBLY", asmName(config->cpu().assembly()));
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
@@ -35,11 +35,13 @@
|
||||
#include "api/Api.h"
|
||||
#include "api/interfaces/IApiListener.h"
|
||||
#include "api/requests/HttpApiRequest.h"
|
||||
#include "api/v1/ApiRouter.h"
|
||||
#include "base/kernel/Base.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
#include "common/crypto/keccak.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "crypto/common/Algorithm.h"
|
||||
#include "crypto/common/keccak.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
@@ -48,34 +50,30 @@
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::Api::Api(Controller *controller) :
|
||||
xmrig::Api::Api(Base *base) :
|
||||
m_base(base),
|
||||
m_id(),
|
||||
m_workerId(),
|
||||
m_controller(controller),
|
||||
m_httpd(nullptr)
|
||||
m_httpd(nullptr),
|
||||
m_timestamp(Chrono::steadyMSecs())
|
||||
{
|
||||
controller->addListener(this);
|
||||
base->addListener(this);
|
||||
|
||||
genId(m_controller->config()->apiId());
|
||||
|
||||
m_v1 = new ApiRouter(controller);
|
||||
addListener(m_v1);
|
||||
genId(base->config()->apiId());
|
||||
}
|
||||
|
||||
|
||||
xmrig::Api::~Api()
|
||||
{
|
||||
delete m_v1;
|
||||
|
||||
# ifdef XMRIG_FEATURE_HTTP
|
||||
delete m_httpd;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Api::request(const HttpRequest &req)
|
||||
void xmrig::Api::request(const HttpData &req)
|
||||
{
|
||||
HttpApiRequest request(req, m_controller->config()->http().isRestricted());
|
||||
HttpApiRequest request(req, m_base->config()->http().isRestricted());
|
||||
|
||||
exec(request);
|
||||
}
|
||||
@@ -83,10 +81,10 @@ void xmrig::Api::request(const HttpRequest &req)
|
||||
|
||||
void xmrig::Api::start()
|
||||
{
|
||||
genWorkerId(m_controller->config()->apiWorkerId());
|
||||
genWorkerId(m_base->config()->apiWorkerId());
|
||||
|
||||
# ifdef XMRIG_FEATURE_HTTP
|
||||
m_httpd = new Httpd(m_controller);
|
||||
m_httpd = new Httpd(m_base);
|
||||
m_httpd->start();
|
||||
# endif
|
||||
}
|
||||
@@ -116,10 +114,31 @@ void xmrig::Api::exec(IApiRequest &request)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
if (request.method() == IApiRequest::METHOD_GET && (request.url() == "/1/summary" || request.url() == "/api.json")) {
|
||||
if (request.type() == IApiRequest::REQ_SUMMARY) {
|
||||
auto &allocator = request.doc().GetAllocator();
|
||||
|
||||
request.accept();
|
||||
request.reply().AddMember("id", StringRef(m_id), request.doc().GetAllocator());
|
||||
request.reply().AddMember("worker_id", StringRef(m_workerId), request.doc().GetAllocator());;
|
||||
request.reply().AddMember("id", StringRef(m_id), allocator);
|
||||
request.reply().AddMember("worker_id", StringRef(m_workerId), allocator);
|
||||
request.reply().AddMember("uptime", (Chrono::steadyMSecs() - m_timestamp) / 1000, allocator);
|
||||
|
||||
Value features(kArrayType);
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
features.PushBack("api", allocator);
|
||||
# endif
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
features.PushBack("asm", allocator);
|
||||
# endif
|
||||
# ifdef XMRIG_FEATURE_HTTP
|
||||
features.PushBack("http", allocator);
|
||||
# endif
|
||||
# ifdef XMRIG_FEATURE_LIBCPUID
|
||||
features.PushBack("cpuid", allocator);
|
||||
# endif
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
features.PushBack("tls", allocator);
|
||||
# endif
|
||||
request.reply().AddMember("features", features, allocator);
|
||||
}
|
||||
|
||||
for (IApiListener *listener : m_listeners) {
|
||||
@@ -155,7 +174,7 @@ void xmrig::Api::genId(const String &id)
|
||||
uint8_t hash[200];
|
||||
const size_t addrSize = sizeof(interfaces[i].phys_addr);
|
||||
const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t);
|
||||
const uint16_t port = static_cast<uint16_t>(m_controller->config()->http().port());
|
||||
const uint16_t port = static_cast<uint16_t>(m_base->config()->http().port());
|
||||
|
||||
uint8_t *input = new uint8_t[inSize]();
|
||||
memcpy(input, &port, sizeof(uint16_t));
|
||||
|
||||
@@ -27,34 +27,34 @@
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IControllerListener.h"
|
||||
#include "base/kernel/interfaces/IBaseListener.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ApiRouter;
|
||||
class Controller;
|
||||
class Base;
|
||||
class Httpd;
|
||||
class HttpRequest;
|
||||
class HttpData;
|
||||
class IApiListener;
|
||||
class IApiRequest;
|
||||
class String;
|
||||
|
||||
|
||||
class Api : public IControllerListener
|
||||
class Api : public IBaseListener
|
||||
{
|
||||
public:
|
||||
Api(Controller *controller);
|
||||
Api(Base *base);
|
||||
~Api() override;
|
||||
|
||||
inline const char *id() const { return m_id; }
|
||||
inline const char *workerId() const { return m_workerId; }
|
||||
inline void addListener(IApiListener *listener) { m_listeners.push_back(listener); }
|
||||
|
||||
void request(const HttpRequest &req);
|
||||
void request(const HttpData &req);
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
@@ -66,12 +66,12 @@ private:
|
||||
void genId(const String &id);
|
||||
void genWorkerId(const String &id);
|
||||
|
||||
ApiRouter *m_v1;
|
||||
Base *m_base;
|
||||
char m_id[32];
|
||||
char m_workerId[128];
|
||||
Controller *m_controller;
|
||||
Httpd *m_httpd;
|
||||
std::vector<IApiListener *> m_listeners;
|
||||
uint64_t m_timestamp;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "api/Httpd.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/http/HttpApiResponse.h"
|
||||
#include "base/net/http/HttpRequest.h"
|
||||
#include "base/net/http/HttpData.h"
|
||||
#include "base/net/http/HttpServer.h"
|
||||
#include "base/net/tools/TcpServer.h"
|
||||
#include "core/config/Config.h"
|
||||
@@ -48,13 +48,13 @@ static size_t faviconSize = 0;
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::Httpd::Httpd(Controller *controller) :
|
||||
m_controller(controller),
|
||||
xmrig::Httpd::Httpd(Base *base) :
|
||||
m_base(base),
|
||||
m_http(nullptr),
|
||||
m_server(nullptr),
|
||||
m_port(0)
|
||||
{
|
||||
controller->addListener(this);
|
||||
base->addListener(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ xmrig::Httpd::~Httpd()
|
||||
|
||||
bool xmrig::Httpd::start()
|
||||
{
|
||||
const Http &config = m_controller->config()->http();
|
||||
const Http &config = m_base->config()->http();
|
||||
|
||||
if (!config.isEnabled()) {
|
||||
return true;
|
||||
@@ -128,51 +128,51 @@ void xmrig::Httpd::onConfigChanged(Config *config, Config *previousConfig)
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Httpd::onHttpRequest(const HttpRequest &req)
|
||||
void xmrig::Httpd::onHttpData(const HttpData &data)
|
||||
{
|
||||
if (req.method == HTTP_OPTIONS) {
|
||||
return HttpApiResponse(req.id()).end();
|
||||
if (data.method == HTTP_OPTIONS) {
|
||||
return HttpApiResponse(data.id()).end();
|
||||
}
|
||||
|
||||
if (req.method == HTTP_GET && req.url == "/favicon.ico") {
|
||||
if (data.method == HTTP_GET && data.url == "/favicon.ico") {
|
||||
# ifdef _WIN32
|
||||
if (favicon != nullptr) {
|
||||
HttpResponse response(req.id());
|
||||
HttpResponse response(data.id());
|
||||
response.setHeader("Content-Type", "image/x-icon");
|
||||
|
||||
return response.end(favicon, faviconSize);
|
||||
}
|
||||
# endif
|
||||
|
||||
return HttpResponse(req.id(), 404).end();
|
||||
return HttpResponse(data.id(), 404).end();
|
||||
}
|
||||
|
||||
if (req.method > 4) {
|
||||
return HttpApiResponse(req.id(), HTTP_STATUS_METHOD_NOT_ALLOWED).end();
|
||||
if (data.method > 4) {
|
||||
return HttpApiResponse(data.id(), HTTP_STATUS_METHOD_NOT_ALLOWED).end();
|
||||
}
|
||||
|
||||
const int status = auth(req);
|
||||
const int status = auth(data);
|
||||
if (status != HTTP_STATUS_OK) {
|
||||
return HttpApiResponse(req.id(), status).end();
|
||||
return HttpApiResponse(data.id(), status).end();
|
||||
}
|
||||
|
||||
if (req.method != HTTP_GET) {
|
||||
if (m_controller->config()->http().isRestricted()) {
|
||||
return HttpApiResponse(req.id(), HTTP_STATUS_FORBIDDEN).end();
|
||||
if (data.method != HTTP_GET) {
|
||||
if (m_base->config()->http().isRestricted()) {
|
||||
return HttpApiResponse(data.id(), HTTP_STATUS_FORBIDDEN).end();
|
||||
}
|
||||
|
||||
if (!req.headers.count(kContentType) || req.headers.at(kContentType) != "application/json") {
|
||||
return HttpApiResponse(req.id(), HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE).end();
|
||||
if (!data.headers.count(kContentType) || data.headers.at(kContentType) != "application/json") {
|
||||
return HttpApiResponse(data.id(), HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE).end();
|
||||
}
|
||||
}
|
||||
|
||||
m_controller->api()->request(req);
|
||||
m_base->api()->request(data);
|
||||
}
|
||||
|
||||
|
||||
int xmrig::Httpd::auth(const HttpRequest &req) const
|
||||
int xmrig::Httpd::auth(const HttpData &req) const
|
||||
{
|
||||
const Http &config = m_controller->config()->http();
|
||||
const Http &config = m_base->config()->http();
|
||||
|
||||
if (!req.headers.count(kAuthorization)) {
|
||||
return config.isAuthRequired() ? HTTP_STATUS_UNAUTHORIZED : HTTP_STATUS_OK;
|
||||
|
||||
@@ -29,22 +29,22 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IControllerListener.h"
|
||||
#include "base/kernel/interfaces/IBaseListener.h"
|
||||
#include "base/kernel/interfaces/IHttpListener.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Controller;
|
||||
class Base;
|
||||
class HttpServer;
|
||||
class TcpServer;
|
||||
|
||||
|
||||
class Httpd : public IControllerListener, public IHttpListener
|
||||
class Httpd : public IBaseListener, public IHttpListener
|
||||
{
|
||||
public:
|
||||
Httpd(Controller *controller);
|
||||
Httpd(Base *base);
|
||||
~Httpd() override;
|
||||
|
||||
bool start();
|
||||
@@ -52,12 +52,12 @@ public:
|
||||
|
||||
protected:
|
||||
void onConfigChanged(Config *config, Config *previousConfig) override;
|
||||
void onHttpRequest(const HttpRequest &req) override;
|
||||
void onHttpData(const HttpData &data) override;
|
||||
|
||||
private:
|
||||
int auth(const HttpRequest &req) const;
|
||||
int auth(const HttpData &req) const;
|
||||
|
||||
Controller *m_controller;
|
||||
Base *m_base;
|
||||
HttpServer *m_http;
|
||||
TcpServer *m_server;
|
||||
uint16_t m_port;
|
||||
|
||||
@@ -35,7 +35,9 @@ class IApiListener
|
||||
public:
|
||||
virtual ~IApiListener() = default;
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
virtual void onRequest(IApiRequest &request) = 0;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
* 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>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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
|
||||
@@ -50,6 +52,12 @@ public:
|
||||
};
|
||||
|
||||
|
||||
enum RequestType {
|
||||
REQ_UNKNOWN,
|
||||
REQ_SUMMARY
|
||||
};
|
||||
|
||||
|
||||
virtual ~IApiRequest() = default;
|
||||
|
||||
virtual bool isDone() const = 0;
|
||||
@@ -57,9 +65,11 @@ public:
|
||||
virtual bool isRestricted() const = 0;
|
||||
virtual const rapidjson::Value &json() const = 0;
|
||||
virtual const String &url() const = 0;
|
||||
virtual int version() const = 0;
|
||||
virtual Method method() const = 0;
|
||||
virtual rapidjson::Document &doc() = 0;
|
||||
virtual rapidjson::Value &reply() = 0;
|
||||
virtual RequestType type() const = 0;
|
||||
virtual Source source() const = 0;
|
||||
virtual void accept() = 0;
|
||||
virtual void done(int status) = 0;
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
|
||||
xmrig::ApiRequest::ApiRequest(Source source, bool restricted) :
|
||||
m_restricted(restricted),
|
||||
m_source(source),
|
||||
m_state(STATE_NEW)
|
||||
m_source(source)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,15 @@ protected:
|
||||
inline bool isDone() const override { return m_state == STATE_DONE; }
|
||||
inline bool isNew() const override { return m_state == STATE_NEW; }
|
||||
inline bool isRestricted() const override { return m_restricted; }
|
||||
inline int version() const override { return m_version; }
|
||||
inline RequestType type() const override { return m_type; }
|
||||
inline Source source() const override { return m_source; }
|
||||
inline void accept() override { m_state = STATE_ACCEPTED; }
|
||||
inline void done(int) override { m_state = STATE_DONE; }
|
||||
|
||||
int m_version = 1;
|
||||
RequestType m_type = REQ_UNKNOWN;
|
||||
|
||||
private:
|
||||
enum State {
|
||||
STATE_NEW,
|
||||
@@ -56,7 +61,7 @@ private:
|
||||
|
||||
bool m_restricted;
|
||||
Source m_source;
|
||||
State m_state;
|
||||
State m_state = STATE_NEW;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -24,17 +24,28 @@
|
||||
|
||||
|
||||
#include "api/requests/HttpApiRequest.h"
|
||||
#include "base/net/http/HttpRequest.h"
|
||||
#include "base/net/http/HttpData.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
|
||||
|
||||
xmrig::HttpApiRequest::HttpApiRequest(const HttpRequest &req, bool restricted) :
|
||||
xmrig::HttpApiRequest::HttpApiRequest(const HttpData &req, bool restricted) :
|
||||
ApiRequest(SOURCE_HTTP, restricted),
|
||||
m_parsed(false),
|
||||
m_req(req),
|
||||
m_res(req.id()),
|
||||
m_url(req.url.c_str())
|
||||
{
|
||||
if (method() == METHOD_GET) {
|
||||
if (url() == "/1/summary" || url() == "/2/summary" || url() == "/api.json") {
|
||||
m_type = REQ_SUMMARY;
|
||||
}
|
||||
}
|
||||
|
||||
if (url().size() > 4) {
|
||||
if (memcmp(url().data(), "/2/", 3) == 0) {
|
||||
m_version = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,13 +35,13 @@
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpRequest;
|
||||
class HttpData;
|
||||
|
||||
|
||||
class HttpApiRequest : public ApiRequest
|
||||
{
|
||||
public:
|
||||
HttpApiRequest(const HttpRequest &req, bool restricted);
|
||||
HttpApiRequest(const HttpData &req, bool restricted);
|
||||
|
||||
protected:
|
||||
inline rapidjson::Document &doc() override { return m_res.doc(); }
|
||||
@@ -55,7 +55,7 @@ protected:
|
||||
|
||||
private:
|
||||
bool m_parsed;
|
||||
const HttpRequest &m_req;
|
||||
const HttpData &m_req;
|
||||
HttpApiResponse m_res;
|
||||
rapidjson::Document m_body;
|
||||
String m_url;
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 <math.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "api/interfaces/IApiRequest.h"
|
||||
#include "api/v1/ApiRouter.h"
|
||||
#include "common/cpu/Cpu.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "interfaces/IThread.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "version.h"
|
||||
#include "workers/Hashrate.h"
|
||||
#include "workers/Workers.h"
|
||||
|
||||
|
||||
static inline double normalize(double d)
|
||||
{
|
||||
if (!isnormal(d)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return floor(d * 100.0) / 100.0;
|
||||
}
|
||||
|
||||
|
||||
xmrig::ApiRouter::ApiRouter(xmrig::Controller *controller) :
|
||||
m_controller(controller)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::ApiRouter::~ApiRouter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::onRequest(IApiRequest &request)
|
||||
{
|
||||
if (request.method() == IApiRequest::METHOD_GET) {
|
||||
if (request.url() == "/1/summary" || request.url() == "/api.json") {
|
||||
request.accept();
|
||||
getMiner(request.reply(), request.doc());
|
||||
getHashrate(request.reply(), request.doc());
|
||||
}
|
||||
else if (request.url() == "/1/threads") {
|
||||
request.accept();
|
||||
getThreads(request.reply(), request.doc());
|
||||
}
|
||||
else if (request.url() == "/1/config") {
|
||||
if (request.isRestricted()) {
|
||||
return request.done(403);
|
||||
}
|
||||
|
||||
request.accept();
|
||||
m_controller->config()->getJSON(request.doc());
|
||||
}
|
||||
}
|
||||
else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) {
|
||||
if (request.url() == "/1/config") {
|
||||
request.accept();
|
||||
|
||||
if (!m_controller->config()->reload(request.json())) {
|
||||
return request.done(400);
|
||||
}
|
||||
|
||||
request.done(204);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value hashrate(kObjectType);
|
||||
Value total(kArrayType);
|
||||
Value threads(kArrayType);
|
||||
|
||||
const Hashrate *hr = Workers::hashrate();
|
||||
|
||||
total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator);
|
||||
total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator);
|
||||
total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator);
|
||||
|
||||
for (size_t i = 0; i < Workers::threads(); i++) {
|
||||
Value thread(kArrayType);
|
||||
thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
||||
thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
||||
thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
|
||||
|
||||
threads.PushBack(thread, allocator);
|
||||
}
|
||||
|
||||
hashrate.AddMember("total", total, allocator);
|
||||
hashrate.AddMember("highest", normalize(hr->highest()), allocator);
|
||||
hashrate.AddMember("threads", threads, allocator);
|
||||
reply.AddMember("hashrate", hashrate, allocator);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value cpu(kObjectType);
|
||||
cpu.AddMember("brand", StringRef(Cpu::info()->brand()), allocator);
|
||||
cpu.AddMember("aes", Cpu::info()->hasAES(), allocator);
|
||||
cpu.AddMember("x64", Cpu::info()->isX64(), allocator);
|
||||
cpu.AddMember("sockets", Cpu::info()->sockets(), allocator);
|
||||
|
||||
reply.AddMember("version", APP_VERSION, allocator);
|
||||
reply.AddMember("kind", APP_KIND, allocator);
|
||||
reply.AddMember("ua", StringRef(Platform::userAgent()), allocator);
|
||||
reply.AddMember("cpu", cpu, allocator);
|
||||
reply.AddMember("algo", StringRef(m_controller->config()->algorithm().name()), allocator);
|
||||
reply.AddMember("hugepages", Workers::hugePages() > 0, allocator);
|
||||
reply.AddMember("donate_level", m_controller->config()->pools().donateLevel(), allocator);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
const Hashrate *hr = Workers::hashrate();
|
||||
|
||||
Workers::threadsSummary(doc);
|
||||
|
||||
const std::vector<xmrig::IThread *> &threads = m_controller->config()->threads();
|
||||
Value list(kArrayType);
|
||||
|
||||
size_t i = 0;
|
||||
for (const xmrig::IThread *thread : threads) {
|
||||
Value value = thread->toAPI(doc);
|
||||
|
||||
Value hashrate(kArrayType);
|
||||
hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
||||
hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
||||
hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
|
||||
|
||||
i++;
|
||||
|
||||
value.AddMember("hashrate", hashrate, allocator);
|
||||
list.PushBack(value, allocator);
|
||||
}
|
||||
|
||||
reply.AddMember("threads", list, allocator);
|
||||
}
|
||||
13
src/backend/backend.cmake
Normal file
13
src/backend/backend.cmake
Normal file
@@ -0,0 +1,13 @@
|
||||
include (src/backend/cpu/cpu.cmake)
|
||||
include (src/backend/common/common.cmake)
|
||||
|
||||
|
||||
set(HEADERS_BACKEND
|
||||
"${HEADERS_BACKEND_COMMON}"
|
||||
"${HEADERS_BACKEND_CPU}"
|
||||
)
|
||||
|
||||
set(SOURCES_BACKEND
|
||||
"${SOURCES_BACKEND_COMMON}"
|
||||
"${SOURCES_BACKEND_CPU}"
|
||||
)
|
||||
@@ -24,22 +24,20 @@
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <chrono>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "backend/common/Hashrate.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "workers/Hashrate.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
inline static const char *format(double h, char *buf, size_t size)
|
||||
{
|
||||
if (isnormal(h)) {
|
||||
if (std::isnormal(h)) {
|
||||
snprintf(buf, size, "%03.1f", h);
|
||||
return buf;
|
||||
}
|
||||
@@ -48,10 +46,9 @@ inline static const char *format(double h, char *buf, size_t size)
|
||||
}
|
||||
|
||||
|
||||
Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) :
|
||||
xmrig::Hashrate::Hashrate(size_t threads) :
|
||||
m_highest(0.0),
|
||||
m_threads(threads),
|
||||
m_timer(nullptr)
|
||||
m_threads(threads)
|
||||
{
|
||||
m_counts = new uint64_t*[threads];
|
||||
m_timestamps = new uint64_t*[threads];
|
||||
@@ -62,27 +59,30 @@ Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) :
|
||||
m_timestamps[i] = new uint64_t[kBucketSize]();
|
||||
m_top[i] = 0;
|
||||
}
|
||||
|
||||
const int printTime = controller->config()->printTime();
|
||||
|
||||
if (printTime > 0) {
|
||||
m_timer = new uv_timer_t;
|
||||
uv_timer_init(uv_default_loop(), m_timer);
|
||||
m_timer->data = this;
|
||||
|
||||
uv_timer_start(m_timer, Hashrate::onReport, (printTime + 4) * 1000, printTime * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double Hashrate::calc(size_t ms) const
|
||||
xmrig::Hashrate::~Hashrate()
|
||||
{
|
||||
for (size_t i = 0; i < m_threads; i++) {
|
||||
delete [] m_counts[i];
|
||||
delete [] m_timestamps[i];
|
||||
}
|
||||
|
||||
delete [] m_counts;
|
||||
delete [] m_timestamps;
|
||||
delete [] m_top;
|
||||
}
|
||||
|
||||
|
||||
double xmrig::Hashrate::calc(size_t ms) const
|
||||
{
|
||||
double result = 0.0;
|
||||
double data;
|
||||
|
||||
for (size_t i = 0; i < m_threads; ++i) {
|
||||
data = calc(i, ms);
|
||||
if (isnormal(data)) {
|
||||
if (std::isnormal(data)) {
|
||||
result += data;
|
||||
}
|
||||
}
|
||||
@@ -91,16 +91,13 @@ double Hashrate::calc(size_t ms) const
|
||||
}
|
||||
|
||||
|
||||
double Hashrate::calc(size_t threadId, size_t ms) const
|
||||
double xmrig::Hashrate::calc(size_t threadId, size_t ms) const
|
||||
{
|
||||
assert(threadId < m_threads);
|
||||
if (threadId >= m_threads) {
|
||||
return nan("");
|
||||
}
|
||||
|
||||
using namespace std::chrono;
|
||||
const uint64_t now = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
|
||||
|
||||
uint64_t earliestHashCount = 0;
|
||||
uint64_t earliestStamp = 0;
|
||||
uint64_t lastestStamp = 0;
|
||||
@@ -119,7 +116,7 @@ double Hashrate::calc(size_t threadId, size_t ms) const
|
||||
lastestHashCnt = m_counts[threadId][idx];
|
||||
}
|
||||
|
||||
if (now - m_timestamps[threadId][idx] > ms) {
|
||||
if (xmrig::Chrono::highResolutionMSecs() - m_timestamps[threadId][idx] > ms) {
|
||||
haveFullSet = true;
|
||||
break;
|
||||
}
|
||||
@@ -136,16 +133,14 @@ double Hashrate::calc(size_t threadId, size_t ms) const
|
||||
return nan("");
|
||||
}
|
||||
|
||||
double hashes, time;
|
||||
hashes = (double) lastestHashCnt - earliestHashCount;
|
||||
time = (double) lastestStamp - earliestStamp;
|
||||
time /= 1000.0;
|
||||
const double hashes = static_cast<double>(lastestHashCnt - earliestHashCount);
|
||||
const double time = static_cast<double>(lastestStamp - earliestStamp) / 1000.0;
|
||||
|
||||
return hashes / time;
|
||||
}
|
||||
|
||||
|
||||
void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp)
|
||||
void xmrig::Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp)
|
||||
{
|
||||
const size_t top = m_top[threadId];
|
||||
m_counts[threadId][top] = count;
|
||||
@@ -155,45 +150,28 @@ void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp)
|
||||
}
|
||||
|
||||
|
||||
void Hashrate::print() const
|
||||
{
|
||||
char num1[8] = { 0 };
|
||||
char num2[8] = { 0 };
|
||||
char num3[8] = { 0 };
|
||||
char num4[8] = { 0 };
|
||||
|
||||
LOG_INFO(WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("H/s") " max " CYAN_BOLD("%s H/s"),
|
||||
format(calc(ShortInterval), num1, sizeof(num1)),
|
||||
format(calc(MediumInterval), num2, sizeof(num2)),
|
||||
format(calc(LargeInterval), num3, sizeof(num3)),
|
||||
format(m_highest, num4, sizeof(num4))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void Hashrate::stop()
|
||||
{
|
||||
xmrig::Handle::close(m_timer);
|
||||
m_timer = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void Hashrate::updateHighest()
|
||||
void xmrig::Hashrate::updateHighest()
|
||||
{
|
||||
double highest = calc(ShortInterval);
|
||||
if (isnormal(highest) && highest > m_highest) {
|
||||
if (std::isnormal(highest) && highest > m_highest) {
|
||||
m_highest = highest;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *Hashrate::format(double h, char *buf, size_t size)
|
||||
const char *xmrig::Hashrate::format(double h, char *buf, size_t size)
|
||||
{
|
||||
return ::format(h, buf, size);
|
||||
}
|
||||
|
||||
|
||||
void Hashrate::onReport(uv_timer_t *handle)
|
||||
rapidjson::Value xmrig::Hashrate::normalize(double d)
|
||||
{
|
||||
static_cast<Hashrate*>(handle->data)->print();
|
||||
using namespace rapidjson;
|
||||
|
||||
if (!std::isnormal(d)) {
|
||||
return Value(kNullType);
|
||||
}
|
||||
|
||||
return Value(floor(d * 100.0) / 100.0);
|
||||
}
|
||||
@@ -26,13 +26,14 @@
|
||||
#define XMRIG_HASHRATE_H
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
|
||||
class Hashrate
|
||||
@@ -44,22 +45,20 @@ public:
|
||||
LargeInterval = 900000
|
||||
};
|
||||
|
||||
Hashrate(size_t threads, xmrig::Controller *controller);
|
||||
Hashrate(size_t threads);
|
||||
~Hashrate();
|
||||
double calc(size_t ms) const;
|
||||
double calc(size_t threadId, size_t ms) const;
|
||||
void add(size_t threadId, uint64_t count, uint64_t timestamp);
|
||||
void print() const;
|
||||
void stop();
|
||||
void updateHighest();
|
||||
|
||||
inline double highest() const { return m_highest; }
|
||||
inline size_t threads() const { return m_threads; }
|
||||
|
||||
static const char *format(double h, char *buf, size_t size);
|
||||
static rapidjson::Value normalize(double d);
|
||||
|
||||
private:
|
||||
static void onReport(uv_timer_t *handle);
|
||||
|
||||
constexpr static size_t kBucketSize = 2 << 11;
|
||||
constexpr static size_t kBucketMask = kBucketSize - 1;
|
||||
|
||||
@@ -68,8 +67,10 @@ private:
|
||||
uint32_t* m_top;
|
||||
uint64_t** m_counts;
|
||||
uint64_t** m_timestamps;
|
||||
uv_timer_t *m_timer;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_HASHRATE_H */
|
||||
67
src/backend/common/Thread.h
Normal file
67
src/backend/common/Thread.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_THREAD_H
|
||||
#define XMRIG_THREAD_H
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "backend/common/interfaces/IWorker.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IBackend;
|
||||
|
||||
|
||||
template<class T>
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
inline Thread(IBackend *backend, size_t index, const T &config) : m_index(index), m_config(config), m_backend(backend) {}
|
||||
inline ~Thread() { uv_thread_join(&m_thread); delete m_worker; }
|
||||
|
||||
inline const T &config() const { return m_config; }
|
||||
inline IBackend *backend() const { return m_backend; }
|
||||
inline IWorker *worker() const { return m_worker; }
|
||||
inline size_t index() const { return m_index; }
|
||||
inline void setWorker(IWorker *worker) { m_worker = worker; }
|
||||
inline void start(void (*callback) (void *)) { uv_thread_create(&m_thread, callback, this); }
|
||||
|
||||
private:
|
||||
const size_t m_index = 0;
|
||||
const T m_config;
|
||||
IBackend *m_backend;
|
||||
IWorker *m_worker = nullptr;
|
||||
uv_thread_t m_thread;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_THREAD_H */
|
||||
164
src/backend/common/Threads.cpp
Normal file
164
src/backend/common/Threads.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 "backend/common/Threads.h"
|
||||
#include "backend/cpu/CpuThread.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static const char *kAsterisk = "*";
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
template <class T>
|
||||
const std::vector<T> &xmrig::Threads<T>::get(const String &profileName) const
|
||||
{
|
||||
static std::vector<T> empty;
|
||||
if (profileName.isNull() || !has(profileName)) {
|
||||
return empty;
|
||||
}
|
||||
|
||||
return m_profiles.at(profileName);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
size_t xmrig::Threads<T>::read(const rapidjson::Value &value)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
for (auto &member : value.GetObject()) {
|
||||
if (member.value.IsArray()) {
|
||||
std::vector<T> threads;
|
||||
|
||||
for (auto &v : member.value.GetArray()) {
|
||||
T thread(v);
|
||||
if (thread.isValid()) {
|
||||
threads.push_back(std::move(thread));
|
||||
}
|
||||
}
|
||||
|
||||
if (!threads.empty()) {
|
||||
move(member.name.GetString(), std::move(threads));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const Algorithm algo(member.name.GetString());
|
||||
if (!algo.isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (member.value.IsBool() && member.value.IsFalse()) {
|
||||
disable(algo);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (member.value.IsString()) {
|
||||
if (has(member.value.GetString())) {
|
||||
m_aliases.insert({ algo, member.value.GetString() });
|
||||
}
|
||||
else {
|
||||
m_disabled.insert(algo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_profiles.size();
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
xmrig::String xmrig::Threads<T>::profileName(const Algorithm &algorithm, bool strict) const
|
||||
{
|
||||
if (isDisabled(algorithm)) {
|
||||
return String();
|
||||
}
|
||||
|
||||
const String name = algorithm.shortName();
|
||||
if (has(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
if (m_aliases.count(algorithm) > 0) {
|
||||
return m_aliases.at(algorithm);
|
||||
}
|
||||
|
||||
if (strict) {
|
||||
return String();
|
||||
}
|
||||
|
||||
if (name.contains("/")) {
|
||||
const String base = name.split('/').at(0);
|
||||
if (has(base)) {
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
if (has(kAsterisk)) {
|
||||
return kAsterisk;
|
||||
}
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void xmrig::Threads<T>::toJSON(rapidjson::Value &out, rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
for (const auto &kv : m_profiles) {
|
||||
Value arr(kArrayType);
|
||||
|
||||
for (const T &thread : kv.second) {
|
||||
arr.PushBack(thread.toJSON(doc), allocator);
|
||||
}
|
||||
|
||||
out.AddMember(kv.first.toJSON(), arr, allocator);
|
||||
}
|
||||
|
||||
for (const Algorithm &algo : m_disabled) {
|
||||
out.AddMember(StringRef(algo.shortName()), false, allocator);
|
||||
}
|
||||
|
||||
for (const auto &kv : m_aliases) {
|
||||
out.AddMember(StringRef(kv.first.shortName()), kv.second.toJSON(), allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
template class Threads<CpuThread>;
|
||||
|
||||
} // namespace xmrig
|
||||
67
src/backend/common/Threads.h
Normal file
67
src/backend/common/Threads.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_THREADS_H
|
||||
#define XMRIG_THREADS_H
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
#include "crypto/common/Algorithm.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
template <class T>
|
||||
class Threads
|
||||
{
|
||||
public:
|
||||
inline bool has(const char *profile) const { return m_profiles.count(profile) > 0; }
|
||||
inline bool isDisabled(const Algorithm &algo) const { return m_disabled.count(algo) > 0; }
|
||||
inline bool isExist(const Algorithm &algo) const { return isDisabled(algo) || m_aliases.count(algo) > 0 || has(algo.shortName()); }
|
||||
inline const std::vector<T> &get(const Algorithm &algo, bool strict = false) const { return get(profileName(algo, strict)); }
|
||||
inline void disable(const Algorithm &algo) { m_disabled.insert(algo); }
|
||||
inline void move(const char *profile, std::vector<T> &&threads) { m_profiles.insert({ profile, threads }); }
|
||||
|
||||
const std::vector<T> &get(const String &profileName) const;
|
||||
size_t read(const rapidjson::Value &value);
|
||||
String profileName(const Algorithm &algorithm, bool strict = false) const;
|
||||
void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const;
|
||||
|
||||
private:
|
||||
std::map<Algorithm, String> m_aliases;
|
||||
std::map<String, std::vector<T> > m_profiles;
|
||||
std::set<Algorithm> m_disabled;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_THREADS_H */
|
||||
47
src/backend/common/Worker.cpp
Normal file
47
src/backend/common/Worker.cpp
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 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 "backend/common/Worker.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
|
||||
|
||||
xmrig::Worker::Worker(size_t id, int64_t affinity, int priority) :
|
||||
m_id(id),
|
||||
m_hashCount(0),
|
||||
m_timestamp(0),
|
||||
m_count(0)
|
||||
{
|
||||
Platform::trySetThreadAffinity(affinity);
|
||||
Platform::setThreadPriority(priority);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Worker::storeStats()
|
||||
{
|
||||
m_hashCount.store(m_count, std::memory_order_relaxed);
|
||||
m_timestamp.store(Chrono::highResolutionMSecs(), std::memory_order_relaxed);
|
||||
}
|
||||
@@ -5,7 +5,9 @@
|
||||
* 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>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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,24 +31,18 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "interfaces/IWorker.h"
|
||||
#include "Mem.h"
|
||||
|
||||
|
||||
class ThreadHandle;
|
||||
#include "backend/common/interfaces/IWorker.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class CpuThread;
|
||||
}
|
||||
|
||||
|
||||
class Worker : public IWorker
|
||||
{
|
||||
public:
|
||||
Worker(ThreadHandle *handle);
|
||||
Worker(size_t id, int64_t affinity, int priority);
|
||||
|
||||
inline const MemInfo &memory() const { return m_memory; }
|
||||
inline const VirtualMemory *memory() const override { return nullptr; }
|
||||
inline size_t id() const override { return m_id; }
|
||||
inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); }
|
||||
inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); }
|
||||
@@ -55,15 +51,13 @@ protected:
|
||||
void storeStats();
|
||||
|
||||
const size_t m_id;
|
||||
const size_t m_totalWays;
|
||||
const uint32_t m_offset;
|
||||
MemInfo m_memory;
|
||||
std::atomic<uint64_t> m_hashCount;
|
||||
std::atomic<uint64_t> m_timestamp;
|
||||
uint64_t m_count;
|
||||
uint64_t m_sequence;
|
||||
xmrig::CpuThread *m_thread;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_WORKER_H */
|
||||
142
src/backend/common/WorkerJob.h
Normal file
142
src/backend/common/WorkerJob.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_WORKERJOB_H
|
||||
#define XMRIG_WORKERJOB_H
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "base/net/stratum/Job.h"
|
||||
#include "crypto/common/Nonce.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
template<size_t N>
|
||||
class WorkerJob
|
||||
{
|
||||
public:
|
||||
inline const Job ¤tJob() const { return m_jobs[index()]; }
|
||||
inline uint32_t *nonce(size_t i = 0) { return reinterpret_cast<uint32_t*>(blob() + (i * currentJob().size()) + 39); }
|
||||
inline uint64_t sequence() const { return m_sequence; }
|
||||
inline uint8_t *blob() { return m_blobs[index()]; }
|
||||
inline uint8_t index() const { return m_index; }
|
||||
|
||||
|
||||
inline void add(const Job &job, uint64_t sequence, uint32_t reserveCount)
|
||||
{
|
||||
m_sequence = sequence;
|
||||
|
||||
if (currentJob() == job) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (index() == 1 && job.index() == 0 && job == m_jobs[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
save(job, reserveCount);
|
||||
}
|
||||
|
||||
|
||||
inline void nextRound(uint32_t reserveCount)
|
||||
{
|
||||
m_rounds[index()]++;
|
||||
|
||||
if ((m_rounds[index()] % reserveCount) == 0) {
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
*nonce(i) = Nonce::next(index(), *nonce(i), reserveCount, currentJob().isNicehash());
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
*nonce(i) += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
inline void save(const Job &job, uint32_t reserveCount)
|
||||
{
|
||||
m_index = job.index();
|
||||
const size_t size = job.size();
|
||||
m_jobs[index()] = job;
|
||||
m_rounds[index()] = 0;
|
||||
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
memcpy(m_blobs[index()] + (i * size), job.blob(), size);
|
||||
*nonce(i) = Nonce::next(index(), *nonce(i), reserveCount, job.isNicehash());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
alignas(16) uint8_t m_blobs[2][Job::kMaxBlobSize * N];
|
||||
Job m_jobs[2];
|
||||
uint32_t m_rounds[2] = { 0, 0 };
|
||||
uint64_t m_sequence = 0;
|
||||
uint8_t m_index = 0;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
inline uint32_t *xmrig::WorkerJob<1>::nonce(size_t)
|
||||
{
|
||||
return reinterpret_cast<uint32_t*>(blob() + 39);
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
inline void xmrig::WorkerJob<1>::nextRound(uint32_t reserveCount)
|
||||
{
|
||||
m_rounds[index()]++;
|
||||
|
||||
if ((m_rounds[index()] % reserveCount) == 0) {
|
||||
*nonce() = Nonce::next(index(), *nonce(), reserveCount, currentJob().isNicehash());
|
||||
}
|
||||
else {
|
||||
*nonce() += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
inline void xmrig::WorkerJob<1>::save(const Job &job, uint32_t reserveCount)
|
||||
{
|
||||
m_index = job.index();
|
||||
m_jobs[index()] = job;
|
||||
m_rounds[index()] = 0;
|
||||
|
||||
memcpy(blob(), job.blob(), job.size());
|
||||
*nonce() = Nonce::next(index(), *nonce(), reserveCount, currentJob().isNicehash());
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_WORKERJOB_H */
|
||||
224
src/backend/common/Workers.cpp
Normal file
224
src/backend/common/Workers.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 "backend/common/Hashrate.h"
|
||||
#include "backend/common/interfaces/IBackend.h"
|
||||
#include "backend/common/Workers.h"
|
||||
#include "backend/cpu/CpuWorker.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class WorkersPrivate
|
||||
{
|
||||
public:
|
||||
inline WorkersPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline ~WorkersPrivate()
|
||||
{
|
||||
delete hashrate;
|
||||
}
|
||||
|
||||
|
||||
Hashrate *hashrate = nullptr;
|
||||
IBackend *backend = nullptr;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
template<class T>
|
||||
xmrig::Workers<T>::Workers() :
|
||||
d_ptr(new WorkersPrivate())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
xmrig::Workers<T>::~Workers()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
const xmrig::Hashrate *xmrig::Workers<T>::hashrate() const
|
||||
{
|
||||
return d_ptr->hashrate;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void xmrig::Workers<T>::setBackend(IBackend *backend)
|
||||
{
|
||||
d_ptr->backend = backend;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void xmrig::Workers<T>::start(const std::vector<T> &data)
|
||||
{
|
||||
for (const T &item : data) {
|
||||
m_workers.push_back(new Thread<T>(d_ptr->backend, m_workers.size(), item));
|
||||
}
|
||||
|
||||
d_ptr->hashrate = new Hashrate(m_workers.size());
|
||||
|
||||
for (Thread<T> *worker : m_workers) {
|
||||
worker->start(Workers<T>::onReady);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void xmrig::Workers<T>::stop()
|
||||
{
|
||||
Nonce::stop(T::backend());
|
||||
|
||||
for (Thread<T> *worker : m_workers) {
|
||||
delete worker;
|
||||
}
|
||||
|
||||
m_workers.clear();
|
||||
Nonce::touch(T::backend());
|
||||
|
||||
delete d_ptr->hashrate;
|
||||
d_ptr->hashrate = nullptr;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void xmrig::Workers<T>::tick(uint64_t)
|
||||
{
|
||||
if (!d_ptr->hashrate) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Thread<T> *handle : m_workers) {
|
||||
if (!handle->worker()) {
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->hashrate->add(handle->index(), handle->worker()->hashCount(), handle->worker()->timestamp());
|
||||
}
|
||||
|
||||
d_ptr->hashrate->updateHighest();
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
xmrig::IWorker *xmrig::Workers<T>::create(Thread<CpuLaunchData> *)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void xmrig::Workers<T>::onReady(void *arg)
|
||||
{
|
||||
Thread<T> *handle = static_cast<Thread<T>* >(arg);
|
||||
|
||||
IWorker *worker = create(handle);
|
||||
if (!worker || !worker->selfTest()) {
|
||||
LOG_ERR("thread %zu error: \"hash self-test failed\".", worker->id());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
handle->setWorker(worker);
|
||||
handle->backend()->start(worker);
|
||||
}
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
#if defined (XMRIG_ALGO_RANDOMX) || defined (XMRIG_ALGO_CN_GPU)
|
||||
static void printIntensityWarning(Thread<CpuLaunchData> *handle)
|
||||
{
|
||||
LOG_WARN("CPU thread %zu warning: \"intensity %d not supported for %s algorithm\".", handle->index(), handle->config().intensity, handle->config().algorithm.shortName());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
template<>
|
||||
xmrig::IWorker *xmrig::Workers<CpuLaunchData>::create(Thread<CpuLaunchData> *handle)
|
||||
{
|
||||
const int intensity = handle->config().intensity;
|
||||
|
||||
# if defined (XMRIG_ALGO_RANDOMX) || defined (XMRIG_ALGO_CN_GPU)
|
||||
if (intensity > 1) {
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
if (handle->config().algorithm.family() == Algorithm::RANDOM_X) {
|
||||
printIntensityWarning(handle);
|
||||
|
||||
return new CpuWorker<1>(handle->index(), handle->config());
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_GPU
|
||||
if (handle->config().algorithm == Algorithm::CN_GPU) {
|
||||
printIntensityWarning(handle);
|
||||
|
||||
return new CpuWorker<1>(handle->index(), handle->config());
|
||||
}
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
switch (intensity) {
|
||||
case 1:
|
||||
return new CpuWorker<1>(handle->index(), handle->config());
|
||||
|
||||
case 2:
|
||||
return new CpuWorker<2>(handle->index(), handle->config());
|
||||
|
||||
case 3:
|
||||
return new CpuWorker<3>(handle->index(), handle->config());
|
||||
|
||||
case 4:
|
||||
return new CpuWorker<4>(handle->index(), handle->config());
|
||||
|
||||
case 5:
|
||||
return new CpuWorker<5>(handle->index(), handle->config());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
template class Workers<CpuLaunchData>;
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
73
src/backend/common/Workers.h
Normal file
73
src/backend/common/Workers.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_WORKERS_H
|
||||
#define XMRIG_WORKERS_H
|
||||
|
||||
|
||||
#include "backend/common/Thread.h"
|
||||
#include "backend/cpu/CpuLaunchData.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Hashrate;
|
||||
class WorkersPrivate;
|
||||
|
||||
|
||||
template<class T>
|
||||
class Workers
|
||||
{
|
||||
public:
|
||||
Workers();
|
||||
~Workers();
|
||||
|
||||
const Hashrate *hashrate() const;
|
||||
void setBackend(IBackend *backend);
|
||||
void start(const std::vector<T> &data);
|
||||
void stop();
|
||||
void tick(uint64_t ticks);
|
||||
|
||||
private:
|
||||
static IWorker *create(Thread<CpuLaunchData> *handle);
|
||||
static void onReady(void *arg);
|
||||
|
||||
std::vector<Thread<T> *> m_workers;
|
||||
WorkersPrivate *d_ptr;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
IWorker *Workers<CpuLaunchData>::create(Thread<CpuLaunchData> *handle);
|
||||
|
||||
|
||||
extern template class Workers<CpuLaunchData>;
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_WORKERS_H */
|
||||
18
src/backend/common/common.cmake
Normal file
18
src/backend/common/common.cmake
Normal file
@@ -0,0 +1,18 @@
|
||||
set(HEADERS_BACKEND_COMMON
|
||||
src/backend/common/interfaces/IBackend.h
|
||||
src/backend/common/interfaces/IThread.h
|
||||
src/backend/common/interfaces/IWorker.h
|
||||
src/backend/common/Hashrate.h
|
||||
src/backend/common/Thread.h
|
||||
src/backend/common/Threads.h
|
||||
src/backend/common/Worker.h
|
||||
src/backend/common/Workers.h
|
||||
src/backend/common/WorkerJob.h
|
||||
)
|
||||
|
||||
set(SOURCES_BACKEND_COMMON
|
||||
src/backend/common/Hashrate.cpp
|
||||
src/backend/common/Threads.cpp
|
||||
src/backend/common/Worker.cpp
|
||||
src/backend/common/Workers.cpp
|
||||
)
|
||||
70
src/backend/common/interfaces/IBackend.h
Normal file
70
src/backend/common/interfaces/IBackend.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_IBACKEND_H
|
||||
#define XMRIG_IBACKEND_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Algorithm;
|
||||
class Hashrate;
|
||||
class IWorker;
|
||||
class Job;
|
||||
class String;
|
||||
|
||||
|
||||
class IBackend
|
||||
{
|
||||
public:
|
||||
virtual ~IBackend() = default;
|
||||
|
||||
virtual bool isEnabled() const = 0;
|
||||
virtual bool isEnabled(const Algorithm &algorithm) const = 0;
|
||||
virtual const Hashrate *hashrate() const = 0;
|
||||
virtual const String &profileName() const = 0;
|
||||
virtual const String &type() const = 0;
|
||||
virtual void printHashrate(bool details) = 0;
|
||||
virtual void setJob(const Job &job) = 0;
|
||||
virtual void start(IWorker *worker) = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void tick(uint64_t ticks) = 0;
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
virtual rapidjson::Value toJSON(rapidjson::Document &doc) const = 0;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_IBACKEND_H
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "common/xmrig.h"
|
||||
#include "crypto/common/Algorithm.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
|
||||
virtual ~IThread() = default;
|
||||
|
||||
virtual Algo algorithm() const = 0;
|
||||
virtual Algorithm algorithm() const = 0;
|
||||
virtual int priority() const = 0;
|
||||
virtual int64_t affinity() const = 0;
|
||||
virtual Multiway multiway() const = 0;
|
||||
@@ -27,6 +27,13 @@
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class VirtualMemory;
|
||||
|
||||
|
||||
class IWorker
|
||||
@@ -35,6 +42,7 @@ public:
|
||||
virtual ~IWorker() = default;
|
||||
|
||||
virtual bool selfTest() = 0;
|
||||
virtual const VirtualMemory *memory() const = 0;
|
||||
virtual size_t id() const = 0;
|
||||
virtual uint64_t hashCount() const = 0;
|
||||
virtual uint64_t timestamp() const = 0;
|
||||
@@ -42,4 +50,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_IWORKER_H
|
||||
@@ -4,8 +4,9 @@
|
||||
* 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 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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,11 +26,13 @@
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "common/cpu/Cpu.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_LIBCPUID
|
||||
# include "core/cpu/AdvancedCpuInfo.h"
|
||||
#ifdef XMRIG_FEATURE_LIBCPUID
|
||||
# include "backend/cpu/platform/AdvancedCpuInfo.h"
|
||||
#else
|
||||
# include "backend/cpu/platform/BasicCpuInfo.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -48,7 +51,11 @@ void xmrig::Cpu::init()
|
||||
{
|
||||
assert(cpuInfo == nullptr);
|
||||
|
||||
# ifdef XMRIG_FEATURE_LIBCPUID
|
||||
cpuInfo = new AdvancedCpuInfo();
|
||||
# else
|
||||
cpuInfo = new BasicCpuInfo();
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
* 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>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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,7 +26,7 @@
|
||||
#define XMRIG_CPU_H
|
||||
|
||||
|
||||
#include "common/interfaces/ICpuInfo.h"
|
||||
#include "backend/cpu/interfaces/ICpuInfo.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -37,6 +38,8 @@ public:
|
||||
static ICpuInfo *info();
|
||||
static void init();
|
||||
static void release();
|
||||
|
||||
inline static Assembly::Id assembly(Assembly::Id hint) { return hint == Assembly::AUTO ? Cpu::info()->assembly() : hint; }
|
||||
};
|
||||
|
||||
|
||||
343
src/backend/cpu/CpuBackend.cpp
Normal file
343
src/backend/cpu/CpuBackend.cpp
Normal file
@@ -0,0 +1,343 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 <uv.h>
|
||||
|
||||
|
||||
#include "backend/common/Hashrate.h"
|
||||
#include "backend/common/interfaces/IWorker.h"
|
||||
#include "backend/common/Workers.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "backend/cpu/CpuBackend.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/Job.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "base/tools/String.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "crypto/rx/Rx.h"
|
||||
#include "crypto/rx/RxDataset.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
extern template class Threads<CpuThread>;
|
||||
|
||||
|
||||
static const String kType = "cpu";
|
||||
|
||||
|
||||
struct LaunchStatus
|
||||
{
|
||||
public:
|
||||
inline void reset()
|
||||
{
|
||||
hugePages = 0;
|
||||
memory = 0;
|
||||
pages = 0;
|
||||
started = 0;
|
||||
threads = 0;
|
||||
ways = 0;
|
||||
ts = Chrono::steadyMSecs();
|
||||
}
|
||||
|
||||
size_t hugePages = 0;
|
||||
size_t memory = 0;
|
||||
size_t pages = 0;
|
||||
size_t started = 0;
|
||||
size_t threads = 0;
|
||||
size_t ways = 0;
|
||||
uint64_t ts = 0;
|
||||
};
|
||||
|
||||
|
||||
class CpuBackendPrivate
|
||||
{
|
||||
public:
|
||||
inline CpuBackendPrivate(Controller *controller) :
|
||||
controller(controller)
|
||||
{
|
||||
uv_mutex_init(&mutex);
|
||||
}
|
||||
|
||||
|
||||
inline ~CpuBackendPrivate()
|
||||
{
|
||||
uv_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
|
||||
inline void start()
|
||||
{
|
||||
LOG_INFO(GREEN_BOLD("CPU") " use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"),
|
||||
profileName.data(),
|
||||
threads.size(),
|
||||
algo.memory() / 1024
|
||||
);
|
||||
|
||||
workers.stop();
|
||||
|
||||
status.reset();
|
||||
status.memory = algo.memory();
|
||||
status.threads = threads.size();
|
||||
|
||||
for (const CpuLaunchData &data : threads) {
|
||||
status.ways += static_cast<size_t>(data.intensity);
|
||||
}
|
||||
|
||||
workers.start(threads);
|
||||
}
|
||||
|
||||
|
||||
Algorithm algo;
|
||||
Controller *controller;
|
||||
LaunchStatus status;
|
||||
std::vector<CpuLaunchData> threads;
|
||||
String profileName;
|
||||
uv_mutex_t mutex;
|
||||
Workers<CpuLaunchData> workers;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::CpuBackend::CpuBackend(Controller *controller) :
|
||||
d_ptr(new CpuBackendPrivate(controller))
|
||||
{
|
||||
d_ptr->workers.setBackend(this);
|
||||
}
|
||||
|
||||
|
||||
xmrig::CpuBackend::~CpuBackend()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CpuBackend::isEnabled() const
|
||||
{
|
||||
return d_ptr->controller->config()->cpu().isEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CpuBackend::isEnabled(const Algorithm &algorithm) const
|
||||
{
|
||||
return !d_ptr->controller->config()->cpu().threads().get(algorithm).empty();
|
||||
}
|
||||
|
||||
|
||||
const xmrig::Hashrate *xmrig::CpuBackend::hashrate() const
|
||||
{
|
||||
return d_ptr->workers.hashrate();
|
||||
}
|
||||
|
||||
|
||||
const xmrig::String &xmrig::CpuBackend::profileName() const
|
||||
{
|
||||
return d_ptr->profileName;
|
||||
}
|
||||
|
||||
|
||||
const xmrig::String &xmrig::CpuBackend::type() const
|
||||
{
|
||||
return kType;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuBackend::printHashrate(bool details)
|
||||
{
|
||||
if (!details || !hashrate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
char num[8 * 3] = { 0 };
|
||||
|
||||
Log::print(WHITE_BOLD_S "| CPU THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |");
|
||||
|
||||
size_t i = 0;
|
||||
for (const CpuLaunchData &data : d_ptr->threads) {
|
||||
Log::print("| %13zu | %8" PRId64 " | %7s | %7s | %7s |",
|
||||
i,
|
||||
data.affinity,
|
||||
Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3),
|
||||
Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, sizeof num / 3),
|
||||
Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3)
|
||||
);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuBackend::setJob(const Job &job)
|
||||
{
|
||||
if (!isEnabled()) {
|
||||
d_ptr->workers.stop();
|
||||
d_ptr->threads.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const CpuConfig &cpu = d_ptr->controller->config()->cpu();
|
||||
|
||||
std::vector<CpuLaunchData> threads = cpu.get(d_ptr->controller->miner(), job.algorithm());
|
||||
if (d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) {
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->algo = job.algorithm();
|
||||
d_ptr->profileName = cpu.threads().profileName(job.algorithm());
|
||||
|
||||
if (d_ptr->profileName.isNull() || threads.empty()) {
|
||||
d_ptr->workers.stop();
|
||||
|
||||
LOG_WARN(YELLOW_BOLD_S "CPU disabled, no suitable configuration for algo %s", job.algorithm().shortName());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->threads = std::move(threads);
|
||||
d_ptr->start();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuBackend::start(IWorker *worker)
|
||||
{
|
||||
uv_mutex_lock(&d_ptr->mutex);
|
||||
|
||||
const auto pages = worker->memory()->hugePages();
|
||||
|
||||
d_ptr->status.started++;
|
||||
d_ptr->status.hugePages += pages.first;
|
||||
d_ptr->status.pages += pages.second;
|
||||
|
||||
if (d_ptr->status.started == d_ptr->status.threads) {
|
||||
const double percent = d_ptr->status.hugePages == 0 ? 0.0 : static_cast<double>(d_ptr->status.hugePages) / d_ptr->status.pages * 100.0;
|
||||
const size_t memory = d_ptr->status.ways * d_ptr->status.memory / 1024;
|
||||
|
||||
LOG_INFO(GREEN_BOLD("CPU READY") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"),
|
||||
d_ptr->status.threads, d_ptr->status.ways,
|
||||
(d_ptr->status.hugePages == d_ptr->status.pages ? GREEN_BOLD_S : (d_ptr->status.hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)),
|
||||
d_ptr->status.hugePages, d_ptr->status.pages, percent, memory,
|
||||
Chrono::steadyMSecs() - d_ptr->status.ts
|
||||
);
|
||||
}
|
||||
|
||||
uv_mutex_unlock(&d_ptr->mutex);
|
||||
|
||||
worker->start();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuBackend::stop()
|
||||
{
|
||||
d_ptr->workers.stop();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuBackend::tick(uint64_t ticks)
|
||||
{
|
||||
d_ptr->workers.tick(ticks);
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
rapidjson::Value xmrig::CpuBackend::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
const CpuConfig &cpu = d_ptr->controller->config()->cpu();
|
||||
|
||||
Value out(kObjectType);
|
||||
out.AddMember("type", type().toJSON(), allocator);
|
||||
out.AddMember("enabled", isEnabled(), allocator);
|
||||
out.AddMember("algo", d_ptr->algo.toJSON(), allocator);
|
||||
out.AddMember("profile", profileName().toJSON(), allocator);
|
||||
out.AddMember("hw-aes", cpu.isHwAES(), allocator);
|
||||
out.AddMember("priority", cpu.priority(), allocator);
|
||||
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
const Assembly assembly = Cpu::assembly(cpu.assembly());
|
||||
out.AddMember("asm", assembly.toJSON(), allocator);
|
||||
# else
|
||||
out.AddMember("asm", false, allocator);
|
||||
# endif
|
||||
|
||||
uv_mutex_lock(&d_ptr->mutex);
|
||||
uint64_t pages[2] = { d_ptr->status.hugePages, d_ptr->status.pages };
|
||||
const size_t ways = d_ptr->status.ways;
|
||||
uv_mutex_unlock(&d_ptr->mutex);
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
if (d_ptr->algo.family() == Algorithm::RANDOM_X) {
|
||||
RxDataset *dataset = Rx::dataset();
|
||||
if (dataset) {
|
||||
const auto rxPages = dataset->hugePages();
|
||||
pages[0] += rxPages.first;
|
||||
pages[1] += rxPages.second;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
rapidjson::Value hugepages(rapidjson::kArrayType);
|
||||
hugepages.PushBack(pages[0], allocator);
|
||||
hugepages.PushBack(pages[1], allocator);
|
||||
|
||||
out.AddMember("hugepages", hugepages, allocator);
|
||||
out.AddMember("memory", static_cast<uint64_t>(d_ptr->algo.isValid() ? (ways * d_ptr->algo.memory()) : 0), allocator);
|
||||
|
||||
if (d_ptr->threads.empty() || !hashrate()) {
|
||||
return out;
|
||||
}
|
||||
|
||||
Value threads(kArrayType);
|
||||
const Hashrate *hr = hashrate();
|
||||
|
||||
size_t i = 0;
|
||||
for (const CpuLaunchData &data : d_ptr->threads) {
|
||||
Value thread(kObjectType);
|
||||
thread.AddMember("intensity", data.intensity, allocator);
|
||||
thread.AddMember("affinity", data.affinity, allocator);
|
||||
thread.AddMember("av", data.av(), allocator);
|
||||
|
||||
Value hashrate(kArrayType);
|
||||
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
||||
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
||||
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
|
||||
|
||||
i++;
|
||||
|
||||
thread.AddMember("hashrate", hashrate, allocator);
|
||||
threads.PushBack(thread, allocator);
|
||||
}
|
||||
|
||||
out.AddMember("threads", threads, allocator);
|
||||
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
70
src/backend/cpu/CpuBackend.h
Normal file
70
src/backend/cpu/CpuBackend.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_CPUBACKEND_H
|
||||
#define XMRIG_CPUBACKEND_H
|
||||
|
||||
|
||||
#include "backend/common/interfaces/IBackend.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Controller;
|
||||
class CpuBackendPrivate;
|
||||
class Miner;
|
||||
|
||||
|
||||
class CpuBackend : public IBackend
|
||||
{
|
||||
public:
|
||||
CpuBackend(Controller *controller);
|
||||
~CpuBackend() override;
|
||||
|
||||
protected:
|
||||
bool isEnabled() const override;
|
||||
bool isEnabled(const Algorithm &algorithm) const override;
|
||||
const Hashrate *hashrate() const override;
|
||||
const String &profileName() const override;
|
||||
const String &type() const override;
|
||||
void printHashrate(bool details) override;
|
||||
void setJob(const Job &job) override;
|
||||
void start(IWorker *worker) override;
|
||||
void stop() override;
|
||||
void tick(uint64_t ticks) override;
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
|
||||
# endif
|
||||
|
||||
private:
|
||||
CpuBackendPrivate *d_ptr;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CPUBACKEND_H */
|
||||
187
src/backend/cpu/CpuConfig.cpp
Normal file
187
src/backend/cpu/CpuConfig.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 "backend/cpu/Cpu.h"
|
||||
#include "backend/cpu/CpuConfig.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char *kCn = "cn";
|
||||
static const char *kEnabled = "enabled";
|
||||
static const char *kHugePages = "huge-pages";
|
||||
static const char *kHwAes = "hw-aes";
|
||||
static const char *kPriority = "priority";
|
||||
|
||||
#ifdef XMRIG_FEATURE_ASM
|
||||
static const char *kAsm = "asm";
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_ALGO_CN_GPU
|
||||
static const char *kCnGPU = "cn/gpu";
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_ALGO_CN_LITE
|
||||
static const char *kCnLite = "cn-lite";
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_ALGO_CN_HEAVY
|
||||
static const char *kCnHeavy = "cn-heavy";
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_ALGO_CN_PICO
|
||||
static const char *kCnPico = "cn-pico";
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_ALGO_RANDOMX
|
||||
static const char *kRx = "rx";
|
||||
static const char *kRxWOW = "rx/wow";
|
||||
#endif
|
||||
|
||||
extern template class Threads<CpuThread>;
|
||||
|
||||
}
|
||||
|
||||
|
||||
xmrig::CpuConfig::CpuConfig()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CpuConfig::isHwAES() const
|
||||
{
|
||||
return (m_aes == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aes) == AES_HW;
|
||||
}
|
||||
|
||||
|
||||
rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value obj(kObjectType);
|
||||
|
||||
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
|
||||
obj.AddMember(StringRef(kHugePages), m_hugePages, allocator);
|
||||
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
|
||||
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
|
||||
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
obj.AddMember(StringRef(kAsm), m_assembly.toJSON(), allocator);
|
||||
# endif
|
||||
|
||||
m_threads.toJSON(obj, doc);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const
|
||||
{
|
||||
std::vector<CpuLaunchData> out;
|
||||
const std::vector<CpuThread> &threads = m_threads.get(algorithm);
|
||||
|
||||
if (threads.empty()) {
|
||||
return out;
|
||||
}
|
||||
|
||||
out.reserve(threads.size());
|
||||
|
||||
for (const CpuThread &thread : threads) {
|
||||
out.push_back(CpuLaunchData(miner, algorithm, *this, thread));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuConfig::read(const rapidjson::Value &value)
|
||||
{
|
||||
if (value.IsObject()) {
|
||||
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
||||
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
|
||||
|
||||
setAesMode(Json::getValue(value, kHwAes));
|
||||
setPriority(Json::getInt(value, kPriority, -1));
|
||||
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
m_assembly = Json::getValue(value, kAsm);
|
||||
# endif
|
||||
|
||||
if (!m_threads.read(value)) {
|
||||
generate();
|
||||
}
|
||||
}
|
||||
else if (value.IsBool() && value.IsFalse()) {
|
||||
m_enabled = false;
|
||||
}
|
||||
else {
|
||||
generate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuConfig::generate()
|
||||
{
|
||||
m_shouldSave = true;
|
||||
|
||||
m_threads.disable(Algorithm::CN_0);
|
||||
m_threads.move(kCn, Cpu::info()->threads(Algorithm::CN_0));
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_GPU
|
||||
m_threads.move(kCnGPU, Cpu::info()->threads(Algorithm::CN_GPU));
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_LITE
|
||||
m_threads.disable(Algorithm::CN_LITE_0);
|
||||
m_threads.move(kCnLite, Cpu::info()->threads(Algorithm::CN_LITE_1));
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||
m_threads.move(kCnHeavy, Cpu::info()->threads(Algorithm::CN_HEAVY_0));
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_PICO
|
||||
m_threads.move(kCnPico, Cpu::info()->threads(Algorithm::CN_PICO_0));
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
m_threads.move(kRx, Cpu::info()->threads(Algorithm::RX_0));
|
||||
m_threads.move(kRxWOW, Cpu::info()->threads(Algorithm::RX_WOW));
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuConfig::setAesMode(const rapidjson::Value &aesMode)
|
||||
{
|
||||
if (aesMode.IsBool()) {
|
||||
m_aes = aesMode.GetBool() ? AES_HW : AES_SOFT;
|
||||
}
|
||||
else {
|
||||
m_aes = AES_AUTO;
|
||||
}
|
||||
}
|
||||
80
src/backend/cpu/CpuConfig.h
Normal file
80
src/backend/cpu/CpuConfig.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_CPUCONFIG_H
|
||||
#define XMRIG_CPUCONFIG_H
|
||||
|
||||
|
||||
#include "backend/common/Threads.h"
|
||||
#include "backend/cpu/CpuLaunchData.h"
|
||||
#include "backend/cpu/CpuThread.h"
|
||||
#include "crypto/common/Assembly.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class CpuConfig
|
||||
{
|
||||
public:
|
||||
enum AesMode {
|
||||
AES_AUTO,
|
||||
AES_HW,
|
||||
AES_SOFT
|
||||
};
|
||||
|
||||
CpuConfig();
|
||||
|
||||
bool isHwAES() const;
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
|
||||
void read(const rapidjson::Value &value);
|
||||
|
||||
inline bool isEnabled() const { return m_enabled; }
|
||||
inline bool isHugePages() const { return m_hugePages; }
|
||||
inline bool isShouldSave() const { return m_shouldSave; }
|
||||
inline const Assembly &assembly() const { return m_assembly; }
|
||||
inline const Threads<CpuThread> &threads() const { return m_threads; }
|
||||
inline int priority() const { return m_priority; }
|
||||
|
||||
private:
|
||||
void generate();
|
||||
void setAesMode(const rapidjson::Value &aesMode);
|
||||
|
||||
inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; }
|
||||
|
||||
AesMode m_aes = AES_AUTO;
|
||||
Assembly m_assembly;
|
||||
bool m_enabled = true;
|
||||
bool m_hugePages = true;
|
||||
bool m_shouldSave = false;
|
||||
int m_priority = -1;
|
||||
Threads<CpuThread> m_threads;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CPUCONFIG_H */
|
||||
64
src/backend/cpu/CpuLaunchData.cpp
Normal file
64
src/backend/cpu/CpuLaunchData.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 "backend/cpu/CpuLaunchData.h"
|
||||
#include "backend/cpu/CpuConfig.h"
|
||||
|
||||
|
||||
xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread) :
|
||||
algorithm(algorithm),
|
||||
assembly(config.assembly()),
|
||||
hugePages(config.isHugePages()),
|
||||
hwAES(config.isHwAES()),
|
||||
intensity(thread.intensity()),
|
||||
priority(config.priority()),
|
||||
affinity(thread.affinity()),
|
||||
miner(miner)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CpuLaunchData::isEqual(const CpuLaunchData &other) const
|
||||
{
|
||||
return (algorithm.memory() == other.algorithm.memory()
|
||||
&& assembly == other.assembly
|
||||
&& hugePages == other.hugePages
|
||||
&& hwAES == other.hwAES
|
||||
&& intensity == other.intensity
|
||||
&& priority == other.priority
|
||||
&& affinity == other.affinity
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
xmrig::CnHash::AlgoVariant xmrig::CpuLaunchData::av() const
|
||||
{
|
||||
if (intensity <= 2) {
|
||||
return static_cast<CnHash::AlgoVariant>(!hwAES ? (intensity + 2) : intensity);
|
||||
}
|
||||
|
||||
return static_cast<CnHash::AlgoVariant>(!hwAES ? (intensity + 5) : (intensity + 2));
|
||||
}
|
||||
@@ -23,54 +23,49 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_MULTIWORKER_H
|
||||
#define XMRIG_MULTIWORKER_H
|
||||
#ifndef XMRIG_CPULAUNCHDATA_H
|
||||
#define XMRIG_CPULAUNCHDATA_H
|
||||
|
||||
|
||||
#include "base/net/stratum/Job.h"
|
||||
#include "Mem.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "workers/Worker.h"
|
||||
#include "crypto/cn/CnHash.h"
|
||||
#include "crypto/common/Algorithm.h"
|
||||
#include "crypto/common/Assembly.h"
|
||||
#include "crypto/common/Nonce.h"
|
||||
|
||||
|
||||
class Handle;
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
template<size_t N>
|
||||
class MultiWorker : public Worker
|
||||
class CpuConfig;
|
||||
class CpuThread;
|
||||
class Miner;
|
||||
|
||||
|
||||
class CpuLaunchData
|
||||
{
|
||||
public:
|
||||
MultiWorker(ThreadHandle *handle);
|
||||
~MultiWorker();
|
||||
CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread);
|
||||
|
||||
protected:
|
||||
bool selfTest() override;
|
||||
void start() override;
|
||||
bool isEqual(const CpuLaunchData &other) const;
|
||||
CnHash::AlgoVariant av() const;
|
||||
|
||||
private:
|
||||
bool resume(const xmrig::Job &job);
|
||||
bool verify(xmrig::Variant variant, const uint8_t *referenceValue);
|
||||
bool verify2(xmrig::Variant variant, const uint8_t *referenceValue);
|
||||
void consumeJob();
|
||||
void save(const xmrig::Job &job);
|
||||
inline constexpr static Nonce::Backend backend() { return Nonce::CPU; }
|
||||
|
||||
inline uint32_t *nonce(size_t index)
|
||||
{
|
||||
return reinterpret_cast<uint32_t*>(m_state.blob + (index * m_state.job.size()) + 39);
|
||||
}
|
||||
inline bool operator!=(const CpuLaunchData &other) const { return !isEqual(other); }
|
||||
inline bool operator==(const CpuLaunchData &other) const { return isEqual(other); }
|
||||
|
||||
struct State
|
||||
{
|
||||
alignas(16) uint8_t blob[xmrig::Job::kMaxBlobSize * N];
|
||||
xmrig::Job job;
|
||||
};
|
||||
|
||||
|
||||
cryptonight_ctx *m_ctx[N];
|
||||
State m_pausedState;
|
||||
State m_state;
|
||||
uint8_t m_hash[N * 32];
|
||||
const Algorithm algorithm;
|
||||
const Assembly assembly;
|
||||
const bool hugePages;
|
||||
const bool hwAES;
|
||||
const int intensity;
|
||||
const int priority;
|
||||
const int64_t affinity;
|
||||
const Miner *miner;
|
||||
};
|
||||
|
||||
|
||||
#endif /* XMRIG_MULTIWORKER_H */
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_CPULAUNCHDATA_H */
|
||||
71
src/backend/cpu/CpuThread.cpp
Normal file
71
src/backend/cpu/CpuThread.cpp
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 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 "backend/cpu/CpuThread.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static const char *kAffinity = "affinity";
|
||||
static const char *kIntensity = "intensity";
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
xmrig::CpuThread::CpuThread(const rapidjson::Value &value)
|
||||
{
|
||||
if (value.IsObject()) {
|
||||
m_intensity = Json::getInt(value, kIntensity, -1);
|
||||
m_affinity = Json::getInt(value, kAffinity, -1);
|
||||
}
|
||||
else if (value.IsInt()) {
|
||||
m_intensity = 1;
|
||||
m_affinity = value.GetInt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rapidjson::Value xmrig::CpuThread::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
if (intensity() > 1) {
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value obj(kObjectType);
|
||||
|
||||
obj.AddMember(StringRef(kIntensity), m_intensity, allocator);
|
||||
obj.AddMember(StringRef(kAffinity), m_affinity, allocator);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
return Value(m_affinity);
|
||||
}
|
||||
67
src/backend/cpu/CpuThread.h
Normal file
67
src/backend/cpu/CpuThread.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_CPUTHREADCONFIG_H
|
||||
#define XMRIG_CPUTHREADCONFIG_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class CpuThread
|
||||
{
|
||||
public:
|
||||
inline constexpr CpuThread(int intensity = 1, int64_t affinity = -1) : m_intensity(intensity), m_affinity(affinity) {}
|
||||
|
||||
CpuThread(const rapidjson::Value &value);
|
||||
|
||||
inline bool isEqual(const CpuThread &other) const { return other.m_affinity == m_affinity && other.m_intensity == m_intensity; }
|
||||
inline bool isValid() const { return m_intensity >= 1 && m_intensity <= 5; }
|
||||
inline int intensity() const { return m_intensity; }
|
||||
inline int64_t affinity() const { return m_affinity; }
|
||||
|
||||
inline bool operator!=(const CpuThread &other) const { return !isEqual(other); }
|
||||
inline bool operator==(const CpuThread &other) const { return isEqual(other); }
|
||||
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
|
||||
private:
|
||||
int m_intensity = -1;
|
||||
int64_t m_affinity = -1;
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<CpuThread> CpuThreads;
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CPUTHREADCONFIG_H */
|
||||
308
src/backend/cpu/CpuWorker.cpp
Normal file
308
src/backend/cpu/CpuWorker.cpp
Normal file
@@ -0,0 +1,308 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 <thread>
|
||||
|
||||
|
||||
#include "backend/cpu/CpuWorker.h"
|
||||
#include "core/Miner.h"
|
||||
#include "crypto/cn/CnCtx.h"
|
||||
#include "crypto/cn/CryptoNight_test.h"
|
||||
#include "crypto/common/Nonce.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "crypto/rx/Rx.h"
|
||||
#include "crypto/rx/RxVm.h"
|
||||
#include "net/JobResults.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_ALGO_RANDOMX
|
||||
# include "crypto/randomx/randomx.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static constexpr uint32_t kReserveCount = 4096;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
||||
template<size_t N>
|
||||
xmrig::CpuWorker<N>::CpuWorker(size_t index, const CpuLaunchData &data) :
|
||||
Worker(index, data.affinity, data.priority),
|
||||
m_algorithm(data.algorithm),
|
||||
m_assembly(data.assembly),
|
||||
m_hwAES(data.hwAES),
|
||||
m_av(data.av()),
|
||||
m_miner(data.miner),
|
||||
m_ctx()
|
||||
{
|
||||
m_memory = new VirtualMemory(m_algorithm.memory() * N, data.hugePages);
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
xmrig::CpuWorker<N>::~CpuWorker()
|
||||
{
|
||||
CnCtx::release(m_ctx, N);
|
||||
delete m_memory;
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
delete m_vm;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_ALGO_RANDOMX
|
||||
template<size_t N>
|
||||
void xmrig::CpuWorker<N>::allocateRandomX_VM()
|
||||
{
|
||||
RxDataset *dataset = Rx::dataset(m_job.currentJob().seedHash(), m_job.currentJob().algorithm());
|
||||
|
||||
if (!m_vm) {
|
||||
m_vm = new RxVm(dataset, m_memory->scratchpad(), !m_hwAES);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
template<size_t N>
|
||||
bool xmrig::CpuWorker<N>::selfTest()
|
||||
{
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
if (m_algorithm.family() == Algorithm::RANDOM_X) {
|
||||
return N == 1;
|
||||
}
|
||||
# endif
|
||||
|
||||
allocateCnCtx();
|
||||
|
||||
if (m_algorithm.family() == Algorithm::CN) {
|
||||
const bool rc = verify(Algorithm::CN_0, test_output_v0) &&
|
||||
verify(Algorithm::CN_1, test_output_v1) &&
|
||||
verify(Algorithm::CN_2, test_output_v2) &&
|
||||
verify(Algorithm::CN_FAST, test_output_msr) &&
|
||||
verify(Algorithm::CN_XAO, test_output_xao) &&
|
||||
verify(Algorithm::CN_RTO, test_output_rto) &&
|
||||
verify(Algorithm::CN_HALF, test_output_half) &&
|
||||
verify2(Algorithm::CN_WOW, test_output_wow) &&
|
||||
verify2(Algorithm::CN_R, test_output_r) &&
|
||||
verify(Algorithm::CN_RWZ, test_output_rwz) &&
|
||||
verify(Algorithm::CN_ZLS, test_output_zls) &&
|
||||
verify(Algorithm::CN_DOUBLE, test_output_double);
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_GPU
|
||||
if (!rc || N > 1) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return verify(Algorithm::CN_GPU, test_output_gpu);
|
||||
# else
|
||||
return rc;
|
||||
# endif
|
||||
}
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_LITE
|
||||
if (m_algorithm.family() == Algorithm::CN_LITE) {
|
||||
return verify(Algorithm::CN_LITE_0, test_output_v0_lite) &&
|
||||
verify(Algorithm::CN_LITE_1, test_output_v1_lite);
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||
if (m_algorithm.family() == Algorithm::CN_HEAVY) {
|
||||
return verify(Algorithm::CN_HEAVY_0, test_output_v0_heavy) &&
|
||||
verify(Algorithm::CN_HEAVY_XHV, test_output_xhv_heavy) &&
|
||||
verify(Algorithm::CN_HEAVY_TUBE, test_output_tube_heavy);
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_PICO
|
||||
if (m_algorithm.family() == Algorithm::CN_PICO) {
|
||||
return verify(Algorithm::CN_PICO_0, test_output_pico_trtl);
|
||||
}
|
||||
# endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
void xmrig::CpuWorker<N>::start()
|
||||
{
|
||||
while (Nonce::sequence(Nonce::CPU) > 0) {
|
||||
if (Nonce::isPaused()) {
|
||||
do {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
}
|
||||
while (Nonce::isPaused() && Nonce::sequence(Nonce::CPU) > 0);
|
||||
|
||||
if (Nonce::sequence(Nonce::CPU) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
consumeJob();
|
||||
}
|
||||
|
||||
while (!Nonce::isOutdated(Nonce::CPU, m_job.sequence())) {
|
||||
if ((m_count & 0x7) == 0) {
|
||||
storeStats();
|
||||
}
|
||||
|
||||
const Job &job = m_job.currentJob();
|
||||
|
||||
if (job.algorithm().memory() != m_algorithm.memory()) {
|
||||
break;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
if (job.algorithm().family() == Algorithm::RANDOM_X) {
|
||||
randomx_calculate_hash(m_vm->get(), m_job.blob(), job.size(), m_hash);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < job.target()) {
|
||||
JobResults::submit(JobResult(job, *m_job.nonce(i), m_hash + (i * 32)));
|
||||
}
|
||||
}
|
||||
|
||||
m_job.nextRound(kReserveCount);
|
||||
m_count += N;
|
||||
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
consumeJob();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
bool xmrig::CpuWorker<N>::verify(const Algorithm &algorithm, const uint8_t *referenceValue)
|
||||
{
|
||||
cn_hash_fun func = fn(algorithm);
|
||||
if (!func) {
|
||||
return false;
|
||||
}
|
||||
|
||||
func(test_input, 76, m_hash, m_ctx, 0);
|
||||
return memcmp(m_hash, referenceValue, sizeof m_hash) == 0;
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
bool xmrig::CpuWorker<N>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue)
|
||||
{
|
||||
cn_hash_fun func = fn(algorithm);
|
||||
if (!func) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < (sizeof(cn_r_test_input) / sizeof(cn_r_test_input[0])); ++i) {
|
||||
const size_t size = cn_r_test_input[i].size;
|
||||
for (size_t k = 0; k < N; ++k) {
|
||||
memcpy(m_job.blob() + (k * size), cn_r_test_input[i].data, size);
|
||||
}
|
||||
|
||||
func(m_job.blob(), size, m_hash, m_ctx, cn_r_test_input[i].height);
|
||||
|
||||
for (size_t k = 0; k < N; ++k) {
|
||||
if (memcmp(m_hash + k * 32, referenceValue + i * 32, sizeof m_hash / N) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
template<>
|
||||
bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue)
|
||||
{
|
||||
cn_hash_fun func = fn(algorithm);
|
||||
if (!func) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < (sizeof(cn_r_test_input) / sizeof(cn_r_test_input[0])); ++i) {
|
||||
func(cn_r_test_input[i].data, cn_r_test_input[i].size, m_hash, m_ctx, cn_r_test_input[i].height);
|
||||
|
||||
if (memcmp(m_hash, referenceValue + i * 32, sizeof m_hash) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
template<size_t N>
|
||||
void xmrig::CpuWorker<N>::allocateCnCtx()
|
||||
{
|
||||
if (m_ctx[0] == nullptr) {
|
||||
CnCtx::create(m_ctx, m_memory->scratchpad(), m_algorithm.memory(), N);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
void xmrig::CpuWorker<N>::consumeJob()
|
||||
{
|
||||
m_job.add(m_miner->job(), Nonce::sequence(Nonce::CPU), kReserveCount);
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) {
|
||||
allocateRandomX_VM();
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
allocateCnCtx();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
template class CpuWorker<1>;
|
||||
template class CpuWorker<2>;
|
||||
template class CpuWorker<3>;
|
||||
template class CpuWorker<4>;
|
||||
template class CpuWorker<5>;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
98
src/backend/cpu/CpuWorker.h
Normal file
98
src/backend/cpu/CpuWorker.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 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_CPUWORKER_H
|
||||
#define XMRIG_CPUWORKER_H
|
||||
|
||||
|
||||
#include "backend/common/Worker.h"
|
||||
#include "backend/common/WorkerJob.h"
|
||||
#include "backend/cpu/CpuLaunchData.h"
|
||||
#include "base/net/stratum/Job.h"
|
||||
#include "net/JobResult.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class RxVm;
|
||||
|
||||
|
||||
template<size_t N>
|
||||
class CpuWorker : public Worker
|
||||
{
|
||||
public:
|
||||
CpuWorker(size_t index, const CpuLaunchData &data);
|
||||
~CpuWorker() override;
|
||||
|
||||
protected:
|
||||
bool selfTest() override;
|
||||
void start() override;
|
||||
|
||||
inline const VirtualMemory *memory() const override { return m_memory; }
|
||||
|
||||
private:
|
||||
inline cn_hash_fun fn(const Algorithm &algorithm) const { return CnHash::fn(algorithm, m_av, m_assembly); }
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
void allocateRandomX_VM();
|
||||
# endif
|
||||
|
||||
bool verify(const Algorithm &algorithm, const uint8_t *referenceValue);
|
||||
bool verify2(const Algorithm &algorithm, const uint8_t *referenceValue);
|
||||
void allocateCnCtx();
|
||||
void consumeJob();
|
||||
|
||||
const Algorithm m_algorithm;
|
||||
const Assembly m_assembly;
|
||||
const bool m_hwAES;
|
||||
const CnHash::AlgoVariant m_av;
|
||||
const Miner *m_miner;
|
||||
cryptonight_ctx *m_ctx[N];
|
||||
uint8_t m_hash[N * 32];
|
||||
VirtualMemory *m_memory = nullptr;
|
||||
WorkerJob<N> m_job;
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
RxVm *m_vm = nullptr;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue);
|
||||
|
||||
|
||||
extern template class CpuWorker<1>;
|
||||
extern template class CpuWorker<2>;
|
||||
extern template class CpuWorker<3>;
|
||||
extern template class CpuWorker<4>;
|
||||
extern template class CpuWorker<5>;
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_CPUWORKER_H */
|
||||
37
src/backend/cpu/cpu.cmake
Normal file
37
src/backend/cpu/cpu.cmake
Normal file
@@ -0,0 +1,37 @@
|
||||
set(HEADERS_BACKEND_CPU
|
||||
src/backend/cpu/Cpu.h
|
||||
src/backend/cpu/CpuBackend.h
|
||||
src/backend/cpu/CpuConfig.h
|
||||
src/backend/cpu/CpuLaunchData.cpp
|
||||
src/backend/cpu/CpuThread.h
|
||||
src/backend/cpu/CpuWorker.h
|
||||
src/backend/cpu/interfaces/ICpuInfo.h
|
||||
)
|
||||
|
||||
set(SOURCES_BACKEND_CPU
|
||||
src/backend/cpu/Cpu.cpp
|
||||
src/backend/cpu/CpuBackend.cpp
|
||||
src/backend/cpu/CpuConfig.cpp
|
||||
src/backend/cpu/CpuLaunchData.h
|
||||
src/backend/cpu/CpuThread.cpp
|
||||
src/backend/cpu/CpuWorker.cpp
|
||||
)
|
||||
|
||||
|
||||
if (WITH_LIBCPUID)
|
||||
add_subdirectory(src/3rdparty/libcpuid)
|
||||
include_directories(src/3rdparty/libcpuid)
|
||||
add_definitions(/DXMRIG_FEATURE_LIBCPUID)
|
||||
|
||||
set(CPUID_LIB cpuid)
|
||||
set(SOURCES_CPUID src/backend/cpu/platform/AdvancedCpuInfo.h src/backend/cpu/platform/AdvancedCpuInfo.cpp src/backend/cpu/Cpu.cpp)
|
||||
else()
|
||||
remove_definitions(/DXMRIG_FEATURE_LIBCPUID)
|
||||
set(SOURCES_CPUID src/backend/cpu/platform/BasicCpuInfo.h src/backend/cpu/Cpu.cpp)
|
||||
|
||||
if (XMRIG_ARM)
|
||||
set(SOURCES_CPUID ${SOURCES_CPUID} src/backend/cpu/platform/BasicCpuInfo_arm.cpp)
|
||||
else()
|
||||
set(SOURCES_CPUID ${SOURCES_CPUID} src/backend/cpu/platform/BasicCpuInfo.cpp)
|
||||
endif()
|
||||
endif()
|
||||
@@ -26,11 +26,9 @@
|
||||
#define XMRIG_CPUINFO_H
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "common/xmrig.h"
|
||||
#include "backend/cpu/CpuThread.h"
|
||||
#include "crypto/common/Assembly.h"
|
||||
#include "crypto/common/Algorithm.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -39,21 +37,26 @@ namespace xmrig {
|
||||
class ICpuInfo
|
||||
{
|
||||
public:
|
||||
virtual ~ICpuInfo() {}
|
||||
virtual ~ICpuInfo() = default;
|
||||
|
||||
# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__)
|
||||
inline constexpr static bool isX64() { return true; }
|
||||
# else
|
||||
inline constexpr static bool isX64() { return false; }
|
||||
# endif
|
||||
|
||||
virtual Assembly::Id assembly() const = 0;
|
||||
virtual bool hasAES() const = 0;
|
||||
virtual bool hasAVX2() const = 0;
|
||||
virtual bool isSupported() const = 0;
|
||||
virtual bool isX64() const = 0;
|
||||
virtual const char *brand() const = 0;
|
||||
virtual int32_t cores() const = 0;
|
||||
virtual int32_t L2() const = 0;
|
||||
virtual int32_t L3() const = 0;
|
||||
virtual int32_t nodes() const = 0;
|
||||
virtual int32_t sockets() const = 0;
|
||||
virtual int32_t threads() const = 0;
|
||||
virtual size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const = 0;
|
||||
virtual xmrig::Assembly assembly() const = 0;
|
||||
virtual CpuThreads threads(const Algorithm &algorithm) const = 0;
|
||||
virtual size_t cores() const = 0;
|
||||
virtual size_t L2() const = 0;
|
||||
virtual size_t L3() const = 0;
|
||||
virtual size_t nodes() const = 0;
|
||||
virtual size_t sockets() const = 0;
|
||||
virtual size_t threads() const = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -22,66 +22,57 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <libcpuid.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "core/cpu/AdvancedCpuInfo.h"
|
||||
#include "backend/cpu/platform/AdvancedCpuInfo.h"
|
||||
|
||||
|
||||
xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
|
||||
m_assembly(ASM_NONE),
|
||||
m_aes(false),
|
||||
m_avx2(false),
|
||||
m_L2_exclusive(false),
|
||||
m_brand(),
|
||||
m_cores(0),
|
||||
m_L2(0),
|
||||
m_L3(0),
|
||||
m_sockets(1),
|
||||
m_threads(0)
|
||||
m_brand()
|
||||
{
|
||||
struct cpu_raw_data_t raw = { 0 };
|
||||
struct cpu_id_t data = { 0 };
|
||||
struct cpu_raw_data_t raw = {};
|
||||
struct cpu_id_t data = {};
|
||||
|
||||
cpuid_get_raw_data(&raw);
|
||||
cpu_identify(&raw, &data);
|
||||
|
||||
strncpy(m_brand, data.brand_str, sizeof(m_brand));
|
||||
|
||||
m_threads = data.total_logical_cpus;
|
||||
m_sockets = threads() / data.num_logical_cpus;
|
||||
if (m_sockets == 0) {
|
||||
m_sockets = 1;
|
||||
}
|
||||
m_threads = static_cast<size_t>(data.total_logical_cpus);
|
||||
m_sockets = std::max<size_t>(threads() / static_cast<size_t>(data.num_logical_cpus), 1);
|
||||
m_cores = static_cast<size_t>(data.num_cores) * m_sockets;
|
||||
m_L3 = data.l3_cache > 0 ? static_cast<size_t>(data.l3_cache) * m_sockets : 0;
|
||||
|
||||
m_cores = data.num_cores * m_sockets;
|
||||
m_L3 = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0;
|
||||
const size_t l2 = static_cast<size_t>(data.l2_cache);
|
||||
|
||||
// Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97
|
||||
if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) {
|
||||
m_L2 = data.l2_cache * (cores() / 2) * m_sockets;
|
||||
m_L2 = l2 * (cores() / 2) * m_sockets;
|
||||
m_L2_exclusive = true;
|
||||
}
|
||||
// Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue
|
||||
// These processors have L2 cache shared by 2 cores.
|
||||
else if (data.vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17)) {
|
||||
int l2_count_per_socket = cores() > 1 ? cores() / 2 : 1;
|
||||
m_L2 = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0;
|
||||
size_t l2_count_per_socket = cores() > 1 ? cores() / 2 : 1;
|
||||
m_L2 = data.l2_cache > 0 ? l2 * l2_count_per_socket * m_sockets : 0;
|
||||
}
|
||||
else{
|
||||
m_L2 = data.l2_cache > 0 ? data.l2_cache * cores() * m_sockets : 0;
|
||||
m_L2 = data.l2_cache > 0 ? l2 * cores() * m_sockets : 0;
|
||||
}
|
||||
|
||||
if (data.flags[CPU_FEATURE_AES]) {
|
||||
m_aes = true;
|
||||
|
||||
if (data.vendor == VENDOR_AMD) {
|
||||
m_assembly = (data.ext_family >= 23) ? ASM_RYZEN : ASM_BULLDOZER;
|
||||
m_assembly = (data.ext_family >= 23) ? Assembly::RYZEN : Assembly::BULLDOZER;
|
||||
}
|
||||
else if (data.vendor == VENDOR_INTEL) {
|
||||
m_assembly = ASM_INTEL;
|
||||
m_assembly = Assembly::INTEL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,13 +80,21 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
|
||||
}
|
||||
|
||||
|
||||
size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
|
||||
xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) const
|
||||
{
|
||||
if (threads() == 1) {
|
||||
return 1;
|
||||
return CpuThreads(1);
|
||||
}
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_GPU
|
||||
if (algorithm == Algorithm::CN_GPU) {
|
||||
return CpuThreads(threads());
|
||||
}
|
||||
# endif
|
||||
|
||||
size_t cache = 0;
|
||||
size_t count = 0;
|
||||
|
||||
if (m_L3) {
|
||||
cache = m_L2_exclusive ? (m_L2 + m_L3) : m_L3;
|
||||
}
|
||||
@@ -103,12 +102,14 @@ size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsa
|
||||
cache = m_L2;
|
||||
}
|
||||
|
||||
size_t count = 0;
|
||||
|
||||
if (cache) {
|
||||
count = cache / memSize;
|
||||
cache *= 1024;
|
||||
const size_t memory = algorithm.memory();
|
||||
assert(memory > 0);
|
||||
|
||||
if (cache % memSize >= memSize / 2) {
|
||||
count = cache / memory;
|
||||
|
||||
if (cache % memory >= memory / 2) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -116,13 +117,5 @@ size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsa
|
||||
count = threads() / 2;
|
||||
}
|
||||
|
||||
if (count > (size_t) threads()) {
|
||||
count = threads();
|
||||
}
|
||||
|
||||
if (((float) count / threads() * 100) > maxCpuUsage) {
|
||||
count = (int) ceil((float) threads() * (maxCpuUsage / 100.0));
|
||||
}
|
||||
|
||||
return count < 1 ? 1 : count;
|
||||
return CpuThreads(std::max<size_t>(std::min<size_t>(count, threads()), 1));
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
#define XMRIG_ADVANCEDCPUINFO_H
|
||||
|
||||
|
||||
#include "common/interfaces/ICpuInfo.h"
|
||||
#include "backend/cpu/interfaces/ICpuInfo.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -38,37 +38,31 @@ public:
|
||||
AdvancedCpuInfo();
|
||||
|
||||
protected:
|
||||
size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override;
|
||||
CpuThreads threads(const Algorithm &algorithm) const override;
|
||||
|
||||
inline Assembly assembly() const override { return m_assembly; }
|
||||
inline Assembly::Id assembly() const override { return m_assembly; }
|
||||
inline bool hasAES() const override { return m_aes; }
|
||||
inline bool hasAVX2() const override { return m_avx2; }
|
||||
inline bool isSupported() const override { return true; }
|
||||
inline const char *brand() const override { return m_brand; }
|
||||
inline int32_t cores() const override { return m_cores; }
|
||||
inline int32_t L2() const override { return m_L2; }
|
||||
inline int32_t L3() const override { return m_L3; }
|
||||
inline int32_t nodes() const override { return -1; }
|
||||
inline int32_t sockets() const override { return m_sockets; }
|
||||
inline int32_t threads() const override { return m_threads; }
|
||||
|
||||
# if defined(__x86_64__) || defined(_M_AMD64)
|
||||
inline bool isX64() const override { return true; }
|
||||
# else
|
||||
inline bool isX64() const override { return false; }
|
||||
# endif
|
||||
inline size_t cores() const override { return m_cores; }
|
||||
inline size_t L2() const override { return m_L2; }
|
||||
inline size_t L3() const override { return m_L3; }
|
||||
inline size_t nodes() const override { return 0; }
|
||||
inline size_t sockets() const override { return m_sockets; }
|
||||
inline size_t threads() const override { return m_threads; }
|
||||
|
||||
private:
|
||||
Assembly m_assembly;
|
||||
bool m_aes;
|
||||
bool m_avx2;
|
||||
bool m_L2_exclusive;
|
||||
bool m_aes = false;
|
||||
bool m_avx2 = false;
|
||||
bool m_L2_exclusive = false;
|
||||
char m_brand[64];
|
||||
int32_t m_cores;
|
||||
int32_t m_L2;
|
||||
int32_t m_L3;
|
||||
int32_t m_sockets;
|
||||
int32_t m_threads;
|
||||
size_t m_cores = 0;
|
||||
size_t m_L2 = 0;
|
||||
size_t m_L3 = 0;
|
||||
size_t m_sockets = 1;
|
||||
size_t m_threads = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <thread>
|
||||
|
||||
@@ -45,7 +46,8 @@
|
||||
#endif
|
||||
|
||||
|
||||
#include "common/cpu/BasicCpuInfo.h"
|
||||
#include "backend/cpu/platform/BasicCpuInfo.h"
|
||||
#include "crypto/common/Assembly.h"
|
||||
|
||||
|
||||
#define VENDOR_ID (0)
|
||||
@@ -121,15 +123,15 @@ static inline bool has_ossave()
|
||||
|
||||
|
||||
xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||
m_assembly(ASM_NONE),
|
||||
m_assembly(Assembly::NONE),
|
||||
m_aes(has_aes_ni()),
|
||||
m_avx2(has_avx2() && has_ossave()),
|
||||
m_brand(),
|
||||
m_avx2(has_avx2() && has_ossave()),
|
||||
m_threads(std::thread::hardware_concurrency())
|
||||
{
|
||||
cpu_brand_string(m_brand);
|
||||
|
||||
# ifndef XMRIG_NO_ASM
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
if (hasAES()) {
|
||||
char vendor[13] = { 0 };
|
||||
int32_t data[4] = { 0 };
|
||||
@@ -141,19 +143,35 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||
memcpy(vendor + 8, &data[2], 4);
|
||||
|
||||
if (memcmp(vendor, "GenuineIntel", 12) == 0) {
|
||||
m_assembly = ASM_INTEL;
|
||||
m_assembly = Assembly::INTEL;
|
||||
}
|
||||
else if (memcmp(vendor, "AuthenticAMD", 12) == 0) {
|
||||
m_assembly = ASM_RYZEN;
|
||||
m_assembly = Assembly::RYZEN;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
|
||||
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const
|
||||
{
|
||||
const size_t count = threads() / 2;
|
||||
if (threads() == 1) {
|
||||
return CpuThreads(1);
|
||||
}
|
||||
|
||||
return count < 1 ? 1 : count;
|
||||
# ifdef XMRIG_ALGO_CN_GPU
|
||||
if (algorithm == Algorithm::CN_GPU) {
|
||||
return CpuThreads(threads());
|
||||
}
|
||||
# endif
|
||||
|
||||
if (algorithm.family() == Algorithm::CN_LITE || algorithm.family() == Algorithm::CN_PICO) {
|
||||
return CpuThreads(threads());
|
||||
}
|
||||
|
||||
if (algorithm.family() == Algorithm::CN_HEAVY) {
|
||||
return CpuThreads(std::max<size_t>(threads() / 4, 1));
|
||||
}
|
||||
|
||||
return CpuThreads(std::max<size_t>(threads() / 2, 1));
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
#define XMRIG_BASICCPUINFO_H
|
||||
|
||||
|
||||
#include "common/interfaces/ICpuInfo.h"
|
||||
#include "backend/cpu/interfaces/ICpuInfo.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -38,32 +38,26 @@ public:
|
||||
BasicCpuInfo();
|
||||
|
||||
protected:
|
||||
size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override;
|
||||
CpuThreads threads(const Algorithm &algorithm) const override;
|
||||
|
||||
inline Assembly assembly() const override { return m_assembly; }
|
||||
inline Assembly::Id assembly() const override { return m_assembly; }
|
||||
inline bool hasAES() const override { return m_aes; }
|
||||
inline bool hasAVX2() const override { return m_avx2; }
|
||||
inline bool isSupported() const override { return true; }
|
||||
inline const char *brand() const override { return m_brand; }
|
||||
inline int32_t cores() const override { return -1; }
|
||||
inline int32_t L2() const override { return -1; }
|
||||
inline int32_t L3() const override { return -1; }
|
||||
inline int32_t nodes() const override { return -1; }
|
||||
inline int32_t sockets() const override { return 1; }
|
||||
inline int32_t threads() const override { return m_threads; }
|
||||
|
||||
# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__)
|
||||
inline bool isX64() const override { return true; }
|
||||
# else
|
||||
inline bool isX64() const override { return false; }
|
||||
# endif
|
||||
inline size_t cores() const override { return 0; }
|
||||
inline size_t L2() const override { return 0; }
|
||||
inline size_t L3() const override { return 0; }
|
||||
inline size_t nodes() const override { return 0; }
|
||||
inline size_t sockets() const override { return 1; }
|
||||
inline size_t threads() const override { return m_threads; }
|
||||
|
||||
private:
|
||||
Assembly m_assembly;
|
||||
bool m_aes;
|
||||
bool m_avx2;
|
||||
char m_brand[64];
|
||||
int32_t m_threads;
|
||||
char m_brand[64 + 6];
|
||||
const bool m_avx2;
|
||||
const size_t m_threads;
|
||||
};
|
||||
|
||||
|
||||
@@ -25,19 +25,20 @@
|
||||
#include <string.h>
|
||||
#include <thread>
|
||||
|
||||
#if __ARM_FEATURE_CRYPTO
|
||||
|
||||
#if __ARM_FEATURE_CRYPTO && !defined(__APPLE__)
|
||||
# include <sys/auxv.h>
|
||||
# include <asm/hwcap.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "common/cpu/BasicCpuInfo.h"
|
||||
#include "backend/cpu/platform/BasicCpuInfo.h"
|
||||
|
||||
|
||||
xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||
m_aes(false),
|
||||
m_avx2(false),
|
||||
m_brand(),
|
||||
m_avx2(false),
|
||||
m_threads(std::thread::hardware_concurrency())
|
||||
{
|
||||
# ifdef XMRIG_ARMv8
|
||||
@@ -47,12 +48,16 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||
# endif
|
||||
|
||||
# if __ARM_FEATURE_CRYPTO
|
||||
# if !defined(__APPLE__)
|
||||
m_aes = getauxval(AT_HWCAP) & HWCAP_AES;
|
||||
# else
|
||||
m_aes = true;
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
|
||||
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const
|
||||
{
|
||||
return threads();
|
||||
return CpuThreads(threads());
|
||||
}
|
||||
@@ -1,15 +1,23 @@
|
||||
set(HEADERS_BASE
|
||||
src/base/io/Console.h
|
||||
src/base/io/Json.h
|
||||
src/base/io/json/Json.h
|
||||
src/base/io/json/JsonChain.h
|
||||
src/base/io/json/JsonRequest.h
|
||||
src/base/io/log/backends/ConsoleLog.h
|
||||
src/base/io/log/backends/FileLog.h
|
||||
src/base/io/log/Log.h
|
||||
src/base/io/Watcher.h
|
||||
src/base/kernel/Base.h
|
||||
src/base/kernel/config/BaseConfig.h
|
||||
src/base/kernel/config/BaseTransform.h
|
||||
src/base/kernel/Entry.h
|
||||
src/base/kernel/interfaces/IBaseListener.h
|
||||
src/base/kernel/interfaces/IClient.h
|
||||
src/base/kernel/interfaces/IClientListener.h
|
||||
src/base/kernel/interfaces/IConfig.h
|
||||
src/base/kernel/interfaces/IConfigListener.h
|
||||
src/base/kernel/interfaces/IConfigTransform.h
|
||||
src/base/kernel/interfaces/IConsoleListener.h
|
||||
src/base/kernel/interfaces/IControllerListener.h
|
||||
src/base/kernel/interfaces/IDnsListener.h
|
||||
src/base/kernel/interfaces/ILineListener.h
|
||||
src/base/kernel/interfaces/ILogBackend.h
|
||||
@@ -18,11 +26,13 @@ set(HEADERS_BASE
|
||||
src/base/kernel/interfaces/IStrategyListener.h
|
||||
src/base/kernel/interfaces/ITimerListener.h
|
||||
src/base/kernel/interfaces/IWatcherListener.h
|
||||
src/base/kernel/Platform.h
|
||||
src/base/kernel/Process.h
|
||||
src/base/kernel/Signals.h
|
||||
src/base/net/dns/Dns.h
|
||||
src/base/net/dns/DnsRecord.h
|
||||
src/base/net/http/Http.h
|
||||
src/base/net/stratum/BaseClient.h
|
||||
src/base/net/stratum/Client.h
|
||||
src/base/net/stratum/Job.h
|
||||
src/base/net/stratum/Pool.h
|
||||
@@ -33,6 +43,7 @@ set(HEADERS_BASE
|
||||
src/base/net/tools/RecvBuf.h
|
||||
src/base/net/tools/Storage.h
|
||||
src/base/tools/Arguments.h
|
||||
src/base/tools/Baton.h
|
||||
src/base/tools/Buffer.h
|
||||
src/base/tools/Chrono.h
|
||||
src/base/tools/Handle.h
|
||||
@@ -42,17 +53,24 @@ set(HEADERS_BASE
|
||||
|
||||
set(SOURCES_BASE
|
||||
src/base/io/Console.cpp
|
||||
src/base/io/Json.cpp
|
||||
src/base/io/json/Json.cpp
|
||||
src/base/io/json/JsonChain.cpp
|
||||
src/base/io/json/JsonRequest.cpp
|
||||
src/base/io/log/backends/ConsoleLog.cpp
|
||||
src/base/io/log/backends/FileLog.cpp
|
||||
src/base/io/log/Log.cpp
|
||||
src/base/io/Watcher.cpp
|
||||
src/base/kernel/Base.cpp
|
||||
src/base/kernel/config/BaseConfig.cpp
|
||||
src/base/kernel/config/BaseTransform.cpp
|
||||
src/base/kernel/Entry.cpp
|
||||
src/base/kernel/Platform.cpp
|
||||
src/base/kernel/Process.cpp
|
||||
src/base/kernel/Signals.cpp
|
||||
src/base/net/dns/Dns.cpp
|
||||
src/base/net/dns/DnsRecord.cpp
|
||||
src/base/net/http/Http.cpp
|
||||
src/base/net/stratum/BaseClient.cpp
|
||||
src/base/net/stratum/Client.cpp
|
||||
src/base/net/stratum/Job.cpp
|
||||
src/base/net/stratum/Pool.cpp
|
||||
@@ -67,9 +85,20 @@ set(SOURCES_BASE
|
||||
|
||||
|
||||
if (WIN32)
|
||||
set(SOURCES_OS src/base/io/Json_win.cpp)
|
||||
set(SOURCES_OS
|
||||
src/base/io/json/Json_win.cpp
|
||||
src/base/kernel/Platform_win.cpp
|
||||
)
|
||||
elseif (APPLE)
|
||||
set(SOURCES_OS
|
||||
src/base/io/json/Json_unix.cpp
|
||||
src/base/kernel/Platform_mac.cpp
|
||||
)
|
||||
else()
|
||||
set(SOURCES_OS src/base/io/Json_unix.cpp)
|
||||
set(SOURCES_OS
|
||||
src/base/io/json/Json_unix.cpp
|
||||
src/base/kernel//Platform_unix.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -82,25 +111,30 @@ if (NOT WIN32)
|
||||
endif()
|
||||
|
||||
|
||||
if (WITH_HTTPD)
|
||||
if (WITH_HTTP)
|
||||
set(HEADERS_BASE_HTTP
|
||||
src/3rdparty/http-parser/http_parser.h
|
||||
src/base/kernel/interfaces/IHttpListener.h
|
||||
src/base/kernel/interfaces/IJsonReader.h
|
||||
src/base/kernel/interfaces/ITcpServerListener.h
|
||||
src/base/net/http/HttpApiResponse.h
|
||||
src/base/net/http/HttpClient.h
|
||||
src/base/net/http/HttpContext.h
|
||||
src/base/net/http/HttpRequest.h
|
||||
src/base/net/http/HttpData.h
|
||||
src/base/net/http/HttpResponse.h
|
||||
src/base/net/http/HttpServer.h
|
||||
src/base/net/stratum/DaemonClient.h
|
||||
src/base/net/tools/TcpServer.h
|
||||
)
|
||||
|
||||
set(SOURCES_BASE_HTTP
|
||||
src/3rdparty/http-parser/http_parser.c
|
||||
src/base/net/http/HttpApiResponse.cpp
|
||||
src/base/net/http/HttpClient.cpp
|
||||
src/base/net/http/HttpContext.cpp
|
||||
src/base/net/http/HttpResponse.cpp
|
||||
src/base/net/http/HttpServer.cpp
|
||||
src/base/net/stratum/DaemonClient.cpp
|
||||
src/base/net/tools/TcpServer.cpp
|
||||
)
|
||||
|
||||
@@ -112,5 +146,3 @@ else()
|
||||
remove_definitions(/DXMRIG_FEATURE_HTTP)
|
||||
remove_definitions(/DXMRIG_FEATURE_API)
|
||||
endif()
|
||||
|
||||
add_definitions(/DXMRIG_DEPRECATED)
|
||||
|
||||
@@ -23,10 +23,17 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const rapidjson::Value kNullValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue)
|
||||
{
|
||||
auto i = obj.FindMember(key);
|
||||
@@ -49,6 +56,39 @@ const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key,
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const char *key)
|
||||
{
|
||||
auto i = obj.FindMember(key);
|
||||
if (i != obj.MemberEnd() && i->value.IsArray()) {
|
||||
return i->value;
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, const char *key)
|
||||
{
|
||||
auto i = obj.FindMember(key);
|
||||
if (i != obj.MemberEnd() && i->value.IsObject()) {
|
||||
return i->value;
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const char *key)
|
||||
{
|
||||
auto i = obj.FindMember(key);
|
||||
if (i != obj.MemberEnd()) {
|
||||
return i->value;
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue)
|
||||
{
|
||||
auto i = obj.FindMember(key);
|
||||
@@ -91,3 +131,9 @@ unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsi
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::JsonReader::isEmpty() const
|
||||
{
|
||||
return !m_obj.IsObject() || m_obj.ObjectEmpty();
|
||||
}
|
||||
79
src/base/io/json/Json.h
Normal file
79
src/base/io/json/Json.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_JSON_H
|
||||
#define XMRIG_JSON_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IJsonReader.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Json
|
||||
{
|
||||
public:
|
||||
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
|
||||
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
|
||||
static const rapidjson::Value &getArray(const rapidjson::Value &obj, const char *key);
|
||||
static const rapidjson::Value &getObject(const rapidjson::Value &obj, const char *key);
|
||||
static const rapidjson::Value &getValue(const rapidjson::Value &obj, const char *key);
|
||||
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
|
||||
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
|
||||
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
|
||||
static unsigned getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue = 0);
|
||||
|
||||
static bool get(const char *fileName, rapidjson::Document &doc);
|
||||
static bool save(const char *fileName, const rapidjson::Document &doc);
|
||||
};
|
||||
|
||||
|
||||
class JsonReader : public IJsonReader
|
||||
{
|
||||
public:
|
||||
inline JsonReader(const rapidjson::Value &obj) : m_obj(obj) {}
|
||||
|
||||
inline bool getBool(const char *key, bool defaultValue = false) const override { return Json::getBool(m_obj, key, defaultValue); }
|
||||
inline const char *getString(const char *key, const char *defaultValue = nullptr) const override { return Json::getString(m_obj, key, defaultValue); }
|
||||
inline const rapidjson::Value &getArray(const char *key) const override { return Json::getArray(m_obj, key); }
|
||||
inline const rapidjson::Value &getObject(const char *key) const override { return Json::getObject(m_obj, key); }
|
||||
inline const rapidjson::Value &getValue(const char *key) const override { return Json::getValue(m_obj, key); }
|
||||
inline int getInt(const char *key, int defaultValue = 0) const override { return Json::getInt(m_obj, key, defaultValue); }
|
||||
inline int64_t getInt64(const char *key, int64_t defaultValue = 0) const override { return Json::getInt64(m_obj, key, defaultValue); }
|
||||
inline uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override { return Json::getUint64(m_obj, key, defaultValue); }
|
||||
inline unsigned getUint(const char *key, unsigned defaultValue = 0) const override { return Json::getUint(m_obj, key, defaultValue); }
|
||||
|
||||
bool isEmpty() const override;
|
||||
|
||||
private:
|
||||
const rapidjson::Value &m_obj;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_JSON_H */
|
||||
213
src/base/io/json/JsonChain.cpp
Normal file
213
src/base/io/json/JsonChain.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 "base/io/json/Json.h"
|
||||
#include "base/io/json/JsonChain.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const rapidjson::Value kNullValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
xmrig::JsonChain::JsonChain()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::JsonChain::add(rapidjson::Document &&doc)
|
||||
{
|
||||
if (doc.HasParseError() || !doc.IsObject() || doc.ObjectEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_chain.push_back(std::move(doc));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::JsonChain::addFile(const char *fileName)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
Document doc;
|
||||
if (Json::get(fileName, doc)) {
|
||||
m_fileName = fileName;
|
||||
|
||||
return add(std::move(doc));
|
||||
}
|
||||
|
||||
if (doc.HasParseError()) {
|
||||
LOG_ERR("%s<offset:%zu>: \"%s\"", fileName, doc.GetErrorOffset(), GetParseError_En(doc.GetParseError()));
|
||||
}
|
||||
else {
|
||||
LOG_ERR("unable to open \"%s\".", fileName);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::JsonChain::addRaw(const char *json)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
Document doc;
|
||||
doc.Parse<kParseCommentsFlag | kParseTrailingCommasFlag>(json);
|
||||
|
||||
return add(std::move(doc));
|
||||
}
|
||||
|
||||
|
||||
void xmrig::JsonChain::dump(const char *fileName)
|
||||
{
|
||||
rapidjson::Document doc(rapidjson::kArrayType);
|
||||
|
||||
for (rapidjson::Document &value : m_chain) {
|
||||
doc.PushBack(value, doc.GetAllocator());
|
||||
}
|
||||
|
||||
Json::save(fileName, doc);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::JsonChain::getBool(const char *key, bool defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsBool()) {
|
||||
return i->value.GetBool();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::JsonChain::getString(const char *key, const char *defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsString()) {
|
||||
return i->value.GetString();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::JsonChain::getArray(const char *key) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsArray()) {
|
||||
return i->value;
|
||||
}
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::JsonChain::getObject(const char *key) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsObject()) {
|
||||
return i->value;
|
||||
}
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::JsonChain::getValue(const char *key) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd()) {
|
||||
return i->value;
|
||||
}
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::JsonChain::getInt(const char *key, int defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsInt()) {
|
||||
return i->value.GetInt();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::JsonChain::getInt64(const char *key, int64_t defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsInt64()) {
|
||||
return i->value.GetInt64();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
uint64_t xmrig::JsonChain::getUint64(const char *key, uint64_t defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsUint64()) {
|
||||
return i->value.GetUint64();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
unsigned xmrig::JsonChain::getUint(const char *key, unsigned defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsUint()) {
|
||||
return i->value.GetUint();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
76
src/base/io/json/JsonChain.h
Normal file
76
src/base/io/json/JsonChain.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_JSONCHAIN_H
|
||||
#define XMRIG_JSONCHAIN_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IJsonReader.h"
|
||||
#include "base/tools/String.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class JsonChain : public IJsonReader
|
||||
{
|
||||
public:
|
||||
JsonChain();
|
||||
|
||||
bool add(rapidjson::Document &&doc);
|
||||
bool addFile(const char *fileName);
|
||||
bool addRaw(const char *json);
|
||||
|
||||
void dump(const char *fileName);
|
||||
|
||||
inline const String &fileName() const { return m_fileName; }
|
||||
inline size_t size() const { return m_chain.size(); }
|
||||
|
||||
protected:
|
||||
inline bool isEmpty() const override { return m_chain.empty(); }
|
||||
|
||||
bool getBool(const char *key, bool defaultValue = false) const override;
|
||||
const char *getString(const char *key, const char *defaultValue = nullptr) const override;
|
||||
const rapidjson::Value &getArray(const char *key) const override;
|
||||
const rapidjson::Value &getObject(const char *key) const override;
|
||||
const rapidjson::Value &getValue(const char *key) const override;
|
||||
int getInt(const char *key, int defaultValue = 0) const override;
|
||||
int64_t getInt64(const char *key, int64_t defaultValue = 0) const override;
|
||||
uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override;
|
||||
unsigned getUint(const char *key, unsigned defaultValue = 0) const override;
|
||||
|
||||
private:
|
||||
std::vector<rapidjson::Document> m_chain;
|
||||
String m_fileName;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_JSONCHAIN_H */
|
||||
38
src/base/io/json/JsonRequest.cpp
Normal file
38
src/base/io/json/JsonRequest.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 "base/io/json/JsonRequest.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
void xmrig::JsonRequest::create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value ¶ms)
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
doc.AddMember("id", id, allocator);
|
||||
doc.AddMember("jsonrpc", "2.0", allocator);
|
||||
doc.AddMember("method", rapidjson::StringRef(method), allocator);
|
||||
doc.AddMember("params", params, allocator);
|
||||
}
|
||||
@@ -22,26 +22,24 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "workers/ThreadHandle.h"
|
||||
#ifndef XMRIG_JSONREQUEST_H
|
||||
#define XMRIG_JSONREQUEST_H
|
||||
|
||||
|
||||
ThreadHandle::ThreadHandle(xmrig::IThread *config, uint32_t offset, size_t totalWays) :
|
||||
m_worker(nullptr),
|
||||
m_totalWays(totalWays),
|
||||
m_offset(offset),
|
||||
m_config(config)
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class JsonRequest
|
||||
{
|
||||
}
|
||||
public:
|
||||
static void create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value ¶ms);
|
||||
};
|
||||
|
||||
|
||||
void ThreadHandle::join()
|
||||
{
|
||||
uv_thread_join(&m_thread);
|
||||
}
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
void ThreadHandle::start(void (*callback) (void *))
|
||||
{
|
||||
uv_thread_create(&m_thread, callback, this);
|
||||
}
|
||||
#endif /* XMRIG_JSONREQUEST_H */
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <fstream>
|
||||
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/istreamwrapper.h"
|
||||
#include "rapidjson/ostreamwrapper.h"
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <fstream>
|
||||
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/istreamwrapper.h"
|
||||
#include "rapidjson/ostreamwrapper.h"
|
||||
@@ -102,7 +102,7 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
|
||||
return false;
|
||||
}
|
||||
# elif defined(__GNUC__)
|
||||
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_TRUNC);
|
||||
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC);
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
}
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/interfaces/ILogBackend.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -134,7 +135,8 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
time_t now = time(nullptr);
|
||||
const uint64_t ms = Chrono::currentMSecsSinceEpoch();
|
||||
time_t now = ms / 1000;
|
||||
tm stime;
|
||||
|
||||
# ifdef _WIN32
|
||||
@@ -143,13 +145,14 @@ private:
|
||||
localtime_r(&now, &stime);
|
||||
# endif
|
||||
|
||||
const int rc = snprintf(m_buf, sizeof(m_buf) - 1, "[%d-%02d-%02d %02d:%02d:%02d] ",
|
||||
const int rc = snprintf(m_buf, sizeof(m_buf) - 1, "[%d-%02d-%02d %02d:%02d:%02d" BLACK_BOLD(".%03d") "] ",
|
||||
stime.tm_year + 1900,
|
||||
stime.tm_mon + 1,
|
||||
stime.tm_mday,
|
||||
stime.tm_hour,
|
||||
stime.tm_min,
|
||||
stime.tm_sec
|
||||
stime.tm_sec,
|
||||
static_cast<int>(ms % 1000)
|
||||
);
|
||||
|
||||
if (rc > 0) {
|
||||
|
||||
@@ -81,6 +81,11 @@ private:
|
||||
#define WHITE_S CSI "0;37m" // another name for LT.GRAY
|
||||
#define WHITE_BOLD_S CSI "1;37m" // actually white
|
||||
|
||||
#define BLUE_BG_S CSI "44m"
|
||||
#define BLUE_BG_BOLD_S CSI "44;1m"
|
||||
#define MAGENTA_BG_S CSI "45m"
|
||||
#define MAGENTA_BG_BOLD_S CSI "45;1m"
|
||||
|
||||
//color wrappings
|
||||
#define BLACK(x) BLACK_S x CLEAR
|
||||
#define BLACK_BOLD(x) BLACK_BOLD_S x CLEAR
|
||||
@@ -99,6 +104,11 @@ private:
|
||||
#define WHITE(x) WHITE_S x CLEAR
|
||||
#define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR
|
||||
|
||||
#define BLUE_BG(x) BLUE_BG_S x CLEAR
|
||||
#define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR
|
||||
#define MAGENTA_BG(x) MAGENTA_BG_S x CLEAR
|
||||
#define MAGENTA_BG_BOLD(x) MAGENTA_BG_BOLD_S x CLEAR
|
||||
|
||||
|
||||
#define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__)
|
||||
#define LOG_ALERT(x, ...) xmrig::Log::print(xmrig::Log::ALERT, x, ##__VA_ARGS__)
|
||||
|
||||
320
src/base/kernel/Base.cpp
Normal file
320
src/base/kernel/Base.cpp
Normal file
@@ -0,0 +1,320 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/io/json/JsonChain.h"
|
||||
#include "base/io/log/backends/ConsoleLog.h"
|
||||
#include "base/io/log/backends/FileLog.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/io/Watcher.h"
|
||||
#include "base/kernel/Base.h"
|
||||
#include "base/kernel/interfaces/IBaseListener.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
#include "base/kernel/Process.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/config/ConfigTransform.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
# include "base/io/log/backends/SysLog.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
# include "api/Api.h"
|
||||
# include "api/interfaces/IApiRequest.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
|
||||
# include "core/config/Config_default.h"
|
||||
#endif
|
||||
|
||||
|
||||
class xmrig::BasePrivate
|
||||
{
|
||||
public:
|
||||
inline BasePrivate(Process *process) :
|
||||
api(nullptr),
|
||||
config(nullptr),
|
||||
process(process),
|
||||
watcher(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
inline ~BasePrivate()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
delete api;
|
||||
# endif
|
||||
|
||||
delete config;
|
||||
delete watcher;
|
||||
}
|
||||
|
||||
|
||||
inline bool read(const JsonChain &chain, std::unique_ptr<Config> &config)
|
||||
{
|
||||
config = std::unique_ptr<Config>(new Config());
|
||||
|
||||
return config->read(chain, chain.fileName());
|
||||
}
|
||||
|
||||
|
||||
inline Config *load()
|
||||
{
|
||||
JsonChain chain;
|
||||
ConfigTransform transform;
|
||||
std::unique_ptr<Config> config;
|
||||
|
||||
transform.load(chain, process, transform);
|
||||
|
||||
if (read(chain, config)) {
|
||||
return config.release();
|
||||
}
|
||||
|
||||
chain.addFile(process->location(Process::ExeLocation, "config.json"));
|
||||
|
||||
if (read(chain, config)) {
|
||||
return config.release();
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
|
||||
chain.addRaw(default_config);
|
||||
|
||||
if (read(chain, config)) {
|
||||
return config.release();
|
||||
}
|
||||
# endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
inline void replace(Config *newConfig)
|
||||
{
|
||||
Config *previousConfig = config;
|
||||
config = newConfig;
|
||||
|
||||
for (IBaseListener *listener : listeners) {
|
||||
listener->onConfigChanged(config, previousConfig);
|
||||
}
|
||||
|
||||
delete previousConfig;
|
||||
}
|
||||
|
||||
|
||||
Api *api;
|
||||
Config *config;
|
||||
Process *process;
|
||||
std::vector<IBaseListener *> listeners;
|
||||
Watcher *watcher;
|
||||
};
|
||||
|
||||
|
||||
xmrig::Base::Base(Process *process)
|
||||
: d_ptr(new BasePrivate(process))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::Base::~Base()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Base::isReady() const
|
||||
{
|
||||
return d_ptr->config != nullptr;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::Base::init()
|
||||
{
|
||||
d_ptr->config = d_ptr->load();
|
||||
|
||||
if (!d_ptr->config) {
|
||||
LOG_EMERG("No valid configuration found. Exiting.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
d_ptr->api = new Api(this);
|
||||
d_ptr->api->addListener(this);
|
||||
# endif
|
||||
|
||||
Platform::init(config()->userAgent());
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
Platform::setProcessPriority(config()->cpu().priority());
|
||||
# endif
|
||||
|
||||
if (!config()->isBackground()) {
|
||||
Log::add(new ConsoleLog());
|
||||
}
|
||||
|
||||
if (config()->logFile()) {
|
||||
Log::add(new FileLog(config()->logFile()));
|
||||
}
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
if (config()->isSyslog()) {
|
||||
Log::add(new SysLog());
|
||||
}
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Base::start()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
api()->start();
|
||||
# endif
|
||||
|
||||
if (config()->isShouldSave()) {
|
||||
config()->save();
|
||||
}
|
||||
|
||||
if (config()->isWatch()) {
|
||||
d_ptr->watcher = new Watcher(config()->fileName(), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Base::stop()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
api()->stop();
|
||||
# endif
|
||||
|
||||
delete d_ptr->watcher;
|
||||
d_ptr->watcher = nullptr;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Api *xmrig::Base::api() const
|
||||
{
|
||||
assert(d_ptr->api != nullptr);
|
||||
|
||||
return d_ptr->api;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Base::reload(const rapidjson::Value &json)
|
||||
{
|
||||
JsonReader reader(json);
|
||||
if (reader.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Config *config = new Config();
|
||||
if (!config->read(reader, d_ptr->config->fileName())) {
|
||||
delete config;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool saved = config->save();
|
||||
|
||||
if (config->isWatch() && d_ptr->watcher && saved) {
|
||||
delete config;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
d_ptr->replace(config);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Config *xmrig::Base::config() const
|
||||
{
|
||||
assert(d_ptr->config != nullptr);
|
||||
|
||||
return d_ptr->config;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Base::addListener(IBaseListener *listener)
|
||||
{
|
||||
d_ptr->listeners.push_back(listener);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Base::onFileChanged(const String &fileName)
|
||||
{
|
||||
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
|
||||
|
||||
JsonChain chain;
|
||||
chain.addFile(fileName);
|
||||
|
||||
Config *config = new Config();
|
||||
|
||||
if (!config->read(chain, chain.fileName())) {
|
||||
LOG_ERR("reloading failed");
|
||||
|
||||
delete config;
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->replace(config);
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
void xmrig::Base::onRequest(IApiRequest &request)
|
||||
{
|
||||
if (request.method() == IApiRequest::METHOD_GET) {
|
||||
if (request.url() == "/1/config") {
|
||||
if (request.isRestricted()) {
|
||||
return request.done(403);
|
||||
}
|
||||
|
||||
request.accept();
|
||||
config()->getJSON(request.doc());
|
||||
}
|
||||
}
|
||||
else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) {
|
||||
if (request.url() == "/1/config") {
|
||||
request.accept();
|
||||
|
||||
if (!reload(request.json())) {
|
||||
return request.done(400);
|
||||
}
|
||||
|
||||
request.done(204);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -22,32 +22,55 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_JSON_H
|
||||
#define XMRIG_JSON_H
|
||||
#ifndef XMRIG_BASE_H
|
||||
#define XMRIG_BASE_H
|
||||
|
||||
|
||||
#include "api/interfaces/IApiListener.h"
|
||||
#include "base/kernel/interfaces/IConfigListener.h"
|
||||
#include "base/kernel/interfaces/IWatcherListener.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Json
|
||||
class Api;
|
||||
class BasePrivate;
|
||||
class Config;
|
||||
class IBaseListener;
|
||||
class Process;
|
||||
|
||||
|
||||
class Base : public IWatcherListener, public IApiListener
|
||||
{
|
||||
public:
|
||||
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
|
||||
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
|
||||
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
|
||||
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
|
||||
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
|
||||
static unsigned getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue = 0);
|
||||
Base(Process *process);
|
||||
~Base() override;
|
||||
|
||||
static bool get(const char *fileName, rapidjson::Document &doc);
|
||||
static bool save(const char *fileName, const rapidjson::Document &doc);
|
||||
virtual bool isReady() const;
|
||||
virtual int init();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
|
||||
Api *api() const;
|
||||
bool reload(const rapidjson::Value &json);
|
||||
Config *config() const;
|
||||
void addListener(IBaseListener *listener);
|
||||
|
||||
protected:
|
||||
void onFileChanged(const String &fileName) override;
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
void onRequest(IApiRequest &request) override;
|
||||
# endif
|
||||
|
||||
private:
|
||||
BasePrivate *d_ptr;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_JSON_H */
|
||||
#endif /* XMRIG_BASE_H */
|
||||
@@ -35,6 +35,15 @@
|
||||
class Platform
|
||||
{
|
||||
public:
|
||||
static inline bool trySetThreadAffinity(int64_t cpu_id)
|
||||
{
|
||||
if (cpu_id < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return setThreadAffinity(static_cast<uint64_t>(cpu_id));
|
||||
}
|
||||
|
||||
static bool setThreadAffinity(uint64_t cpu_id);
|
||||
static uint32_t setTimerResolution(uint32_t resolution);
|
||||
static void init(const char *userAgent);
|
||||
164
src/base/kernel/config/BaseConfig.cpp
Normal file
164
src/base/kernel/config/BaseConfig.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include <openssl/opensslv.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_AMD_PROJECT
|
||||
# if defined(__APPLE__)
|
||||
# include <OpenCL/cl.h>
|
||||
# else
|
||||
# include "3rdparty/CL/cl.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_NVIDIA_PROJECT
|
||||
# include "nvidia/cryptonight.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/config/BaseConfig.h"
|
||||
#include "base/kernel/interfaces/IJsonReader.h"
|
||||
#include "donate.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
xmrig::BaseConfig::BaseConfig()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseConfig::printVersions()
|
||||
{
|
||||
char buf[256] = { 0 };
|
||||
|
||||
# if defined(__clang__)
|
||||
snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
|
||||
# elif defined(__GNUC__)
|
||||
snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
|
||||
# elif defined(_MSC_VER)
|
||||
snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION);
|
||||
# endif
|
||||
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s"), "ABOUT", APP_NAME, APP_VERSION, buf);
|
||||
|
||||
# if defined(XMRIG_AMD_PROJECT)
|
||||
# if CL_VERSION_2_0
|
||||
const char *ocl = "2.0";
|
||||
# elif CL_VERSION_1_2
|
||||
const char *ocl = "1.2";
|
||||
# elif CL_VERSION_1_1
|
||||
const char *ocl = "1.1";
|
||||
# elif CL_VERSION_1_0
|
||||
const char *ocl = "1.0";
|
||||
# else
|
||||
const char *ocl = "0.0";
|
||||
# endif
|
||||
int length = snprintf(buf, sizeof buf, "OpenCL/%s ", ocl);
|
||||
# elif defined(XMRIG_NVIDIA_PROJECT)
|
||||
const int cudaVersion = cuda_get_runtime_version();
|
||||
int length = snprintf(buf, sizeof buf, "CUDA/%d.%d ", cudaVersion / 1000, cudaVersion % 100);
|
||||
# else
|
||||
memset(buf, 0, 16);
|
||||
|
||||
# if defined(XMRIG_FEATURE_HTTP) || defined(XMRIG_FEATURE_TLS)
|
||||
int length = 0;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
|
||||
{
|
||||
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
|
||||
length += snprintf(buf + length, (sizeof buf) - length, "OpenSSL/%.*s ", static_cast<int>(strchr(v, ' ') - v), v);
|
||||
}
|
||||
# endif
|
||||
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s"), "LIBS", uv_version_string(), buf);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
|
||||
{
|
||||
m_fileName = fileName;
|
||||
|
||||
if (reader.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_autoSave = reader.getBool("autosave", m_autoSave);
|
||||
m_background = reader.getBool("background", m_background);
|
||||
m_dryRun = reader.getBool("dry-run", m_dryRun);
|
||||
m_syslog = reader.getBool("syslog", m_syslog);
|
||||
m_watch = reader.getBool("watch", m_watch);
|
||||
Log::colors = reader.getBool("colors", Log::colors);
|
||||
m_logFile = reader.getString("log-file");
|
||||
m_userAgent = reader.getString("user-agent");
|
||||
|
||||
setPrintTime(reader.getUint("print-time", 60));
|
||||
|
||||
const rapidjson::Value &api = reader.getObject("api");
|
||||
if (api.IsObject()) {
|
||||
m_apiId = Json::getString(api, "id");
|
||||
m_apiWorkerId = Json::getString(api, "worker-id");
|
||||
}
|
||||
|
||||
m_http.load(reader.getObject("http"));
|
||||
m_pools.load(reader);
|
||||
|
||||
return m_pools.active() > 0;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::BaseConfig::save()
|
||||
{
|
||||
if (m_fileName.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rapidjson::Document doc;
|
||||
getJSON(doc);
|
||||
|
||||
if (Json::save(m_fileName, doc)) {
|
||||
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -22,81 +22,72 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_COMMONCONFIG_H
|
||||
#define XMRIG_COMMONCONFIG_H
|
||||
#ifndef XMRIG_BASECONFIG_H
|
||||
#define XMRIG_BASECONFIG_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IConfig.h"
|
||||
#include "base/net/http/Http.h"
|
||||
#include "base/net/stratum/Pools.h"
|
||||
#include "common/interfaces/IConfig.h"
|
||||
#include "common/xmrig.h"
|
||||
|
||||
|
||||
struct option;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class CommonConfig : public IConfig
|
||||
class IJsonReader;
|
||||
|
||||
|
||||
class BaseConfig : public IConfig
|
||||
{
|
||||
public:
|
||||
CommonConfig();
|
||||
BaseConfig();
|
||||
|
||||
inline bool isAutoSave() const { return m_autoSave; }
|
||||
inline bool isBackground() const { return m_background; }
|
||||
inline bool isDryRun() const { return m_dryRun; }
|
||||
inline bool isSyslog() const { return m_syslog; }
|
||||
inline const String &apiId() const { return m_apiId; }
|
||||
inline const String &apiWorkerId() const { return m_apiWorkerId; }
|
||||
inline const char *logFile() const { return m_logFile.data(); }
|
||||
inline const char *userAgent() const { return m_userAgent.data(); }
|
||||
inline const Http &http() const { return m_http; }
|
||||
inline const Pools &pools() const { return m_pools; }
|
||||
inline int printTime() const { return m_printTime; }
|
||||
inline const String &apiId() const { return m_apiId; }
|
||||
inline const String &apiWorkerId() const { return m_apiWorkerId; }
|
||||
inline uint32_t printTime() const { return m_printTime; }
|
||||
|
||||
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
|
||||
inline const Algorithm &algorithm() const override { return m_algorithm; }
|
||||
inline const String &fileName() const override { return m_fileName; }
|
||||
inline void setFileName(const char *fileName) override { m_fileName = fileName; }
|
||||
|
||||
bool read(const IJsonReader &reader, const char *fileName) override;
|
||||
bool save() override;
|
||||
|
||||
void printVersions();
|
||||
|
||||
protected:
|
||||
enum State {
|
||||
NoneState,
|
||||
ReadyState,
|
||||
ErrorState
|
||||
};
|
||||
|
||||
bool finalize() override;
|
||||
bool parseBoolean(int key, bool enable) override;
|
||||
bool parseString(int key, const char *arg) override;
|
||||
bool parseUint64(int key, uint64_t arg) override;
|
||||
void parseJSON(const rapidjson::Value &json) override;
|
||||
void setFileName(const char *fileName) override;
|
||||
|
||||
Algorithm m_algorithm;
|
||||
bool m_adjusted;
|
||||
bool m_autoSave;
|
||||
bool m_background;
|
||||
bool m_dryRun;
|
||||
bool m_syslog;
|
||||
bool m_upgrade;
|
||||
bool m_watch;
|
||||
bool m_autoSave = true;
|
||||
bool m_background = false;
|
||||
bool m_dryRun = false;
|
||||
bool m_syslog = false;
|
||||
bool m_upgrade = false;
|
||||
bool m_watch = true;
|
||||
Http m_http;
|
||||
int m_printTime;
|
||||
Pools m_pools;
|
||||
State m_state;
|
||||
String m_apiId;
|
||||
String m_apiWorkerId;
|
||||
String m_fileName;
|
||||
String m_logFile;
|
||||
String m_userAgent;
|
||||
uint32_t m_printTime;
|
||||
|
||||
private:
|
||||
bool parseInt(int key, int arg);
|
||||
inline void setPrintTime(uint32_t printTime) { if (printTime <= 3600) { m_printTime = printTime; } }
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
} // namespace xmrig
|
||||
|
||||
#endif /* XMRIG_COMMONCONFIG_H */
|
||||
|
||||
#endif /* XMRIG_BASECONFIG_H */
|
||||
269
src/base/kernel/config/BaseTransform.cpp
Normal file
269
src/base/kernel/config/BaseTransform.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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>
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include "getopt/getopt.h"
|
||||
#else
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "base/kernel/config/BaseTransform.h"
|
||||
#include "base/kernel/Process.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/interfaces/IConfig.h"
|
||||
#include "base/io/json/JsonChain.h"
|
||||
#include "core/config/Config_platform.h"
|
||||
|
||||
|
||||
namespace xmrig
|
||||
{
|
||||
|
||||
static const char *kAlgo = "algo";
|
||||
static const char *kApi = "api";
|
||||
static const char *kHttp = "http";
|
||||
static const char *kPools = "pools";
|
||||
|
||||
}
|
||||
|
||||
|
||||
xmrig::BaseTransform::BaseTransform()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTransform &transform)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
int key;
|
||||
int argc = process->arguments().argc();
|
||||
char **argv = process->arguments().argv();
|
||||
|
||||
Document doc(kObjectType);
|
||||
|
||||
while (1) {
|
||||
key = getopt_long(argc, argv, short_options, options, nullptr);
|
||||
if (key < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (key == IConfig::ConfigKey) {
|
||||
chain.add(std::move(doc));
|
||||
chain.addFile(optarg);
|
||||
|
||||
doc = Document(kObjectType);
|
||||
}
|
||||
else {
|
||||
transform.transform(doc, key, optarg);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
LOG_WARN("%s: unsupported non-option argument '%s'", argv[0], argv[optind]);
|
||||
}
|
||||
|
||||
transform.finalize(doc);
|
||||
chain.add(std::move(doc));
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseTransform::finalize(rapidjson::Document &doc)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
if (m_algorithm.isValid() && doc.HasMember(kPools)) {
|
||||
auto &pools = doc[kPools];
|
||||
for (Value &pool : pools.GetArray()) {
|
||||
if (!pool.HasMember(kAlgo)) {
|
||||
pool.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const char *arg)
|
||||
{
|
||||
switch (key) {
|
||||
case IConfig::AlgorithmKey: /* --algo */
|
||||
if (!doc.HasMember(kPools)) {
|
||||
m_algorithm = arg;
|
||||
}
|
||||
else {
|
||||
return add(doc, kPools, kAlgo, arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case IConfig::UserpassKey: /* --userpass */
|
||||
{
|
||||
const char *p = strrchr(arg, ':');
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *user = new char[p - arg + 1]();
|
||||
strncpy(user, arg, static_cast<size_t>(p - arg));
|
||||
|
||||
add<const char *>(doc, kPools, "user", user);
|
||||
add(doc, kPools, "pass", p + 1);
|
||||
delete [] user;
|
||||
}
|
||||
break;
|
||||
|
||||
case IConfig::UrlKey: /* --url */
|
||||
return add(doc, kPools, "url", arg, true);
|
||||
|
||||
case IConfig::UserKey: /* --user */
|
||||
return add(doc, kPools, "user", arg);
|
||||
|
||||
case IConfig::PasswordKey: /* --pass */
|
||||
return add(doc, kPools, "pass", arg);
|
||||
|
||||
case IConfig::RigIdKey: /* --rig-id */
|
||||
return add(doc, kPools, "rig-id", arg);
|
||||
|
||||
case IConfig::FingerprintKey: /* --tls-fingerprint */
|
||||
return add(doc, kPools, "tls-fingerprint", arg);
|
||||
|
||||
case IConfig::LogFileKey: /* --log-file */
|
||||
return set(doc, "log-file", arg);
|
||||
|
||||
case IConfig::HttpAccessTokenKey: /* --http-access-token */
|
||||
return set(doc, kHttp, "access-token", arg);
|
||||
|
||||
case IConfig::HttpHostKey: /* --http-host */
|
||||
return set(doc, kHttp, "host", arg);
|
||||
|
||||
case IConfig::ApiWorkerIdKey: /* --api-worker-id */
|
||||
return set(doc, kApi, "worker-id", arg);
|
||||
|
||||
case IConfig::ApiIdKey: /* --api-id */
|
||||
return set(doc, kApi, "id", arg);
|
||||
|
||||
case IConfig::UserAgentKey: /* --user-agent */
|
||||
return set(doc, "user-agent", arg);
|
||||
|
||||
case IConfig::RetriesKey: /* --retries */
|
||||
case IConfig::RetryPauseKey: /* --retry-pause */
|
||||
case IConfig::PrintTimeKey: /* --print-time */
|
||||
case IConfig::HttpPort: /* --http-port */
|
||||
case IConfig::DonateLevelKey: /* --donate-level */
|
||||
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
|
||||
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
|
||||
case IConfig::BackgroundKey: /* --background */
|
||||
case IConfig::SyslogKey: /* --syslog */
|
||||
case IConfig::KeepAliveKey: /* --keepalive */
|
||||
case IConfig::NicehashKey: /* --nicehash */
|
||||
case IConfig::TlsKey: /* --tls */
|
||||
case IConfig::DryRunKey: /* --dry-run */
|
||||
case IConfig::HttpEnabledKey: /* --http-enabled */
|
||||
case IConfig::DaemonKey: /* --daemon */
|
||||
return transformBoolean(doc, key, true);
|
||||
|
||||
case IConfig::ColorKey: /* --no-color */
|
||||
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
|
||||
return transformBoolean(doc, key, false);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, bool enable)
|
||||
{
|
||||
switch (key) {
|
||||
case IConfig::BackgroundKey: /* --background */
|
||||
return set(doc, "background", enable);
|
||||
|
||||
case IConfig::SyslogKey: /* --syslog */
|
||||
return set(doc, "syslog", enable);
|
||||
|
||||
case IConfig::KeepAliveKey: /* --keepalive */
|
||||
return add(doc, kPools, "keepalive", enable);
|
||||
|
||||
case IConfig::TlsKey: /* --tls */
|
||||
return add(doc, kPools, "tls", enable);
|
||||
|
||||
case IConfig::DaemonKey: /* --daemon */
|
||||
return add(doc, kPools, "daemon", enable);
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
case IConfig::NicehashKey: /* --nicehash */
|
||||
return add<bool>(doc, kPools, "nicehash", enable);
|
||||
# endif
|
||||
|
||||
case IConfig::ColorKey: /* --no-color */
|
||||
return set(doc, "colors", enable);
|
||||
|
||||
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
|
||||
return set(doc, kHttp, "restricted", enable);
|
||||
|
||||
case IConfig::HttpEnabledKey: /* --http-enabled */
|
||||
return set(doc, kHttp, "enabled", enable);
|
||||
|
||||
case IConfig::DryRunKey: /* --dry-run */
|
||||
return set(doc, "dry-run", enable);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, uint64_t arg)
|
||||
{
|
||||
switch (key) {
|
||||
case IConfig::RetriesKey: /* --retries */
|
||||
return set(doc, "retries", arg);
|
||||
|
||||
case IConfig::RetryPauseKey: /* --retry-pause */
|
||||
return set(doc, "retry-pause", arg);
|
||||
|
||||
case IConfig::DonateLevelKey: /* --donate-level */
|
||||
return set(doc, "donate-level", arg);
|
||||
|
||||
case IConfig::ProxyDonateKey: /* --donate-over-proxy */
|
||||
return set(doc, "donate-over-proxy", arg);
|
||||
|
||||
case IConfig::HttpPort: /* --http-port */
|
||||
return set(doc, kHttp, "port", arg);
|
||||
|
||||
case IConfig::PrintTimeKey: /* --print-time */
|
||||
return set(doc, "print-time", arg);
|
||||
|
||||
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
|
||||
return add(doc, kPools, "daemon-poll-interval", arg);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
127
src/base/kernel/config/BaseTransform.h
Normal file
127
src/base/kernel/config/BaseTransform.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_BASETRANSFORM_H
|
||||
#define XMRIG_BASETRANSFORM_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IConfigTransform.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
struct option;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConfigTransform;
|
||||
class JsonChain;
|
||||
class Process;
|
||||
|
||||
|
||||
class BaseTransform : public IConfigTransform
|
||||
{
|
||||
public:
|
||||
BaseTransform();
|
||||
|
||||
static void load(JsonChain &chain, Process *process, IConfigTransform &transform);
|
||||
|
||||
protected:
|
||||
void finalize(rapidjson::Document &doc) override;
|
||||
void transform(rapidjson::Document &doc, int key, const char *arg) override;
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void set(rapidjson::Document &doc, const char *key, T value) { set<T>(doc, doc, key, value); }
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void set(rapidjson::Document &doc, const char *objKey, const char *key, T value)
|
||||
{
|
||||
if (!doc.HasMember(objKey)) {
|
||||
doc.AddMember(rapidjson::StringRef(objKey), rapidjson::kObjectType, doc.GetAllocator());
|
||||
}
|
||||
|
||||
set<T>(doc, doc[objKey], key, value);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void add(rapidjson::Document &doc, const char *arrayKey, const char *key, T value, bool force = false)
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
if (!doc.HasMember(arrayKey)) {
|
||||
doc.AddMember(rapidjson::StringRef(arrayKey), rapidjson::kArrayType, allocator);
|
||||
}
|
||||
|
||||
rapidjson::Value &array = doc[arrayKey];
|
||||
if (force || array.Size() == 0) {
|
||||
array.PushBack(rapidjson::kObjectType, allocator);
|
||||
}
|
||||
|
||||
set<T>(doc, array[array.Size() - 1], key, value);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void set(rapidjson::Document &doc, rapidjson::Value &obj, const char *key, T value)
|
||||
{
|
||||
if (obj.HasMember(key)) {
|
||||
obj[key] = value;
|
||||
}
|
||||
else {
|
||||
obj.AddMember(rapidjson::StringRef(key), value, doc.GetAllocator());
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Algorithm m_algorithm;
|
||||
|
||||
|
||||
private:
|
||||
void transformBoolean(rapidjson::Document &doc, int key, bool enable);
|
||||
void transformUint64(rapidjson::Document &doc, int key, uint64_t arg);
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
inline void BaseTransform::set(rapidjson::Document &doc, rapidjson::Value &obj, const char *key, const char *value)
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
if (obj.HasMember(key)) {
|
||||
obj[key] = rapidjson::Value(value, allocator);
|
||||
}
|
||||
else {
|
||||
obj.AddMember(rapidjson::StringRef(key), rapidjson::Value(value, allocator), allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_BASETRANSFORM_H */
|
||||
@@ -22,8 +22,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ICONTROLLERLISTENER_H
|
||||
#define XMRIG_ICONTROLLERLISTENER_H
|
||||
#ifndef XMRIG_IBASELISTENER_H
|
||||
#define XMRIG_IBASELISTENER_H
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -32,10 +32,10 @@ namespace xmrig {
|
||||
class Config;
|
||||
|
||||
|
||||
class IControllerListener
|
||||
class IBaseListener
|
||||
{
|
||||
public:
|
||||
virtual ~IControllerListener() = default;
|
||||
virtual ~IBaseListener() = default;
|
||||
|
||||
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
|
||||
};
|
||||
@@ -44,4 +44,4 @@ public:
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ICONTROLLERLISTENER_H
|
||||
#endif // XMRIG_IBASELISTENER_H
|
||||
85
src/base/kernel/interfaces/IClient.h
Normal file
85
src/base/kernel/interfaces/IClient.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_ICLIENT_H
|
||||
#define XMRIG_ICLIENT_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Algorithm;
|
||||
class Job;
|
||||
class JobResult;
|
||||
class Pool;
|
||||
class String;
|
||||
|
||||
|
||||
class IClient
|
||||
{
|
||||
public:
|
||||
enum Extension {
|
||||
EXT_ALGO,
|
||||
EXT_NICEHASH,
|
||||
EXT_CONNECT,
|
||||
EXT_TLS,
|
||||
EXT_KEEPALIVE,
|
||||
EXT_MAX
|
||||
};
|
||||
|
||||
virtual ~IClient() = default;
|
||||
|
||||
virtual bool disconnect() = 0;
|
||||
virtual bool hasExtension(Extension extension) const noexcept = 0;
|
||||
virtual bool isEnabled() const = 0;
|
||||
virtual bool isTLS() const = 0;
|
||||
virtual const char *mode() const = 0;
|
||||
virtual const char *tlsFingerprint() const = 0;
|
||||
virtual const char *tlsVersion() const = 0;
|
||||
virtual const Job &job() const = 0;
|
||||
virtual const Pool &pool() const = 0;
|
||||
virtual const String &ip() const = 0;
|
||||
virtual int id() const = 0;
|
||||
virtual int64_t submit(const JobResult &result) = 0;
|
||||
virtual void connect() = 0;
|
||||
virtual void connect(const Pool &pool) = 0;
|
||||
virtual void deleteLater() = 0;
|
||||
virtual void setAlgo(const Algorithm &algo) = 0;
|
||||
virtual void setEnabled(bool enabled) = 0;
|
||||
virtual void setPool(const Pool &pool) = 0;
|
||||
virtual void setQuiet(bool quiet) = 0;
|
||||
virtual void setRetries(int retries) = 0;
|
||||
virtual void setRetryPause(uint64_t ms) = 0;
|
||||
virtual void tick(uint64_t now) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ICLIENT_H
|
||||
@@ -35,7 +35,8 @@
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Client;
|
||||
class Algorithm;
|
||||
class IClient;
|
||||
class Job;
|
||||
class SubmitResult;
|
||||
|
||||
@@ -45,11 +46,12 @@ class IClientListener
|
||||
public:
|
||||
virtual ~IClientListener() = default;
|
||||
|
||||
virtual void onClose(Client *client, int failures) = 0;
|
||||
virtual void onJobReceived(Client *client, const Job &job, const rapidjson::Value ¶ms) = 0;
|
||||
virtual void onLogin(Client *client, rapidjson::Document &doc, rapidjson::Value ¶ms) = 0;
|
||||
virtual void onLoginSuccess(Client *client) = 0;
|
||||
virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
|
||||
virtual void onClose(IClient *client, int failures) = 0;
|
||||
virtual void onJobReceived(IClient *client, const Job &job, const rapidjson::Value ¶ms) = 0;
|
||||
virtual void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) = 0;
|
||||
virtual void onLoginSuccess(IClient *client) = 0;
|
||||
virtual void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) = 0;
|
||||
virtual void onVerifyAlgorithm(const IClient *client, const Algorithm &algorithm, bool *ok) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -26,13 +26,14 @@
|
||||
#define XMRIG_ICONFIG_H
|
||||
|
||||
|
||||
#include "common/crypto/Algorithm.h"
|
||||
#include "crypto/common/Algorithm.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IJsonReader;
|
||||
class String;
|
||||
|
||||
|
||||
@@ -64,20 +65,12 @@ public:
|
||||
UserAgentKey = 1008,
|
||||
UserKey = 'u',
|
||||
UserpassKey = 'O',
|
||||
VariantKey = 1010,
|
||||
VerboseKey = 1100,
|
||||
WatchKey = 1105,
|
||||
TlsKey = 1013,
|
||||
FingerprintKey = 1014,
|
||||
AutoSaveKey = 1016,
|
||||
ProxyDonateKey = 1017,
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
ApiPort = 4000,
|
||||
ApiAccessTokenKey = 4001,
|
||||
ApiIPv6Key = 4003,
|
||||
ApiRestrictedKey = 4004,
|
||||
# endif
|
||||
DaemonKey = 1018,
|
||||
DaemonPollKey = 1019,
|
||||
|
||||
// xmrig common
|
||||
CPUPriorityKey = 1021,
|
||||
@@ -89,10 +82,8 @@ public:
|
||||
CPUAffinityKey = 1020,
|
||||
DryRunKey = 5000,
|
||||
HugePagesKey = 1009,
|
||||
MaxCPUUsageKey = 1004,
|
||||
SafeKey = 1005,
|
||||
ThreadsKey = 't',
|
||||
HardwareAESKey = 1011,
|
||||
// HardwareAESKey = 1011,
|
||||
AssemblyKey = 1015,
|
||||
|
||||
// xmrig amd
|
||||
@@ -111,7 +102,6 @@ public:
|
||||
// xmrig-proxy
|
||||
AccessLogFileKey = 'A',
|
||||
BindKey = 'b',
|
||||
CoinKey = 1104,
|
||||
CustomDiffKey = 1102,
|
||||
DebugKey = 1101,
|
||||
ModeKey = 'm',
|
||||
@@ -141,16 +131,11 @@ public:
|
||||
|
||||
virtual ~IConfig() = default;
|
||||
|
||||
virtual bool finalize() = 0;
|
||||
virtual bool isWatch() const = 0;
|
||||
virtual bool parseBoolean(int key, bool enable) = 0;
|
||||
virtual bool parseString(int key, const char *arg) = 0;
|
||||
virtual bool parseUint64(int key, uint64_t arg) = 0;
|
||||
virtual bool read(const IJsonReader &reader, const char *fileName) = 0;
|
||||
virtual bool save() = 0;
|
||||
virtual const Algorithm &algorithm() const = 0;
|
||||
virtual const String &fileName() const = 0;
|
||||
virtual void getJSON(rapidjson::Document &doc) const = 0;
|
||||
virtual void parseJSON(const rapidjson::Value &json) = 0;
|
||||
virtual void setFileName(const char *fileName) = 0;
|
||||
};
|
||||
|
||||
@@ -22,40 +22,32 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CONFIGWATCHER_H
|
||||
#define XMRIG_CONFIGWATCHER_H
|
||||
#ifndef XMRIG_ICONFIGTRANSFORM_H
|
||||
#define XMRIG_ICONFIGTRANSFORM_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IWatcherListener.h"
|
||||
#include "base/tools/String.h"
|
||||
#include "crypto/common/Algorithm.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
struct option;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConfigListener;
|
||||
class Watcher;
|
||||
class IJsonReader;
|
||||
class String;
|
||||
|
||||
|
||||
class ConfigWatcher : public IWatcherListener
|
||||
class IConfigTransform
|
||||
{
|
||||
public:
|
||||
ConfigWatcher(const String &path, IConfigListener *listener);
|
||||
~ConfigWatcher() override;
|
||||
virtual ~IConfigTransform() = default;
|
||||
|
||||
protected:
|
||||
void onFileChanged(const String &fileName) override;
|
||||
|
||||
private:
|
||||
IConfigListener *m_listener;
|
||||
Watcher *m_watcher;
|
||||
virtual void finalize(rapidjson::Document &doc) = 0;
|
||||
virtual void transform(rapidjson::Document &doc, int key, const char *arg) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* __CONFIGWATCHER_H__ */
|
||||
|
||||
#endif // XMRIG_ICONFIGTRANSFORM_H
|
||||
@@ -29,7 +29,7 @@
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpRequest;
|
||||
class HttpData;
|
||||
class HttpResponse;
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class IHttpListener
|
||||
public:
|
||||
virtual ~IHttpListener() = default;
|
||||
|
||||
virtual void onHttpRequest(const HttpRequest &req) = 0;
|
||||
virtual void onHttpData(const HttpData &data) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
56
src/base/kernel/interfaces/IJsonReader.h
Normal file
56
src/base/kernel/interfaces/IJsonReader.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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_IJSONREADER_H
|
||||
#define XMRIG_IJSONREADER_H
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IJsonReader
|
||||
{
|
||||
public:
|
||||
virtual ~IJsonReader() = default;
|
||||
|
||||
virtual bool getBool(const char *key, bool defaultValue = false) const = 0;
|
||||
virtual bool isEmpty() const = 0;
|
||||
virtual const char *getString(const char *key, const char *defaultValue = nullptr) const = 0;
|
||||
virtual const rapidjson::Value &getArray(const char *key) const = 0;
|
||||
virtual const rapidjson::Value &getObject(const char *key) const = 0;
|
||||
virtual const rapidjson::Value &getValue(const char *key) const = 0;
|
||||
virtual int getInt(const char *key, int defaultValue = 0) const = 0;
|
||||
virtual int64_t getInt64(const char *key, int64_t defaultValue = 0) const = 0;
|
||||
virtual uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const = 0;
|
||||
virtual unsigned getUint(const char *key, unsigned defaultValue = 0) const = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_IJSONREADER_H
|
||||
@@ -33,7 +33,7 @@ namespace xmrig {
|
||||
|
||||
|
||||
class Algorithm;
|
||||
class Client;
|
||||
class IClient;
|
||||
class JobResult;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
virtual ~IStrategy() = default;
|
||||
|
||||
virtual bool isActive() const = 0;
|
||||
virtual Client *client() const = 0;
|
||||
virtual IClient *client() const = 0;
|
||||
virtual int64_t submit(const JobResult &result) = 0;
|
||||
virtual void connect() = 0;
|
||||
virtual void resume() = 0;
|
||||
|
||||
@@ -26,13 +26,14 @@
|
||||
#define XMRIG_ISTRATEGYLISTENER_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Client;
|
||||
class Algorithm;
|
||||
class IClient;
|
||||
class IStrategy;
|
||||
class Job;
|
||||
class SubmitResult;
|
||||
@@ -43,10 +44,12 @@ class IStrategyListener
|
||||
public:
|
||||
virtual ~IStrategyListener() = default;
|
||||
|
||||
virtual void onActive(IStrategy *strategy, Client *client) = 0;
|
||||
virtual void onJob(IStrategy *strategy, Client *client, const Job &job) = 0;
|
||||
virtual void onActive(IStrategy *strategy, IClient *client) = 0;
|
||||
virtual void onJob(IStrategy *strategy, IClient *client, const Job &job) = 0;
|
||||
virtual void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) = 0;
|
||||
virtual void onPause(IStrategy *strategy) = 0;
|
||||
virtual void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) = 0;
|
||||
virtual void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) = 0;
|
||||
virtual void onVerifyAlgorithm(IStrategy *strategy, const IClient *client, const Algorithm &algorithm, bool *ok) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -144,7 +144,11 @@ void xmrig::Dns::onResolved(int status, addrinfo *res)
|
||||
ptr = ptr->ai_next;
|
||||
}
|
||||
|
||||
m_listener->onResolved(*this, status);
|
||||
if (isEmpty()) {
|
||||
m_status = UV_EAI_NONAME;
|
||||
}
|
||||
|
||||
m_listener->onResolved(*this, m_status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
~Dns();
|
||||
|
||||
inline bool isEmpty() const { return m_ipv4.empty() && m_ipv6.empty(); }
|
||||
inline const String &host() const { return m_host; }
|
||||
inline int status() const { return m_status; }
|
||||
|
||||
bool resolve(const String &host);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "base/io/Json.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/net/http/Http.h"
|
||||
|
||||
|
||||
|
||||
224
src/base/net/http/HttpClient.cpp
Normal file
224
src/base/net/http/HttpClient.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/* 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 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 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 <sstream>
|
||||
|
||||
|
||||
#include "3rdparty/http-parser/http_parser.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
#include "base/net/dns/Dns.h"
|
||||
#include "base/net/http/HttpClient.h"
|
||||
#include "base/tools/Baton.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char *kCRLF = "\r\n";
|
||||
|
||||
|
||||
class ClientWriteBaton : public Baton<uv_write_t>
|
||||
{
|
||||
public:
|
||||
inline ClientWriteBaton(const std::string &header, std::string &&body) :
|
||||
m_body(std::move(body)),
|
||||
m_header(header)
|
||||
{
|
||||
bufs[0].len = m_header.size();
|
||||
bufs[0].base = const_cast<char *>(m_header.c_str());
|
||||
|
||||
if (!m_body.empty()) {
|
||||
bufs[1].len = m_body.size();
|
||||
bufs[1].base = const_cast<char *>(m_body.c_str());
|
||||
}
|
||||
else {
|
||||
bufs[1].base = nullptr;
|
||||
bufs[1].len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; }
|
||||
inline size_t size() const { return bufs[0].len + bufs[1].len; }
|
||||
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<ClientWriteBaton *>(req->data); }
|
||||
|
||||
|
||||
uv_buf_t bufs[2];
|
||||
|
||||
private:
|
||||
std::string m_body;
|
||||
std::string m_header;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HttpClient::HttpClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) :
|
||||
HttpContext(HTTP_RESPONSE, listener),
|
||||
m_quiet(false),
|
||||
m_port(0)
|
||||
{
|
||||
this->method = method;
|
||||
this->url = url;
|
||||
|
||||
if (data) {
|
||||
body = size ? std::string(data, size) : data;
|
||||
}
|
||||
|
||||
m_dns = new Dns(this);
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpClient::~HttpClient()
|
||||
{
|
||||
delete m_dns;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpClient::connect(const String &host, uint16_t port)
|
||||
{
|
||||
m_port = port;
|
||||
|
||||
return m_dns->resolve(host);
|
||||
}
|
||||
|
||||
|
||||
const xmrig::String &xmrig::HttpClient::host() const
|
||||
{
|
||||
return m_dns->host();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpClient::onResolved(const Dns &dns, int status)
|
||||
{
|
||||
this->status = status;
|
||||
|
||||
if (status < 0 && dns.isEmpty()) {
|
||||
if (!m_quiet) {
|
||||
LOG_ERR("[%s:%d] DNS error: \"%s\"", dns.host().data(), m_port, uv_strerror(status));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sockaddr *addr = dns.get().addr(m_port);
|
||||
|
||||
uv_connect_t *req = new uv_connect_t;
|
||||
req->data = this;
|
||||
|
||||
uv_tcp_connect(req, m_tcp, addr, onConnect);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpClient::handshake()
|
||||
{
|
||||
headers.insert({ "Host", m_dns->host().data() });
|
||||
headers.insert({ "Connection", "close" });
|
||||
headers.insert({ "User-Agent", Platform::userAgent() });
|
||||
|
||||
if (body.size()) {
|
||||
headers.insert({ "Content-Length", std::to_string(body.size()) });
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << http_method_str(static_cast<http_method>(method)) << " " << url << " HTTP/1.1" << kCRLF;
|
||||
|
||||
for (auto &header : headers) {
|
||||
ss << header.first << ": " << header.second << kCRLF;
|
||||
}
|
||||
|
||||
ss << kCRLF;
|
||||
|
||||
headers.clear();
|
||||
|
||||
write(ss.str());
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpClient::read(const char *data, size_t size)
|
||||
{
|
||||
if (parse(data, size) < size) {
|
||||
close(UV_EPROTO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpClient::write(const std::string &header)
|
||||
{
|
||||
ClientWriteBaton *baton = new ClientWriteBaton(header, std::move(body));
|
||||
uv_write(&baton->req, stream(), baton->bufs, baton->count(), ClientWriteBaton::onWrite);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
|
||||
{
|
||||
HttpClient *client = static_cast<HttpClient *>(req->data);
|
||||
if (!client) {
|
||||
delete req;
|
||||
return;
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
if (!client->m_quiet) {
|
||||
LOG_ERR("[%s:%d] connect error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(status));
|
||||
}
|
||||
|
||||
delete req;
|
||||
client->close(status);
|
||||
return;
|
||||
}
|
||||
|
||||
uv_read_start(client->stream(),
|
||||
[](uv_handle_t *, size_t suggested_size, uv_buf_t *buf)
|
||||
{
|
||||
buf->base = new char[suggested_size];
|
||||
|
||||
# ifdef _WIN32
|
||||
buf->len = static_cast<unsigned int>(suggested_size);
|
||||
# else
|
||||
buf->len = suggested_size;
|
||||
# endif
|
||||
},
|
||||
[](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
|
||||
{
|
||||
HttpClient *client = static_cast<HttpClient*>(tcp->data);
|
||||
|
||||
if (nread >= 0) {
|
||||
client->read(buf->base, static_cast<size_t>(nread));
|
||||
} else {
|
||||
if (!client->m_quiet && nread != UV_EOF) {
|
||||
LOG_ERR("[%s:%d] read error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(static_cast<int>(nread)));
|
||||
}
|
||||
|
||||
client->close(static_cast<int>(nread));
|
||||
}
|
||||
|
||||
delete [] buf->base;
|
||||
});
|
||||
|
||||
client->handshake();
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
* 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 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
@@ -22,50 +23,52 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CONFIGLOADER_H
|
||||
#define XMRIG_CONFIGLOADER_H
|
||||
|
||||
#ifndef XMRIG_HTTPCLIENT_H
|
||||
#define XMRIG_HTTPCLIENT_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
struct option;
|
||||
#include "base/net/http/HttpContext.h"
|
||||
#include "base/kernel/interfaces/IDnsListener.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ConfigWatcher;
|
||||
class IConfigListener;
|
||||
class IConfig;
|
||||
class Process;
|
||||
class String;
|
||||
|
||||
|
||||
class ConfigLoader
|
||||
class HttpClient : public HttpContext, public IDnsListener
|
||||
{
|
||||
public:
|
||||
static bool loadFromFile(IConfig *config, const char *fileName);
|
||||
static bool loadFromJSON(IConfig *config, const char *json);
|
||||
static bool loadFromJSON(IConfig *config, const rapidjson::Value &json);
|
||||
static bool reload(IConfig *oldConfig, const rapidjson::Value &json);
|
||||
static bool watch(IConfig *config);
|
||||
static IConfig *load(Process *process, IConfigListener *listener);
|
||||
static void release();
|
||||
HttpClient(int method, const String &url, IHttpListener *listener, const char *data = nullptr, size_t size = 0);
|
||||
~HttpClient() override;
|
||||
|
||||
inline uint16_t port() const { return m_port; }
|
||||
inline void setQuiet(bool quiet) { m_quiet = quiet; }
|
||||
|
||||
bool connect(const String &host, uint16_t port);
|
||||
const String &host() const;
|
||||
|
||||
protected:
|
||||
void onResolved(const Dns &dns, int status) override;
|
||||
|
||||
virtual void handshake();
|
||||
virtual void read(const char *data, size_t size);
|
||||
virtual void write(const std::string &header);
|
||||
|
||||
bool m_quiet;
|
||||
|
||||
private:
|
||||
static bool getJSON(const char *fileName, rapidjson::Document &doc);
|
||||
static bool parseArg(IConfig *config, int key, const char *arg);
|
||||
static void parseJSON(IConfig *config, const struct option *option, const rapidjson::Value &object);
|
||||
static void onConnect(uv_connect_t *req, int status);
|
||||
|
||||
static ConfigWatcher *m_watcher;
|
||||
static IConfigListener *m_listener;
|
||||
Dns *m_dns;
|
||||
uint16_t m_port;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_CONFIGLOADER_H */
|
||||
#endif // XMRIG_HTTPCLIENT_H
|
||||
|
||||
@@ -35,43 +35,77 @@
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static http_parser_settings http_settings;
|
||||
static std::map<uint64_t, HttpContext *> storage;
|
||||
static uint64_t SEQUENCE = 0;
|
||||
std::map<uint64_t, HttpContext *> HttpContext::m_storage;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HttpContext::HttpContext(int parser_type, IHttpListener *listener) :
|
||||
HttpRequest(SEQUENCE++),
|
||||
listener(listener),
|
||||
connect(nullptr),
|
||||
m_wasHeaderValue(false)
|
||||
HttpData(SEQUENCE++),
|
||||
m_wasHeaderValue(false),
|
||||
m_listener(listener)
|
||||
{
|
||||
m_storage[id()] = this;
|
||||
storage[id()] = this;
|
||||
|
||||
parser = new http_parser;
|
||||
tcp = new uv_tcp_t;
|
||||
m_parser = new http_parser;
|
||||
m_tcp = new uv_tcp_t;
|
||||
|
||||
uv_tcp_init(uv_default_loop(), tcp);
|
||||
http_parser_init(parser, static_cast<http_parser_type>(parser_type));
|
||||
uv_tcp_init(uv_default_loop(), m_tcp);
|
||||
uv_tcp_nodelay(m_tcp, 1);
|
||||
|
||||
parser->data = tcp->data = this;
|
||||
http_parser_init(m_parser, static_cast<http_parser_type>(parser_type));
|
||||
|
||||
m_parser->data = m_tcp->data = this;
|
||||
|
||||
if (http_settings.on_message_complete == nullptr) {
|
||||
attach(&http_settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpContext::~HttpContext()
|
||||
{
|
||||
delete connect;
|
||||
delete tcp;
|
||||
delete parser;
|
||||
delete m_tcp;
|
||||
delete m_parser;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::close()
|
||||
size_t xmrig::HttpContext::parse(const char *data, size_t size)
|
||||
{
|
||||
auto it = m_storage.find(id());
|
||||
if (it != m_storage.end()) {
|
||||
m_storage.erase(it);
|
||||
return http_parser_execute(m_parser, &http_settings, data, size);
|
||||
}
|
||||
|
||||
|
||||
std::string xmrig::HttpContext::ip() const
|
||||
{
|
||||
char ip[46] = {};
|
||||
sockaddr_storage addr = {};
|
||||
int size = sizeof(addr);
|
||||
|
||||
uv_tcp_getpeername(m_tcp, reinterpret_cast<sockaddr*>(&addr), &size);
|
||||
if (reinterpret_cast<sockaddr_in *>(&addr)->sin_family == AF_INET6) {
|
||||
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(&addr), ip, 45);
|
||||
}
|
||||
else {
|
||||
uv_ip4_name(reinterpret_cast<sockaddr_in*>(&addr), ip, 16);
|
||||
}
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::close(int status)
|
||||
{
|
||||
if (status < 0 && m_listener) {
|
||||
this->status = status;
|
||||
m_listener->onHttpData(*this);
|
||||
}
|
||||
|
||||
auto it = storage.find(id());
|
||||
if (it != storage.end()) {
|
||||
storage.erase(it);
|
||||
}
|
||||
|
||||
if (!uv_is_closing(handle())) {
|
||||
@@ -82,65 +116,17 @@ void xmrig::HttpContext::close()
|
||||
|
||||
xmrig::HttpContext *xmrig::HttpContext::get(uint64_t id)
|
||||
{
|
||||
if (m_storage.count(id) == 0) {
|
||||
if (storage.count(id) == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_storage[id];
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::attach(http_parser_settings *settings)
|
||||
{
|
||||
if (settings->on_message_complete != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
settings->on_message_begin = nullptr;
|
||||
settings->on_status = nullptr;
|
||||
settings->on_chunk_header = nullptr;
|
||||
settings->on_chunk_complete = nullptr;
|
||||
|
||||
settings->on_url = [](http_parser *parser, const char *at, size_t length) -> int
|
||||
{
|
||||
static_cast<HttpContext*>(parser->data)->url = std::string(at, length);
|
||||
return 0;
|
||||
};
|
||||
|
||||
settings->on_header_field = onHeaderField;
|
||||
settings->on_header_value = onHeaderValue;
|
||||
|
||||
settings->on_headers_complete = [](http_parser* parser) -> int {
|
||||
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||
ctx->method = parser->method;
|
||||
|
||||
if (!ctx->m_lastHeaderField.empty()) {
|
||||
ctx->setHeader();
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
settings->on_body = [](http_parser *parser, const char *at, size_t len) -> int
|
||||
{
|
||||
static_cast<HttpContext*>(parser->data)->body += std::string(at, len);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
settings->on_message_complete = [](http_parser *parser) -> int
|
||||
{
|
||||
const HttpContext *ctx = reinterpret_cast<const HttpContext*>(parser->data);
|
||||
ctx->listener->onHttpRequest(*ctx);
|
||||
|
||||
return 0;
|
||||
};
|
||||
return storage[id];
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::closeAll()
|
||||
{
|
||||
for (auto kv : m_storage) {
|
||||
for (auto kv : storage) {
|
||||
if (!uv_is_closing(kv.second->handle())) {
|
||||
uv_close(kv.second->handle(), [](uv_handle_t *handle) -> void { delete reinterpret_cast<HttpContext*>(handle->data); });
|
||||
}
|
||||
@@ -182,6 +168,55 @@ int xmrig::HttpContext::onHeaderValue(http_parser *parser, const char *at, size_
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::attach(http_parser_settings *settings)
|
||||
{
|
||||
settings->on_message_begin = nullptr;
|
||||
settings->on_status = nullptr;
|
||||
settings->on_chunk_header = nullptr;
|
||||
settings->on_chunk_complete = nullptr;
|
||||
|
||||
settings->on_url = [](http_parser *parser, const char *at, size_t length) -> int
|
||||
{
|
||||
static_cast<HttpContext*>(parser->data)->url = std::string(at, length);
|
||||
return 0;
|
||||
};
|
||||
|
||||
settings->on_header_field = onHeaderField;
|
||||
settings->on_header_value = onHeaderValue;
|
||||
|
||||
settings->on_headers_complete = [](http_parser* parser) -> int {
|
||||
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||
ctx->status = parser->status_code;
|
||||
|
||||
if (parser->type == HTTP_REQUEST) {
|
||||
ctx->method = parser->method;
|
||||
}
|
||||
|
||||
if (!ctx->m_lastHeaderField.empty()) {
|
||||
ctx->setHeader();
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
settings->on_body = [](http_parser *parser, const char *at, size_t len) -> int
|
||||
{
|
||||
static_cast<HttpContext*>(parser->data)->body += std::string(at, len);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
settings->on_message_complete = [](http_parser *parser) -> int
|
||||
{
|
||||
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||
ctx->m_listener->onHttpData(*ctx);
|
||||
ctx->m_listener = nullptr;
|
||||
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::setHeader()
|
||||
{
|
||||
std::transform(m_lastHeaderField.begin(), m_lastHeaderField.end(), m_lastHeaderField.begin(), ::tolower);
|
||||
|
||||
@@ -36,7 +36,7 @@ typedef struct uv_stream_s uv_stream_t;
|
||||
typedef struct uv_tcp_s uv_tcp_t;
|
||||
|
||||
|
||||
#include "base/net/http/HttpRequest.h"
|
||||
#include "base/net/http/HttpData.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -45,37 +45,37 @@ namespace xmrig {
|
||||
class IHttpListener;
|
||||
|
||||
|
||||
class HttpContext : public HttpRequest
|
||||
class HttpContext : public HttpData
|
||||
{
|
||||
public:
|
||||
HttpContext(int parser_type, IHttpListener *listener);
|
||||
~HttpContext();
|
||||
virtual ~HttpContext();
|
||||
|
||||
inline uv_stream_t *stream() const { return reinterpret_cast<uv_stream_t *>(tcp); }
|
||||
inline uv_handle_t *handle() const { return reinterpret_cast<uv_handle_t *>(tcp); }
|
||||
inline uv_stream_t *stream() const { return reinterpret_cast<uv_stream_t *>(m_tcp); }
|
||||
inline uv_handle_t *handle() const { return reinterpret_cast<uv_handle_t *>(m_tcp); }
|
||||
|
||||
void close();
|
||||
size_t parse(const char *data, size_t size);
|
||||
std::string ip() const;
|
||||
void close(int status = 0);
|
||||
|
||||
static HttpContext *get(uint64_t id);
|
||||
static void attach(http_parser_settings *settings);
|
||||
static void closeAll();
|
||||
|
||||
http_parser *parser;
|
||||
IHttpListener *listener;
|
||||
uv_connect_t *connect;
|
||||
uv_tcp_t *tcp;
|
||||
protected:
|
||||
uv_tcp_t *m_tcp;
|
||||
|
||||
private:
|
||||
static int onHeaderField(http_parser *parser, const char *at, size_t length);
|
||||
static int onHeaderValue(http_parser *parser, const char *at, size_t length);
|
||||
static void attach(http_parser_settings *settings);
|
||||
|
||||
void setHeader();
|
||||
|
||||
bool m_wasHeaderValue;
|
||||
http_parser *m_parser;
|
||||
IHttpListener *m_listener;
|
||||
std::string m_lastHeaderField;
|
||||
std::string m_lastHeaderValue;
|
||||
|
||||
static std::map<uint64_t, HttpContext *> m_storage;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -24,26 +24,26 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_HTTPREQUEST_H
|
||||
#define XMRIG_HTTPREQUEST_H
|
||||
#ifndef XMRIG_HTTPDATA_H
|
||||
#define XMRIG_HTTPDATA_H
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpRequest
|
||||
class HttpData
|
||||
{
|
||||
public:
|
||||
inline HttpRequest(uint64_t id) : method(0), m_id(id) {}
|
||||
inline HttpData(uint64_t id) : method(0), status(0), m_id(id) {}
|
||||
|
||||
inline uint64_t id() const { return m_id; }
|
||||
|
||||
int method;
|
||||
int status;
|
||||
std::map<const std::string, const std::string> headers;
|
||||
std::string body;
|
||||
std::string url;
|
||||
@@ -56,5 +56,5 @@ private:
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTPREQUEST_H
|
||||
#endif // XMRIG_HTTPDATA_H
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/http/HttpContext.h"
|
||||
#include "base/net/http/HttpResponse.h"
|
||||
#include "base/tools/Baton.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -40,6 +41,51 @@ namespace xmrig {
|
||||
static const char *kCRLF = "\r\n";
|
||||
static const char *kUserAgent = "user-agent";
|
||||
|
||||
|
||||
class WriteBaton : public Baton<uv_write_t>
|
||||
{
|
||||
public:
|
||||
inline WriteBaton(const std::stringstream &ss, const char *data, size_t size, HttpContext *ctx) :
|
||||
m_ctx(ctx),
|
||||
m_header(ss.str())
|
||||
{
|
||||
bufs[0].len = m_header.size();
|
||||
bufs[0].base = const_cast<char *>(m_header.c_str());
|
||||
|
||||
if (data) {
|
||||
bufs[1].len = size;
|
||||
bufs[1].base = new char[size];
|
||||
memcpy(bufs[1].base, data, size);
|
||||
}
|
||||
else {
|
||||
bufs[1].base = nullptr;
|
||||
bufs[1].len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline ~WriteBaton()
|
||||
{
|
||||
if (count() == 2) {
|
||||
delete [] bufs[1].base;
|
||||
}
|
||||
|
||||
m_ctx->close();
|
||||
}
|
||||
|
||||
|
||||
inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; }
|
||||
inline size_t size() const { return bufs[0].len + bufs[1].len; }
|
||||
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<WriteBaton *>(req->data); }
|
||||
|
||||
|
||||
uv_buf_t bufs[2];
|
||||
|
||||
private:
|
||||
HttpContext *m_ctx;
|
||||
std::string m_header;
|
||||
};
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
@@ -82,58 +128,26 @@ void xmrig::HttpResponse::end(const char *data, size_t size)
|
||||
}
|
||||
|
||||
ss << kCRLF;
|
||||
const std::string header = ss.str();
|
||||
|
||||
uv_buf_t bufs[2];
|
||||
bufs[0].base = const_cast<char *>(header.c_str());
|
||||
|
||||
# ifdef _WIN32
|
||||
bufs[0].len = static_cast<unsigned int>(header.size());
|
||||
# else
|
||||
bufs[0].len = header.size();
|
||||
# endif
|
||||
|
||||
if (data) {
|
||||
bufs[1].base = const_cast<char *>(data);
|
||||
|
||||
# ifdef _WIN32
|
||||
bufs[1].len = static_cast<unsigned int>(size);
|
||||
# else
|
||||
bufs[1].len = size;
|
||||
# endif
|
||||
}
|
||||
|
||||
HttpContext *ctx = HttpContext::get(m_id);
|
||||
WriteBaton *baton = new WriteBaton(ss, data, size, ctx);
|
||||
|
||||
# ifndef APP_DEBUG
|
||||
if (statusCode() >= 400)
|
||||
# endif
|
||||
{
|
||||
const bool err = statusCode() >= 400;
|
||||
char ip[46] = {};
|
||||
sockaddr_storage addr = {};
|
||||
int aSize = sizeof(addr);
|
||||
|
||||
uv_tcp_getpeername(ctx->tcp, reinterpret_cast<sockaddr*>(&addr), &aSize);
|
||||
if (reinterpret_cast<sockaddr_in *>(&addr)->sin_family == AF_INET6) {
|
||||
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(&addr), ip, 45);
|
||||
}
|
||||
else {
|
||||
uv_ip4_name(reinterpret_cast<sockaddr_in*>(&addr), ip, 16);
|
||||
}
|
||||
|
||||
Log::print(err ? Log::ERR : Log::INFO, CYAN("%s ") CLEAR MAGENTA_BOLD("%s") WHITE_BOLD(" %s ") CSI "1;%dm%d " CLEAR WHITE_BOLD("%zu ") BLACK_BOLD("\"%s\""),
|
||||
ip,
|
||||
ctx->ip().c_str(),
|
||||
http_method_str(static_cast<http_method>(ctx->method)),
|
||||
ctx->url.c_str(),
|
||||
err ? 31 : 32,
|
||||
statusCode(),
|
||||
header.size() + size,
|
||||
baton->size(),
|
||||
ctx->headers.count(kUserAgent) ? ctx->headers.at(kUserAgent).c_str() : nullptr
|
||||
);
|
||||
}
|
||||
|
||||
uv_try_write(ctx->stream(), bufs, data ? 2 : 1);
|
||||
|
||||
ctx->close();
|
||||
uv_write(&baton->req, ctx->stream(), baton->bufs, baton->count(), WriteBaton::onWrite);
|
||||
}
|
||||
|
||||
@@ -35,17 +35,9 @@
|
||||
#include "base/net/http/HttpServer.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static http_parser_settings http_settings;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HttpServer::HttpServer(IHttpListener *listener) :
|
||||
m_listener(listener)
|
||||
{
|
||||
HttpContext::attach(&http_settings);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +69,7 @@ void xmrig::HttpServer::onConnection(uv_stream_t *stream, uint16_t)
|
||||
|
||||
if (nread >= 0) {
|
||||
const size_t size = static_cast<size_t>(nread);
|
||||
const size_t parsed = http_parser_execute(ctx->parser, &http_settings, buf->base, size);
|
||||
const size_t parsed = ctx->parse(buf->base, size);
|
||||
|
||||
if (parsed < size) {
|
||||
ctx->close();
|
||||
|
||||
208
src/base/net/http/HttpsClient.cpp
Normal file
208
src/base/net/http/HttpsClient.cpp
Normal file
@@ -0,0 +1,208 @@
|
||||
/* 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 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/http/HttpsClient.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::HttpsClient::HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint) :
|
||||
HttpClient(method, url, listener, data, size),
|
||||
m_ready(false),
|
||||
m_buf(),
|
||||
m_ssl(nullptr),
|
||||
m_fp(fingerprint)
|
||||
{
|
||||
m_ctx = SSL_CTX_new(SSLv23_method());
|
||||
assert(m_ctx != nullptr);
|
||||
|
||||
if (!m_ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_writeBio = BIO_new(BIO_s_mem());
|
||||
m_readBio = BIO_new(BIO_s_mem());
|
||||
SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpsClient::~HttpsClient()
|
||||
{
|
||||
if (m_ctx) {
|
||||
SSL_CTX_free(m_ctx);
|
||||
}
|
||||
|
||||
if (m_ssl) {
|
||||
SSL_free(m_ssl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::HttpsClient::fingerprint() const
|
||||
{
|
||||
return m_ready ? m_fingerprint : nullptr;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::HttpsClient::version() const
|
||||
{
|
||||
return m_ready ? SSL_get_version(m_ssl) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpsClient::handshake()
|
||||
{
|
||||
m_ssl = SSL_new(m_ctx);
|
||||
assert(m_ssl != nullptr);
|
||||
|
||||
if (!m_ssl) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSL_set_connect_state(m_ssl);
|
||||
SSL_set_bio(m_ssl, m_readBio, m_writeBio);
|
||||
SSL_set_tlsext_host_name(m_ssl, host().data());
|
||||
|
||||
SSL_do_handshake(m_ssl);
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpsClient::read(const char *data, size_t size)
|
||||
{
|
||||
BIO_write(m_readBio, data, size);
|
||||
|
||||
if (!SSL_is_init_finished(m_ssl)) {
|
||||
const int rc = SSL_connect(m_ssl);
|
||||
|
||||
if (rc < 0 && SSL_get_error(m_ssl, rc) == SSL_ERROR_WANT_READ) {
|
||||
flush();
|
||||
} else if (rc == 1) {
|
||||
X509 *cert = SSL_get_peer_certificate(m_ssl);
|
||||
if (!verify(cert)) {
|
||||
X509_free(cert);
|
||||
return close(UV_EPROTO);
|
||||
}
|
||||
|
||||
X509_free(cert);
|
||||
m_ready = true;
|
||||
|
||||
HttpClient::handshake();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int bytes_read = 0;
|
||||
while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) {
|
||||
HttpClient::read(m_buf, static_cast<size_t>(bytes_read));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpsClient::write(const std::string &header)
|
||||
{
|
||||
SSL_write(m_ssl, (header + body).c_str(), header.size() + body.size());
|
||||
body.clear();
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpsClient::verify(X509 *cert)
|
||||
{
|
||||
if (cert == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!verifyFingerprint(cert)) {
|
||||
if (!m_quiet) {
|
||||
LOG_ERR("[%s:%d] Failed to verify server certificate fingerprint", host().data(), port());
|
||||
|
||||
if (strlen(m_fingerprint) == 64 && !m_fp.isNull()) {
|
||||
LOG_ERR("\"%s\" was given", m_fingerprint);
|
||||
LOG_ERR("\"%s\" was configured", m_fp.data());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpsClient::verifyFingerprint(X509 *cert)
|
||||
{
|
||||
const EVP_MD *digest = EVP_get_digestbyname("sha256");
|
||||
if (digest == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
unsigned int dlen;
|
||||
|
||||
if (X509_digest(cert, digest, md, &dlen) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Buffer::toHex(md, 32, m_fingerprint);
|
||||
|
||||
return m_fp.isNull() || strncasecmp(m_fingerprint, m_fp.data(), 64) == 0;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpsClient::flush()
|
||||
{
|
||||
uv_buf_t buf;
|
||||
buf.len = BIO_get_mem_data(m_writeBio, &buf.base);
|
||||
|
||||
if (buf.len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
if (uv_is_writable(stream())) {
|
||||
result = uv_try_write(stream(), &buf, 1) == static_cast<int>(buf.len);
|
||||
|
||||
if (!result) {
|
||||
close(UV_EIO);
|
||||
}
|
||||
}
|
||||
|
||||
(void) BIO_reset(m_writeBio);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user