diff options
-rw-r--r-- | .gitattributes | 1 | ||||
-rw-r--r-- | CMakeLists.txt | 47 | ||||
-rw-r--r-- | doc/compile.md | 10 | ||||
-rw-r--r-- | doc/compile_Linux.md | 4 | ||||
-rw-r--r-- | doc/usage.md | 9 | ||||
-rw-r--r-- | xmrstak/backend/amd/minethd.cpp | 7 | ||||
-rw-r--r-- | xmrstak/backend/amd/minethd.hpp | 1 | ||||
-rw-r--r-- | xmrstak/backend/cpu/minethd.cpp | 8 | ||||
-rw-r--r-- | xmrstak/backend/cpu/minethd.hpp | 1 | ||||
-rw-r--r-- | xmrstak/backend/iBackend.hpp | 18 | ||||
-rw-r--r-- | xmrstak/backend/nvidia/autoAdjust.hpp | 13 | ||||
-rw-r--r-- | xmrstak/backend/nvidia/minethd.cpp | 7 | ||||
-rw-r--r-- | xmrstak/backend/nvidia/minethd.hpp | 1 | ||||
-rw-r--r-- | xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu | 43 | ||||
-rw-r--r-- | xmrstak/cli/cli-miner.cpp | 33 | ||||
-rw-r--r-- | xmrstak/http/webdesign.cpp | 13 | ||||
-rw-r--r-- | xmrstak/jconf.cpp | 9 | ||||
-rw-r--r-- | xmrstak/misc/executor.cpp | 107 | ||||
-rw-r--r-- | xmrstak/misc/executor.hpp | 2 | ||||
-rw-r--r-- | xmrstak/net/jpsock.cpp | 4 | ||||
-rw-r--r-- | xmrstak/net/msgstruct.hpp | 11 | ||||
-rw-r--r-- | xmrstak/version.cpp | 52 | ||||
-rw-r--r-- | xmrstak/version.hpp | 19 |
23 files changed, 332 insertions, 88 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..71ed00d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +xmrstak/version.cpp export-subst diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e13aa0..6e0f282 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,17 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${BUILD_TYPE}") set(XMR-STAK_CURRENCY "all" CACHE STRING "select miner currency") set_property(CACHE XMR-STAK_CURRENCY PROPERTY STRINGS "all;monero;aeon") +if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + set(XMR-STAK_COMPILE "native" CACHE STRING "select CPU compute architecture") + set_property(CACHE XMR-STAK_COMPILE PROPERTY STRINGS "native;generic") + if("${XMR-STAK_COMPILE}" STREQUAL "native") + set(CMAKE_CXX_FLAGS "-march=native -mtune=native ${CMAKE_CXX_FLAGS}") + set(CMAKE_C_FLAGS "-march=native -mtune=native ${CMAKE_C_FLAGS}") + elseif(NOT "${XMR-STAK_COMPILE}" STREQUAL "generic") + message(FATAL_ERROR "XMR-STAK_COMPILE is set to an unknown value '${XMR-STAK_COMPILE}'") + endif() +endif() + if("${XMR-STAK_CURRENCY}" STREQUAL "all") message(STATUS "Set miner currency to 'monero' and 'aeon'") elseif("${XMR-STAK_CURRENCY}" STREQUAL "aeon") @@ -63,7 +74,7 @@ if(CUDA_ENABLE) find_package(CUDA 7.5) if(CUDA_FOUND) - + list(APPEND BACKEND_TYPES "nvidia") option(XMR-STAK_LARGEGRID "Support large CUDA block count > 128" ON) if(XMR-STAK_LARGEGRID) add_definitions("-DXMR_STAK_LARGEGRID=${XMR-STAK_LARGEGRID}") @@ -233,6 +244,7 @@ if(OpenCL_ENABLE) # find package will use the previews searched path variables find_package(OpenCL) if(OpenCL_FOUND) + list(APPEND BACKEND_TYPES "amd") include_directories(SYSTEM ${OpenCL_INCLUDE_DIRS}) #set(LIBS ${LIBS} ${OpenCL_LIBRARY}) link_directories(${OpenCL_LIBRARY}) @@ -250,6 +262,8 @@ endif() option(CPU_ENABLE "Enable or disable CPU support" ON) if(NOT CPU_ENABLE) add_definitions("-DCONF_NO_CPU") +else() + list(APPEND BACKEND_TYPES "cpu") endif() ################################################################################ @@ -359,6 +373,37 @@ if(WIN32) endif() ################################################################################ +# Versioning +################################################################################ + +# Get the current working branch +execute_process( + COMMAND git rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_BRANCH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# Get the latest abbreviated commit hash of the working branch +execute_process( + COMMAND git log -1 --format=%h + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if(NOT "${GIT_COMMIT_HASH}" STREQUAL "") + add_definitions("-DGIT_COMMIT_HASH=${GIT_COMMIT_HASH}") +endif() +if(NOT "${GIT_BRANCH}" STREQUAL "") + add_definitions("-DGIT_BRANCH=${GIT_BRANCH}") +endif() + +# generate backend string +string(REPLACE ";" "-" STR_BACKEND_TYPES "${BACKEND_TYPES}") +add_definitions("-DBACKEND_TYPE=${STR_BACKEND_TYPES}") + +################################################################################ # Compile & Link ################################################################################ diff --git a/doc/compile.md b/doc/compile.md index 537a736..30cf58c 100644 --- a/doc/compile.md +++ b/doc/compile.md @@ -37,6 +37,7 @@ After the configuration you need to compile the miner, follow the guide for your - you can find the binary and the `config.txt` file after `make install` in `$HOME/xmr-stak-cpu/bin` - `CMAKE_LINK_STATIC` link libgcc and libstdc++ libraries static (default OFF) - disable with `cmake .. -DCMAKE_LINK_STATIC=ON` + - if you use static compile to run the miner on another system set `-DXMR-STAK_COMPILE=generic` (only available for LINUX, BSD and MacOSX) - `CMAKE_BUILD_TYPE` set the build type - valid options: `Release` or `Debug` - you should always keep `Release` for your productive miners @@ -44,10 +45,17 @@ After the configuration you need to compile the miner, follow the guide for your - there is no *http* interface available if option is disabled: `cmake .. -DMICROHTTPD_ENABLE=OFF` - `OpenSSL_ENABLE` allow to disable/enable the dependency *OpenSSL* - it is not possible to connect to a *https* secured pool if option is disabled: `cmake .. -DOpenSSL_ENABLE=OFF` +- `XMR-STAK_CURRENCY` - compile for Monero(XMR) or Aeon(AEON) usage only e.g. `cmake .. -DXMR-STAK_CURRENCY=monero` + +### only available for LINUX, BSD and MacOSX +- `XMR-STAK_COMPILE` select the CPU compute architecture (default: native) + - native means the miner binary can be used only on the system where it is compiled but will archive the highest hash rate + - use `cmake .. -DXMR-STAK_COMPILE=generic` to run the miner on all CPU's with sse2 + +### only available for Windows - `WIN_UAC` will enable or disable the "Run As Administrator" prompt on Windows. - UAC confirmation is needed to use large pages on Windows 7. - On Windows 10 it is only needed once to set up the account to use them. -- `XMR-STAK_CURRENCY` - compile for Monero(XMR) or Aeon(AEON) usage only e.g. `cmake .. -DXMR-STAK_CURRENCY=monero` ## CPU Build Options diff --git a/doc/compile_Linux.md b/doc/compile_Linux.md index c9347f5..cf99121 100644 --- a/doc/compile_Linux.md +++ b/doc/compile_Linux.md @@ -69,9 +69,9 @@ - g++ version 5.1 or higher is required for full C++11 support. If you want to compile the binary without installing libraries / compiler or just compile binary for some other distribution, please check the [build_xmr-stak_docker.sh script](scripts/build_xmr-stak_docker/build_xmr-stak_docker.sh). -### To do a static build for a system without gcc 5.1+ +### To do a generic and static build for a system without gcc 5.1+ ``` - cmake -DCMAKE_LINK_STATIC=ON . + cmake -DCMAKE_LINK_STATIC=ON -DXMR-STAK_COMPILE=generic . make install ``` Note - cmake caches variables, so if you want to do a dynamic build later you need to specify '-DCMAKE_LINK_STATIC=OFF' diff --git a/doc/usage.md b/doc/usage.md index 9a38384..ca379ab 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -32,6 +32,8 @@ The miner allow to overwrite some of the settings via command line options. Usage: xmr-stak [OPTION]... -h, --help show this help + -v, --version show version number + -V, --version-long show long version number -c, --config FILE common miner configuration file --currency NAME currency to mine: monero or aeon --noCPU disable the CPU miner backend @@ -43,13 +45,8 @@ The Following options temporary overwrites the config file settings: -o, --url URL pool url and port, e.g. pool.usxmrpool.com:3333 -u, --user USERNAME pool user name or wallet address -p, --pass PASSWD pool password, in the most cases x or empty "" +``` ## HTML and JSON API report configuraton To configure the reports shown on the [README](README.md) side you need to edit the httpd_port variable. Then enable wifi on your phone and navigate to [miner ip address]:[httpd_port] in your phone browser. If you want to use the data in scripts, you can get the JSON version of the data at url [miner ip address]:[httpd_port]/api.json - -## Default Developer Donation -By default the miner will donate 2% of the hashpower (2 minute in 100 minutes) to my pool. If you want to change that, edit **xmrstak/donate-level.hpp** before you build the binaries. - -If you want to donate directly to support further development, here is my wallet -``` diff --git a/xmrstak/backend/amd/minethd.cpp b/xmrstak/backend/amd/minethd.cpp index f12e12c..94fc088 100644 --- a/xmrstak/backend/amd/minethd.cpp +++ b/xmrstak/backend/amd/minethd.cpp @@ -49,6 +49,7 @@ namespace amd minethd::minethd(miner_work& pWork, size_t iNo, GpuContext* ctx, const jconf::thd_cfg cfg) { + this->backendType = iBackend::AMD; oWork = pWork; bQuit = 0; iThreadNo = (uint8_t)iNo; @@ -58,6 +59,7 @@ minethd::minethd(miner_work& pWork, size_t iNo, GpuContext* ctx, const jconf::th pGpuCtx = ctx; this->affinity = cfg.cpu_aff; + std::unique_lock<std::mutex> lck(thd_aff_set); std::future<void> order_guard = order_fix.get_future(); oWorkThd = std::thread(&minethd::work_main, this); @@ -179,6 +181,9 @@ void minethd::work_main() bindMemoryToNUMANode(affinity); order_fix.set_value(); + std::unique_lock<std::mutex> lck(thd_aff_set); + lck.release(); + std::this_thread::yield(); uint64_t iCount = 0; cryptonight_ctx* cpu_ctx; @@ -238,7 +243,7 @@ void minethd::work_main() if ( (*((uint64_t*)(bResult + 24))) < oWork.iTarget) executor::inst()->push_event(ex_event(job_result(oWork.sJobID, results[i], bResult), oWork.iPoolId)); else - executor::inst()->log_result_error("AMD Invalid Result"); + executor::inst()->push_event(ex_event("AMD Invalid Result", oWork.iPoolId)); } iCount += pGpuCtx->rawIntensity; diff --git a/xmrstak/backend/amd/minethd.hpp b/xmrstak/backend/amd/minethd.hpp index c4c2ce6..c808192 100644 --- a/xmrstak/backend/amd/minethd.hpp +++ b/xmrstak/backend/amd/minethd.hpp @@ -38,6 +38,7 @@ private: miner_work oWork; std::promise<void> order_fix; + std::mutex thd_aff_set; std::thread oWorkThd; int64_t affinity; diff --git a/xmrstak/backend/cpu/minethd.cpp b/xmrstak/backend/cpu/minethd.cpp index d36ebf1..8183adf 100644 --- a/xmrstak/backend/cpu/minethd.cpp +++ b/xmrstak/backend/cpu/minethd.cpp @@ -94,6 +94,7 @@ bool minethd::thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id minethd::minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch, int64_t affinity) { + this->backendType = iBackend::CPU; oWork = pWork; bQuit = 0; iThreadNo = (uint8_t)iNo; @@ -101,6 +102,7 @@ minethd::minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefet bNoPrefetch = no_prefetch; this->affinity = affinity; + std::unique_lock<std::mutex> lck(thd_aff_set); std::future<void> order_guard = order_fix.get_future(); if(double_work) @@ -339,6 +341,9 @@ void minethd::work_main() bindMemoryToNUMANode(affinity); order_fix.set_value(); + std::unique_lock<std::mutex> lck(thd_aff_set); + lck.release(); + std::this_thread::yield(); cn_hash_fun hash_fun; cryptonight_ctx* ctx; @@ -466,6 +471,9 @@ void minethd::double_work_main() bindMemoryToNUMANode(affinity); order_fix.set_value(); + std::unique_lock<std::mutex> lck(thd_aff_set); + lck.release(); + std::this_thread::yield(); cn_hash_fun_dbl hash_fun; cryptonight_ctx* ctx0; diff --git a/xmrstak/backend/cpu/minethd.hpp b/xmrstak/backend/cpu/minethd.hpp index 670ec8d..5520d9e 100644 --- a/xmrstak/backend/cpu/minethd.hpp +++ b/xmrstak/backend/cpu/minethd.hpp @@ -46,6 +46,7 @@ private: miner_work oWork; std::promise<void> order_fix; + std::mutex thd_aff_set; std::thread oWorkThd; int64_t affinity; diff --git a/xmrstak/backend/iBackend.hpp b/xmrstak/backend/iBackend.hpp index ab964ce..dbfbc99 100644 --- a/xmrstak/backend/iBackend.hpp +++ b/xmrstak/backend/iBackend.hpp @@ -5,15 +5,31 @@ #include <atomic> #include <cstdint> #include <climits> - +#include <vector> +#include <string> namespace xmrstak { struct iBackend { + + enum BackendType : uint32_t { UNKNOWN = 0, CPU = 1u, AMD = 2u, NVIDIA = 3u }; + + static std::string getName(const BackendType type) + { + std::vector<std::string> backendNames = { + "UNKNOWN", + "CPU", + "AMD", + "NVIDIA" + }; + return backendNames[static_cast<uint32_t>(type)]; + } + std::atomic<uint64_t> iHashCount; std::atomic<uint64_t> iTimestamp; uint32_t iThreadNo; + BackendType backendType = UNKNOWN; iBackend() : iHashCount(0), iTimestamp(0) { diff --git a/xmrstak/backend/nvidia/autoAdjust.hpp b/xmrstak/backend/nvidia/autoAdjust.hpp index bf04518..d36a46a 100644 --- a/xmrstak/backend/nvidia/autoAdjust.hpp +++ b/xmrstak/backend/nvidia/autoAdjust.hpp @@ -60,17 +60,15 @@ public: ctx.device_bfactor = 6; ctx.device_bsleep = 25; #endif - if( cuda_get_deviceinfo(&ctx) != 1 ) - { - printer::inst()->print_msg(L0, "Setup failed for GPU %d. Exitting.\n", i); - std::exit(0); - } - nvidCtxVec.push_back(ctx); + if(cuda_get_deviceinfo(&ctx) == 0) + nvidCtxVec.push_back(ctx); + else + printer::inst()->print_msg(L0, "WARNING: NVIDIA setup failed for GPU %d.\n", i); } generateThreadConfig(); - return true; + return true; } @@ -94,6 +92,7 @@ private: { conf += std::string(" // gpu: ") + ctx.name + " architecture: " + std::to_string(ctx.device_arch[0] * 10 + ctx.device_arch[1]) + "\n"; conf += std::string(" // memory: ") + std::to_string(ctx.free_device_memory / byte2mib) + "/" + std::to_string(ctx.total_device_memory / byte2mib) + " MiB\n"; + conf += std::string(" // smx: ") + std::to_string(ctx.device_mpcount) + "\n"; conf += std::string(" { \"index\" : ") + std::to_string(ctx.device_id) + ",\n" + " \"threads\" : " + std::to_string(ctx.device_threads) + ", \"blocks\" : " + std::to_string(ctx.device_blocks) + ",\n" + " \"bfactor\" : " + std::to_string(ctx.device_bfactor) + ", \"bsleep\" : " + std::to_string(ctx.device_bsleep) + ",\n" + diff --git a/xmrstak/backend/nvidia/minethd.cpp b/xmrstak/backend/nvidia/minethd.cpp index 0cf9a42..5170305 100644 --- a/xmrstak/backend/nvidia/minethd.cpp +++ b/xmrstak/backend/nvidia/minethd.cpp @@ -66,6 +66,7 @@ namespace nvidia minethd::minethd(miner_work& pWork, size_t iNo, const jconf::thd_cfg& cfg) { + this->backendType = iBackend::NVIDIA; oWork = pWork; bQuit = 0; iThreadNo = (uint8_t)iNo; @@ -78,6 +79,7 @@ minethd::minethd(miner_work& pWork, size_t iNo, const jconf::thd_cfg& cfg) ctx.device_bsleep = (int)cfg.bsleep; this->affinity = cfg.cpu_aff; + std::unique_lock<std::mutex> lck(thd_aff_set); std::future<void> order_guard = order_fix.get_future(); oWorkThd = std::thread(&minethd::work_main, this); @@ -206,6 +208,9 @@ void minethd::work_main() bindMemoryToNUMANode(affinity); order_fix.set_value(); + std::unique_lock<std::mutex> lck(thd_aff_set); + lck.release(); + std::this_thread::yield(); uint64_t iCount = 0; cryptonight_ctx* cpu_ctx; @@ -280,7 +285,7 @@ void minethd::work_main() if ( (*((uint64_t*)(bResult + 24))) < oWork.iTarget) executor::inst()->push_event(ex_event(job_result(oWork.sJobID, foundNonce[i], bResult), oWork.iPoolId)); else - executor::inst()->log_result_error("NVIDIA Invalid Result"); + executor::inst()->push_event(ex_event("NVIDIA Invalid Result", oWork.iPoolId)); } iCount += h_per_round; diff --git a/xmrstak/backend/nvidia/minethd.hpp b/xmrstak/backend/nvidia/minethd.hpp index f6d989c..ffcdab1 100644 --- a/xmrstak/backend/nvidia/minethd.hpp +++ b/xmrstak/backend/nvidia/minethd.hpp @@ -45,6 +45,7 @@ private: miner_work oWork; std::promise<void> order_fix; + std::mutex thd_aff_set; std::thread oWorkThd; int64_t affinity; diff --git a/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu b/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu index e18532f..61d45ed 100644 --- a/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu +++ b/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu @@ -270,6 +270,14 @@ extern "C" int cuda_get_devicecount( int* deviceCount) return 1; } +/** get device information + * + * @return 0 = all OK, + * 1 = something went wrong, + * 2 = gpu cannot be selected, + * 3 = context cannot be created + * 4 = not enough memory + */ extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx) { cudaError_t err; @@ -279,25 +287,25 @@ extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx) if(err != cudaSuccess) { printf("Unable to query CUDA driver version! Is an nVidia driver installed?\n"); - return 0; + return 1; } if(version < CUDART_VERSION) { printf("Driver does not support CUDA %d.%d API! Update your nVidia driver!\n", CUDART_VERSION / 1000, (CUDART_VERSION % 1000) / 10); - return 0; + return 1; } int GPU_N; if(cuda_get_devicecount(&GPU_N) == 0) { - return 0; + return 1; } if(ctx->device_id >= GPU_N) { printf("Invalid device ID!\n"); - return 0; + return 1; } cudaDeviceProp props; @@ -305,7 +313,7 @@ extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx) if(err != cudaSuccess) { printf("\nGPU %d: %s\n%s line %d\n", ctx->device_id, cudaGetErrorString(err), __FILE__, __LINE__); - return 0; + return 1; } ctx->device_name = strdup(props.name); @@ -347,9 +355,31 @@ extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx) maxMemUsage = size_t(1024u) * byteToMiB; } + int* tmp; + cudaError_t err; + // a device must be selected to get the right memory usage later on + err = cudaSetDevice(ctx->device_id); + if(err != cudaSuccess) + { + printf("WARNING: NVIDIA GPU %d: cannot be selected.\n", ctx->device_id); + return 2; + } + // trigger that a context on the gpu will be allocated + err = cudaMalloc(&tmp, 256); + if(err != cudaSuccess) + { + printf("WARNING: NVIDIA GPU %d: context cannot be created.\n", ctx->device_id); + return 3; + } + + size_t freeMemory = 0; size_t totalMemory = 0; CUDA_CHECK(ctx->device_id, cudaMemGetInfo(&freeMemory, &totalMemory)); + + cudaFree(tmp); + // delete created context on the gpu + cudaDeviceReset(); ctx->total_device_memory = totalMemory; ctx->free_device_memory = freeMemory; @@ -379,6 +409,7 @@ extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx) printf("WARNING: NVIDIA GPU %d: already %s MiB memory in use, skip GPU.\n", ctx->device_id, std::to_string(usedMem/byteToMiB).c_str()); + return 4; } else maxMemUsage -= usedMem; @@ -404,5 +435,5 @@ extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx) } - return 1; + return 0; } diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index 5c16c1b..f0f3c3a 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -63,6 +63,8 @@ void help() cout<<"Usage: "<<params::inst().binaryName<<" [OPTION]..."<<endl; cout<<" "<<endl; cout<<" -h, --help show this help"<<endl; + cout<<" -v, --version show version number"<<endl; + cout<<" -V, --version-long show long version number"<<endl; cout<<" -c, --config FILE common miner configuration file"<<endl; #if (!defined(CONF_NO_AEON)) && (!defined(CONF_NO_MONERO)) cout<<" --currency NAME currency to mine: monero or aeon"<<endl; @@ -85,7 +87,7 @@ void help() cout<<" -u, --user USERNAME pool user name or wallet address"<<endl; cout<<" -p, --pass PASSWD pool password, in the most cases x or empty \"\""<<endl; cout<<" \n"<<endl; - cout<<XMR_STAK_NAME<<" "<<XMR_STAK_VERSION<<endl; + cout<< "Version: " << get_version_str_short() << endl; cout<<"Brought to by fireice_uk and psychocrypt under GPLv3."<<endl; } @@ -128,7 +130,11 @@ std::string get_multipool_entry(bool& final) std::cout<<"- Password (mostly empty or x):"<<std::endl; getline(std::cin, passwd); +#ifdef CONF_NO_TLS + bool tls = false; +#else bool tls = read_yes_no("- Does this pool port support TLS/SSL? Use no if unknown. (y/N)"); +#endif bool nicehash = read_yes_no("- Do you want to use nicehash on this pool? (y/n)"); int64_t pool_weight; @@ -205,7 +211,11 @@ void do_guided_config(bool userSetPasswd) getline(std::cin, passwd); } +#ifdef CONF_NO_TLS + bool tls = false; +#else bool tls = read_yes_no("- Does this pool port support TLS/SSL? Use no if unknown. (y/N)"); +#endif bool nicehash = read_yes_no("- Do you want to use nicehash on this pool? (y/n)"); bool multipool; @@ -296,6 +306,16 @@ int main(int argc, char *argv[]) //win_exit(); return 0; } + if(opName.compare("-v") == 0 || opName.compare("--version") == 0) + { + std::cout<< "Version: " << get_version_str_short() << std::endl; + return 0; + } + else if(opName.compare("-V") == 0 || opName.compare("--version-long") == 0) + { + std::cout<< "Version: " << get_version_str() << std::endl; + return 0; + } else if(opName.compare("--noCPU") == 0) { params::inst().useCPU = false; @@ -433,17 +453,18 @@ int main(int argc, char *argv[]) #endif printer::inst()->print_str("-------------------------------------------------------------------\n"); - printer::inst()->print_str( XMR_STAK_NAME" " XMR_STAK_VERSION " mining software.\n"); + printer::inst()->print_str(get_version_str_short().c_str()); + printer::inst()->print_str("\n\n"); + printer::inst()->print_str("Brought to you by fireice_uk and psychocrypt under GPLv3.\n"); printer::inst()->print_str("Based on CPU mining code by wolf9466 (heavily optimized by fireice_uk).\n"); #ifndef CONF_NO_CUDA - printer::inst()->print_str("NVIDIA mining code was written by KlausT and psychocrypt.\n"); + printer::inst()->print_str("Based on NVIDIA mining code by KlausT and psychocrypt.\n"); #endif #ifndef CONF_NO_OPENCL - printer::inst()->print_str("AMD mining code was written by wolf9466.\n"); + printer::inst()->print_str("Based on OpenCL mining code by wolf9466.\n"); #endif - printer::inst()->print_str("Brought to you by fireice_uk and psychocrypt under GPLv3.\n\n"); char buffer[64]; - snprintf(buffer, sizeof(buffer), "Configurable dev donation level is set to %.1f %%\n\n", fDevDonationLevel * 100.0); + snprintf(buffer, sizeof(buffer), "\nConfigurable dev donation level is set to %.1f%%\n\n", fDevDonationLevel * 100.0); printer::inst()->print_str(buffer); printer::inst()->print_str("You can use following keys to display reports:\n"); printer::inst()->print_str("'h' - hashrate\n"); diff --git a/xmrstak/http/webdesign.cpp b/xmrstak/http/webdesign.cpp index 1cb76c3..3c33e1f 100644 --- a/xmrstak/http/webdesign.cpp +++ b/xmrstak/http/webdesign.cpp @@ -1,6 +1,6 @@ #include <stdlib.h> -extern const char sHtmlCssEtag [] = "00000006"; +extern const char sHtmlCssEtag [] = "00000008"; extern const char sHtmlCssFile [] = "body {" "font-family: Tahoma, Arial, sans-serif;" @@ -38,7 +38,13 @@ extern const char sHtmlCssFile [] = "color: white;" "padding: 10px;" "font-weight: bold;" - "margin: 10px 0px;" + "margin: 0px;" + "margin-bottom: 10px;" + "}" + + ".version {" + "font-size: 75%;" + "text-align: right;" "}" ".links {" @@ -108,6 +114,7 @@ extern const char sHtmlCommonHeader [] = "<link rel='stylesheet' href='style.css' /><title>%s</title></head>" "<body>" "<div class='all'>" + "<div class='version'>%s</div>" "<div class='header'><span style='color: rgb(255, 160, 0)'>XMR</span>-Stak Monero Miner</div>" "<div class='flex-container'>" @@ -192,6 +199,8 @@ extern const char sJsonApiConnectionError[] = extern const char sJsonApiFormat [] = "{" + "\"version\":\"%s\"," + "\"hashrate\":{" "\"threads\":[%s]," "\"total\":%s," diff --git a/xmrstak/jconf.cpp b/xmrstak/jconf.cpp index 0418842..6d0f8ae 100644 --- a/xmrstak/jconf.cpp +++ b/xmrstak/jconf.cpp @@ -484,15 +484,6 @@ bool jconf::parse_config(const char* sFilename) return false; } -#ifdef CONF_NO_TLS - if(prv->configValues[bTlsMode]->GetBool()) - { - printer::inst()->print_msg(L0, - "Invalid config file. TLS enabled while the application has been compiled without TLS support."); - return false; - } -#endif // CONF_NO_TLS - if(prv->configValues[bAesOverride]->IsBool()) bHaveAes = prv->configValues[bAesOverride]->GetBool(); diff --git a/xmrstak/misc/executor.cpp b/xmrstak/misc/executor.cpp index 6f48edd..4a3a77b 100644 --- a/xmrstak/misc/executor.cpp +++ b/xmrstak/misc/executor.cpp @@ -29,10 +29,12 @@ #include "xmrstak/backend/miner_work.hpp" #include "xmrstak/backend/globalStates.hpp" #include "xmrstak/backend/backendConnector.hpp" +#include "xmrstak/backend/iBackend.hpp" #include "xmrstak/jconf.hpp" #include "xmrstak/misc/console.hpp" #include "xmrstak/donate-level.hpp" +#include "xmrstak/version.hpp" #include "xmrstak/http/webdesign.hpp" #include <thread> @@ -43,6 +45,7 @@ #include <assert.h> #include <time.h> + #ifdef _WIN32 #define strncasecmp _strnicmp #endif // _WIN32 @@ -491,6 +494,13 @@ void executor::ex_main() { jconf::pool_cfg cfg; jconf::inst()->GetPoolConfig(i, cfg); +#ifdef CONF_NO_TLS + if(cfg.tls) + { + printer::inst()->print_msg(L1, "ERROR: No miner was compiled without TLS support."); + win_exit(); + } +#endif if(!cfg.tls) tls = false; pools.emplace_back(i+1, cfg.sPoolAddr, cfg.sWalletAddr, cfg.sPasswd, cfg.weight, false, cfg.tls, cfg.tls_fingerprint, cfg.nicehash); } @@ -549,6 +559,10 @@ void executor::ex_main() eval_pool_choice(); break; + case EV_GPU_RES_ERROR: + log_result_error(ev.oGpuError.error_str); + break; + case EV_PERF_TICK: for (i = 0; i < pvThreads->size(); i++) telem->push_perf_value(i, pvThreads->at(i)->iHashCount.load(std::memory_order_relaxed), @@ -619,49 +633,64 @@ inline const char* hps_format(double h, char* buf, size_t l) void executor::hashrate_report(std::string& out) { char num[32]; - size_t nthd = pvThreads->size(); - - out.reserve(256 + nthd * 64); - double fTotal[3] = { 0.0, 0.0, 0.0}; - size_t i; - - out.append("HASHRATE REPORT\n"); - out.append("| ID | 10s | 60s | 15m |"); - if(nthd != 1) - out.append(" ID | 10s | 60s | 15m |\n"); - else - out.append(1, '\n'); - for (i = 0; i < nthd; i++) + for( uint32_t b = 0; b < 4u; ++b) { - double fHps[3]; + std::vector<xmrstak::iBackend*> backEnds; + std::copy_if(pvThreads->begin(), pvThreads->end(), std::back_inserter(backEnds), + [&](xmrstak::iBackend* backend) + { + return backend->backendType == b; + } + ); - fHps[0] = telem->calc_telemetry_data(10000, i); - fHps[1] = telem->calc_telemetry_data(60000, i); - fHps[2] = telem->calc_telemetry_data(900000, i); + size_t nthd = backEnds.size(); + if(nthd != 0) + { + out.reserve(256 + nthd * 64); + + size_t i; + auto bType = static_cast<xmrstak::iBackend::BackendType>(b); + out.append("HASHRATE REPORT - ").append(xmrstak::iBackend::getName(bType)).append("\n"); + out.append("| ID | 10s | 60s | 15m |"); + if(nthd != 1) + out.append(" ID | 10s | 60s | 15m |\n"); + else + out.append(1, '\n'); - snprintf(num, sizeof(num), "| %2u |", (unsigned int)i); - out.append(num); - out.append(hps_format(fHps[0], num, sizeof(num))).append(" |"); - out.append(hps_format(fHps[1], num, sizeof(num))).append(" |"); - out.append(hps_format(fHps[2], num, sizeof(num))).append(1, ' '); + for (i = 0; i < nthd; i++) + { + double fHps[3]; - fTotal[0] += fHps[0]; - fTotal[1] += fHps[1]; - fTotal[2] += fHps[2]; + uint32_t tid = backEnds[i]->iThreadNo; + fHps[0] = telem->calc_telemetry_data(10000, tid); + fHps[1] = telem->calc_telemetry_data(60000, tid); + fHps[2] = telem->calc_telemetry_data(900000, tid); - if((i & 0x1) == 1) //Odd i's - out.append("|\n"); - } + snprintf(num, sizeof(num), "| %2u |", (unsigned int)i); + out.append(num); + out.append(hps_format(fHps[0], num, sizeof(num))).append(" |"); + out.append(hps_format(fHps[1], num, sizeof(num))).append(" |"); + out.append(hps_format(fHps[2], num, sizeof(num))).append(1, ' '); - if((i & 0x1) == 1) //We had odd number of threads - out.append("|\n"); + fTotal[0] += fHps[0]; + fTotal[1] += fHps[1]; + fTotal[2] += fHps[2]; - if(nthd != 1) - out.append("-----------------------------------------------------\n"); - else - out.append("---------------------------\n"); + if((i & 0x1) == 1) //Odd i's + out.append("|\n"); + } + + if((i & 0x1) == 1) //We had odd number of threads + out.append("|\n"); + + if(nthd != 1) + out.append("-----------------------------------------------------\n"); + else + out.append("---------------------------\n"); + } + } out.append("Totals: "); out.append(hps_format(fTotal[0], num, sizeof(num))); @@ -832,7 +861,7 @@ void executor::http_hashrate_report(std::string& out) out.reserve(4096); - snprintf(buffer, sizeof(buffer), sHtmlCommonHeader, "Hashrate Report", "Hashrate Report"); + snprintf(buffer, sizeof(buffer), sHtmlCommonHeader, "Hashrate Report", ver_html, "Hashrate Report"); out.append(buffer); snprintf(buffer, sizeof(buffer), sHtmlHashrateBodyHigh, (unsigned int)nthd + 3); @@ -877,7 +906,7 @@ void executor::http_result_report(std::string& out) out.reserve(4096); - snprintf(buffer, sizeof(buffer), sHtmlCommonHeader, "Result Report", "Result Report"); + snprintf(buffer, sizeof(buffer), sHtmlCommonHeader, "Result Report", ver_html, "Result Report"); out.append(buffer); size_t iGoodRes = vMineResults[0].count, iTotalRes = iGoodRes; @@ -923,7 +952,7 @@ void executor::http_connection_report(std::string& out) out.reserve(4096); - snprintf(buffer, sizeof(buffer), sHtmlCommonHeader, "Connection Report", "Connection Report"); + snprintf(buffer, sizeof(buffer), sHtmlCommonHeader, "Connection Report", ver_html, "Connection Report"); out.append(buffer); jpsock* pool = pick_pool_by_id(current_pool_id); @@ -1063,11 +1092,11 @@ void executor::http_json_report(std::string& out) cn_error.append(buffer); } - size_t bb_size = 1024 + hr_thds.size() + res_error.size() + cn_error.size(); + size_t bb_size = 2048 + hr_thds.size() + res_error.size() + cn_error.size(); std::unique_ptr<char[]> bigbuf( new char[ bb_size ] ); int bb_len = snprintf(bigbuf.get(), bb_size, sJsonApiFormat, - hr_thds.c_str(), hr_buffer, a, + get_version_str().c_str(), hr_thds.c_str(), hr_buffer, a, int_port(iPoolDiff), int_port(iGoodRes), int_port(iTotalRes), fAvgResTime, int_port(iPoolHashes), int_port(iTopDiff[0]), int_port(iTopDiff[1]), int_port(iTopDiff[2]), int_port(iTopDiff[3]), int_port(iTopDiff[4]), int_port(iTopDiff[5]), int_port(iTopDiff[6]), int_port(iTopDiff[7]), int_port(iTopDiff[8]), int_port(iTopDiff[9]), diff --git a/xmrstak/misc/executor.hpp b/xmrstak/misc/executor.hpp index 11c8206..9ff0323 100644 --- a/xmrstak/misc/executor.hpp +++ b/xmrstak/misc/executor.hpp @@ -42,7 +42,6 @@ public: inline void push_event(ex_event&& ev) { oEventQ.push(std::move(ev)); } void push_timed_event(ex_event&& ev, size_t sec); - void log_result_error(std::string&& sError); private: struct timed_event @@ -180,6 +179,7 @@ private: double fHighestHps = 0.0; void log_socket_error(jpsock* pool, std::string&& sError); + void log_result_error(std::string&& sError); void log_result_ok(uint64_t iActualDiff); void on_sock_ready(size_t pool_id); diff --git a/xmrstak/net/jpsock.cpp b/xmrstak/net/jpsock.cpp index f6f5c1f..cb586d2 100644 --- a/xmrstak/net/jpsock.cpp +++ b/xmrstak/net/jpsock.cpp @@ -509,8 +509,8 @@ bool jpsock::cmd_login() { char cmd_buffer[1024]; - snprintf(cmd_buffer, sizeof(cmd_buffer), "{\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"" AGENTID_STR "\"},\"id\":1}\n", - usr_login.c_str(), usr_pass.c_str()); + snprintf(cmd_buffer, sizeof(cmd_buffer), "{\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"},\"id\":1}\n", + usr_login.c_str(), usr_pass.c_str(), get_version_str().c_str()); opq_json_val oResult(nullptr); diff --git a/xmrstak/net/msgstruct.hpp b/xmrstak/net/msgstruct.hpp index 01aa76c..4d8d845 100644 --- a/xmrstak/net/msgstruct.hpp +++ b/xmrstak/net/msgstruct.hpp @@ -62,7 +62,14 @@ struct sock_err sock_err& operator=(sock_err const&) = delete; }; -enum ex_event_name { EV_INVALID_VAL, EV_SOCK_READY, EV_SOCK_ERROR, +// Unlike socket errors, GPU errors are read-only strings +struct gpu_res_err +{ + const char* error_str; + gpu_res_err(const char* error_str) : error_str(error_str) {} +}; + +enum ex_event_name { EV_INVALID_VAL, EV_SOCK_READY, EV_SOCK_ERROR, EV_GPU_RES_ERROR, EV_POOL_HAVE_JOB, EV_MINER_HAVE_RESULT, EV_PERF_TICK, EV_EVAL_POOL_CHOICE, EV_USR_HASHRATE, EV_USR_RESULTS, EV_USR_CONNSTAT, EV_HASHRATE_LOOP, EV_HTML_HASHRATE, EV_HTML_RESULTS, EV_HTML_CONNSTAT, EV_HTML_JSON }; @@ -87,9 +94,11 @@ struct ex_event pool_job oPoolJob; job_result oJobResult; sock_err oSocketError; + gpu_res_err oGpuError; }; ex_event() { iName = EV_INVALID_VAL; iPoolId = 0;} + ex_event(const char* gpu_err, size_t id) : iName(EV_GPU_RES_ERROR), iPoolId(id), oGpuError(gpu_err) {} ex_event(std::string&& err, bool silent, size_t id) : iName(EV_SOCK_ERROR), iPoolId(id), oSocketError(std::move(err), silent) { } ex_event(job_result dat, size_t id) : iName(EV_MINER_HAVE_RESULT), iPoolId(id), oJobResult(dat) {} ex_event(pool_job dat, size_t id) : iName(EV_POOL_HAVE_JOB), iPoolId(id), oPoolJob(dat) {} diff --git a/xmrstak/version.cpp b/xmrstak/version.cpp new file mode 100644 index 0000000..3b8a19d --- /dev/null +++ b/xmrstak/version.cpp @@ -0,0 +1,52 @@ +#include "version.hpp" + +//! git will put "#define GIT_ARCHIVE 1" on the next line inside archives. $Format:%n#define GIT_ARCHIVE 1$ +#if defined(GIT_ARCHIVE) && !defined(GIT_COMMIT_HASH) +#define GIT_COMMIT_HASH $Format:%h$ +#endif + +#ifndef GIT_COMMIT_HASH +#define GIT_COMMIT_HASH 0000000 +#endif + +#ifndef GIT_BRANCH +#define GIT_BRANCH unknown +#endif + +#ifndef BACKEND_TYPE +#define BACKEND_TYPE unknown +#endif + +#define XMR_STAK_NAME "xmr-stak" +#define XMR_STAK_VERSION "2.0.0" + +#if defined(_WIN32) +#define OS_TYPE "win" +#elif defined(__APPLE__) +#define OS_TYPE "mac" +#elif defined(__FreeBSD__) +#define OS_TYPE "bsd" +#elif defined(__linux__) +#define OS_TYPE "lin" +#else +#define OS_TYPE "unk" +#endif + +#if defined(CONF_NO_AEON) +#define COIN_TYPE "monero" +#elif defined(CONF_NO_MONERO) +#define COIN_TYPE "aeon" +#else +#define COIN_TYPE "aeon-monero" +#endif + +#define XMRSTAK_PP_TOSTRING1(str) #str +#define XMRSTAK_PP_TOSTRING(str) XMRSTAK_PP_TOSTRING1(str) + +#define VERSION_LONG XMR_STAK_NAME "/" XMR_STAK_VERSION "/" XMRSTAK_PP_TOSTRING(GIT_COMMIT_HASH) "/" XMRSTAK_PP_TOSTRING(GIT_BRANCH) "/" OS_TYPE "/" XMRSTAK_PP_TOSTRING(BACKEND_TYPE) "/" COIN_TYPE "/" +#define VERSION_SHORT XMR_STAK_NAME " " XMR_STAK_VERSION " " XMRSTAK_PP_TOSTRING(GIT_COMMIT_HASH) +#define VERSION_HTML "v" XMR_STAK_VERSION "-" XMRSTAK_PP_TOSTRING(GIT_COMMIT_HASH) + +const char ver_long[] = VERSION_LONG; +const char ver_short[] = VERSION_SHORT; +const char ver_html[] = VERSION_HTML; diff --git a/xmrstak/version.hpp b/xmrstak/version.hpp index 44214c8..cdf82f3 100644 --- a/xmrstak/version.hpp +++ b/xmrstak/version.hpp @@ -1,4 +1,19 @@ #pragma once -#define XMR_STAK_NAME "xmr-stak" -#define XMR_STAK_VERSION "2.0.0-predev" +#include <inttypes.h> +#include <string> +#include "donate-level.hpp" + +extern const char ver_long[]; +extern const char ver_short[]; +extern const char ver_html[]; + +inline std::string get_version_str() +{ + return std::string(ver_long) + std::to_string(uint32_t(fDevDonationLevel * 1000)) ; +} + +inline std::string get_version_str_short() +{ + return std::string(ver_short); +} |