1
0
mirror of https://github.com/xmrig/xmrig.git synced 2025-12-07 07:55:04 -05:00

Compare commits

..

163 Commits

Author SHA1 Message Date
xmrig
6a1c52b904 Update README.md 2018-04-03 19:02:12 +07:00
XMRig
7003559c74 Merge branch 'feature-cryptonight-heavy' into dev 2018-04-03 18:23:17 +07:00
xmrig
6b710ff3b3 Update CHANGELOG.md 2018-04-03 18:12:24 +07:00
XMRig
4e8ef7c6ed Added cryptonight-heavy support for ARM 2018-04-03 17:51:06 +07:00
XMRig
26e1b14020 Added test hashes for self test. 2018-04-03 17:19:01 +07:00
XMRig
d4123b8fa6 Quick fix, temporary use old style affinity. 2018-04-03 17:06:03 +07:00
XMRig
dd6bc339bf First working cryptonight-heavy. 2018-04-03 16:55:41 +07:00
XMRig
7d5a97137d Fix autoconfig and memory allocation for heavy algo. 2018-04-03 16:08:15 +07:00
XMRig
5c6ec587ac Move selfTest to threads, remove legacy CryptoNight.cpp. 2018-04-03 14:51:05 +07:00
XMRig
d7c5630509 Fix nonce allocation in DoubleWorker. 2018-04-03 03:27:44 +07:00
XMRig
c1bc6acd26 Fix DoubleWorker. 2018-04-03 03:01:04 +07:00
XMRig
903b243308 New style function selector. 2018-04-03 02:55:28 +07:00
XMRig
72cd6d168e Now used IThread to start threads, cpu-affinity broken, nonce allocation in double mode probably broken too. 2018-04-02 15:03:56 +07:00
XMRig
6c970612bf Transform affinity and av to internal representation. 2018-04-02 14:05:16 +07:00
XMRig
a042cbf885 Added classes IThread, CpuThread and API endpoint "GET /1/threads". 2018-04-01 22:49:21 +07:00
XMRig
44d56393db Fix Linux build. 2018-03-31 20:26:07 +07:00
XMRig
edd47b12a8 Update CHANGELOG.md and version. 2018-03-31 19:43:16 +07:00
XMRig
6e51b4191e Merge branch 'feature-controller' into dev 2018-03-31 19:15:22 +07:00
XMRig
8d4d1a3285 Added API endpoint "GET /1/config". 2018-03-31 19:00:31 +07:00
XMRig
341557c34e Added client storage from proxy. 2018-03-31 18:12:52 +07:00
XMRig
af0a6fdf20 Small fixes. 2018-03-31 17:51:33 +07:00
XMRig
7f5d7cf7dd Fix Linux build. 2018-03-31 16:52:58 +07:00
XMRig
aac7b0404a Options class replaced to xmrig::Config. 2018-03-31 16:29:47 +07:00
XMRig
aad19f1a35 Added initial next gen config support from proxy. 2018-03-31 13:48:06 +07:00
XMRig
872148c35c Merge branch 'feature-http-in-main-loop' into dev 2018-03-29 17:55:10 +07:00
XMRig
9fe863b5d7 Background http changes from proxy. 2018-03-27 14:01:38 +07:00
XMRig
f1bc06473f Merge branch 'dev' of github.com:xmrig/xmrig into dev 2018-03-27 12:13:44 +07:00
XMRig
bab6a63822 Merge branch 'master' into dev 2018-03-27 12:13:21 +07:00
xmrig
1bd05d136b Update README.md 2018-03-26 13:59:20 +07:00
XMRig
ec08550fd9 v2.5.2 2018-03-26 13:34:04 +07:00
XMRig
6f4ed5f66d #478 Fixed totally broken reconnect. 2018-03-26 11:47:01 +07:00
xmrig
f852996f97 Update README.md 2018-03-25 15:14:19 +07:00
xmrig
38da8ef86c Update README.md 2018-03-25 15:04:00 +07:00
XMRig
dd7f70d6e8 Fix error in config.json 2018-03-24 13:55:45 +07:00
XMRig
89608ade3b Removed unused private field in FailoverStrategy class. 2018-03-24 13:45:54 +07:00
XMRig
f8f89a0946 v2.5.1 release candidate. 2018-03-24 13:04:04 +07:00
xmrig
e99928aa44 Update CHANGELOG.md 2018-03-24 11:02:04 +07:00
XMRig
1011fd4891 Partial fix for ARMv7 2018-03-24 10:14:21 +07:00
XMRig
673a1291e1 Randomized donation start time. 2018-03-24 09:41:32 +07:00
XMRig
8aa73318c8 Backport changes from proxy. 2018-03-24 00:10:39 +07:00
xmrig
04a95e3aa8 Update CHANGELOG.md 2018-03-22 10:19:29 +07:00
XMRig
ff68840220 Merge branch 'master' of github.com:xmrig/xmrig 2018-03-20 06:21:14 +07:00
XMRig
f2625b7ff5 New app icon. 2018-03-20 06:20:43 +07:00
xmrig
4440d3edd5 Update README.md 2018-03-19 07:03:50 +07:00
XMRig
efa21b2531 #454 Fixed build with libmicrohttpd version below v0.9.35. 2018-03-18 08:30:56 +07:00
XMRig
2de5d92d3a Removed unnecessary pointers cast. 2018-03-18 05:48:19 +07:00
xmrig
2e320d28d9 Update CHANGELOG.md 2018-03-17 18:08:17 +07:00
XMRig
e58429a044 Merge branch 'feature-donate-failover' 2018-03-17 17:57:02 +07:00
XMRig
ed5bf3420c Add donate pool IP address to avoid DNS issues. 2018-03-17 17:55:11 +07:00
xmrig
a7cf34d2eb Update CHANGELOG.md 2018-03-17 16:38:32 +07:00
XMRig
de5016dda8 #459 Fix issue with xmr.f2pool.com 2018-03-17 16:30:41 +07:00
XMRig
1cf1d616c6 DonateStrategy now use FailoverStrategy internally and possible to use any other IStrategy. 2018-03-17 14:33:30 +07:00
XMRig
c46c019c83 Unify network strategies with upcoming proxy. 2018-03-17 05:03:14 +07:00
XMRig
a2f747fb0c Pass all options to network strategies in constructor. 2018-03-17 04:16:08 +07:00
XMRig
38c39321d0 Merge branch 'master' of github.com:xmrig/xmrig 2018-03-17 01:08:41 +07:00
XMRig
7ab81ef19a #456 Don't show error "JSON decode failed" in quiet mode. 2018-03-17 01:07:53 +07:00
XMRig
2e503f7f8c Merge branch 'master' into dev 2018-03-16 15:02:02 +07:00
xmrig
3d41629170 Update README.md 2018-03-15 01:32:09 +07:00
xmrig
7959cf39fa Update README.md 2018-03-14 23:43:57 +07:00
XMRig
d48921bfc8 v2.5.0 2018-03-14 20:33:17 +07:00
XMRig
04c02d4add Fix macOS compile. 2018-03-14 20:22:30 +07:00
XMRig
2c2b3d2f36 Fix FindMHD.cmake 2018-03-14 19:58:38 +07:00
XMRig
0e60c5802d Fix. 2018-03-14 17:17:36 +07:00
XMRig
7adf30e326 Remove align.h. 2018-03-14 17:11:51 +07:00
XMRig
f9a3315d75 Fixes for 32 bit gcc builds. 2018-03-14 16:58:39 +07:00
XMRig
c0ca68e2db Fix FindUV.cmake and FindMHD.cmake. 2018-03-14 06:32:43 +07:00
xmrig
fdc9fbe876 Merge pull request #442 from kpcyrd/static
Add -DBUILD_STATIC=ON for static builds
2018-03-13 22:35:06 +07:00
XMRig
18f1ac6c62 Merge branch 'dev' 2018-03-13 22:33:37 +07:00
XMRig
81ef40fbb7 Fix for previous commit. 2018-03-13 21:01:00 +07:00
XMRig
41abe17286 #438 Fixed memory release. 2018-03-13 20:59:35 +07:00
XMRig
a01b4d0566 Simplify variant selection. 2018-03-13 17:50:09 +07:00
kpcyrd
11f00a2e6e Add -DBUILD_STATIC=ON for static builds
See #238
2018-03-12 21:03:04 +01:00
XMRig
07f0a107d3 Change port for AEON donate. 2018-03-13 02:17:19 +07:00
XMRig
30ab6f79ff Merge branch 'v1-pow' into dev 2018-03-13 01:49:54 +07:00
XMRig
125072a30e Added test hashes for AEON. 2018-03-13 01:29:31 +07:00
XMRig
aec31c43c0 Better v1 PoW implementation, added variant option. 2018-03-12 22:29:44 +07:00
XMRig
83e5832bc1 Some small fixes. 2018-03-12 14:44:23 +07:00
XMRig
244ca93aa4 Change donation address to separate old and new versions. 2018-03-09 13:15:55 +07:00
XMRig
ff68c047f9 v2.5.0-dev 2018-03-09 01:49:24 +07:00
XMRig
b662cb77a4 Revert changes in Api class, single threaded http server will not be included in 2.5 release. 2018-03-09 01:47:44 +07:00
XMRig
3e2863dca5 Merge branch 'vtnerd-monero-v1-pow' into dev
# Conflicts:
#	src/api/Httpd.cpp
#	src/api/Httpd.h
2018-03-09 01:41:47 +07:00
xmrig
6e95b0d052 Update CHANGELOG.md 2018-03-09 01:30:32 +07:00
xmrig
da4aa69c89 Update CHANGELOG.md 2018-03-09 00:56:29 +07:00
XMRig
84970e9e9b Added coin field support added in xmrig-proxy 2.5. 2018-03-09 00:50:06 +07:00
XMRig
37ac1aa62c Automatically enable nicehash when use with upcoming xmrig-proxy 2.5. 2018-03-07 21:56:43 +07:00
XMRig
69b8a4faf1 Added option to disable Monero v7 PoW, may useful in future if other coins update their network to v7 without PoW change. 2018-03-07 19:12:18 +07:00
XMRig
8a6988d381 Added full IPv6 support. 2018-03-07 16:38:58 +07:00
XMRig
79779b51da Added reference hashes. 2018-03-07 15:32:44 +07:00
XMRig
8b60585004 PoW changes WIP 2018-03-06 21:34:20 +07:00
XMRig
df6a397e52 Update copyright and move version into Job class. 2018-03-06 17:06:07 +07:00
XMRig
274c6306a8 Merge branch 'monero-v1-pow' of https://github.com/vtnerd/xmrig into vtnerd-monero-v1-pow 2018-03-06 16:37:33 +07:00
XMRig
a398c8af2f Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy parsed incorrectly. 2018-03-05 13:54:21 +07:00
XMRig
fc82cf1cf2 #428 Fixed regression with CPU cache size detection. 2018-03-05 02:15:05 +07:00
Lee Clagett
48b1de0b59 Changes for the Monero v1 PoW 2018-03-02 22:17:29 +00:00
XMRig
3edc30d067 Use adaptive timer instead of idle handler for HTTP server. 2018-03-01 09:53:27 +07:00
XMRig
ff6dc727f5 Added XMRIG_DEPS cmake variable for unified dependencies. 2018-02-21 00:52:52 +07:00
XMRig
a0d4e4ed3f Run internal http server in main loop to avoid requirement to thread synchronization. 2018-02-20 23:22:34 +07:00
XMRig
71759e3752 Merge branch 'master' into dev 2018-02-20 22:48:39 +07:00
xmrig
79345119c6 Update CHANGELOG.md 2018-02-19 15:58:44 +07:00
XMRig
9af8ceb063 v2.4.5 RC 2018-02-19 04:31:50 +07:00
xmrig
f5a0429f0d Update README.md 2018-02-19 04:17:50 +07:00
xmrig
cc22c9d61c Update README.md 2018-02-18 05:49:37 +07:00
xmrig
45f5afd2b7 Merge pull request #379 from DeadManWalkingTO/master
Update README.md
2018-02-18 05:48:09 +07:00
xmrig
c9acc2912e Update CHANGELOG.md 2018-02-18 05:32:36 +07:00
xmrig
f0604d1e97 Update README.md 2018-02-18 05:06:10 +07:00
XMRig
531c657b64 Merge branch 'master' of github.com:xmrig/xmrig 2018-02-08 17:35:20 +07:00
XMRig
c50ccd4e06 Merge branch 'Foudge-master' 2018-02-08 17:34:33 +07:00
XMRig
184f79ad3f Fix code style, replace tabs to space #2. 2018-02-08 17:21:12 +07:00
XMRig
e78e810cfe Fix code style, replace tabs to space. 2018-02-08 17:02:32 +07:00
XMRig
c804ef1888 Merge branch 'master' of https://github.com/Foudge/xmrig into Foudge-master 2018-02-08 16:56:20 +07:00
Foudge
037abd7037 Correct L2 cache size calculation for Intel Core 2 family
This is a workaround for total L2 cache size calculation of Intel Core Solo, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue. These processors have L2 cache shared by 2 cores.

There is maybe more CPU with L2 shared cache, but I am sure that these models are concerned and they are not so numerous.
A better way would be to modify libcpuid to implement L2 cache counting.
2018-02-03 16:31:13 +01:00
DeadManWalking
75f462f0e1 Update README.md 2018-02-02 00:58:11 +02:00
DeadManWalking
9f92449e15 Update README.md 2018-02-02 00:54:58 +02:00
DeadManWalking
a917590862 Update README.md 2018-02-02 00:14:39 +02:00
DeadManWalking
41b92740ea Merge pull request #1 from xmrig/master
!
2018-02-01 23:02:32 +02:00
Foudge
d2964576c7 Compilation error under FreeBSD
ULONG is not recognized under this OS, so replaced it with more portable definition.
2018-01-28 18:13:00 +01:00
Foudge
9a28ad590c up to 20% perf increase with Cryptonight with non-AES CPU
This time, the performance increase is got with MSVC and GCC. On non-AES CPU, there were an useless load/store SSE2 register. The last MSVC "hack" is replaced by a portable code and he's more complete (a load is saved).

On my C2Q6600, with 3 thread, I have +16% with MSVC2015 and +20% with GCC 7.3, compared to official 2.4.4 version.
2018-01-28 12:58:19 +01:00
Foudge
15fe6ce23f Remove compilation warnings under MSVC 2018-01-27 11:42:22 +01:00
xmrig
17f90de677 Merge pull request #353 from Foudge/master
up to 15% boost on CryptoNight algo with non-AES CPU
2018-01-26 00:53:22 +07:00
XMRig
631fd755c8 #341 Added option --dry-run. 2018-01-20 20:43:31 +07:00
Foudge
9bceb65ad8 +15% boost with non-AES CPU
Performance boost validated on Core 2 Quad processor under Windows 10.
But it's Windows/MS Visual C++ specific.
2018-01-20 10:43:56 +01:00
XMRig
56ffa7af79 #341 Fix wrong exit code. 2018-01-20 12:58:43 +07:00
xmrig
f210708f3b Merge pull request #324 from stanz2g/master
can build without microhttpd when WITH_HTTPD=OFF
2018-01-20 01:35:12 +07:00
xmrig
916cf0ae0d Update CHANGELOG.md 2018-01-11 15:08:24 +07:00
XMRig
e6540229cb #328 Added guard to prevent paused message spam and crash. 2018-01-10 22:55:45 +07:00
XMRig
360f0e8ffd Merge branch 'master' of github.com:xmrig/xmrig 2018-01-10 17:35:40 +07:00
XMRig
038bb1f6bc Fix version. 2018-01-10 16:56:08 +07:00
xmrig
d73bee81ab Update README.md 2018-01-07 21:36:49 +07:00
stanz2g
f93187b024 can build without microhttpd when WITH_HTTPD=OFF 2018-01-06 17:07:07 +08:00
XMRig
49b45ddd18 Add libmicrohttpd version to --version output. 2018-01-05 19:41:19 +07:00
XMRig
8b7a737ceb Fix recent MSVC 2017 version detection. 2018-01-05 17:23:39 +07:00
XMRig
5b88213f61 Fix wrong signal handle. 2018-01-04 11:38:32 +07:00
XMRig
785df62183 Update README.md. 2018-01-02 13:49:31 +07:00
XMRig
1b025f681c Remove extra semicolon. 2018-01-02 13:41:00 +07:00
XMRig
114a9b041d #279 Add missing stdio header 2018-01-02 12:24:57 +07:00
XMRig
fbd100ef10 #262 Reduce cmake version requirement to 2.8. 2017-12-16 19:27:11 +07:00
XMRig
e458c56139 v2.4.3 2017-11-30 02:11:15 +03:00
xmrig
b68b2a907b Update CHANGELOG.md 2017-11-29 18:49:28 +03:00
xmrig
905f9190ae Update CHANGELOG.md 2017-11-29 17:54:12 +03:00
XMRig
aa4f8b6fa7 #216 Added ARMv7 support. 2017-11-26 22:23:23 +03:00
XMRig
9100e3fb65 Merge branch 'arm' 2017-11-24 23:47:12 +03:00
XMRig
47527d48ee Fixed build in termux environment, thanks Imran Yusuff. 2017-11-24 00:23:04 +03:00
XMRig
989c217b3f #200 Use fprintf failback when fail to use uv_tty. 2017-11-18 14:07:04 +03:00
XMRig
1961dcf824 #204 Fix Linux build, again. 2017-11-17 22:44:36 +03:00
XMRig
4b00eb4a9f #196 Fix Linux build. 2017-11-17 12:59:46 +03:00
XMRig
6cc152e26f Added ARMv8 (aarch64) support. 2017-11-06 03:11:35 +03:00
XMRig
d403dcf95c Optimized software aes. 2017-11-03 05:35:29 +03:00
xmrig
c0e849b394 Update CHANGELOG.md 2017-11-02 19:49:25 +03:00
XMRig
2e4c2d3ca8 Merge branch 'master' of github.com:xmrig/xmrig 2017-11-02 19:42:19 +03:00
XMRig
1391a2d858 #184 Workaround for CPUs with disabled Hyper-Threading. 2017-11-02 19:40:33 +03:00
xmrig
ee441b6b9a Update README.md 2017-11-02 03:39:47 +03:00
xmrig
c384df9651 Update README.md 2017-11-02 03:37:58 +03:00
XMRig
6479d6bb6f #157 Explicitly add linking with librt, probably fix build issue with some old Linux. 2017-10-30 00:48:49 +03:00
XMRig
fd029201b0 v2.4.2. 2017-10-23 15:32:07 +03:00
xmrig
a7c0ba6d28 Update CHANGELOG.md 2017-10-23 14:10:37 +03:00
XMRig
66e9f5a8bf Merge branch 'vcambur-master' 2017-10-20 19:55:03 +03:00
XMRig
10df3ec227 Code style fixes for FreeBSD support pull request. 2017-10-20 19:54:18 +03:00
vcambur
9c0fe73102 Some FreeBSD fixes 2017-10-20 08:41:08 +00:00
XMRig
1af1ba6b5f #153 Force reconnect when duplicated job received. 2017-10-16 01:26:55 +03:00
XMRig
bea3bc74b2 v2.4.1. 2017-10-15 04:52:00 +03:00
xmrig
7e4d0d83ff Update CHANGELOG.md 2017-10-15 03:42:45 +03:00
xmrig
4138d4a178 Update README.md 2017-10-12 22:40:20 +03:00
XMRig
f9202c6951 #147 Fixed comparability with monero-stratum. 2017-10-10 16:31:19 +03:00
106 changed files with 7765 additions and 2136 deletions

View File

@@ -1,3 +1,53 @@
# v2.6.0-beta1
- [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.**
- HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization.
- Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested.
- Added API endpoint `PUT /1/config` to update current config.
- Added API endpoint `GET /1/config` to get current active config.
- Added API endpoint `GET /1/threads` to get current active threads configuration.
- API endpoint `GET /` now deprecated, use `GET /1/summary` instead.
- Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API.
- Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified.
# v2.5.2
- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect.
# v2.5.1
- [#454](https://github.com/xmrig/xmrig/issues/454) Fixed build with libmicrohttpd version below v0.9.35.
- [#456](https://github.com/xmrig/xmrig/issues/459) Verbose errors related to donation pool was not fully silenced.
- [#459](https://github.com/xmrig/xmrig/issues/459) Fixed regression (version 2.5.0 affected) with connection to **xmr.f2pool.com**.
# v2.5.0
- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.**
- Added full IPv6 support.
- Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option.
- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly.
- [#428](https://github.com/xmrig/xmrig/issues/428) Fixed regression (version 2.4.5 affected) with CPU cache size detection.
# v2.4.5
- [#324](https://github.com/xmrig/xmrig/pull/324) Fixed build without libmicrohttpd (CMake cache issue).
- [#341](https://github.com/xmrig/xmrig/issues/341) Fixed wrong exit code and added command line option `--dry-run`.
- [#385](https://github.com/xmrig/xmrig/pull/385) Up to 20% performance increase for non-AES CPU and fixed Intel Core 2 cache detection.
# v2.4.4
- Added libmicrohttpd version to --version output.
- Fixed bug in singal handler, in some cases miner wasn't shutdown properly.
- Fixed recent MSVC 2017 version detection.
- [#279](https://github.com/xmrig/xmrig/pull/279) Fixed build on some macOS versions.
# v2.4.3
- [#94](https://github.com/xmrig/xmrig/issues/94#issuecomment-342019257) [#216](https://github.com/xmrig/xmrig/issues/216) Added **ARMv8** and **ARMv7** support. Hardware AES supported, thanks [Imran Yusuff](https://github.com/imranyusuff).
- [#157](https://github.com/xmrig/xmrig/issues/157) [#196](https://github.com/xmrig/xmrig/issues/196) Fixed Linux compile issues.
- [#184](https://github.com/xmrig/xmrig/issues/184) Fixed cache size detection for CPUs with disabled Hyper-Threading.
- [#200](https://github.com/xmrig/xmrig/issues/200) In some cases miner was doesn't write log to stdout.
# v2.4.2
- [#60](https://github.com/xmrig/xmrig/issues/60) Added FreeBSD support, thanks [vcambur](https://github.com/vcambur).
- [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com.
# v2.4.1
- [#147](https://github.com/xmrig/xmrig/issues/147) Fixed comparability with monero-stratum.
# v2.4.0
- Added [HTTP API](https://github.com/xmrig/xmrig/wiki/API).
- Added comments support in config file.

View File

@@ -1,52 +1,67 @@
cmake_minimum_required(VERSION 3.0)
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_HTTPD "HTTP REST API" ON)
option(BUILD_STATIC "Build static binary" OFF)
include (CheckIncludeFile)
include (cmake/cpu.cmake)
set(HEADERS
src/3rdparty/align.h
src/api/Api.h
src/api/ApiState.h
src/api/NetworkState.h
src/App.h
src/Console.h
src/core/CommonConfig.h
src/core/Config.cpp
src/core/ConfigLoader.cpp
src/core/ConfigLoader.h
src/core/ConfigLoader_platform.h
src/core/ConfigWatcher.cpp
src/core/Controller.h
src/Cpu.h
src/interfaces/IClientListener.h
src/interfaces/IConfig.h
src/interfaces/IConfigCreator.h
src/interfaces/IConsoleListener.h
src/interfaces/IControllerListener.h
src/interfaces/IJobResultListener.h
src/interfaces/ILogBackend.h
src/interfaces/IStrategy.h
src/interfaces/IStrategyListener.h
src/interfaces/IThread.h
src/interfaces/IWatcherListener.h
src/interfaces/IWorker.h
src/log/ConsoleLog.h
src/log/FileLog.h
src/log/Log.h
src/Mem.h
src/net/Client.h
src/net/Id.h
src/net/Job.h
src/net/JobId.h
src/net/JobResult.h
src/net/Network.h
src/net/Storage.h
src/net/strategies/DonateStrategy.h
src/net/strategies/FailoverStrategy.h
src/net/strategies/SinglePoolStrategy.h
src/net/SubmitResult.h
src/net/Url.h
src/Options.h
src/Platform.h
src/Summary.h
src/version.h
src/workers/CpuThread.h
src/workers/DoubleWorker.h
src/workers/Handle.h
src/workers/Hashrate.h
src/workers/SingleWorker.h
src/workers/Worker.h
src/workers/Workers.h
src/xmrig.h
)
set(HEADERS_CRYPTO
@@ -56,19 +71,31 @@ set(HEADERS_CRYPTO
src/crypto/c_keccak.h
src/crypto/c_skein.h
src/crypto/CryptoNight.h
src/crypto/CryptoNight_p.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
)
if (XMRIG_ARM)
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_arm.h)
else()
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_x86.h)
endif()
set(SOURCES
src/api/Api.cpp
src/api/ApiState.cpp
src/api/NetworkState.cpp
src/App.cpp
src/Console.cpp
src/core/CommonConfig.cpp
src/core/Config.cpp
src/core/ConfigLoader.cpp
src/core/ConfigWatcher.cpp
src/core/Controller.cpp
src/log/ConsoleLog.cpp
src/log/FileLog.cpp
src/log/Log.cpp
@@ -81,9 +108,9 @@ set(SOURCES
src/net/strategies/SinglePoolStrategy.cpp
src/net/SubmitResult.cpp
src/net/Url.cpp
src/Options.cpp
src/Platform.cpp
src/Summary.cpp
src/workers/CpuThread.cpp
src/workers/DoubleWorker.cpp
src/workers/Handle.cpp
src/workers/Hashrate.cpp
@@ -99,9 +126,6 @@ set(SOURCES_CRYPTO
src/crypto/c_blake256.c
src/crypto/c_jh.c
src/crypto/c_skein.c
src/crypto/soft_aes.c
src/crypto/soft_aes.c
src/crypto/CryptoNight.cpp
)
if (WIN32)
@@ -130,68 +154,29 @@ else()
src/Platform_unix.cpp
)
set(EXTRA_LIBS pthread)
set(EXTRA_LIBS pthread rt)
endif()
if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
set(EXTRA_LIBS ${EXTRA_LIBS} kvm)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
EXECUTE_PROCESS(COMMAND uname -o COMMAND tr -d '\n' OUTPUT_VARIABLE OPERATING_SYSTEM)
if (OPERATING_SYSTEM MATCHES "Android")
set(EXTRA_LIBS ${EXTRA_LIBS} log)
endif()
endif()
add_definitions(/D__STDC_FORMAT_MACROS)
add_definitions(/DUNICODE)
add_definitions(/DRAPIDJSON_SSE2)
#add_definitions(/DAPP_DEBUG)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
find_package(UV REQUIRED)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 11)
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -Wno-strict-aliasing")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
if (WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
endif()
add_definitions(/D_GNU_SOURCE)
if (${CMAKE_VERSION} VERSION_LESS "3.1.0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2")
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL")
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
add_definitions(/DNOMINMAX)
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti -Wno-missing-braces")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
endif()
include(cmake/flags.cmake)
if (WITH_LIBCPUID)
add_subdirectory(src/3rdparty/libcpuid)
@@ -201,7 +186,12 @@ if (WITH_LIBCPUID)
set(SOURCES_CPUID src/Cpu.cpp)
else()
add_definitions(/DXMRIG_NO_LIBCPUID)
set(SOURCES_CPUID src/Cpu_stub.cpp)
if (XMRIG_ARM)
set(SOURCES_CPUID src/Cpu_arm.cpp)
else()
set(SOURCES_CPUID src/Cpu_stub.cpp)
endif()
endif()
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
@@ -214,16 +204,30 @@ if (NOT WITH_AEON)
add_definitions(/DXMRIG_NO_AEON)
endif()
if (NOT WITH_SUMO)
add_definitions(/DXMRIG_NO_SUMO)
endif()
if (WITH_HTTPD)
find_package(MHD)
if (MHD_FOUND)
include_directories(${MHD_INCLUDE_DIRS})
set(HTTPD_SOURCES src/api/Httpd.h src/api/Httpd.cpp)
set(HTTPD_SOURCES
src/api/ApiRouter.h
src/api/HttpBody.h
src/api/Httpd.h
src/api/HttpReply.h
src/api/HttpRequest.h
src/api/ApiRouter.cpp
src/api/Httpd.cpp
src/api/HttpRequest.cpp
)
else()
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
endif()
else()
set(MHD_LIBRARY "")
add_definitions(/DXMRIG_NO_HTTPD)
add_definitions(/DXMRIG_NO_API)
endif()
@@ -232,5 +236,9 @@ include_directories(src)
include_directories(src/3rdparty)
include_directories(${UV_INCLUDE_DIR})
if (BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS " -static")
endif()
add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES})
target_link_libraries(xmrig ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})

View File

@@ -1,8 +1,19 @@
# XMRig
XMRig is high performance Monero (XMR) CPU miner, with the official full Windows support.
Originally based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code, since version 1.0.0 complete rewritten from scratch on C++.
* This is the CPU-mining version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia).
:warning: **You must update miners to version 2.5 before April 6 due [Monero PoW change](https://getmonero.org/2018/02/11/PoW-change-and-key-reuse.html).**
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub Release Date](https://img.shields.io/github/release-date-pre/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub license](https://img.shields.io/github/license/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/blob/master/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/network)
XMRig is a high performance Monero (XMR) CPU miner, with official support for Windows.
Originally based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code, since version 1.0.0 completely rewritten from scratch on C++.
* 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" >
@@ -15,6 +26,7 @@ Originally based on cpuminer-multi with heavy optimizations/rewrites and removin
* [Common Issues](#common-issues)
* [Other information](#other-information)
* [Donations](#donations)
* [Release checksums](#release-checksums)
* [Contacts](#contacts)
## Features
@@ -36,44 +48,40 @@ Originally based on cpuminer-multi with heavy optimizations/rewrites and removin
* Clone with `git clone https://github.com/xmrig/xmrig.git` :hammer: [Build instructions](https://github.com/xmrig/xmrig/wiki/Build).
## Usage
### Basic example
```
xmrig.exe -o pool.minemonero.pro:5555 -u YOUR_WALLET -p x -k
```
### Failover
```
xmrig.exe -o pool.minemonero.pro:5555 -u YOUR_WALLET1 -p x -k -o pool.supportxmr.com:5555 -u YOUR_WALLET2 -p x -k
```
For failover you can add multiple pools, maximum count not limited.
Use [config.xmrig.com](https://config.xmrig.com/xmrig) to generate, edit or share configurations.
### Options
```
-a, --algo=ALGO cryptonight (default) or cryptonight-lite
-o, --url=URL URL of mining server
-O, --userpass=U:P username:password pair for mining server
-u, --user=USERNAME username for mining server
-p, --pass=PASSWORD password for mining server
-t, --threads=N number of miner threads
-v, --av=N algorithm variation, 0 auto select
-k, --keepalive send keepalived for prevent timeout (need pool support)
-r, --retries=N number of times to retry before switch to backup server (default: 5)
-R, --retry-pause=N time to pause between retries (default: 5)
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)
--no-huge-pages disable huge pages support
--no-color disable colored output
--donate-level=N donate level, default 5% (5 minutes in 100 minutes)
--user-agent set custom user-agent string for pool
-B, --background run the miner in the background
-c, --config=FILE load a JSON-format configuration file
-l, --log-file=FILE log all output to a file
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)
--safe safe adjust threads and av settings for current CPU
--nicehash enable nicehash support
--print-time=N print hashrate report every N seconds
-h, --help display this help and exit
-V, --version output version information and exit
-a, --algo=ALGO cryptonight (default) or cryptonight-lite
-o, --url=URL URL of mining server
-O, --userpass=U:P username:password pair for mining server
-u, --user=USERNAME username for mining server
-p, --pass=PASSWORD password for mining server
-t, --threads=N number of miner threads
-v, --av=N algorithm variation, 0 auto select
-k, --keepalive send keepalived for prevent timeout (need pool support)
-r, --retries=N number of times to retry before switch to backup server (default: 5)
-R, --retry-pause=N time to pause between retries (default: 5)
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)
--no-huge-pages disable huge pages support
--no-color disable colored output
--variant algorithm PoW variant
--donate-level=N donate level, default 5% (5 minutes in 100 minutes)
--user-agent set custom user-agent string for pool
-B, --background run the miner in the background
-c, --config=FILE load a JSON-format configuration file
-l, --log-file=FILE log all output to a file
-S, --syslog use system log for output messages
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)
--safe safe adjust threads and av settings for current CPU
--nicehash enable nicehash/xmrig-proxy support
--print-time=N print hashrate report every N seconds
--api-port=N port for the miner API
--api-access-token=T access token for API
--api-worker-id=ID custom worker-id for API
-h, --help display this help and exit
-V, --version output version information and exit
```
Also you can use configuration via config file, default **config.json**. You can load multiple config files and combine it with command line options.
@@ -88,7 +96,7 @@ Since version 0.8.0.
## Common Issues
### HUGE PAGES unavailable
* Run XMRig as Administrator.
* Since version 0.8.0 XMRig automatically enable SeLockMemoryPrivilege for current user, but reboot or sign out still required. [Manual instruction](https://msdn.microsoft.com/en-gb/library/ms190730.aspx).
* Since version 0.8.0 XMRig automatically enables SeLockMemoryPrivilege for current user, but reboot or sign out still required. [Manual instruction](https://msdn.microsoft.com/en-gb/library/ms190730.aspx).
## Other information
* No HTTP support, only stratum protocol support.
@@ -105,7 +113,7 @@ Please note performance is highly dependent on system load. The numbers above ar
### Maximum performance checklist
* Idle operating system.
* Do not exceed optimal thread count.
* Use modern CPUs with AES-NI instructuon set.
* Use modern CPUs with AES-NI instruction set.
* Try setup optimal cpu affinity.
* Enable fast memory (Large/Huge pages).
@@ -113,6 +121,15 @@ Please note performance is highly dependent on system load. The numbers above ar
* XMR: `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD`
* BTC: `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT`
## Release checksums
### SHA-256
```
bd14bc3cfd9528e4a7583ab39aecc876250333e1e0faab83781584bb7f65e3eb xmrig-2.6.0-beta1-xenial-amd64.tar.gz/xmrig-2.6.0-beta1/xmrig
32eebf71e5631029202ae5cbf6f03caad912f1722aa86a1be01a26d491801aba xmrig-2.6.0-beta1-gcc-win32.zip/xmrig.exe
1cc08844ff019408e2e2c9560fee0c4e0b2dbc2a72bcc1c1da4a847a1787eca3 xmrig-2.6.0-beta1-gcc-win64.zip/xmrig.exe
fdf99aa8e7792a34b1be0cc6c77e4e83ff9a4b21abb27989f7927dcfed82f6e2 xmrig-2.6.0-beta1-msvc-win64.zip/xmrig.exe
```
## Contacts
* support@xmrig.com
* [reddit](https://www.reddit.com/user/XMRig/)

View File

@@ -8,15 +8,25 @@
find_path(
MHD_INCLUDE_DIR
NAMES microhttpd.h
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "include"
DOC "microhttpd include dir"
NO_DEFAULT_PATH
)
find_path(MHD_INCLUDE_DIR NAMES microhttpd.h)
find_library(
MHD_LIBRARY
NAMES microhttpd microhttpd-10 libmicrohttpd libmicrohttpd-dll
NAMES libmicrohttpd.a microhttpd libmicrohttpd
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "lib"
DOC "microhttpd library"
NO_DEFAULT_PATH
)
find_library(MHD_LIBRARY NAMES microhttpd libmicrohttpd)
set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR})
set(MHD_LIBRARIES ${MHD_LIBRARY})
@@ -34,6 +44,6 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(mhd DEFAULT_MSG MHD_INCLUDE_DIR MHD_LIBRARY)
find_package_handle_standard_args(MHD DEFAULT_MSG MHD_LIBRARY MHD_INCLUDE_DIR)
mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY)

View File

@@ -1,5 +1,22 @@
find_path(
UV_INCLUDE_DIR
NAMES uv.h
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "include"
NO_DEFAULT_PATH
)
find_path(UV_INCLUDE_DIR NAMES uv.h)
find_library(UV_LIBRARY NAMES uv libuv)
find_library(
UV_LIBRARY
NAMES libuv.a uv libuv
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
find_library(UV_LIBRARY NAMES libuv.a uv libuv)
set(UV_LIBRARIES ${UV_LIBRARY})
set(UV_INCLUDE_DIRS ${UV_INCLUDE_DIR})

25
cmake/cpu.cmake Normal file
View File

@@ -0,0 +1,25 @@
if (NOT CMAKE_SYSTEM_PROCESSOR)
message(WARNING "CMAKE_SYSTEM_PROCESSOR not defined")
endif()
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$")
add_definitions(/DRAPIDJSON_SSE2)
endif()
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64)$")
set(XMRIG_ARM ON)
set(XMRIG_ARMv8 ON)
set(WITH_LIBCPUID OFF)
add_definitions(/DXMRIG_ARM)
add_definitions(/DXMRIG_ARMv8)
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7|armv7f|armv7s|armv7k|armv7-a|armv7l)$")
set(XMRIG_ARM ON)
set(XMRIG_ARMv7 ON)
set(WITH_LIBCPUID OFF)
add_definitions(/DXMRIG_ARM)
add_definitions(/DXMRIG_ARMv7)
endif()

73
cmake/flags.cmake Normal file
View File

@@ -0,0 +1,73 @@
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 11)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE Release)
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Release")
add_definitions(/DNDEBUG)
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
if (XMRIG_ARMv8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crypto -flax-vector-conversions")
elseif (XMRIG_ARMv7)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -flax-vector-conversions")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
endif()
if (WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
endif()
add_definitions(/D_GNU_SOURCE)
if (${CMAKE_VERSION} VERSION_LESS "3.1.0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2")
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL")
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
add_definitions(/DNOMINMAX)
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_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
if (XMRIG_ARMv8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crypto")
elseif (XMRIG_ARMv7)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -march=${CMAKE_SYSTEM_PROCESSOR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -march=${CMAKE_SYSTEM_PROCESSOR}")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
endif()
endif()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 21 KiB

65
src/3rdparty/aligned_malloc.h vendored Normal file
View File

@@ -0,0 +1,65 @@
/* 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__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,6 +29,8 @@
#include "api/Api.h"
#include "App.h"
#include "Console.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "Cpu.h"
#include "crypto/CryptoNight.h"
#include "log/ConsoleLog.h"
@@ -36,17 +38,12 @@
#include "log/Log.h"
#include "Mem.h"
#include "net/Network.h"
#include "Options.h"
#include "Platform.h"
#include "Summary.h"
#include "version.h"
#include "workers/Workers.h"
#ifdef HAVE_SYSLOG_H
# include "log/SysLog.h"
#endif
#ifndef XMRIG_NO_HTTPD
# include "api/Httpd.h"
#endif
@@ -58,98 +55,90 @@ App *App::m_self = nullptr;
App::App(int argc, char **argv) :
m_console(nullptr),
m_httpd(nullptr),
m_network(nullptr),
m_options(nullptr)
m_httpd(nullptr)
{
m_self = this;
Cpu::init();
m_options = Options::parse(argc, argv);
if (!m_options) {
m_controller = new xmrig::Controller();
if (m_controller->init(argc, argv) != 0) {
return;
}
Log::init();
if (!m_options->background()) {
Log::add(new ConsoleLog(m_options->colors()));
if (!m_controller->config()->isBackground()) {
m_console = new Console(this);
}
if (m_options->logFile()) {
Log::add(new FileLog(m_options->logFile()));
}
# ifdef HAVE_SYSLOG_H
if (m_options->syslog()) {
Log::add(new SysLog());
}
# endif
Platform::init(m_options->userAgent());
Platform::setProcessPriority(m_options->priority());
m_network = new Network(m_options);
uv_signal_init(uv_default_loop(), &m_signal);
uv_signal_init(uv_default_loop(), &m_sigHUP);
uv_signal_init(uv_default_loop(), &m_sigINT);
uv_signal_init(uv_default_loop(), &m_sigTERM);
}
App::~App()
{
Mem::release();
uv_tty_reset_mode();
delete m_console;
delete m_controller;
# ifndef XMRIG_NO_HTTPD
delete m_httpd;
# endif
delete m_console;
}
int App::exec()
{
if (!m_options) {
return 0;
if (!m_controller->isReady()) {
return 2;
}
uv_signal_start(&m_signal, App::onSignal, SIGHUP);
uv_signal_start(&m_signal, App::onSignal, SIGTERM);
uv_signal_start(&m_signal, App::onSignal, SIGINT);
uv_signal_start(&m_sigHUP, App::onSignal, SIGHUP);
uv_signal_start(&m_sigINT, App::onSignal, SIGINT);
uv_signal_start(&m_sigTERM, App::onSignal, SIGTERM);
background();
if (!CryptoNight::init(m_options->algo(), m_options->algoVariant())) {
LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName());
return 1;
Mem::allocate(m_controller->config()->algorithm(),
m_controller->config()->threadsCount(),
m_controller->config()->isDoubleHash(),
m_controller->config()->isHugePages()
);
Summary::print(m_controller);
if (m_controller->config()->isDryRun()) {
LOG_NOTICE("OK");
release();
return 0;
}
Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash(), m_options->hugePages());
Summary::print();
# ifndef XMRIG_NO_API
Api::start();
Api::start(m_controller);
# endif
# ifndef XMRIG_NO_HTTPD
m_httpd = new Httpd(m_options->apiPort(), m_options->apiToken());
m_httpd = new Httpd(
m_controller->config()->apiPort(),
m_controller->config()->apiToken(),
m_controller->config()->isApiIPv6(),
m_controller->config()->isApiRestricted()
);
m_httpd->start();
# endif
Workers::start(m_options->affinity(), m_options->priority());
Workers::start(m_controller);
m_network->connect();
m_controller->network()->connect();
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
uv_loop_close(uv_default_loop());
delete m_network;
Options::release();
Mem::release();
Platform::release();
release();
return r;
}
@@ -164,14 +153,16 @@ void App::onConsoleCommand(char command)
case 'p':
case 'P':
LOG_INFO(m_options->colors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" : "paused, press 'r' to resume");
Workers::setEnabled(false);
if (Workers::isEnabled()) {
LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" : "paused, press 'r' to resume");
Workers::setEnabled(false);
}
break;
case 'r':
case 'R':
if (!Workers::isEnabled()) {
LOG_INFO(m_options->colors() ? "\x1B[01;32mresumed" : "resumed");
LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;32mresumed" : "resumed");
Workers::setEnabled(true);
}
break;
@@ -189,13 +180,18 @@ void App::onConsoleCommand(char command)
void App::close()
{
m_network->stop();
m_controller->network()->stop();
Workers::stop();
uv_stop(uv_default_loop());
}
void App::release()
{
}
void App::onSignal(uv_signal_t *handle, int signum)
{
switch (signum)

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,6 +37,11 @@ class Network;
class Options;
namespace xmrig {
class Controller;
}
class App : public IConsoleListener
{
public:
@@ -51,6 +56,7 @@ protected:
private:
void background();
void close();
void release();
static void onSignal(uv_signal_t *handle, int signum);
@@ -58,9 +64,10 @@ private:
Console *m_console;
Httpd *m_httpd;
Network *m_network;
Options *m_options;
uv_signal_t m_signal;
uv_signal_t m_sigHUP;
uv_signal_t m_sigINT;
uv_signal_t m_sigTERM;
xmrig::Controller *m_controller;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,18 +29,22 @@
#include "App.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "Cpu.h"
#include "log/Log.h"
#include "Options.h"
void App::background()
{
if (m_options->affinity() != -1L) {
Cpu::setAffinity(-1, m_options->affinity());
signal(SIGPIPE, SIG_IGN);
const int64_t affinity = m_controller->config()->affinity();
if (affinity != -1L) {
Cpu::setAffinity(-1, affinity);
}
if (!m_options->background()) {
if (!m_controller->config()->isBackground()) {
return;
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,17 +27,19 @@
#include "App.h"
#include "Options.h"
#include "Cpu.h"
#include "core/Controller.h"
#include "core/Config.h"
void App::background()
{
if (m_options->affinity() != -1L) {
Cpu::setAffinity(-1, m_options->affinity());
const int64_t affinity = m_controller->config()->affinity();
if (affinity != -1L) {
Cpu::setAffinity(-1, affinity);
}
if (!m_options->background()) {
if (!m_controller->config()->isBackground()) {
return;
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,7 +39,7 @@ int Cpu::m_totalCores = 0;
int Cpu::m_totalThreads = 0;
int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage)
int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage)
{
if (m_totalThreads == 1) {
return 1;
@@ -54,7 +54,18 @@ int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage)
}
int count = 0;
const int size = (algo ? 1024 : 2048) * (doubleHash ? 2 : 1);
int size = 2048;
if (algo == xmrig::CRYPTONIGHT_LITE) {
size = 1024;
}
else if (algo == xmrig::CRYPTONIGHT_HEAVY) {
size = 4096;
}
if (doubleHash) {
size *= 2;
}
if (cache) {
count = cache / size;
@@ -86,9 +97,13 @@ void Cpu::initCommon()
strncpy(m_brand, data.brand_str, sizeof(m_brand) - 1);
m_totalThreads = data.total_logical_cpus;
m_sockets = m_totalThreads / data.num_logical_cpus;
m_totalCores = data.num_cores *m_sockets;
m_sockets = m_totalThreads / data.num_logical_cpus;
if (m_sockets == 0) {
m_sockets = 1;
}
m_totalCores = data.num_cores * m_sockets;
m_l3_cache = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0;
// Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97
@@ -96,7 +111,13 @@ void Cpu::initCommon()
m_l2_cache = data.l2_cache * (m_totalCores / 2) * m_sockets;
m_l2_exclusive = true;
}
else {
// 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 = m_totalCores > 1 ? m_totalCores / 2 : 1;
m_l2_cache = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0;
}
else{
m_l2_cache = data.l2_cache > 0 ? data.l2_cache * m_totalCores * m_sockets : 0;
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,6 +28,9 @@
#include <stdint.h>
#include "xmrig.h"
class Cpu
{
public:
@@ -37,7 +40,7 @@ public:
BMI2 = 4
};
static int optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage);
static int optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage);
static void init();
static void setAffinity(int id, uint64_t mask);

54
src/Cpu_arm.cpp Normal file
View File

@@ -0,0 +1,54 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "Cpu.h"
char Cpu::m_brand[64] = { 0 };
int Cpu::m_flags = 0;
int Cpu::m_l2_cache = 0;
int Cpu::m_l3_cache = 0;
int Cpu::m_sockets = 1;
int Cpu::m_totalCores = 0;
int Cpu::m_totalThreads = 0;
int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage)
{
return m_totalThreads;
}
void Cpu::initCommon()
{
memcpy(m_brand, "Unknown", 7);
# if defined(XMRIG_ARMv8)
m_flags |= X86_64;
m_flags |= AES;
# endif
}

View File

@@ -24,13 +24,18 @@
#ifdef _MSC_VER
# include <intrin.h>
# define bit_AES (1 << 25)
# define bit_BMI2 (1 << 8)
#else
# include <cpuid.h>
#endif
#ifndef bit_AES
# define bit_AES (1 << 25)
#endif
#ifndef bit_BMI2
# define bit_BMI2 (1 << 8)
#endif
#include <string.h>
@@ -87,7 +92,7 @@ static inline bool has_aes_ni()
int cpu_info[4] = { 0 };
cpuid(PROCESSOR_INFO, cpu_info);
return cpu_info[ECX_Reg] & bit_AES;
return (cpu_info[ECX_Reg] & bit_AES) != 0;
}
@@ -95,7 +100,7 @@ static inline bool has_bmi2() {
int cpu_info[4] = { 0 };
cpuid(EXTENDED_FEATURES, cpu_info);
return cpu_info[EBX_Reg] & bit_BMI2;
return (cpu_info[EBX_Reg] & bit_BMI2) != 0;
}

View File

@@ -22,6 +22,14 @@
*/
#ifdef __FreeBSD__
# include <sys/types.h>
# include <sys/param.h>
# include <sys/cpuset.h>
# include <pthread_np.h>
#endif
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
@@ -31,6 +39,11 @@
#include "Cpu.h"
#ifdef __FreeBSD__
typedef cpuset_t cpu_set_t;
#endif
void Cpu::init()
{
# ifdef XMRIG_NO_LIBCPUID
@@ -53,8 +66,14 @@ void Cpu::setAffinity(int id, uint64_t mask)
}
if (id == -1) {
# ifndef __FreeBSD__
sched_setaffinity(0, sizeof(&set), &set);
# endif
} else {
# ifndef __ANDROID__
pthread_setaffinity_np(pthread_self(), sizeof(&set), &set);
# else
sched_setaffinity(gettid(), sizeof(&set), &set);
# endif
}
}

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,30 +27,34 @@
#include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_constants.h"
#include "Mem.h"
#include "Options.h"
bool Mem::m_doubleHash = false;
int Mem::m_algo = 0;
int Mem::m_flags = 0;
int Mem::m_threads = 0;
size_t Mem::m_offset = 0;
uint8_t *Mem::m_memory = nullptr;
bool Mem::m_doubleHash = false;
int Mem::m_algo = 0;
int Mem::m_flags = 0;
int Mem::m_threads = 0;
size_t Mem::m_offset = 0;
size_t Mem::m_size = 0;
alignas(16) uint8_t *Mem::m_memory = nullptr;
cryptonight_ctx *Mem::create(int threadId)
{
# ifndef XMRIG_NO_AEON
if (m_algo == Options::ALGO_CRYPTONIGHT_LITE) {
if (m_algo == xmrig::CRYPTONIGHT_LITE) {
return createLite(threadId);
}
# endif
cryptonight_ctx *ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
const size_t size = m_algo == xmrig::CRYPTONIGHT_HEAVY ? xmrig::cn_select_memory<xmrig::CRYPTONIGHT_HEAVY>()
: xmrig::cn_select_memory<xmrig::CRYPTONIGHT>();
cryptonight_ctx *ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[size - sizeof(cryptonight_ctx) * (threadId + 1)]);
const int ratio = m_doubleHash ? 2 : 1;
ctx->memory = &m_memory[MEMORY * (threadId * ratio + 1)];
ctx->memory = &m_memory[size * (threadId * ratio + 1)];
return ctx;
}
@@ -72,15 +77,15 @@ cryptonight_ctx *Mem::createLite(int threadId) {
cryptonight_ctx *ctx;
if (!m_doubleHash) {
const size_t offset = MEMORY * (threadId + 1);
const size_t offset = MONERO_MEMORY * (threadId + 1);
ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[offset + MEMORY_LITE]);
ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[offset + AEON_MEMORY]);
ctx->memory = &m_memory[offset];
return ctx;
}
ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
ctx->memory = &m_memory[MEMORY * (threadId + 1)];
ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[MONERO_MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
ctx->memory = &m_memory[MONERO_MEMORY * (threadId + 1)];
return ctx;
}

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +30,7 @@
#include <stdint.h>
#include "align.h"
#include "xmrig.h"
struct cryptonight_ctx;
@@ -44,7 +45,7 @@ public:
Lock = 4
};
static bool allocate(int algo, int threads, bool doubleHash, bool enabled);
static bool allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled);
static cryptonight_ctx *create(int threadId);
static void *calloc(size_t num, size_t size);
static void release();
@@ -61,7 +62,8 @@ private:
static int m_flags;
static int m_threads;
static size_t m_offset;
VAR_ALIGN(16, static uint8_t *m_memory);
static size_t m_size;
alignas(16) static uint8_t *m_memory;
# ifndef XMRIG_NO_AEON
static cryptonight_ctx *createLite(int threadId);

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,50 +24,61 @@
#include <stdlib.h>
#include <mm_malloc.h>
#include <sys/mman.h>
#if defined(XMRIG_ARM) && !defined(__clang__)
# include "aligned_malloc.h"
#else
# include <mm_malloc.h>
#endif
#include "crypto/CryptoNight.h"
#include "log/Log.h"
#include "Mem.h"
#include "Options.h"
#include "xmrig.h"
bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled)
{
m_algo = algo;
m_threads = threads;
m_doubleHash = doubleHash;
const int ratio = (doubleHash && algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1;
const size_t size = MEMORY * (threads * ratio + 1);
const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1;
m_size = MONERO_MEMORY * (threads * ratio + 1);
if (algo == xmrig::CRYPTONIGHT_HEAVY) {
m_size *= 2;
}
if (!enabled) {
m_memory = static_cast<uint8_t*>(_mm_malloc(size, 16));
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
return true;
}
m_flags |= HugepagesAvailable;
# if defined(__APPLE__)
m_memory = static_cast<uint8_t*>(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
m_memory = static_cast<uint8_t*>(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
# elif defined(__FreeBSD__)
m_memory = static_cast<uint8_t*>(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
# else
m_memory = static_cast<uint8_t*>(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
m_memory = static_cast<uint8_t*>(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
# endif
if (m_memory == MAP_FAILED) {
m_memory = static_cast<uint8_t*>(_mm_malloc(size, 16));
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
return true;
}
m_flags |= HugepagesEnabled;
if (madvise(m_memory, size, MADV_RANDOM | MADV_WILLNEED) != 0) {
if (madvise(m_memory, m_size, MADV_RANDOM | MADV_WILLNEED) != 0) {
LOG_ERR("madvise failed");
}
if (mlock(m_memory, size) == 0) {
if (mlock(m_memory, m_size) == 0) {
m_flags |= Lock;
}
@@ -76,14 +88,12 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
void Mem::release()
{
const int size = MEMORY * (m_threads + 1);
if (m_flags & HugepagesEnabled) {
if (m_flags & Lock) {
munlock(m_memory, size);
munlock(m_memory, m_size);
}
munmap(m_memory, size);
munmap(m_memory, m_size);
}
else {
_mm_free(m_memory);

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,7 +37,7 @@
#include "log/Log.h"
#include "crypto/CryptoNight.h"
#include "Mem.h"
#include "Options.h"
#include "xmrig.h"
/*****************************************************************
@@ -144,17 +145,21 @@ static BOOL TrySetLockPagesPrivilege() {
}
bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled)
{
m_algo = algo;
m_threads = threads;
m_doubleHash = doubleHash;
const int ratio = (doubleHash && algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1;
const size_t size = MEMORY * (threads * ratio + 1);
const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1;
m_size = MONERO_MEMORY * (threads * ratio + 1);
if (algo == xmrig::CRYPTONIGHT_HEAVY) {
m_size *= 2;
}
if (!enabled) {
m_memory = static_cast<uint8_t*>(_mm_malloc(size, 16));
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
return true;
}
@@ -162,9 +167,9 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
m_flags |= HugepagesAvailable;
}
m_memory = static_cast<uint8_t*>(VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
m_memory = static_cast<uint8_t*>(VirtualAlloc(NULL, m_size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
if (!m_memory) {
m_memory = static_cast<uint8_t*>(_mm_malloc(size, 16));
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
}
else {
m_flags |= HugepagesEnabled;

View File

@@ -1,729 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <uv.h>
#ifdef _MSC_VER
# include "getopt/getopt.h"
#else
# include <getopt.h>
#endif
#include "Cpu.h"
#include "donate.h"
#include "net/Url.h"
#include "Options.h"
#include "Platform.h"
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/filereadstream.h"
#include "version.h"
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
Options *Options::m_self = nullptr;
static char const usage[] = "\
Usage: " APP_ID " [OPTIONS]\n\
Options:\n\
-a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\
-o, --url=URL URL of mining server\n\
-O, --userpass=U:P username:password pair for mining server\n\
-u, --user=USERNAME username for mining server\n\
-p, --pass=PASSWORD password for mining server\n\
-t, --threads=N number of miner threads\n\
-v, --av=N algorithm variation, 0 auto select\n\
-k, --keepalive send keepalived for prevent timeout (need pool support)\n\
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
-R, --retry-pause=N time to pause between retries (default: 5)\n\
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\
--no-huge-pages disable huge pages support\n\
--no-color disable colored output\n\
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\
--user-agent set custom user-agent string for pool\n\
-B, --background run the miner in the background\n\
-c, --config=FILE load a JSON-format configuration file\n\
-l, --log-file=FILE log all output to a file\n"
# ifdef HAVE_SYSLOG_H
"\
-S, --syslog use system log for output messages\n"
# endif
"\
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\
--safe safe adjust threads and av settings for current CPU\n\
--nicehash enable nicehash/xmrig-proxy support\n\
--print-time=N print hashrate report every N seconds\n\
--api-port=N port for the miner API\n\
--api-access-token=T access token for API\n\
--api-worker-id=ID custom worker-id for API\n\
-h, --help display this help and exit\n\
-V, --version output version information and exit\n\
";
static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vl:S";
static struct option const options[] = {
{ "algo", 1, nullptr, 'a' },
{ "av", 1, nullptr, 'v' },
{ "background", 0, nullptr, 'B' },
{ "config", 1, nullptr, 'c' },
{ "cpu-affinity", 1, nullptr, 1020 },
{ "cpu-priority", 1, nullptr, 1021 },
{ "donate-level", 1, nullptr, 1003 },
{ "help", 0, nullptr, 'h' },
{ "keepalive", 0, nullptr ,'k' },
{ "log-file", 1, nullptr, 'l' },
{ "max-cpu-usage", 1, nullptr, 1004 },
{ "nicehash", 0, nullptr, 1006 },
{ "no-color", 0, nullptr, 1002 },
{ "no-huge-pages", 0, nullptr, 1009 },
{ "pass", 1, nullptr, 'p' },
{ "print-time", 1, nullptr, 1007 },
{ "retries", 1, nullptr, 'r' },
{ "retry-pause", 1, nullptr, 'R' },
{ "safe", 0, nullptr, 1005 },
{ "syslog", 0, nullptr, 'S' },
{ "threads", 1, nullptr, 't' },
{ "url", 1, nullptr, 'o' },
{ "user", 1, nullptr, 'u' },
{ "user-agent", 1, nullptr, 1008 },
{ "userpass", 1, nullptr, 'O' },
{ "version", 0, nullptr, 'V' },
{ "api-port", 1, nullptr, 4000 },
{ "api-access-token", 1, nullptr, 4001 },
{ "api-worker-id", 1, nullptr, 4002 },
{ 0, 0, 0, 0 }
};
static struct option const config_options[] = {
{ "algo", 1, nullptr, 'a' },
{ "av", 1, nullptr, 'v' },
{ "background", 0, nullptr, 'B' },
{ "colors", 0, nullptr, 2000 },
{ "cpu-affinity", 1, nullptr, 1020 },
{ "cpu-priority", 1, nullptr, 1021 },
{ "donate-level", 1, nullptr, 1003 },
{ "huge-pages", 0, nullptr, 1009 },
{ "log-file", 1, nullptr, 'l' },
{ "max-cpu-usage", 1, nullptr, 1004 },
{ "print-time", 1, nullptr, 1007 },
{ "retries", 1, nullptr, 'r' },
{ "retry-pause", 1, nullptr, 'R' },
{ "safe", 0, nullptr, 1005 },
{ "syslog", 0, nullptr, 'S' },
{ "threads", 1, nullptr, 't' },
{ "user-agent", 1, nullptr, 1008 },
{ 0, 0, 0, 0 }
};
static struct option const pool_options[] = {
{ "url", 1, nullptr, 'o' },
{ "pass", 1, nullptr, 'p' },
{ "user", 1, nullptr, 'u' },
{ "userpass", 1, nullptr, 'O' },
{ "keepalive", 0, nullptr ,'k' },
{ "nicehash", 0, nullptr, 1006 },
{ 0, 0, 0, 0 }
};
static struct option const api_options[] = {
{ "port", 1, nullptr, 4000 },
{ "access-token", 1, nullptr, 4001 },
{ "worker-id", 1, nullptr, 4002 },
{ 0, 0, 0, 0 }
};
static const char *algo_names[] = {
"cryptonight",
# ifndef XMRIG_NO_AEON
"cryptonight-lite"
# endif
};
Options *Options::parse(int argc, char **argv)
{
Options *options = new Options(argc, argv);
if (options->isReady()) {
m_self = options;
return m_self;
}
delete options;
return nullptr;
}
const char *Options::algoName() const
{
return algo_names[m_algo];
}
Options::Options(int argc, char **argv) :
m_background(false),
m_colors(true),
m_doubleHash(false),
m_hugePages(true),
m_ready(false),
m_safe(false),
m_syslog(false),
m_apiToken(nullptr),
m_apiWorkerId(nullptr),
m_logFile(nullptr),
m_userAgent(nullptr),
m_algo(0),
m_algoVariant(0),
m_apiPort(0),
m_donateLevel(kDonateLevel),
m_maxCpuUsage(75),
m_printTime(60),
m_priority(-1),
m_retries(5),
m_retryPause(5),
m_threads(0),
m_affinity(-1L)
{
m_pools.push_back(new Url());
int key;
while (1) {
key = getopt_long(argc, argv, short_options, options, NULL);
if (key < 0) {
break;
}
if (!parseArg(key, optarg)) {
return;
}
}
if (optind < argc) {
fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]);
return;
}
if (!m_pools[0]->isValid()) {
parseConfig(Platform::defaultConfigName());
}
if (!m_pools[0]->isValid()) {
fprintf(stderr, "No pool URL supplied. Exiting.\n");
return;
}
m_algoVariant = getAlgoVariant();
if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) {
m_doubleHash = true;
}
if (!m_threads) {
m_threads = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage);
}
else if (m_safe) {
const int count = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage);
if (m_threads > count) {
m_threads = count;
}
}
for (Url *url : m_pools) {
url->applyExceptions();
}
m_ready = true;
}
Options::~Options()
{
}
bool Options::getJSON(const char *fileName, rapidjson::Document &doc)
{
uv_fs_t req;
const int fd = uv_fs_open(uv_default_loop(), &req, fileName, O_RDONLY, 0644, nullptr);
if (fd < 0) {
fprintf(stderr, "unable to open %s: %s\n", fileName, uv_strerror(fd));
return false;
}
uv_fs_req_cleanup(&req);
FILE *fp = fdopen(fd, "rb");
char buf[8192];
rapidjson::FileReadStream is(fp, buf, sizeof(buf));
doc.ParseStream(is);
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req);
if (doc.HasParseError()) {
printf("%s:%d: %s\n", fileName, (int) doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError()));
return false;
}
return doc.IsObject();
}
bool Options::parseArg(int key, const char *arg)
{
switch (key) {
case 'a': /* --algo */
if (!setAlgo(arg)) {
return false;
}
break;
case 'o': /* --url */
if (m_pools.size() > 1 || m_pools[0]->isValid()) {
Url *url = new Url(arg);
if (url->isValid()) {
m_pools.push_back(url);
}
else {
delete url;
}
}
else {
m_pools[0]->parse(arg);
}
if (!m_pools.back()->isValid()) {
return false;
}
break;
case 'O': /* --userpass */
if (!m_pools.back()->setUserpass(arg)) {
return false;
}
break;
case 'u': /* --user */
m_pools.back()->setUser(arg);
break;
case 'p': /* --pass */
m_pools.back()->setPassword(arg);
break;
case 'l': /* --log-file */
free(m_logFile);
m_logFile = strdup(arg);
m_colors = false;
break;
case 4001: /* --access-token */
free(m_apiToken);
m_apiToken = strdup(arg);
break;
case 4002: /* --worker-id */
free(m_apiWorkerId);
m_apiWorkerId = strdup(arg);
break;
case 'r': /* --retries */
case 'R': /* --retry-pause */
case 'v': /* --av */
case 1003: /* --donate-level */
case 1004: /* --max-cpu-usage */
case 1007: /* --print-time */
case 1021: /* --cpu-priority */
case 4000: /* --api-port */
return parseArg(key, strtol(arg, nullptr, 10));
case 'B': /* --background */
case 'k': /* --keepalive */
case 'S': /* --syslog */
case 1005: /* --safe */
case 1006: /* --nicehash */
return parseBoolean(key, true);
case 1002: /* --no-color */
case 1009: /* --no-huge-pages */
return parseBoolean(key, false);
case 't': /* --threads */
if (strncmp(arg, "all", 3) == 0) {
m_threads = Cpu::threads();
return true;
}
return parseArg(key, strtol(arg, nullptr, 10));
case 'V': /* --version */
showVersion();
return false;
case 'h': /* --help */
showUsage(0);
return false;
case 'c': /* --config */
parseConfig(arg);
break;
case 1020: { /* --cpu-affinity */
const char *p = strstr(arg, "0x");
return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
}
case 1008: /* --user-agent */
free(m_userAgent);
m_userAgent = strdup(arg);
break;
default:
showUsage(1);
return false;
}
return true;
}
bool Options::parseArg(int key, uint64_t arg)
{
switch (key) {
case 'r': /* --retries */
if (arg < 1 || arg > 1000) {
showUsage(1);
return false;
}
m_retries = (int) arg;
break;
case 'R': /* --retry-pause */
if (arg < 1 || arg > 3600) {
showUsage(1);
return false;
}
m_retryPause = (int) arg;
break;
case 't': /* --threads */
if (arg < 1 || arg > 1024) {
showUsage(1);
return false;
}
m_threads = (int) arg;
break;
case 'v': /* --av */
if (arg > 1000) {
showUsage(1);
return false;
}
m_algoVariant = (int) arg;
break;
case 1003: /* --donate-level */
if (arg < 1 || arg > 99) {
return true;
}
m_donateLevel = (int) arg;
break;
case 1004: /* --max-cpu-usage */
if (arg < 1 || arg > 100) {
showUsage(1);
return false;
}
m_maxCpuUsage = (int) arg;
break;
case 1007: /* --print-time */
if (arg > 1000) {
showUsage(1);
return false;
}
m_printTime = (int) arg;
break;
case 1020: /* --cpu-affinity */
if (arg) {
m_affinity = arg;
}
break;
case 1021: /* --cpu-priority */
if (arg <= 5) {
m_priority = (int) arg;
}
break;
case 4000: /* --api-port */
if (arg <= 65536) {
m_apiPort = (int) arg;
}
break;
default:
break;
}
return true;
}
bool Options::parseBoolean(int key, bool enable)
{
switch (key) {
case 'k': /* --keepalive */
m_pools.back()->setKeepAlive(enable);
break;
case 'B': /* --background */
m_background = enable;
m_colors = enable ? false : m_colors;
break;
case 'S': /* --syslog */
m_syslog = enable;
m_colors = enable ? false : m_colors;
break;
case 1002: /* --no-color */
m_colors = enable;
break;
case 1005: /* --safe */
m_safe = enable;
break;
case 1006: /* --nicehash */
m_pools.back()->setNicehash(enable);
break;
case 1009: /* --no-huge-pages */
m_hugePages = enable;
break;
case 2000: /* colors */
m_colors = enable;
break;
default:
break;
}
return true;
}
Url *Options::parseUrl(const char *arg) const
{
auto url = new Url(arg);
if (!url->isValid()) {
delete url;
return nullptr;
}
return url;
}
void Options::parseConfig(const char *fileName)
{
rapidjson::Document doc;
if (!getJSON(fileName, doc)) {
return;
}
for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) {
parseJSON(&config_options[i], doc);
}
const rapidjson::Value &pools = doc["pools"];
if (pools.IsArray()) {
for (const rapidjson::Value &value : pools.GetArray()) {
if (!value.IsObject()) {
continue;
}
for (size_t i = 0; i < ARRAY_SIZE(pool_options); i++) {
parseJSON(&pool_options[i], value);
}
}
}
const rapidjson::Value &api = doc["api"];
if (api.IsObject()) {
for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) {
parseJSON(&api_options[i], api);
}
}
}
void Options::parseJSON(const struct option *option, const rapidjson::Value &object)
{
if (!option->name || !object.HasMember(option->name)) {
return;
}
const rapidjson::Value &value = object[option->name];
if (option->has_arg && value.IsString()) {
parseArg(option->val, value.GetString());
}
else if (option->has_arg && value.IsUint64()) {
parseArg(option->val, value.GetUint64());
}
else if (!option->has_arg && value.IsBool()) {
parseBoolean(option->val, value.IsTrue());
}
}
void Options::showUsage(int status) const
{
if (status) {
fprintf(stderr, "Try \"" APP_ID "\" --help' for more information.\n");
}
else {
printf(usage);
}
}
void Options::showVersion()
{
printf(APP_NAME " " APP_VERSION "\n built on " __DATE__
# if defined(__clang__)
" with clang " __clang_version__);
# elif defined(__GNUC__)
" with GCC");
printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif defined(_MSC_VER)
" with MSVC");
printf(" %d", MSVC_VERSION);
# else
);
# endif
printf("\n features:"
# if defined(__i386__) || defined(_M_IX86)
" i386"
# elif defined(__x86_64__) || defined(_M_AMD64)
" x86_64"
# endif
# if defined(__AES__) || defined(_MSC_VER)
" AES-NI"
# endif
"\n");
printf("\nlibuv/%s\n", uv_version_string());
}
bool Options::setAlgo(const char *algo)
{
for (size_t i = 0; i < ARRAY_SIZE(algo_names); i++) {
if (algo_names[i] && !strcmp(algo, algo_names[i])) {
m_algo = (int) i;
break;
}
# ifndef XMRIG_NO_AEON
if (i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-light")) {
m_algo = ALGO_CRYPTONIGHT_LITE;
break;
}
# endif
if (i == ARRAY_SIZE(algo_names) - 1) {
showUsage(1);
return false;
}
}
return true;
}
int Options::getAlgoVariant() const
{
# ifndef XMRIG_NO_AEON
if (m_algo == ALGO_CRYPTONIGHT_LITE) {
return getAlgoVariantLite();
}
# endif
if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) {
return Cpu::hasAES() ? AV1_AESNI : AV3_SOFT_AES;
}
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) {
return m_algoVariant + 2;
}
return m_algoVariant;
}
#ifndef XMRIG_NO_AEON
int Options::getAlgoVariantLite() const
{
if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) {
return Cpu::hasAES() ? AV2_AESNI_DOUBLE : AV4_SOFT_AES_DOUBLE;
}
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) {
return m_algoVariant + 2;
}
return m_algoVariant;
}
#endif

View File

@@ -1,134 +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 __OPTIONS_H__
#define __OPTIONS_H__
#include <stdint.h>
#include <vector>
#include "rapidjson/fwd.h"
class Url;
struct option;
class Options
{
public:
enum Algo {
ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */
ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
};
enum AlgoVariant {
AV0_AUTO,
AV1_AESNI,
AV2_AESNI_DOUBLE,
AV3_SOFT_AES,
AV4_SOFT_AES_DOUBLE,
AV_MAX
};
static inline Options* i() { return m_self; }
static Options *parse(int argc, char **argv);
inline bool background() const { return m_background; }
inline bool colors() const { return m_colors; }
inline bool doubleHash() const { return m_doubleHash; }
inline bool hugePages() const { return m_hugePages; }
inline bool syslog() const { return m_syslog; }
inline const char *apiToken() const { return m_apiToken; }
inline const char *apiWorkerId() const { return m_apiWorkerId; }
inline const char *logFile() const { return m_logFile; }
inline const char *userAgent() const { return m_userAgent; }
inline const std::vector<Url*> &pools() const { return m_pools; }
inline int algo() const { return m_algo; }
inline int algoVariant() const { return m_algoVariant; }
inline int apiPort() const { return m_apiPort; }
inline int donateLevel() const { return m_donateLevel; }
inline int printTime() const { return m_printTime; }
inline int priority() const { return m_priority; }
inline int retries() const { return m_retries; }
inline int retryPause() const { return m_retryPause; }
inline int threads() const { return m_threads; }
inline int64_t affinity() const { return m_affinity; }
inline static void release() { delete m_self; }
const char *algoName() const;
private:
Options(int argc, char **argv);
~Options();
inline bool isReady() const { return m_ready; }
static Options *m_self;
bool getJSON(const char *fileName, rapidjson::Document &doc);
bool parseArg(int key, const char *arg);
bool parseArg(int key, uint64_t arg);
bool parseBoolean(int key, bool enable);
Url *parseUrl(const char *arg) const;
void parseConfig(const char *fileName);
void parseJSON(const struct option *option, const rapidjson::Value &object);
void showUsage(int status) const;
void showVersion(void);
bool setAlgo(const char *algo);
int getAlgoVariant() const;
# ifndef XMRIG_NO_AEON
int getAlgoVariantLite() const;
# endif
bool m_background;
bool m_colors;
bool m_doubleHash;
bool m_hugePages;
bool m_ready;
bool m_safe;
bool m_syslog;
char *m_apiToken;
char *m_apiWorkerId;
char *m_logFile;
char *m_userAgent;
int m_algo;
int m_algoVariant;
int m_apiPort;
int m_donateLevel;
int m_maxCpuUsage;
int m_printTime;
int m_priority;
int m_retries;
int m_retryPause;
int m_threads;
int64_t m_affinity;
std::vector<Url*> m_pools;
};
#endif /* __OPTIONS_H__ */

View File

@@ -22,6 +22,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <uv.h>
@@ -41,11 +42,11 @@ static inline char *createUserAgent()
char *buf = new char[max];
# ifdef XMRIG_NVIDIA_PROJECT
const int cudaVersion = cuda_get_runtime_version();
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s CUDA/%d.%d clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), cudaVersion / 1000, cudaVersion % 100, __clang_major__, __clang_minor__, __clang_patchlevel__);
# else
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), __clang_major__, __clang_minor__, __clang_patchlevel__);
# ifdef XMRIG_NVIDIA_PROJECT
const int cudaVersion = cuda_get_runtime_version();
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s CUDA/%d.%d clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), cudaVersion / 1000, cudaVersion % 100, __clang_major__, __clang_minor__, __clang_patchlevel__);
# else
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), __clang_major__, __clang_minor__, __clang_patchlevel__);
# endif
return buf;

View File

@@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
@@ -116,6 +116,7 @@ void Platform::setThreadPriority(int priority)
setpriority(PRIO_PROCESS, 0, prio);
# ifdef SCHED_IDLE
if (priority == 0) {
sched_param param;
param.sched_priority = 0;
@@ -124,4 +125,5 @@ void Platform::setThreadPriority(int priority)
sched_setscheduler(0, SCHED_BATCH, &param);
}
}
# endif
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,19 +23,21 @@
#include <inttypes.h>
#include <stdio.h>
#include <uv.h>
#include "core/Config.h"
#include "core/Controller.h"
#include "Cpu.h"
#include "log/Log.h"
#include "Mem.h"
#include "net/Url.h"
#include "Options.h"
#include "Summary.h"
#include "version.h"
static void print_versions()
static void print_versions(xmrig::Config *config)
{
char buf[16];
@@ -50,13 +52,13 @@ static void print_versions()
# endif
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" : " * VERSIONS: XMRig/%s libuv/%s%s",
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" : " * VERSIONS: XMRig/%s libuv/%s%s",
APP_VERSION, uv_version_string(), buf);
}
static void print_memory() {
if (Options::i()->colors()) {
static void print_memory(xmrig::Config *config) {
if (config->isColors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s",
Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable",
Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled");
@@ -67,9 +69,9 @@ static void print_memory() {
}
static void print_cpu()
static void print_cpu(xmrig::Config *config)
{
if (Options::i()->colors()) {
if (config->isColors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI",
Cpu::brand(),
Cpu::sockets(),
@@ -88,32 +90,32 @@ static void print_cpu()
}
static void print_threads()
static void print_threads(xmrig::Config *config)
{
char buf[32];
if (Options::i()->affinity() != -1L) {
snprintf(buf, 32, ", affinity=0x%" PRIX64, Options::i()->affinity());
if (config->affinity() != -1L) {
snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity());
}
else {
buf[0] = '\0';
}
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s",
Options::i()->threads(),
Options::i()->algoName(),
Options::i()->algoVariant(),
Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "",
Options::i()->donateLevel(),
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s",
config->threadsCount(),
config->algoName(),
config->algoVariant(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "",
config->donateLevel(),
buf);
}
static void print_pools()
static void print_pools(xmrig::Config *config)
{
const std::vector<Url*> &pools = Options::i()->pools();
const std::vector<Url*> &pools = config->pools();
for (size_t i = 0; i < pools.size(); ++i) {
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s:%d" : " * POOL #%d: %s:%d",
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s:%d" : " * POOL #%d: %s:%d",
i + 1,
pools[i]->host(),
pools[i]->port());
@@ -128,20 +130,22 @@ static void print_pools()
#ifndef XMRIG_NO_API
static void print_api()
static void print_api(xmrig::Config *config)
{
if (Options::i()->apiPort() == 0) {
const int port = config->apiPort();
if (port == 0) {
return;
}
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT: \x1B[01;36m%d" : " * API PORT: %d", Options::i()->apiPort());
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mAPI BIND: \x1B[01;36m%s:%d" : " * API BIND: %s:%d",
config->isApiIPv6() ? "[::]" : "0.0.0.0", port);
}
#endif
static void print_commands()
static void print_commands(xmrig::Config *config)
{
if (Options::i()->colors()) {
if (config->isColors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mh\x1B[01;37mashrate, \x1B[01;35mp\x1B[01;37mause, \x1B[01;35mr\x1B[01;37mesume");
}
else {
@@ -150,19 +154,19 @@ static void print_commands()
}
void Summary::print()
void Summary::print(xmrig::Controller *controller)
{
print_versions();
print_memory();
print_cpu();
print_threads();
print_pools();
print_versions(controller->config());
print_memory(controller->config());
print_cpu(controller->config());
print_threads(controller->config());
print_pools(controller->config());
# ifndef XMRIG_NO_API
print_api();
print_api(controller->config());
# endif
print_commands();
print_commands(controller->config());
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,10 +25,15 @@
#define __SUMMARY_H__
namespace xmrig {
class Controller;
}
class Summary
{
public:
static void print();
static void print(xmrig::Controller *controller);
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,17 +25,17 @@
#include "api/Api.h"
#include "api/ApiState.h"
#include "api/ApiRouter.h"
#include "api/HttpReply.h"
#include "api/HttpRequest.h"
ApiState *Api::m_state = nullptr;
uv_mutex_t Api::m_mutex;
ApiRouter *Api::m_router = nullptr;
bool Api::start()
bool Api::start(xmrig::Controller *controller)
{
uv_mutex_init(&m_mutex);
m_state = new ApiState();
m_router = new ApiRouter(controller);
return true;
}
@@ -43,43 +43,40 @@ bool Api::start()
void Api::release()
{
delete m_state;
delete m_router;
}
char *Api::get(const char *url, int *status)
void Api::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
{
if (!m_state) {
return nullptr;
if (!m_router) {
reply.status = 500;
return;
}
uv_mutex_lock(&m_mutex);
char *buf = m_state->get(url, status);
uv_mutex_unlock(&m_mutex);
if (req.method() == xmrig::HttpRequest::Get) {
return m_router->get(req, reply);
}
return buf;
m_router->exec(req, reply);
}
void Api::tick(const Hashrate *hashrate)
{
if (!m_state) {
if (!m_router) {
return;
}
uv_mutex_lock(&m_mutex);
m_state->tick(hashrate);
uv_mutex_unlock(&m_mutex);
m_router->tick(hashrate);
}
void Api::tick(const NetworkState &network)
{
if (!m_state) {
if (!m_router) {
return;
}
uv_mutex_lock(&m_mutex);
m_state->tick(network);
uv_mutex_unlock(&m_mutex);
m_router->tick(network);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,24 +28,30 @@
#include <uv.h>
class ApiState;
class ApiRouter;
class Hashrate;
class NetworkState;
namespace xmrig {
class Controller;
class HttpReply;
class HttpRequest;
}
class Api
{
public:
static bool start();
static bool start(xmrig::Controller *controller);
static void release();
static char *get(const char *url, int *status);
static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
static void tick(const Hashrate *hashrate);
static void tick(const NetworkState &results);
private:
static ApiState *m_state;
static uv_mutex_t m_mutex;
static ApiRouter *m_router;
};
#endif /* __API_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cmath>
#include <math.h>
#include <string.h>
#include <uv.h>
@@ -32,15 +32,19 @@
#endif
#include "api/ApiState.h"
#include "api/ApiRouter.h"
#include "api/HttpReply.h"
#include "api/HttpRequest.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "Cpu.h"
#include "interfaces/IThread.h"
#include "Mem.h"
#include "net/Job.h"
#include "Options.h"
#include "Platform.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include "version.h"
#include "workers/Hashrate.h"
@@ -53,42 +57,55 @@ extern "C"
static inline double normalize(double d)
{
if (!std::isnormal(d)) {
if (!isnormal(d)) {
return 0.0;
}
return std::floor(d * 100.0) / 100.0;
return floor(d * 100.0) / 100.0;
}
ApiState::ApiState()
ApiRouter::ApiRouter(xmrig::Controller *controller) :
m_controller(controller)
{
m_threads = Options::i()->threads();
m_threads = controller->config()->threadsCount();
m_hashrate = new double[m_threads * 3]();
memset(m_totalHashrate, 0, sizeof(m_totalHashrate));
memset(m_workerId, 0, sizeof(m_workerId));
if (Options::i()->apiWorkerId()) {
strncpy(m_workerId, Options::i()->apiWorkerId(), sizeof(m_workerId) - 1);
}
else {
gethostname(m_workerId, sizeof(m_workerId) - 1);
}
setWorkerId(controller->config()->apiWorkerId());
genId();
}
ApiState::~ApiState()
ApiRouter::~ApiRouter()
{
delete [] m_hashrate;
}
char *ApiState::get(const char *url, int *status) const
void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const
{
rapidjson::Document doc;
if (req.match("/1/config")) {
if (req.isRestricted()) {
reply.status = 403;
return;
}
m_controller->config()->getJSON(doc);
return finalize(reply, doc);
}
if (req.match("/1/threads")) {
getThreads(doc);
return finalize(reply, doc);
}
doc.SetObject();
getIdentify(doc);
@@ -97,11 +114,22 @@ char *ApiState::get(const char *url, int *status) const
getResults(doc);
getConnection(doc);
return finalize(doc);
return finalize(reply, doc);
}
void ApiState::tick(const Hashrate *hashrate)
void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
{
if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) {
m_controller->config()->reload(req.body());
return;
}
reply.status = 404;
}
void ApiRouter::tick(const Hashrate *hashrate)
{
for (int i = 0; i < m_threads; ++i) {
m_hashrate[i * 3] = hashrate->calc((size_t) i, Hashrate::ShortInterval);
@@ -116,24 +144,32 @@ void ApiState::tick(const Hashrate *hashrate)
}
void ApiState::tick(const NetworkState &network)
void ApiRouter::tick(const NetworkState &network)
{
m_network = network;
}
char *ApiState::finalize(rapidjson::Document &doc) const
void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
{
updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId());
}
void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const
{
rapidjson::StringBuffer buffer(0, 4096);
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
writer.SetMaxDecimalPlaces(10);
doc.Accept(writer);
return strdup(buffer.GetString());
reply.status = 200;
reply.buf = strdup(buffer.GetString());
reply.size = buffer.GetSize();
}
void ApiState::genId()
void ApiRouter::genId()
{
memset(m_id, 0, sizeof(m_id));
@@ -166,7 +202,7 @@ void ApiState::genId()
}
void ApiState::getConnection(rapidjson::Document &doc) const
void ApiRouter::getConnection(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
@@ -181,7 +217,7 @@ void ApiState::getConnection(rapidjson::Document &doc) const
}
void ApiState::getHashrate(rapidjson::Document &doc) const
void ApiRouter::getHashrate(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
@@ -209,14 +245,14 @@ void ApiState::getHashrate(rapidjson::Document &doc) const
}
void ApiState::getIdentify(rapidjson::Document &doc) const
void ApiRouter::getIdentify(rapidjson::Document &doc) const
{
doc.AddMember("id", rapidjson::StringRef(m_id), doc.GetAllocator());
doc.AddMember("worker_id", rapidjson::StringRef(m_workerId), doc.GetAllocator());
}
void ApiState::getMiner(rapidjson::Document &doc) const
void ApiRouter::getMiner(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
@@ -230,13 +266,13 @@ void ApiState::getMiner(rapidjson::Document &doc) const
doc.AddMember("kind", APP_KIND, allocator);
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
doc.AddMember("cpu", cpu, allocator);
doc.AddMember("algo", rapidjson::StringRef(Options::i()->algoName()), allocator);
doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algoName()), allocator);
doc.AddMember("hugepages", Mem::isHugepagesEnabled(), allocator);
doc.AddMember("donate_level", Options::i()->donateLevel(), allocator);
doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator);
}
void ApiState::getResults(rapidjson::Document &doc) const
void ApiRouter::getResults(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
@@ -258,3 +294,42 @@ void ApiState::getResults(rapidjson::Document &doc) const
doc.AddMember("results", results, allocator);
}
void ApiRouter::getThreads(rapidjson::Document &doc) const
{
doc.SetArray();
const std::vector<xmrig::IThread *> &threads = m_controller->config()->threads();
for (const xmrig::IThread *thread : threads) {
doc.PushBack(thread->toAPI(doc), doc.GetAllocator());
}
}
void ApiRouter::setWorkerId(const char *id)
{
memset(m_workerId, 0, sizeof(m_workerId));
if (id && strlen(id) > 0) {
strncpy(m_workerId, id, sizeof(m_workerId) - 1);
}
else {
gethostname(m_workerId, sizeof(m_workerId) - 1);
}
}
void ApiRouter::updateWorkerId(const char *id, const char *previousId)
{
if (id == previousId) {
return;
}
if (id != nullptr && previousId != nullptr && strcmp(id, previousId) == 0) {
return;
}
setWorkerId(id);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,35 +21,51 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __APISTATE_H__
#define __APISTATE_H__
#ifndef __APIROUTER_H__
#define __APIROUTER_H__
#include "api/NetworkState.h"
#include "interfaces/IControllerListener.h"
#include "rapidjson/fwd.h"
class Hashrate;
class ApiState
namespace xmrig {
class Controller;
class HttpReply;
class HttpRequest;
}
class ApiRouter : public xmrig::IControllerListener
{
public:
ApiState();
~ApiState();
ApiRouter(xmrig::Controller *controller);
~ApiRouter();
void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const;
void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
char *get(const char *url, int *status) const;
void tick(const Hashrate *hashrate);
void tick(const NetworkState &results);
protected:
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
private:
char *finalize(rapidjson::Document &doc) const;
void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const;
void genId();
void getConnection(rapidjson::Document &doc) const;
void getHashrate(rapidjson::Document &doc) const;
void getIdentify(rapidjson::Document &doc) const;
void getMiner(rapidjson::Document &doc) const;
void getResults(rapidjson::Document &doc) const;
void getThreads(rapidjson::Document &doc) const;
void setWorkerId(const char *id);
void updateWorkerId(const char *id, const char *previousId);
char m_id[17];
char m_workerId[128];
@@ -58,6 +74,7 @@ private:
double m_totalHashrate[3];
int m_threads;
NetworkState m_network;
xmrig::Controller *m_controller;
};
#endif /* __APISTATE_H__ */
#endif /* __APIROUTER_H__ */

69
src/api/HttpBody.h Normal file
View File

@@ -0,0 +1,69 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __HTTPBODY_H__
#define __HTTPBODY_H__
#include <string.h>
namespace xmrig {
class HttpBody
{
public:
inline HttpBody() :
m_pos(0)
{}
inline bool write(const char *data, size_t size)
{
if (size > (sizeof(m_data) - m_pos - 1)) {
return false;
}
memcpy(m_data + m_pos, data, size);
m_pos += size;
m_data[m_pos] = '\0';
return true;
}
inline const char *data() const { return m_data; }
private:
char m_data[32768];
size_t m_pos;
};
} /* namespace xmrig */
#endif /* __HTTPBODY_H__ */

53
src/api/HttpReply.h Normal file
View File

@@ -0,0 +1,53 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __HTTPREPLY_H__
#define __HTTPREPLY_H__
#include <stdint.h>
namespace xmrig {
class HttpReply
{
public:
HttpReply() :
buf(nullptr),
status(200),
size(0)
{}
char *buf;
int status;
size_t size;
};
} /* namespace xmrig */
#endif /* __HTTPREPLY_H__ */

175
src/api/HttpRequest.cpp Normal file
View File

@@ -0,0 +1,175 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <microhttpd.h>
#include <string.h>
#include "api/HttpBody.h"
#include "api/HttpRequest.h"
#include "api/HttpReply.h"
#ifndef MHD_HTTP_PAYLOAD_TOO_LARGE
# define MHD_HTTP_PAYLOAD_TOO_LARGE 413
#endif
xmrig::HttpRequest::HttpRequest(MHD_Connection *connection, const char *url, const char *method, const char *uploadData, size_t *uploadSize, void **cls) :
m_fulfilled(true),
m_restricted(true),
m_uploadData(uploadData),
m_url(url),
m_body(static_cast<HttpBody*>(*cls)),
m_method(Unsupported),
m_connection(connection),
m_uploadSize(uploadSize),
m_cls(cls)
{
if (strcmp(method, MHD_HTTP_METHOD_OPTIONS) == 0) {
m_method = Options;
}
else if (strcmp(method, MHD_HTTP_METHOD_GET) == 0) {
m_method = Get;
}
else if (strcmp(method, MHD_HTTP_METHOD_PUT) == 0) {
m_method = Put;
}
}
xmrig::HttpRequest::~HttpRequest()
{
if (m_fulfilled) {
delete m_body;
}
}
bool xmrig::HttpRequest::match(const char *path) const
{
return strcmp(m_url, path) == 0;
}
bool xmrig::HttpRequest::process(const char *accessToken, bool restricted, xmrig::HttpReply &reply)
{
m_restricted = restricted || !accessToken;
if (m_body) {
if (*m_uploadSize != 0) {
if (!m_body->write(m_uploadData, *m_uploadSize)) {
*m_cls = nullptr;
m_fulfilled = true;
reply.status = MHD_HTTP_PAYLOAD_TOO_LARGE;
return false;
}
*m_uploadSize = 0;
m_fulfilled = false;
return true;
}
m_fulfilled = true;
return true;
}
reply.status = auth(accessToken);
if (reply.status != MHD_HTTP_OK) {
return false;
}
if (m_restricted && m_method != Get) {
reply.status = MHD_HTTP_FORBIDDEN;
return false;
}
if (m_method == Get) {
return true;
}
const char *contentType = MHD_lookup_connection_value(m_connection, MHD_HEADER_KIND, "Content-Type");
if (!contentType || strcmp(contentType, "application/json") != 0) {
reply.status = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE;
return false;
}
m_body = new xmrig::HttpBody();
m_fulfilled = false;
*m_cls = m_body;
return true;
}
const char *xmrig::HttpRequest::body() const
{
return m_body ? m_body->data() : nullptr;
}
int xmrig::HttpRequest::end(const HttpReply &reply)
{
if (reply.buf) {
return end(reply.status, MHD_create_response_from_buffer(reply.size ? reply.size : strlen(reply.buf), (void*) reply.buf, MHD_RESPMEM_MUST_FREE));
}
return end(reply.status, nullptr);
}
int xmrig::HttpRequest::end(int status, MHD_Response *rsp)
{
if (!rsp) {
rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);
}
MHD_add_response_header(rsp, "Content-Type", "application/json");
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*");
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET, PUT");
MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization");
const int ret = MHD_queue_response(m_connection, status, rsp);
MHD_destroy_response(rsp);
return ret;
}
int xmrig::HttpRequest::auth(const char *accessToken)
{
if (!accessToken) {
return MHD_HTTP_OK;
}
const char *header = MHD_lookup_connection_value(m_connection, MHD_HEADER_KIND, "Authorization");
if (accessToken && !header) {
return MHD_HTTP_UNAUTHORIZED;
}
const size_t size = strlen(header);
if (size < 8 || strlen(accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) {
return MHD_HTTP_FORBIDDEN;
}
return strncmp(accessToken, header + 7, strlen(accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
}

84
src/api/HttpRequest.h Normal file
View File

@@ -0,0 +1,84 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __HTTPREQUEST_H__
#define __HTTPREQUEST_H__
#include <stdint.h>
struct MHD_Connection;
struct MHD_Response;
namespace xmrig {
class HttpBody;
class HttpReply;
class HttpRequest
{
public:
enum Method {
Unsupported,
Options,
Get,
Put
};
HttpRequest(MHD_Connection *connection, const char *url, const char *method, const char *uploadData, size_t *uploadSize, void **cls);
~HttpRequest();
inline bool isFulfilled() const { return m_fulfilled; }
inline bool isRestricted() const { return m_restricted; }
inline Method method() const { return m_method; }
bool match(const char *path) const;
bool process(const char *accessToken, bool restricted, xmrig::HttpReply &reply);
const char *body() const;
int end(const HttpReply &reply);
int end(int status, MHD_Response *rsp);
private:
int auth(const char *accessToken);
bool m_fulfilled;
bool m_restricted;
const char *m_uploadData;
const char *m_url;
HttpBody *m_body;
Method m_method;
MHD_Connection *m_connection;
size_t *m_uploadSize;
void **m_cls;
};
} /* namespace xmrig */
#endif /* __HTTPREQUEST_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,14 +28,64 @@
#include "api/Api.h"
#include "api/Httpd.h"
#include "api/HttpReply.h"
#include "api/HttpRequest.h"
#include "log/Log.h"
Httpd::Httpd(int port, const char *accessToken) :
m_accessToken(accessToken),
class UploadCtx
{
public:
inline UploadCtx() :
m_pos(0)
{}
inline bool write(const char *data, size_t size)
{
if (size > (sizeof(m_data) - m_pos - 1)) {
return false;
}
memcpy(m_data + m_pos, data, size);
m_pos += size;
m_data[m_pos] = '\0';
return true;
}
inline const char *data() const { return m_data; }
private:
char m_data[32768];
size_t m_pos;
};
Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) :
m_idle(true),
m_IPv6(IPv6),
m_restricted(restricted),
m_accessToken(accessToken ? strdup(accessToken) : nullptr),
m_port(port),
m_daemon(nullptr)
{
uv_timer_init(uv_default_loop(), &m_timer);
m_timer.data = this;
}
Httpd::~Httpd()
{
uv_timer_stop(&m_timer);
if (m_daemon) {
MHD_stop_daemon(m_daemon);
}
delete m_accessToken;
}
@@ -45,72 +95,78 @@ bool Httpd::start()
return false;
}
m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
unsigned int flags = 0;
# if MHD_VERSION >= 0x00093500
if (m_IPv6 && MHD_is_feature_supported(MHD_FEATURE_IPv6)) {
flags |= MHD_USE_DUAL_STACK;
}
if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
flags |= MHD_USE_EPOLL_LINUX_ONLY;
}
# endif
m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
if (!m_daemon) {
LOG_ERR("HTTP Daemon failed to start.");
return false;
}
uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval);
return true;
}
int Httpd::auth(const char *header)
int Httpd::process(xmrig::HttpRequest &req)
{
if (!m_accessToken) {
return MHD_HTTP_OK;
xmrig::HttpReply reply;
if (!req.process(m_accessToken, m_restricted, reply)) {
return req.end(reply);
}
if (m_accessToken && !header) {
return MHD_HTTP_UNAUTHORIZED;
if (!req.isFulfilled()) {
return MHD_YES;
}
const size_t size = strlen(header);
if (size < 8 || strlen(m_accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) {
return MHD_HTTP_FORBIDDEN;
}
Api::exec(req, reply);
return strncmp(m_accessToken, header + 7, strlen(m_accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
return req.end(reply);
}
int Httpd::done(MHD_Connection *connection, int status, MHD_Response *rsp)
void Httpd::run()
{
if (!rsp) {
rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);
MHD_run(m_daemon);
const MHD_DaemonInfo *info = MHD_get_daemon_info(m_daemon, MHD_DAEMON_INFO_CURRENT_CONNECTIONS);
if (m_idle && info->num_connections) {
uv_timer_set_repeat(&m_timer, kActiveInterval);
m_idle = false;
}
else if (!m_idle && !info->num_connections) {
uv_timer_set_repeat(&m_timer, kIdleInterval);
m_idle = true;
}
MHD_add_response_header(rsp, "Content-Type", "application/json");
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*");
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET");
MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization");
const int ret = MHD_queue_response(connection, status, rsp);
MHD_destroy_response(rsp);
return ret;
}
int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls)
{
if (strcmp(method, "OPTIONS") == 0) {
return done(connection, MHD_HTTP_OK, nullptr);
xmrig::HttpRequest req(connection, url, method, uploadData, uploadSize, con_cls);
if (req.method() == xmrig::HttpRequest::Options) {
return req.end(MHD_HTTP_OK, nullptr);
}
if (strcmp(method, "GET") != 0) {
return MHD_NO;
if (req.method() == xmrig::HttpRequest::Unsupported) {
return req.end(MHD_HTTP_METHOD_NOT_ALLOWED, nullptr);
}
int status = static_cast<Httpd*>(cls)->auth(MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Authorization"));
if (status != MHD_HTTP_OK) {
return done(connection, status, nullptr);
}
char *buf = Api::get(url, &status);
if (buf == nullptr) {
return MHD_NO;
}
MHD_Response *rsp = MHD_create_response_from_buffer(strlen(buf), (void*) buf, MHD_RESPMEM_MUST_FREE);
return done(connection, status, rsp);
return static_cast<Httpd*>(cls)->process(req);
}
void Httpd::onTimer(uv_timer_t *handle)
{
static_cast<Httpd*>(handle->data)->run();
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,21 +33,38 @@ struct MHD_Daemon;
struct MHD_Response;
class UploadCtx;
namespace xmrig {
class HttpRequest;
}
class Httpd
{
public:
Httpd(int port, const char *accessToken);
Httpd(int port, const char *accessToken, bool IPv6, bool restricted);
~Httpd();
bool start();
private:
int auth(const char *header);
constexpr static const int kIdleInterval = 200;
constexpr static const int kActiveInterval = 25;
static int done(MHD_Connection *connection, int status, MHD_Response *rsp);
static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls);
int process(xmrig::HttpRequest &req);
void run();
static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls);
static void onTimer(uv_timer_t *handle);
bool m_idle;
bool m_IPv6;
bool m_restricted;
const char *m_accessToken;
const int m_port;
MHD_Daemon *m_daemon;
uv_timer_t m_timer;
};
#endif /* __HTTPD_H__ */

View File

@@ -23,6 +23,7 @@
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <uv.h>
@@ -45,7 +46,7 @@ NetworkState::NetworkState() :
int NetworkState::connectionTime() const
{
return m_active ? ((uv_now(uv_default_loop()) - m_connectionTime) / 1000) : 0;
return m_active ? (int)((uv_now(uv_default_loop()) - m_connectionTime) / 1000) : 0;
}
@@ -55,7 +56,7 @@ uint32_t NetworkState::avgTime() const
return 0;
}
return (uint32_t) connectionTime() / m_latency.size();
return connectionTime() / (uint32_t)m_latency.size();
}

View File

@@ -16,11 +16,12 @@
"threads": null, // number of miner threads
"pools": [
{
"url": "pool.minemonero.pro:5555", // URL of mining server
"user": "", // username for mining server
"pass": "x", // password for mining server
"keepalive": true, // send keepalived for prevent timeout (need pool support)
"nicehash": false // enable nicehash/xmrig-proxy support
"url": "failover.xmrig.com:443", // URL of mining server
"user": "YOUR_WALLET", // username for mining server
"pass": "x", // password for mining server
"keepalive": true, // send keepalived for prevent timeout (need pool support)
"nicehash": false, // enable nicehash/xmrig-proxy support
"variant": -1 // algorithm PoW variant
}
],
"api": {

382
src/core/CommonConfig.cpp Normal file
View File

@@ -0,0 +1,382 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#include "core/CommonConfig.h"
#include "donate.h"
#include "log/Log.h"
#include "net/Url.h"
#include "rapidjson/document.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h"
#include "xmrig.h"
static const char *algoNames[] = {
"cryptonight",
"cryptonight-lite",
"cryptonight-heavy"
};
#if defined(_WIN32) && !defined(strcasecmp)
# define strcasecmp _stricmp
#endif
xmrig::CommonConfig::CommonConfig() :
m_algorithm(CRYPTONIGHT),
m_adjusted(false),
m_apiIPv6(true),
m_apiRestricted(true),
m_background(false),
m_colors(true),
m_syslog(false),
m_watch(false), // TODO: enable config file watch by default when this feature propertly handled and tested.
m_apiToken(nullptr),
m_apiWorkerId(nullptr),
m_fileName(nullptr),
m_logFile(nullptr),
m_userAgent(nullptr),
m_apiPort(0),
m_donateLevel(kDefaultDonateLevel),
m_printTime(60),
m_retries(5),
m_retryPause(5)
{
m_pools.push_back(new Url());
# ifdef XMRIG_PROXY_PROJECT
m_retries = 2;
m_retryPause = 1;
# endif
}
xmrig::CommonConfig::~CommonConfig()
{
for (Url *url : m_pools) {
delete url;
}
m_pools.clear();
free(m_fileName);
free(m_apiToken);
free(m_apiWorkerId);
free(m_logFile);
free(m_userAgent);
}
const char *xmrig::CommonConfig::algoName(Algo algorithm)
{
return algoNames[algorithm];
}
bool xmrig::CommonConfig::adjust()
{
if (m_adjusted) {
return false;
}
m_adjusted = true;
for (Url *url : m_pools) {
url->adjust(algorithm());
}
return true;
}
bool xmrig::CommonConfig::isValid() const
{
return m_pools[0]->isValid();
}
bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
{
switch (key) {
case BackgroundKey: /* --background */
m_background = enable;
break;
case SyslogKey: /* --syslog */
m_syslog = enable;
break;
case KeepAliveKey: /* --keepalive */
m_pools.back()->setKeepAlive(enable ? Url::kKeepAliveTimeout : 0);
break;
# ifndef XMRIG_PROXY_PROJECT
case NicehashKey: /* --nicehash */
m_pools.back()->setNicehash(enable);
break;
# endif
case ColorKey: /* --no-color */
m_colors = enable;
break;
case WatchKey: /* watch */
m_watch = enable;
break;
case ApiIPv6Key: /* ipv6 */
m_apiIPv6 = enable;
case ApiRestrictedKey: /* restricted */
m_apiRestricted = enable;
default:
break;
}
return true;
}
bool xmrig::CommonConfig::parseString(int key, const char *arg)
{
switch (key) {
case AlgorithmKey: /* --algo */
setAlgo(arg);
break;
case UserpassKey: /* --userpass */
if (!m_pools.back()->setUserpass(arg)) {
return false;
}
break;
case UrlKey: /* --url */
if (m_pools.size() > 1 || m_pools[0]->isValid()) {
Url *url = new Url(arg);
if (url->isValid()) {
m_pools.push_back(url);
}
else {
delete url;
}
}
else {
m_pools[0]->parse(arg);
}
if (!m_pools.back()->isValid()) {
return false;
}
break;
case UserKey: /* --user */
m_pools.back()->setUser(arg);
break;
case PasswordKey: /* --pass */
m_pools.back()->setPassword(arg);
break;
case LogFileKey: /* --log-file */
free(m_logFile);
m_logFile = strdup(arg);
break;
case ApiAccessTokenKey: /* --api-access-token */
free(m_apiToken);
m_apiToken = strdup(arg);
break;
case ApiWorkerIdKey: /* --api-worker-id */
free(m_apiWorkerId);
m_apiWorkerId = strdup(arg);
break;
case UserAgentKey: /* --user-agent */
free(m_userAgent);
m_userAgent = strdup(arg);
break;
case RetriesKey: /* --retries */
case RetryPauseKey: /* --retry-pause */
case VariantKey: /* --variant */
case ApiPort: /* --api-port */
case PrintTimeKey: /* --cpu-priority */
return parseUint64(key, strtol(arg, nullptr, 10));
case BackgroundKey: /* --background */
case SyslogKey: /* --syslog */
case KeepAliveKey: /* --keepalive */
case NicehashKey: /* --nicehash */
return parseBoolean(key, true);
case ColorKey: /* --no-color */
case WatchKey: /* --no-watch */
case ApiRestrictedKey: /* --api-no-restricted */
case ApiIPv6Key: /* --api-no-ipv6 */
return parseBoolean(key, false);
# ifdef XMRIG_PROXY_PROJECT
case 1003: /* --donate-level */
if (strncmp(arg, "minemonero.pro", 14) == 0) {
m_donateLevel = 0;
}
else {
parseUint64(key, strtol(arg, nullptr, 10));
}
break;
# endif
default:
break;
}
return true;
}
bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg)
{
return parseInt(key, static_cast<int>(arg));
}
bool xmrig::CommonConfig::save()
{
if (!m_fileName) {
return false;
}
uv_fs_t req;
const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName, O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr);
if (fd < 0) {
return false;
}
uv_fs_req_cleanup(&req);
rapidjson::Document doc;
getJSON(doc);
FILE *fp = fdopen(fd, "w");
char buf[4096];
rapidjson::FileWriteStream os(fp, buf, sizeof(buf));
rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os);
doc.Accept(writer);
fclose(fp);
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req);
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName);
return true;
}
void xmrig::CommonConfig::setFileName(const char *fileName)
{
free(m_fileName);
m_fileName = fileName ? strdup(fileName) : nullptr;
}
bool xmrig::CommonConfig::parseInt(int key, int arg)
{
switch (key) {
case RetriesKey: /* --retries */
if (arg > 0 && arg <= 1000) {
m_retries = arg;
}
break;
case RetryPauseKey: /* --retry-pause */
if (arg > 0 && arg <= 3600) {
m_retryPause = arg;
}
break;
case KeepAliveKey: /* --keepalive */
m_pools.back()->setKeepAlive(arg);
break;
case VariantKey: /* --variant */
m_pools.back()->setVariant(arg);
break;
case DonateLevelKey: /* --donate-level */
if (arg >= kMinDonateLevel && arg <= 99) {
m_donateLevel = arg;
}
break;
case ApiPort: /* --api-port */
if (arg > 0 && arg <= 65536) {
m_apiPort = arg;
}
break;
case PrintTimeKey: /* --print-time */
if (arg >= 0 && arg <= 3600) {
m_printTime = arg;
}
break;
default:
break;
}
return true;
}
void xmrig::CommonConfig::setAlgo(const char *algo)
{
if (strcasecmp(algo, "cryptonight-light") == 0) {
fprintf(stderr, "Algorithm \"cryptonight-light\" is deprecated, use \"cryptonight-lite\" instead\n");
m_algorithm = CRYPTONIGHT_LITE;
return;
}
const size_t size = sizeof(algoNames) / sizeof((algoNames)[0]);
for (size_t i = 0; i < size; i++) {
if (algoNames[i] && strcasecmp(algo, algoNames[i]) == 0) {
m_algorithm = static_cast<Algo>(i);
break;
}
}
}

108
src/core/CommonConfig.h Normal file
View File

@@ -0,0 +1,108 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __COMMONCONFIG_H__
#define __COMMONCONFIG_H__
#include <vector>
#include "interfaces/IConfig.h"
#include "xmrig.h"
class Url;
namespace xmrig {
class CommonConfig : public IConfig
{
public:
CommonConfig();
~CommonConfig();
static const char *algoName(Algo algorithm);
inline Algo algorithm() const { return m_algorithm; }
inline bool isApiIPv6() const { return m_apiIPv6; }
inline bool isApiRestricted() const { return m_apiRestricted; }
inline bool isBackground() const { return m_background; }
inline bool isColors() const { return m_colors; }
inline bool isSyslog() const { return m_syslog; }
inline const char *algoName() const { return algoName(m_algorithm); }
inline const char *apiToken() const { return m_apiToken; }
inline const char *apiWorkerId() const { return m_apiWorkerId; }
inline const char *logFile() const { return m_logFile; }
inline const char *userAgent() const { return m_userAgent; }
inline const std::vector<Url*> &pools() const { return m_pools; }
inline int apiPort() const { return m_apiPort; }
inline int donateLevel() const { return m_donateLevel; }
inline int printTime() const { return m_printTime; }
inline int retries() const { return m_retries; }
inline int retryPause() const { return m_retryPause; }
inline void setColors(bool colors) { m_colors = colors; }
inline bool isWatch() const override { return m_watch && m_fileName; }
inline const char *fileName() const override { return m_fileName; }
protected:
bool adjust() override;
bool isValid() const override;
bool parseBoolean(int key, bool enable) override;
bool parseString(int key, const char *arg) override;
bool parseUint64(int key, uint64_t arg) override;
bool save() override;
void setFileName(const char *fileName) override;
Algo m_algorithm;
bool m_adjusted;
bool m_apiIPv6;
bool m_apiRestricted;
bool m_background;
bool m_colors;
bool m_syslog;
bool m_watch;
char *m_apiToken;
char *m_apiWorkerId;
char *m_fileName;
char *m_logFile;
char *m_userAgent;
int m_apiPort;
int m_donateLevel;
int m_printTime;
int m_retries;
int m_retryPause;
std::vector<Url*> m_pools;
private:
bool parseInt(int key, int arg);
void setAlgo(const char *algo);
};
} /* namespace xmrig */
#endif /* __COMMONCONFIG_H__ */

346
src/core/Config.cpp Normal file
View File

@@ -0,0 +1,346 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <uv.h>
#include <inttypes.h>
#include "core/Config.h"
#include "core/ConfigCreator.h"
#include "core/ConfigLoader.h"
#include "Cpu.h"
#include "net/Url.h"
#include "rapidjson/document.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h"
#include "workers/CpuThread.h"
#include "xmrig.h"
static char affinity_tmp[20] = { 0 };
xmrig::Config::Config() : xmrig::CommonConfig(),
m_algoVariant(AV_AUTO),
m_doubleHash(false),
m_dryRun(false),
m_hugePages(true),
m_safe(false),
m_maxCpuUsage(75),
m_printTime(60),
m_priority(-1),
m_affinity(-1L),
m_threadsCount(0)
{
}
xmrig::Config::~Config()
{
}
bool xmrig::Config::reload(const char *json)
{
return xmrig::ConfigLoader::reload(this, json);
}
void xmrig::Config::getJSON(rapidjson::Document &doc) const
{
doc.SetObject();
auto &allocator = doc.GetAllocator();
doc.AddMember("algo", rapidjson::StringRef(algoName()), allocator);
rapidjson::Value api(rapidjson::kObjectType);
api.AddMember("port", apiPort(), allocator);
api.AddMember("access-token", apiToken() ? rapidjson::Value(rapidjson::StringRef(apiToken())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
api.AddMember("worker-id", apiWorkerId() ? rapidjson::Value(rapidjson::StringRef(apiWorkerId())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
api.AddMember("ipv6", isApiIPv6(), allocator);
api.AddMember("restricted", isApiRestricted(), allocator);
doc.AddMember("api", api, allocator);
doc.AddMember("av", algoVariant(), allocator);
doc.AddMember("background", isBackground(), allocator);
doc.AddMember("colors", isColors(), allocator);
if (affinity() != -1L) {
snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, affinity());
doc.AddMember("cpu-affinity", rapidjson::StringRef(affinity_tmp), allocator);
}
else {
doc.AddMember("cpu-affinity", rapidjson::kNullType, allocator);
}
if (priority() != -1) {
doc.AddMember("cpu-priority", priority(), allocator);
}
else {
doc.AddMember("cpu-priority", rapidjson::kNullType, allocator);
}
doc.AddMember("donate-level", donateLevel(), allocator);
doc.AddMember("huge-pages", isHugePages(), allocator);
doc.AddMember("log-file", logFile() ? rapidjson::Value(rapidjson::StringRef(logFile())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator);
rapidjson::Value pools(rapidjson::kArrayType);
for (const Url *url : m_pools) {
rapidjson::Value obj(rapidjson::kObjectType);
obj.AddMember("url", rapidjson::StringRef(url->url()), allocator);
obj.AddMember("user", rapidjson::StringRef(url->user()), allocator);
obj.AddMember("pass", rapidjson::StringRef(url->password()), allocator);
if (url->keepAlive() == 0 || url->keepAlive() == Url::kKeepAliveTimeout) {
obj.AddMember("keepalive", url->keepAlive() > 0, allocator);
}
else {
obj.AddMember("keepalive", url->keepAlive(), allocator);
}
obj.AddMember("nicehash", url->isNicehash(), allocator);
obj.AddMember("variant", url->variant(), allocator);
pools.PushBack(obj, allocator);
}
doc.AddMember("pools", pools, allocator);
doc.AddMember("print-time", printTime(), allocator);
doc.AddMember("retries", retries(), allocator);
doc.AddMember("retry-pause", retryPause(), allocator);
doc.AddMember("safe", m_safe, allocator);
doc.AddMember("threads", threadsCount(), allocator);
doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
# ifdef HAVE_SYSLOG_H
doc.AddMember("syslog", isSyslog(), allocator);
# endif
doc.AddMember("watch", m_watch, allocator);
}
xmrig::Config *xmrig::Config::load(int argc, char **argv, IWatcherListener *listener)
{
return static_cast<Config*>(ConfigLoader::load(argc, argv, new ConfigCreator(), listener));
}
bool xmrig::Config::adjust()
{
if (!CommonConfig::adjust()) {
return false;
}
m_algoVariant = getAlgoVariant();
if (m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT) {
m_doubleHash = true;
}
if (!m_threadsCount) {
m_threadsCount = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage);
}
else if (m_safe) {
const size_t count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage);
if (m_threadsCount > count) {
m_threadsCount = count;
}
}
for (size_t i = 0; i < m_threadsCount; ++i) {
m_threads.push_back(CpuThread::createFromAV(i, m_algorithm, m_algoVariant, m_affinity, m_priority));
}
return true;
}
bool xmrig::Config::parseBoolean(int key, bool enable)
{
if (!CommonConfig::parseBoolean(key, enable)) {
return false;
}
switch (key) {
case xmrig::IConfig::SafeKey: /* --safe */
m_safe = enable;
break;
case xmrig::IConfig::HugePagesKey: /* --no-huge-pages */
m_hugePages = enable;
break;
case xmrig::IConfig::DryRunKey: /* --dry-run */
m_dryRun = enable;
break;
default:
break;
}
return true;
}
bool xmrig::Config::parseString(int key, const char *arg)
{
if (!CommonConfig::parseString(key, arg)) {
return false;
}
switch (key) {
case xmrig::IConfig::AVKey: /* --av */
case xmrig::IConfig::MaxCPUUsageKey: /* --max-cpu-usage */
case xmrig::IConfig::CPUPriorityKey: /* --cpu-priority */
return parseUint64(key, strtol(arg, nullptr, 10));
case xmrig::IConfig::SafeKey: /* --safe */
case xmrig::IConfig::DryRunKey: /* --dry-run */
return parseBoolean(key, true);
case xmrig::IConfig::HugePagesKey: /* --no-huge-pages */
return parseBoolean(key, false);
case xmrig::IConfig::ThreadsKey: /* --threads */
if (strncmp(arg, "all", 3) == 0) {
m_threadsCount = Cpu::threads();
return true;
}
return parseUint64(key, strtol(arg, nullptr, 10));
case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */
{
const char *p = strstr(arg, "0x");
return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
}
default:
break;
}
return true;
}
bool xmrig::Config::parseUint64(int key, uint64_t arg)
{
if (!CommonConfig::parseUint64(key, arg)) {
return false;
}
switch (key) {
case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */
if (arg) {
m_affinity = arg;
}
break;
default:
return parseInt(key, static_cast<int>(arg));
}
return true;
}
void xmrig::Config::parseJSON(const rapidjson::Document &doc)
{
}
bool xmrig::Config::parseInt(int key, int arg)
{
switch (key) {
case xmrig::IConfig::ThreadsKey: /* --threads */
if (m_threadsCount >= 0 && arg < 1024) {
m_threadsCount = arg;
}
break;
case xmrig::IConfig::AVKey: /* --av */
if (arg >= AV_AUTO && arg < AV_MAX) {
m_algoVariant = static_cast<AlgoVariant>(arg);
}
break;
case xmrig::IConfig::MaxCPUUsageKey: /* --max-cpu-usage */
if (m_maxCpuUsage > 0 && arg <= 100) {
m_maxCpuUsage = arg;
}
break;
case xmrig::IConfig::CPUPriorityKey: /* --cpu-priority */
if (arg >= 0 && arg <= 5) {
m_priority = arg;
}
break;
default:
break;
}
return true;
}
xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const
{
# ifndef XMRIG_NO_AEON
if (m_algorithm == xmrig::CRYPTONIGHT_LITE) {
return getAlgoVariantLite();
}
# endif
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) {
return Cpu::hasAES() ? AV_SINGLE : AV_SINGLE_SOFT;
}
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) {
return static_cast<AlgoVariant>(m_algoVariant + 2);
}
return m_algoVariant;
}
#ifndef XMRIG_NO_AEON
xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const
{
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) {
return Cpu::hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT;
}
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) {
return static_cast<AlgoVariant>(m_algoVariant + 2);
}
return m_algoVariant;
}
#endif

113
src/core/Config.h Normal file
View File

@@ -0,0 +1,113 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include <stdint.h>
#include <vector>
#include "core/CommonConfig.h"
#include "rapidjson/fwd.h"
#include "xmrig.h"
class Addr;
class Url;
namespace xmrig {
class ConfigLoader;
class IThread;
class IWatcherListener;
/**
* @brief The Config class
*
* Options with dynamic reload:
* colors
* debug
* verbose
* custom-diff (only for new connections)
* api/worker-id
* pools/
*/
class Config : public CommonConfig
{
public:
Config();
~Config();
bool reload(const char *json);
void getJSON(rapidjson::Document &doc) const override;
inline AlgoVariant algoVariant() const { return m_algoVariant; }
inline bool isDoubleHash() const { return m_doubleHash; }
inline bool isDryRun() const { return m_dryRun; }
inline bool isHugePages() const { return m_hugePages; }
inline const std::vector<IThread *> &threads() const { return m_threads; }
inline int printTime() const { return m_printTime; }
inline int priority() const { return m_priority; }
inline int threadsCount() const { return m_threadsCount; }
inline int64_t affinity() const { return m_affinity; }
static Config *load(int argc, char **argv, IWatcherListener *listener);
protected:
bool adjust() override;
bool parseBoolean(int key, bool enable) override;
bool parseString(int key, const char *arg) override;
bool parseUint64(int key, uint64_t arg) override;
void parseJSON(const rapidjson::Document &doc) override;
private:
bool parseInt(int key, int arg);
AlgoVariant getAlgoVariant() const;
# ifndef XMRIG_NO_AEON
AlgoVariant getAlgoVariantLite() const;
# endif
AlgoVariant m_algoVariant;
bool m_doubleHash;
bool m_dryRun;
bool m_hugePages;
bool m_safe;
int m_maxCpuUsage;
int m_printTime;
int m_priority;
int64_t m_affinity;
size_t m_threadsCount;
std::vector<IThread *> m_threads;
};
} /* namespace xmrig */
#endif /* __CONFIG_H__ */

50
src/core/ConfigCreator.h Normal file
View File

@@ -0,0 +1,50 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2018 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONFIGCREATOR_H__
#define __CONFIGCREATOR_H__
#include "core/Config.h"
#include "interfaces/IConfigCreator.h"
namespace xmrig {
class IConfig;
class ConfigCreator : public IConfigCreator
{
public:
inline IConfig *create() const override
{
return new Config();
}
};
} /* namespace xmrig */
#endif // __CONFIGCREATOR_H__

311
src/core/ConfigLoader.cpp Normal file
View File

@@ -0,0 +1,311 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <limits.h>
#include <stdio.h>
#include <uv.h>
#ifndef XMRIG_NO_HTTPD
# include <microhttpd.h>
#endif
#include "core/ConfigCreator.h"
#include "core/ConfigLoader.h"
#include "core/ConfigLoader_platform.h"
#include "core/ConfigWatcher.h"
#include "interfaces/IConfig.h"
#include "interfaces/IWatcherListener.h"
#include "net/Url.h"
#include "Platform.h"
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/filereadstream.h"
xmrig::ConfigWatcher *xmrig::ConfigLoader::m_watcher = nullptr;
xmrig::IConfigCreator *xmrig::ConfigLoader::m_creator = nullptr;
xmrig::IWatcherListener *xmrig::ConfigLoader::m_listener = nullptr;
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
bool xmrig::ConfigLoader::loadFromFile(xmrig::IConfig *config, const char *fileName)
{
rapidjson::Document doc;
if (!getJSON(fileName, doc)) {
return false;
}
config->setFileName(fileName);
return loadFromJSON(config, doc);
}
bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const char *json)
{
rapidjson::Document doc;
doc.Parse(json);
if (doc.HasParseError() || !doc.IsObject()) {
return false;
}
return loadFromJSON(config, doc);
}
bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson::Document &doc)
{
for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) {
parseJSON(config, &config_options[i], doc);
}
const rapidjson::Value &pools = doc["pools"];
if (pools.IsArray()) {
for (const rapidjson::Value &value : pools.GetArray()) {
if (!value.IsObject()) {
continue;
}
for (size_t i = 0; i < ARRAY_SIZE(pool_options); i++) {
parseJSON(config, &pool_options[i], value);
}
}
}
const rapidjson::Value &api = doc["api"];
if (api.IsObject()) {
for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) {
parseJSON(config, &api_options[i], api);
}
}
config->parseJSON(doc);
config->adjust();
return config->isValid();
}
bool xmrig::ConfigLoader::reload(xmrig::IConfig *oldConfig, const char *json)
{
xmrig::IConfig *config = m_creator->create();
if (!loadFromJSON(config, json)) {
delete config;
return false;
}
config->setFileName(oldConfig->fileName());
const bool saved = config->save();
if (config->isWatch() && m_watcher && saved) {
delete config;
return true;
}
m_listener->onNewConfig(config);
return true;
}
xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator *creator, IWatcherListener *listener)
{
m_creator = creator;
m_listener = listener;
xmrig::IConfig *config = m_creator->create();
int key;
while (1) {
key = getopt_long(argc, argv, short_options, options, NULL);
if (key < 0) {
break;
}
if (!parseArg(config, key, optarg)) {
delete config;
return nullptr;
}
}
if (optind < argc) {
fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]);
delete config;
return nullptr;
}
if (!config->isValid()) {
loadFromFile(config, Platform::defaultConfigName());
}
if (!config->isValid()) {
fprintf(stderr, "No pool URL supplied. Exiting.\n");
delete config;
return nullptr;
}
if (config->isWatch()) {
m_watcher = new xmrig::ConfigWatcher(config->fileName(), creator, listener);
}
config->adjust();
return config;
}
void xmrig::ConfigLoader::release()
{
delete m_watcher;
delete m_creator;
m_watcher = nullptr;
m_creator = nullptr;
}
bool xmrig::ConfigLoader::getJSON(const char *fileName, rapidjson::Document &doc)
{
uv_fs_t req;
const int fd = uv_fs_open(uv_default_loop(), &req, fileName, O_RDONLY, 0644, nullptr);
if (fd < 0) {
fprintf(stderr, "unable to open %s: %s\n", fileName, uv_strerror(fd));
return false;
}
uv_fs_req_cleanup(&req);
FILE *fp = fdopen(fd, "rb");
char buf[8192];
rapidjson::FileReadStream is(fp, buf, sizeof(buf));
doc.ParseStream(is);
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req);
if (doc.HasParseError()) {
printf("%s<%d>: %s\n", fileName, (int) doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError()));
return false;
}
return doc.IsObject();
}
bool xmrig::ConfigLoader::parseArg(xmrig::IConfig *config, int key, const char *arg)
{
switch (key) {
case xmrig::IConfig::VersionKey: /* --version */
showVersion();
return false;
case xmrig::IConfig::HelpKey: /* --help */
showUsage();
return false;
case xmrig::IConfig::ConfigKey: /* --config */
loadFromFile(config, arg);
break;
default:
return config->parseString(key, arg);;
}
return true;
}
void xmrig::ConfigLoader::parseJSON(xmrig::IConfig *config, const struct option *option, const rapidjson::Value &object)
{
if (!option->name || !object.HasMember(option->name)) {
return;
}
const rapidjson::Value &value = object[option->name];
if (option->has_arg) {
if (value.IsString()) {
config->parseString(option->val, value.GetString());
}
else if (value.IsInt64()) {
config->parseUint64(option->val, value.GetUint64());
}
else if (value.IsBool()) {
config->parseBoolean(option->val, value.IsTrue());
}
}
else if (value.IsBool()) {
config->parseBoolean(option->val, value.IsTrue());
}
}
void xmrig::ConfigLoader::showUsage()
{
printf(usage);
}
void xmrig::ConfigLoader::showVersion()
{
printf(APP_NAME " " APP_VERSION "\n built on " __DATE__
# if defined(__clang__)
" with clang " __clang_version__);
# elif defined(__GNUC__)
" with GCC");
printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif defined(_MSC_VER)
" with MSVC");
printf(" %d", MSVC_VERSION);
# else
);
# endif
printf("\n features:"
# if defined(__i386__) || defined(_M_IX86)
" i386"
# elif defined(__x86_64__) || defined(_M_AMD64)
" x86_64"
# endif
# if defined(__AES__) || defined(_MSC_VER)
" AES-NI"
# endif
"\n");
printf("\nlibuv/%s\n", uv_version_string());
# ifndef XMRIG_NO_HTTPD
printf("libmicrohttpd/%s\n", MHD_get_version());
# endif
}

71
src/core/ConfigLoader.h Normal file
View File

@@ -0,0 +1,71 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONFIGLOADER_H__
#define __CONFIGLOADER_H__
#include <stdint.h>
#include "rapidjson/fwd.h"
struct option;
namespace xmrig {
class ConfigWatcher;
class IConfigCreator;
class IWatcherListener;
class IConfig;
class ConfigLoader
{
public:
static bool loadFromFile(IConfig *config, const char *fileName);
static bool loadFromJSON(IConfig *config, const char *json);
static bool loadFromJSON(IConfig *config, const rapidjson::Document &doc);
static bool reload(IConfig *oldConfig, const char *json);
static IConfig *load(int argc, char **argv, IConfigCreator *creator, IWatcherListener *listener);
static void release();
private:
static bool getJSON(const char *fileName, rapidjson::Document &doc);
static bool parseArg(IConfig *config, int key, const char *arg);
static void parseJSON(IConfig *config, const struct option *option, const rapidjson::Value &object);
static void showUsage();
static void showVersion();
static ConfigWatcher *m_watcher;
static IConfigCreator *m_creator;
static IWatcherListener *m_listener;
};
} /* namespace xmrig */
#endif /* __CONFIGLOADER_H__ */

View File

@@ -0,0 +1,171 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONFIGLOADER_PLATFORM_H__
#define __CONFIGLOADER_PLATFORM_H__
#ifdef _MSC_VER
# include "getopt/getopt.h"
#else
# include <getopt.h>
#endif
#include "version.h"
#include "interfaces/IConfig.h"
namespace xmrig {
static char const usage[] = "\
Usage: " APP_ID " [OPTIONS]\n\
Options:\n\
-a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\
-o, --url=URL URL of mining server\n\
-O, --userpass=U:P username:password pair for mining server\n\
-u, --user=USERNAME username for mining server\n\
-p, --pass=PASSWORD password for mining server\n\
-t, --threads=N number of miner threads\n\
-v, --av=N algorithm variation, 0 auto select\n\
-k, --keepalive send keepalived for prevent timeout (need pool support)\n\
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
-R, --retry-pause=N time to pause between retries (default: 5)\n\
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\
--no-huge-pages disable huge pages support\n\
--no-color disable colored output\n\
--variant algorithm PoW variant\n\
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\
--user-agent set custom user-agent string for pool\n\
-B, --background run the miner in the background\n\
-c, --config=FILE load a JSON-format configuration file\n\
-l, --log-file=FILE log all output to a file\n"
# ifdef HAVE_SYSLOG_H
"\
-S, --syslog use system log for output messages\n"
# endif
"\
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\
--safe safe adjust threads and av settings for current CPU\n\
--nicehash enable nicehash/xmrig-proxy support\n\
--print-time=N print hashrate report every N seconds\n\
--api-port=N port for the miner API\n\
--api-access-token=T access token for API\n\
--api-worker-id=ID custom worker-id for API\n\
-h, --help display this help and exit\n\
-V, --version output version information and exit\n\
";
static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vl:S";
static struct option const options[] = {
{ "algo", 1, nullptr, xmrig::IConfig::AlgorithmKey },
{ "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey },
{ "api-port", 1, nullptr, xmrig::IConfig::ApiPort },
{ "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
{ "api-no-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
{ "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
{ "av", 1, nullptr, xmrig::IConfig::AVKey },
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey },
{ "config", 1, nullptr, xmrig::IConfig::ConfigKey },
{ "cpu-affinity", 1, nullptr, xmrig::IConfig::CPUAffinityKey },
{ "cpu-priority", 1, nullptr, xmrig::IConfig::CPUPriorityKey },
{ "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey },
{ "dry-run", 0, nullptr, xmrig::IConfig::DryRunKey },
{ "help", 0, nullptr, xmrig::IConfig::HelpKey },
{ "keepalive", 0, nullptr, xmrig::IConfig::KeepAliveKey },
{ "log-file", 1, nullptr, xmrig::IConfig::LogFileKey },
{ "max-cpu-usage", 1, nullptr, xmrig::IConfig::MaxCPUUsageKey },
{ "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey },
{ "no-color", 0, nullptr, xmrig::IConfig::ColorKey },
{ "no-huge-pages", 0, nullptr, xmrig::IConfig::HugePagesKey },
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey },
{ "pass", 1, nullptr, xmrig::IConfig::PasswordKey },
{ "print-time", 1, nullptr, xmrig::IConfig::PrintTimeKey },
{ "retries", 1, nullptr, xmrig::IConfig::RetriesKey },
{ "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey },
{ "safe", 0, nullptr, xmrig::IConfig::SafeKey },
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey },
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey },
{ "url", 1, nullptr, xmrig::IConfig::UrlKey },
{ "user", 1, nullptr, xmrig::IConfig::UserKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
{ "version", 0, nullptr, xmrig::IConfig::VersionKey },
{ 0, 0, 0, 0 }
};
static struct option const config_options[] = {
{ "algo", 1, nullptr, xmrig::IConfig::AlgorithmKey },
{ "av", 1, nullptr, xmrig::IConfig::AVKey },
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey },
{ "colors", 0, nullptr, xmrig::IConfig::ColorKey },
{ "cpu-affinity", 1, nullptr, xmrig::IConfig::CPUAffinityKey },
{ "cpu-priority", 1, nullptr, xmrig::IConfig::CPUPriorityKey },
{ "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey },
{ "dry-run", 0, nullptr, xmrig::IConfig::DryRunKey },
{ "huge-pages", 0, nullptr, xmrig::IConfig::HugePagesKey },
{ "log-file", 1, nullptr, xmrig::IConfig::LogFileKey },
{ "max-cpu-usage", 1, nullptr, xmrig::IConfig::MaxCPUUsageKey },
{ "print-time", 1, nullptr, xmrig::IConfig::PrintTimeKey },
{ "retries", 1, nullptr, xmrig::IConfig::RetriesKey },
{ "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey },
{ "safe", 0, nullptr, xmrig::IConfig::SafeKey },
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey },
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ 0, 0, 0, 0 }
};
static struct option const pool_options[] = {
{ "url", 1, nullptr, xmrig::IConfig::UrlKey },
{ "pass", 1, nullptr, xmrig::IConfig::PasswordKey },
{ "user", 1, nullptr, xmrig::IConfig::UserKey },
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
{ "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey },
{ "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey },
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey },
{ 0, 0, 0, 0 }
};
static struct option const api_options[] = {
{ "port", 1, nullptr, xmrig::IConfig::ApiPort },
{ "access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey },
{ "worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
{ "ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
{ "restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
{ 0, 0, 0, 0 }
};
} /* namespace xmrig */
#endif /* __CONFIGLOADER_PLATFORM_H__ */

107
src/core/ConfigWatcher.cpp Normal file
View File

@@ -0,0 +1,107 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "core/ConfigCreator.h"
#include "core/ConfigLoader.h"
#include "core/ConfigWatcher.h"
#include "interfaces/IWatcherListener.h"
#include "log/Log.h"
xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) :
m_path(strdup(path)),
m_creator(creator),
m_listener(listener)
{
uv_fs_event_init(uv_default_loop(), &m_fsEvent);
uv_timer_init(uv_default_loop(), &m_timer);
m_fsEvent.data = m_timer.data = this;
start();
}
xmrig::ConfigWatcher::~ConfigWatcher()
{
uv_timer_stop(&m_timer);
uv_fs_event_stop(&m_fsEvent);
free(m_path);
}
void xmrig::ConfigWatcher::onTimer(uv_timer_t* handle)
{
static_cast<xmrig::ConfigWatcher *>(handle->data)->reload();
}
void xmrig::ConfigWatcher::onFsEvent(uv_fs_event_t* handle, const char *filename, int events, int status)
{
if (!filename) {
return;
}
static_cast<xmrig::ConfigWatcher *>(handle->data)->queueUpdate();
}
void xmrig::ConfigWatcher::queueUpdate()
{
uv_timer_stop(&m_timer);
uv_timer_start(&m_timer, xmrig::ConfigWatcher::onTimer, kDelay, 0);
}
void xmrig::ConfigWatcher::reload()
{
LOG_WARN("\"%s\" was changed, reloading configuration", m_path);
IConfig *config = m_creator->create();
ConfigLoader::loadFromFile(config, m_path);
if (!config->isValid()) {
LOG_ERR("reloading failed");
delete config;
return;
}
m_listener->onNewConfig(config);
# ifndef _WIN32
uv_fs_event_stop(&m_fsEvent);
start();
# endif
}
void xmrig::ConfigWatcher::start()
{
uv_fs_event_start(&m_fsEvent, xmrig::ConfigWatcher::onFsEvent, m_path, 0);
}

69
src/core/ConfigWatcher.h Normal file
View File

@@ -0,0 +1,69 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONFIGWATCHER_H__
#define __CONFIGWATCHER_H__
#include <stdint.h>
#include <uv.h>
#include "rapidjson/fwd.h"
struct option;
namespace xmrig {
class IConfigCreator;
class IWatcherListener;
class ConfigWatcher
{
public:
ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener);
~ConfigWatcher();
private:
constexpr static int kDelay = 500;
static void onFsEvent(uv_fs_event_t* handle, const char *filename, int events, int status);
static void onTimer(uv_timer_t* handle);
void queueUpdate();
void reload();
void start();
char *m_path;
IConfigCreator *m_creator;
IWatcherListener *m_listener;
uv_fs_event_t m_fsEvent;
uv_timer_t m_timer;
};
} /* namespace xmrig */
#endif /* __CONFIGWATCHER_H__ */

152
src/core/Controller.cpp Normal file
View File

@@ -0,0 +1,152 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include "core/Config.h"
#include "core/ConfigLoader.h"
#include "core/Controller.h"
#include "Cpu.h"
#include "interfaces/IControllerListener.h"
#include "log/ConsoleLog.h"
#include "log/FileLog.h"
#include "log/Log.h"
#include "net/Network.h"
#include "Platform.h"
#ifdef HAVE_SYSLOG_H
# include "log/SysLog.h"
#endif
class xmrig::ControllerPrivate
{
public:
inline ControllerPrivate() :
network(nullptr),
config(nullptr)
{}
inline ~ControllerPrivate()
{
delete network;
delete config;
}
Network *network;
std::vector<xmrig::IControllerListener *> listeners;
xmrig::Config *config;
};
xmrig::Controller::Controller()
: d_ptr(new ControllerPrivate())
{
}
xmrig::Controller::~Controller()
{
ConfigLoader::release();
Platform::release();
delete d_ptr;
}
bool xmrig::Controller::isReady() const
{
return d_ptr->config && d_ptr->network;
}
xmrig::Config *xmrig::Controller::config() const
{
assert(d_ptr->config != nullptr);
return d_ptr->config;
}
int xmrig::Controller::init(int argc, char **argv)
{
Cpu::init();
d_ptr->config = xmrig::Config::load(argc, argv, this);
if (!d_ptr->config) {
return 1;
}
Log::init();
Platform::init(config()->userAgent());
Platform::setProcessPriority(d_ptr->config->priority());
if (!config()->isBackground()) {
Log::add(new ConsoleLog(this));
}
if (config()->logFile()) {
Log::add(new FileLog(config()->logFile()));
}
# ifdef HAVE_SYSLOG_H
if (config()->isSyslog()) {
Log::add(new SysLog());
}
# endif
d_ptr->network = new Network(this);
return 0;
}
Network *xmrig::Controller::network() const
{
assert(d_ptr->network != nullptr);
return d_ptr->network;
}
void xmrig::Controller::addListener(IControllerListener *listener)
{
d_ptr->listeners.push_back(listener);
}
void xmrig::Controller::onNewConfig(IConfig *config)
{
Config *previousConfig = d_ptr->config;
d_ptr->config = static_cast<Config*>(config);
for (xmrig::IControllerListener *listener : d_ptr->listeners) {
listener->onConfigChanged(d_ptr->config, previousConfig);
}
delete previousConfig;
}

64
src/core/Controller.h Normal file
View File

@@ -0,0 +1,64 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONTROLLER_H__
#define __CONTROLLER_H__
#include "interfaces/IWatcherListener.h"
class Network;
class StatsData;
namespace xmrig {
class Config;
class ControllerPrivate;
class IControllerListener;
class Controller : public IWatcherListener
{
public:
Controller();
~Controller();
bool isReady() const;
Config *config() const;
int init(int argc, char **argv);
Network *network() const;
void addListener(IControllerListener *listener);
protected:
void onNewConfig(IConfig *config) override;
private:
ControllerPrivate *d_ptr;
};
} /* namespace xmrig */
#endif /* __CONTROLLER_H__ */

View File

@@ -1,148 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_p.h"
#include "crypto/CryptoNight_test.h"
#include "net/Job.h"
#include "net/JobResult.h"
#include "Options.h"
void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = nullptr;
static void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) {
cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx);
}
static void cryptonight_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx);
}
static void cryptonight_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, true>(input, size, output, ctx);
}
static void cryptonight_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, true>(input, size, output, ctx);
}
#ifndef XMRIG_NO_AEON
static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx);
}
static void cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx);
}
static void cryptonight_lite_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, true>(input, size, output, ctx);
}
static void cryptonight_lite_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, true>(input, size, output, ctx);
}
void (*cryptonight_variations[8])(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = {
cryptonight_av1_aesni,
cryptonight_av2_aesni_double,
cryptonight_av3_softaes,
cryptonight_av4_softaes_double,
cryptonight_lite_av1_aesni,
cryptonight_lite_av2_aesni_double,
cryptonight_lite_av3_softaes,
cryptonight_lite_av4_softaes_double
};
#else
void (*cryptonight_variations[4])(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = {
cryptonight_av1_aesni,
cryptonight_av2_aesni_double,
cryptonight_av3_softaes,
cryptonight_av4_softaes_double
};
#endif
bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx)
{
cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx);
return *reinterpret_cast<uint64_t*>(result.result + 24) < job.target();
}
bool CryptoNight::init(int algo, int variant)
{
if (variant < 1 || variant > 4) {
return false;
}
# ifndef XMRIG_NO_AEON
const int index = algo == Options::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1);
# else
const int index = variant - 1;
# endif
cryptonight_hash_ctx = cryptonight_variations[index];
return selfTest(algo);
}
void CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx)
{
cryptonight_hash_ctx(input, size, output, ctx);
}
bool CryptoNight::selfTest(int algo) {
if (cryptonight_hash_ctx == nullptr) {
return false;
}
char output[64];
struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16);
ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 2, 16);
cryptonight_hash_ctx(test_input, 76, output, ctx);
_mm_free(ctx->memory);
_mm_free(ctx);
# ifndef XMRIG_NO_AEON
return memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0;
# else
return memcmp(output, test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0;
# endif
}

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,33 +30,20 @@
#include <stdint.h>
#include "align.h"
#define AEON_MEMORY 1048576
#define AEON_MASK 0xFFFF0
#define AEON_ITER 0x40000
#define MEMORY 2097152 /* 2 MiB */
#define MEMORY_LITE 1048576 /* 1 MiB */
#define MONERO_MEMORY 2097152
#define MONERO_MASK 0x1FFFF0
#define MONERO_ITER 0x80000
struct cryptonight_ctx {
VAR_ALIGN(16, uint8_t state0[200]);
VAR_ALIGN(16, uint8_t state1[200]);
VAR_ALIGN(16, uint8_t* memory);
alignas(16) uint8_t state0[200];
alignas(16) uint8_t state1[200];
alignas(16) uint8_t* memory;
};
class Job;
class JobResult;
class CryptoNight
{
public:
static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx);
static bool init(int algo, int variant);
static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx);
private:
static bool selfTest(int algo);
};
#endif /* __CRYPTONIGHT_H__ */

View File

@@ -0,0 +1,686 @@
/* 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 Imran Yusuff <https://github.com/imranyusuff>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CRYPTONIGHT_ARM_H__
#define __CRYPTONIGHT_ARM_H__
#if defined(XMRIG_ARM) && !defined(__clang__)
# include "aligned_malloc.h"
#else
# include <mm_malloc.h>
#endif
#include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_constants.h"
#include "crypto/CryptoNight_monero.h"
#include "crypto/soft_aes.h"
extern "C"
{
#include "crypto/c_keccak.h"
#include "crypto/c_groestl.h"
#include "crypto/c_blake256.h"
#include "crypto/c_jh.h"
#include "crypto/c_skein.h"
}
static inline void do_blake_hash(const uint8_t *input, size_t len, uint8_t *output) {
blake256_hash(output, input, len);
}
static inline void do_groestl_hash(const uint8_t *input, size_t len, uint8_t *output) {
groestl(input, len * 8, output);
}
static inline void do_jh_hash(const uint8_t *input, size_t len, uint8_t *output) {
jh_hash(32 * 8, input, 8 * len, output);
}
static inline void do_skein_hash(const uint8_t *input, size_t len, uint8_t *output) {
xmr_skein(input, output);
}
void (* const extra_hashes[4])(const uint8_t *, size_t, uint8_t *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash};
static inline __attribute__((always_inline)) __m128i _mm_set_epi64x(const uint64_t a, const uint64_t b)
{
return vcombine_u64(vcreate_u64(b), vcreate_u64(a));
}
/* this one was not implemented yet so here it is */
static inline __attribute__((always_inline)) uint64_t _mm_cvtsi128_si64(__m128i a)
{
return vgetq_lane_u64(a, 0);
}
#define EXTRACT64(X) _mm_cvtsi128_si64(X)
#if defined(XMRIG_ARMv8)
static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi)
{
unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b;
*hi = r >> 64;
return (uint64_t) r;
}
#else
static inline uint64_t __umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) {
// multiplier = ab = a * 2^32 + b
// multiplicand = cd = c * 2^32 + d
// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
uint64_t a = multiplier >> 32;
uint64_t b = multiplier & 0xFFFFFFFF;
uint64_t c = multiplicand >> 32;
uint64_t d = multiplicand & 0xFFFFFFFF;
//uint64_t ac = a * c;
uint64_t ad = a * d;
//uint64_t bc = b * c;
uint64_t bd = b * d;
uint64_t adbc = ad + (b * c);
uint64_t adbc_carry = adbc < ad ? 1 : 0;
// multiplier * multiplicand = product_hi * 2^64 + product_lo
uint64_t product_lo = bd + (adbc << 32);
uint64_t product_lo_carry = product_lo < bd ? 1 : 0;
*product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
return product_lo;
}
#endif
// This will shift and xor tmp1 into itself as 4 32-bit vals such as
// sl_xor(a1 a2 a3 a4) = a1 (a2^a1) (a3^a2^a1) (a4^a3^a2^a1)
static inline __m128i sl_xor(__m128i tmp1)
{
__m128i tmp4;
tmp4 = _mm_slli_si128(tmp1, 0x04);
tmp1 = _mm_xor_si128(tmp1, tmp4);
tmp4 = _mm_slli_si128(tmp4, 0x04);
tmp1 = _mm_xor_si128(tmp1, tmp4);
tmp4 = _mm_slli_si128(tmp4, 0x04);
tmp1 = _mm_xor_si128(tmp1, tmp4);
return tmp1;
}
template<uint8_t rcon>
static inline void soft_aes_genkey_sub(__m128i* xout0, __m128i* xout2)
{
__m128i xout1 = soft_aeskeygenassist<rcon>(*xout2);
xout1 = _mm_shuffle_epi32(xout1, 0xFF); // see PSHUFD, set all elems to 4th elem
*xout0 = sl_xor(*xout0);
*xout0 = _mm_xor_si128(*xout0, xout1);
xout1 = soft_aeskeygenassist<0x00>(*xout0);
xout1 = _mm_shuffle_epi32(xout1, 0xAA); // see PSHUFD, set all elems to 3rd elem
*xout2 = sl_xor(*xout2);
*xout2 = _mm_xor_si128(*xout2, xout1);
}
template<bool SOFT_AES>
static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3, __m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9)
{
__m128i xout0 = _mm_load_si128(memory);
__m128i xout2 = _mm_load_si128(memory + 1);
*k0 = xout0;
*k1 = xout2;
SOFT_AES ? soft_aes_genkey_sub<0x01>(&xout0, &xout2) : soft_aes_genkey_sub<0x01>(&xout0, &xout2);
*k2 = xout0;
*k3 = xout2;
SOFT_AES ? soft_aes_genkey_sub<0x02>(&xout0, &xout2) : soft_aes_genkey_sub<0x02>(&xout0, &xout2);
*k4 = xout0;
*k5 = xout2;
SOFT_AES ? soft_aes_genkey_sub<0x04>(&xout0, &xout2) : soft_aes_genkey_sub<0x04>(&xout0, &xout2);
*k6 = xout0;
*k7 = xout2;
SOFT_AES ? soft_aes_genkey_sub<0x08>(&xout0, &xout2) : soft_aes_genkey_sub<0x08>(&xout0, &xout2);
*k8 = xout0;
*k9 = xout2;
}
template<bool SOFT_AES>
static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7)
{
if (SOFT_AES) {
*x0 = soft_aesenc((uint32_t*)x0, key);
*x1 = soft_aesenc((uint32_t*)x1, key);
*x2 = soft_aesenc((uint32_t*)x2, key);
*x3 = soft_aesenc((uint32_t*)x3, key);
*x4 = soft_aesenc((uint32_t*)x4, key);
*x5 = soft_aesenc((uint32_t*)x5, key);
*x6 = soft_aesenc((uint32_t*)x6, key);
*x7 = soft_aesenc((uint32_t*)x7, key);
}
# ifndef XMRIG_ARMv7
else {
*x0 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x0), key));
*x1 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x1), key));
*x2 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x2), key));
*x3 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x3), key));
*x4 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x4), key));
*x5 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x5), key));
*x6 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x6), key));
*x7 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x7), key));
}
# endif
}
inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3, __m128i& x4, __m128i& x5, __m128i& x6, __m128i& x7)
{
__m128i tmp0 = x0;
x0 = _mm_xor_si128(x0, x1);
x1 = _mm_xor_si128(x1, x2);
x2 = _mm_xor_si128(x2, x3);
x3 = _mm_xor_si128(x3, x4);
x4 = _mm_xor_si128(x4, x5);
x5 = _mm_xor_si128(x5, x6);
x6 = _mm_xor_si128(x6, x7);
x7 = _mm_xor_si128(x7, tmp0);
}
template<xmrig::Algo ALGO, size_t MEM, bool SOFT_AES>
static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
{
__m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7;
__m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;
aes_genkey<SOFT_AES>(input, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);
xin0 = _mm_load_si128(input + 4);
xin1 = _mm_load_si128(input + 5);
xin2 = _mm_load_si128(input + 6);
xin3 = _mm_load_si128(input + 7);
xin4 = _mm_load_si128(input + 8);
xin5 = _mm_load_si128(input + 9);
xin6 = _mm_load_si128(input + 10);
xin7 = _mm_load_si128(input + 11);
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
for (size_t i = 0; i < 16; i++) {
if (!SOFT_AES) {
aes_round<SOFT_AES>(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
}
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
if (!SOFT_AES) {
xin0 ^= k9;
xin1 ^= k9;
xin2 ^= k9;
xin3 ^= k9;
xin4 ^= k9;
xin5 ^= k9;
xin6 ^= k9;
xin7 ^= k9;
}
else {
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
}
mix_and_propagate(xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
}
}
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
if (!SOFT_AES) {
aes_round<SOFT_AES>(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
}
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
if (!SOFT_AES) {
xin0 ^= k9;
xin1 ^= k9;
xin2 ^= k9;
xin3 ^= k9;
xin4 ^= k9;
xin5 ^= k9;
xin6 ^= k9;
xin7 ^= k9;
}
else {
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
}
_mm_store_si128(output + i + 0, xin0);
_mm_store_si128(output + i + 1, xin1);
_mm_store_si128(output + i + 2, xin2);
_mm_store_si128(output + i + 3, xin3);
_mm_store_si128(output + i + 4, xin4);
_mm_store_si128(output + i + 5, xin5);
_mm_store_si128(output + i + 6, xin6);
_mm_store_si128(output + i + 7, xin7);
}
}
template<xmrig::Algo ALGO, size_t MEM, bool SOFT_AES>
static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
{
__m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7;
__m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;
aes_genkey<SOFT_AES>(output + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);
xout0 = _mm_load_si128(output + 4);
xout1 = _mm_load_si128(output + 5);
xout2 = _mm_load_si128(output + 6);
xout3 = _mm_load_si128(output + 7);
xout4 = _mm_load_si128(output + 8);
xout5 = _mm_load_si128(output + 9);
xout6 = _mm_load_si128(output + 10);
xout7 = _mm_load_si128(output + 11);
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8)
{
xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0);
xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1);
xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2);
xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3);
xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4);
xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5);
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
if (!SOFT_AES) {
aes_round<SOFT_AES>(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
}
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
if (!SOFT_AES) {
xout0 ^= k9;
xout1 ^= k9;
xout2 ^= k9;
xout3 ^= k9;
xout4 ^= k9;
xout5 ^= k9;
xout6 ^= k9;
xout7 ^= k9;
}
else {
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
}
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
}
}
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0);
xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1);
xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2);
xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3);
xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4);
xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5);
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
if (!SOFT_AES) {
aes_round<SOFT_AES>(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
}
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
if (!SOFT_AES) {
xout0 ^= k9;
xout1 ^= k9;
xout2 ^= k9;
xout3 ^= k9;
xout4 ^= k9;
xout5 ^= k9;
xout6 ^= k9;
xout7 ^= k9;
}
else {
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
}
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
}
for (size_t i = 0; i < 16; i++) {
if (!SOFT_AES) {
aes_round<SOFT_AES>(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
}
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
if (!SOFT_AES) {
xout0 ^= k9;
xout1 ^= k9;
xout2 ^= k9;
xout3 ^= k9;
xout4 ^= k9;
xout5 ^= k9;
xout6 ^= k9;
xout7 ^= k9;
}
else {
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
}
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
}
}
_mm_store_si128(output + 4, xout0);
_mm_store_si128(output + 5, xout1);
_mm_store_si128(output + 6, xout2);
_mm_store_si128(output + 7, xout3);
_mm_store_si128(output + 8, xout4);
_mm_store_si128(output + 9, xout5);
_mm_store_si128(output + 10, xout6);
_mm_store_si128(output + 11, xout7);
}
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx)
{
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
if (VARIANT > 0 && size < 43) {
memset(output, 0, 32);
return;
}
keccak(input, (int) size, ctx->state0, 200);
VARIANT1_INIT(0);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx->state0, (__m128i*) ctx->memory);
const uint8_t* l0 = ctx->memory;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
uint64_t al0 = h0[0] ^ h0[4];
uint64_t ah0 = h0[1] ^ h0[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
uint64_t idx0 = h0[0] ^ h0[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx;
if (SOFT_AES) {
cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
}
else {
cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
# ifndef XMRIG_ARMv7
cx = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
# endif
}
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
VARIANT1_1(&l0[idx0 & MASK]);
idx0 = EXTRACT64(cx);
bx0 = cx;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi);
al0 += hi;
ah0 += lo;
VARIANT1_2(ah0, 0);
((uint64_t*)&l0[idx0 & MASK])[0] = al0;
((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
VARIANT1_2(ah0, 0);
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0];
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2];
int64_t q = n / (d | 0x5);
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
idx0 = d ^ q;
}
}
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx->memory, (__m128i*) ctx->state0);
keccakf(h0, 24);
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
}
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
{
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
if (VARIANT > 0 && size < 43) {
memset(output, 0, 64);
return;
}
keccak(input, (int) size, ctx->state0, 200);
keccak(input + size, (int) size, ctx->state1, 200);
VARIANT1_INIT(0);
VARIANT1_INIT(1);
const uint8_t* l0 = ctx->memory;
const uint8_t* l1 = ctx->memory + MEM;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state1);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
uint64_t al0 = h0[0] ^ h0[4];
uint64_t al1 = h1[0] ^ h1[4];
uint64_t ah0 = h0[1] ^ h0[5];
uint64_t ah1 = h1[1] ^ h1[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
uint64_t idx0 = h0[0] ^ h0[4];
uint64_t idx1 = h1[0] ^ h1[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0, cx1;
if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
}
else {
cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]);
# ifndef XMRIG_ARMv7
cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1);
# endif
}
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
VARIANT1_1(&l0[idx0 & MASK]);
VARIANT1_1(&l1[idx1 & MASK]);
idx0 = EXTRACT64(cx0);
idx1 = EXTRACT64(cx1);
bx0 = cx0;
bx1 = cx1;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi);
al0 += hi;
ah0 += lo;
VARIANT1_2(ah0, 0);
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
VARIANT1_2(ah0, 0);
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0];
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2];
int64_t q = n / (d | 0x5);
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
idx0 = d ^ q;
}
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi);
al1 += hi;
ah1 += lo;
VARIANT1_2(ah1, 1);
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
VARIANT1_2(ah1, 1);
ah1 ^= ch;
al1 ^= cl;
idx1 = al1;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
int64_t n = ((int64_t*)&l1[idx1 & MASK])[0];
int32_t d = ((int32_t*)&l1[idx1 & MASK])[2];
int64_t q = n / (d | 0x5);
((int64_t*)&l1[idx1 & MASK])[0] = n ^ q;
idx1 = d ^ q;
}
}
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
keccakf(h0, 24);
keccakf(h1, 24);
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32);
}
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
{
}
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
{
}
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
{
}
#endif /* __CRYPTONIGHT_ARM_H__ */

View File

@@ -0,0 +1,117 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CRYPTONIGHT_CONSTANTS_H__
#define __CRYPTONIGHT_CONSTANTS_H__
#include <stdint.h>
#include "xmrig.h"
namespace xmrig
{
constexpr const size_t CRYPTONIGHT_MEMORY = 2 * 1024 * 1024;
constexpr const uint32_t CRYPTONIGHT_MASK = 0x1FFFF0;
constexpr const uint32_t CRYPTONIGHT_ITER = 0x80000;
constexpr const size_t CRYPTONIGHT_LITE_MEMORY = 1 * 1024 * 1024;
constexpr const uint32_t CRYPTONIGHT_LITE_MASK = 0xFFFF0;
constexpr const uint32_t CRYPTONIGHT_LITE_ITER = 0x40000;
constexpr const size_t CRYPTONIGHT_HEAVY_MEMORY = 4 * 1024 * 1024;
constexpr const uint32_t CRYPTONIGHT_HEAVY_MASK = 0x3FFFF0;
constexpr const uint32_t CRYPTONIGHT_HEAVY_ITER = 0x40000;
template<Algo ALGO> inline constexpr size_t cn_select_memory() { return 0; }
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT>() { return CRYPTONIGHT_MEMORY; }
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_MEMORY; }
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_MEMORY; }
inline size_t cn_select_memory(Algo algorithm)
{
switch(algorithm)
{
case CRYPTONIGHT:
return CRYPTONIGHT_MEMORY;
case CRYPTONIGHT_LITE:
return CRYPTONIGHT_LITE_MEMORY;
case CRYPTONIGHT_HEAVY:
return CRYPTONIGHT_HEAVY_MEMORY;
}
}
template<Algo ALGO> inline constexpr uint32_t cn_select_mask() { return 0; }
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT>() { return CRYPTONIGHT_MASK; }
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_MASK; }
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_MASK; }
inline uint32_t cn_select_mask(Algo algorithm)
{
switch(algorithm)
{
case CRYPTONIGHT:
return CRYPTONIGHT_MASK;
case CRYPTONIGHT_LITE:
return CRYPTONIGHT_LITE_MASK;
case CRYPTONIGHT_HEAVY:
return CRYPTONIGHT_HEAVY_MASK;
}
}
template<Algo ALGO> inline constexpr uint32_t cn_select_iter() { return 0; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_ITER; }
inline uint32_t cn_select_iter(Algo algorithm)
{
switch(algorithm)
{
case CRYPTONIGHT:
return CRYPTONIGHT_ITER;
case CRYPTONIGHT_LITE:
return CRYPTONIGHT_LITE_ITER;
case CRYPTONIGHT_HEAVY:
return CRYPTONIGHT_HEAVY_ITER;
}
}
} /* namespace xmrig */
#endif /* __CRYPTONIGHT_CONSTANTS_H__ */

View File

@@ -0,0 +1,61 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CRYPTONIGHT_MONERO_H__
#define __CRYPTONIGHT_MONERO_H__
// VARIANT ALTERATIONS
#ifndef XMRIG_ARM
# define VARIANT1_INIT(part) \
uint64_t tweak1_2_##part = 0; \
if (VARIANT > 0) { \
tweak1_2_##part = (*reinterpret_cast<const uint64_t*>(input + 35 + part * size) ^ \
*(reinterpret_cast<const uint64_t*>(ctx->state##part) + 24)); \
}
#else
# define VARIANT1_INIT(part) \
uint64_t tweak1_2_##part = 0; \
if (VARIANT > 0) { \
volatile const uint64_t a = *reinterpret_cast<const uint64_t*>(input + 35 + part * size); \
volatile const uint64_t b = *(reinterpret_cast<const uint64_t*>(ctx->state##part) + 24); \
tweak1_2_##part = a ^ b; \
}
#endif
#define VARIANT1_1(p) \
if (VARIANT > 0) { \
const uint8_t tmp = reinterpret_cast<const uint8_t*>(p)[11]; \
static const uint32_t table = 0x75310; \
const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \
((uint8_t*)(p))[11] = tmp ^ ((table >> index) & 0x30); \
}
#define VARIANT1_2(p, part) \
if (VARIANT > 0) { \
(p) ^= tweak1_2_##part; \
}
#endif /* __CRYPTONIGHT_MONERO_H__ */

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,7 +40,7 @@ const static uint8_t test_input[152] = {
};
const static uint8_t test_output0[64] = {
const static uint8_t test_output_v0[64] = {
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
@@ -47,12 +48,40 @@ const static uint8_t test_output0[64] = {
};
// Monero v7
const static uint8_t test_output_v1[64] = {
0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D,
0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22,
0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9,
0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9
};
#ifndef XMRIG_NO_AEON
const static uint8_t test_output1[64] = {
const static uint8_t test_output_v0_lite[64] = {
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88,
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88
};
// AEON v7
const static uint8_t test_output_v1_lite[64] = {
0x87, 0xC4, 0xE5, 0x70, 0x65, 0x3E, 0xB4, 0xC2, 0xB4, 0x2B, 0x7A, 0x0D, 0x54, 0x65, 0x59, 0x45,
0x2D, 0xFA, 0xB5, 0x73, 0xB8, 0x2E, 0xC5, 0x2F, 0x15, 0x2B, 0x7F, 0xF9, 0x8E, 0x79, 0x44, 0x6F,
0x6D, 0x8C, 0xDC, 0x44, 0x4E, 0x9B, 0xBB, 0xFD, 0x68, 0xFC, 0x43, 0xFC, 0xD4, 0x85, 0x5B, 0x22,
0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41
};
#endif
#ifndef XMRIG_NO_SUMO
const static uint8_t test_output_heavy[64] = {
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2
};
#endif

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CRYPTONIGHT_P_H__
#define __CRYPTONIGHT_P_H__
#ifndef __CRYPTONIGHT_X86_H__
#define __CRYPTONIGHT_X86_H__
#ifdef __GNUC__
@@ -34,6 +35,9 @@
#include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_constants.h"
#include "crypto/CryptoNight_monero.h"
#include "crypto/soft_aes.h"
extern "C"
@@ -43,33 +47,30 @@ extern "C"
#include "crypto/c_blake256.h"
#include "crypto/c_jh.h"
#include "crypto/c_skein.h"
__m128i soft_aesenc(__m128i in, __m128i key);
__m128i soft_aeskeygenassist(__m128i key, uint8_t rcon);
}
static inline void do_blake_hash(const void* input, size_t len, char* output) {
blake256_hash(reinterpret_cast<uint8_t*>(output), static_cast<const uint8_t*>(input), len);
static inline void do_blake_hash(const uint8_t *input, size_t len, uint8_t *output) {
blake256_hash(output, input, len);
}
static inline void do_groestl_hash(const void* input, size_t len, char* output) {
groestl(static_cast<const uint8_t*>(input), len * 8, reinterpret_cast<uint8_t*>(output));
static inline void do_groestl_hash(const uint8_t *input, size_t len, uint8_t *output) {
groestl(input, len * 8, output);
}
static inline void do_jh_hash(const void* input, size_t len, char* output) {
jh_hash(32 * 8, static_cast<const uint8_t*>(input), 8 * len, reinterpret_cast<uint8_t*>(output));
static inline void do_jh_hash(const uint8_t *input, size_t len, uint8_t *output) {
jh_hash(32 * 8, input, 8 * len, output);
}
static inline void do_skein_hash(const void* input, size_t len, char* output) {
xmr_skein(static_cast<const uint8_t*>(input), reinterpret_cast<uint8_t*>(output));
static inline void do_skein_hash(const uint8_t *input, size_t len, uint8_t *output) {
xmr_skein(input, output);
}
void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash};
void (* const extra_hashes[4])(const uint8_t *, size_t, uint8_t *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash};
@@ -151,13 +152,14 @@ static inline void aes_genkey_sub(__m128i* xout0, __m128i* xout2)
}
static inline void soft_aes_genkey_sub(__m128i* xout0, __m128i* xout2, uint8_t rcon)
template<uint8_t rcon>
static inline void soft_aes_genkey_sub(__m128i* xout0, __m128i* xout2)
{
__m128i xout1 = soft_aeskeygenassist(*xout2, rcon);
__m128i xout1 = soft_aeskeygenassist<rcon>(*xout2);
xout1 = _mm_shuffle_epi32(xout1, 0xFF); // see PSHUFD, set all elems to 4th elem
*xout0 = sl_xor(*xout0);
*xout0 = _mm_xor_si128(*xout0, xout1);
xout1 = soft_aeskeygenassist(*xout0, 0x00);
xout1 = soft_aeskeygenassist<0x00>(*xout0);
xout1 = _mm_shuffle_epi32(xout1, 0xAA); // see PSHUFD, set all elems to 3rd elem
*xout2 = sl_xor(*xout2);
*xout2 = _mm_xor_si128(*xout2, xout1);
@@ -168,23 +170,23 @@ template<bool SOFT_AES>
static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3, __m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9)
{
__m128i xout0 = _mm_load_si128(memory);
__m128i xout2 = _mm_load_si128(memory +1 );
__m128i xout2 = _mm_load_si128(memory + 1);
*k0 = xout0;
*k1 = xout2;
SOFT_AES ? soft_aes_genkey_sub(&xout0, &xout2, 0x01) : aes_genkey_sub<0x01>(&xout0, &xout2);
SOFT_AES ? soft_aes_genkey_sub<0x01>(&xout0, &xout2) : aes_genkey_sub<0x01>(&xout0, &xout2);
*k2 = xout0;
*k3 = xout2;
SOFT_AES ? soft_aes_genkey_sub(&xout0, &xout2, 0x02) : aes_genkey_sub<0x02>(&xout0, &xout2);
SOFT_AES ? soft_aes_genkey_sub<0x02>(&xout0, &xout2) : aes_genkey_sub<0x02>(&xout0, &xout2);
*k4 = xout0;
*k5 = xout2;
SOFT_AES ? soft_aes_genkey_sub(&xout0, &xout2, 0x04) : aes_genkey_sub<0x04>(&xout0, &xout2);
SOFT_AES ? soft_aes_genkey_sub<0x04>(&xout0, &xout2) : aes_genkey_sub<0x04>(&xout0, &xout2);
*k6 = xout0;
*k7 = xout2;
SOFT_AES ? soft_aes_genkey_sub(&xout0, &xout2, 0x08) : aes_genkey_sub<0x08>(&xout0, &xout2);
SOFT_AES ? soft_aes_genkey_sub<0x08>(&xout0, &xout2) : aes_genkey_sub<0x08>(&xout0, &xout2);
*k8 = xout0;
*k9 = xout2;
}
@@ -194,14 +196,14 @@ template<bool SOFT_AES>
static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7)
{
if (SOFT_AES) {
*x0 = soft_aesenc(*x0, key);
*x1 = soft_aesenc(*x1, key);
*x2 = soft_aesenc(*x2, key);
*x3 = soft_aesenc(*x3, key);
*x4 = soft_aesenc(*x4, key);
*x5 = soft_aesenc(*x5, key);
*x6 = soft_aesenc(*x6, key);
*x7 = soft_aesenc(*x7, key);
*x0 = soft_aesenc((uint32_t*)x0, key);
*x1 = soft_aesenc((uint32_t*)x1, key);
*x2 = soft_aesenc((uint32_t*)x2, key);
*x3 = soft_aesenc((uint32_t*)x3, key);
*x4 = soft_aesenc((uint32_t*)x4, key);
*x5 = soft_aesenc((uint32_t*)x5, key);
*x6 = soft_aesenc((uint32_t*)x6, key);
*x7 = soft_aesenc((uint32_t*)x7, key);
}
else {
*x0 = _mm_aesenc_si128(*x0, key);
@@ -216,7 +218,21 @@ static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2,
}
template<size_t MEM, bool SOFT_AES>
inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3, __m128i& x4, __m128i& x5, __m128i& x6, __m128i& x7)
{
__m128i tmp0 = x0;
x0 = _mm_xor_si128(x0, x1);
x1 = _mm_xor_si128(x1, x2);
x2 = _mm_xor_si128(x2, x3);
x3 = _mm_xor_si128(x3, x4);
x4 = _mm_xor_si128(x4, x5);
x5 = _mm_xor_si128(x5, x6);
x6 = _mm_xor_si128(x6, x7);
x7 = _mm_xor_si128(x7, tmp0);
}
template<xmrig::Algo ALGO, size_t MEM, bool SOFT_AES>
static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
{
__m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7;
@@ -233,6 +249,23 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
xin6 = _mm_load_si128(input + 10);
xin7 = _mm_load_si128(input + 11);
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
for (size_t i = 0; i < 16; i++) {
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
mix_and_propagate(xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
}
}
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
@@ -257,7 +290,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
}
template<size_t MEM, bool SOFT_AES>
template<xmrig::Algo ALGO, size_t MEM, bool SOFT_AES>
static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
{
__m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7;
@@ -295,6 +328,51 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
}
}
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0);
xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1);
xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2);
xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3);
xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4);
xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5);
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
}
for (size_t i = 0; i < 16; i++) {
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
}
}
_mm_store_si128(output + 4, xout0);
@@ -308,12 +386,23 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
}
template<size_t ITERATIONS, size_t MEM, size_t MASK, bool SOFT_AES>
inline void cryptonight_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, cryptonight_ctx *__restrict__ ctx)
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx)
{
keccak(static_cast<const uint8_t*>(input), (int) size, ctx->state0, 200);
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) ctx->state0, (__m128i*) ctx->memory);
if (VARIANT > 0 && size < 43) {
memset(output, 0, 32);
return;
}
keccak(input, (int) size, ctx->state0, 200);
VARIANT1_INIT(0);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx->state0, (__m128i*) ctx->memory);
const uint8_t* l0 = ctx->memory;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
@@ -326,16 +415,16 @@ inline void cryptonight_hash(const void *__restrict__ input, size_t size, void *
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx;
cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
if (SOFT_AES) {
cx = soft_aesenc(cx, _mm_set_epi64x(ah0, al0));
cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
}
else {
else {
cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0));
}
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
VARIANT1_1(&l0[idx0 & MASK]);
idx0 = EXTRACT64(cx);
bx0 = cx;
@@ -347,34 +436,57 @@ inline void cryptonight_hash(const void *__restrict__ input, size_t size, void *
al0 += hi;
ah0 += lo;
VARIANT1_2(ah0, 0);
((uint64_t*)&l0[idx0 & MASK])[0] = al0;
((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
VARIANT1_2(ah0, 0);
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0];
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2];
int64_t q = n / (d | 0x5);
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
idx0 = d ^ q;
}
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) ctx->memory, (__m128i*) ctx->state0);
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx->memory, (__m128i*) ctx->state0);
keccakf(h0, 24);
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, static_cast<char*>(output));
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
}
template<size_t ITERATIONS, size_t MEM, size_t MASK, bool SOFT_AES>
inline void cryptonight_double_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
{
keccak((const uint8_t *) input, (int) size, ctx->state0, 200);
keccak((const uint8_t *) input + size, (int) size, ctx->state1, 200);
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
if (VARIANT > 0 && size < 43) {
memset(output, 0, 64);
return;
}
keccak(input, (int) size, ctx->state0, 200);
keccak(input + size, (int) size, ctx->state1, 200);
VARIANT1_INIT(0);
VARIANT1_INIT(1);
const uint8_t* l0 = ctx->memory;
const uint8_t* l1 = ctx->memory + MEM;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state1);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
uint64_t al0 = h0[0] ^ h0[4];
uint64_t al1 = h1[0] ^ h1[4];
@@ -388,20 +500,23 @@ inline void cryptonight_double_hash(const void *__restrict__ input, size_t size,
uint64_t idx1 = h1[0] ^ h1[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
__m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]);
__m128i cx0, cx1;
if (SOFT_AES) {
cx0 = soft_aesenc(cx0, _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc(cx1, _mm_set_epi64x(ah1, al1));
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
}
else {
cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]);
cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0));
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1));
}
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
VARIANT1_1(&l0[idx0 & MASK]);
VARIANT1_1(&l1[idx1 & MASK]);
idx0 = EXTRACT64(cx0);
idx1 = EXTRACT64(cx1);
@@ -417,13 +532,24 @@ inline void cryptonight_double_hash(const void *__restrict__ input, size_t size,
al0 += hi;
ah0 += lo;
VARIANT1_2(ah0, 0);
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
VARIANT1_2(ah0, 0);
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0];
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2];
int64_t q = n / (d | 0x5);
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
idx0 = d ^ q;
}
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi);
@@ -431,22 +557,51 @@ inline void cryptonight_double_hash(const void *__restrict__ input, size_t size,
al1 += hi;
ah1 += lo;
VARIANT1_2(ah1, 1);
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
VARIANT1_2(ah1, 1);
ah1 ^= ch;
al1 ^= cl;
idx1 = al1;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
int64_t n = ((int64_t*)&l1[idx1 & MASK])[0];
int32_t d = ((int32_t*)&l1[idx1 & MASK])[2];
int64_t q = n / (d | 0x5);
((int64_t*)&l1[idx1 & MASK])[0] = n ^ q;
idx1 = d ^ q;
}
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
keccakf(h0, 24);
keccakf(h1, 24);
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, static_cast<char*>(output));
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, static_cast<char*>(output) + 32);
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32);
}
#endif /* __CRYPTONIGHT_P_H__ */
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
{
}
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
{
}
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
{
}
#endif /* __CRYPTONIGHT_X86_H__ */

1497
src/crypto/SSE2NEON.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,212 +0,0 @@
/*
* 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
* 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/>.
*
* Additional permission under GNU GPL version 3 section 7
*
* If you modify this Program, or any covered work, by linking or combining
* it with OpenSSL (or a modified version of that library), containing parts
* covered by the terms of OpenSSL License and SSLeay License, the licensors
* of this Program grant you additional permission to convey the resulting work.
*
*/
/*
* The orginal author of this AES implementation is Karl Malbrain.
*/
#ifdef __GNUC__
#include <x86intrin.h>
#else
#include <intrin.h>
#endif // __GNUC__
#include <inttypes.h>
#define TABLE_ALIGN 32
#define WPOLY 0x011b
#define N_COLS 4
#define AES_BLOCK_SIZE 16
#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2))
#if defined(_MSC_VER)
#define ALIGN __declspec(align(TABLE_ALIGN))
#elif defined(__GNUC__)
#define ALIGN __attribute__ ((aligned(16)))
#else
#define ALIGN
#endif
#define rf1(r,c) (r)
#define word_in(x,c) (*((uint32_t*)(x)+(c)))
#define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v))
#define s(x,c) x[c]
#define si(y,x,c) (s(y,c) = word_in(x, c))
#define so(y,x,c) word_out(y, c, s(x,c))
#define state_in(y,x) si(y,x,0); si(y,x,1); si(y,x,2); si(y,x,3)
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
#define round(y,x,k) \
y[0] = (k)[0] ^ (t_fn[0][x[0] & 0xff] ^ t_fn[1][(x[1] >> 8) & 0xff] ^ t_fn[2][(x[2] >> 16) & 0xff] ^ t_fn[3][x[3] >> 24]); \
y[1] = (k)[1] ^ (t_fn[0][x[1] & 0xff] ^ t_fn[1][(x[2] >> 8) & 0xff] ^ t_fn[2][(x[3] >> 16) & 0xff] ^ t_fn[3][x[0] >> 24]); \
y[2] = (k)[2] ^ (t_fn[0][x[2] & 0xff] ^ t_fn[1][(x[3] >> 8) & 0xff] ^ t_fn[2][(x[0] >> 16) & 0xff] ^ t_fn[3][x[1] >> 24]); \
y[3] = (k)[3] ^ (t_fn[0][x[3] & 0xff] ^ t_fn[1][(x[0] >> 8) & 0xff] ^ t_fn[2][(x[1] >> 16) & 0xff] ^ t_fn[3][x[2] >> 24]);
#define to_byte(x) ((x) & 0xff)
#define bval(x,n) to_byte((x) >> (8 * (n)))
#define fwd_var(x,r,c)\
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
: r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
: ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
#define sb_data(w) {\
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
#define rc_data(w) {\
w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
w(0x1b), w(0x36) }
#define bytes2word(b0, b1, b2, b3) (((uint32_t)(b3) << 24) | \
((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0))
#define h0(x) (x)
#define w0(p) bytes2word(p, 0, 0, 0)
#define w1(p) bytes2word(0, p, 0, 0)
#define w2(p) bytes2word(0, 0, p, 0)
#define w3(p) bytes2word(0, 0, 0, p)
#define u0(p) bytes2word(f2(p), p, p, f3(p))
#define u1(p) bytes2word(f3(p), f2(p), p, p)
#define u2(p) bytes2word(p, f3(p), f2(p), p)
#define u3(p) bytes2word(p, p, f3(p), f2(p))
#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) ^ (((x>>5) & 4) * WPOLY))
#define f3(x) (f2(x) ^ x)
#define f9(x) (f8(x) ^ x)
#define fb(x) (f8(x) ^ f2(x) ^ x)
#define fd(x) (f8(x) ^ f4(x) ^ x)
#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
#define t_dec(m,n) t_##m##n
#define t_set(m,n) t_##m##n
#define t_use(m,n) t_##m##n
#define d_4(t,n,b,e,f,g,h) ALIGN const t n[4][256] = { b(e), b(f), b(g), b(h) }
#define four_tables(x,tab,vf,rf,c) \
(tab[0][bval(vf(x,0,c),rf(0,c))] \
^ tab[1][bval(vf(x,1,c),rf(1,c))] \
^ tab[2][bval(vf(x,2,c),rf(2,c))] \
^ tab[3][bval(vf(x,3,c),rf(3,c))])
d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3);
__m128i soft_aesenc(__m128i in, __m128i key)
{
uint32_t x0, x1, x2, x3;
x0 = _mm_cvtsi128_si32(in);
x1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0x55));
x2 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xAA));
x3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xFF));
__m128i out = _mm_set_epi32(
(t_fn[0][x3 & 0xff] ^ t_fn[1][(x0 >> 8) & 0xff] ^ t_fn[2][(x1 >> 16) & 0xff] ^ t_fn[3][x2 >> 24]),
(t_fn[0][x2 & 0xff] ^ t_fn[1][(x3 >> 8) & 0xff] ^ t_fn[2][(x0 >> 16) & 0xff] ^ t_fn[3][x1 >> 24]),
(t_fn[0][x1 & 0xff] ^ t_fn[1][(x2 >> 8) & 0xff] ^ t_fn[2][(x3 >> 16) & 0xff] ^ t_fn[3][x0 >> 24]),
(t_fn[0][x0 & 0xff] ^ t_fn[1][(x1 >> 8) & 0xff] ^ t_fn[2][(x2 >> 16) & 0xff] ^ t_fn[3][x3 >> 24]));
return _mm_xor_si128(out, key);
}
uint8_t Sbox[256] = { // forward s-box
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
static inline void sub_word(uint8_t* key)
{
key[0] = Sbox[key[0]];
key[1] = Sbox[key[1]];
key[2] = Sbox[key[2]];
key[3] = Sbox[key[3]];
}
#ifdef __clang__
uint32_t _rotr(uint32_t value, uint32_t amount)
{
return (value >> amount) | (value << ((32 - amount) & 31));
}
#endif
__m128i soft_aeskeygenassist(__m128i key, uint8_t rcon)
{
uint32_t X1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0x55));
uint32_t X3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0xFF));
sub_word((uint8_t*)&X1);
sub_word((uint8_t*)&X3);
return _mm_set_epi32(_rotr(X3, 8) ^ rcon, X3,_rotr(X1, 8) ^ rcon, X1);
}

129
src/crypto/soft_aes.h Normal file
View File

@@ -0,0 +1,129 @@
/*
* 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
* 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/>.
*
* Additional permission under GNU GPL version 3 section 7
*
* If you modify this Program, or any covered work, by linking or combining
* it with OpenSSL (or a modified version of that library), containing parts
* covered by the terms of OpenSSL License and SSLeay License, the licensors
* of this Program grant you additional permission to convey the resulting work.
*
*/
/*
* Parts of this file are originally copyright (c) 2014-2017, The Monero Project
*/
#pragma once
#if defined(XMRIG_ARM)
# include "crypto/SSE2NEON.h"
#elif defined(__GNUC__)
# include <x86intrin.h>
#else
# include <intrin.h>
#endif
#include <inttypes.h>
#define saes_data(w) {\
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
#define SAES_WPOLY 0x011b
#define saes_b2w(b0, b1, b2, b3) (((uint32_t)(b3) << 24) | \
((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0))
#define saes_f2(x) ((x<<1) ^ (((x>>7) & 1) * SAES_WPOLY))
#define saes_f3(x) (saes_f2(x) ^ x)
#define saes_h0(x) (x)
#define saes_u0(p) saes_b2w(saes_f2(p), p, p, saes_f3(p))
#define saes_u1(p) saes_b2w(saes_f3(p), saes_f2(p), p, p)
#define saes_u2(p) saes_b2w( p, saes_f3(p), saes_f2(p), p)
#define saes_u3(p) saes_b2w( p, p, saes_f3(p), saes_f2(p))
alignas(16) const uint32_t saes_table[4][256] = { saes_data(saes_u0), saes_data(saes_u1), saes_data(saes_u2), saes_data(saes_u3) };
alignas(16) const uint8_t saes_sbox[256] = saes_data(saes_h0);
static inline __m128i soft_aesenc(const uint32_t* in, __m128i key)
{
const uint32_t x0 = in[0];
const uint32_t x1 = in[1];
const uint32_t x2 = in[2];
const uint32_t x3 = in[3];
__m128i out = _mm_set_epi32(
(saes_table[0][x3 & 0xff] ^ saes_table[1][(x0 >> 8) & 0xff] ^ saes_table[2][(x1 >> 16) & 0xff] ^ saes_table[3][x2 >> 24]),
(saes_table[0][x2 & 0xff] ^ saes_table[1][(x3 >> 8) & 0xff] ^ saes_table[2][(x0 >> 16) & 0xff] ^ saes_table[3][x1 >> 24]),
(saes_table[0][x1 & 0xff] ^ saes_table[1][(x2 >> 8) & 0xff] ^ saes_table[2][(x3 >> 16) & 0xff] ^ saes_table[3][x0 >> 24]),
(saes_table[0][x0 & 0xff] ^ saes_table[1][(x1 >> 8) & 0xff] ^ saes_table[2][(x2 >> 16) & 0xff] ^ saes_table[3][x3 >> 24]));
return _mm_xor_si128(out, key);
}
static inline uint32_t sub_word(uint32_t key)
{
return (saes_sbox[key >> 24 ] << 24) |
(saes_sbox[(key >> 16) & 0xff] << 16 ) |
(saes_sbox[(key >> 8) & 0xff] << 8 ) |
saes_sbox[key & 0xff];
}
#if defined(__clang__) || defined(XMRIG_ARM)
static inline uint32_t _rotr(uint32_t value, uint32_t amount)
{
return (value >> amount) | (value << ((32 - amount) & 31));
}
#endif
template<uint8_t rcon>
static inline __m128i soft_aeskeygenassist(__m128i key)
{
const uint32_t X1 = sub_word(_mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0x55)));
const uint32_t X3 = sub_word(_mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0xFF)));
return _mm_set_epi32(_rotr(X3, 8) ^ rcon, X3, _rotr(X1, 8) ^ rcon, X1);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,13 +31,15 @@
* Percentage of your hashing power that you want to donate to the developer, can be 0 if you don't want to do that.
* Example of how it works for the default setting of 1:
* You miner will mine into your usual pool for 99 minutes, then switch to the developer's pool for 1 minute.
* Since v2.5.1 start time randomized in range from 50 to 150 minutes minus donation time.
* Switching is instant, and only happens after a successful connection, so you never loose any hashes.
*
* If you plan on changing this setting to 0 please consider making a one off donation to my wallet:
* XMR: 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD
* BTC: 1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT
*/
constexpr const int kDonateLevel = 5;
constexpr const int kDefaultDonateLevel = 5;
constexpr const int kMinDonateLevel = 1;
#endif /* __DONATE_H__ */

109
src/interfaces/IConfig.h Normal file
View File

@@ -0,0 +1,109 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2018 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ICONFIG_H__
#define __ICONFIG_H__
#include "rapidjson/fwd.h"
namespace xmrig {
class IConfig
{
public:
enum Keys {
// common
AlgorithmKey = 'a',
ApiPort = 4000,
ApiAccessTokenKey = 4001,
ApiWorkerIdKey = 4002,
ApiIPv6Key = 4003,
ApiRestrictedKey = 4004,
BackgroundKey = 'B',
ConfigKey = 'c',
DonateLevelKey = 1003,
HelpKey = 'h',
KeepAliveKey = 'k',
LogFileKey = 'l',
ColorKey = 1002,
WatchKey = 1105,
PasswordKey = 'p',
RetriesKey = 'r',
RetryPauseKey = 'R',
SyslogKey = 'S',
UrlKey = 'o',
UserKey = 'u',
UserAgentKey = 1008,
UserpassKey = 'O',
VerboseKey = 1100,
VersionKey = 'V',
VariantKey = 1010,
// xmrig common
CPUPriorityKey = 1021,
NicehashKey = 1006,
PrintTimeKey = 1007,
// xmrig cpu
AVKey = 'v',
CPUAffinityKey = 1020,
DryRunKey = 5000,
HugePagesKey = 1009,
MaxCPUUsageKey = 1004,
SafeKey = 1005,
ThreadsKey = 't',
// xmrig-proxy
AccessLogFileKey = 'A',
BindKey = 'b',
CoinKey = 1104,
CustomDiffKey = 1102,
DebugKey = 1101,
ModeKey = 'm',
PoolCoinKey = 'C',
ReuseTimeoutKey = 1106,
WorkersKey = 1103,
};
virtual ~IConfig() {}
virtual bool adjust() = 0;
virtual bool isValid() const = 0;
virtual bool isWatch() const = 0;
virtual bool parseBoolean(int key, bool enable) = 0;
virtual bool parseString(int key, const char *arg) = 0;
virtual bool parseUint64(int key, uint64_t arg) = 0;
virtual bool save() = 0;
virtual const char *fileName() const = 0;
virtual void getJSON(rapidjson::Document &doc) const = 0;
virtual void parseJSON(const rapidjson::Document &doc) = 0;
virtual void setFileName(const char *fileName) = 0;
};
} /* namespace xmrig */
#endif // __ICONFIG_H__

View File

@@ -4,8 +4,7 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2016-2018 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,13 +20,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ALIGN_H__
#define __ALIGN_H__
#ifndef __ICONFIGCREATOR_H__
#define __ICONFIGCREATOR_H__
#ifdef _MSC_VER
# define VAR_ALIGN(x, decl) __declspec(align(x)) decl
#else
# define VAR_ALIGN(x, decl) decl __attribute__ ((aligned(x)))
#endif
#endif /* __ALIGN_H__ */
namespace xmrig {
class IConfig;
class IConfigCreator
{
public:
virtual ~IConfigCreator() {}
virtual IConfig *create() const = 0;
};
} /* namespace xmrig */
#endif // __ICONFIGCREATOR_H__

View File

@@ -0,0 +1,46 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ICONTROLLERLISTENER_H__
#define __ICONTROLLERLISTENER_H__
namespace xmrig {
class Config;
class IControllerListener
{
public:
virtual ~IControllerListener() {}
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
};
} /* namespace xmrig */
#endif // __ICONTROLLERLISTENER_H__

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,10 +39,10 @@ class IStrategyListener
public:
virtual ~IStrategyListener() {}
virtual void onActive(Client *client) = 0;
virtual void onJob(Client *client, const Job &job) = 0;
virtual void onPause(IStrategy *strategy) = 0;
virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
virtual void onActive(IStrategy *strategy, Client *client) = 0;
virtual void onJob(IStrategy *strategy, Client *client, const Job &job) = 0;
virtual void onPause(IStrategy *strategy) = 0;
virtual void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) = 0;
};

64
src/interfaces/IThread.h Normal file
View 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 2016-2018 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ITHREAD_H__
#define __ITHREAD_H__
#include <stdint.h>
#include "rapidjson/fwd.h"
#include "xmrig.h"
namespace xmrig {
class IThread
{
public:
enum Type {
CPU,
OpenCL,
CUDA
};
virtual ~IThread() {}
virtual Algo algorithm() const = 0;
virtual int multiway() const = 0;
virtual int priority() const = 0;
virtual int64_t affinity() const = 0;
virtual size_t index() const = 0;
virtual Type type() const = 0;
# ifndef XMRIG_NO_API
virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0;
# endif
};
} /* namespace xmrig */
#endif // __ITHREAD_H__

View File

@@ -0,0 +1,46 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __IWATCHERLISTENER_H__
#define __IWATCHERLISTENER_H__
namespace xmrig {
class IConfig;
class IWatcherListener
{
public:
virtual ~IWatcherListener() {}
virtual void onNewConfig(IConfig *config) = 0;
};
} /* namespace xmrig */
#endif // __IWATCHERLISTENER_H__

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,9 +33,10 @@ class IWorker
public:
virtual ~IWorker() {}
virtual bool start() = 0;
virtual size_t id() const = 0;
virtual uint64_t hashCount() const = 0;
virtual uint64_t timestamp() const = 0;
virtual void start() = 0;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,15 +34,18 @@
#endif
#include "core/Config.h"
#include "core/Controller.h"
#include "log/ConsoleLog.h"
#include "log/Log.h"
ConsoleLog::ConsoleLog(bool colors) :
m_colors(colors),
m_stream(nullptr)
ConsoleLog::ConsoleLog(xmrig::Controller *controller) :
m_stream(nullptr),
m_controller(controller)
{
if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) {
controller->config()->setColors(false);
return;
}
@@ -65,10 +68,6 @@ ConsoleLog::ConsoleLog(bool colors) :
void ConsoleLog::message(int level, const char* fmt, va_list args)
{
if (!isWritable()) {
return;
}
time_t now = time(nullptr);
tm stime;
@@ -79,7 +78,9 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
# endif
const char* color = nullptr;
if (m_colors) {
const bool colors = m_controller->config()->isColors();
if (colors) {
switch (level) {
case Log::ERR:
color = Log::kCL_RED;
@@ -110,9 +111,9 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
stime.tm_hour,
stime.tm_min,
stime.tm_sec,
m_colors ? color : "",
colors ? color : "",
fmt,
m_colors ? Log::kCL_N : ""
colors ? Log::kCL_N : ""
);
print(args);
@@ -121,11 +122,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
void ConsoleLog::text(const char* fmt, va_list args)
{
if (!isWritable()) {
return;
}
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_colors ? Log::kCL_N : "");
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_controller->config()->isColors() ? Log::kCL_N : "");
print(args);
}
@@ -149,5 +146,11 @@ void ConsoleLog::print(va_list args)
return;
}
uv_try_write(m_stream, &m_uvBuf, 1);
if (!isWritable()) {
fputs(m_buf, stdout);
fflush(stdout);
}
else {
uv_try_write(m_stream, &m_uvBuf, 1);
}
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,10 +31,15 @@
#include "interfaces/ILogBackend.h"
namespace xmrig {
class Controller;
}
class ConsoleLog : public ILogBackend
{
public:
ConsoleLog(bool colors);
ConsoleLog(xmrig::Controller *controller);
void message(int level, const char *fmt, va_list args) override;
void text(const char *fmt, va_list args) override;
@@ -43,12 +48,12 @@ private:
bool isWritable() const;
void print(va_list args);
bool m_colors;
char m_buf[512];
char m_fmt[256];
uv_buf_t m_uvBuf;
uv_stream_t *m_stream;
uv_tty_t m_tty;
xmrig::Controller *m_controller;
};
#endif /* __CONSOLELOG_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <inttypes.h>
#include <iterator>
#include <stdio.h>
@@ -51,9 +52,12 @@
int64_t Client::m_sequence = 1;
xmrig::Storage<Client> Client::m_storage;
Client::Client(int id, const char *agent, IClientListener *listener) :
m_ipv6(false),
m_nicehash(false),
m_quiet(false),
m_agent(agent),
m_listener(listener),
@@ -63,25 +67,25 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_recvBufPos(0),
m_state(UnconnectedState),
m_expire(0),
m_jobs(0),
m_keepAlive(0),
m_key(0),
m_stream(nullptr),
m_socket(nullptr)
{
m_key = m_storage.add(this);
memset(m_ip, 0, sizeof(m_ip));
memset(&m_hints, 0, sizeof(m_hints));
m_resolver.data = this;
m_resolver.data = m_storage.ptr(m_key);
m_hints.ai_family = PF_INET;
m_hints.ai_family = AF_UNSPEC;
m_hints.ai_socktype = SOCK_STREAM;
m_hints.ai_protocol = IPPROTO_TCP;
m_recvBuf.base = m_buf;
m_recvBuf.len = sizeof(m_buf);
# ifndef XMRIG_PROXY_PROJECT
m_keepAliveTimer.data = this;
uv_timer_init(uv_default_loop(), &m_keepAliveTimer);
# endif
}
@@ -109,16 +113,22 @@ void Client::connect(const Url *url)
}
void Client::disconnect()
void Client::deleteLater()
{
# ifndef XMRIG_PROXY_PROJECT
uv_timer_stop(&m_keepAliveTimer);
# endif
if (!m_listener) {
return;
}
m_expire = 0;
m_failures = -1;
m_listener = nullptr;
close();
if (state() == HostLookupState) {
uv_cancel(reinterpret_cast<uv_req_t*>(&m_resolver));
return;
}
if (!disconnect() && m_state != ClosingState) {
m_storage.remove(m_key);
}
}
@@ -134,22 +144,32 @@ void Client::setUrl(const Url *url)
void Client::tick(uint64_t now)
{
if (m_expire == 0 || now < m_expire) {
return;
}
if (m_state == ConnectedState) {
LOG_DEBUG_ERR("[%s:%u] timeout", m_url.host(), m_url.port());
close();
if (m_expire && now > m_expire) {
LOG_DEBUG_ERR("[%s:%u] timeout", m_url.host(), m_url.port());
close();
}
else if (m_keepAlive && now > m_keepAlive) {
ping();
}
}
if (m_state == ConnectingState) {
if (m_expire && now > m_expire && m_state == ConnectingState) {
connect();
}
}
bool Client::disconnect()
{
m_keepAlive = 0;
m_expire = 0;
m_failures = -1;
return close();
}
int64_t Client::submit(const JobResult &result)
{
# ifdef XMRIG_PROXY_PROJECT
@@ -167,13 +187,55 @@ int64_t Client::submit(const JobResult &result)
# endif
const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRIu64 ",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
m_sequence, m_rpcId, result.jobId.data(), nonce, data);
m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data);
# ifdef XMRIG_PROXY_PROJECT
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
# else
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
# endif
return send(size);
}
bool Client::close()
{
if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) {
return false;
}
setState(ClosingState);
uv_stream_t *stream = reinterpret_cast<uv_stream_t*>(m_socket);
if (uv_is_readable(stream) == 1) {
uv_read_stop(stream);
}
if (uv_is_writable(stream) == 1) {
const int rc = uv_shutdown(new uv_shutdown_t, stream, [](uv_shutdown_t* req, int status) {
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(req->handle)) == 0) {
uv_close(reinterpret_cast<uv_handle_t*>(req->handle), Client::onClose);
}
delete req;
});
assert(rc == 0);
if (rc != 0) {
onClose();
}
}
else {
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
}
return true;
}
bool Client::isCriticalError(const char *message)
{
if (!message) {
@@ -203,7 +265,14 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
return false;
}
Job job(m_id, m_url.isNicehash());
# ifdef XMRIG_PROXY_PROJECT
Job job(m_id, m_url.variant());
job.setClientId(m_rpcId);
job.setCoin(m_url.coin());
# else
Job job(m_id, m_nicehash, m_url.algo(), m_url.variant());
# endif
if (!job.setId(params["job_id"].GetString())) {
*code = 3;
return false;
@@ -219,28 +288,52 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
return false;
}
if (m_job == job) {
LOG_WARN("[%s:%u] duplicate job received, ignore", m_url.host(), m_url.port());
if (params.HasMember("coin")) {
job.setCoin(params["coin"].GetString());
}
if (params.HasMember("variant")) {
job.setVariant(params["variant"].GetInt());
}
if (m_job != job) {
m_jobs++;
m_job = std::move(job);
return true;
}
if (m_jobs == 0) { // https://github.com/xmrig/xmrig/issues/459
return false;
}
m_job = std::move(job);
return true;
if (!m_quiet) {
LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
}
close();
return false;
}
bool Client::parseLogin(const rapidjson::Value &result, int *code)
{
const char *id = result["id"].GetString();
if (!id || strlen(id) >= sizeof(m_rpcId)) {
if (!m_rpcId.setId(result["id"].GetString())) {
*code = 1;
return false;
}
memset(m_rpcId, 0, sizeof(m_rpcId));
memcpy(m_rpcId, id, strlen(id));
# ifndef XMRIG_PROXY_PROJECT
m_nicehash = m_url.isNicehash();
# endif
return parseJob(result["job"], code);
if (result.HasMember("extensions")) {
parseExtensions(result["extensions"]);
}
const bool rc = parseJob(result["job"], code);
m_jobs = 0;
return rc;
}
@@ -255,7 +348,7 @@ int Client::resolve(const char *host)
m_failures = 0;
}
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints);
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, nullptr, &m_hints);
if (r) {
if (!m_quiet) {
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r));
@@ -287,21 +380,25 @@ int64_t Client::send(size_t size)
}
void Client::close()
void Client::connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6)
{
if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) {
return;
addrinfo *addr = nullptr;
m_ipv6 = ipv4.empty() && !ipv6.empty();
if (m_ipv6) {
addr = ipv6[ipv6.size() == 1 ? 0 : rand() % ipv6.size()];
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), m_ip, 45);
}
else {
addr = ipv4[ipv4.size() == 1 ? 0 : rand() % ipv4.size()];
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), m_ip, 16);
}
setState(ClosingState);
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_socket)) == 0) {
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
}
connect(addr->ai_addr);
}
void Client::connect(struct sockaddr *addr)
void Client::connect(sockaddr *addr)
{
setState(ConnectingState);
@@ -309,10 +406,10 @@ void Client::connect(struct sockaddr *addr)
delete m_socket;
uv_connect_t *req = new uv_connect_t;
req->data = this;
req->data = m_storage.ptr(m_key);
m_socket = new uv_tcp_t;
m_socket->data = this;
m_socket->data = m_storage.ptr(m_key);
uv_tcp_init(uv_default_loop(), m_socket);
uv_tcp_nodelay(m_socket, 1);
@@ -362,6 +459,18 @@ void Client::login()
}
void Client::onClose()
{
delete m_socket;
m_stream = nullptr;
m_socket = nullptr;
setState(UnconnectedState);
reconnect();
}
void Client::parse(char *line, size_t len)
{
startTimeout();
@@ -370,6 +479,14 @@ void Client::parse(char *line, size_t len)
LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
if (len < 32 || line[0] != '{') {
if (!m_quiet) {
LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port());
}
return;
}
rapidjson::Document doc;
if (doc.ParseInsitu(line).HasParseError()) {
if (!m_quiet) {
@@ -393,6 +510,24 @@ void Client::parse(char *line, size_t len)
}
void Client::parseExtensions(const rapidjson::Value &value)
{
if (!value.IsArray()) {
return;
}
for (const rapidjson::Value &ext : value.GetArray()) {
if (!ext.IsString()) {
continue;
}
if (strcmp(ext.GetString(), "nicehash") == 0) {
m_nicehash = true;
}
}
}
void Client::parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error)
{
if (error.IsObject()) {
@@ -434,7 +569,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), message, error["code"].GetInt());
}
if (id == 1 || isCriticalError(message)) {
if (isCriticalError(message)) {
close();
}
@@ -452,7 +587,8 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code);
}
return close();
close();
return;
}
m_failures = 0;
@@ -472,19 +608,20 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
void Client::ping()
{
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId));
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId.data()));
}
void Client::reconnect()
{
setState(ConnectingState);
if (!m_listener) {
m_storage.remove(m_key);
# ifndef XMRIG_PROXY_PROJECT
if (m_url.isKeepAlive()) {
uv_timer_stop(&m_keepAliveTimer);
return;
}
# endif
setState(ConnectingState);
m_keepAlive = 0;
if (m_failures == -1) {
return m_listener->onClose(this, -1);
@@ -513,19 +650,18 @@ void Client::startTimeout()
{
m_expire = 0;
# ifndef XMRIG_PROXY_PROJECT
if (!m_url.isKeepAlive()) {
return;
if (m_url.keepAlive()) {
m_keepAlive = uv_now(uv_default_loop()) + (m_url.keepAlive() * 1000);
}
uv_timer_start(&m_keepAliveTimer, [](uv_timer_t *handle) { getClient(handle->data)->ping(); }, kKeepAliveTimeout, 0);
# endif
}
void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
{
auto client = getClient(handle->data);
if (!client) {
return;
}
buf->base = &client->m_recvBuf.base[client->m_recvBufPos];
buf->len = client->m_recvBuf.len - client->m_recvBufPos;
@@ -535,20 +671,22 @@ void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t
void Client::onClose(uv_handle_t *handle)
{
auto client = getClient(handle->data);
if (!client) {
return;
}
delete client->m_socket;
client->m_stream = nullptr;
client->m_socket = nullptr;
client->setState(UnconnectedState);
client->reconnect();
client->onClose();
}
void Client::onConnect(uv_connect_t *req, int status)
{
auto client = getClient(req->data);
if (!client) {
delete req;
return;
}
if (status < 0) {
if (!client->m_quiet) {
LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
@@ -573,22 +711,33 @@ void Client::onConnect(uv_connect_t *req, int status)
void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
{
auto client = getClient(stream->data);
if (!client) {
return;
}
if (nread < 0) {
if (nread != UV_EOF && !client->m_quiet) {
LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror((int) nread));
}
return client->close();;
client->close();
return;
}
if ((size_t) nread > (sizeof(m_buf) - 8 - client->m_recvBufPos)) {
return client->close();;
client->close();
return;
}
assert(client->m_listener != nullptr);
if (!client->m_listener) {
return client->reconnect();
}
client->m_recvBufPos += nread;
char* end;
char* start = buf->base;
char* start = client->m_recvBuf.base;
size_t remaining = client->m_recvBufPos;
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
@@ -605,11 +754,11 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
return;
}
if (start == buf->base) {
if (start == client->m_recvBuf.base) {
return;
}
memcpy(buf->base, start, remaining);
memcpy(client->m_recvBuf.base, start, remaining);
client->m_recvBufPos = remaining;
}
@@ -617,31 +766,48 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
{
auto client = getClient(req->data);
if (!client) {
return;
}
assert(client->m_listener != nullptr);
if (!client->m_listener) {
return client->reconnect();
}
if (status < 0) {
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
return client->reconnect();;
if (!client->m_quiet) {
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
}
return client->reconnect();
}
addrinfo *ptr = res;
std::vector<addrinfo*> ipv4;
std::vector<addrinfo*> ipv6;
while (ptr != nullptr) {
if (ptr->ai_family == AF_INET) {
ipv4.push_back(ptr);
}
if (ptr->ai_family == AF_INET6) {
ipv6.push_back(ptr);
}
ptr = ptr->ai_next;
}
if (ipv4.empty()) {
LOG_ERR("[%s:%u] DNS error: \"No IPv4 records found\"", client->m_url.host(), client->m_url.port());
if (ipv4.empty() && ipv6.empty()) {
if (!client->m_quiet) {
LOG_ERR("[%s:%u] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_url.host(), client->m_url.port());
}
uv_freeaddrinfo(res);
return client->reconnect();
}
ptr = ipv4[rand() % ipv4.size()];
uv_ip4_name(reinterpret_cast<sockaddr_in*>(ptr->ai_addr), client->m_ip, 16);
client->connect(ptr->ai_addr);
client->connect(ipv4, ipv6);
uv_freeaddrinfo(res);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,9 +27,12 @@
#include <map>
#include <uv.h>
#include <vector>
#include "net/Id.h"
#include "net/Job.h"
#include "net/Storage.h"
#include "net/SubmitResult.h"
#include "net/Url.h"
#include "rapidjson/fwd.h"
@@ -51,15 +54,15 @@ public:
};
constexpr static int kResponseTimeout = 20 * 1000;
constexpr static int kKeepAliveTimeout = 60 * 1000;
Client(int id, const char *agent, IClientListener *listener);
~Client();
bool disconnect();
int64_t submit(const JobResult &result);
void connect();
void connect(const Url *url);
void disconnect();
void deleteLater();
void setUrl(const Url *url);
void tick(uint64_t now);
@@ -74,15 +77,18 @@ public:
inline void setRetryPause(int ms) { m_retryPause = ms; }
private:
bool close();
bool isCriticalError(const char *message);
bool parseJob(const rapidjson::Value &params, int *code);
bool parseLogin(const rapidjson::Value &result, int *code);
int resolve(const char *host);
int64_t send(size_t size);
void close();
void connect(struct sockaddr *addr);
void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6);
void connect(sockaddr *addr);
void login();
void onClose();
void parse(char *line, size_t len);
void parseExtensions(const rapidjson::Value &value);
void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error);
void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
void ping();
@@ -96,13 +102,14 @@ private:
static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
static void onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res);
static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
static inline Client *getClient(void *data) { return m_storage.get(data); }
addrinfo m_hints;
bool m_ipv6;
bool m_nicehash;
bool m_quiet;
char m_buf[2048];
char m_ip[17];
char m_rpcId[64];
char m_ip[46];
char m_sendBuf[768];
const char *m_agent;
IClientListener *m_listener;
@@ -112,18 +119,20 @@ private:
Job m_job;
size_t m_recvBufPos;
SocketState m_state;
static int64_t m_sequence;
std::map<int64_t, SubmitResult> m_results;
uint64_t m_expire;
uint64_t m_jobs;
uint64_t m_keepAlive;
uintptr_t m_key;
Url m_url;
uv_buf_t m_recvBuf;
uv_getaddrinfo_t m_resolver;
uv_stream_t *m_stream;
uv_tcp_t *m_socket;
xmrig::Id m_rpcId;
# ifndef XMRIG_PROXY_PROJECT
uv_timer_t m_keepAliveTimer;
# endif
static int64_t m_sequence;
static xmrig::Storage<Client> m_storage;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,40 +21,51 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __JOBID_H__
#define __JOBID_H__
#ifndef __ID_H__
#define __ID_H__
#include <string.h>
class JobId
namespace xmrig {
class Id
{
public:
inline JobId()
inline Id() :
m_data()
{
memset(m_data, 0, sizeof(m_data));
}
inline JobId(const char *id, size_t sizeFix = 0)
inline Id(const char *id, size_t sizeFix = 0)
{
setId(id, sizeFix);
}
inline bool operator==(const JobId &other) const
inline bool operator==(const Id &other) const
{
return memcmp(m_data, other.m_data, sizeof(m_data)) == 0;
}
inline bool operator!=(const JobId &other) const
inline bool operator!=(const Id &other) const
{
return memcmp(m_data, other.m_data, sizeof(m_data)) != 0;
}
Id &operator=(const Id &other)
{
memcpy(m_data, other.m_data, sizeof(m_data));
return *this;
}
inline bool setId(const char *id, size_t sizeFix = 0)
{
memset(m_data, 0, sizeof(m_data));
@@ -63,7 +74,7 @@ public:
}
const size_t size = strlen(id);
if (size < 4 || size >= sizeof(m_data)) {
if (size >= sizeof(m_data)) {
return false;
}
@@ -80,4 +91,8 @@ private:
char m_data[64];
};
#endif /* __JOBID_H__ */
} /* namespace xmrig */
#endif /* __ID_H__ */

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +23,7 @@
*/
#include <assert.h>
#include <string.h>
@@ -55,14 +57,33 @@ static inline char hf_bin2hex(unsigned char c)
}
Job::Job(int poolId, bool nicehash) :
Job::Job() :
m_nicehash(false),
m_coin(),
m_algo(xmrig::CRYPTONIGHT),
m_poolId(-2),
m_threadId(-1),
m_size(0),
m_diff(0),
m_target(0),
m_blob(),
m_variant(xmrig::VARIANT_AUTO)
{
}
Job::Job(int poolId, bool nicehash, int algo, int variant) :
m_nicehash(nicehash),
m_coin(),
m_algo(algo),
m_poolId(poolId),
m_threadId(-1),
m_size(0),
m_diff(0),
m_target(0)
m_target(0),
m_blob()
{
setVariant(variant);
}
@@ -95,11 +116,6 @@ bool Job::setBlob(const char *blob)
m_nicehash = true;
}
# ifdef XMRIG_PROXY_PROJECT
memset(m_rawBlob, 0, sizeof(m_rawBlob));
memcpy(m_rawBlob, blob, m_size * 2);
# endif
return true;
}
@@ -136,16 +152,40 @@ bool Job::setTarget(const char *target)
return false;
}
# ifdef XMRIG_PROXY_PROJECT
memset(m_rawTarget, 0, sizeof(m_rawTarget));
memcpy(m_rawTarget, target, len);
# endif
m_diff = toDiff(m_target);
return true;
}
void Job::setCoin(const char *coin)
{
if (!coin || strlen(coin) > 4) {
memset(m_coin, 0, sizeof(m_coin));
return;
}
strncpy(m_coin, coin, sizeof(m_coin));
m_algo = strcmp(m_coin, "AEON") == 0 ? xmrig::CRYPTONIGHT_LITE : xmrig::CRYPTONIGHT;
}
void Job::setVariant(int variant)
{
switch (variant) {
case xmrig::VARIANT_AUTO:
case xmrig::VARIANT_NONE:
case xmrig::VARIANT_V1:
m_variant = static_cast<xmrig::Variant>(variant);
break;
default:
assert(false);
m_variant = xmrig::VARIANT_AUTO;
break;
}
}
bool Job::fromHex(const char* in, unsigned int len, unsigned char* out)
{
bool error = false;
@@ -173,3 +213,9 @@ bool Job::operator==(const Job &other) const
{
return m_id == other.m_id && memcmp(m_blob, other.m_blob, sizeof(m_blob)) == 0;
}
bool Job::operator!=(const Job &other) const
{
return m_id != other.m_id || memcmp(m_blob, other.m_blob, sizeof(m_blob)) != 0;
}

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,25 +30,29 @@
#include <stdint.h>
#include "align.h"
#include "net/JobId.h"
#include "net/Id.h"
#include "xmrig.h"
class Job
{
public:
Job(int poolId = -2, bool nicehash = false);
Job();
Job(int poolId, bool nicehash, int algo, int variant);
~Job();
bool setBlob(const char *blob);
bool setTarget(const char *target);
void setCoin(const char *coin);
void setVariant(int variant);
inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
inline bool setId(const char *id) { return m_id.setId(id); }
inline const JobId &id() const { return m_id; }
inline const char *coin() const { return m_coin; }
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
inline const uint8_t *blob() const { return m_blob; }
inline const xmrig::Id &id() const { return m_id; }
inline int poolId() const { return m_poolId; }
inline int threadId() const { return m_threadId; }
inline size_t size() const { return m_size; }
@@ -55,12 +60,9 @@ public:
inline uint32_t diff() const { return (uint32_t) m_diff; }
inline uint64_t target() const { return m_target; }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
inline void setPoolId(int poolId) { m_poolId = poolId; }
inline void setThreadId(int threadId) { m_threadId = threadId; }
# ifdef XMRIG_PROXY_PROJECT
inline char *rawBlob() { return m_rawBlob; }
inline const char *rawTarget() const { return m_rawTarget; }
# endif
inline xmrig::Variant variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_V1 : xmrig::VARIANT_NONE) : m_variant); }
static bool fromHex(const char* in, unsigned int len, unsigned char* out);
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
@@ -68,22 +70,20 @@ public:
static void toHex(const unsigned char* in, unsigned int len, char* out);
bool operator==(const Job &other) const;
bool operator!=(const Job &other) const;
private:
VAR_ALIGN(16, uint8_t m_blob[84]); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
bool m_nicehash;
char m_coin[5];
int m_algo;
int m_poolId;
int m_threadId;
JobId m_id;
size_t m_size;
uint64_t m_diff;
uint64_t m_target;
# ifdef XMRIG_PROXY_PROJECT
VAR_ALIGN(16, char m_rawBlob[169]);
VAR_ALIGN(16, char m_rawTarget[17]);
# endif
uint8_t m_blob[96]; // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
xmrig::Id m_id;
xmrig::Variant m_variant;
};
#endif /* __JOB_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,11 +36,11 @@ class JobResult
{
public:
inline JobResult() : poolId(0), diff(0), nonce(0) {}
inline JobResult(int poolId, const JobId &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) :
inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) :
poolId(poolId),
jobId(jobId),
diff(diff),
nonce(nonce)
nonce(nonce),
jobId(jobId)
{
memcpy(this->result, result, sizeof(this->result));
}
@@ -71,10 +71,10 @@ public:
int poolId;
JobId jobId;
uint32_t diff;
uint32_t nonce;
uint8_t result[32];
xmrig::Id jobId;
};
#endif /* __JOBRESULT_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,30 +39,30 @@
#include "net/strategies/SinglePoolStrategy.h"
#include "net/SubmitResult.h"
#include "net/Url.h"
#include "Options.h"
#include "Platform.h"
#include "workers/Workers.h"
#include "core/Controller.h"
#include "core/Config.h"
Network::Network(const Options *options) :
m_options(options),
m_donate(nullptr)
Network::Network(xmrig::Controller *controller) :
m_donate(nullptr),
m_controller(controller)
{
srand(time(0) ^ (uintptr_t) this);
Workers::setListener(this);
const std::vector<Url*> &pools = options->pools();
const std::vector<Url*> &pools = controller->config()->pools();
if (pools.size() > 1) {
m_strategy = new FailoverStrategy(pools, Platform::userAgent(), this);
m_strategy = new FailoverStrategy(pools, controller->config()->retryPause(), controller->config()->retries(), this);
}
else {
m_strategy = new SinglePoolStrategy(pools.front(), Platform::userAgent(), this);
m_strategy = new SinglePoolStrategy(pools.front(), controller->config()->retryPause(), this);
}
if (m_options->donateLevel() > 0) {
m_donate = new DonateStrategy(Platform::userAgent(), this);
if (controller->config()->donateLevel() > 0) {
m_donate = new DonateStrategy(controller->config()->donateLevel(), controller->config()->pools().front()->user(), controller->config()->algorithm(), this);
}
m_timer.data = this;
@@ -93,26 +93,26 @@ void Network::stop()
}
void Network::onActive(Client *client)
void Network::onActive(IStrategy *strategy, Client *client)
{
if (client->id() == -1) {
if (m_donate && m_donate == strategy) {
LOG_NOTICE("dev donate started");
return;
}
m_state.setPool(client->host(), client->port(), client->ip());
LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "use pool %s:%d %s", client->host(), client->port(), client->ip());
LOG_INFO(isColors() ? "\x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "use pool %s:%d %s", client->host(), client->port(), client->ip());
}
void Network::onJob(Client *client, const Job &job)
void Network::onJob(IStrategy *strategy, Client *client, const Job &job)
{
if (m_donate && m_donate->isActive() && client->id() != -1) {
if (m_donate && m_donate->isActive() && m_donate != strategy) {
return;
}
setJob(client, job);
setJob(client, job, m_donate == strategy);
}
@@ -142,26 +142,32 @@ void Network::onPause(IStrategy *strategy)
}
void Network::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
void Network::onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error)
{
m_state.add(result, error);
if (error) {
LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
: "rejected (%" PRId64 "/%" PRId64 ") diff %u \"%s\" (%" PRIu64 " ms)",
LOG_INFO(isColors() ? "\x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
: "rejected (%" PRId64 "/%" PRId64 ") diff %u \"%s\" (%" PRIu64 " ms)",
m_state.accepted, m_state.rejected, result.diff, error, result.elapsed);
}
else {
LOG_INFO(m_options->colors() ? "\x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
: "accepted (%" PRId64 "/%" PRId64 ") diff %u (%" PRIu64 " ms)",
LOG_INFO(isColors() ? "\x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
: "accepted (%" PRId64 "/%" PRId64 ") diff %u (%" PRIu64 " ms)",
m_state.accepted, m_state.rejected, result.diff, result.elapsed);
}
}
void Network::setJob(Client *client, const Job &job)
bool Network::isColors() const
{
if (m_options->colors()) {
return m_controller->config()->isColors();
}
void Network::setJob(Client *client, const Job &job, bool donate)
{
if (isColors()) {
LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", client->host(), client->port(), job.diff());
}
else {
@@ -169,7 +175,7 @@ void Network::setJob(Client *client, const Job &job)
}
m_state.diff = job.diff();
Workers::setJob(job);
Workers::setJob(job, donate);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,39 +35,44 @@
class IStrategy;
class Options;
class Url;
namespace xmrig {
class Controller;
}
class Network : public IJobResultListener, public IStrategyListener
{
public:
Network(const Options *options);
Network(xmrig::Controller *controller);
~Network();
void connect();
void stop();
protected:
void onActive(Client *client) override;
void onJob(Client *client, const Job &job) override;
void onActive(IStrategy *strategy, Client *client) override;
void onJob(IStrategy *strategy, Client *client, const Job &job) override;
void onJobResult(const JobResult &result) override;
void onPause(IStrategy *strategy) override;
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
private:
constexpr static int kTickInterval = 1 * 1000;
void setJob(Client *client, const Job &job);
bool isColors() const;
void setJob(Client *client, const Job &job, bool donate);
void tick();
static void onTick(uv_timer_t *handle);
const Options *m_options;
IStrategy *m_donate;
IStrategy *m_strategy;
NetworkState m_state;
uv_timer_t m_timer;
xmrig::Controller *m_controller;
};

97
src/net/Storage.h Normal file
View File

@@ -0,0 +1,97 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __STORAGE_H__
#define __STORAGE_H__
#include <assert.h>
#include <map>
#include "log/Log.h"
namespace xmrig {
template <class TYPE>
class Storage
{
public:
inline Storage() :
m_counter(0)
{
}
inline uintptr_t add(TYPE *ptr)
{
m_data[m_counter] = ptr;
return m_counter++;
}
inline static void *ptr(uintptr_t id) { return reinterpret_cast<void *>(id); }
inline TYPE *get(void *id) const { return get(reinterpret_cast<uintptr_t>(id)); }
inline TYPE *get(uintptr_t id) const
{
assert(m_data.count(id) > 0);
if (m_data.count(id) == 0) {
return nullptr;
}
return m_data.at(id);
}
inline void remove(void *id) { remove(reinterpret_cast<uintptr_t>(id)); }
inline void remove(uintptr_t id)
{
TYPE *obj = get(id);
if (obj == nullptr) {
return;
}
auto it = m_data.find(id);
if (it != m_data.end()) {
m_data.erase(it);
}
delete obj;
}
private:
std::map<uintptr_t, TYPE *> m_data;
uint64_t m_counter;
};
} /* namespace xmrig */
#endif /* __STORAGE_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,6 +28,7 @@
#include "net/Url.h"
#include "xmrig.h"
#ifdef _MSC_VER
@@ -36,11 +37,14 @@
Url::Url() :
m_keepAlive(false),
m_nicehash(false),
m_host(nullptr),
m_password(nullptr),
m_user(nullptr),
m_algo(xmrig::CRYPTONIGHT),
m_keepAlive(0),
m_variant(xmrig::VARIANT_AUTO),
m_url(nullptr),
m_port(kDefaultPort)
{
}
@@ -58,22 +62,28 @@ Url::Url() :
* @param url
*/
Url::Url(const char *url) :
m_keepAlive(false),
m_nicehash(false),
m_host(nullptr),
m_password(nullptr),
m_user(nullptr),
m_algo(xmrig::CRYPTONIGHT),
m_keepAlive(0),
m_variant(xmrig::VARIANT_AUTO),
m_url(nullptr),
m_port(kDefaultPort)
{
parse(url);
}
Url::Url(const char *host, uint16_t port, const char *user, const char *password, bool keepAlive, bool nicehash) :
m_keepAlive(keepAlive),
Url::Url(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, int variant) :
m_nicehash(nicehash),
m_password(password ? strdup(password) : nullptr),
m_user(user ? strdup(user) : nullptr),
m_algo(xmrig::CRYPTONIGHT),
m_keepAlive(keepAlive),
m_variant(variant),
m_url(nullptr),
m_port(port)
{
m_host = strdup(host);
@@ -85,6 +95,10 @@ Url::~Url()
free(m_host);
free(m_password);
free(m_user);
if (m_url) {
delete [] m_url;
}
}
@@ -105,6 +119,10 @@ bool Url::parse(const char *url)
return false;
}
if (base[0] == '[') {
return parseIPv6(base);
}
const char *port = strchr(base, ':');
if (!port) {
m_host = strdup(base);
@@ -112,9 +130,8 @@ bool Url::parse(const char *url)
}
const size_t size = port++ - base + 1;
m_host = static_cast<char*>(malloc(size));
m_host = new char[size]();
memcpy(m_host, base, size - 1);
m_host[size - 1] = '\0';
m_port = (uint16_t) strtol(port, nullptr, 10);
return true;
@@ -139,12 +156,27 @@ bool Url::setUserpass(const char *userpass)
}
void Url::applyExceptions()
const char *Url::url() const
{
if (!m_url) {
const size_t size = strlen(m_host) + 8;
m_url = new char[size];
snprintf(m_url, size - 1, "%s:%d", m_host, m_port);
}
return m_url;
}
void Url::adjust(int algo)
{
if (!isValid()) {
return;
}
m_algo = algo;
if (strstr(m_host, ".nicehash.com")) {
m_keepAlive = false;
m_nicehash = true;
@@ -178,9 +210,40 @@ void Url::setUser(const char *user)
}
void Url::setVariant(int variant)
{
switch (variant) {
case xmrig::VARIANT_AUTO:
case xmrig::VARIANT_NONE:
case xmrig::VARIANT_V1:
m_variant = variant;
break;
default:
break;
}
}
bool Url::operator==(const Url &other) const
{
if (m_port != other.m_port || m_keepAlive != other.m_keepAlive || m_nicehash != other.m_nicehash) {
return false;
}
if (strcmp(host(), other.host()) != 0 || strcmp(user(), other.user()) != 0 || strcmp(password(), other.password()) != 0) {
return false;
}
return true;
}
Url &Url::operator=(const Url *other)
{
m_keepAlive = other->m_keepAlive;
m_algo = other->m_algo;
m_variant = other->m_variant;
m_nicehash = other->m_nicehash;
m_port = other->m_port;
@@ -190,5 +253,32 @@ Url &Url::operator=(const Url *other)
setPassword(other->m_password);
setUser(other->m_user);
if (m_url) {
delete [] m_url;
m_url = nullptr;
}
return *this;
}
bool Url::parseIPv6(const char *addr)
{
const char *end = strchr(addr, ']');
if (!end) {
return false;
}
const char *port = strchr(end, ':');
if (!port) {
return false;
}
const size_t size = end - addr;
m_host = new char[size]();
memcpy(m_host, addr + 1, size - 1);
m_port = (uint16_t) strtol(port + 1, nullptr, 10);
return true;
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,36 +34,48 @@ public:
constexpr static const char *kDefaultPassword = "x";
constexpr static const char *kDefaultUser = "x";
constexpr static uint16_t kDefaultPort = 3333;
constexpr static int kKeepAliveTimeout = 60;
Url();
Url(const char *url);
Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, bool keepAlive = false, bool nicehash = false );
Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, int keepAlive = 0, bool nicehash = false, int variant = -1);
~Url();
inline bool isKeepAlive() const { return m_keepAlive; }
inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_host && m_port > 0; }
inline const char *host() const { return m_host; }
inline const char *password() const { return m_password ? m_password : kDefaultPassword; }
inline const char *user() const { return m_user ? m_user : kDefaultUser; }
inline int algo() const { return m_algo; }
inline int keepAlive() const { return m_keepAlive; }
inline int variant() const { return m_variant; }
inline uint16_t port() const { return m_port; }
inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; }
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
inline void setVariant(bool monero) { m_variant = monero; }
bool parse(const char *url);
bool setUserpass(const char *userpass);
void applyExceptions();
const char *url() const;
void adjust(int algo);
void setPassword(const char *password);
void setUser(const char *user);
void setVariant(int variant);
bool operator==(const Url &other) const;
Url &operator=(const Url *other);
private:
bool m_keepAlive;
bool parseIPv6(const char *addr);
bool m_nicehash;
char *m_host;
char *m_password;
char *m_user;
int m_algo;
int m_keepAlive;
int m_variant;
mutable char *m_url;
uint16_t m_port;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,7 +26,9 @@
#include "net/Client.h"
#include "net/Job.h"
#include "net/strategies/DonateStrategy.h"
#include "Options.h"
#include "net/strategies/FailoverStrategy.h"
#include "Platform.h"
#include "xmrig.h"
extern "C"
@@ -35,102 +37,124 @@ extern "C"
}
DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
const static char *kDonatePool1 = "miner.fee.xmrig.com";
const static char *kDonatePool2 = "emergency.fee.xmrig.com";
static inline int random(int min, int max){
return min + rand() / (RAND_MAX / (max - min + 1) + 1);
}
DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyListener *listener) :
m_active(false),
m_donateTime(Options::i()->donateLevel() * 60 * 1000),
m_idleTime((100 - Options::i()->donateLevel()) * 60 * 1000),
m_donateTime(level * 60 * 1000),
m_idleTime((100 - level) * 60 * 1000),
m_strategy(nullptr),
m_listener(listener)
{
uint8_t hash[200];
char userId[65] = { 0 };
const char *user = Options::i()->pools().front()->user();
keccak(reinterpret_cast<const uint8_t *>(user), static_cast<int>(strlen(user)), hash, sizeof(hash));
Job::toHex(hash, 32, userId);
Url *url = new Url("fee.xmrig.com", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443, userId, nullptr, false, true);
if (algo == xmrig::CRYPTONIGHT) {
m_pools.push_back(new Url(kDonatePool1, 6666, userId, nullptr, false, true));
m_pools.push_back(new Url(kDonatePool1, 80, userId, nullptr, false, true));
m_pools.push_back(new Url(kDonatePool2, 5555, "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", "emergency", false, false));
}
else if (algo == xmrig::CRYPTONIGHT_HEAVY) {
m_pools.push_back(new Url(kDonatePool1, 8888, userId, nullptr, false, true));
m_pools.push_back(new Url(kDonatePool1, 8889, userId, nullptr, false, true));
}
else {
m_pools.push_back(new Url(kDonatePool1, 5555, userId, nullptr, false, true));
m_pools.push_back(new Url(kDonatePool1, 7777, userId, nullptr, false, true));
}
m_client = new Client(-1, agent, this);
m_client->setUrl(url);
m_client->setRetryPause(Options::i()->retryPause() * 1000);
m_client->setQuiet(true);
delete url;
m_strategy = new FailoverStrategy(m_pools, 1, 1, this, true);
m_timer.data = this;
uv_timer_init(uv_default_loop(), &m_timer);
idle();
idle(random(3000, 9000) * 1000 - m_donateTime);
}
DonateStrategy::~DonateStrategy()
{
delete m_strategy;
}
int64_t DonateStrategy::submit(const JobResult &result)
{
return m_client->submit(result);
return m_strategy->submit(result);
}
void DonateStrategy::connect()
{
m_client->connect();
m_strategy->connect();
}
void DonateStrategy::stop()
{
uv_timer_stop(&m_timer);
m_client->disconnect();
m_strategy->stop();
}
void DonateStrategy::tick(uint64_t now)
{
m_client->tick(now);
m_strategy->tick(now);
}
void DonateStrategy::onClose(Client *client, int failures)
{
}
void DonateStrategy::onJobReceived(Client *client, const Job &job)
{
m_listener->onJob(client, job);
}
void DonateStrategy::onLoginSuccess(Client *client)
void DonateStrategy::onActive(IStrategy *strategy, Client *client)
{
if (!isActive()) {
uv_timer_start(&m_timer, DonateStrategy::onTimer, m_donateTime, 0);
}
m_active = true;
m_listener->onActive(client);
m_listener->onActive(this, client);
}
void DonateStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
void DonateStrategy::onJob(IStrategy *strategy, Client *client, const Job &job)
{
m_listener->onResultAccepted(client, result, error);
m_listener->onJob(this, client, job);
}
void DonateStrategy::idle()
void DonateStrategy::onPause(IStrategy *strategy)
{
uv_timer_start(&m_timer, DonateStrategy::onTimer, m_idleTime, 0);
}
void DonateStrategy::onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error)
{
m_listener->onResultAccepted(this, client, result, error);
}
void DonateStrategy::idle(uint64_t timeout)
{
uv_timer_start(&m_timer, DonateStrategy::onTimer, timeout, 0);
}
void DonateStrategy::suspend()
{
m_client->disconnect();
m_strategy->stop();
m_active = false;
m_listener->onPause(this);
idle();
idle(m_idleTime);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,10 +26,12 @@
#include <uv.h>
#include <vector>
#include "interfaces/IClientListener.h"
#include "interfaces/IStrategy.h"
#include "interfaces/IStrategyListener.h"
class Client;
@@ -37,10 +39,11 @@ class IStrategyListener;
class Url;
class DonateStrategy : public IStrategy, public IClientListener
class DonateStrategy : public IStrategy, public IStrategyListener
{
public:
DonateStrategy(const char *agent, IStrategyListener *listener);
DonateStrategy(int level, const char *user, int algo, IStrategyListener *listener);
~DonateStrategy();
public:
inline bool isActive() const override { return m_active; }
@@ -52,22 +55,23 @@ public:
void tick(uint64_t now) override;
protected:
void onClose(Client *client, int failures) override;
void onJobReceived(Client *client, const Job &job) override;
void onLoginSuccess(Client *client) override;
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
void onActive(IStrategy *strategy, Client *client) override;
void onJob(IStrategy *strategy, Client *client, const Job &job) override;
void onPause(IStrategy *strategy) override;
void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
private:
void idle();
void idle(uint64_t timeout);
void suspend();
static void onTimer(uv_timer_t *handle);
bool m_active;
Client *m_client;
const int m_donateTime;
const int m_idleTime;
IStrategy *m_strategy;
IStrategyListener *m_listener;
std::vector<Url*> m_pools;
uv_timer_t m_timer;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,22 +25,37 @@
#include "interfaces/IStrategyListener.h"
#include "net/Client.h"
#include "net/strategies/FailoverStrategy.h"
#include "Options.h"
#include "Platform.h"
FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, const char *agent, IStrategyListener *listener) :
FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
m_quiet(quiet),
m_retries(retries),
m_retryPause(retryPause),
m_active(-1),
m_index(0),
m_listener(listener)
{
for (const Url *url : urls) {
add(url, agent);
add(url);
}
}
FailoverStrategy::~FailoverStrategy()
{
for (Client *client : m_pools) {
client->deleteLater();
}
}
int64_t FailoverStrategy::submit(const JobResult &result)
{
if (m_active == -1) {
return -1;
}
return m_pools[m_active]->submit(result);
}
@@ -57,7 +72,7 @@ void FailoverStrategy::resume()
return;
}
m_listener->onJob( m_pools[m_active], m_pools[m_active]->job());
m_listener->onJob(this, m_pools[m_active], m_pools[m_active]->job());
}
@@ -93,7 +108,7 @@ void FailoverStrategy::onClose(Client *client, int failures)
m_listener->onPause(this);
}
if (m_index == 0 && failures < Options::i()->retries()) {
if (m_index == 0 && failures < m_retries) {
return;
}
@@ -106,7 +121,7 @@ void FailoverStrategy::onClose(Client *client, int failures)
void FailoverStrategy::onJobReceived(Client *client, const Job &job)
{
if (m_active == client->id()) {
m_listener->onJob(client, job);
m_listener->onJob(this, client, job);
}
}
@@ -127,22 +142,23 @@ void FailoverStrategy::onLoginSuccess(Client *client)
if (active >= 0 && active != m_active) {
m_index = m_active = active;
m_listener->onActive(client);
m_listener->onActive(this, client);
}
}
void FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
{
m_listener->onResultAccepted(client, result, error);
m_listener->onResultAccepted(this, client, result, error);
}
void FailoverStrategy::add(const Url *url, const char *agent)
void FailoverStrategy::add(const Url *url)
{
Client *client = new Client((int) m_pools.size(), agent, this);
Client *client = new Client((int) m_pools.size(), Platform::userAgent(), this);
client->setUrl(url);
client->setRetryPause(Options::i()->retryPause() * 1000);
client->setRetryPause(m_retryPause * 1000);
client->setQuiet(m_quiet);
m_pools.push_back(client);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,7 +40,8 @@ class Url;
class FailoverStrategy : public IStrategy, public IClientListener
{
public:
FailoverStrategy(const std::vector<Url*> &urls, const char *agent, IStrategyListener *listener);
FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
~FailoverStrategy();
public:
inline bool isActive() const override { return m_active >= 0; }
@@ -58,8 +59,11 @@ protected:
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
private:
void add(const Url *url, const char *agent);
void add(const Url *url);
const bool m_quiet;
const int m_retries;
const int m_retryPause;
int m_active;
int m_index;
IStrategyListener *m_listener;

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,16 +25,23 @@
#include "interfaces/IStrategyListener.h"
#include "net/Client.h"
#include "net/strategies/SinglePoolStrategy.h"
#include "Options.h"
#include "Platform.h"
SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener) :
SinglePoolStrategy::SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet) :
m_active(false),
m_listener(listener)
{
m_client = new Client(0, agent, this);
m_client = new Client(0, Platform::userAgent(), this);
m_client->setUrl(url);
m_client->setRetryPause(Options::i()->retryPause() * 1000);
m_client->setRetryPause(retryPause * 1000);
m_client->setQuiet(quiet);
}
SinglePoolStrategy::~SinglePoolStrategy()
{
m_client->deleteLater();
}
@@ -56,7 +63,7 @@ void SinglePoolStrategy::resume()
return;
}
m_listener->onJob(m_client, m_client->job());
m_listener->onJob(this, m_client, m_client->job());
}
@@ -85,18 +92,18 @@ void SinglePoolStrategy::onClose(Client *client, int failures)
void SinglePoolStrategy::onJobReceived(Client *client, const Job &job)
{
m_listener->onJob(client, job);
m_listener->onJob(this, client, job);
}
void SinglePoolStrategy::onLoginSuccess(Client *client)
{
m_active = true;
m_listener->onActive(client);
m_listener->onActive(this, client);
}
void SinglePoolStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
{
m_listener->onResultAccepted(client, result, error);
m_listener->onResultAccepted(this, client, result, error);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,7 +37,8 @@ class Url;
class SinglePoolStrategy : public IStrategy, public IClientListener
{
public:
SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener);
SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet = false);
~SinglePoolStrategy();
public:
inline bool isActive() const override { return m_active; }

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,19 +27,19 @@
#define APP_ID "xmrig"
#define APP_NAME "XMRig"
#define APP_DESC "XMRig CPU miner"
#define APP_VERSION "2.4.0"
#define APP_VERSION "2.6.0-beta1"
#define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com"
#define APP_KIND "cpu"
#define APP_VER_MAJOR 2
#define APP_VER_MINOR 4
#define APP_VER_MINOR 6
#define APP_VER_BUILD 0
#define APP_VER_REV 0
#define APP_VER_REV 1
#ifdef _MSC_VER
# if (_MSC_VER == 1910 || _MSC_VER == 1911)
# if (_MSC_VER >= 1910)
# define MSVC_VERSION 2017
# elif _MSC_VER == 1900
# define MSVC_VERSION 2015

216
src/workers/CpuThread.cpp Normal file
View File

@@ -0,0 +1,216 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include "core/CommonConfig.h"
#include "rapidjson/document.h"
#include "workers/CpuThread.h"
#if defined(XMRIG_ARM)
# include "crypto/CryptoNight_arm.h"
#else
# include "crypto/CryptoNight_x86.h"
#endif
xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch) :
m_algorithm(algorithm),
m_av(av),
m_prefetch(prefetch),
m_softAES(softAES),
m_priority(priority),
m_affinity(affinity),
m_multiway(multiway),
m_index(index)
{
}
xmrig::CpuThread::~CpuThread()
{
}
xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant)
{
assert(variant == VARIANT_NONE || variant == VARIANT_V1);
static const cn_hash_fun func_table[50] = {
cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_NONE>,
cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_NONE>,
cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_NONE>,
cryptonight_double_hash<CRYPTONIGHT, true, VARIANT_NONE>,
cryptonight_triple_hash<CRYPTONIGHT, false, VARIANT_NONE>,
cryptonight_quad_hash<CRYPTONIGHT, false, VARIANT_NONE>,
cryptonight_penta_hash<CRYPTONIGHT, false, VARIANT_NONE>,
cryptonight_triple_hash<CRYPTONIGHT, true, VARIANT_NONE>,
cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_NONE>,
cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_NONE>,
cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_V1>,
cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_V1>,
cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_V1>,
cryptonight_double_hash<CRYPTONIGHT, true, VARIANT_V1>,
cryptonight_triple_hash<CRYPTONIGHT, false, VARIANT_V1>,
cryptonight_quad_hash<CRYPTONIGHT, false, VARIANT_V1>,
cryptonight_penta_hash<CRYPTONIGHT, false, VARIANT_V1>,
cryptonight_triple_hash<CRYPTONIGHT, true, VARIANT_V1>,
cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_V1>,
cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_V1>,
# ifndef XMRIG_NO_AEON
cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_NONE>,
cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_NONE>,
cryptonight_single_hash<CRYPTONIGHT_LITE, true, VARIANT_NONE>,
cryptonight_double_hash<CRYPTONIGHT_LITE, true, VARIANT_NONE>,
cryptonight_triple_hash<CRYPTONIGHT_LITE, false, VARIANT_NONE>,
cryptonight_quad_hash<CRYPTONIGHT_LITE, false, VARIANT_NONE>,
cryptonight_penta_hash<CRYPTONIGHT_LITE, false, VARIANT_NONE>,
cryptonight_triple_hash<CRYPTONIGHT_LITE, true, VARIANT_NONE>,
cryptonight_quad_hash<CRYPTONIGHT_LITE, true, VARIANT_NONE>,
cryptonight_penta_hash<CRYPTONIGHT_LITE, true, VARIANT_NONE>,
cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_V1>,
cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_V1>,
cryptonight_single_hash<CRYPTONIGHT_LITE, true, VARIANT_V1>,
cryptonight_double_hash<CRYPTONIGHT_LITE, true, VARIANT_V1>,
cryptonight_triple_hash<CRYPTONIGHT_LITE, false, VARIANT_V1>,
cryptonight_quad_hash<CRYPTONIGHT_LITE, false, VARIANT_V1>,
cryptonight_penta_hash<CRYPTONIGHT_LITE, false, VARIANT_V1>,
cryptonight_triple_hash<CRYPTONIGHT_LITE, true, VARIANT_V1>,
cryptonight_quad_hash<CRYPTONIGHT_LITE, true, VARIANT_V1>,
cryptonight_penta_hash<CRYPTONIGHT_LITE, true, VARIANT_V1>,
# else
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
# endif
# ifndef XMRIG_NO_SUMO
cryptonight_single_hash<CRYPTONIGHT_HEAVY, false, VARIANT_NONE>,
cryptonight_double_hash<CRYPTONIGHT_HEAVY, false, VARIANT_NONE>,
cryptonight_single_hash<CRYPTONIGHT_HEAVY, true, VARIANT_NONE>,
cryptonight_double_hash<CRYPTONIGHT_HEAVY, true, VARIANT_NONE>,
cryptonight_triple_hash<CRYPTONIGHT_HEAVY, false, VARIANT_NONE>,
cryptonight_quad_hash<CRYPTONIGHT_HEAVY, false, VARIANT_NONE>,
cryptonight_penta_hash<CRYPTONIGHT_HEAVY, false, VARIANT_NONE>,
cryptonight_triple_hash<CRYPTONIGHT_HEAVY, true, VARIANT_NONE>,
cryptonight_quad_hash<CRYPTONIGHT_HEAVY, true, VARIANT_NONE>,
cryptonight_penta_hash<CRYPTONIGHT_HEAVY, true, VARIANT_NONE>,
# else
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
# endif
};
# ifndef XMRIG_NO_SUMO
if (algorithm == CRYPTONIGHT_HEAVY) {
variant = VARIANT_NONE;
}
# endif
return func_table[20 * algorithm + 10 * variant + av - 1];
}
xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority)
{
assert(av > AV_AUTO && av < AV_MAX);
Multiway multiway = SingleWay;
bool softAES = false;
switch (av) {
case AV_SINGLE_SOFT:
softAES = true;
break;
case AV_DOUBLE:
multiway = DoubleWay;
case AV_DOUBLE_SOFT:
softAES = true;
break;
case AV_TRIPLE:
multiway = TripleWay;
case AV_TRIPLE_SOFT:
softAES = true;
break;
case AV_QUAD:
multiway = QuadWay;
case AV_QUAD_SOFT:
softAES = true;
break;
case AV_PENTA:
multiway = PentaWay;
case AV_PENTA_SOFT:
softAES = true;
break;
default:
break;
}
int64_t cpuId = -1L;
if (affinity != -1L) {
size_t idx = 0;
for (size_t i = 0; i < 64; i++) {
if (!(affinity & (1ULL << i))) {
continue;
}
if (idx == index) {
cpuId = i;
break;
}
idx++;
}
}
return new CpuThread(index, algorithm, av, multiway, cpuId, priority, softAES, false);
}
#ifndef XMRIG_NO_API
rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const
{
rapidjson::Value obj(rapidjson::kObjectType);
auto &allocator = doc.GetAllocator();
obj.AddMember("type", "cpu", allocator);
obj.AddMember("algo", rapidjson::StringRef(CommonConfig::algoName(algorithm())), allocator);
obj.AddMember("av", m_av, allocator);
obj.AddMember("low_power_mode", multiway(), allocator);
obj.AddMember("affine_to_cpu", affinity(), allocator);
obj.AddMember("priority", priority(), allocator);
obj.AddMember("soft_aes", isSoftAES(), allocator);
return obj;
}
#endif

87
src/workers/CpuThread.h Normal file
View File

@@ -0,0 +1,87 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CPUTHREAD_H__
#define __CPUTHREAD_H__
#include "interfaces/IThread.h"
#include "xmrig.h"
struct cryptonight_ctx;
namespace xmrig {
class CpuThread : public IThread
{
public:
enum Multiway {
SingleWay = 1,
DoubleWay,
TripleWay,
QuadWay,
PentaWay
};
CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch);
~CpuThread();
typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx);
static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant);
static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority);
inline bool isPrefetch() const { return m_prefetch; }
inline bool isSoftAES() const { return m_softAES; }
inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant); }
inline Algo algorithm() const override { return m_algorithm; }
inline int multiway() const override { return m_multiway; }
inline int priority() const override { return m_priority; }
inline int64_t affinity() const override { return m_affinity; }
inline size_t index() const override { return m_index; }
inline Type type() const override { return CPU; }
# ifndef XMRIG_NO_API
rapidjson::Value toAPI(rapidjson::Document &doc) const override;
# endif
private:
const Algo m_algorithm;
const AlgoVariant m_av;
const bool m_prefetch;
const bool m_softAES;
const int m_priority;
const int64_t m_affinity;
const Multiway m_multiway;
const size_t m_index;
};
} /* namespace xmrig */
#endif /* __CPUTHREAD_H__ */

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +26,8 @@
#include <thread>
#include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_test.h"
#include "workers/CpuThread.h"
#include "workers/DoubleWorker.h"
#include "workers/Workers.h"
@@ -60,8 +62,12 @@ DoubleWorker::~DoubleWorker()
}
void DoubleWorker::start()
bool DoubleWorker::start()
{
if (!selfTest()) {
return false;
}
while (Workers::sequence() > 0) {
if (Workers::isPaused()) {
do {
@@ -85,7 +91,7 @@ void DoubleWorker::start()
*Job::nonce(m_state->blob) = ++m_state->nonce1;
*Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2;
CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx);
m_thread->fn(m_state->job.variant())(m_state->blob, m_state->job.size(), m_hash, m_ctx);
if (*reinterpret_cast<uint64_t*>(m_hash + 24) < m_state->job.target()) {
Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff()));
@@ -100,6 +106,8 @@ void DoubleWorker::start()
consumeJob();
}
return true;
}
@@ -114,6 +122,32 @@ bool DoubleWorker::resume(const Job &job)
}
bool DoubleWorker::selfTest()
{
if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) {
return false;
}
m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_hash, m_ctx);
if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, 64) == 0) {
m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx);
return memcmp(m_hash, test_output_v1, 64) == 0;
}
# ifndef XMRIG_NO_AEON
if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, 64) == 0) {
m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx);
return memcmp(m_hash, test_output_v1_lite, 64) == 0;
}
# endif
return memcmp(m_hash, test_output_heavy, 64) == 0;
}
void DoubleWorker::consumeJob()
{
Job job = Workers::job();
@@ -133,12 +167,12 @@ void DoubleWorker::consumeJob()
memcpy(m_state->blob + m_state->job.size(), m_state->job.blob(), m_state->job.size());
if (m_state->job.isNicehash()) {
m_state->nonce1 = (*Job::nonce(m_state->blob) & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id);
m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / (m_threads * 2) * (m_id + m_threads));
m_state->nonce1 = (*Job::nonce(m_state->blob) & 0xff000000U) + (0xffffffU / m_totalWays * m_id);
m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / m_totalWays * (m_id + m_totalThreads));
}
else {
m_state->nonce1 = 0xffffffffU / (m_threads * 2) * m_id;
m_state->nonce2 = 0xffffffffU / (m_threads * 2) * (m_id + m_threads);
m_state->nonce1 = 0xffffffffU / m_totalWays * m_id;
m_state->nonce2 = 0xffffffffU / m_totalWays * (m_id + m_totalThreads);
}
}

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +26,6 @@
#define __DOUBLEWORKER_H__
#include "align.h"
#include "net/Job.h"
#include "net/JobResult.h"
#include "workers/Worker.h"
@@ -40,10 +40,11 @@ public:
DoubleWorker(Handle *handle);
~DoubleWorker();
void start() override;
bool start() override;
private:
bool resume(const Job &job);
bool selfTest();
void consumeJob();
void save(const Job &job);

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,12 +25,12 @@
#include "workers/Handle.h"
Handle::Handle(int threadId, int threads, int64_t affinity, int priority) :
m_priority(priority),
m_threadId(threadId),
m_threads(threads),
Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays, int64_t affinity) :
m_affinity(affinity),
m_worker(nullptr)
m_worker(nullptr),
m_totalThreads(totalThreads),
m_totalWays(totalWays),
m_config(config)
{
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,30 +29,34 @@
#include <uv.h>
#include "interfaces/IThread.h"
class IWorker;
class Handle
{
public:
Handle(int threadId, int threads, int64_t affinity, int priority);
Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays, int64_t affinity);
void join();
void start(void (*callback) (void *));
inline int priority() const { return m_priority; }
inline int threadId() const { return m_threadId; }
inline int threads() const { return m_threads; }
inline int64_t affinity() const { return m_affinity; }
inline IWorker *worker() const { return m_worker; }
inline size_t threadId() const { return m_config->index(); }
inline size_t totalThreads() const { return m_totalThreads; }
inline size_t totalWays() const { return m_totalWays; }
inline void setWorker(IWorker *worker) { m_worker = worker; }
inline xmrig::IThread *config() const { return m_config; }
private:
int m_priority;
int m_threadId;
int m_threads;
int64_t m_affinity;
IWorker *m_worker;
size_t m_totalThreads;
size_t m_totalWays;
uv_thread_t m_thread;
xmrig::IThread *m_config;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,17 +23,20 @@
#include <chrono>
#include <cmath>
#include <math.h>
#include <memory.h>
#include <stdio.h>
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "Options.h"
#include "workers/Hashrate.h"
inline const char *format(double h, char* buf, size_t size)
{
if (std::isnormal(h)) {
if (isnormal(h)) {
snprintf(buf, size, "%03.1f", h);
return buf;
}
@@ -42,9 +45,10 @@ inline const char *format(double h, char* buf, size_t size)
}
Hashrate::Hashrate(int threads) :
Hashrate::Hashrate(int threads, xmrig::Controller *controller) :
m_highest(0.0),
m_threads(threads)
m_threads(threads),
m_controller(controller)
{
m_counts = new uint64_t*[threads];
m_timestamps = new uint64_t*[threads];
@@ -59,7 +63,7 @@ Hashrate::Hashrate(int threads) :
memset(m_timestamps[0], 0, sizeof(uint64_t) * kBucketSize);
}
const int printTime = Options::i()->printTime();
const int printTime = controller->config()->printTime();
if (printTime > 0) {
uv_timer_init(uv_default_loop(), &m_timer);
@@ -77,7 +81,7 @@ double Hashrate::calc(size_t ms) const
for (int i = 0; i < m_threads; ++i) {
data = calc(i, ms);
if (std::isnormal(data)) {
if (isnormal(data)) {
result += data;
}
}
@@ -152,7 +156,7 @@ void Hashrate::print()
char num3[8];
char num4[8];
LOG_INFO(Options::i()->colors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s max: %s H/s",
LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s max: %s H/s",
format(calc(ShortInterval), num1, sizeof(num1)),
format(calc(MediumInterval), num2, sizeof(num2)),
format(calc(LargeInterval), num3, sizeof(num3)),
@@ -170,7 +174,7 @@ void Hashrate::stop()
void Hashrate::updateHighest()
{
double highest = calc(ShortInterval);
if (std::isnormal(highest) && highest > m_highest) {
if (isnormal(highest) && highest > m_highest) {
m_highest = highest;
}
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,6 +29,11 @@
#include <uv.h>
namespace xmrig {
class Controller;
}
class Hashrate
{
public:
@@ -38,7 +43,7 @@ public:
LargeInterval = 900000
};
Hashrate(int threads);
Hashrate(int threads, xmrig::Controller *controller);
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);
@@ -61,6 +66,7 @@ private:
uint64_t** m_counts;
uint64_t** m_timestamps;
uv_timer_t m_timer;
xmrig::Controller *m_controller;
};

View File

@@ -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 Lee Clagett <https://github.com/vtnerd>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +26,8 @@
#include <thread>
#include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_test.h"
#include "workers/CpuThread.h"
#include "workers/SingleWorker.h"
#include "workers/Workers.h"
@@ -36,8 +38,12 @@ SingleWorker::SingleWorker(Handle *handle)
}
void SingleWorker::start()
bool SingleWorker::start()
{
if (!selfTest()) {
return false;
}
while (Workers::sequence() > 0) {
if (Workers::isPaused()) {
do {
@@ -60,7 +66,8 @@ void SingleWorker::start()
m_count++;
*m_job.nonce() = ++m_result.nonce;
if (CryptoNight::hash(m_job, m_result, m_ctx)) {
m_thread->fn(m_job.variant())(m_job.blob(), m_job.size(), m_result.result, m_ctx);
if (*reinterpret_cast<uint64_t*>(m_result.result + 24) < m_job.target()) {
Workers::submit(m_result);
}
@@ -69,6 +76,8 @@ void SingleWorker::start()
consumeJob();
}
return true;
}
@@ -85,6 +94,32 @@ bool SingleWorker::resume(const Job &job)
}
bool SingleWorker::selfTest()
{
if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) {
return false;
}
m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_result.result, m_ctx);
if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_result.result, test_output_v0, 32) == 0) {
m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctx);
return memcmp(m_result.result, test_output_v1, 32) == 0;
}
# ifndef XMRIG_NO_AEON
if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_result.result, test_output_v0_lite, 32) == 0) {
m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctx);
return memcmp(m_result.result, test_output_v1_lite, 32) == 0;
}
# endif
return memcmp(m_result.result, test_output_heavy, 32) == 0;
}
void SingleWorker::consumeJob()
{
Job job = Workers::job();
@@ -103,10 +138,10 @@ void SingleWorker::consumeJob()
m_result = m_job;
if (m_job.isNicehash()) {
m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id);
m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_totalWays * m_id);
}
else {
m_result.nonce = 0xffffffffU / m_threads * m_id;
m_result.nonce = 0xffffffffU / m_totalWays * m_id;
}
}

Some files were not shown because too many files have changed in this diff Show More