diff options
Diffstat (limited to 'xmrstak/cli/cli-miner.cpp')
-rw-r--r-- | xmrstak/cli/cli-miner.cpp | 335 |
1 files changed, 248 insertions, 87 deletions
diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index b84b783..2e84ec5 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -55,7 +55,7 @@ # include "xmrstak/misc/uac.hpp" #endif // _WIN32 -void do_benchmark(); +int do_benchmark(int block_version); void help() { @@ -64,43 +64,50 @@ 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; + 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; + cout<<" -C, --poolconf FILE pool configuration file"<<endl; #ifdef _WIN32 - cout<<" --noUAC disable the UAC dialog"<<endl; -#endif -#if (!defined(CONF_NO_AEON)) && (!defined(CONF_NO_MONERO)) - cout<<" --currency NAME currency to mine: monero or aeon"<<endl; + cout<<" --noUAC disable the UAC dialog"<<endl; #endif + cout<<" --benchmark BLOCKVERSION ONLY do a 60-second benchmark and exit"<<endl; #ifndef CONF_NO_CPU - cout<<" --noCPU disable the CPU miner backend"<<endl; - cout<<" --cpu FILE CPU backend miner config file"<<endl; + cout<<" --noCPU disable the CPU miner backend"<<endl; + cout<<" --cpu FILE CPU backend miner config file"<<endl; #endif #ifndef CONF_NO_OPENCL - cout<<" --noAMD disable the AMD miner backend"<<endl; - cout<<" --amd FILE AMD backend miner config file"<<endl; + cout<<" --noAMD disable the AMD miner backend"<<endl; + cout<<" --amd FILE AMD backend miner config file"<<endl; #endif #ifndef CONF_NO_CUDA - cout<<" --noNVIDIA disable the NVIDIA miner backend"<<endl; - cout<<" --nvidia FILE NVIDIA backend miner config file"<<endl; + cout<<" --noNVIDIA disable the NVIDIA miner backend"<<endl; + cout<<" --nvidia FILE NVIDIA backend miner config file"<<endl; +#endif +#ifndef CONF_NO_HTTPD + cout<<" -i --httpd HTTP_PORT HTTP interface port"<<endl; #endif cout<<" "<<endl; cout<<"The following options can be used for automatic start without a guided config,"<<endl; cout<<"If config exists then this pool will be top priority."<<endl; - cout<<" -o, --url URL pool url and port, e.g. pool.usxmrpool.com:3333"<<endl; - cout<<" -O, --tls-url URL TLS pool url and port, e.g. pool.usxmrpool.com:10443"<<endl; - 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<<" --use-nicehash the pool should run in nicehash mode"<<endl; - cout<<" \n"<<endl; + cout<<" -o, --url URL pool url and port, e.g. pool.usxmrpool.com:3333"<<endl; + cout<<" -O, --tls-url URL TLS pool url and port, e.g. pool.usxmrpool.com:10443"<<endl; + cout<<" -u, --user USERNAME pool user name or wallet address"<<endl; + cout<<" -r, --rigid RIGID rig identifier for pool-side statistics (needs pool support)"<<endl; + cout<<" -p, --pass PASSWD pool password, in the most cases x or empty \"\""<<endl; + cout<<" --use-nicehash the pool should run in nicehash mode"<<endl; + cout<<" --currency NAME currency to mine"<<endl; + cout<< endl; #ifdef _WIN32 cout<<"Environment variables:\n"<<endl; - cout<<" XMRSTAK_NOWAIT disable the dialog `Press any key to exit."<<std::endl; - cout<<" for non UAC execution"<<endl; - cout<<" \n"<<endl; + cout<<" XMRSTAK_NOWAIT disable the dialog `Press any key to exit."<<std::endl; + cout<<" for non UAC execution"<<endl; + cout<< endl; #endif + std::string algos; + jconf::GetAlgoList(algos); + cout<< "Supported coin opitons: " << endl << algos << endl; cout<< "Version: " << get_version_str_short() << endl; cout<<"Brought to by fireice_uk and psychocrypt under GPLv3."<<endl; } @@ -129,10 +136,7 @@ std::string get_multipool_entry(bool& final) std::cout<<std::endl<<"- Next Pool:"<<std::endl<<std::endl; std::string pool; - if(xmrstak::params::inst().currency == "monero") - std::cout<<"- Pool address: e.g. pool.usxmrpool.com:3333"<<std::endl; - else - std::cout<<"- Pool address: e.g. mine.aeon-pool.com:5555"<<std::endl; + std::cout<<"- Pool address: e.g. " << jconf::GetDefaultPool(xmrstak::params::inst().currency.c_str()) << std::endl; std::cin >> pool; std::string userName; @@ -143,6 +147,10 @@ std::string get_multipool_entry(bool& final) std::cin.clear(); std::cin.ignore(INT_MAX,'\n'); std::cout<<"- Password (mostly empty or x):"<<std::endl; getline(std::cin, passwd); + + std::string rigid; + std::cout<<"- Rig identifier for pool-side statistics (needs pool support). Can be empty:"<<std::endl; + getline(std::cin, rigid); #ifdef CONF_NO_TLS bool tls = false; @@ -162,9 +170,9 @@ std::string get_multipool_entry(bool& final) final = !read_yes_no("- Do you want to add another pool? (y/n)"); - return "\t{\"pool_address\" : \"" + pool +"\", \"wallet_address\" : \"" + userName + "\", \"pool_password\" : \"" + - passwd + "\", \"use_nicehash\" : " + bool_to_str(nicehash) + ", \"use_tls\" : " + bool_to_str(tls) + - ", \"tls_fingerprint\" : \"\", \"pool_weight\" : " + std::to_string(pool_weight) + " },\n"; + return "\t{\"pool_address\" : \"" + pool +"\", \"wallet_address\" : \"" + userName + "\", \"rig_id\" : \"" + rigid + + "\", \"pool_password\" : \"" + passwd + "\", \"use_nicehash\" : " + bool_to_str(nicehash) + ", \"use_tls\" : " + + bool_to_str(tls) + ", \"tls_fingerprint\" : \"\", \"pool_weight\" : " + std::to_string(pool_weight) + " },\n"; } inline void prompt_once(bool& prompted) @@ -176,35 +184,32 @@ inline void prompt_once(bool& prompted) } } -void do_guided_config() +void do_guided_pool_config() { using namespace xmrstak; // load the template of the backend config into a char variable const char *tpl = - #include "../config.tpl" + #include "../pools.tpl" ; configEditor configTpl{}; configTpl.set(std::string(tpl)); bool prompted = false; - + auto& currency = params::inst().currency; - if(currency.empty()) + if(currency.empty() || !jconf::IsOnAlgoList(currency)) { prompt_once(prompted); std::string tmp; -#if defined(CONF_NO_AEON) - tmp = "monero"; -#elif defined(CONF_NO_MONERO) - tmp = "aeon"; -#endif - while(tmp != "monero" && tmp != "aeon") + while(tmp.empty() || !jconf::IsOnAlgoList(tmp)) { - std::cout<<"- Currency: 'monero' or 'aeon'"<<std::endl; + std::string list; + jconf::GetAlgoList(list); + std::cout << "- Please enter the currency that you want to mine: "<<std::endl; + std::cout << list << std::endl; std::cin >> tmp; - std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); } currency = tmp; } @@ -216,10 +221,7 @@ void do_guided_config() prompt_once(prompted); userSetPool = false; - if(currency == "monero") - std::cout<<"- Pool address: e.g. pool.usxmrpool.com:3333"<<std::endl; - else - std::cout<<"- Pool address: e.g. mine.aeon-pool.com:5555"<<std::endl; + std::cout<<"- Pool address: e.g. " << jconf::GetDefaultPool(xmrstak::params::inst().currency.c_str()) << std::endl; std::cin >> pool; } @@ -232,6 +234,7 @@ void do_guided_config() std::cin >> userName; } + bool stdin_flushed = false; auto& passwd = params::inst().poolPasswd; if(passwd.empty() && !params::inst().userSetPwd) { @@ -239,10 +242,27 @@ void do_guided_config() // clear everything from stdin to allow an empty password std::cin.clear(); std::cin.ignore(INT_MAX,'\n'); + stdin_flushed = true; + std::cout<<"- Password (mostly empty or x):"<<std::endl; getline(std::cin, passwd); } + auto& rigid = params::inst().poolRigid; + if(rigid.empty() && !params::inst().userSetRigid) + { + prompt_once(prompted); + + if(!stdin_flushed) + { + // clear everything from stdin to allow an empty rigid + std::cin.clear(); std::cin.ignore(INT_MAX,'\n'); + } + + std::cout<<"- Rig identifier for pool-side statistics (needs pool support). Can be empty:"<<std::endl; + getline(std::cin, rigid); + } + bool tls; #ifdef CONF_NO_TLS tls = false; @@ -290,9 +310,9 @@ void do_guided_config() pool_weight = 1; std::string pool_table; - pool_table += "\t{\"pool_address\" : \"" + pool +"\", \"wallet_address\" : \"" + userName + "\", \"pool_password\" : \"" + - passwd + "\", \"use_nicehash\" : " + bool_to_str(nicehash) + ", \"use_tls\" : " + bool_to_str(tls) + - ", \"tls_fingerprint\" : \"\", \"pool_weight\" : " + std::to_string(pool_weight) + " },\n"; + pool_table += "\t{\"pool_address\" : \"" + pool +"\", \"wallet_address\" : \"" + userName + "\", \"rig_id\" : \"" + rigid + + "\", \"pool_password\" : \"" + passwd + "\", \"use_nicehash\" : " + bool_to_str(nicehash) + ", \"use_tls\" : " + + bool_to_str(tls) + ", \"tls_fingerprint\" : \"\", \"pool_weight\" : " + std::to_string(pool_weight) + " },\n"; if(multipool) { @@ -304,8 +324,50 @@ void do_guided_config() while(!final); } - configTpl.replace("POOLCONF", pool_table); configTpl.replace("CURRENCY", currency); + configTpl.replace("POOLCONF", pool_table); + configTpl.write(params::inst().configFilePools); + std::cout<<"Pool configuration stored in file '"<<params::inst().configFilePools<<"'"<<std::endl; +} + +void do_guided_config() +{ + using namespace xmrstak; + + // load the template of the backend config into a char variable + const char *tpl = + #include "../config.tpl" + ; + + configEditor configTpl{}; + configTpl.set(std::string(tpl)); + bool prompted = false; + + auto& http_port = params::inst().httpd_port; + if(http_port == params::httpd_port_unset) + { +#if defined(CONF_NO_HTTPD) + http_port = params::httpd_port_disabled; +#else + prompt_once(prompted); + + std::cout<<"- Do you want to use the HTTP interface?" <<std::endl; + std::cout<<"Unlike the screen display, browser interface is not affected by the GPU lag." <<std::endl; + std::cout<<"If you don't want to use it, please enter 0, otherwise enter port number that the miner should listen on" <<std::endl; + + int32_t port; + while(!(std::cin >> port) || port < 0 || port > 65535) + { + std::cin.clear(); + std::cin.ignore(INT_MAX, '\n'); + std::cout << "Invalid port number. Please enter a number between 0 and 65535." << std::endl; + } + + http_port = port; +#endif + } + + configTpl.replace("HTTP_PORT", std::to_string(http_port)); configTpl.write(params::inst().configFile); std::cout<<"Configuration stored in file '"<<params::inst().configFile<<"'"<<std::endl; } @@ -342,7 +404,14 @@ int main(int argc, char *argv[]) params::inst().executablePrefix += seperator; } - bool uacDialog = true; + params::inst().minerArg0 = argv[0]; + params::inst().minerArgs.reserve(argc * 16); + for(int i = 1; i < argc; i++) + { + params::inst().minerArgs += " "; + params::inst().minerArgs += argv[i]; + } + bool pool_url_set = false; for(size_t i = 1; i < argc-1; i++) { @@ -489,6 +558,26 @@ int main(int argc, char *argv[]) params::inst().userSetPwd = true; params::inst().poolPasswd = argv[i]; } + else if(opName.compare("-r") == 0 || opName.compare("--rigid") == 0) + { + if(!pool_url_set) + { + printer::inst()->print_msg(L0, "Pool address has to be set if you want to specify rigid."); + win_exit(); + return 1; + } + + ++i; + if( i >=argc ) + { + printer::inst()->print_msg(L0, "No argument for parameter '-r/--rigid' given"); + win_exit(); + return 1; + } + + params::inst().userSetRigid = true; + params::inst().poolRigid = argv[i]; + } else if(opName.compare("--use-nicehash") == 0) { params::inst().nicehashMode = true; @@ -504,9 +593,61 @@ int main(int argc, char *argv[]) } params::inst().configFile = argv[i]; } + else if(opName.compare("-C") == 0 || opName.compare("--poolconf") == 0) + { + ++i; + if( i >=argc ) + { + printer::inst()->print_msg(L0, "No argument for parameter '-C/--poolconf' given"); + win_exit(); + return 1; + } + params::inst().configFilePools = argv[i]; + } + else if(opName.compare("-i") == 0 || opName.compare("--httpd") == 0) + { + ++i; + if( i >=argc ) + { + printer::inst()->print_msg(L0, "No argument for parameter '-i/--httpd' given"); + win_exit(); + return 1; + } + + char* endp = nullptr; + long int ret = strtol(argv[i], &endp, 10); + + if(endp == nullptr || ret < 0 || ret > 65535) + { + printer::inst()->print_msg(L0, "Argument for parameter '-i/--httpd' must be a number between 0 and 65535"); + win_exit(); + return 1; + } + + params::inst().httpd_port = ret; + } else if(opName.compare("--noUAC") == 0) { - uacDialog = false; + params::inst().allowUAC = false; + } + else if(opName.compare("--benchmark") == 0) + { + ++i; + if( i >= argc ) + { + printer::inst()->print_msg(L0, "No argument for parameter '--benchmark' given"); + win_exit(); + return 1; + } + char* block_version = nullptr; + long int bversion = strtol(argv[i], &block_version, 10); + + if(bversion < 0 || bversion >= 256) + { + printer::inst()->print_msg(L0, "Benchmark block version must be in the range [0,255]"); + return 1; + } + params::inst().benchmark_block_version = bversion; } else { @@ -516,46 +657,51 @@ int main(int argc, char *argv[]) } } -#ifdef _WIN32 - if(uacDialog && !IsElevated()) - { - std::string minerArgs; - for(int i = 1; i < argc; i++) - { - minerArgs += " "; - minerArgs += argv[i]; - } - - SelfElevate(argv[0], minerArgs); - } -#endif - // check if we need a guided start if(!configEditor::file_exist(params::inst().configFile)) do_guided_config(); - if(!jconf::inst()->parse_config(params::inst().configFile.c_str())) + if(!configEditor::file_exist(params::inst().configFilePools)) + do_guided_pool_config(); + + if(!jconf::inst()->parse_config(params::inst().configFile.c_str(), params::inst().configFilePools.c_str())) { win_exit(); return 1; } +#ifdef _WIN32 + /* For Windows 7 and 8 request elevation at all times unless we are using slow memory */ + if(jconf::inst()->GetSlowMemSetting() != jconf::slow_mem_cfg::always_use && !IsWindows10OrNewer()) + { + printer::inst()->print_msg(L0, "Elevating due to Windows 7 or 8. You need Windows 10 to use fast memory without UAC elevation."); + RequestElevation(); + } +#endif + + if(strlen(jconf::inst()->GetOutputFile()) != 0) + printer::inst()->open_logfile(jconf::inst()->GetOutputFile()); + if (!BackendConnector::self_test()) { win_exit(); return 1; } -#ifndef CONF_NO_HTTPD - if(jconf::inst()->GetHttpdPort() != 0) + if(jconf::inst()->GetHttpdPort() != uint16_t(params::httpd_port_disabled)) { +#ifdef CONF_NO_HTTPD + printer::inst()->print_msg(L0, "HTTPD port is enabled but this binary was compiled without HTTP support!"); + win_exit(); + return 1; +#else if (!httpd::inst()->start_daemon()) { win_exit(); return 1; } - } #endif + } printer::inst()->print_str("-------------------------------------------------------------------\n"); printer::inst()->print_str(get_version_str_short().c_str()); @@ -576,14 +722,14 @@ int main(int argc, char *argv[]) printer::inst()->print_str("'r' - results\n"); printer::inst()->print_str("'c' - connection\n"); printer::inst()->print_str("-------------------------------------------------------------------\n"); - if(::jconf::inst()->IsCurrencyMonero()) - printer::inst()->print_msg(L0,"Start mining: MONERO"); - else - printer::inst()->print_msg(L0,"Start mining: AEON"); - - if(strlen(jconf::inst()->GetOutputFile()) != 0) - printer::inst()->open_logfile(jconf::inst()->GetOutputFile()); + printer::inst()->print_msg(L0, "Mining coin: %s", jconf::inst()->GetMiningCoin().c_str()); + if(params::inst().benchmark_block_version >= 0) + { + printer::inst()->print_str("!!!! Doing only a benchmark and exiting. To mine, remove the '--benchmark' option. !!!!\n"); + return do_benchmark(params::inst().benchmark_block_version); + } + executor::inst()->ex_start(jconf::inst()->DaemonMode()); uint64_t lastTime = get_timestamp_ms(); @@ -618,23 +764,34 @@ int main(int argc, char *argv[]) return 0; } -void do_benchmark() +int do_benchmark(int block_version) { using namespace std::chrono; std::vector<xmrstak::iBackend*>* pvThreads; - printer::inst()->print_msg(L0, "Running a 60 second benchmark..."); + printer::inst()->print_msg(L0, "Prepare benchmark for block version %d", block_version); - uint8_t work[76] = {0}; - xmrstak::miner_work oWork = xmrstak::miner_work("", work, sizeof(work), 0, false, 0); + uint8_t work[112]; + memset(work,0,112); + work[0] = static_cast<uint8_t>(block_version); + + xmrstak::pool_data dat; + + xmrstak::miner_work oWork = xmrstak::miner_work(); pvThreads = xmrstak::BackendConnector::thread_starter(oWork); + printer::inst()->print_msg(L0, "Wait 30 sec until all backends are initialized"); + std::this_thread::sleep_for(std::chrono::seconds(30)); + + /* AMD and NVIDIA is currently only supporting work sizes up to 84byte + * \todo fix this issue + */ + xmrstak::miner_work benchWork = xmrstak::miner_work("", work, 84, 0, false, 0); + printer::inst()->print_msg(L0, "Start a 60 second benchmark..."); + xmrstak::globalStates::inst().switch_work(benchWork, dat); uint64_t iStartStamp = get_timestamp_ms(); std::this_thread::sleep_for(std::chrono::seconds(60)); - - oWork = xmrstak::miner_work(); - xmrstak::pool_data dat; xmrstak::globalStates::inst().switch_work(oWork, dat); double fTotalHps = 0.0; @@ -643,9 +800,13 @@ void do_benchmark() double fHps = pvThreads->at(i)->iHashCount; fHps /= (pvThreads->at(i)->iTimestamp - iStartStamp) / 1000.0; - printer::inst()->print_msg(L0, "Thread %u: %.1f H/S", i, fHps); + auto bType = static_cast<xmrstak::iBackend::BackendType>(pvThreads->at(i)->backendType); + std::string name(xmrstak::iBackend::getName(bType)); + + printer::inst()->print_msg(L0, "Benchmark Thread %u %s: %.1f H/S", i,name.c_str(), fHps); fTotalHps += fHps; } - printer::inst()->print_msg(L0, "Total: %.1f H/S", fTotalHps); + printer::inst()->print_msg(L0, "Benchmark Total: %.1f H/S", fTotalHps); + return 0; } |