Merge branch 'dev'

This commit is contained in:
XMRig 2018-09-30 19:59:25 +03:00
commit 880747d0e0
86 changed files with 4347 additions and 1930 deletions

View file

@ -1,3 +1,12 @@
# v2.8.0
- **[#753](https://github.com/xmrig/xmrig/issues/753) Added new algorithm [CryptoNight variant 2](https://github.com/xmrig/xmrig/issues/753) for Monero fork, thanks [@SChernykh](https://github.com/SChernykh).**
- Added global and per thread option `"asm"` and and command line equivalent.
- **[#758](https://github.com/xmrig/xmrig/issues/758) Added SSL/TLS support for secure connections to pools.**
- Added per pool options `"tls"` and `"tls-fingerprint"` and command line equivalents.
- [#767](https://github.com/xmrig/xmrig/issues/767) Added config autosave feature, same with GPU miners.
- [#245](https://github.com/xmrig/xmrig-proxy/issues/245) Fixed API ID collision when run multiple miners on same machine.
- [#757](https://github.com/xmrig/xmrig/issues/757) Fixed send buffer overflow.
# v2.6.4 # v2.6.4
- [#700](https://github.com/xmrig/xmrig/issues/700) `cryptonight-lite/ipbc` replaced to `cryptonight-heavy/tube` for **Bittube (TUBE)**. - [#700](https://github.com/xmrig/xmrig/issues/700) `cryptonight-lite/ipbc` replaced to `cryptonight-heavy/tube` for **Bittube (TUBE)**.
- Added `cryptonight/rto` (cryptonight variant 1 with IPBC/TUBE mod) variant for **Arto (RTO)** coin. - Added `cryptonight/rto` (cryptonight variant 1 with IPBC/TUBE mod) variant for **Arto (RTO)** coin.

View file

@ -1,11 +1,14 @@
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
project(xmrig) project(xmrig)
option(WITH_LIBCPUID "Use Libcpuid" ON) option(WITH_LIBCPUID "Use Libcpuid" ON)
option(WITH_AEON "CryptoNight-Lite support" ON) option(WITH_AEON "CryptoNight-Lite support" ON)
option(WITH_SUMO "CryptoNight-Heavy support" ON) option(WITH_SUMO "CryptoNight-Heavy support" ON)
option(WITH_HTTPD "HTTP REST API" ON) option(WITH_HTTPD "HTTP REST API" ON)
option(BUILD_STATIC "Build static binary" OFF) option(WITH_DEBUG_LOG "Enable debug log output" OFF)
option(WITH_TLS "Enable OpenSSL support" ON)
option(WITH_ASM "Enable ASM PoW implementations" ON)
option(BUILD_STATIC "Build static binary" OFF)
include (CheckIncludeFile) include (CheckIncludeFile)
include (cmake/cpu.cmake) include (cmake/cpu.cmake)
@ -18,6 +21,7 @@ set(HEADERS
src/common/config/ConfigLoader.h src/common/config/ConfigLoader.h
src/common/config/ConfigWatcher.h src/common/config/ConfigWatcher.h
src/common/Console.h src/common/Console.h
src/common/cpu/Cpu.h
src/common/crypto/Algorithm.h src/common/crypto/Algorithm.h
src/common/crypto/keccak.h src/common/crypto/keccak.h
src/common/interfaces/IClientListener.h src/common/interfaces/IClientListener.h
@ -25,10 +29,12 @@ set(HEADERS
src/common/interfaces/IConfigCreator.h src/common/interfaces/IConfigCreator.h
src/common/interfaces/IConsoleListener.h src/common/interfaces/IConsoleListener.h
src/common/interfaces/IControllerListener.h src/common/interfaces/IControllerListener.h
src/common/interfaces/ICpuInfo.h
src/common/interfaces/ILogBackend.h src/common/interfaces/ILogBackend.h
src/common/interfaces/IStrategy.h src/common/interfaces/IStrategy.h
src/common/interfaces/IStrategyListener.h src/common/interfaces/IStrategyListener.h
src/common/interfaces/IWatcherListener.h src/common/interfaces/IWatcherListener.h
src/common/log/BasicLog.h
src/common/log/ConsoleLog.h src/common/log/ConsoleLog.h
src/common/log/FileLog.h src/common/log/FileLog.h
src/common/log/Log.h src/common/log/Log.h
@ -46,7 +52,6 @@ set(HEADERS
src/common/xmrig.h src/common/xmrig.h
src/core/ConfigLoader_platform.h src/core/ConfigLoader_platform.h
src/core/Controller.h src/core/Controller.h
src/Cpu.h
src/interfaces/IJobResultListener.h src/interfaces/IJobResultListener.h
src/interfaces/IThread.h src/interfaces/IThread.h
src/interfaces/IWorker.h src/interfaces/IWorker.h
@ -94,6 +99,7 @@ set(SOURCES
src/common/Console.cpp src/common/Console.cpp
src/common/crypto/Algorithm.cpp src/common/crypto/Algorithm.cpp
src/common/crypto/keccak.cpp src/common/crypto/keccak.cpp
src/common/log/BasicLog.cpp
src/common/log/ConsoleLog.cpp src/common/log/ConsoleLog.cpp
src/common/log/FileLog.cpp src/common/log/FileLog.cpp
src/common/log/Log.cpp src/common/log/Log.cpp
@ -131,7 +137,6 @@ if (WIN32)
res/app.rc res/app.rc
src/App_win.cpp src/App_win.cpp
src/common/Platform_win.cpp src/common/Platform_win.cpp
src/Cpu_win.cpp
src/Mem_win.cpp src/Mem_win.cpp
) )
@ -141,18 +146,16 @@ elseif (APPLE)
set(SOURCES_OS set(SOURCES_OS
src/App_unix.cpp src/App_unix.cpp
src/common/Platform_mac.cpp src/common/Platform_mac.cpp
src/Cpu_mac.cpp
src/Mem_unix.cpp src/Mem_unix.cpp
) )
else() else()
set(SOURCES_OS set(SOURCES_OS
src/App_unix.cpp src/App_unix.cpp
src/common/Platform_unix.cpp src/common/Platform_unix.cpp
src/Cpu_unix.cpp
src/Mem_unix.cpp src/Mem_unix.cpp
) )
set(EXTRA_LIBS pthread rt) set(EXTRA_LIBS pthread rt dl)
endif() endif()
if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD) if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
@ -168,7 +171,6 @@ endif()
add_definitions(/D__STDC_FORMAT_MACROS) add_definitions(/D__STDC_FORMAT_MACROS)
add_definitions(/DUNICODE) add_definitions(/DUNICODE)
#add_definitions(/DAPP_DEBUG)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
@ -181,17 +183,21 @@ if (WITH_LIBCPUID)
include_directories(src/3rdparty/libcpuid) include_directories(src/3rdparty/libcpuid)
set(CPUID_LIB cpuid) set(CPUID_LIB cpuid)
set(SOURCES_CPUID src/Cpu.cpp) set(SOURCES_CPUID src/core/cpu/AdvancedCpuInfo.h src/core/cpu/AdvancedCpuInfo.cpp src/core/cpu/Cpu.cpp)
else() else()
add_definitions(/DXMRIG_NO_LIBCPUID) add_definitions(/DXMRIG_NO_LIBCPUID)
set(SOURCES_CPUID src/common/cpu/BasicCpuInfo.h src/common/cpu/Cpu.cpp)
if (XMRIG_ARM) if (XMRIG_ARM)
set(SOURCES_CPUID src/Cpu_arm.cpp) set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo_arm.cpp)
else() else()
set(SOURCES_CPUID src/Cpu_stub.cpp) set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo.cpp)
endif() endif()
endif() endif()
include(cmake/OpenSSL.cmake)
include(cmake/asm.cmake)
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H) CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
if (HAVE_SYSLOG_H) if (HAVE_SYSLOG_H)
add_definitions(/DHAVE_SYSLOG_H) add_definitions(/DHAVE_SYSLOG_H)
@ -231,6 +237,7 @@ if (WITH_HTTPD)
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support") message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
endif() endif()
else() else()
set(HTTPD_SOURCES "")
set(MHD_LIBRARY "") set(MHD_LIBRARY "")
add_definitions(/DXMRIG_NO_HTTPD) add_definitions(/DXMRIG_NO_HTTPD)
add_definitions(/DXMRIG_NO_API) add_definitions(/DXMRIG_NO_API)
@ -244,5 +251,9 @@ if (BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS " -static") set(CMAKE_EXE_LINKER_FLAGS " -static")
endif() endif()
add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES}) if (WITH_DEBUG_LOG)
target_link_libraries(${PROJECT_NAME} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB}) add_definitions(/DAPP_DEBUG)
endif()
add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES})
target_link_libraries(${PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})

View file

@ -1,6 +1,6 @@
# XMRig # XMRig
:warning: **If you mine Monero, Aeon, Sumokoin, Turtlecoin, Stellite, GRAFT, Haven Protocol, IPBC, [PLEASE READ](https://github.com/xmrig/xmrig/issues/482)!** :warning: :warning: **[Monero will change PoW algorithm on October 18](https://github.com/xmrig/xmrig/issues/753), all miners and proxy should be updated to v2.8+** :warning:
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases) [![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](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases)
@ -87,11 +87,22 @@ Use [config.xmrig.com](https://config.xmrig.com/xmrig) to generate, edit or shar
Also you can use configuration via config file, default **config.json**. You can load multiple config files and combine it with command line options. Also you can use configuration via config file, default **config.json**. You can load multiple config files and combine it with command line options.
## Algorithm variations ## Algorithm variations
Since version 0.8.0.
* `--av=1` For CPUs with hardware AES. - `av` option used for automatic and simple threads mode (when you specify only threads count).
* `--av=2` Lower power mode (double hash) of `1`. - For [advanced threads mode](https://github.com/xmrig/xmrig/issues/563) each thread configured individually and `av` option not used.
* `--av=3` Software AES implementation.
* `--av=4` Lower power mode (double hash) of `3`. | av | Hashes per round | Hardware AES |
|----|------------------|--------------|
| 1 | 1 (Single) | yes |
| 2 | 2 (Double) | yes |
| 3 | 1 (Single) | no |
| 4 | 2 (Double) | no |
| 5 | 3 (Triple) | yes |
| 6 | 4 (Quard) | yes |
| 7 | 5 (Penta) | yes |
| 8 | 3 (Triple) | no |
| 9 | 4 (Quard) | no |
| 10 | 5 (Penta) | no |
## Common Issues ## Common Issues
### HUGE PAGES unavailable ### HUGE PAGES unavailable
@ -100,8 +111,7 @@ Since version 0.8.0.
## Other information ## Other information
* No HTTP support, only stratum protocol support. * No HTTP support, only stratum protocol support.
* No TLS support. * Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via option `donate-level`.
* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`.
### CPU mining performance ### CPU mining performance

23
cmake/OpenSSL.cmake Normal file
View file

@ -0,0 +1,23 @@
if (WITH_TLS)
set(OPENSSL_ROOT_DIR ${XMRIG_DEPS})
if (WIN32)
set(OPENSSL_USE_STATIC_LIBS TRUE)
set(OPENSSL_MSVC_STATIC_RT TRUE)
set(EXTRA_LIBS ${EXTRA_LIBS} Crypt32)
endif()
find_package(OpenSSL)
if (OPENSSL_FOUND)
set(TLS_SOURCES src/common/net/Tls.h src/common/net/Tls.cpp)
include_directories(${OPENSSL_INCLUDE_DIR})
else()
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
endif()
else()
set(TLS_SOURCES "")
set(OPENSSL_LIBRARIES "")
add_definitions(/DXMRIG_NO_TLS)
endif()

27
cmake/asm.cmake Normal file
View file

@ -0,0 +1,27 @@
if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
set(XMRIG_ASM_LIBRARY "xmrig-asm")
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
enable_language(ASM_MASM)
set(XMRIG_ASM_FILE "src/crypto/asm/cnv2_main_loop.asm")
set_property(SOURCE ${XMRIG_ASM_FILE} PROPERTY ASM_MASM)
else()
enable_language(ASM)
if (WIN32 AND CMAKE_C_COMPILER_ID MATCHES GNU)
set(XMRIG_ASM_FILE "src/crypto/asm/cnv2_main_loop_win.S")
else()
set(XMRIG_ASM_FILE "src/crypto/asm/cnv2_main_loop.S")
endif()
set_property(SOURCE ${XMRIG_ASM_FILE} PROPERTY C)
endif()
add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILE})
set(XMRIG_ASM_SOURCES src/crypto/Asm.h src/crypto/Asm.cpp)
set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C)
else()
set(XMRIG_ASM_SOURCES "")
set(XMRIG_ASM_LIBRARY "")
add_definitions(/DXMRIG_NO_ASM)
endif()

View file

@ -15,7 +15,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-class-memaccess")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s")
if (XMRIG_ARMv8) if (XMRIG_ARMv8)

File diff suppressed because it is too large Load diff

View file

@ -1,53 +1,71 @@
/* /*
* Copyright 2008 Veselin Georgiev, * Copyright 2008 Veselin Georgiev,
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail) * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __ASM_BITS_H__ #ifndef __ASM_BITS_H__
#define __ASM_BITS_H__ #define __ASM_BITS_H__
#include "libcpuid.h" #include "libcpuid.h"
/* Determine Compiler: */ /* Determine Compiler: */
#if defined(_MSC_VER) #if defined(_MSC_VER)
# define COMPILER_MICROSOFT #if !defined(COMPILER_MICROSOFT)
#elif defined(__GNUC__) # define COMPILER_MICROSOFT
# define COMPILER_GCC #endif
#endif #elif defined(__GNUC__)
#if !defined(COMPILER_GCC)
/* Determine Platform */ # define COMPILER_GCC
#if defined(__x86_64__) || defined(_M_AMD64) #endif
# define PLATFORM_X64 #elif defined(__clang__)
#elif defined(__i386__) || defined(_M_IX86) #if !defined(COMPILER_CLANG)
# define PLATFORM_X86 # define COMPILER_CLANG
#endif #endif
#endif
/* Under Windows/AMD64 with MSVC, inline assembly isn't supported */
#if (defined(COMPILER_GCC) && defined(PLATFORM_X64)) || defined(PLATFORM_X86) /* Determine Platform */
# define INLINE_ASM_SUPPORTED #if defined(__x86_64__) || defined(_M_AMD64)
#endif #if !defined(PLATFORM_X64)
# define PLATFORM_X64
int cpuid_exists_by_eflags(void); #endif
void exec_cpuid(uint32_t *regs); #elif defined(__i386__) || defined(_M_IX86)
void busy_sse_loop(int cycles); #if !defined(PLATFORM_X86)
# define PLATFORM_X86
#endif /* __ASM_BITS_H__ */ #endif
#elif defined(__ARMEL__)
#if !defined(PLATFORM_ARM)
# define PLATFORM_ARM
#endif
#endif
/* Under Windows/AMD64 with MSVC, inline assembly isn't supported */
#if (((defined(COMPILER_GCC) || defined(COMPILER_CLANG))) && \
(defined(PLATFORM_X64) || defined(PLATFORM_X86) || defined(PLATFORM_ARM))) || \
(defined(COMPILER_MICROSOFT) && defined(PLATFORM_X86))
# define INLINE_ASM_SUPPORTED
#endif
int cpuid_exists_by_eflags(void);
void exec_cpuid(uint32_t *regs);
void busy_sse_loop(int cycles);
#endif /* __ASM_BITS_H__ */

View file

@ -221,42 +221,42 @@ static void load_features_common(struct cpu_raw_data_t* raw, struct cpu_id_t* da
static cpu_vendor_t cpuid_vendor_identify(const uint32_t *raw_vendor, char *vendor_str) static cpu_vendor_t cpuid_vendor_identify(const uint32_t *raw_vendor, char *vendor_str)
{ {
int i; int i;
cpu_vendor_t vendor = VENDOR_UNKNOWN; cpu_vendor_t vendor = VENDOR_UNKNOWN;
const struct { cpu_vendor_t vendor; char match[16]; } const struct { cpu_vendor_t vendor; char match[16]; }
matchtable[NUM_CPU_VENDORS] = { matchtable[NUM_CPU_VENDORS] = {
/* source: http://www.sandpile.org/ia32/cpuid.htm */ /* source: http://www.sandpile.org/ia32/cpuid.htm */
{ VENDOR_INTEL , "GenuineIntel" }, { VENDOR_INTEL , "GenuineIntel" },
{ VENDOR_AMD , "AuthenticAMD" }, { VENDOR_AMD , "AuthenticAMD" },
{ VENDOR_CYRIX , "CyrixInstead" }, { VENDOR_CYRIX , "CyrixInstead" },
{ VENDOR_NEXGEN , "NexGenDriven" }, { VENDOR_NEXGEN , "NexGenDriven" },
{ VENDOR_TRANSMETA , "GenuineTMx86" }, { VENDOR_TRANSMETA , "GenuineTMx86" },
{ VENDOR_UMC , "UMC UMC UMC " }, { VENDOR_UMC , "UMC UMC UMC " },
{ VENDOR_CENTAUR , "CentaurHauls" }, { VENDOR_CENTAUR , "CentaurHauls" },
{ VENDOR_RISE , "RiseRiseRise" }, { VENDOR_RISE , "RiseRiseRise" },
{ VENDOR_SIS , "SiS SiS SiS " }, { VENDOR_SIS , "SiS SiS SiS " },
{ VENDOR_NSC , "Geode by NSC" }, { VENDOR_NSC , "Geode by NSC" },
}; };
memcpy(vendor_str + 0, &raw_vendor[1], 4); memcpy(vendor_str + 0, &raw_vendor[1], 4);
memcpy(vendor_str + 4, &raw_vendor[3], 4); memcpy(vendor_str + 4, &raw_vendor[3], 4);
memcpy(vendor_str + 8, &raw_vendor[2], 4); memcpy(vendor_str + 8, &raw_vendor[2], 4);
vendor_str[12] = 0; vendor_str[12] = 0;
/* Determine vendor: */ /* Determine vendor: */
for (i = 0; i < NUM_CPU_VENDORS; i++) for (i = 0; i < NUM_CPU_VENDORS; i++)
if (!strcmp(vendor_str, matchtable[i].match)) { if (!strcmp(vendor_str, matchtable[i].match)) {
vendor = matchtable[i].vendor; vendor = matchtable[i].vendor;
break; break;
} }
return vendor; return vendor;
} }
static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{ {
int i, j, basic, xmodel, xfamily, ext; int i, j, basic, xmodel, xfamily, ext;
char brandstr[64] = {0}; char brandstr[64] = {0};
data->vendor = cpuid_vendor_identify(raw->basic_cpuid[0], data->vendor_str); data->vendor = cpuid_vendor_identify(raw->basic_cpuid[0], data->vendor_str);
if (data->vendor == VENDOR_UNKNOWN) if (data->vendor == VENDOR_UNKNOWN)
return set_error(ERR_CPU_UNKN); return set_error(ERR_CPU_UNKN);

View file

@ -60,7 +60,7 @@
*/ */
/** @mainpage A simple libcpuid introduction /** @mainpage A simple libcpuid introduction
* *
* LibCPUID provides CPU identification and access to the CPUID and RDTSC * LibCPUID provides CPU identification and access to the CPUID and RDTSC
* instructions on the x86. * instructions on the x86.
* <p> * <p>
@ -82,6 +82,7 @@
*/ */
/** @defgroup libcpuid LibCPUID /** @defgroup libcpuid LibCPUID
* @brief LibCPUID provides CPU identification
@{ */ @{ */
/* Include some integer type specifications: */ /* Include some integer type specifications: */
@ -535,23 +536,23 @@ typedef enum {
* @brief Describes common library error codes * @brief Describes common library error codes
*/ */
typedef enum { typedef enum {
ERR_OK = 0, /*!< "No error" */ ERR_OK = 0, /*!< No error */
ERR_NO_CPUID = -1, /*!< "CPUID instruction is not supported" */ ERR_NO_CPUID = -1, /*!< CPUID instruction is not supported */
ERR_NO_RDTSC = -2, /*!< "RDTSC instruction is not supported" */ ERR_NO_RDTSC = -2, /*!< RDTSC instruction is not supported */
ERR_NO_MEM = -3, /*!< "Memory allocation failed" */ ERR_NO_MEM = -3, /*!< Memory allocation failed */
ERR_OPEN = -4, /*!< "File open operation failed" */ ERR_OPEN = -4, /*!< File open operation failed */
ERR_BADFMT = -5, /*!< "Bad file format" */ ERR_BADFMT = -5, /*!< Bad file format */
ERR_NOT_IMP = -6, /*!< "Not implemented" */ ERR_NOT_IMP = -6, /*!< Not implemented */
ERR_CPU_UNKN = -7, /*!< "Unsupported processor" */ ERR_CPU_UNKN = -7, /*!< Unsupported processor */
ERR_NO_RDMSR = -8, /*!< "RDMSR instruction is not supported" */ ERR_NO_RDMSR = -8, /*!< RDMSR instruction is not supported */
ERR_NO_DRIVER= -9, /*!< "RDMSR driver error (generic)" */ ERR_NO_DRIVER= -9, /*!< RDMSR driver error (generic) */
ERR_NO_PERMS = -10, /*!< "No permissions to install RDMSR driver" */ ERR_NO_PERMS = -10, /*!< No permissions to install RDMSR driver */
ERR_EXTRACT = -11, /*!< "Cannot extract RDMSR driver (read only media?)" */ ERR_EXTRACT = -11, /*!< Cannot extract RDMSR driver (read only media?) */
ERR_HANDLE = -12, /*!< "Bad handle" */ ERR_HANDLE = -12, /*!< Bad handle */
ERR_INVMSR = -13, /*!< "Invalid MSR" */ ERR_INVMSR = -13, /*!< Invalid MSR */
ERR_INVCNB = -14, /*!< "Invalid core number" */ ERR_INVCNB = -14, /*!< Invalid core number */
ERR_HANDLE_R = -15, /*!< "Error on handle read" */ ERR_HANDLE_R = -15, /*!< Error on handle read */
ERR_INVRANGE = -16, /*!< "Invalid given range" */ ERR_INVRANGE = -16, /*!< Invalid given range */
} cpu_error_t; } cpu_error_t;
/** /**
@ -668,7 +669,7 @@ struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw);
const char* cpuid_lib_version(void); const char* cpuid_lib_version(void);
#ifdef __cplusplus #ifdef __cplusplus
}; /* extern "C" */ } /* extern "C" */
#endif #endif

View file

@ -75,8 +75,9 @@ enum _intel_bits_t {
_3 = LBIT( 14 ), _3 = LBIT( 14 ),
_5 = LBIT( 15 ), _5 = LBIT( 15 ),
_7 = LBIT( 16 ), _7 = LBIT( 16 ),
XEON_ = LBIT( 17 ), _9 = LBIT( 17 ),
ATOM_ = LBIT( 18 ), XEON_ = LBIT( 18 ),
ATOM_ = LBIT( 19 ),
}; };
typedef enum _intel_bits_t intel_bits_t; typedef enum _intel_bits_t intel_bits_t;

View file

@ -32,6 +32,32 @@
#ifndef __LIBCPUID_TYPES_H__ #ifndef __LIBCPUID_TYPES_H__
#define __LIBCPUID_TYPES_H__ #define __LIBCPUID_TYPES_H__
#include <stdint.h> #if !defined(_MSC_VER) || _MSC_VER >= 1600
# include <stdint.h>
#else
/* we have to provide our own: */
# if !defined(__int32_t_defined)
typedef int int32_t;
# endif
# if !defined(__uint32_t_defined)
typedef unsigned uint32_t;
# endif
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
#if (defined _MSC_VER) && (_MSC_VER <= 1300)
/* MSVC 6.0: no long longs ... */
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
/* all other sane compilers: */
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#endif
#endif
#endif /* __LIBCPUID_TYPES_H__ */ #endif /* __LIBCPUID_TYPES_H__ */

View file

@ -49,6 +49,10 @@ enum _amd_model_codes_t {
_1400, _1400,
_1500, _1500,
_1600, _1600,
_1900,
_2400,
_2500,
_2700,
}; };
static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data) static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)

View file

@ -376,7 +376,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
bits |= bit_matchtable[i].bit; bits |= bit_matchtable[i].bit;
} }
if ((i = match_pattern(bs, "Core(TM) [im][357]")) != 0) { if ((i = match_pattern(bs, "Core(TM) [im][3579]")) != 0) {
bits |= CORE_; bits |= CORE_;
i--; i--;
switch (bs[i + 9]) { switch (bs[i + 9]) {
@ -387,6 +387,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
case '3': bits |= _3; break; case '3': bits |= _3; break;
case '5': bits |= _5; break; case '5': bits |= _5; break;
case '7': bits |= _7; break; case '7': bits |= _7; break;
case '9': bits |= _9; break;
} }
} }
for (i = 0; i < COUNT_OF(matchtable); i++) for (i = 0; i < COUNT_OF(matchtable); i++)

View file

@ -29,11 +29,11 @@
#include "api/Api.h" #include "api/Api.h"
#include "App.h" #include "App.h"
#include "common/Console.h" #include "common/Console.h"
#include "common/cpu/Cpu.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h"
#include "crypto/CryptoNight.h" #include "crypto/CryptoNight.h"
#include "Mem.h" #include "Mem.h"
#include "net/Network.h" #include "net/Network.h"

View file

@ -27,32 +27,31 @@
#include <uv.h> #include <uv.h>
#include "common/cpu/Cpu.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/Pool.h" #include "common/net/Pool.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h" #include "crypto/Asm.h"
#include "Mem.h" #include "Mem.h"
#include "Summary.h" #include "Summary.h"
#include "version.h" #include "version.h"
static void print_versions(xmrig::Config *config) #ifndef XMRIG_NO_ASM
static const char *coloredAsmNames[] = {
"\x1B[1;31mnone\x1B[0m",
"auto",
"\x1B[1;32mintel\x1B[0m",
"\x1B[1;32mryzen\x1B[0m"
};
inline static const char *asmName(xmrig::Assembly assembly, bool colors)
{ {
char buf[16] = { 0 }; return colors ? coloredAsmNames[assembly] : xmrig::Asm::toString(assembly);
# if defined(__clang__)
snprintf(buf, 16, " clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
# elif defined(__GNUC__)
snprintf(buf, 16, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif defined(_MSC_VER)
snprintf(buf, 16, " MSVC/%d", MSVC_VERSION);
# endif
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" libuv/%s%s")
: " * %-13s%s/%s libuv/%s%s",
"VERSIONS", APP_NAME, APP_VERSION, uv_version_string(), buf);
} }
#endif
static void print_memory(xmrig::Config *config) { static void print_memory(xmrig::Config *config) {
@ -70,21 +69,23 @@ static void print_memory(xmrig::Config *config) {
static void print_cpu(xmrig::Config *config) static void print_cpu(xmrig::Config *config)
{ {
using namespace xmrig;
if (config->isColors()) { if (config->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s (%d) %sx64 %sAES-NI", Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES",
"CPU", "CPU",
Cpu::brand(), Cpu::info()->brand(),
Cpu::sockets(), Cpu::info()->sockets(),
Cpu::isX64() ? "\x1B[1;32m" : "\x1B[1;31m-", Cpu::info()->isX64() ? "\x1B[1;32m" : "\x1B[1;31m-",
Cpu::hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-"); Cpu::info()->hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-");
# ifndef XMRIG_NO_LIBCPUID # ifndef XMRIG_NO_LIBCPUID
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%.1f MB/%.1f MB", "CPU L2/L3", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
# endif # endif
} }
else { else {
Log::i()->text(" * %-13s%s (%d) %sx64 %sAES-NI", "CPU", Cpu::brand(), Cpu::sockets(), Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-"); Log::i()->text(" * %-13s%s (%d) %sx64 %sAES", "CPU", Cpu::info()->brand(), Cpu::info()->sockets(), Cpu::info()->isX64() ? "" : "-", Cpu::info()->hasAES() ? "" : "-");
# ifndef XMRIG_NO_LIBCPUID # ifndef XMRIG_NO_LIBCPUID
Log::i()->text(" * %-13s%.1f MB/%.1f MB", "CPU L2/L3", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); Log::i()->text(" * %-13s%.1f MB/%.1f MB", "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
# endif # endif
} }
} }
@ -117,45 +118,21 @@ static void print_threads(xmrig::Config *config)
config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "", config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel()); config->donateLevel());
} }
}
# ifndef XMRIG_NO_ASM
if (config->assembly() == xmrig::ASM_AUTO) {
const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly();
static void print_pools(xmrig::Config *config) Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s")
{ : " * %-13sauto:%s", "ASSEMBLY", asmName(assembly, config->isColors()));
const std::vector<Pool> &pools = config->pools();
for (size_t i = 0; i < pools.size(); ++i) {
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CYAN_BOLD("%s") " variant " WHITE_BOLD("%s")
: " * POOL #%-7d%s variant %s",
i + 1,
pools[i].url(),
pools[i].algorithm().variantName()
);
} }
else {
# ifdef APP_DEBUG Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s") : " * %-13s%s", "ASSEMBLY", asmName(config->assembly(), config->isColors()));
for (const Pool &pool : pools) {
pool.print();
} }
# endif # endif
} }
#ifndef XMRIG_NO_API
static void print_api(xmrig::Config *config)
{
const int port = config->apiPort();
if (port == 0) {
return;
}
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN("%s:") CYAN_BOLD("%d")
: " * %-13s%s:%d",
"API BIND", config->isApiIPv6() ? "[::]" : "0.0.0.0", port);
}
#endif
static void print_commands(xmrig::Config *config) static void print_commands(xmrig::Config *config)
{ {
if (config->isColors()) { if (config->isColors()) {
@ -171,15 +148,12 @@ static void print_commands(xmrig::Config *config)
void Summary::print(xmrig::Controller *controller) void Summary::print(xmrig::Controller *controller)
{ {
print_versions(controller->config()); controller->config()->printVersions();
print_memory(controller->config()); print_memory(controller->config());
print_cpu(controller->config()); print_cpu(controller->config());
print_threads(controller->config()); print_threads(controller->config());
print_pools(controller->config()); controller->config()->printPools();
controller->config()->printAPI();
# ifndef XMRIG_NO_API
print_api(controller->config());
# endif
print_commands(controller->config()); print_commands(controller->config());
} }

View file

@ -35,14 +35,13 @@
#include "api/ApiRouter.h" #include "api/ApiRouter.h"
#include "common/api/HttpReply.h" #include "common/api/HttpReply.h"
#include "common/api/HttpRequest.h" #include "common/api/HttpRequest.h"
#include "common/cpu/Cpu.h"
#include "common/crypto/keccak.h" #include "common/crypto/keccak.h"
#include "common/net/Job.h" #include "common/net/Job.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h"
#include "interfaces/IThread.h" #include "interfaces/IThread.h"
#include "Mem.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h" #include "rapidjson/stringbuffer.h"
@ -67,7 +66,7 @@ ApiRouter::ApiRouter(xmrig::Controller *controller) :
memset(m_workerId, 0, sizeof(m_workerId)); memset(m_workerId, 0, sizeof(m_workerId));
setWorkerId(controller->config()->apiWorkerId()); setWorkerId(controller->config()->apiWorkerId());
genId(); genId(controller->config()->apiId());
} }
@ -145,10 +144,15 @@ void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) cons
} }
void ApiRouter::genId() void ApiRouter::genId(const char *id)
{ {
memset(m_id, 0, sizeof(m_id)); memset(m_id, 0, sizeof(m_id));
if (id && strlen(id) > 0) {
strncpy(m_id, id, sizeof(m_id) - 1);
return;
}
uv_interface_address_t *interfaces; uv_interface_address_t *interfaces;
int count = 0; int count = 0;
@ -160,11 +164,13 @@ void ApiRouter::genId()
if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) { if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
uint8_t hash[200]; uint8_t hash[200];
const size_t addrSize = sizeof(interfaces[i].phys_addr); const size_t addrSize = sizeof(interfaces[i].phys_addr);
const size_t inSize = strlen(APP_KIND) + addrSize; const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t);
const uint16_t port = static_cast<uint16_t>(m_controller->config()->apiPort());
uint8_t *input = new uint8_t[inSize](); uint8_t *input = new uint8_t[inSize]();
memcpy(input, interfaces[i].phys_addr, addrSize); memcpy(input, &port, sizeof(uint16_t));
memcpy(input + addrSize, APP_KIND, strlen(APP_KIND)); memcpy(input + sizeof(uint16_t), interfaces[i].phys_addr, addrSize);
memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND));
xmrig::keccak(input, inSize, hash); xmrig::keccak(input, inSize, hash);
Job::toHex(hash, 8, m_id); Job::toHex(hash, 8, m_id);
@ -232,13 +238,14 @@ void ApiRouter::getIdentify(rapidjson::Document &doc) const
void ApiRouter::getMiner(rapidjson::Document &doc) const void ApiRouter::getMiner(rapidjson::Document &doc) const
{ {
using namespace xmrig;
auto &allocator = doc.GetAllocator(); auto &allocator = doc.GetAllocator();
rapidjson::Value cpu(rapidjson::kObjectType); rapidjson::Value cpu(rapidjson::kObjectType);
cpu.AddMember("brand", rapidjson::StringRef(Cpu::brand()), allocator); cpu.AddMember("brand", rapidjson::StringRef(Cpu::info()->brand()), allocator);
cpu.AddMember("aes", Cpu::hasAES(), allocator); cpu.AddMember("aes", Cpu::info()->hasAES(), allocator);
cpu.AddMember("x64", Cpu::isX64(), allocator); cpu.AddMember("x64", Cpu::info()->isX64(), allocator);
cpu.AddMember("sockets", Cpu::sockets(), allocator); cpu.AddMember("sockets", Cpu::info()->sockets(), allocator);
doc.AddMember("version", APP_VERSION, allocator); doc.AddMember("version", APP_VERSION, allocator);
doc.AddMember("kind", APP_KIND, allocator); doc.AddMember("kind", APP_KIND, allocator);

View file

@ -56,7 +56,7 @@ protected:
private: private:
void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const; void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const;
void genId(); void genId(const char *id);
void getConnection(rapidjson::Document &doc) const; void getConnection(rapidjson::Document &doc) const;
void getHashrate(rapidjson::Document &doc) const; void getHashrate(rapidjson::Document &doc) const;
void getIdentify(rapidjson::Document &doc) const; void getIdentify(rapidjson::Document &doc) const;
@ -66,7 +66,7 @@ private:
void setWorkerId(const char *id); void setWorkerId(const char *id);
void updateWorkerId(const char *id, const char *previousId); void updateWorkerId(const char *id, const char *previousId);
char m_id[17]; char m_id[32];
char m_workerId[128]; char m_workerId[128];
NetworkState m_network; NetworkState m_network;
xmrig::Controller *m_controller; xmrig::Controller *m_controller;

View file

@ -26,6 +26,12 @@
#include <uv.h> #include <uv.h>
#ifndef XMRIG_NO_TLS
# include <openssl/ssl.h>
# include <openssl/err.h>
#endif
#include "Platform.h" #include "Platform.h"
@ -61,3 +67,23 @@ const char *Platform::defaultConfigName()
*m_defaultConfigName = '\0'; *m_defaultConfigName = '\0';
return nullptr; return nullptr;
} }
void Platform::init(const char *userAgent)
{
# ifndef XMRIG_NO_TLS
SSL_library_init();
SSL_load_error_strings();
ERR_load_BIO_strings();
ERR_load_crypto_strings();
SSL_load_error_strings();
OpenSSL_add_all_digests();
# endif
if (userAgent) {
m_userAgent = userAgent;
}
else {
m_userAgent = createUserAgent();
}
}

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __PLATFORM_H__ #ifndef XMRIG_PLATFORM_H
#define __PLATFORM_H__ #define XMRIG_PLATFORM_H
#include <stdint.h> #include <stdint.h>
@ -43,9 +43,11 @@ public:
static inline const char *userAgent() { return m_userAgent.data(); } static inline const char *userAgent() { return m_userAgent.data(); }
private: private:
static char *createUserAgent();
static char m_defaultConfigName[520]; static char m_defaultConfigName[520];
static xmrig::c_str m_userAgent; static xmrig::c_str m_userAgent;
}; };
#endif /* __PLATFORM_H__ */ #endif /* XMRIG_PLATFORM_H */

View file

@ -38,7 +38,7 @@
#endif #endif
static inline char *createUserAgent() char *Platform::createUserAgent()
{ {
const size_t max = 160; const size_t max = 160;
@ -65,17 +65,6 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
} }
void Platform::init(const char *userAgent)
{
if (userAgent) {
m_userAgent = userAgent;
}
else {
m_userAgent = createUserAgent();
}
}
void Platform::setProcessPriority(int priority) void Platform::setProcessPriority(int priority)
{ {

View file

@ -52,7 +52,7 @@ typedef cpuset_t cpu_set_t;
#endif #endif
static inline char *createUserAgent() char *Platform::createUserAgent()
{ {
const size_t max = 160; const size_t max = 160;
@ -92,23 +92,11 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
} }
void Platform::init(const char *userAgent)
{
if (userAgent) {
m_userAgent = userAgent;
}
else {
m_userAgent = createUserAgent();
}
}
void Platform::setProcessPriority(int priority) void Platform::setProcessPriority(int priority)
{ {
} }
void Platform::setThreadPriority(int priority) void Platform::setThreadPriority(int priority)
{ {
if (priority == -1) { if (priority == -1) {

View file

@ -55,7 +55,7 @@ static inline OSVERSIONINFOEX winOsVersion()
} }
static inline char *createUserAgent() char *Platform::createUserAgent()
{ {
const auto osver = winOsVersion(); const auto osver = winOsVersion();
const size_t max = 160; const size_t max = 160;
@ -94,17 +94,6 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
} }
void Platform::init(const char *userAgent)
{
if (userAgent) {
m_userAgent = userAgent;
}
else {
m_userAgent = createUserAgent();
}
}
void Platform::setProcessPriority(int priority) void Platform::setProcessPriority(int priority)
{ {
if (priority == -1) { if (priority == -1) {

View file

@ -147,7 +147,7 @@ int xmrig::HttpRequest::end(int status, MHD_Response *rsp)
MHD_add_response_header(rsp, "Content-Type", "application/json"); 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-Origin", "*");
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET, PUT"); MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET, PUT");
MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization"); MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization, Content-Type");
const int ret = MHD_queue_response(m_connection, status, rsp); const int ret = MHD_queue_response(m_connection, status, rsp);
MHD_destroy_response(rsp); MHD_destroy_response(rsp);

View file

@ -29,12 +29,37 @@
#include <uv.h> #include <uv.h>
#ifndef XMRIG_NO_HTTPD
# include <microhttpd.h>
#endif
#ifndef XMRIG_NO_TLS
# include <openssl/opensslv.h>
#endif
#ifdef XMRIG_AMD_PROJECT
# if defined(__APPLE__)
# include <OpenCL/cl.h>
# else
# include "3rdparty/CL/cl.h"
# endif
#endif
#ifdef XMRIG_NVIDIA_PROJECT
# include "nvidia/cryptonight.h"
#endif
#include "common/config/CommonConfig.h" #include "common/config/CommonConfig.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "donate.h" #include "donate.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
#include "version.h"
xmrig::CommonConfig::CommonConfig() : xmrig::CommonConfig::CommonConfig() :
@ -42,6 +67,7 @@ xmrig::CommonConfig::CommonConfig() :
m_adjusted(false), m_adjusted(false),
m_apiIPv6(false), m_apiIPv6(false),
m_apiRestricted(true), m_apiRestricted(true),
m_autoSave(true),
m_background(false), m_background(false),
m_colors(true), m_colors(true),
m_dryRun(false), m_dryRun(false),
@ -69,8 +95,102 @@ xmrig::CommonConfig::CommonConfig() :
} }
xmrig::CommonConfig::~CommonConfig() void xmrig::CommonConfig::printAPI()
{ {
# ifndef XMRIG_NO_API
if (apiPort() == 0) {
return;
}
Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN("%s:") CYAN_BOLD("%d")
: " * %-13s%s:%d",
"API BIND", isApiIPv6() ? "[::]" : "0.0.0.0", apiPort());
# endif
}
void xmrig::CommonConfig::printPools()
{
for (size_t i = 0; i < m_activePools.size(); ++i) {
if (!isColors()) {
Log::i()->text(" * POOL #%-7zu%s variant=%s, TLS=%d",
i + 1,
m_activePools[i].url(),
m_activePools[i].algorithm().variantName(),
static_cast<int>(m_activePools[i].isTLS())
);
}
else {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") "\x1B[1;%dm%s\x1B[0m variant " WHITE_BOLD("%s"),
i + 1,
m_activePools[i].isTLS() ? 32 : 36,
m_activePools[i].url(),
m_activePools[i].algorithm().variantName()
);
}
}
# ifdef APP_DEBUG
LOG_NOTICE("POOLS --------------------------------------------------------------------");
for (const Pool &pool : m_activePools) {
pool.print();
}
LOG_NOTICE("--------------------------------------------------------------------------");
# endif
}
void xmrig::CommonConfig::printVersions()
{
char buf[256] = { 0 };
# if defined(__clang__)
snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
# elif defined(__GNUC__)
snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif defined(_MSC_VER)
snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION);
# endif
Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s")
: " * %-13s%s/%s %s",
"ABOUT", APP_NAME, APP_VERSION, buf);
# if defined(XMRIG_AMD_PROJECT)
# if CL_VERSION_2_0
const char *ocl = "2.0";
# elif CL_VERSION_1_2
const char *ocl = "1.2";
# elif CL_VERSION_1_1
const char *ocl = "1.1";
# elif CL_VERSION_1_0
const char *ocl = "1.0";
# else
const char *ocl = "0.0";
# endif
int length = snprintf(buf, sizeof buf, "OpenCL/%s ", ocl);
# elif defined(XMRIG_NVIDIA_PROJECT)
const int cudaVersion = cuda_get_runtime_version();
int length = snprintf(buf, sizeof buf, "CUDA/%d.%d ", cudaVersion / 1000, cudaVersion % 100);
# else
memset(buf, 0, 16);
int length = 0;
# endif
# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT)
{
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
length += snprintf(buf + length, (sizeof buf) - length, "OpenSSL/%.*s ", static_cast<int>(strchr(v, ' ') - v), v);
}
# endif
# ifndef XMRIG_NO_HTTPD
length += snprintf(buf + length, (sizeof buf) - length, "microhttpd/%s ", MHD_get_version());
# endif
Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s")
: " * %-13slibuv/%s %s",
"LIBS", uv_version_string(), buf);
} }
@ -98,7 +218,7 @@ bool xmrig::CommonConfig::save()
rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os); rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os);
doc.Accept(writer); doc.Accept(writer);
fclose(fp); fflush(fp);
uv_fs_close(uv_default_loop(), &req, fd, nullptr); uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
@ -126,6 +246,12 @@ bool xmrig::CommonConfig::finalize()
pool.adjust(m_algorithm); pool.adjust(m_algorithm);
if (pool.isValid() && pool.algorithm().isValid()) { if (pool.isValid() && pool.algorithm().isValid()) {
# ifdef XMRIG_NO_TLS
if (pool.isTLS()) {
continue;
}
# endif
m_activePools.push_back(std::move(pool)); m_activePools.push_back(std::move(pool));
} }
} }
@ -157,6 +283,10 @@ bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
m_pools.back().setKeepAlive(enable ? Pool::kKeepAliveTimeout : 0); m_pools.back().setKeepAlive(enable ? Pool::kKeepAliveTimeout : 0);
break; break;
case TlsKey: /* --tls */
m_pools.back().setTLS(enable);
break;
# ifndef XMRIG_PROXY_PROJECT # ifndef XMRIG_PROXY_PROJECT
case NicehashKey: /* --nicehash */ case NicehashKey: /* --nicehash */
m_pools.back().setNicehash(enable); m_pools.back().setNicehash(enable);
@ -179,10 +309,14 @@ bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
m_apiRestricted = enable; m_apiRestricted = enable;
break; break;
case IConfig::DryRunKey: /* --dry-run */ case DryRunKey: /* --dry-run */
m_dryRun = enable; m_dryRun = enable;
break; break;
case AutoSaveKey:
m_autoSave = enable;
break;
default: default:
break; break;
} }
@ -235,6 +369,10 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
m_pools.back().setRigId(arg); m_pools.back().setRigId(arg);
break; break;
case FingerprintKey: /* --tls-fingerprint */
m_pools.back().setFingerprint(arg);
break;
case VariantKey: /* --variant */ case VariantKey: /* --variant */
m_pools.back().algorithm().parseVariant(arg); m_pools.back().algorithm().parseVariant(arg);
break; break;
@ -251,6 +389,10 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
m_apiWorkerId = arg; m_apiWorkerId = arg;
break; break;
case ApiIdKey: /* --api-id */
m_apiId = arg;
break;
case UserAgentKey: /* --user-agent */ case UserAgentKey: /* --user-agent */
m_userAgent = arg; m_userAgent = arg;
break; break;
@ -265,6 +407,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
case SyslogKey: /* --syslog */ case SyslogKey: /* --syslog */
case KeepAliveKey: /* --keepalive */ case KeepAliveKey: /* --keepalive */
case NicehashKey: /* --nicehash */ case NicehashKey: /* --nicehash */
case TlsKey: /* --tls */
case ApiIPv6Key: /* --api-ipv6 */ case ApiIPv6Key: /* --api-ipv6 */
case DryRunKey: /* --dry-run */ case DryRunKey: /* --dry-run */
return parseBoolean(key, true); return parseBoolean(key, true);

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __COMMONCONFIG_H__ #ifndef XMRIG_COMMONCONFIG_H
#define __COMMONCONFIG_H__ #define XMRIG_COMMONCONFIG_H
#include <vector> #include <vector>
@ -41,14 +41,15 @@ class CommonConfig : public IConfig
{ {
public: public:
CommonConfig(); CommonConfig();
~CommonConfig();
inline bool isApiIPv6() const { return m_apiIPv6; } inline bool isApiIPv6() const { return m_apiIPv6; }
inline bool isApiRestricted() const { return m_apiRestricted; } inline bool isApiRestricted() const { return m_apiRestricted; }
inline bool isAutoSave() const { return m_autoSave; }
inline bool isBackground() const { return m_background; } inline bool isBackground() const { return m_background; }
inline bool isColors() const { return m_colors; } inline bool isColors() const { return m_colors; }
inline bool isDryRun() const { return m_dryRun; } inline bool isDryRun() const { return m_dryRun; }
inline bool isSyslog() const { return m_syslog; } inline bool isSyslog() const { return m_syslog; }
inline const char *apiId() const { return m_apiId.data(); }
inline const char *apiToken() const { return m_apiToken.data(); } inline const char *apiToken() const { return m_apiToken.data(); }
inline const char *apiWorkerId() const { return m_apiWorkerId.data(); } inline const char *apiWorkerId() const { return m_apiWorkerId.data(); }
inline const char *logFile() const { return m_logFile.data(); } inline const char *logFile() const { return m_logFile.data(); }
@ -67,6 +68,10 @@ public:
bool save() override; bool save() override;
void printAPI();
void printPools();
void printVersions();
protected: protected:
enum State { enum State {
NoneState, NoneState,
@ -84,6 +89,7 @@ protected:
bool m_adjusted; bool m_adjusted;
bool m_apiIPv6; bool m_apiIPv6;
bool m_apiRestricted; bool m_apiRestricted;
bool m_autoSave;
bool m_background; bool m_background;
bool m_colors; bool m_colors;
bool m_dryRun; bool m_dryRun;
@ -97,6 +103,7 @@ protected:
State m_state; State m_state;
std::vector<Pool> m_activePools; std::vector<Pool> m_activePools;
std::vector<Pool> m_pools; std::vector<Pool> m_pools;
xmrig::c_str m_apiId;
xmrig::c_str m_apiToken; xmrig::c_str m_apiToken;
xmrig::c_str m_apiWorkerId; xmrig::c_str m_apiWorkerId;
xmrig::c_str m_fileName; xmrig::c_str m_fileName;

View file

@ -32,6 +32,11 @@
#endif #endif
#ifndef XMRIG_NO_TLS
# include <openssl/opensslv.h>
#endif
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/config/ConfigWatcher.h" #include "common/config/ConfigWatcher.h"
#include "common/interfaces/IConfig.h" #include "common/interfaces/IConfig.h"
@ -313,6 +318,13 @@ void xmrig::ConfigLoader::showVersion()
printf("\nlibuv/%s\n", uv_version_string()); printf("\nlibuv/%s\n", uv_version_string());
# ifndef XMRIG_NO_HTTPD # ifndef XMRIG_NO_HTTPD
printf("libmicrohttpd/%s\n", MHD_get_version()); printf("microhttpd/%s\n", MHD_get_version());
# endif
# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT)
{
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
printf("OpenSSL/%.*s\n", static_cast<int>(strchr(v, ' ') - v), v);
}
# endif # endif
} }

View file

@ -21,6 +21,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h>
#include <thread>
#ifdef _MSC_VER #ifdef _MSC_VER
# include <intrin.h> # include <intrin.h>
@ -32,14 +35,8 @@
# define bit_AES (1 << 25) # define bit_AES (1 << 25)
#endif #endif
#ifndef bit_BMI2
# define bit_BMI2 (1 << 8)
#endif
#include <string.h> #include "common/cpu/BasicCpuInfo.h"
#include "Cpu.h"
#define VENDOR_ID (0) #define VENDOR_ID (0)
@ -96,43 +93,18 @@ static inline bool has_aes_ni()
} }
static inline bool has_bmi2() { xmrig::BasicCpuInfo::BasicCpuInfo() :
int cpu_info[4] = { 0 }; m_aes(has_aes_ni()),
cpuid(EXTENDED_FEATURES, cpu_info); m_brand(),
m_threads(std::thread::hardware_concurrency())
return (cpu_info[EBX_Reg] & bit_BMI2) != 0;
}
char Cpu::m_brand[64] = { 0 };
int Cpu::m_flags = 0;
int Cpu::m_l2_cache = 0;
int Cpu::m_l3_cache = 0;
int Cpu::m_sockets = 1;
int Cpu::m_totalCores = 0;
size_t Cpu::m_totalThreads = 0;
size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage)
{
const size_t count = m_totalThreads / 2;
return count < 1 ? 1 : count;
}
void Cpu::initCommon()
{ {
cpu_brand_string(m_brand); cpu_brand_string(m_brand);
}
# if defined(__x86_64__) || defined(_M_AMD64)
m_flags |= X86_64;
# endif size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
{
if (has_aes_ni()) { const size_t count = threads() / 2;
m_flags |= AES;
} return count < 1 ? 1 : count;
if (has_bmi2()) {
m_flags |= BMI2;
}
} }

View file

@ -0,0 +1,70 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_BASICCPUINFO_H
#define XMRIG_BASICCPUINFO_H
#include "common/interfaces/ICpuInfo.h"
namespace xmrig {
class BasicCpuInfo : public ICpuInfo
{
public:
BasicCpuInfo();
protected:
size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override;
inline Assembly assembly() const override { return ASM_NONE; }
inline bool hasAES() const override { return m_aes; }
inline bool isSupported() const override { return true; }
inline const char *brand() const override { return m_brand; }
inline int32_t cores() const override { return -1; }
inline int32_t L2() const override { return -1; }
inline int32_t L3() const override { return -1; }
inline int32_t nodes() const override { return -1; }
inline int32_t sockets() const override { return 1; }
inline int32_t threads() const override { return m_threads; }
# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__)
inline bool isX64() const override { return true; }
# else
inline bool isX64() const override { return false; }
# endif
private:
bool m_aes;
char m_brand[64];
int32_t m_threads;
};
} /* namespace xmrig */
#endif /* XMRIG_BASICCPUINFO_H */

View file

@ -21,37 +21,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h> #include <string.h>
#include <thread>
#include "Cpu.h" #include "common/cpu/BasicCpuInfo.h"
char Cpu::m_brand[64] = { 0 }; xmrig::BasicCpuInfo::BasicCpuInfo() :
int Cpu::m_flags = 0; m_aes(false),
int Cpu::m_l2_cache = 0; m_brand(),
int Cpu::m_l3_cache = 0; m_threads(std::thread::hardware_concurrency())
int Cpu::m_sockets = 1;
int Cpu::m_totalCores = 0;
size_t Cpu::m_totalThreads = 0;
size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage)
{
return m_totalThreads;
}
void Cpu::initCommon()
{ {
memcpy(m_brand, "Unknown", 7); memcpy(m_brand, "Unknown", 7);
# if defined (__arm64__) || defined (__aarch64__)
m_flags |= X86_64;
# endif
# if __ARM_FEATURE_CRYPTO # if __ARM_FEATURE_CRYPTO
m_flags |= AES; m_aes = true;
# endif # endif
} }
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
{
return threads();
}

View file

@ -22,33 +22,36 @@
*/ */
#ifdef __FreeBSD__ #include <assert.h>
# include <sys/types.h>
# include <sys/param.h>
# include <sys/cpuset.h>
# include <pthread_np.h>
#endif
#include <pthread.h> #include "common/cpu/BasicCpuInfo.h"
#include <sched.h> #include "common/cpu/Cpu.h"
#include <unistd.h>
#include <string.h>
#include "Cpu.h" static xmrig::ICpuInfo *cpuInfo = nullptr;
#ifdef __FreeBSD__ xmrig::ICpuInfo *xmrig::Cpu::info()
typedef cpuset_t cpu_set_t;
#endif
void Cpu::init()
{ {
# ifdef XMRIG_NO_LIBCPUID assert(cpuInfo != nullptr);
m_totalThreads = sysconf(_SC_NPROCESSORS_CONF);
# endif
initCommon(); return cpuInfo;
}
void xmrig::Cpu::init()
{
assert(cpuInfo == nullptr);
cpuInfo = new BasicCpuInfo();
}
void xmrig::Cpu::release()
{
assert(cpuInfo != nullptr);
delete cpuInfo;
cpuInfo = nullptr;
} }

View file

@ -4,7 +4,7 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -21,20 +21,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_CPU_H
#include <pthread.h> #define XMRIG_CPU_H
#include <sched.h>
#include <unistd.h>
#include "Cpu.h" #include "common/interfaces/ICpuInfo.h"
void Cpu::init() namespace xmrig {
class Cpu
{ {
# ifdef XMRIG_NO_LIBCPUID public:
m_totalThreads = sysconf(_SC_NPROCESSORS_CONF); static ICpuInfo *info();
# endif static void init();
static void release();
};
initCommon();
} } /* namespace xmrig */
#endif /* XMRIG_CPU_H */

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -60,6 +61,7 @@ static AlgoData const algorithms[] = {
{ "cryptonight/msr", "cn/msr", xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR }, { "cryptonight/msr", "cn/msr", xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR },
{ "cryptonight/xao", "cn/xao", xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO }, { "cryptonight/xao", "cn/xao", xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO },
{ "cryptonight/rto", "cn/rto", xmrig::CRYPTONIGHT, xmrig::VARIANT_RTO }, { "cryptonight/rto", "cn/rto", xmrig::CRYPTONIGHT, xmrig::VARIANT_RTO },
{ "cryptonight/2", "cn/2", xmrig::CRYPTONIGHT, xmrig::VARIANT_2 },
# ifndef XMRIG_NO_AEON # ifndef XMRIG_NO_AEON
{ "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO }, { "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO },
@ -81,6 +83,8 @@ static AlgoData const algorithms[] = {
static AlgoData const xmrStakAlgorithms[] = { static AlgoData const xmrStakAlgorithms[] = {
{ "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, { "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
{ "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, { "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
{ "cryptonight-monerov8", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_2 },
{ "cryptonight_v8", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_2 },
{ "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, { "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL },
{ "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, { "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 },
{ "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, { "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 },
@ -103,7 +107,8 @@ static const char *variants[] = {
"msr", "msr",
"xhv", "xhv",
"xao", "xao",
"rto" "rto",
"2",
}; };
@ -172,11 +177,21 @@ void xmrig::Algorithm::parseVariant(const char *variant)
void xmrig::Algorithm::parseVariant(int variant) void xmrig::Algorithm::parseVariant(int variant)
{ {
if (variant >= VARIANT_AUTO && variant < VARIANT_MAX) { assert(variant >= -1 && variant <= 2);
m_variant = static_cast<Variant>(variant);
} switch (variant) {
else { case -1:
assert(false); case 0:
case 1:
m_variant = static_cast<Variant>(variant);
break;
case 2:
m_variant = VARIANT_2;
break;
default:
break;
} }
} }

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -22,8 +23,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __ALGORITHM_H__ #ifndef XMRIG_ALGORITHM_H
#define __ALGORITHM_H__ #define XMRIG_ALGORITHM_H
#include <vector> #include <vector>

View file

@ -23,8 +23,8 @@
*/ */
#ifndef KECCAK_H_ #ifndef XMRIG_KECCAK_H
#define KECCAK_H_ #define XMRIG_KECCAK_H
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -41,9 +41,15 @@ inline void keccak(const uint8_t *in, size_t inlen, uint8_t *md)
keccak(in, static_cast<int>(inlen), md, 200); keccak(in, static_cast<int>(inlen), md, 200);
} }
inline void keccak(const char *in, size_t inlen, uint8_t *md)
{
keccak(reinterpret_cast<const uint8_t *>(in), static_cast<int>(inlen), md, 200);
}
// update the state // update the state
void keccakf(uint64_t st[25], int norounds); void keccakf(uint64_t st[25], int norounds);
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* KECCAK_H_ */ #endif /* XMRIG_KECCAK_H */

View file

@ -20,8 +20,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __ICONFIG_H__ #ifndef XMRIG_ICONFIG_H
#define __ICONFIG_H__ #define XMRIG_ICONFIG_H
#include "common/crypto/Algorithm.h" #include "common/crypto/Algorithm.h"
@ -42,6 +42,7 @@ public:
ApiPort = 4000, ApiPort = 4000,
ApiRestrictedKey = 4004, ApiRestrictedKey = 4004,
ApiWorkerIdKey = 4002, ApiWorkerIdKey = 4002,
ApiIdKey = 4005,
BackgroundKey = 'B', BackgroundKey = 'B',
ColorKey = 1002, ColorKey = 1002,
ConfigKey = 'c', ConfigKey = 'c',
@ -62,6 +63,9 @@ public:
VerboseKey = 1100, VerboseKey = 1100,
VersionKey = 'V', VersionKey = 'V',
WatchKey = 1105, WatchKey = 1105,
TlsKey = 1013,
FingerprintKey = 1014,
AutoSaveKey = 1016,
// xmrig common // xmrig common
CPUPriorityKey = 1021, CPUPriorityKey = 1021,
@ -77,12 +81,20 @@ public:
SafeKey = 1005, SafeKey = 1005,
ThreadsKey = 't', ThreadsKey = 't',
HardwareAESKey = 1011, HardwareAESKey = 1011,
AssemblyKey = 1015,
// xmrig amd // xmrig amd
OclPlatform = 1400, OclPlatformKey = 1400,
OclAffinity = 1401, OclAffinityKey = 1401,
OclDevices = 1402, OclDevicesKey = 1402,
OclLaunch = 1403, OclLaunchKey = 1403,
OclCacheKey = 1404,
OclPrintKey = 1405,
OclLoaderKey = 1406,
OclSridedIndexKey = 1407,
OclMemChunkKey = 1408,
OclUnrollKey = 1409,
OclCompModeKey = 1410,
// xmrig-proxy // xmrig-proxy
AccessLogFileKey = 'A', AccessLogFileKey = 'A',
@ -94,6 +106,16 @@ public:
PoolCoinKey = 'C', PoolCoinKey = 'C',
ReuseTimeoutKey = 1106, ReuseTimeoutKey = 1106,
WorkersKey = 1103, WorkersKey = 1103,
WorkersAdvKey = 1107,
// xmrig nvidia
CudaMaxThreadsKey = 1200,
CudaBFactorKey = 1201,
CudaBSleepKey = 1202,
CudaDevicesKey = 1203,
CudaLaunchKey = 1204,
CudaAffinityKey = 1205,
CudaMaxUsageKey = 1206,
}; };
virtual ~IConfig() {} virtual ~IConfig() {}
@ -115,4 +137,4 @@ public:
} /* namespace xmrig */ } /* namespace xmrig */
#endif // __ICONFIG_H__ #endif // XMRIG_ICONFIG_H

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __ICONTROLLERLISTENER_H__ #ifndef XMRIG_ICONTROLLERLISTENER_H
#define __ICONTROLLERLISTENER_H__ #define XMRIG_ICONTROLLERLISTENER_H
namespace xmrig { namespace xmrig {
@ -43,4 +43,4 @@ public:
} /* namespace xmrig */ } /* namespace xmrig */
#endif // __ICONTROLLERLISTENER_H__ #endif // XMRIG_ICONTROLLERLISTENER_H

View file

@ -0,0 +1,60 @@
/* 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 XMRIG_CPUINFO_H
#define XMRIG_CPUINFO_H
#include <stddef.h>
#include <stdint.h>
#include "common/xmrig.h"
namespace xmrig {
class ICpuInfo
{
public:
virtual ~ICpuInfo() {}
virtual bool hasAES() const = 0;
virtual bool isSupported() const = 0;
virtual bool isX64() const = 0;
virtual const char *brand() const = 0;
virtual int32_t cores() const = 0;
virtual int32_t L2() const = 0;
virtual int32_t L3() const = 0;
virtual int32_t nodes() const = 0;
virtual int32_t sockets() const = 0;
virtual int32_t threads() const = 0;
virtual size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const = 0;
virtual xmrig::Assembly assembly() const = 0;
};
} /* namespace xmrig */
#endif // XMRIG_CPUINFO_H

View file

@ -21,46 +21,69 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CPU_H__
#define __CPU_H__ #include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef WIN32
# include <winsock2.h>
# include <windows.h>
#endif
#include <stdint.h> #include "common/log/BasicLog.h"
#include "common/log/Log.h"
class Cpu BasicLog::BasicLog()
{ {
public: }
enum Flags {
X86_64 = 1,
AES = 2,
BMI2 = 4
};
static size_t optimalThreadsCount(size_t size, int maxCpuUsage);
static void init();
static inline bool hasAES() { return (m_flags & AES) != 0; }
static inline bool isX64() { return (m_flags & X86_64) != 0; }
static inline const char *brand() { return m_brand; }
static inline int cores() { return m_totalCores; }
static inline int l2() { return m_l2_cache; }
static inline int l3() { return m_l3_cache; }
static inline int sockets() { return m_sockets; }
static inline int threads() { return m_totalThreads; }
private:
static void initCommon();
static bool m_l2_exclusive;
static char m_brand[64];
static int m_flags;
static int m_l2_cache;
static int m_l3_cache;
static int m_sockets;
static int m_totalCores;
static size_t m_totalThreads;
};
#endif /* __CPU_H__ */ void BasicLog::message(Level level, const char* fmt, va_list args)
{
time_t now = time(nullptr);
tm stime;
# ifdef _WIN32
localtime_s(&stime, &now);
# else
localtime_r(&now, &stime);
# endif
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
stime.tm_hour,
stime.tm_min,
stime.tm_sec,
Log::colorByLevel(level, false),
fmt,
Log::endl(false)
);
print(args);
}
void BasicLog::text(const char* fmt, va_list args)
{
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(false));
print(args);
}
void BasicLog::print(va_list args)
{
if (vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args) <= 0) {
return;
}
fputs(m_buf, stdout);
fflush(stdout);
}

55
src/common/log/BasicLog.h Normal file
View file

@ -0,0 +1,55 @@
/* 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 __BASICLOG_H__
#define __BASICLOG_H__
#include <uv.h>
#include "common/interfaces/ILogBackend.h"
namespace xmrig {
class Controller;
}
class BasicLog : public ILogBackend
{
public:
BasicLog();
void message(Level level, const char *fmt, va_list args) override;
void text(const char *fmt, va_list args) override;
private:
bool isWritable() const;
void print(va_list args);
char m_buf[kBufferSize];
char m_fmt[256];
};
#endif /* __BASICLOG_H__ */

View file

@ -30,6 +30,7 @@
#include "common/interfaces/ILogBackend.h" #include "common/interfaces/ILogBackend.h"
#include "common/log/BasicLog.h"
#include "common/log/Log.h" #include "common/log/Log.h"
@ -109,6 +110,14 @@ const char *Log::endl(bool isColors)
} }
void Log::defaultInit()
{
m_self = new Log();
add(new BasicLog());
}
Log::~Log() Log::~Log()
{ {
for (auto backend : m_backends) { for (auto backend : m_backends) {

View file

@ -36,7 +36,7 @@
class Log class Log
{ {
public: public:
static inline Log* i() { assert(m_self != nullptr); return m_self; } static inline Log* i() { if (!m_self) { defaultInit(); } return m_self; }
static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); } static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); }
static inline void init() { if (!m_self) { new Log(); } } static inline void init() { if (!m_self) { new Log(); } }
static inline void release() { assert(m_self != nullptr); delete m_self; } static inline void release() { assert(m_self != nullptr); delete m_self; }
@ -46,6 +46,7 @@ public:
static const char *colorByLevel(ILogBackend::Level level, bool isColors = true); static const char *colorByLevel(ILogBackend::Level level, bool isColors = true);
static const char *endl(bool isColors = true); static const char *endl(bool isColors = true);
static void defaultInit();
private: private:
inline Log() { inline Log() {
@ -68,6 +69,8 @@ private:
#define RED(x) "\x1B[0;31m" x "\x1B[0m" #define RED(x) "\x1B[0;31m" x "\x1B[0m"
#define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m" #define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m"
#define GREEN(x) "\x1B[0;32m" x "\x1B[0m" #define GREEN(x) "\x1B[0;32m" x "\x1B[0m"
#define YELLOW(x) "\x1B[0;33m" x "\x1B[0m"
#define YELLOW_BOLD(x) "\x1B[1;33m" x "\x1B[0m"
#define MAGENTA_BOLD(x) "\x1B[1;35m" x "\x1B[0m" #define MAGENTA_BOLD(x) "\x1B[1;35m" x "\x1B[0m"
#define MAGENTA(x) "\x1B[0;35m" x "\x1B[0m" #define MAGENTA(x) "\x1B[0;35m" x "\x1B[0m"
#define CYAN_BOLD(x) "\x1B[1;36m" x "\x1B[0m" #define CYAN_BOLD(x) "\x1B[1;36m" x "\x1B[0m"

View file

@ -29,6 +29,13 @@
#include <utility> #include <utility>
#ifndef XMRIG_NO_TLS
# include <openssl/ssl.h>
# include <openssl/err.h>
# include "common/net/Tls.h"
#endif
#include "common/interfaces/IClientListener.h" #include "common/interfaces/IClientListener.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/Client.h" #include "common/net/Client.h"
@ -48,6 +55,17 @@ int64_t Client::m_sequence = 1;
xmrig::Storage<Client> Client::m_storage; xmrig::Storage<Client> Client::m_storage;
#ifdef APP_DEBUG
static const char *states[] = {
"unconnected",
"host-lookup",
"connecting",
"connected",
"closing"
};
#endif
Client::Client(int id, const char *agent, IClientListener *listener) : Client::Client(int id, const char *agent, IClientListener *listener) :
m_ipv6(false), m_ipv6(false),
m_nicehash(false), m_nicehash(false),
@ -61,6 +79,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_failures(0), m_failures(0),
m_recvBufPos(0), m_recvBufPos(0),
m_state(UnconnectedState), m_state(UnconnectedState),
m_tls(nullptr),
m_expire(0), m_expire(0),
m_jobs(0), m_jobs(0),
m_keepAlive(0), m_keepAlive(0),
@ -92,6 +111,12 @@ Client::~Client()
void Client::connect() void Client::connect()
{ {
# ifndef XMRIG_NO_TLS
if (m_pool.isTLS()) {
m_tls = new Tls(this);
}
# endif
resolve(m_pool.host()); resolve(m_pool.host());
} }
@ -122,6 +147,7 @@ void Client::deleteLater()
} }
void Client::setPool(const Pool &pool) void Client::setPool(const Pool &pool)
{ {
if (!pool.isValid()) { if (!pool.isValid()) {
@ -160,6 +186,30 @@ bool Client::disconnect()
} }
const char *Client::tlsFingerprint() const
{
# ifndef XMRIG_NO_TLS
if (isTLS() && m_pool.fingerprint() == nullptr) {
return m_tls->fingerprint();
}
# endif
return nullptr;
}
const char *Client::tlsVersion() const
{
# ifndef XMRIG_NO_TLS
if (isTLS()) {
return m_tls->version();
}
# endif
return nullptr;
}
int64_t Client::submit(const JobResult &result) int64_t Client::submit(const JobResult &result)
{ {
using namespace rapidjson; using namespace rapidjson;
@ -245,6 +295,16 @@ bool Client::isCriticalError(const char *message)
} }
bool Client::isTLS() const
{
# ifndef XMRIG_NO_TLS
return m_pool.isTLS() && m_tls;
# else
return false;
# endif
}
bool Client::parseJob(const rapidjson::Value &params, int *code) bool Client::parseJob(const rapidjson::Value &params, int *code)
{ {
if (!params.IsObject()) { if (!params.IsObject()) {
@ -270,17 +330,17 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
} }
if (params.HasMember("algo")) { if (params.HasMember("algo")) {
job.algorithm().parseAlgorithm(params["algo"].GetString()); job.setAlgorithm(params["algo"].GetString());
} }
if (params.HasMember("variant")) { if (params.HasMember("variant")) {
const rapidjson::Value &variant = params["variant"]; const rapidjson::Value &variant = params["variant"];
if (variant.IsInt()) { if (variant.IsInt()) {
job.algorithm().parseVariant(variant.GetInt()); job.setVariant(variant.GetInt());
} }
else if (variant.IsString()){ else if (variant.IsString()){
job.algorithm().parseVariant(variant.GetString()); job.setVariant(variant.GetString());
} }
} }
@ -330,6 +390,39 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code)
} }
bool Client::send(BIO *bio)
{
# ifndef XMRIG_NO_TLS
uv_buf_t buf;
buf.len = BIO_get_mem_data(bio, &buf.base);
if (buf.len == 0) {
return true;
}
LOG_DEBUG("[%s] TLS send (%d bytes)", m_pool.url(), static_cast<int>(buf.len));
bool result = false;
if (state() == ConnectedState && uv_is_writable(m_stream)) {
result = uv_try_write(m_stream, &buf, 1) > 0;
if (!result) {
close();
}
}
else {
LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state);
}
(void) BIO_reset(bio);
return result;
# else
return false;
# endif
}
bool Client::verifyAlgorithm(const xmrig::Algorithm &algorithm) const bool Client::verifyAlgorithm(const xmrig::Algorithm &algorithm) const
{ {
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
@ -389,7 +482,9 @@ int64_t Client::send(const rapidjson::Document &doc)
doc.Accept(writer); doc.Accept(writer);
const size_t size = buffer.GetSize(); const size_t size = buffer.GetSize();
if (size > (sizeof(m_buf) - 2)) { if (size > (sizeof(m_sendBuf) - 2)) {
LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", m_pool.url(), size, (sizeof(m_sendBuf) - 2));
close();
return -1; return -1;
} }
@ -404,16 +499,27 @@ int64_t Client::send(const rapidjson::Document &doc)
int64_t Client::send(size_t size) int64_t Client::send(size_t size)
{ {
LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf); LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf);
if (state() != ConnectedState || !uv_is_writable(m_stream)) {
LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state); # ifndef XMRIG_NO_TLS
return -1; if (isTLS()) {
if (!m_tls->send(m_sendBuf, size)) {
return -1;
}
} }
else
# endif
{
if (state() != ConnectedState || !uv_is_writable(m_stream)) {
LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state);
return -1;
}
uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size); uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size);
if (uv_try_write(m_stream, &buf, 1) < 0) { if (uv_try_write(m_stream, &buf, 1) < 0) {
close(); close();
return -1; return -1;
}
} }
m_expire = uv_now(uv_default_loop()) + kResponseTimeout; m_expire = uv_now(uv_default_loop()) + kResponseTimeout;
@ -463,6 +569,22 @@ void Client::connect(sockaddr *addr)
} }
void Client::handshake()
{
# ifndef XMRIG_NO_TLS
if (isTLS()) {
m_expire = uv_now(uv_default_loop()) + kResponseTimeout;
m_tls->handshake();
}
else
# endif
{
login();
}
}
void Client::login() void Client::login()
{ {
using namespace rapidjson; using namespace rapidjson;
@ -511,6 +633,13 @@ void Client::onClose()
m_socket = nullptr; m_socket = nullptr;
setState(UnconnectedState); setState(UnconnectedState);
# ifndef XMRIG_NO_TLS
if (m_tls) {
delete m_tls;
m_tls = nullptr;
}
# endif
reconnect(); reconnect();
} }
@ -665,6 +794,35 @@ void Client::ping()
} }
void Client::read()
{
char* end;
char* start = m_recvBuf.base;
size_t remaining = m_recvBufPos;
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
end++;
size_t len = end - start;
parse(start, len);
remaining -= len;
start = end;
}
if (remaining == 0) {
m_recvBufPos = 0;
return;
}
if (start == m_recvBuf.base) {
return;
}
memcpy(m_recvBuf.base, start, remaining);
m_recvBufPos = remaining;
}
void Client::reconnect() void Client::reconnect()
{ {
if (!m_listener) { if (!m_listener) {
@ -689,7 +847,7 @@ void Client::reconnect()
void Client::setState(SocketState state) void Client::setState(SocketState state)
{ {
LOG_DEBUG("[%s] state: %d", m_pool.url(), state); LOG_DEBUG("[%s] state: \"%s\"", m_pool.url(), states[state]);
if (m_state == state) { if (m_state == state) {
return; return;
@ -757,7 +915,7 @@ void Client::onConnect(uv_connect_t *req, int status)
uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead); uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead);
delete req; delete req;
client->login(); client->handshake();
} }
@ -789,30 +947,18 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
client->m_recvBufPos += nread; client->m_recvBufPos += nread;
char* end; # ifndef XMRIG_NO_TLS
char* start = client->m_recvBuf.base; if (client->isTLS()) {
size_t remaining = client->m_recvBufPos; LOG_DEBUG("[%s] TLS received (%d bytes)", client->m_pool.url(), static_cast<int>(nread));
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) { client->m_tls->read(client->m_recvBuf.base, client->m_recvBufPos);
end++;
size_t len = end - start;
client->parse(start, len);
remaining -= len;
start = end;
}
if (remaining == 0) {
client->m_recvBufPos = 0; client->m_recvBufPos = 0;
return;
} }
else
if (start == client->m_recvBuf.base) { # endif
return; {
client->read();
} }
memcpy(client->m_recvBuf.base, start, remaining);
client->m_recvBufPos = remaining;
} }

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CLIENT_H__ #ifndef XMRIG_CLIENT_H
#define __CLIENT_H__ #define XMRIG_CLIENT_H
#include <map> #include <map>
@ -43,6 +43,9 @@ class IClientListener;
class JobResult; class JobResult;
typedef struct bio_st BIO;
class Client class Client
{ {
public: public:
@ -54,12 +57,20 @@ public:
ClosingState ClosingState
}; };
constexpr static int kResponseTimeout = 20 * 1000; constexpr static int kResponseTimeout = 20 * 1000;
# ifndef XMRIG_NO_TLS
constexpr static int kInputBufferSize = 1024 * 16;
# else
constexpr static int kInputBufferSize = 1024 * 2;
# endif
Client(int id, const char *agent, IClientListener *listener); Client(int id, const char *agent, IClientListener *listener);
~Client(); ~Client();
bool disconnect(); bool disconnect();
const char *tlsFingerprint() const;
const char *tlsVersion() const;
int64_t submit(const JobResult &result); int64_t submit(const JobResult &result);
void connect(); void connect();
void connect(const Pool &pool); void connect(const Pool &pool);
@ -80,6 +91,9 @@ public:
inline void setRetryPause(int ms) { m_retryPause = ms; } inline void setRetryPause(int ms) { m_retryPause = ms; }
private: private:
class Tls;
enum Extensions { enum Extensions {
NicehashExt = 1, NicehashExt = 1,
AlgoExt = 2 AlgoExt = 2
@ -87,14 +101,17 @@ private:
bool close(); bool close();
bool isCriticalError(const char *message); bool isCriticalError(const char *message);
bool isTLS() const;
bool parseJob(const rapidjson::Value &params, int *code); bool parseJob(const rapidjson::Value &params, int *code);
bool parseLogin(const rapidjson::Value &result, int *code); bool parseLogin(const rapidjson::Value &result, int *code);
bool send(BIO *bio);
bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const; bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const;
int resolve(const char *host); int resolve(const char *host);
int64_t send(const rapidjson::Document &doc); int64_t send(const rapidjson::Document &doc);
int64_t send(size_t size); int64_t send(size_t size);
void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6); void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6);
void connect(sockaddr *addr); void connect(sockaddr *addr);
void handshake();
void login(); void login();
void onClose(); void onClose();
void parse(char *line, size_t len); void parse(char *line, size_t len);
@ -102,6 +119,7 @@ private:
void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error); 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 parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
void ping(); void ping();
void read();
void reconnect(); void reconnect();
void setState(SocketState state); void setState(SocketState state);
void startTimeout(); void startTimeout();
@ -120,9 +138,9 @@ private:
bool m_ipv6; bool m_ipv6;
bool m_nicehash; bool m_nicehash;
bool m_quiet; bool m_quiet;
char m_buf[2048]; char m_buf[kInputBufferSize];
char m_ip[46]; char m_ip[46];
char m_sendBuf[768]; char m_sendBuf[2048];
const char *m_agent; const char *m_agent;
IClientListener *m_listener; IClientListener *m_listener;
int m_extensions; int m_extensions;
@ -135,6 +153,7 @@ private:
size_t m_recvBufPos; size_t m_recvBufPos;
SocketState m_state; SocketState m_state;
std::map<int64_t, SubmitResult> m_results; std::map<int64_t, SubmitResult> m_results;
Tls *m_tls;
uint64_t m_expire; uint64_t m_expire;
uint64_t m_jobs; uint64_t m_jobs;
uint64_t m_keepAlive; uint64_t m_keepAlive;
@ -150,4 +169,4 @@ private:
}; };
#endif /* __CLIENT_H__ */ #endif /* XMRIG_CLIENT_H */

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -58,6 +59,7 @@ static inline char hf_bin2hex(unsigned char c)
Job::Job() : Job::Job() :
m_autoVariant(false),
m_nicehash(false), m_nicehash(false),
m_poolId(-2), m_poolId(-2),
m_threadId(-1), m_threadId(-1),
@ -69,7 +71,8 @@ Job::Job() :
} }
Job::Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId) : Job::Job(int poolId, bool nicehash, const xmrig::Algorithm &algorithm, const xmrig::Id &clientId) :
m_autoVariant(algorithm.variant() == xmrig::VARIANT_AUTO),
m_nicehash(nicehash), m_nicehash(nicehash),
m_poolId(poolId), m_poolId(poolId),
m_threadId(-1), m_threadId(-1),
@ -112,6 +115,10 @@ bool Job::setBlob(const char *blob)
m_nicehash = true; m_nicehash = true;
} }
if (m_autoVariant) {
m_algorithm.setVariant(variant());
}
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
memset(m_rawBlob, 0, sizeof(m_rawBlob)); memset(m_rawBlob, 0, sizeof(m_rawBlob));
memcpy(m_rawBlob, blob, m_size * 2); memcpy(m_rawBlob, blob, m_size * 2);
@ -163,25 +170,13 @@ bool Job::setTarget(const char *target)
} }
xmrig::Variant Job::variant() const void Job::setAlgorithm(const char *algo)
{ {
if (m_algorithm.variant() == xmrig::VARIANT_XTL && m_blob[0] < 4) { m_algorithm.parseAlgorithm(algo);
return xmrig::VARIANT_1;
}
if (m_algorithm.variant() == xmrig::VARIANT_MSR && m_blob[0] < 7) {
return xmrig::VARIANT_1;
}
if (m_algorithm.variant() == xmrig::VARIANT_XHV && m_blob[0] < 3) {
return xmrig::VARIANT_0;
}
if (m_algorithm.variant() == xmrig::VARIANT_AUTO) { if (m_algorithm.variant() == xmrig::VARIANT_AUTO) {
return m_algorithm.algo() == xmrig::CRYPTONIGHT_HEAVY ? xmrig::VARIANT_0 : xmrig::VARIANT_1; m_algorithm.setVariant(variant());
} }
return m_algorithm.variant();
} }
@ -229,3 +224,25 @@ bool Job::operator!=(const Job &other) const
{ {
return m_id != other.m_id || memcmp(m_blob, other.m_blob, sizeof(m_blob)) != 0; return m_id != other.m_id || memcmp(m_blob, other.m_blob, sizeof(m_blob)) != 0;
} }
xmrig::Variant Job::variant() const
{
using namespace xmrig;
switch (m_algorithm.algo()) {
case CRYPTONIGHT:
return (m_blob[0] >= 8) ? VARIANT_2 : VARIANT_1;
case CRYPTONIGHT_LITE:
return VARIANT_1;
case CRYPTONIGHT_HEAVY:
return VARIANT_0;
default:
break;
}
return m_algorithm.variant();
}

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -22,8 +23,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __JOB_H__ #ifndef XMRIG_JOB_H
#define __JOB_H__ #define XMRIG_JOB_H
#include <stddef.h> #include <stddef.h>
@ -38,12 +39,12 @@ class Job
{ {
public: public:
Job(); Job();
Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId); Job(int poolId, bool nicehash, const xmrig::Algorithm &algorithm, const xmrig::Id &clientId);
~Job(); ~Job();
bool setBlob(const char *blob); bool setBlob(const char *blob);
bool setTarget(const char *target); bool setTarget(const char *target);
xmrig::Variant variant() const; void setAlgorithm(const char *algo);
inline bool isNicehash() const { return m_nicehash; } inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_size > 0 && m_diff > 0; } inline bool isValid() const { return m_size > 0 && m_diff > 0; }
@ -63,7 +64,8 @@ public:
inline void setClientId(const xmrig::Id &id) { m_clientId = id; } inline void setClientId(const xmrig::Id &id) { m_clientId = id; }
inline void setPoolId(int poolId) { m_poolId = poolId; } inline void setPoolId(int poolId) { m_poolId = poolId; }
inline void setThreadId(int threadId) { m_threadId = threadId; } inline void setThreadId(int threadId) { m_threadId = threadId; }
inline xmrig::Algorithm &algorithm() { return m_algorithm; } inline void setVariant(const char *variant) { m_algorithm.parseVariant(variant); }
inline void setVariant(int variant) { m_algorithm.parseVariant(variant); }
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
inline char *rawBlob() { return m_rawBlob; } inline char *rawBlob() { return m_rawBlob; }
@ -83,6 +85,9 @@ public:
bool operator!=(const Job &other) const; bool operator!=(const Job &other) const;
private: private:
xmrig::Variant variant() const;
bool m_autoVariant;
bool m_nicehash; bool m_nicehash;
int m_poolId; int m_poolId;
int m_threadId; int m_threadId;
@ -100,4 +105,4 @@ private:
# endif # endif
}; };
#endif /* __JOB_H__ */ #endif /* XMRIG_JOB_H */

View file

@ -5,6 +5,7 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -45,6 +46,7 @@
Pool::Pool() : Pool::Pool() :
m_nicehash(false), m_nicehash(false),
m_tls(false),
m_keepAlive(0), m_keepAlive(0),
m_port(kDefaultPort) m_port(kDefaultPort)
{ {
@ -64,6 +66,7 @@ Pool::Pool() :
*/ */
Pool::Pool(const char *url) : Pool::Pool(const char *url) :
m_nicehash(false), m_nicehash(false),
m_tls(false),
m_keepAlive(0), m_keepAlive(0),
m_port(kDefaultPort) m_port(kDefaultPort)
{ {
@ -71,8 +74,9 @@ Pool::Pool(const char *url) :
} }
Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash) : Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls) :
m_nicehash(nicehash), m_nicehash(nicehash),
m_tls(tls),
m_keepAlive(keepAlive), m_keepAlive(keepAlive),
m_port(port), m_port(port),
m_host(host), m_host(host),
@ -113,15 +117,17 @@ bool Pool::isCompatible(const xmrig::Algorithm &algorithm) const
bool Pool::isEqual(const Pool &other) const bool Pool::isEqual(const Pool &other) const
{ {
return (m_nicehash == other.m_nicehash return (m_nicehash == other.m_nicehash
&& m_keepAlive == other.m_keepAlive && m_tls == other.m_tls
&& m_port == other.m_port && m_keepAlive == other.m_keepAlive
&& m_algorithm == other.m_algorithm && m_port == other.m_port
&& m_host == other.m_host && m_algorithm == other.m_algorithm
&& m_password == other.m_password && m_fingerprint == other.m_fingerprint
&& m_rigId == other.m_rigId && m_host == other.m_host
&& m_url == other.m_url && m_password == other.m_password
&& m_user == other.m_user); && m_rigId == other.m_rigId
&& m_url == other.m_url
&& m_user == other.m_user);
} }
@ -133,7 +139,13 @@ bool Pool::parse(const char *url)
const char *base = url; const char *base = url;
if (p) { if (p) {
if (strncasecmp(url, "stratum+tcp://", 14)) { if (strncasecmp(url, "stratum+tcp://", 14) == 0) {
m_tls = false;
}
else if (strncasecmp(url, "stratum+ssl://", 14) == 0) {
m_tls = true;
}
else {
return false; return false;
} }
@ -211,6 +223,7 @@ rapidjson::Value Pool::toJSON(rapidjson::Document &doc) const
case xmrig::VARIANT_AUTO: case xmrig::VARIANT_AUTO:
case xmrig::VARIANT_0: case xmrig::VARIANT_0:
case xmrig::VARIANT_1: case xmrig::VARIANT_1:
case xmrig::VARIANT_2:
obj.AddMember("variant", m_algorithm.variant(), allocator); obj.AddMember("variant", m_algorithm.variant(), allocator);
break; break;
@ -219,6 +232,9 @@ rapidjson::Value Pool::toJSON(rapidjson::Document &doc) const
break; break;
} }
obj.AddMember("tls", isTLS(), allocator);
obj.AddMember("tls-fingerprint", fingerprint() ? Value(StringRef(fingerprint())).Move() : Value(kNullType).Move(), allocator);
return obj; return obj;
} }
@ -359,7 +375,7 @@ void Pool::adjustVariant(const xmrig::Variant variantHint)
if (m_algorithm.algo() == CRYPTONIGHT_HEAVY) { if (m_algorithm.algo() == CRYPTONIGHT_HEAVY) {
m_algorithm.setVariant(VARIANT_0); m_algorithm.setVariant(VARIANT_0);
} }
else { else if (m_algorithm.algo() == CRYPTONIGHT_LITE) {
m_algorithm.setVariant(VARIANT_1); m_algorithm.setVariant(VARIANT_1);
} }
# endif # endif
@ -377,6 +393,7 @@ void Pool::rebuild()
m_algorithms.push_back(m_algorithm); m_algorithms.push_back(m_algorithm);
# ifndef XMRIG_PROXY_PROJECT # ifndef XMRIG_PROXY_PROJECT
addVariant(xmrig::VARIANT_2);
addVariant(xmrig::VARIANT_1); addVariant(xmrig::VARIANT_1);
addVariant(xmrig::VARIANT_0); addVariant(xmrig::VARIANT_0);
addVariant(xmrig::VARIANT_XTL); addVariant(xmrig::VARIANT_XTL);

View file

@ -5,6 +5,7 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -21,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __POOL_H__ #ifndef XMRIG_POOL_H
#define __POOL_H__ #define XMRIG_POOL_H
#include <vector> #include <vector>
@ -44,30 +45,35 @@ public:
Pool(); Pool();
Pool(const char *url); Pool(const char *url);
Pool(const char *host, Pool(const char *host,
uint16_t port, uint16_t port,
const char *user = nullptr, const char *user = nullptr,
const char *password = nullptr, const char *password = nullptr,
int keepAlive = 0, int keepAlive = 0,
bool nicehash = false bool nicehash = false,
bool tls = false
); );
inline bool isNicehash() const { return m_nicehash; } inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; } inline bool isTLS() const { return m_tls; }
inline const char *host() const { return m_host.data(); } inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } inline const char *fingerprint() const { return m_fingerprint.data(); }
inline const char *rigId() const { return m_rigId.data(); } inline const char *host() const { return m_host.data(); }
inline const char *url() const { return m_url.data(); } inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; }
inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } inline const char *rigId() const { return m_rigId.data(); }
inline const xmrig::Algorithm &algorithm() const { return m_algorithm; } inline const char *url() const { return m_url.data(); }
inline const xmrig::Algorithms &algorithms() const { return m_algorithms; } inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; }
inline int keepAlive() const { return m_keepAlive; } inline const xmrig::Algorithm &algorithm() const { return m_algorithm; }
inline uint16_t port() const { return m_port; } inline const xmrig::Algorithms &algorithms() const { return m_algorithms; }
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } inline int keepAlive() const { return m_keepAlive; }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } inline uint16_t port() const { return m_port; }
inline void setPassword(const char *password) { m_password = password; } inline void setFingerprint(const char *fingerprint) { m_fingerprint = fingerprint; }
inline void setRigId(const char *rigId) { m_rigId = rigId; } inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
inline void setUser(const char *user) { m_user = user; } inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
inline xmrig::Algorithm &algorithm() { return m_algorithm; } inline void setPassword(const char *password) { m_password = password; }
inline void setRigId(const char *rigId) { m_rigId = rigId; }
inline void setTLS(bool tls) { m_tls = tls; }
inline void setUser(const char *user) { m_user = user; }
inline xmrig::Algorithm &algorithm() { return m_algorithm; }
inline bool operator!=(const Pool &other) const { return !isEqual(other); } inline bool operator!=(const Pool &other) const { return !isEqual(other); }
inline bool operator==(const Pool &other) const { return isEqual(other); } inline bool operator==(const Pool &other) const { return isEqual(other); }
@ -91,10 +97,12 @@ private:
void rebuild(); void rebuild();
bool m_nicehash; bool m_nicehash;
bool m_tls;
int m_keepAlive; int m_keepAlive;
uint16_t m_port; uint16_t m_port;
xmrig::Algorithm m_algorithm; xmrig::Algorithm m_algorithm;
xmrig::Algorithms m_algorithms; xmrig::Algorithms m_algorithms;
xmrig::c_str m_fingerprint;
xmrig::c_str m_host; xmrig::c_str m_host;
xmrig::c_str m_password; xmrig::c_str m_password;
xmrig::c_str m_rigId; xmrig::c_str m_rigId;
@ -105,4 +113,4 @@ private:
typedef std::vector<Pool> Pools; typedef std::vector<Pool> Pools;
#endif /* __POOL_H__ */ #endif /* XMRIG_POOL_H */

190
src/common/net/Tls.cpp Normal file
View file

@ -0,0 +1,190 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include "common/net/Client.h"
#include "common/net/Tls.h"
#include "common/log/Log.h"
#ifdef _MSC_VER
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif
Client::Tls::Tls(Client *client) :
m_ready(false),
m_buf(),
m_fingerprint(),
m_client(client),
m_ssl(nullptr)
{
m_ctx = SSL_CTX_new(SSLv23_method());
assert(m_ctx != nullptr);
if (!m_ctx) {
return;
}
m_writeBio = BIO_new(BIO_s_mem());
m_readBio = BIO_new(BIO_s_mem());
SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
}
Client::Tls::~Tls()
{
if (m_ctx) {
SSL_CTX_free(m_ctx);
}
if (m_ssl) {
SSL_free(m_ssl);
}
}
bool Client::Tls::handshake()
{
m_ssl = SSL_new(m_ctx);
assert(m_ssl != nullptr);
if (!m_ssl) {
return false;
}
SSL_set_connect_state(m_ssl);
SSL_set_bio(m_ssl, m_readBio, m_writeBio);
SSL_do_handshake(m_ssl);
return send();
}
bool Client::Tls::send(const char *data, size_t size)
{
SSL_write(m_ssl, data, size);
return send();
}
const char *Client::Tls::fingerprint() const
{
return m_ready ? m_fingerprint : nullptr;
}
const char *Client::Tls::version() const
{
return m_ready ? SSL_get_version(m_ssl) : nullptr;
}
void Client::Tls::read(const char *data, size_t size)
{
BIO_write(m_readBio, data, size);
if (!SSL_is_init_finished(m_ssl)) {
const int rc = SSL_connect(m_ssl);
if (rc < 0 && SSL_get_error(m_ssl, rc) == SSL_ERROR_WANT_READ) {
send();
} else if (rc == 1) {
X509 *cert = SSL_get_peer_certificate(m_ssl);
if (!verify(cert)) {
X509_free(cert);
m_client->close();
return;
}
X509_free(cert);
m_ready = true;
m_client->login();
}
return;
}
int bytes_read = 0;
while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) {
m_client->parse(m_buf, bytes_read);
}
}
bool Client::Tls::send()
{
return m_client->send(m_writeBio);
}
bool Client::Tls::verify(X509 *cert)
{
if (cert == nullptr) {
LOG_ERR("[%s] Failed to get server certificate", m_client->m_pool.url());
return false;
}
if (!verifyFingerprint(cert)) {
LOG_ERR("[%s] Failed to verify server certificate fingerprint", m_client->m_pool.url());
const char *fingerprint = m_client->m_pool.fingerprint();
if (strlen(m_fingerprint) == 64 && fingerprint != nullptr) {
LOG_ERR("\"%s\" was given", m_fingerprint);
LOG_ERR("\"%s\" was configured", fingerprint);
}
return false;
}
return true;
}
bool Client::Tls::verifyFingerprint(X509 *cert)
{
const EVP_MD *digest = EVP_get_digestbyname("sha256");
if (digest == nullptr) {
return false;
}
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int dlen;
if (X509_digest(cert, digest, md, &dlen) != 1) {
return false;
}
Job::toHex(md, 32, m_fingerprint);
const char *fingerprint = m_client->m_pool.fingerprint();
return fingerprint == nullptr || strncasecmp(m_fingerprint, fingerprint, 64) == 0;
}

62
src/common/net/Tls.h Normal file
View file

@ -0,0 +1,62 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_TLS_H
#define XMRIG_TLS_H
#include <openssl/ssl.h>
#include "common/net/Client.h"
class Client::Tls
{
public:
Tls(Client *client);
~Tls();
bool handshake();
bool send(const char *data, size_t size);
const char *fingerprint() const;
const char *version() const;
void read(const char *data, size_t size);
private:
bool send();
bool verify(X509 *cert);
bool verifyFingerprint(X509 *cert);
BIO *m_readBio;
BIO *m_writeBio;
bool m_ready;
char m_buf[1024 * 2];
char m_fingerprint[32 * 2 + 8];
Client *m_client;
SSL *m_ssl;
SSL_CTX *m_ctx;
};
#endif /* XMRIG_TLS_H */

View file

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

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __XMRIG_H__ #ifndef XMRIG_XMRIG_H
#define __XMRIG_H__ #define XMRIG_XMRIG_H
namespace xmrig namespace xmrig
@ -33,7 +33,7 @@ enum Algo {
INVALID_ALGO = -1, INVALID_ALGO = -1,
CRYPTONIGHT, /* CryptoNight (Monero) */ CRYPTONIGHT, /* CryptoNight (Monero) */
CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (SUMO) */ CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (RYO) */
}; };
@ -65,8 +65,9 @@ enum Variant {
VARIANT_XTL = 3, // Modified CryptoNight variant 1 (Stellite only) VARIANT_XTL = 3, // Modified CryptoNight variant 1 (Stellite only)
VARIANT_MSR = 4, // Modified CryptoNight variant 1 (Masari only) VARIANT_MSR = 4, // Modified CryptoNight variant 1 (Masari only)
VARIANT_XHV = 5, // Modified CryptoNight-Heavy (Haven Protocol only) VARIANT_XHV = 5, // Modified CryptoNight-Heavy (Haven Protocol only)
VARIANT_XAO = 6, // Modified CryptoNight variant 1 (Alloy only) VARIANT_XAO = 6, // Modified CryptoNight variant 0 (Alloy only)
VARIANT_RTO = 7, // Modified CryptoNight variant 1 (Arto only) VARIANT_RTO = 7, // Modified CryptoNight variant 1 (Arto only)
VARIANT_2 = 8, // CryptoNight variant 2
VARIANT_MAX VARIANT_MAX
}; };
@ -84,7 +85,25 @@ enum AesMode {
}; };
enum OclVendor {
OCL_VENDOR_UNKNOWN = -2,
OCL_VENDOR_MANUAL = -1,
OCL_VENDOR_AMD = 0,
OCL_VENDOR_NVIDIA = 1,
OCL_VENDOR_INTEL = 2
};
enum Assembly {
ASM_NONE,
ASM_AUTO,
ASM_INTEL,
ASM_RYZEN,
ASM_MAX
};
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* __XMRIG_H__ */ #endif /* XMRIG_XMRIG_H */

View file

@ -3,10 +3,13 @@
"api": { "api": {
"port": 0, "port": 0,
"access-token": null, "access-token": null,
"id": null,
"worker-id": null, "worker-id": null,
"ipv6": false, "ipv6": false,
"restricted": true "restricted": true
}, },
"asm": true,
"autosave": true,
"av": 0, "av": 0,
"background": false, "background": false,
"colors": true, "colors": true,
@ -19,13 +22,15 @@
"max-cpu-usage": 75, "max-cpu-usage": 75,
"pools": [ "pools": [
{ {
"url": "proxy.fee.xmrig.com:9999", "url": "donate.v2.xmrig.com:3333",
"user": "YOUR_WALLET", "user": "YOUR_WALLET_ADDRESS",
"pass": "x", "pass": "x",
"rig-id": null, "rig-id": null,
"nicehash": false, "nicehash": false,
"keepalive": false, "keepalive": false,
"variant": 1 "variant": -1,
"tls": false,
"tls-fingerprint": null
} }
], ],
"print-time": 60, "print-time": 60,

View file

@ -27,9 +27,10 @@
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/cpu/Cpu.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/ConfigCreator.h" #include "core/ConfigCreator.h"
#include "Cpu.h" #include "crypto/Asm.h"
#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_constants.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
@ -43,19 +44,16 @@ static char affinity_tmp[20] = { 0 };
xmrig::Config::Config() : xmrig::CommonConfig(), xmrig::Config::Config() : xmrig::CommonConfig(),
m_aesMode(AES_AUTO), m_aesMode(AES_AUTO),
m_algoVariant(AV_AUTO), m_algoVariant(AV_AUTO),
m_assembly(ASM_AUTO),
m_hugePages(true), m_hugePages(true),
m_safe(false), m_safe(false),
m_shouldSave(false),
m_maxCpuUsage(75), m_maxCpuUsage(75),
m_priority(-1) m_priority(-1)
{ {
} }
xmrig::Config::~Config()
{
}
bool xmrig::Config::reload(const char *json) bool xmrig::Config::reload(const char *json)
{ {
return xmrig::ConfigLoader::reload(this, json); return xmrig::ConfigLoader::reload(this, json);
@ -75,11 +73,17 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
Value api(kObjectType); Value api(kObjectType);
api.AddMember("port", apiPort(), allocator); api.AddMember("port", apiPort(), allocator);
api.AddMember("access-token", apiToken() ? Value(StringRef(apiToken())).Move() : Value(kNullType).Move(), allocator); api.AddMember("access-token", apiToken() ? Value(StringRef(apiToken())).Move() : Value(kNullType).Move(), allocator);
api.AddMember("id", apiId() ? Value(StringRef(apiId())).Move() : Value(kNullType).Move(), allocator);
api.AddMember("worker-id", apiWorkerId() ? Value(StringRef(apiWorkerId())).Move() : Value(kNullType).Move(), allocator); api.AddMember("worker-id", apiWorkerId() ? Value(StringRef(apiWorkerId())).Move() : Value(kNullType).Move(), allocator);
api.AddMember("ipv6", isApiIPv6(), allocator); api.AddMember("ipv6", isApiIPv6(), allocator);
api.AddMember("restricted", isApiRestricted(), allocator); api.AddMember("restricted", isApiRestricted(), allocator);
doc.AddMember("api", api, allocator); doc.AddMember("api", api, allocator);
# ifndef XMRIG_NO_ASM
doc.AddMember("asm", Asm::toJSON(m_assembly), allocator);
# endif
doc.AddMember("autosave", isAutoSave(), allocator);
doc.AddMember("av", algoVariant(), allocator); doc.AddMember("av", algoVariant(), allocator);
doc.AddMember("background", isBackground(), allocator); doc.AddMember("background", isBackground(), allocator);
doc.AddMember("colors", isColors(), allocator); doc.AddMember("colors", isColors(), allocator);
@ -111,7 +115,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
doc.AddMember("retry-pause", retryPause(), allocator); doc.AddMember("retry-pause", retryPause(), allocator);
doc.AddMember("safe", m_safe, allocator); doc.AddMember("safe", m_safe, allocator);
if (threadsMode() == Advanced) { if (threadsMode() != Simple) {
Value threads(kArrayType); Value threads(kArrayType);
for (const IThread *thread : m_threads.list) { for (const IThread *thread : m_threads.list) {
@ -121,7 +125,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
doc.AddMember("threads", threads, allocator); doc.AddMember("threads", threads, allocator);
} }
else { else {
doc.AddMember("threads", threadsMode() == Automatic ? Value(kNullType) : Value(threadsCount()), allocator); doc.AddMember("threads", threadsCount(), allocator);
} }
doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator);
@ -152,7 +156,7 @@ bool xmrig::Config::finalize()
if (!m_threads.cpu.empty()) { if (!m_threads.cpu.empty()) {
m_threads.mode = Advanced; m_threads.mode = Advanced;
const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT;
for (size_t i = 0; i < m_threads.cpu.size(); ++i) { for (size_t i = 0; i < m_threads.cpu.size(); ++i) {
m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES)); m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES));
@ -161,25 +165,26 @@ bool xmrig::Config::finalize()
return true; return true;
} }
const AlgoVariant av = getAlgoVariant(); const AlgoVariant av = getAlgoVariant();
m_threads.mode = m_threads.count ? Simple : Automatic; m_threads.mode = m_threads.count ? Simple : Automatic;
const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024; const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024;
if (!m_threads.count) { if (!m_threads.count) {
m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); m_threads.count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage);
} }
else if (m_safe) { else if (m_safe) {
const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage);
if (m_threads.count > count) { if (m_threads.count > count) {
m_threads.count = count; m_threads.count = count;
} }
} }
for (size_t i = 0; i < m_threads.count; ++i) { for (size_t i = 0; i < m_threads.count; ++i) {
m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority)); m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority, m_assembly));
} }
m_shouldSave = m_threads.mode == Automatic;
return true; return true;
} }
@ -203,6 +208,12 @@ bool xmrig::Config::parseBoolean(int key, bool enable)
m_aesMode = enable ? AES_HW : AES_SOFT; m_aesMode = enable ? AES_HW : AES_SOFT;
break; break;
# ifndef XMRIG_NO_ASM
case AssemblyKey:
m_assembly = Asm::parse(enable);
break;
# endif
default: default:
break; break;
} }
@ -231,7 +242,7 @@ bool xmrig::Config::parseString(int key, const char *arg)
case ThreadsKey: /* --threads */ case ThreadsKey: /* --threads */
if (strncmp(arg, "all", 3) == 0) { if (strncmp(arg, "all", 3) == 0) {
m_threads.count = Cpu::threads(); m_threads.count = Cpu::info()->threads();
return true; return true;
} }
@ -243,6 +254,12 @@ bool xmrig::Config::parseString(int key, const char *arg)
return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
} }
# ifndef XMRIG_NO_ASM
case AssemblyKey: /* --asm */
m_assembly = Asm::parse(arg);
break;
# endif
default: default:
break; break;
} }
@ -338,10 +355,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const
# endif # endif
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) {
return Cpu::hasAES() ? AV_SINGLE : AV_SINGLE_SOFT; return Cpu::info()->hasAES() ? AV_SINGLE : AV_SINGLE_SOFT;
} }
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) { if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) {
return static_cast<AlgoVariant>(m_algoVariant + 2); return static_cast<AlgoVariant>(m_algoVariant + 2);
} }
@ -353,10 +370,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const
xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const
{ {
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) {
return Cpu::hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT; return Cpu::info()->hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT;
} }
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) { if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) {
return static_cast<AlgoVariant>(m_algoVariant + 2); return static_cast<AlgoVariant>(m_algoVariant + 2);
} }

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CONFIG_H__ #ifndef XMRIG_CONFIG_H
#define __CONFIG_H__ #define XMRIG_CONFIG_H
#include <stdint.h> #include <stdint.h>
@ -69,7 +69,6 @@ public:
Config(); Config();
~Config();
bool reload(const char *json); bool reload(const char *json);
@ -77,7 +76,9 @@ public:
inline AesMode aesMode() const { return m_aesMode; } inline AesMode aesMode() const { return m_aesMode; }
inline AlgoVariant algoVariant() const { return m_algoVariant; } inline AlgoVariant algoVariant() const { return m_algoVariant; }
inline Assembly assembly() const { return m_assembly; }
inline bool isHugePages() const { return m_hugePages; } inline bool isHugePages() const { return m_hugePages; }
inline bool isShouldSave() const { return m_shouldSave && isAutoSave(); }
inline const std::vector<IThread *> &threads() const { return m_threads.list; } inline const std::vector<IThread *> &threads() const { return m_threads.list; }
inline int priority() const { return m_priority; } inline int priority() const { return m_priority; }
inline int threadsCount() const { return m_threads.list.size(); } inline int threadsCount() const { return m_threads.list.size(); }
@ -116,8 +117,10 @@ private:
AesMode m_aesMode; AesMode m_aesMode;
AlgoVariant m_algoVariant; AlgoVariant m_algoVariant;
Assembly m_assembly;
bool m_hugePages; bool m_hugePages;
bool m_safe; bool m_safe;
bool m_shouldSave;
int m_maxCpuUsage; int m_maxCpuUsage;
int m_priority; int m_priority;
Threads m_threads; Threads m_threads;
@ -126,4 +129,4 @@ private:
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* __CONFIG_H__ */ #endif /* XMRIG_CONFIG_H */

View file

@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CONFIGLOADER_PLATFORM_H__ #ifndef XMRIG_CONFIGLOADER_PLATFORM_H
#define __CONFIGLOADER_PLATFORM_H__ #define XMRIG_CONFIGLOADER_PLATFORM_H
#ifdef _MSC_VER #ifdef _MSC_VER
@ -86,6 +86,7 @@ Options:\n\
--api-port=N port for the miner API\n\ --api-port=N port for the miner API\n\
--api-access-token=T access token for API\n\ --api-access-token=T access token for API\n\
--api-worker-id=ID custom worker-id for API\n\ --api-worker-id=ID custom worker-id for API\n\
--api-id=ID custom instance ID for API\n\
--api-ipv6 enable IPv6 support for API\n\ --api-ipv6 enable IPv6 support for API\n\
--api-no-restricted enable full remote access (only if API token set)\n\ --api-no-restricted enable full remote access (only if API token set)\n\
-h, --help display this help and exit\n\ -h, --help display this help and exit\n\
@ -101,6 +102,7 @@ static struct option const options[] = {
{ "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey }, { "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey },
{ "api-port", 1, nullptr, xmrig::IConfig::ApiPort }, { "api-port", 1, nullptr, xmrig::IConfig::ApiPort },
{ "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, { "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
{ "api-id", 1, nullptr, xmrig::IConfig::ApiIdKey },
{ "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, { "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
{ "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, { "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
{ "av", 1, nullptr, xmrig::IConfig::AVKey }, { "av", 1, nullptr, xmrig::IConfig::AVKey },
@ -130,8 +132,11 @@ static struct option const options[] = {
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
{ "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey },
{ "tls", 0, nullptr, xmrig::IConfig::TlsKey },
{ "tls-fingerprint", 1, nullptr, xmrig::IConfig::FingerprintKey },
{ "version", 0, nullptr, xmrig::IConfig::VersionKey }, { "version", 0, nullptr, xmrig::IConfig::VersionKey },
{ 0, 0, 0, 0 } { "asm", 1, nullptr, xmrig::IConfig::AssemblyKey },
{ nullptr, 0, nullptr, 0 }
}; };
@ -155,20 +160,24 @@ static struct option const config_options[] = {
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey }, { "threads", 1, nullptr, xmrig::IConfig::ThreadsKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey }, { "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey },
{ 0, 0, 0, 0 } { "asm", 1, nullptr, xmrig::IConfig::AssemblyKey },
{ "autosave", 0, nullptr, xmrig::IConfig::AutoSaveKey },
{ nullptr, 0, nullptr, 0 }
}; };
static struct option const pool_options[] = { static struct option const pool_options[] = {
{ "url", 1, nullptr, xmrig::IConfig::UrlKey }, { "url", 1, nullptr, xmrig::IConfig::UrlKey },
{ "pass", 1, nullptr, xmrig::IConfig::PasswordKey }, { "pass", 1, nullptr, xmrig::IConfig::PasswordKey },
{ "user", 1, nullptr, xmrig::IConfig::UserKey }, { "user", 1, nullptr, xmrig::IConfig::UserKey },
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
{ "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey }, { "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey },
{ "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey }, { "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey },
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey }, { "variant", 1, nullptr, xmrig::IConfig::VariantKey },
{ "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey },
{ 0, 0, 0, 0 } { "tls", 0, nullptr, xmrig::IConfig::TlsKey },
{ "tls-fingerprint", 1, nullptr, xmrig::IConfig::FingerprintKey },
{ nullptr, 0, nullptr, 0 }
}; };
@ -178,10 +187,11 @@ static struct option const api_options[] = {
{ "worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, { "worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
{ "ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, { "ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
{ "restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, { "restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
{ 0, 0, 0, 0 } { "id", 1, nullptr, xmrig::IConfig::ApiIdKey },
{ nullptr, 0, nullptr, 0 }
}; };
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* __CONFIGLOADER_PLATFORM_H__ */ #endif /* XMRIG_CONFIGLOADER_PLATFORM_H */

View file

@ -26,6 +26,7 @@
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/cpu/Cpu.h"
#include "common/interfaces/IControllerListener.h" #include "common/interfaces/IControllerListener.h"
#include "common/log/ConsoleLog.h" #include "common/log/ConsoleLog.h"
#include "common/log/FileLog.h" #include "common/log/FileLog.h"
@ -33,7 +34,6 @@
#include "common/Platform.h" #include "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h"
#include "net/Network.h" #include "net/Network.h"

View file

@ -21,65 +21,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <libcpuid.h> #include <libcpuid.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <thread>
#include "Cpu.h" #include "core/cpu/AdvancedCpuInfo.h"
bool Cpu::m_l2_exclusive = false; xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
char Cpu::m_brand[64] = { 0 }; m_assembly(ASM_NONE),
int Cpu::m_flags = 0; m_aes(false),
int Cpu::m_l2_cache = 0; m_L2_exclusive(false),
int Cpu::m_l3_cache = 0; m_brand(),
int Cpu::m_sockets = 1; m_cores(0),
int Cpu::m_totalCores = 0; m_L2(0),
size_t Cpu::m_totalThreads = 0; m_L3(0),
m_sockets(1),
m_threads(std::thread::hardware_concurrency())
size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage)
{
if (m_totalThreads == 1) {
return 1;
}
size_t cache = 0;
if (m_l3_cache) {
cache = m_l2_exclusive ? (m_l2_cache + m_l3_cache) : m_l3_cache;
}
else {
cache = m_l2_cache;
}
size_t count = 0;
if (cache) {
count = cache / size;
if (cache % size >= size / 2) {
count++;
}
}
else {
count = m_totalThreads / 2;
}
if (count > m_totalThreads) {
count = m_totalThreads;
}
if (((float) count / m_totalThreads * 100) > maxCpuUsage) {
count = (int) ceil((float) m_totalThreads * (maxCpuUsage / 100.0));
}
return count < 1 ? 1 : count;
}
void Cpu::initCommon()
{ {
struct cpu_raw_data_t raw = { 0 }; struct cpu_raw_data_t raw = { 0 };
struct cpu_id_t data = { 0 }; struct cpu_id_t data = { 0 };
@ -87,42 +47,78 @@ void Cpu::initCommon()
cpuid_get_raw_data(&raw); cpuid_get_raw_data(&raw);
cpu_identify(&raw, &data); cpu_identify(&raw, &data);
strncpy(m_brand, data.brand_str, sizeof(m_brand) - 1); strncpy(m_brand, data.brand_str, sizeof(m_brand));
m_totalThreads = data.total_logical_cpus;
m_sockets = m_totalThreads / data.num_logical_cpus;
m_sockets = threads() / data.num_logical_cpus;
if (m_sockets == 0) { if (m_sockets == 0) {
m_sockets = 1; m_sockets = 1;
} }
m_totalCores = data.num_cores * m_sockets; m_cores = data.num_cores * m_sockets;
m_l3_cache = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0; m_L3 = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0;
// Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97 // Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97
if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) { if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) {
m_l2_cache = data.l2_cache * (m_totalCores / 2) * m_sockets; m_L2 = data.l2_cache * (cores() / 2) * m_sockets;
m_l2_exclusive = true; m_L2_exclusive = true;
} }
// Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue // 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. // 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)) { 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; int l2_count_per_socket = cores() > 1 ? cores() / 2 : 1;
m_l2_cache = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0; m_L2 = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0;
} }
else{ else{
m_l2_cache = data.l2_cache > 0 ? data.l2_cache * m_totalCores * m_sockets : 0; m_L2 = data.l2_cache > 0 ? data.l2_cache * cores() * m_sockets : 0;
} }
# if defined(__x86_64__) || defined(_M_AMD64)
m_flags |= X86_64;
# endif
if (data.flags[CPU_FEATURE_AES]) { if (data.flags[CPU_FEATURE_AES]) {
m_flags |= AES; m_aes = true;
}
if (data.flags[CPU_FEATURE_BMI2]) { if (data.vendor == VENDOR_AMD && data.ext_family >= 23) {
m_flags |= BMI2; m_assembly = ASM_RYZEN;
}
else if (data.vendor == VENDOR_INTEL && data.ext_model >= 42) {
m_assembly = ASM_INTEL;
}
} }
} }
size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
{
if (threads() == 1) {
return 1;
}
size_t cache = 0;
if (m_L3) {
cache = m_L2_exclusive ? (m_L2 + m_L3) : m_L3;
}
else {
cache = m_L2;
}
size_t count = 0;
if (cache) {
count = cache / memSize;
if (cache % memSize >= memSize / 2) {
count++;
}
}
else {
count = threads() / 2;
}
if (count > (size_t) threads()) {
count = threads();
}
if (((float) count / threads() * 100) > maxCpuUsage) {
count = (int) ceil((float) threads() * (maxCpuUsage / 100.0));
}
return count < 1 ? 1 : count;
}

View file

@ -0,0 +1,75 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ADVANCEDCPUINFO_H
#define XMRIG_ADVANCEDCPUINFO_H
#include "common/interfaces/ICpuInfo.h"
namespace xmrig {
class AdvancedCpuInfo : public ICpuInfo
{
public:
AdvancedCpuInfo();
protected:
size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override;
inline Assembly assembly() const override { return m_assembly; }
inline bool hasAES() const override { return m_aes; }
inline bool isSupported() const override { return true; }
inline const char *brand() const override { return m_brand; }
inline int32_t cores() const override { return m_cores; }
inline int32_t L2() const override { return m_L2; }
inline int32_t L3() const override { return m_L3; }
inline int32_t nodes() const override { return -1; }
inline int32_t sockets() const override { return m_sockets; }
inline int32_t threads() const override { return m_threads; }
# if defined(__x86_64__) || defined(_M_AMD64)
inline bool isX64() const override { return true; }
# else
inline bool isX64() const override { return false; }
# endif
private:
Assembly m_assembly;
bool m_aes;
bool m_L2_exclusive;
char m_brand[64];
int32_t m_cores;
int32_t m_L2;
int32_t m_L3;
int32_t m_sockets;
int32_t m_threads;
};
} /* namespace xmrig */
#endif /* XMRIG_ADVANCEDCPUINFO_H */

View file

@ -22,20 +22,40 @@
*/ */
#include <windows.h> #include <assert.h>
#include "Cpu.h" #include "common/cpu/Cpu.h"
void Cpu::init() #ifndef XMRIG_NO_LIBCPUID
# include "core/cpu/AdvancedCpuInfo.h"
#endif
static xmrig::ICpuInfo *cpuInfo = nullptr;
xmrig::ICpuInfo *xmrig::Cpu::info()
{ {
# ifdef XMRIG_NO_LIBCPUID assert(cpuInfo != nullptr);
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
m_totalThreads = sysinfo.dwNumberOfProcessors; return cpuInfo;
# endif }
initCommon();
void xmrig::Cpu::init()
{
assert(cpuInfo == nullptr);
cpuInfo = new AdvancedCpuInfo();
}
void xmrig::Cpu::release()
{
assert(cpuInfo != nullptr);
delete cpuInfo;
cpuInfo = nullptr;
} }

100
src/crypto/Asm.cpp Normal file
View file

@ -0,0 +1,100 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <string.h>
#ifdef _MSC_VER
# define strncasecmp _strnicmp
# define strcasecmp _stricmp
#endif
#include "crypto/Asm.h"
#include "rapidjson/document.h"
static const char *asmNames[] = {
"none",
"auto",
"intel",
"ryzen"
};
xmrig::Assembly xmrig::Asm::parse(const char *assembly, Assembly defaultValue)
{
constexpr size_t const size = sizeof(asmNames) / sizeof((asmNames)[0]);
assert(assembly != nullptr);
assert(ASM_MAX == size);
if (assembly == nullptr) {
return defaultValue;
}
for (size_t i = 0; i < size; i++) {
if (strcasecmp(assembly, asmNames[i]) == 0) {
return static_cast<Assembly>(i);
}
}
return defaultValue;
}
xmrig::Assembly xmrig::Asm::parse(const rapidjson::Value &value, Assembly defaultValue)
{
if (value.IsBool()) {
return parse(value.GetBool());
}
if (value.IsString()) {
return parse(value.GetString(), defaultValue);
}
return defaultValue;
}
const char *xmrig::Asm::toString(Assembly assembly)
{
return asmNames[assembly];
}
rapidjson::Value xmrig::Asm::toJSON(Assembly assembly)
{
using namespace rapidjson;
if (assembly == ASM_NONE) {
return Value(false);
}
if (assembly == ASM_AUTO) {
return Value(true);
}
return Value(StringRef(toString(assembly)));
}

50
src/crypto/Asm.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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ASM_H
#define XMRIG_ASM_H
#include "common/xmrig.h"
#include "rapidjson/fwd.h"
namespace xmrig {
class Asm
{
public:
static Assembly parse(const char *assembly, Assembly defaultValue = ASM_AUTO);
static Assembly parse(const rapidjson::Value &value, Assembly defaultValue = ASM_AUTO);
static const char *toString(Assembly assembly);
static rapidjson::Value toJSON(Assembly assembly);
inline static Assembly parse(bool enable) { return enable ? ASM_AUTO : ASM_NONE; }
};
} /* namespace xmrig */
#endif /* XMRIG_ASM_H */

View file

@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CRYPTONIGHT_H__ #ifndef XMRIG_CRYPTONIGHT_H
#define __CRYPTONIGHT_H__ #define XMRIG_CRYPTONIGHT_H
#include <stddef.h> #include <stddef.h>
@ -31,9 +31,9 @@
struct cryptonight_ctx { struct cryptonight_ctx {
alignas(16) uint8_t state[200]; alignas(16) uint8_t state[224];
alignas(16) uint8_t* memory; alignas(16) uint8_t *memory;
}; };
#endif /* __CRYPTONIGHT_H__ */ #endif /* XMRIG_CRYPTONIGHT_H */

View file

@ -7,6 +7,7 @@
* Copyright 2016 Imran Yusuff <https://github.com/imranyusuff> * Copyright 2016 Imran Yusuff <https://github.com/imranyusuff>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -23,8 +24,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CRYPTONIGHT_ARM_H__ #ifndef XMRIG_CRYPTONIGHT_ARM_H
#define __CRYPTONIGHT_ARM_H__ #define XMRIG_CRYPTONIGHT_ARM_H
#include "common/crypto/keccak.h" #include "common/crypto/keccak.h"
@ -95,9 +96,6 @@ static inline __attribute__((always_inline)) uint64_t _mm_cvtsi128_si64(__m128i
} }
#define EXTRACT64(X) _mm_cvtsi128_si64(X)
#if defined (__arm64__) || defined (__aarch64__) #if defined (__arm64__) || defined (__aarch64__)
static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi) static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi)
{ {
@ -404,19 +402,27 @@ static inline __m128i aes_round_tweak_div(const __m128i &in, const __m128i &key)
} }
template<int SHIFT> template<xmrig::Variant VARIANT>
static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) static inline void cryptonight_monero_tweak(const uint8_t* l, uint64_t idx, __m128i ax0, __m128i bx0, __m128i bx1, __m128i cx)
{ {
mem_out[0] = EXTRACT64(tmp); uint64_t* mem_out = (uint64_t*)&l[idx];
uint64_t vh = vgetq_lane_u64(tmp, 1); if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1);
_mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx));
} else {
__m128i tmp = _mm_xor_si128(bx0, cx);
mem_out[0] = _mm_cvtsi128_si64(tmp);
uint8_t x = vh >> 24; uint64_t vh = vgetq_lane_u64(tmp, 1);
static const uint16_t table = 0x7531;
const uint8_t index = (((x >> SHIFT) & 6) | (x & 1)) << 1;
vh ^= ((table >> index) & 0x3) << 28;
mem_out[1] = vh; uint8_t x = vh >> 24;
static const uint16_t table = 0x7531;
const uint8_t index = (((x >> (VARIANT == xmrig::VARIANT_XTL ? 4 : 3)) & 6) | (x & 1)) << 1;
vh ^= ((table >> index) & 0x3) << 28;
mem_out[1] = vh;
}
} }
@ -426,27 +432,29 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>(); constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>(); constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>(); constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
constexpr bool IS_MONERO = xmrig::cn_is_monero<VARIANT>(); constexpr bool IS_V1 = xmrig::cn_base_variant<VARIANT>() == xmrig::VARIANT_1;
if (IS_MONERO && size < 43) { if (IS_V1 && size < 43) {
memset(output, 0, 32); memset(output, 0, 32);
return; return;
} }
xmrig::keccak(input, size, ctx[0]->state); xmrig::keccak(input, size, ctx[0]->state);
VARIANT1_INIT(0);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory);
const uint8_t* l0 = ctx[0]->memory; const uint8_t* l0 = ctx[0]->memory;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state); uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
VARIANT1_INIT(0);
VARIANT2_INIT(0);
uint64_t al0 = h0[0] ^ h0[4]; uint64_t al0 = h0[0] ^ h0[4];
uint64_t ah0 = h0[1] ^ h0[5]; uint64_t ah0 = h0[1] ^ h0[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]);
uint64_t idx0 = h0[0] ^ h0[4]; uint64_t idx0 = al0;
for (size_t i = 0; i < ITERATIONS; i++) { for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx; __m128i cx;
@ -454,44 +462,47 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
} }
const __m128i ax0 = _mm_set_epi64x(ah0, al0);
if (VARIANT == xmrig::VARIANT_TUBE) { if (VARIANT == xmrig::VARIANT_TUBE) {
cx = aes_round_tweak_div(cx, _mm_set_epi64x(ah0, al0)); cx = aes_round_tweak_div(cx, ax0);
} }
else if (SOFT_AES) { else if (SOFT_AES) {
cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0)); cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0);
} }
else { else {
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); cx = _mm_aesenc_si128(cx, ax0);
} }
if (IS_MONERO) { if (IS_V1 || VARIANT == xmrig::VARIANT_2) {
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); cryptonight_monero_tweak<VARIANT>(l0, idx0 & MASK, ax0, bx0, bx1, cx);
} else { } else {
_mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
} }
idx0 = EXTRACT64(cx); idx0 = _mm_cvtsi128_si64(cx);
bx0 = cx;
uint64_t hi, lo, cl, ch; uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0]; cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1]; ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi); if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_INTEGER_MATH(0, cl, cx);
lo = __umul128(idx0, cl, &hi);
VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo);
}
else {
lo = __umul128(idx0, cl, &hi);
}
al0 += hi; al0 += hi;
ah0 += lo; ah0 += lo;
((uint64_t*)&l0[idx0 & MASK])[0] = al0; ((uint64_t*)&l0[idx0 & MASK])[0] = al0;
if (IS_MONERO) { if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) {
if (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO) { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0;
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; } else if (IS_V1) {
} ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
else { } else {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
}
}
else {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0; ((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
} }
@ -514,6 +525,10 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
idx0 = d ^ q; idx0 = d ^ q;
} }
} }
if (VARIANT == xmrig::VARIANT_2) {
bx1 = bx0;
}
bx0 = cx;
} }
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state);
@ -529,9 +544,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>(); constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>(); constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>(); constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
constexpr bool IS_MONERO = xmrig::cn_is_monero<VARIANT>(); constexpr bool IS_V1 = xmrig::cn_base_variant<VARIANT>() == xmrig::VARIANT_1;
if (IS_MONERO && size < 43) { if (IS_V1 && size < 43) {
memset(output, 0, 64); memset(output, 0, 64);
return; return;
} }
@ -539,14 +554,16 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
xmrig::keccak(input, size, ctx[0]->state); xmrig::keccak(input, size, ctx[0]->state);
xmrig::keccak(input + size, size, ctx[1]->state); xmrig::keccak(input + size, size, ctx[1]->state);
VARIANT1_INIT(0);
VARIANT1_INIT(1);
const uint8_t* l0 = ctx[0]->memory; const uint8_t* l0 = ctx[0]->memory;
const uint8_t* l1 = ctx[1]->memory; const uint8_t* l1 = ctx[1]->memory;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state); uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state); uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
VARIANT1_INIT(0);
VARIANT1_INIT(1);
VARIANT2_INIT(0);
VARIANT2_INIT(1);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
@ -555,11 +572,13 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
uint64_t ah0 = h0[1] ^ h0[5]; uint64_t ah0 = h0[1] ^ h0[5];
uint64_t ah1 = h1[1] ^ h1[5]; uint64_t ah1 = h1[1] ^ h1[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); __m128i bx00 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); __m128i bx01 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]);
__m128i bx10 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
__m128i bx11 = _mm_set_epi64x(h1[9] ^ h1[11], h1[8] ^ h1[10]);
uint64_t idx0 = h0[0] ^ h0[4]; uint64_t idx0 = al0;
uint64_t idx1 = h1[0] ^ h1[4]; uint64_t idx1 = al1;
for (size_t i = 0; i < ITERATIONS; i++) { for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0, cx1; __m128i cx0, cx1;
@ -568,52 +587,53 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]);
} }
const __m128i ax0 = _mm_set_epi64x(ah0, al0);
const __m128i ax1 = _mm_set_epi64x(ah1, al1);
if (VARIANT == xmrig::VARIANT_TUBE) { if (VARIANT == xmrig::VARIANT_TUBE) {
cx0 = aes_round_tweak_div(cx0, _mm_set_epi64x(ah0, al0)); cx0 = aes_round_tweak_div(cx0, ax0);
cx1 = aes_round_tweak_div(cx1, _mm_set_epi64x(ah1, al1)); cx1 = aes_round_tweak_div(cx1, ax1);
} }
else if (SOFT_AES) { else if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0)); cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0);
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1)); cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], ax1);
} }
else { else {
cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); cx0 = _mm_aesenc_si128(cx0, ax0);
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); cx1 = _mm_aesenc_si128(cx1, ax1);
} }
if (IS_MONERO) { if (IS_V1 || (VARIANT == xmrig::VARIANT_2)) {
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); cryptonight_monero_tweak<VARIANT>(l0, idx0 & MASK, ax0, bx00, bx01, cx0);
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); cryptonight_monero_tweak<VARIANT>(l1, idx1 & MASK, ax1, bx10, bx11, cx1);
} else { } else {
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx00, cx0));
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx10, cx1));
}; }
idx0 = EXTRACT64(cx0); idx0 = _mm_cvtsi128_si64(cx0);
idx1 = EXTRACT64(cx1); idx1 = _mm_cvtsi128_si64(cx1);
bx0 = cx0;
bx1 = cx1;
uint64_t hi, lo, cl, ch; uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0]; cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1]; ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi); if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_INTEGER_MATH(0, cl, cx0);
lo = __umul128(idx0, cl, &hi);
VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo);
} else {
lo = __umul128(idx0, cl, &hi);
}
al0 += hi; al0 += hi;
ah0 += lo; ah0 += lo;
((uint64_t*)&l0[idx0 & MASK])[0] = al0; ((uint64_t*)&l0[idx0 & MASK])[0] = al0;
if (IS_MONERO) { if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) {
if (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO) { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0;
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; } else if (IS_V1) {
} ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
else { } else {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
}
}
else {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0; ((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
} }
@ -639,22 +659,24 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
cl = ((uint64_t*) &l1[idx1 & MASK])[0]; cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1]; ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi); if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_INTEGER_MATH(1, cl, cx1);
lo = __umul128(idx1, cl, &hi);
VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo);
} else {
lo = __umul128(idx1, cl, &hi);
}
al1 += hi; al1 += hi;
ah1 += lo; ah1 += lo;
((uint64_t*)&l1[idx1 & MASK])[0] = al1; ((uint64_t*)&l1[idx1 & MASK])[0] = al1;
if (IS_MONERO) { if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) {
if (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO) { ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1;
((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1; } else if (IS_V1) {
} ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1;
else { } else {
((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1;
}
}
else {
((uint64_t*)&l1[idx1 & MASK])[1] = ah1; ((uint64_t*)&l1[idx1 & MASK])[1] = ah1;
} }
@ -677,6 +699,12 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
idx1 = d ^ q; idx1 = d ^ q;
} }
} }
if (VARIANT == xmrig::VARIANT_2) {
bx01 = bx00;
bx11 = bx10;
}
bx00 = cx0;
bx10 = cx1;
} }
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);

View file

@ -107,6 +107,7 @@ inline uint32_t cn_select_mask(Algo algorithm)
template<Algo ALGO, Variant variant> inline constexpr uint32_t cn_select_iter() { return 0; } template<Algo ALGO, Variant variant> inline constexpr uint32_t cn_select_iter() { return 0; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_0>() { return CRYPTONIGHT_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_0>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_1>() { return CRYPTONIGHT_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_1>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_2>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_XTL>() { return CRYPTONIGHT_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_XTL>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_MSR>() { return CRYPTONIGHT_MSR_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_MSR>() { return CRYPTONIGHT_MSR_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_XAO>() { return CRYPTONIGHT_XAO_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_XAO>() { return CRYPTONIGHT_XAO_ITER; }
@ -150,29 +151,16 @@ inline uint32_t cn_select_iter(Algo algorithm, Variant variant)
} }
template<Variant variant> inline constexpr bool cn_is_monero() { return false; } template<Variant variant> inline constexpr Variant cn_base_variant() { return VARIANT_0; }
template<> inline constexpr bool cn_is_monero<VARIANT_0>() { return false; } template<> inline constexpr Variant cn_base_variant<VARIANT_0>() { return VARIANT_0; }
template<> inline constexpr bool cn_is_monero<VARIANT_1>() { return true; } template<> inline constexpr Variant cn_base_variant<VARIANT_1>() { return VARIANT_1; }
template<> inline constexpr bool cn_is_monero<VARIANT_TUBE>() { return true; } template<> inline constexpr Variant cn_base_variant<VARIANT_TUBE>() { return VARIANT_1; }
template<> inline constexpr bool cn_is_monero<VARIANT_XTL>() { return true; } template<> inline constexpr Variant cn_base_variant<VARIANT_XTL>() { return VARIANT_1; }
template<> inline constexpr bool cn_is_monero<VARIANT_MSR>() { return true; } template<> inline constexpr Variant cn_base_variant<VARIANT_MSR>() { return VARIANT_1; }
template<> inline constexpr bool cn_is_monero<VARIANT_XHV>() { return false; } template<> inline constexpr Variant cn_base_variant<VARIANT_XHV>() { return VARIANT_0; }
template<> inline constexpr bool cn_is_monero<VARIANT_XAO>() { return false; } template<> inline constexpr Variant cn_base_variant<VARIANT_XAO>() { return VARIANT_0; }
template<> inline constexpr bool cn_is_monero<VARIANT_RTO>() { return true; } template<> inline constexpr Variant cn_base_variant<VARIANT_RTO>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_2>() { return VARIANT_2; }
inline bool cn_is_monero(Variant variant)
{
switch (variant) {
case VARIANT_0:
case VARIANT_XHV:
case VARIANT_RTO:
return false;
default:
return true;
}
}
} /* namespace xmrig */ } /* namespace xmrig */

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -22,29 +23,31 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CRYPTONIGHT_MONERO_H__ #ifndef XMRIG_CRYPTONIGHT_MONERO_H
#define __CRYPTONIGHT_MONERO_H__ #define XMRIG_CRYPTONIGHT_MONERO_H
#include <fenv.h>
#include <math.h>
// VARIANT ALTERATIONS // VARIANT ALTERATIONS
#ifndef XMRIG_ARM #ifndef XMRIG_ARM
# define VARIANT1_INIT(part) \ # define VARIANT1_INIT(part) \
uint64_t tweak1_2_##part = 0; \ uint64_t tweak1_2_##part = 0; \
if (IS_MONERO) { \ if (IS_V1) { \
tweak1_2_##part = (*reinterpret_cast<const uint64_t*>(input + 35 + part * size) ^ \ tweak1_2_##part = (*reinterpret_cast<const uint64_t*>(input + 35 + part * size) ^ \
*(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24)); \ *(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24)); \
} }
#else #else
# define VARIANT1_INIT(part) \ # define VARIANT1_INIT(part) \
uint64_t tweak1_2_##part = 0; \ uint64_t tweak1_2_##part = 0; \
if (IS_MONERO) { \ if (IS_V1) { \
memcpy(&tweak1_2_##part, input + 35 + part * size, sizeof tweak1_2_##part); \ memcpy(&tweak1_2_##part, input + 35 + part * size, sizeof tweak1_2_##part); \
tweak1_2_##part ^= *(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24); \ tweak1_2_##part ^= *(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24); \
} }
#endif #endif
#define VARIANT1_1(p) \ #define VARIANT1_1(p) \
if (IS_MONERO) { \ if (IS_V1) { \
const uint8_t tmp = reinterpret_cast<const uint8_t*>(p)[11]; \ const uint8_t tmp = reinterpret_cast<const uint8_t*>(p)[11]; \
static const uint32_t table = 0x75310; \ static const uint32_t table = 0x75310; \
const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \
@ -52,9 +55,96 @@
} }
#define VARIANT1_2(p, part) \ #define VARIANT1_2(p, part) \
if (IS_MONERO) { \ if (IS_V1) { \
(p) ^= tweak1_2_##part; \ (p) ^= tweak1_2_##part; \
} }
#endif /* __CRYPTONIGHT_MONERO_H__ */ #ifndef XMRIG_ARM
# define VARIANT2_INIT(part) \
__m128i division_result_xmm_##part = _mm_cvtsi64_si128(h##part[12]); \
__m128i sqrt_result_xmm_##part = _mm_cvtsi64_si128(h##part[13]);
#ifdef _MSC_VER
# define VARIANT2_SET_ROUNDING_MODE() if (VARIANT == xmrig::VARIANT_2) { _control87(RC_DOWN, MCW_RC); }
#else
# define VARIANT2_SET_ROUNDING_MODE() if (VARIANT == xmrig::VARIANT_2) { fesetround(FE_DOWNWARD); }
#endif
# define VARIANT2_INTEGER_MATH(part, cl, cx) \
do { \
const uint64_t sqrt_result = static_cast<uint64_t>(_mm_cvtsi128_si64(sqrt_result_xmm_##part)); \
const uint64_t cx_0 = _mm_cvtsi128_si64(cx); \
cl ^= static_cast<uint64_t>(_mm_cvtsi128_si64(division_result_xmm_##part)) ^ (sqrt_result << 32); \
const uint32_t d = static_cast<uint32_t>(cx_0 + (sqrt_result << 1)) | 0x80000001UL; \
const uint64_t cx_1 = _mm_cvtsi128_si64(_mm_srli_si128(cx, 8)); \
const uint64_t division_result = static_cast<uint32_t>(cx_1 / d) + ((cx_1 % d) << 32); \
division_result_xmm_##part = _mm_cvtsi64_si128(static_cast<int64_t>(division_result)); \
sqrt_result_xmm_##part = int_sqrt_v2(cx_0 + division_result); \
} while (0)
# define VARIANT2_SHUFFLE(base_ptr, offset, _a, _b, _b1) \
do { \
const __m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))); \
const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \
const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \
} while (0)
# define VARIANT2_SHUFFLE2(base_ptr, offset, _a, _b, _b1, hi, lo) \
do { \
const __m128i chunk1 = _mm_xor_si128(_mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))), _mm_set_epi64x(lo, hi)); \
const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \
hi ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[0]; \
lo ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[1]; \
const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \
} while (0)
#else
# define VARIANT2_INIT(part) \
uint64_t division_result_##part = h##part[12]; \
uint64_t sqrt_result_##part = h##part[13];
# define VARIANT2_INTEGER_MATH(part, cl, cx) \
do { \
const uint64_t cx_0 = _mm_cvtsi128_si64(cx); \
cl ^= division_result_##part ^ (sqrt_result_##part << 32); \
const uint32_t d = static_cast<uint32_t>(cx_0 + (sqrt_result_##part << 1)) | 0x80000001UL; \
const uint64_t cx_1 = _mm_cvtsi128_si64(_mm_srli_si128(cx, 8)); \
division_result_##part = static_cast<uint32_t>(cx_1 / d) + ((cx_1 % d) << 32); \
const uint64_t sqrt_input = cx_0 + division_result_##part; \
sqrt_result_##part = sqrt(sqrt_input + 18446744073709551616.0) * 2.0 - 8589934592.0; \
const uint64_t s = sqrt_result_##part >> 1; \
const uint64_t b = sqrt_result_##part & 1; \
const uint64_t r2 = (uint64_t)(s) * (s + b) + (sqrt_result_##part << 32); \
sqrt_result_##part += ((r2 + b > sqrt_input) ? -1 : 0) + ((r2 + (1ULL << 32) < sqrt_input - s) ? 1 : 0); \
} while (0)
# define VARIANT2_SHUFFLE(base_ptr, offset, _a, _b, _b1) \
do { \
const uint64x2_t chunk1 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10))); \
const uint64x2_t chunk2 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20))); \
const uint64x2_t chunk3 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \
} while (0)
# define VARIANT2_SHUFFLE2(base_ptr, offset, _a, _b, _b1, hi, lo) \
do { \
const uint64x2_t chunk1 = veorq_u64(vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10))), vcombine_u64(vcreate_u64(hi), vcreate_u64(lo))); \
const uint64x2_t chunk2 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20))); \
hi ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[0]; \
lo ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[1]; \
const uint64x2_t chunk3 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \
} while (0)
#endif
#endif /* XMRIG_CRYPTONIGHT_MONERO_H */

View file

@ -69,7 +69,7 @@ const static uint8_t test_output_v0[160] = {
}; };
// Monero v7 // Cryptonight variant 1 (Monero v7)
const static uint8_t test_output_v1[160] = { const static uint8_t test_output_v1[160] = {
0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9, 0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9,
0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9, 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9,
@ -84,6 +84,21 @@ const static uint8_t test_output_v1[160] = {
}; };
// Cryptonight variant 2 (Monero v8)
const static uint8_t test_output_v2[160] = {
0x97, 0x37, 0x82, 0x82, 0xCF, 0x10, 0xE7, 0xAD, 0x03, 0x3F, 0x7B, 0x80, 0x74, 0xC4, 0x0E, 0x14,
0xD0, 0x6E, 0x7F, 0x60, 0x9D, 0xDD, 0xDA, 0x78, 0x76, 0x80, 0xB5, 0x8C, 0x05, 0xF4, 0x3D, 0x21,
0x87, 0x1F, 0xCD, 0x68, 0x23, 0xF6, 0xA8, 0x79, 0xBB, 0x3F, 0x33, 0x95, 0x1C, 0x8E, 0x8E, 0x89,
0x1D, 0x40, 0x43, 0x88, 0x0B, 0x02, 0xDF, 0xA1, 0xBB, 0x3B, 0xE4, 0x98, 0xB5, 0x0E, 0x75, 0x78,
0xE6, 0x0D, 0x24, 0x0F, 0x65, 0x85, 0x60, 0x3A, 0x4A, 0xE5, 0x5F, 0x54, 0x9B, 0xC8, 0x79, 0x93,
0xEB, 0x3D, 0x98, 0x2C, 0xFE, 0x9B, 0xFB, 0x15, 0xB6, 0x88, 0x21, 0x94, 0xB0, 0x05, 0x86, 0x5C,
0x59, 0x8B, 0x93, 0x7A, 0xDA, 0xD2, 0xA2, 0x14, 0xED, 0xB7, 0xC4, 0x5D, 0xA1, 0xEF, 0x26, 0xF3,
0xC7, 0x73, 0x29, 0x4D, 0xF1, 0xC8, 0x2C, 0xE0, 0xD0, 0xE9, 0xED, 0x0C, 0x70, 0x75, 0x05, 0x3E,
0x5B, 0xF6, 0xA0, 0x6E, 0xEA, 0xDE, 0x87, 0x0B, 0x06, 0x29, 0x03, 0xBF, 0xB4, 0x85, 0x9D, 0x04,
0x75, 0x1A, 0xCD, 0x1E, 0xD6, 0xAA, 0x1B, 0x05, 0x24, 0x6A, 0x2C, 0x80, 0x69, 0x68, 0xDC, 0x97
};
// Stellite (XTL) // Stellite (XTL)
const static uint8_t test_output_xtl[160] = { const static uint8_t test_output_xtl[160] = {
0x8F, 0xE5, 0xF0, 0x5F, 0x02, 0x2A, 0x61, 0x7D, 0xE5, 0x3F, 0x79, 0x36, 0x4B, 0x25, 0xCB, 0xC3, 0x8F, 0xE5, 0xF0, 0x5F, 0x02, 0x2A, 0x61, 0x7D, 0xE5, 0x3F, 0x79, 0x36, 0x4B, 0x25, 0xCB, 0xC3,

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -22,8 +23,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CRYPTONIGHT_X86_H__ #ifndef XMRIG_CRYPTONIGHT_X86_H
#define __CRYPTONIGHT_X86_H__ #define XMRIG_CRYPTONIGHT_X86_H
#ifdef __GNUC__ #ifdef __GNUC__
@ -73,10 +74,7 @@ static inline void do_skein_hash(const uint8_t *input, size_t len, uint8_t *outp
void (* const extra_hashes[4])(const uint8_t *, size_t, uint8_t *) = {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};
#if defined(__x86_64__) || defined(_M_AMD64) #if defined(__x86_64__) || defined(_M_AMD64)
# define EXTRACT64(X) _mm_cvtsi128_si64(X)
# ifdef __GNUC__ # ifdef __GNUC__
static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi) static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi)
{ {
@ -88,13 +86,14 @@ static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi)
#define __umul128 _umul128 #define __umul128 _umul128
# endif # endif
#elif defined(__i386__) || defined(_M_IX86) #elif defined(__i386__) || defined(_M_IX86)
# define HI32(X) \ static inline int64_t _mm_cvtsi128_si64(__m128i a)
_mm_srli_si128((X), 4) {
return ((uint64_t)(uint32_t)_mm_cvtsi128_si32(a) | ((uint64_t)(uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(a, 4)) << 32));
}
static inline __m128i _mm_cvtsi64_si128(int64_t a) {
# define EXTRACT64(X) \ return _mm_set_epi64x(0, a);
((uint64_t)(uint32_t)_mm_cvtsi128_si32(X) | \ }
((uint64_t)(uint32_t)_mm_cvtsi128_si32(HI32(X)) << 32))
static inline uint64_t __umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) { static inline uint64_t __umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) {
// multiplier = ab = a * 2^32 + b // multiplier = ab = a * 2^32 + b
@ -408,20 +407,46 @@ static inline __m128i aes_round_tweak_div(const __m128i &in, const __m128i &key)
} }
template<int SHIFT> static inline __m128i int_sqrt_v2(const uint64_t n0)
static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp)
{ {
mem_out[0] = EXTRACT64(tmp); __m128d x = _mm_castsi128_pd(_mm_add_epi64(_mm_cvtsi64_si128(n0 >> 12), _mm_set_epi64x(0, 1023ULL << 52)));
x = _mm_sqrt_sd(_mm_setzero_pd(), x);
uint64_t r = static_cast<uint64_t>(_mm_cvtsi128_si64(_mm_castpd_si128(x)));
tmp = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(tmp), _mm_castsi128_ps(tmp))); const uint64_t s = r >> 20;
uint64_t vh = EXTRACT64(tmp); r >>= 19;
uint8_t x = vh >> 24; uint64_t x2 = (s - (1022ULL << 32)) * (r - s - (1022ULL << 32) + 1);
static const uint16_t table = 0x7531; # if (defined(_MSC_VER) || __GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 1)) && (defined(__x86_64__) || defined(_M_AMD64))
const uint8_t index = (((x >> SHIFT) & 6) | (x & 1)) << 1; _addcarry_u64(_subborrow_u64(0, x2, n0, (unsigned long long int*)&x2), r, 0, (unsigned long long int*)&r);
vh ^= ((table >> index) & 0x3) << 28; # else
if (x2 < n0) ++r;
# endif
mem_out[1] = vh; return _mm_cvtsi64_si128(r);
}
template<xmrig::Variant VARIANT>
static inline void cryptonight_monero_tweak(uint64_t* mem_out, const uint8_t* l, uint64_t idx, __m128i ax0, __m128i bx0, __m128i bx1, __m128i cx)
{
if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1);
_mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx));
} else {
__m128i tmp = _mm_xor_si128(bx0, cx);
mem_out[0] = _mm_cvtsi128_si64(tmp);
tmp = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(tmp), _mm_castsi128_ps(tmp)));
uint64_t vh = _mm_cvtsi128_si64(tmp);
uint8_t x = static_cast<uint8_t>(vh >> 24);
static const uint16_t table = 0x7531;
const uint8_t index = (((x >> (VARIANT == xmrig::VARIANT_XTL ? 4 : 3)) & 6) | (x & 1)) << 1;
vh ^= ((table >> index) & 0x3) << 28;
mem_out[1] = vh;
}
} }
@ -431,25 +456,28 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>(); constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>(); constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>(); constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
constexpr bool IS_MONERO = xmrig::cn_is_monero<VARIANT>(); constexpr bool IS_V1 = xmrig::cn_base_variant<VARIANT>() == xmrig::VARIANT_1;
if (IS_MONERO && size < 43) { if (IS_V1 && size < 43) {
memset(output, 0, 32); memset(output, 0, 32);
return; return;
} }
xmrig::keccak(input, size, ctx[0]->state); xmrig::keccak(input, size, ctx[0]->state);
VARIANT1_INIT(0)
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory);
const uint8_t* l0 = ctx[0]->memory; const uint8_t* l0 = ctx[0]->memory;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state); uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
VARIANT1_INIT(0);
VARIANT2_INIT(0);
VARIANT2_SET_ROUNDING_MODE();
uint64_t al0 = h0[0] ^ h0[4]; uint64_t al0 = h0[0] ^ h0[4];
uint64_t ah0 = h0[1] ^ h0[5]; uint64_t ah0 = h0[1] ^ h0[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]);
uint64_t idx0 = al0; uint64_t idx0 = al0;
@ -459,44 +487,47 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
} }
const __m128i ax0 = _mm_set_epi64x(ah0, al0);
if (VARIANT == xmrig::VARIANT_TUBE) { if (VARIANT == xmrig::VARIANT_TUBE) {
cx = aes_round_tweak_div(cx, _mm_set_epi64x(ah0, al0)); cx = aes_round_tweak_div(cx, ax0);
} }
else if (SOFT_AES) { else if (SOFT_AES) {
cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0)); cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0);
} }
else { else {
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); cx = _mm_aesenc_si128(cx, ax0);
} }
if (IS_MONERO) { if (IS_V1 || VARIANT == xmrig::VARIANT_2) {
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); cryptonight_monero_tweak<VARIANT>((uint64_t*)&l0[idx0 & MASK], l0, idx0 & MASK, ax0, bx0, bx1, cx);
} else { } else {
_mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
} }
idx0 = EXTRACT64(cx); idx0 = _mm_cvtsi128_si64(cx);
bx0 = cx;
uint64_t hi, lo, cl, ch; uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0]; cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1]; ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi); if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_INTEGER_MATH(0, cl, cx);
lo = __umul128(idx0, cl, &hi);
VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo);
}
else {
lo = __umul128(idx0, cl, &hi);
}
al0 += hi; al0 += hi;
ah0 += lo; ah0 += lo;
((uint64_t*)&l0[idx0 & MASK])[0] = al0; ((uint64_t*)&l0[idx0 & MASK])[0] = al0;
if (IS_MONERO) { if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) {
if (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO) { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0;
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; } else if (IS_V1) {
} ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
else { } else {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
}
}
else {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0; ((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
} }
@ -517,6 +548,10 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
idx0 = d ^ q; idx0 = d ^ q;
} }
if (VARIANT == xmrig::VARIANT_2) {
bx1 = bx0;
}
bx0 = cx;
} }
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state);
@ -526,15 +561,67 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
} }
#ifndef XMRIG_NO_ASM
extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx *ctx);
extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx *ctx);
extern "C" void cnv2_double_mainloop_sandybridge_asm(cryptonight_ctx* ctx0, cryptonight_ctx* ctx1);
template<xmrig::Algo ALGO, xmrig::Variant VARIANT, xmrig::Assembly ASM>
inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
{
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
xmrig::keccak(input, size, ctx[0]->state);
cn_explode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory));
if (ASM == xmrig::ASM_INTEL) {
cnv2_mainloop_ivybridge_asm(ctx[0]);
}
else {
cnv2_mainloop_ryzen_asm(ctx[0]);
}
cn_implode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state));
xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[0]->state), 24);
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
}
template<xmrig::Algo ALGO, xmrig::Variant VARIANT, xmrig::Assembly ASM>
inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
{
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
xmrig::keccak(input, size, ctx[0]->state);
xmrig::keccak(input + size, size, ctx[1]->state);
cn_explode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory));
cn_explode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[1]->state), reinterpret_cast<__m128i*>(ctx[1]->memory));
cnv2_double_mainloop_sandybridge_asm(ctx[0], ctx[1]);
cn_implode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state));
cn_implode_scratchpad<ALGO, MEM, false>(reinterpret_cast<__m128i*>(ctx[1]->memory), reinterpret_cast<__m128i*>(ctx[1]->state));
xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[0]->state), 24);
xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[1]->state), 24);
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32);
}
#endif
template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT> template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT>
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) inline void cryptonight_double_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 MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>(); constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>(); constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
constexpr bool IS_MONERO = xmrig::cn_is_monero<VARIANT>(); constexpr bool IS_V1 = xmrig::cn_base_variant<VARIANT>() == xmrig::VARIANT_1;
if (IS_MONERO && size < 43) { if (IS_V1 && size < 43) {
memset(output, 0, 64); memset(output, 0, 64);
return; return;
} }
@ -542,14 +629,17 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
xmrig::keccak(input, size, ctx[0]->state); xmrig::keccak(input, size, ctx[0]->state);
xmrig::keccak(input + size, size, ctx[1]->state); xmrig::keccak(input + size, size, ctx[1]->state);
VARIANT1_INIT(0);
VARIANT1_INIT(1);
const uint8_t* l0 = ctx[0]->memory; const uint8_t* l0 = ctx[0]->memory;
const uint8_t* l1 = ctx[1]->memory; const uint8_t* l1 = ctx[1]->memory;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state); uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state); uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
VARIANT1_INIT(0);
VARIANT1_INIT(1);
VARIANT2_INIT(0);
VARIANT2_INIT(1);
VARIANT2_SET_ROUNDING_MODE();
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
@ -558,8 +648,10 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
uint64_t ah0 = h0[1] ^ h0[5]; uint64_t ah0 = h0[1] ^ h0[5];
uint64_t ah1 = h1[1] ^ h1[5]; uint64_t ah1 = h1[1] ^ h1[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); __m128i bx00 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); __m128i bx01 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]);
__m128i bx10 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
__m128i bx11 = _mm_set_epi64x(h1[9] ^ h1[11], h1[8] ^ h1[10]);
uint64_t idx0 = al0; uint64_t idx0 = al0;
uint64_t idx1 = al1; uint64_t idx1 = al1;
@ -571,53 +663,54 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]);
} }
const __m128i ax0 = _mm_set_epi64x(ah0, al0);
const __m128i ax1 = _mm_set_epi64x(ah1, al1);
if (VARIANT == xmrig::VARIANT_TUBE) { if (VARIANT == xmrig::VARIANT_TUBE) {
cx0 = aes_round_tweak_div(cx0, _mm_set_epi64x(ah0, al0)); cx0 = aes_round_tweak_div(cx0, ax0);
cx1 = aes_round_tweak_div(cx1, _mm_set_epi64x(ah1, al1)); cx1 = aes_round_tweak_div(cx1, ax1);
} }
else if (SOFT_AES) { else if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0)); cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0);
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1)); cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], ax1);
} }
else { else {
cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); cx0 = _mm_aesenc_si128(cx0, ax0);
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); cx1 = _mm_aesenc_si128(cx1, ax1);
} }
if (IS_MONERO) { if (IS_V1 || (VARIANT == xmrig::VARIANT_2)) {
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); cryptonight_monero_tweak<VARIANT>((uint64_t*)&l0[idx0 & MASK], l0, idx0 & MASK, ax0, bx00, bx01, cx0);
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); cryptonight_monero_tweak<VARIANT>((uint64_t*)&l1[idx1 & MASK], l1, idx1 & MASK, ax1, bx10, bx11, cx1);
} else { } else {
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx00, cx0));
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx10, cx1));
} }
idx0 = EXTRACT64(cx0); idx0 = _mm_cvtsi128_si64(cx0);
idx1 = EXTRACT64(cx1); idx1 = _mm_cvtsi128_si64(cx1);
bx0 = cx0;
bx1 = cx1;
uint64_t hi, lo, cl, ch; uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0]; cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1]; ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi); if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_INTEGER_MATH(0, cl, cx0);
lo = __umul128(idx0, cl, &hi);
VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo);
} else {
lo = __umul128(idx0, cl, &hi);
}
al0 += hi; al0 += hi;
ah0 += lo; ah0 += lo;
((uint64_t*)&l0[idx0 & MASK])[0] = al0; ((uint64_t*)&l0[idx0 & MASK])[0] = al0;
if (IS_MONERO) { if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) {
if (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO) { ((uint64_t*) &l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0;
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; } else if (IS_V1) {
} ((uint64_t*) &l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
else { } else {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; ((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
}
}
else {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
} }
al0 ^= cl; al0 ^= cl;
@ -640,22 +733,24 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
cl = ((uint64_t*) &l1[idx1 & MASK])[0]; cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1]; ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi); if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_INTEGER_MATH(1, cl, cx1);
lo = __umul128(idx1, cl, &hi);
VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo);
} else {
lo = __umul128(idx1, cl, &hi);
}
al1 += hi; al1 += hi;
ah1 += lo; ah1 += lo;
((uint64_t*)&l1[idx1 & MASK])[0] = al1; ((uint64_t*)&l1[idx1 & MASK])[0] = al1;
if (IS_MONERO) { if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) {
if (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO) { ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1;
((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1; } else if (IS_V1) {
} ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1;
else { } else {
((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1;
}
}
else {
((uint64_t*)&l1[idx1 & MASK])[1] = ah1; ((uint64_t*)&l1[idx1 & MASK])[1] = ah1;
} }
@ -676,6 +771,13 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
idx1 = d ^ q; idx1 = d ^ q;
} }
if (VARIANT == xmrig::VARIANT_2) {
bx01 = bx00;
bx11 = bx10;
}
bx00 = cx0;
bx10 = cx1;
} }
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
@ -689,12 +791,12 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
} }
#define CN_STEP1(a, b, c, l, ptr, idx) \ #define CN_STEP1(a, b0, b1, c, l, ptr, idx) \
ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \ ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \
c = _mm_load_si128(ptr); c = _mm_load_si128(ptr);
#define CN_STEP2(a, b, c, l, ptr, idx) \ #define CN_STEP2(a, b0, b1, c, l, ptr, idx) \
if (VARIANT == xmrig::VARIANT_TUBE) { \ if (VARIANT == xmrig::VARIANT_TUBE) { \
c = aes_round_tweak_div(c, a); \ c = aes_round_tweak_div(c, a); \
} \ } \
@ -704,26 +806,31 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
c = _mm_aesenc_si128(c, a); \ c = _mm_aesenc_si128(c, a); \
} \ } \
\ \
b = _mm_xor_si128(b, c); \ if (IS_V1 || (VARIANT == xmrig::VARIANT_2)) { \
\ cryptonight_monero_tweak<VARIANT>((uint64_t*)ptr, l, idx & MASK, a, b0, b1, c); \
if (IS_MONERO) { \
cryptonight_monero_tweak<VARIANT == xmrig::VARIANT_XTL ? 4 : 3>(reinterpret_cast<uint64_t*>(ptr), b); \
} else { \ } else { \
_mm_store_si128(ptr, b); \ _mm_store_si128(ptr, _mm_xor_si128(b0, c)); \
} }
#define CN_STEP3(a, b, c, l, ptr, idx) \ #define CN_STEP3(part, a, b0, b1, c, l, ptr, idx) \
idx = EXTRACT64(c); \ idx = _mm_cvtsi128_si64(c); \
ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \ ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \
b = _mm_load_si128(ptr); uint64_t cl##part = ((uint64_t*)ptr)[0]; \
uint64_t ch##part = ((uint64_t*)ptr)[1];
#define CN_STEP4(a, b, c, l, mc, ptr, idx) \ #define CN_STEP4(part, a, b0, b1, c, l, mc, ptr, idx) \
lo = __umul128(idx, EXTRACT64(b), &hi); \ if (VARIANT == xmrig::VARIANT_2) { \
VARIANT2_INTEGER_MATH(part, cl##part, c); \
lo = __umul128(idx, cl##part, &hi); \
VARIANT2_SHUFFLE2(l, idx & MASK, a, b0, b1, hi, lo); \
} else { \
lo = __umul128(idx, cl##part, &hi); \
} \
a = _mm_add_epi64(a, _mm_set_epi64x(lo, hi)); \ a = _mm_add_epi64(a, _mm_set_epi64x(lo, hi)); \
\ \
if (IS_MONERO) { \ if (IS_V1) { \
_mm_store_si128(ptr, _mm_xor_si128(a, mc)); \ _mm_store_si128(ptr, _mm_xor_si128(a, mc)); \
\ \
if (VARIANT == xmrig::VARIANT_TUBE || \ if (VARIANT == xmrig::VARIANT_TUBE || \
@ -734,8 +841,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
_mm_store_si128(ptr, a); \ _mm_store_si128(ptr, a); \
} \ } \
\ \
a = _mm_xor_si128(a, b); \ a = _mm_xor_si128(a, _mm_set_epi64x(ch##part, cl##part)); \
idx = EXTRACT64(a); \ idx = _mm_cvtsi128_si64(a); \
\ \
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { \ if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { \
int64_t n = ((int64_t*)&l[idx & MASK])[0]; \ int64_t n = ((int64_t*)&l[idx & MASK])[0]; \
@ -747,15 +854,29 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
} \ } \
\ \
idx = d ^ q; \ idx = d ^ q; \
} } \
if (VARIANT == xmrig::VARIANT_2) { \
b1 = b0; \
} \
b0 = c;
#define CONST_INIT(ctx, n) \ #define CONST_INIT(ctx, n) \
__m128i mc##n; \ __m128i mc##n; \
if (IS_MONERO) { \ __m128i division_result_xmm_##n; \
__m128i sqrt_result_xmm_##n; \
if (IS_V1) { \
mc##n = _mm_set_epi64x(*reinterpret_cast<const uint64_t*>(input + n * size + 35) ^ \ mc##n = _mm_set_epi64x(*reinterpret_cast<const uint64_t*>(input + n * size + 35) ^ \
*(reinterpret_cast<const uint64_t*>((ctx)->state) + 24), 0); \ *(reinterpret_cast<const uint64_t*>((ctx)->state) + 24), 0); \
} } \
if (VARIANT == xmrig::VARIANT_2) { \
division_result_xmm_##n = _mm_cvtsi64_si128(h##n[12]); \
sqrt_result_xmm_##n = _mm_cvtsi64_si128(h##n[13]); \
} \
__m128i ax##n = _mm_set_epi64x(h##n[1] ^ h##n[5], h##n[0] ^ h##n[4]); \
__m128i bx##n##0 = _mm_set_epi64x(h##n[3] ^ h##n[7], h##n[2] ^ h##n[6]); \
__m128i bx##n##1 = _mm_set_epi64x(h##n[9] ^ h##n[11], h##n[8] ^ h##n[10]); \
__m128i cx##n = _mm_setzero_si128();
template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT> template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT>
@ -764,9 +885,9 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>(); constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>(); constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>(); constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
constexpr bool IS_MONERO = xmrig::cn_is_monero<VARIANT>(); constexpr bool IS_V1 = xmrig::cn_base_variant<VARIANT>() == xmrig::VARIANT_1;
if (IS_MONERO && size < 43) { if (IS_V1 && size < 43) {
memset(output, 0, 32 * 3); memset(output, 0, 32 * 3);
return; return;
} }
@ -776,10 +897,6 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
} }
CONST_INIT(ctx[0], 0);
CONST_INIT(ctx[1], 1);
CONST_INIT(ctx[2], 2);
uint8_t* l0 = ctx[0]->memory; uint8_t* l0 = ctx[0]->memory;
uint8_t* l1 = ctx[1]->memory; uint8_t* l1 = ctx[1]->memory;
uint8_t* l2 = ctx[2]->memory; uint8_t* l2 = ctx[2]->memory;
@ -787,58 +904,35 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state); uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx[2]->state); uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx[2]->state);
__m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); CONST_INIT(ctx[0], 0);
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); CONST_INIT(ctx[1], 1);
__m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); CONST_INIT(ctx[2], 2);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); VARIANT2_SET_ROUNDING_MODE();
__m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]);
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
__m128i cx0 = _mm_set_epi64x(0, 0);
__m128i cx1 = _mm_set_epi64x(0, 0);
__m128i cx2 = _mm_set_epi64x(0, 0);
uint64_t idx0, idx1, idx2; uint64_t idx0, idx1, idx2;
idx0 = EXTRACT64(ax0); idx0 = _mm_cvtsi128_si64(ax0);
idx1 = EXTRACT64(ax1); idx1 = _mm_cvtsi128_si64(ax1);
idx2 = EXTRACT64(ax2); idx2 = _mm_cvtsi128_si64(ax2);
for (size_t i = 0; i < ITERATIONS / 2; i++) { for (size_t i = 0; i < ITERATIONS; i++) {
uint64_t hi, lo; uint64_t hi, lo;
__m128i *ptr0, *ptr1, *ptr2; __m128i *ptr0, *ptr1, *ptr2;
// EVEN ROUND CN_STEP1(ax0, bx00, bx01, cx0, l0, ptr0, idx0);
CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); CN_STEP1(ax1, bx10, bx11, cx1, l1, ptr1, idx1);
CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); CN_STEP1(ax2, bx20, bx21, cx2, l2, ptr2, idx2);
CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2);
CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); CN_STEP2(ax0, bx00, bx01, cx0, l0, ptr0, idx0);
CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); CN_STEP2(ax1, bx10, bx11, cx1, l1, ptr1, idx1);
CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); CN_STEP2(ax2, bx20, bx21, cx2, l2, ptr2, idx2);
CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); CN_STEP3(0, ax0, bx00, bx01, cx0, l0, ptr0, idx0);
CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); CN_STEP3(1, ax1, bx10, bx11, cx1, l1, ptr1, idx1);
CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); CN_STEP3(2, ax2, bx20, bx21, cx2, l2, ptr2, idx2);
CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); CN_STEP4(0, ax0, bx00, bx01, cx0, l0, mc0, ptr0, idx0);
CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); CN_STEP4(1, ax1, bx10, bx11, cx1, l1, mc1, ptr1, idx1);
CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); CN_STEP4(2, ax2, bx20, bx21, cx2, l2, mc2, ptr2, idx2);
// ODD ROUND
CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0);
CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1);
CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2);
CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0);
CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1);
CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2);
CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0);
CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1);
CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2);
CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0);
CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1);
CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2);
} }
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
@ -855,9 +949,9 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>(); constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>(); constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>(); constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
constexpr bool IS_MONERO = xmrig::cn_is_monero<VARIANT>(); constexpr bool IS_V1 = xmrig::cn_base_variant<VARIANT>() == xmrig::VARIANT_1;;
if (IS_MONERO && size < 43) { if (IS_V1 && size < 43) {
memset(output, 0, 32 * 4); memset(output, 0, 32 * 4);
return; return;
} }
@ -867,11 +961,6 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
} }
CONST_INIT(ctx[0], 0);
CONST_INIT(ctx[1], 1);
CONST_INIT(ctx[2], 2);
CONST_INIT(ctx[3], 3);
uint8_t* l0 = ctx[0]->memory; uint8_t* l0 = ctx[0]->memory;
uint8_t* l1 = ctx[1]->memory; uint8_t* l1 = ctx[1]->memory;
uint8_t* l2 = ctx[2]->memory; uint8_t* l2 = ctx[2]->memory;
@ -881,71 +970,42 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx[2]->state); uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx[2]->state);
uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx[3]->state); uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx[3]->state);
__m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); CONST_INIT(ctx[0], 0);
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); CONST_INIT(ctx[1], 1);
__m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); CONST_INIT(ctx[2], 2);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); CONST_INIT(ctx[3], 3);
__m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); VARIANT2_SET_ROUNDING_MODE();
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
__m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]);
__m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]);
__m128i cx0 = _mm_set_epi64x(0, 0);
__m128i cx1 = _mm_set_epi64x(0, 0);
__m128i cx2 = _mm_set_epi64x(0, 0);
__m128i cx3 = _mm_set_epi64x(0, 0);
uint64_t idx0, idx1, idx2, idx3; uint64_t idx0, idx1, idx2, idx3;
idx0 = EXTRACT64(ax0); idx0 = _mm_cvtsi128_si64(ax0);
idx1 = EXTRACT64(ax1); idx1 = _mm_cvtsi128_si64(ax1);
idx2 = EXTRACT64(ax2); idx2 = _mm_cvtsi128_si64(ax2);
idx3 = EXTRACT64(ax3); idx3 = _mm_cvtsi128_si64(ax3);
for (size_t i = 0; i < ITERATIONS / 2; i++) for (size_t i = 0; i < ITERATIONS; i++)
{ {
uint64_t hi, lo; uint64_t hi, lo;
__m128i *ptr0, *ptr1, *ptr2, *ptr3; __m128i *ptr0, *ptr1, *ptr2, *ptr3;
// EVEN ROUND CN_STEP1(ax0, bx00, bx01, cx0, l0, ptr0, idx0);
CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); CN_STEP1(ax1, bx10, bx11, cx1, l1, ptr1, idx1);
CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); CN_STEP1(ax2, bx20, bx21, cx2, l2, ptr2, idx2);
CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); CN_STEP1(ax3, bx30, bx31, cx3, l3, ptr3, idx3);
CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3);
CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); CN_STEP2(ax0, bx00, bx01, cx0, l0, ptr0, idx0);
CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); CN_STEP2(ax1, bx10, bx11, cx1, l1, ptr1, idx1);
CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); CN_STEP2(ax2, bx20, bx21, cx2, l2, ptr2, idx2);
CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3); CN_STEP2(ax3, bx30, bx31, cx3, l3, ptr3, idx3);
CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); CN_STEP3(0, ax0, bx00, bx01, cx0, l0, ptr0, idx0);
CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); CN_STEP3(1, ax1, bx10, bx11, cx1, l1, ptr1, idx1);
CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); CN_STEP3(2, ax2, bx20, bx21, cx2, l2, ptr2, idx2);
CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3); CN_STEP3(3, ax3, bx30, bx31, cx3, l3, ptr3, idx3);
CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); CN_STEP4(0, ax0, bx00, bx01, cx0, l0, mc0, ptr0, idx0);
CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); CN_STEP4(1, ax1, bx10, bx11, cx1, l1, mc1, ptr1, idx1);
CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); CN_STEP4(2, ax2, bx20, bx21, cx2, l2, mc2, ptr2, idx2);
CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3); CN_STEP4(3, ax3, bx30, bx31, cx3, l3, mc3, ptr3, idx3);
// ODD ROUND
CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0);
CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1);
CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2);
CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3);
CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0);
CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1);
CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2);
CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3);
CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0);
CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1);
CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2);
CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3);
CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0);
CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1);
CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2);
CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3);
} }
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 4; i++) {
@ -962,9 +1022,9 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>(); constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>(); constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>(); constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
constexpr bool IS_MONERO = xmrig::cn_is_monero<VARIANT>(); constexpr bool IS_V1 = xmrig::cn_base_variant<VARIANT>() == xmrig::VARIANT_1;
if (IS_MONERO && size < 43) { if (IS_V1 && size < 43) {
memset(output, 0, 32 * 5); memset(output, 0, 32 * 5);
return; return;
} }
@ -974,12 +1034,6 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
} }
CONST_INIT(ctx[0], 0);
CONST_INIT(ctx[1], 1);
CONST_INIT(ctx[2], 2);
CONST_INIT(ctx[3], 3);
CONST_INIT(ctx[4], 4);
uint8_t* l0 = ctx[0]->memory; uint8_t* l0 = ctx[0]->memory;
uint8_t* l1 = ctx[1]->memory; uint8_t* l1 = ctx[1]->memory;
uint8_t* l2 = ctx[2]->memory; uint8_t* l2 = ctx[2]->memory;
@ -991,83 +1045,48 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz
uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx[3]->state); uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx[3]->state);
uint64_t* h4 = reinterpret_cast<uint64_t*>(ctx[4]->state); uint64_t* h4 = reinterpret_cast<uint64_t*>(ctx[4]->state);
__m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); CONST_INIT(ctx[0], 0);
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); CONST_INIT(ctx[1], 1);
__m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); CONST_INIT(ctx[2], 2);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); CONST_INIT(ctx[3], 3);
__m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); CONST_INIT(ctx[4], 4);
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]); VARIANT2_SET_ROUNDING_MODE();
__m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]);
__m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]);
__m128i ax4 = _mm_set_epi64x(h4[1] ^ h4[5], h4[0] ^ h4[4]);
__m128i bx4 = _mm_set_epi64x(h4[3] ^ h4[7], h4[2] ^ h4[6]);
__m128i cx0 = _mm_set_epi64x(0, 0);
__m128i cx1 = _mm_set_epi64x(0, 0);
__m128i cx2 = _mm_set_epi64x(0, 0);
__m128i cx3 = _mm_set_epi64x(0, 0);
__m128i cx4 = _mm_set_epi64x(0, 0);
uint64_t idx0, idx1, idx2, idx3, idx4; uint64_t idx0, idx1, idx2, idx3, idx4;
idx0 = EXTRACT64(ax0); idx0 = _mm_cvtsi128_si64(ax0);
idx1 = EXTRACT64(ax1); idx1 = _mm_cvtsi128_si64(ax1);
idx2 = EXTRACT64(ax2); idx2 = _mm_cvtsi128_si64(ax2);
idx3 = EXTRACT64(ax3); idx3 = _mm_cvtsi128_si64(ax3);
idx4 = EXTRACT64(ax4); idx4 = _mm_cvtsi128_si64(ax4);
for (size_t i = 0; i < ITERATIONS / 2; i++) for (size_t i = 0; i < ITERATIONS; i++)
{ {
uint64_t hi, lo; uint64_t hi, lo;
__m128i *ptr0, *ptr1, *ptr2, *ptr3, *ptr4; __m128i *ptr0, *ptr1, *ptr2, *ptr3, *ptr4;
// EVEN ROUND CN_STEP1(ax0, bx00, bx01, cx0, l0, ptr0, idx0);
CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); CN_STEP1(ax1, bx10, bx11, cx1, l1, ptr1, idx1);
CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); CN_STEP1(ax2, bx20, bx21, cx2, l2, ptr2, idx2);
CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); CN_STEP1(ax3, bx30, bx31, cx3, l3, ptr3, idx3);
CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3); CN_STEP1(ax4, bx40, bx41, cx4, l4, ptr4, idx4);
CN_STEP1(ax4, bx4, cx4, l4, ptr4, idx4);
CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); CN_STEP2(ax0, bx00, bx01, cx0, l0, ptr0, idx0);
CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); CN_STEP2(ax1, bx10, bx11, cx1, l1, ptr1, idx1);
CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); CN_STEP2(ax2, bx20, bx21, cx2, l2, ptr2, idx2);
CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3); CN_STEP2(ax3, bx30, bx31, cx3, l3, ptr3, idx3);
CN_STEP2(ax4, bx4, cx4, l4, ptr4, idx4); CN_STEP2(ax4, bx40, bx41, cx4, l4, ptr4, idx4);
CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); CN_STEP3(0, ax0, bx00, bx01, cx0, l0, ptr0, idx0);
CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); CN_STEP3(1, ax1, bx10, bx11, cx1, l1, ptr1, idx1);
CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); CN_STEP3(2, ax2, bx20, bx21, cx2, l2, ptr2, idx2);
CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3); CN_STEP3(3, ax3, bx30, bx31, cx3, l3, ptr3, idx3);
CN_STEP3(ax4, bx4, cx4, l4, ptr4, idx4); CN_STEP3(4, ax4, bx40, bx41, cx4, l4, ptr4, idx4);
CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); CN_STEP4(0, ax0, bx00, bx01, cx0, l0, mc0, ptr0, idx0);
CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); CN_STEP4(1, ax1, bx10, bx11, cx1, l1, mc1, ptr1, idx1);
CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); CN_STEP4(2, ax2, bx20, bx21, cx2, l2, mc2, ptr2, idx2);
CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3); CN_STEP4(3, ax3, bx30, bx31, cx3, l3, mc3, ptr3, idx3);
CN_STEP4(ax4, bx4, cx4, l4, mc4, ptr4, idx4); CN_STEP4(4, ax4, bx40, bx41, cx4, l4, mc4, ptr4, idx4);
// ODD ROUND
CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0);
CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1);
CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2);
CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3);
CN_STEP1(ax4, cx4, bx4, l4, ptr4, idx4);
CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0);
CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1);
CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2);
CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3);
CN_STEP2(ax4, cx4, bx4, l4, ptr4, idx4);
CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0);
CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1);
CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2);
CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3);
CN_STEP3(ax4, cx4, bx4, l4, ptr4, idx4);
CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0);
CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1);
CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2);
CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3);
CN_STEP4(ax4, cx4, bx4, l4, mc4, ptr4, idx4);
} }
for (size_t i = 0; i < 5; i++) { for (size_t i = 0; i < 5; i++) {
@ -1077,4 +1096,4 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz
} }
} }
#endif /* __CRYPTONIGHT_X86_H__ */ #endif /* XMRIG_CRYPTONIGHT_X86_H */

View file

@ -0,0 +1,410 @@
mov rax, rsp
push rbx
push rbp
push rsi
push rdi
push r12
push r13
push r14
push r15
sub rsp, 184
stmxcsr DWORD PTR [rsp+272]
mov DWORD PTR [rsp+276], 24448
ldmxcsr DWORD PTR [rsp+276]
mov r13, QWORD PTR [rcx+224]
mov r9, rdx
mov r10, QWORD PTR [rcx+32]
mov r8, rcx
xor r10, QWORD PTR [rcx]
mov r14d, 524288
mov r11, QWORD PTR [rcx+40]
xor r11, QWORD PTR [rcx+8]
mov rsi, QWORD PTR [rdx+224]
mov rdx, QWORD PTR [rcx+56]
xor rdx, QWORD PTR [rcx+24]
mov rdi, QWORD PTR [r9+32]
xor rdi, QWORD PTR [r9]
mov rbp, QWORD PTR [r9+40]
xor rbp, QWORD PTR [r9+8]
movq xmm0, rdx
movaps XMMWORD PTR [rax-88], xmm6
movaps XMMWORD PTR [rax-104], xmm7
movaps XMMWORD PTR [rax-120], xmm8
movaps XMMWORD PTR [rsp+112], xmm9
movaps XMMWORD PTR [rsp+96], xmm10
movaps XMMWORD PTR [rsp+80], xmm11
movaps XMMWORD PTR [rsp+64], xmm12
movaps XMMWORD PTR [rsp+48], xmm13
movaps XMMWORD PTR [rsp+32], xmm14
movaps XMMWORD PTR [rsp+16], xmm15
mov rdx, r10
movq xmm4, QWORD PTR [r8+96]
and edx, 2097136
mov rax, QWORD PTR [rcx+48]
xorps xmm13, xmm13
xor rax, QWORD PTR [rcx+16]
mov rcx, QWORD PTR [rcx+88]
xor rcx, QWORD PTR [r8+72]
movq xmm5, QWORD PTR [r8+104]
movq xmm7, rax
mov eax, 1
shl rax, 52
movq xmm14, rax
punpcklqdq xmm14, xmm14
mov eax, 1023
shl rax, 52
movq xmm12, rax
punpcklqdq xmm12, xmm12
mov rax, QWORD PTR [r8+80]
xor rax, QWORD PTR [r8+64]
punpcklqdq xmm7, xmm0
movq xmm0, rcx
mov rcx, QWORD PTR [r9+56]
xor rcx, QWORD PTR [r9+24]
movq xmm3, rax
mov rax, QWORD PTR [r9+48]
xor rax, QWORD PTR [r9+16]
punpcklqdq xmm3, xmm0
movq xmm0, rcx
mov QWORD PTR [rsp], r13
mov rcx, QWORD PTR [r9+88]
xor rcx, QWORD PTR [r9+72]
movq xmm6, rax
mov rax, QWORD PTR [r9+80]
xor rax, QWORD PTR [r9+64]
punpcklqdq xmm6, xmm0
movq xmm0, rcx
mov QWORD PTR [rsp+256], r10
mov rcx, rdi
mov QWORD PTR [rsp+264], r11
movq xmm8, rax
and ecx, 2097136
punpcklqdq xmm8, xmm0
movq xmm0, QWORD PTR [r9+96]
punpcklqdq xmm4, xmm0
movq xmm0, QWORD PTR [r9+104]
lea r8, QWORD PTR [rcx+rsi]
movdqu xmm11, XMMWORD PTR [r8]
punpcklqdq xmm5, xmm0
lea r9, QWORD PTR [rdx+r13]
movdqu xmm15, XMMWORD PTR [r9]
ALIGN 16
main_loop_double_sandybridge:
movdqu xmm9, xmm15
mov eax, edx
mov ebx, edx
xor eax, 16
xor ebx, 32
xor edx, 48
movq xmm0, r11
movq xmm2, r10
punpcklqdq xmm2, xmm0
aesenc xmm9, xmm2
movdqu xmm0, XMMWORD PTR [rax+r13]
movdqu xmm1, XMMWORD PTR [rbx+r13]
paddq xmm0, xmm7
paddq xmm1, xmm2
movdqu XMMWORD PTR [rbx+r13], xmm0
movdqu xmm0, XMMWORD PTR [rdx+r13]
movdqu XMMWORD PTR [rdx+r13], xmm1
paddq xmm0, xmm3
movdqu XMMWORD PTR [rax+r13], xmm0
movq r11, xmm9
mov edx, r11d
and edx, 2097136
movdqa xmm0, xmm9
pxor xmm0, xmm7
movdqu XMMWORD PTR [r9], xmm0
lea rbx, QWORD PTR [rdx+r13]
mov r10, QWORD PTR [rdx+r13]
movdqu xmm10, xmm11
movq xmm0, rbp
movq xmm11, rdi
punpcklqdq xmm11, xmm0
aesenc xmm10, xmm11
mov eax, ecx
mov r12d, ecx
xor eax, 16
xor r12d, 32
xor ecx, 48
movdqu xmm0, XMMWORD PTR [rax+rsi]
paddq xmm0, xmm6
movdqu xmm1, XMMWORD PTR [r12+rsi]
movdqu XMMWORD PTR [r12+rsi], xmm0
paddq xmm1, xmm11
movdqu xmm0, XMMWORD PTR [rcx+rsi]
movdqu XMMWORD PTR [rcx+rsi], xmm1
paddq xmm0, xmm8
movdqu XMMWORD PTR [rax+rsi], xmm0
movq rcx, xmm10
and ecx, 2097136
movdqa xmm0, xmm10
pxor xmm0, xmm6
movdqu XMMWORD PTR [r8], xmm0
mov r12, QWORD PTR [rcx+rsi]
mov r9, QWORD PTR [rbx+8]
xor edx, 16
mov r8d, edx
mov r15d, edx
movq rdx, xmm5
shl rdx, 32
movq rax, xmm4
xor rdx, rax
xor r10, rdx
mov rax, r10
mul r11
mov r11d, r8d
xor r11d, 48
movq xmm0, rdx
xor rdx, [r11+r13]
movq xmm1, rax
xor rax, [r11+r13+8]
punpcklqdq xmm0, xmm1
pxor xmm0, XMMWORD PTR [r8+r13]
xor r8d, 32
movdqu xmm1, XMMWORD PTR [r11+r13]
paddq xmm0, xmm7
paddq xmm1, xmm2
movdqu XMMWORD PTR [r11+r13], xmm0
movdqu xmm0, XMMWORD PTR [r8+r13]
movdqu XMMWORD PTR [r8+r13], xmm1
paddq xmm0, xmm3
movdqu XMMWORD PTR [r15+r13], xmm0
mov r11, QWORD PTR [rsp+256]
add r11, rdx
mov rdx, QWORD PTR [rsp+264]
add rdx, rax
mov QWORD PTR [rbx], r11
xor r11, r10
mov QWORD PTR [rbx+8], rdx
xor rdx, r9
mov QWORD PTR [rsp+256], r11
and r11d, 2097136
mov QWORD PTR [rsp+264], rdx
mov QWORD PTR [rsp+8], r11
lea r15, QWORD PTR [r11+r13]
movdqu xmm15, XMMWORD PTR [r11+r13]
lea r13, QWORD PTR [rsi+rcx]
movdqa xmm0, xmm5
psrldq xmm0, 8
movaps xmm2, xmm13
movq r10, xmm0
psllq xmm5, 1
shl r10, 32
movdqa xmm0, xmm9
psrldq xmm0, 8
movdqa xmm1, xmm10
movq r11, xmm0
psrldq xmm1, 8
movq r8, xmm1
psrldq xmm4, 8
movaps xmm0, xmm13
movq rax, xmm4
xor r10, rax
movaps xmm1, xmm13
xor r10, r12
lea rax, QWORD PTR [r11+1]
shr rax, 1
movdqa xmm3, xmm9
punpcklqdq xmm3, xmm10
paddq xmm5, xmm3
movq rdx, xmm5
psrldq xmm5, 8
cvtsi2sd xmm2, rax
or edx, -2147483647
lea rax, QWORD PTR [r8+1]
shr rax, 1
movq r9, xmm5
cvtsi2sd xmm0, rax
or r9d, -2147483647
cvtsi2sd xmm1, rdx
unpcklpd xmm2, xmm0
movaps xmm0, xmm13
cvtsi2sd xmm0, r9
unpcklpd xmm1, xmm0
divpd xmm2, xmm1
paddq xmm2, xmm14
cvttsd2si rax, xmm2
psrldq xmm2, 8
mov rbx, rax
imul rax, rdx
sub r11, rax
js div_fix_1_sandybridge
div_fix_1_ret_sandybridge:
cvttsd2si rdx, xmm2
mov rax, rdx
imul rax, r9
movd xmm2, r11d
movd xmm4, ebx
sub r8, rax
js div_fix_2_sandybridge
div_fix_2_ret_sandybridge:
movd xmm1, r8d
movd xmm0, edx
punpckldq xmm2, xmm1
punpckldq xmm4, xmm0
punpckldq xmm4, xmm2
paddq xmm3, xmm4
movdqa xmm0, xmm3
psrlq xmm0, 12
paddq xmm0, xmm12
sqrtpd xmm1, xmm0
movq r9, xmm1
movdqa xmm5, xmm1
psrlq xmm5, 19
test r9, 524287
je sqrt_fix_1_sandybridge
sqrt_fix_1_ret_sandybridge:
movq r9, xmm10
psrldq xmm1, 8
movq r8, xmm1
test r8, 524287
je sqrt_fix_2_sandybridge
sqrt_fix_2_ret_sandybridge:
mov r12d, ecx
mov r8d, ecx
xor r12d, 16
xor r8d, 32
xor ecx, 48
mov rax, r10
mul r9
movq xmm0, rax
movq xmm3, rdx
punpcklqdq xmm3, xmm0
movdqu xmm0, XMMWORD PTR [r12+rsi]
pxor xmm0, xmm3
movdqu xmm1, XMMWORD PTR [r8+rsi]
xor rdx, [r8+rsi]
xor rax, [r8+rsi+8]
movdqu xmm3, XMMWORD PTR [rcx+rsi]
paddq xmm0, xmm6
paddq xmm1, xmm11
paddq xmm3, xmm8
movdqu XMMWORD PTR [r8+rsi], xmm0
movdqu XMMWORD PTR [rcx+rsi], xmm1
movdqu XMMWORD PTR [r12+rsi], xmm3
add rdi, rdx
mov QWORD PTR [r13], rdi
xor rdi, r10
mov ecx, edi
and ecx, 2097136
lea r8, QWORD PTR [rcx+rsi]
mov rdx, QWORD PTR [r13+8]
add rbp, rax
mov QWORD PTR [r13+8], rbp
movdqu xmm11, XMMWORD PTR [rcx+rsi]
xor rbp, rdx
mov r13, QWORD PTR [rsp]
movdqa xmm3, xmm7
mov rdx, QWORD PTR [rsp+8]
movdqa xmm8, xmm6
mov r10, QWORD PTR [rsp+256]
movdqa xmm7, xmm9
mov r11, QWORD PTR [rsp+264]
movdqa xmm6, xmm10
mov r9, r15
dec r14d
jne main_loop_double_sandybridge
ldmxcsr DWORD PTR [rsp+272]
movaps xmm13, XMMWORD PTR [rsp+48]
lea r11, QWORD PTR [rsp+184]
movaps xmm6, XMMWORD PTR [r11-24]
movaps xmm7, XMMWORD PTR [r11-40]
movaps xmm8, XMMWORD PTR [r11-56]
movaps xmm9, XMMWORD PTR [r11-72]
movaps xmm10, XMMWORD PTR [r11-88]
movaps xmm11, XMMWORD PTR [r11-104]
movaps xmm12, XMMWORD PTR [r11-120]
movaps xmm14, XMMWORD PTR [rsp+32]
movaps xmm15, XMMWORD PTR [rsp+16]
mov rsp, r11
pop r15
pop r14
pop r13
pop r12
pop rdi
pop rsi
pop rbp
pop rbx
jmp cnv2_double_mainloop_asm_sandybridge_endp
div_fix_1_sandybridge:
dec rbx
add r11, rdx
jmp div_fix_1_ret_sandybridge
div_fix_2_sandybridge:
dec rdx
add r8, r9
jmp div_fix_2_ret_sandybridge
sqrt_fix_1_sandybridge:
movq r8, xmm3
movdqa xmm0, xmm5
psrldq xmm0, 8
dec r9
mov r11d, -1022
shl r11, 32
mov rax, r9
shr r9, 19
shr rax, 20
mov rdx, r9
sub rdx, rax
lea rdx, [rdx+r11+1]
add rax, r11
imul rdx, rax
sub rdx, r8
adc r9, 0
movq xmm5, r9
punpcklqdq xmm5, xmm0
jmp sqrt_fix_1_ret_sandybridge
sqrt_fix_2_sandybridge:
psrldq xmm3, 8
movq r11, xmm3
dec r8
mov ebx, -1022
shl rbx, 32
mov rax, r8
shr r8, 19
shr rax, 20
mov rdx, r8
sub rdx, rax
lea rdx, [rdx+rbx+1]
add rax, rbx
imul rdx, rax
sub rdx, r11
adc r8, 0
movq xmm0, r8
punpcklqdq xmm5, xmm0
jmp sqrt_fix_2_ret_sandybridge
cnv2_double_mainloop_asm_sandybridge_endp:

View file

@ -0,0 +1,37 @@
#define ALIGN .align
.intel_syntax noprefix
#ifdef __APPLE__
# define FN_PREFIX(fn) _ ## fn
.text
#else
# define FN_PREFIX(fn) fn
.section .text
#endif
.global FN_PREFIX(cnv2_mainloop_ivybridge_asm)
.global FN_PREFIX(cnv2_mainloop_ryzen_asm)
.global FN_PREFIX(cnv2_double_mainloop_sandybridge_asm)
ALIGN 16
FN_PREFIX(cnv2_mainloop_ivybridge_asm):
sub rsp, 48
mov rcx, rdi
#include "cnv2_main_loop_ivybridge.inc"
add rsp, 48
ret 0
ALIGN 16
FN_PREFIX(cnv2_mainloop_ryzen_asm):
sub rsp, 48
mov rcx, rdi
#include "cnv2_main_loop_ryzen.inc"
add rsp, 48
ret 0
ALIGN 16
FN_PREFIX(cnv2_double_mainloop_sandybridge_asm):
sub rsp, 48
mov rcx, rdi
mov rdx, rsi
#include "cnv2_double_main_loop_sandybridge.inc"
add rsp, 48
ret 0

View file

@ -0,0 +1,25 @@
_TEXT_CNV2_MAINLOOP SEGMENT PAGE READ EXECUTE
PUBLIC cnv2_mainloop_ivybridge_asm
PUBLIC cnv2_mainloop_ryzen_asm
PUBLIC cnv2_double_mainloop_sandybridge_asm
ALIGN 64
cnv2_mainloop_ivybridge_asm PROC
INCLUDE cnv2_main_loop_ivybridge.inc
ret 0
cnv2_mainloop_ivybridge_asm ENDP
ALIGN 64
cnv2_mainloop_ryzen_asm PROC
INCLUDE cnv2_main_loop_ryzen.inc
ret 0
cnv2_mainloop_ryzen_asm ENDP
ALIGN 64
cnv2_double_mainloop_sandybridge_asm PROC
INCLUDE cnv2_double_main_loop_sandybridge.inc
ret 0
cnv2_double_mainloop_sandybridge_asm ENDP
_TEXT_CNV2_MAINLOOP ENDS
END

View file

@ -0,0 +1,186 @@
mov QWORD PTR [rsp+24], rbx
push rbp
push rsi
push rdi
push r12
push r13
push r14
push r15
sub rsp, 80
stmxcsr DWORD PTR [rsp]
mov DWORD PTR [rsp+4], 24448
ldmxcsr DWORD PTR [rsp+4]
mov rax, QWORD PTR [rcx+48]
mov r9, rcx
xor rax, QWORD PTR [rcx+16]
mov esi, 524288
mov r8, QWORD PTR [rcx+32]
mov r13d, -2147483647
xor r8, QWORD PTR [rcx]
mov r11, QWORD PTR [rcx+40]
mov r10, r8
mov rdx, QWORD PTR [rcx+56]
movq xmm4, rax
xor rdx, QWORD PTR [rcx+24]
xor r11, QWORD PTR [rcx+8]
mov rbx, QWORD PTR [rcx+224]
mov rax, QWORD PTR [r9+80]
xor rax, QWORD PTR [r9+64]
movq xmm0, rdx
mov rcx, QWORD PTR [rcx+88]
xor rcx, QWORD PTR [r9+72]
movq xmm3, QWORD PTR [r9+104]
movaps XMMWORD PTR [rsp+64], xmm6
movaps XMMWORD PTR [rsp+48], xmm7
movaps XMMWORD PTR [rsp+32], xmm8
and r10d, 2097136
movq xmm5, rax
xor eax, eax
mov QWORD PTR [rsp+16], rax
mov ax, 1023
shl rax, 52
movq xmm8, rax
mov r15, QWORD PTR [r9+96]
punpcklqdq xmm4, xmm0
movq xmm0, rcx
punpcklqdq xmm5, xmm0
movdqu xmm6, XMMWORD PTR [r10+rbx]
ALIGN 16
main_loop_ivybridge:
lea rdx, QWORD PTR [r10+rbx]
mov ecx, r10d
mov eax, r10d
mov rdi, r15
xor ecx, 16
xor eax, 32
xor r10d, 48
movq xmm0, r11
movq xmm7, r8
punpcklqdq xmm7, xmm0
aesenc xmm6, xmm7
movq rbp, xmm6
mov r9, rbp
and r9d, 2097136
movdqu xmm2, XMMWORD PTR [rcx+rbx]
movdqu xmm1, XMMWORD PTR [rax+rbx]
movdqu xmm0, XMMWORD PTR [r10+rbx]
paddq xmm1, xmm7
paddq xmm0, xmm5
paddq xmm2, xmm4
movdqu XMMWORD PTR [rcx+rbx], xmm0
movdqu XMMWORD PTR [rax+rbx], xmm2
movdqu XMMWORD PTR [r10+rbx], xmm1
mov r10, r9
xor r10d, 32
movq rcx, xmm3
mov rax, rcx
shl rax, 32
xor rdi, rax
movdqa xmm0, xmm6
pxor xmm0, xmm4
movdqu XMMWORD PTR [rdx], xmm0
xor rdi, QWORD PTR [r9+rbx]
lea r14, QWORD PTR [r9+rbx]
mov r12, QWORD PTR [r14+8]
xor edx, edx
lea r9d, DWORD PTR [ecx+ecx]
add r9d, ebp
movdqa xmm0, xmm6
psrldq xmm0, 8
or r9d, r13d
movq rax, xmm0
div r9
xorps xmm3, xmm3
mov eax, eax
shl rdx, 32
add rdx, rax
lea r9, QWORD PTR [rdx+rbp]
mov r15, rdx
mov rax, r9
shr rax, 12
movq xmm0, rax
paddq xmm0, xmm8
sqrtsd xmm3, xmm0
psubq xmm3, XMMWORD PTR [rsp+16]
movq rdx, xmm3
test edx, 524287
je sqrt_fixup_ivybridge
psrlq xmm3, 19
sqrt_fixup_ivybridge_ret:
mov ecx, r10d
mov rax, rdi
mul rbp
movq xmm2, rdx
xor rdx, [rcx+rbx]
add r8, rdx
mov QWORD PTR [r14], r8
xor r8, rdi
mov edi, r8d
and edi, 2097136
movq xmm0, rax
xor rax, [rcx+rbx+8]
add r11, rax
mov QWORD PTR [r14+8], r11
punpcklqdq xmm2, xmm0
mov r9d, r10d
xor r9d, 48
xor r10d, 16
pxor xmm2, XMMWORD PTR [r9+rbx]
movdqu xmm0, XMMWORD PTR [r10+rbx]
paddq xmm0, xmm5
movdqu xmm1, XMMWORD PTR [rcx+rbx]
paddq xmm2, xmm4
paddq xmm1, xmm7
movdqa xmm5, xmm4
movdqu XMMWORD PTR [r9+rbx], xmm0
movdqa xmm4, xmm6
movdqu XMMWORD PTR [rcx+rbx], xmm2
movdqu XMMWORD PTR [r10+rbx], xmm1
movdqu xmm6, [rdi+rbx]
mov r10d, edi
xor r11, r12
dec rsi
jne main_loop_ivybridge
ldmxcsr DWORD PTR [rsp]
mov rbx, QWORD PTR [rsp+160]
movaps xmm6, XMMWORD PTR [rsp+64]
movaps xmm7, XMMWORD PTR [rsp+48]
movaps xmm8, XMMWORD PTR [rsp+32]
add rsp, 80
pop r15
pop r14
pop r13
pop r12
pop rdi
pop rsi
pop rbp
jmp cnv2_main_loop_ivybridge_endp
sqrt_fixup_ivybridge:
dec rdx
mov r13d, -1022
shl r13, 32
mov rax, rdx
shr rdx, 19
shr rax, 20
mov rcx, rdx
sub rcx, rax
add rax, r13
not r13
sub rcx, r13
mov r13d, -2147483647
imul rcx, rax
sub rcx, r9
adc rdx, 0
movq xmm3, rdx
jmp sqrt_fixup_ivybridge_ret
cnv2_main_loop_ivybridge_endp:

View file

@ -0,0 +1,179 @@
mov QWORD PTR [rsp+16], rbx
mov QWORD PTR [rsp+24], rbp
mov QWORD PTR [rsp+32], rsi
push rdi
push r12
push r13
push r14
push r15
sub rsp, 64
stmxcsr DWORD PTR [rsp]
mov DWORD PTR [rsp+4], 24448
ldmxcsr DWORD PTR [rsp+4]
mov rax, QWORD PTR [rcx+48]
mov r9, rcx
xor rax, QWORD PTR [rcx+16]
mov ebp, 524288
mov r8, QWORD PTR [rcx+32]
xor r8, QWORD PTR [rcx]
mov r11, QWORD PTR [rcx+40]
mov r10, r8
mov rdx, QWORD PTR [rcx+56]
movq xmm3, rax
xor rdx, QWORD PTR [rcx+24]
xor r11, QWORD PTR [rcx+8]
mov rbx, QWORD PTR [rcx+224]
mov rax, QWORD PTR [r9+80]
xor rax, QWORD PTR [r9+64]
movq xmm0, rdx
mov rcx, QWORD PTR [rcx+88]
xor rcx, QWORD PTR [r9+72]
mov rdi, QWORD PTR [r9+104]
and r10d, 2097136
movaps XMMWORD PTR [rsp+48], xmm6
movq xmm4, rax
movaps XMMWORD PTR [rsp+32], xmm7
movaps XMMWORD PTR [rsp+16], xmm8
xorps xmm8, xmm8
mov ax, 1023
shl rax, 52
movq xmm7, rax
mov r15, QWORD PTR [r9+96]
punpcklqdq xmm3, xmm0
movq xmm0, rcx
punpcklqdq xmm4, xmm0
ALIGN 16
main_loop_ryzen:
movdqa xmm5, XMMWORD PTR [r10+rbx]
movq xmm0, r11
movq xmm6, r8
punpcklqdq xmm6, xmm0
lea rdx, QWORD PTR [r10+rbx]
lea r9, QWORD PTR [rdi+rdi]
shl rdi, 32
mov ecx, r10d
mov eax, r10d
xor ecx, 16
xor eax, 32
xor r10d, 48
aesenc xmm5, xmm6
movdqa xmm2, XMMWORD PTR [rcx+rbx]
movdqa xmm1, XMMWORD PTR [rax+rbx]
movdqa xmm0, XMMWORD PTR [r10+rbx]
paddq xmm2, xmm3
paddq xmm1, xmm6
paddq xmm0, xmm4
movdqa XMMWORD PTR [rcx+rbx], xmm0
movdqa XMMWORD PTR [rax+rbx], xmm2
movdqa XMMWORD PTR [r10+rbx], xmm1
movaps xmm1, xmm8
mov rsi, r15
xor rsi, rdi
movq r14, xmm5
movdqa xmm0, xmm5
pxor xmm0, xmm3
mov r10, r14
and r10d, 2097136
movdqa XMMWORD PTR [rdx], xmm0
xor rsi, QWORD PTR [r10+rbx]
lea r12, QWORD PTR [r10+rbx]
mov r13, QWORD PTR [r10+rbx+8]
add r9d, r14d
or r9d, -2147483647
xor edx, edx
movdqa xmm0, xmm5
psrldq xmm0, 8
movq rax, xmm0
div r9
movq xmm0, rax
movq xmm1, rdx
punpckldq xmm0, xmm1
movq r15, xmm0
paddq xmm0, xmm5
movdqa xmm2, xmm0
psrlq xmm0, 12
paddq xmm0, xmm7
sqrtsd xmm1, xmm0
movq rdi, xmm1
test rdi, 524287
je sqrt_fixup_ryzen
shr rdi, 19
sqrt_fixup_ryzen_ret:
mov rax, rsi
mul r14
movq xmm1, rax
movq xmm0, rdx
punpcklqdq xmm0, xmm1
mov r9d, r10d
mov ecx, r10d
xor r9d, 16
xor ecx, 32
xor r10d, 48
movdqa xmm1, XMMWORD PTR [rcx+rbx]
xor rdx, [rcx+rbx]
xor rax, [rcx+rbx+8]
movdqa xmm2, XMMWORD PTR [r9+rbx]
pxor xmm2, xmm0
paddq xmm4, XMMWORD PTR [r10+rbx]
paddq xmm2, xmm3
paddq xmm1, xmm6
movdqa XMMWORD PTR [r9+rbx], xmm4
movdqa XMMWORD PTR [rcx+rbx], xmm2
movdqa XMMWORD PTR [r10+rbx], xmm1
movdqa xmm4, xmm3
add r8, rdx
add r11, rax
mov QWORD PTR [r12], r8
xor r8, rsi
mov QWORD PTR [r12+8], r11
mov r10, r8
xor r11, r13
and r10d, 2097136
movdqa xmm3, xmm5
dec ebp
jne main_loop_ryzen
ldmxcsr DWORD PTR [rsp]
movaps xmm6, XMMWORD PTR [rsp+48]
lea r11, QWORD PTR [rsp+64]
mov rbx, QWORD PTR [r11+56]
mov rbp, QWORD PTR [r11+64]
mov rsi, QWORD PTR [r11+72]
movaps xmm8, XMMWORD PTR [r11-48]
movaps xmm7, XMMWORD PTR [rsp+32]
mov rsp, r11
pop r15
pop r14
pop r13
pop r12
pop rdi
jmp cnv2_main_loop_ryzen_endp
sqrt_fixup_ryzen:
movq r9, xmm2
dec rdi
mov edx, -1022
shl rdx, 32
mov rax, rdi
shr rdi, 19
shr rax, 20
mov rcx, rdi
sub rcx, rax
lea rcx, [rcx+rdx+1]
add rax, rdx
imul rcx, rax
sub rcx, r9
adc rdi, 0
jmp sqrt_fixup_ryzen_ret
cnv2_main_loop_ryzen_endp:

View file

@ -0,0 +1,21 @@
#define ALIGN .align
.intel_syntax noprefix
.section .text
.global cnv2_mainloop_ivybridge_asm
.global cnv2_mainloop_ryzen_asm
.global cnv2_double_mainloop_sandybridge_asm
ALIGN 16
cnv2_mainloop_ivybridge_asm:
#include "cnv2_main_loop_ivybridge.inc"
ret 0
ALIGN 16
cnv2_mainloop_ryzen_asm:
#include "cnv2_main_loop_ryzen.inc"
ret 0
ALIGN 16
cnv2_double_mainloop_sandybridge_asm:
#include "cnv2_double_main_loop_sandybridge.inc"
ret 0

View file

@ -20,8 +20,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __ITHREAD_H__ #ifndef XMRIG_ITHREAD_H
#define __ITHREAD_H__ #define XMRIG_ITHREAD_H
#include <stdint.h> #include <stdint.h>
@ -64,10 +64,14 @@ public:
# ifndef XMRIG_NO_API # ifndef XMRIG_NO_API
virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0; virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0;
# endif # endif
# ifdef APP_DEBUG
virtual void print() const = 0;
# endif
}; };
} /* namespace xmrig */ } /* namespace xmrig */
#endif // __ITHREAD_H__ #endif // XMRIG_ITHREAD_H

View file

@ -101,7 +101,15 @@ void Network::onActive(IStrategy *strategy, Client *client)
m_state.setPool(client->host(), client->port(), client->ip()); m_state.setPool(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()); const char *tlsVersion = client->tlsVersion();
LOG_INFO(isColors() ? WHITE_BOLD("use pool ") CYAN_BOLD("%s:%d ") GREEN_BOLD("%s") " \x1B[1;30m%s "
: "use pool %s:%d %s %s",
client->host(), client->port(), tlsVersion ? tlsVersion : "", client->ip());
const char *fingerprint = client->tlsFingerprint();
if (fingerprint != nullptr) {
LOG_INFO("\x1B[1;30mfingerprint (SHA-256): \"%s\"", fingerprint);
}
} }

View file

@ -33,10 +33,6 @@
#include "net/strategies/DonateStrategy.h" #include "net/strategies/DonateStrategy.h"
const static char *kDonatePool1 = "miner.fee.xmrig.com";
const static char *kDonatePool2 = "emergency.fee.xmrig.com";
static inline float randomf(float min, float max) { static inline float randomf(float min, float max) {
return (max - min) * ((((float) rand()) / (float) RAND_MAX)) + min; return (max - min) * ((((float) rand()) / (float) RAND_MAX)) + min;
} }
@ -55,17 +51,11 @@ DonateStrategy::DonateStrategy(int level, const char *user, xmrig::Algo algo, IS
xmrig::keccak(reinterpret_cast<const uint8_t *>(user), strlen(user), hash); xmrig::keccak(reinterpret_cast<const uint8_t *>(user), strlen(user), hash);
Job::toHex(hash, 32, userId); Job::toHex(hash, 32, userId);
if (algo == xmrig::CRYPTONIGHT) { # ifndef XMRIG_NO_TLS
m_pools.push_back(Pool(kDonatePool1, 6666, userId, nullptr, false, true)); m_pools.push_back(Pool("donate.ssl.xmrig.com", 443, userId, nullptr, false, true, true));
m_pools.push_back(Pool(kDonatePool1, 80, userId, nullptr, false, true)); # endif
m_pools.push_back(Pool(kDonatePool2, 5555, "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", "emergency", false, false));
} m_pools.push_back(Pool("donate.v2.xmrig.com", 3333, userId, nullptr, false, true));
else if (algo == xmrig::CRYPTONIGHT_HEAVY) {
m_pools.push_back(Pool(kDonatePool1, 8888, userId, nullptr, false, true));
}
else {
m_pools.push_back(Pool(kDonatePool1, 5555, userId, nullptr, false, true));
}
for (Pool &pool : m_pools) { for (Pool &pool : m_pools) {
pool.adjust(xmrig::Algorithm(algo, xmrig::VARIANT_AUTO)); pool.adjust(xmrig::Algorithm(algo, xmrig::VARIANT_AUTO));

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __DONATESTRATEGY_H__ #ifndef XMRIG_DONATESTRATEGY_H
#define __DONATESTRATEGY_H__ #define XMRIG_DONATESTRATEGY_H
#include <uv.h> #include <uv.h>
@ -76,4 +76,4 @@ private:
uv_timer_t m_timer; uv_timer_t m_timer;
}; };
#endif /* __DONATESTRATEGY_H__ */ #endif /* XMRIG_DONATESTRATEGY_H */

View file

@ -21,21 +21,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __VERSION_H__ #ifndef XMRIG_VERSION_H
#define __VERSION_H__ #define XMRIG_VERSION_H
#define APP_ID "xmrig" #define APP_ID "xmrig"
#define APP_NAME "XMRig" #define APP_NAME "XMRig"
#define APP_DESC "XMRig CPU miner" #define APP_DESC "XMRig CPU miner"
#define APP_VERSION "2.6.4" #define APP_VERSION "2.8.0-dev"
#define APP_DOMAIN "xmrig.com" #define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com" #define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com"
#define APP_KIND "cpu" #define APP_KIND "cpu"
#define APP_VER_MAJOR 2 #define APP_VER_MAJOR 2
#define APP_VER_MINOR 6 #define APP_VER_MINOR 8
#define APP_VER_PATCH 4 #define APP_VER_PATCH 0
#ifdef _MSC_VER #ifdef _MSC_VER
# if (_MSC_VER >= 1910) # if (_MSC_VER >= 1910)
@ -53,4 +53,4 @@
# endif # endif
#endif #endif
#endif /* __VERSION_H__ */ #endif /* XMRIG_VERSION_H */

View file

@ -24,7 +24,10 @@
#include <assert.h> #include <assert.h>
#include "common/cpu/Cpu.h"
#include "common/log/Log.h"
#include "common/net/Pool.h" #include "common/net/Pool.h"
#include "crypto/Asm.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "workers/CpuThread.h" #include "workers/CpuThread.h"
@ -36,9 +39,10 @@
#endif #endif
xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch) : xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) :
m_algorithm(algorithm), m_algorithm(algorithm),
m_av(av), m_av(av),
m_assembly(assembly),
m_prefetch(prefetch), m_prefetch(prefetch),
m_softAES(softAES), m_softAES(softAES),
m_priority(priority), m_priority(priority),
@ -49,22 +53,23 @@ xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiw
} }
xmrig::CpuThread::~CpuThread()
{
}
bool xmrig::CpuThread::isSoftAES(AlgoVariant av) bool xmrig::CpuThread::isSoftAES(AlgoVariant av)
{ {
return av == AV_SINGLE_SOFT || av == AV_DOUBLE_SOFT || av > AV_PENTA; return av == AV_SINGLE_SOFT || av == AV_DOUBLE_SOFT || av > AV_PENTA;
} }
xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly)
{ {
assert(variant >= VARIANT_0 && variant < VARIANT_MAX); assert(variant >= VARIANT_0 && variant < VARIANT_MAX);
static const cn_hash_fun func_table[VARIANT_MAX * 10 * 3] = { # ifndef XMRIG_NO_ASM
constexpr const size_t count = VARIANT_MAX * 10 * 3 + 3;
# else
constexpr const size_t count = VARIANT_MAX * 10 * 3;
# endif
static const cn_hash_fun func_table[count] = {
cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_0>, cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_0>,
cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_0>, cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_0>,
cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_0>, cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_0>,
@ -135,6 +140,17 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_RTO>, cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_RTO>,
cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_RTO>, cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_RTO>,
cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_2>,
cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_2>,
cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_2>,
cryptonight_double_hash<CRYPTONIGHT, true, VARIANT_2>,
cryptonight_triple_hash<CRYPTONIGHT, false, VARIANT_2>,
cryptonight_quad_hash<CRYPTONIGHT, false, VARIANT_2>,
cryptonight_penta_hash<CRYPTONIGHT, false, VARIANT_2>,
cryptonight_triple_hash<CRYPTONIGHT, true, VARIANT_2>,
cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_2>,
cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_2>,
# ifndef XMRIG_NO_AEON # ifndef XMRIG_NO_AEON
cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_0>, cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_0>, cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
@ -164,6 +180,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2
# else # else
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
@ -173,6 +190,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
# endif # endif
# ifndef XMRIG_NO_SUMO # ifndef XMRIG_NO_SUMO
@ -216,6 +234,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2
# else # else
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
@ -225,12 +244,17 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
# endif
# ifndef XMRIG_NO_ASM
cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_INTEL>,
cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_RYZEN>,
cryptonight_double_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_INTEL>
# endif # endif
}; };
const size_t index = VARIANT_MAX * 10 * algorithm + 10 * variant + av - 1;
# ifndef NDEBUG # ifndef NDEBUG
const size_t index = fnIndex(algorithm, av, variant, assembly);
cn_hash_fun func = func_table[index]; cn_hash_fun func = func_table[index];
assert(index < sizeof(func_table) / sizeof(func_table[0])); assert(index < sizeof(func_table) / sizeof(func_table[0]));
@ -238,12 +262,12 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
return func; return func;
# else # else
return func_table[index]; return func_table[fnIndex(algorithm, av, variant, assembly)];
# endif # endif
} }
xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority) xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly)
{ {
assert(av > AV_AUTO && av < AV_MAX); assert(av > AV_AUTO && av < AV_MAX);
@ -266,7 +290,7 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A
} }
} }
return new CpuThread(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false); return new CpuThread(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false, assembly);
} }
@ -284,7 +308,7 @@ xmrig::CpuThread *xmrig::CpuThread::createFromData(size_t index, Algo algorithm,
assert(av > AV_AUTO && av < AV_MAX); assert(av > AV_AUTO && av < AV_MAX);
return new CpuThread(index, algorithm, static_cast<AlgoVariant>(av), multiway, data.affinity, priority, softAES, false); return new CpuThread(index, algorithm, static_cast<AlgoVariant>(av), multiway, data.affinity, priority, softAES, false, data.assembly);
} }
@ -306,11 +330,14 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object)
} }
const auto &affinity = object["affine_to_cpu"]; const auto &affinity = object["affine_to_cpu"];
if (affinity.IsUint64()) { if (affinity.IsUint64()) {
data.affinity = affinity.GetInt64(); data.affinity = affinity.GetInt64();
} }
# ifndef XMRIG_NO_ASM
data.assembly = Asm::parse(object["asm"]);
# endif
return data; return data;
} }
@ -346,6 +373,21 @@ xmrig::IThread::Multiway xmrig::CpuThread::multiway(AlgoVariant av)
} }
#ifdef APP_DEBUG
void xmrig::CpuThread::print() const
{
LOG_DEBUG(GREEN_BOLD("CPU thread: ") " index " WHITE_BOLD("%zu") ", multiway " WHITE_BOLD("%d") ", av " WHITE_BOLD("%d") ",",
index(), static_cast<int>(multiway()), static_cast<int>(m_av));
# ifndef XMRIG_NO_ASM
LOG_DEBUG(" assembly: %s, affine_to_cpu: %" PRId64, Asm::toString(m_assembly), affinity());
# else
LOG_DEBUG(" affine_to_cpu: %" PRId64, affinity());
# endif
}
#endif
#ifndef XMRIG_NO_API #ifndef XMRIG_NO_API
rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const
{ {
@ -376,5 +418,39 @@ rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const
obj.AddMember("low_power_mode", multiway(), allocator); obj.AddMember("low_power_mode", multiway(), allocator);
obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator); obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator);
# ifndef XMRIG_NO_ASM
obj.AddMember("asm", Asm::toJSON(m_assembly), allocator);
# endif
return obj; return obj;
} }
size_t xmrig::CpuThread::fnIndex(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly)
{
const size_t index = VARIANT_MAX * 10 * algorithm + 10 * variant + av - 1;
# ifndef XMRIG_NO_ASM
if (assembly == ASM_AUTO) {
assembly = Cpu::info()->assembly();
}
if (assembly == ASM_NONE) {
return index;
}
constexpr const size_t offset = VARIANT_MAX * 10 * 3;
if (algorithm == CRYPTONIGHT && variant == VARIANT_2) {
if (av == AV_SINGLE) {
return offset + assembly - 2;
}
if (av == AV_DOUBLE) {
return offset + 2;
}
}
# endif
return index;
}

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CPUTHREAD_H__ #ifndef XMRIG_CPUTHREAD_H
#define __CPUTHREAD_H__ #define XMRIG_CPUTHREAD_H
#include "common/xmrig.h" #include "common/xmrig.h"
@ -40,7 +40,7 @@ class CpuThread : public IThread
public: public:
struct Data struct Data
{ {
inline Data() : valid(false), affinity(-1L), multiway(SingleWay) {} inline Data() : assembly(ASM_AUTO), valid(false), affinity(-1L), multiway(SingleWay) {}
inline void setMultiway(int value) inline void setMultiway(int value)
{ {
@ -50,27 +50,27 @@ public:
} }
} }
Assembly assembly;
bool valid; bool valid;
int64_t affinity; int64_t affinity;
Multiway multiway; Multiway multiway;
}; };
CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch); CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly);
~CpuThread();
typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx); typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx);
static bool isSoftAES(AlgoVariant av); static bool isSoftAES(AlgoVariant av);
static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly);
static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly);
static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES); static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES);
static Data parse(const rapidjson::Value &object); static Data parse(const rapidjson::Value &object);
static Multiway multiway(AlgoVariant av); static Multiway multiway(AlgoVariant av);
inline bool isPrefetch() const { return m_prefetch; } inline bool isPrefetch() const { return m_prefetch; }
inline bool isSoftAES() const { return m_softAES; } inline bool isSoftAES() const { return m_softAES; }
inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant); } inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant, m_assembly); }
inline Algo algorithm() const override { return m_algorithm; } inline Algo algorithm() const override { return m_algorithm; }
inline int priority() const override { return m_priority; } inline int priority() const override { return m_priority; }
@ -80,6 +80,10 @@ public:
inline Type type() const override { return CPU; } inline Type type() const override { return CPU; }
protected: protected:
# ifdef APP_DEBUG
void print() const override;
# endif
# ifndef XMRIG_NO_API # ifndef XMRIG_NO_API
rapidjson::Value toAPI(rapidjson::Document &doc) const override; rapidjson::Value toAPI(rapidjson::Document &doc) const override;
# endif # endif
@ -87,8 +91,11 @@ protected:
rapidjson::Value toConfig(rapidjson::Document &doc) const override; rapidjson::Value toConfig(rapidjson::Document &doc) const override;
private: private:
static size_t fnIndex(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly);
const Algo m_algorithm; const Algo m_algorithm;
const AlgoVariant m_av; const AlgoVariant m_av;
const Assembly m_assembly;
const bool m_prefetch; const bool m_prefetch;
const bool m_softAES; const bool m_softAES;
const int m_priority; const int m_priority;
@ -101,4 +108,4 @@ private:
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* __CPUTHREAD_H__ */ #endif /* XMRIG_CPUTHREAD_H */

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -55,6 +56,7 @@ bool MultiWorker<N>::selfTest()
if (m_thread->algorithm() == CRYPTONIGHT) { if (m_thread->algorithm() == CRYPTONIGHT) {
return verify(VARIANT_0, test_output_v0) && return verify(VARIANT_0, test_output_v0) &&
verify(VARIANT_1, test_output_v1) && verify(VARIANT_1, test_output_v1) &&
verify(VARIANT_2, test_output_v2) &&
verify(VARIANT_XTL, test_output_xtl) && verify(VARIANT_XTL, test_output_xtl) &&
verify(VARIANT_MSR, test_output_msr) && verify(VARIANT_MSR, test_output_msr) &&
verify(VARIANT_XAO, test_output_xao) && verify(VARIANT_XAO, test_output_xao) &&
@ -102,7 +104,7 @@ void MultiWorker<N>::start()
storeStats(); storeStats();
} }
m_thread->fn(m_state.job.variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx); m_thread->fn(m_state.job.algorithm().variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx);
for (size_t i = 0; i < N; ++i) { for (size_t i = 0; i < N; ++i) {
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < m_state.job.target()) { if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < m_state.job.target()) {

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -22,8 +23,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __MULTIWORKER_H__ #ifndef XMRIG_MULTIWORKER_H
#define __MULTIWORKER_H__ #define XMRIG_MULTIWORKER_H
#include "common/net/Job.h" #include "common/net/Job.h"
@ -71,4 +72,4 @@ private:
}; };
#endif /* __MULTIWORKER_H__ */ #endif /* XMRIG_MULTIWORKER_H */

View file

@ -24,8 +24,8 @@
#include <chrono> #include <chrono>
#include "common/cpu/Cpu.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "Cpu.h"
#include "workers/CpuThread.h" #include "workers/CpuThread.h"
#include "workers/Handle.h" #include "workers/Handle.h"
#include "workers/Worker.h" #include "workers/Worker.h"
@ -41,7 +41,7 @@ Worker::Worker(Handle *handle) :
m_sequence(0), m_sequence(0),
m_thread(static_cast<xmrig::CpuThread *>(handle->config())) m_thread(static_cast<xmrig::CpuThread *>(handle->config()))
{ {
if (Cpu::threads() > 1 && m_thread->affinity() != -1L) { if (xmrig::Cpu::info()->threads() > 1 && m_thread->affinity() != -1L) {
Platform::setThreadAffinity(m_thread->affinity()); Platform::setThreadAffinity(m_thread->affinity());
} }

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __WORKER_H__ #ifndef XMRIG_WORKER_H
#define __WORKER_H__ #define XMRIG_WORKER_H
#include <atomic> #include <atomic>
@ -33,7 +33,6 @@
#include "Mem.h" #include "Mem.h"
struct cryptonight_ctx;
class Handle; class Handle;
@ -67,4 +66,4 @@ protected:
}; };
#endif /* __WORKER_H__ */ #endif /* XMRIG_WORKER_H */

View file

@ -160,6 +160,14 @@ void Workers::setJob(const Job &job, bool donate)
void Workers::start(xmrig::Controller *controller) void Workers::start(xmrig::Controller *controller)
{ {
# ifdef APP_DEBUG
LOG_NOTICE("THREADS ------------------------------------------------------------------");
for (const xmrig::IThread *thread : controller->config()->threads()) {
thread->print();
}
LOG_NOTICE("--------------------------------------------------------------------------");
# endif
m_controller = controller; m_controller = controller;
const std::vector<xmrig::IThread *> &threads = controller->config()->threads(); const std::vector<xmrig::IThread *> &threads = controller->config()->threads();
@ -192,6 +200,10 @@ void Workers::start(xmrig::Controller *controller)
m_workers.push_back(handle); m_workers.push_back(handle);
handle->start(Workers::onReady); handle->start(Workers::onReady);
} }
if (controller->config()->isShouldSave()) {
controller->config()->save();
}
} }