// Copyright (c) 2011-2016 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "MiningConfig.h" #include #include #include #include #include #include #include "CryptoNoteConfig.h" #include "Logging/ILogger.h" namespace po = boost::program_options; namespace CryptoNote { namespace { const size_t DEFAULT_SCANT_PERIOD = 30; const char* DEFAULT_DAEMON_HOST = "127.0.0.1"; const size_t CONCURRENCY_LEVEL = std::thread::hardware_concurrency(); po::options_description cmdOptions; void parseDaemonAddress(const std::string& daemonAddress, std::string& daemonHost, uint16_t& daemonPort) { std::vector splittedAddress; boost::algorithm::split(splittedAddress, daemonAddress, boost::algorithm::is_any_of(":")); if (splittedAddress.size() != 2) { throw std::runtime_error("Wrong daemon address format"); } if (splittedAddress[0].empty() || splittedAddress[1].empty()) { throw std::runtime_error("Wrong daemon address format"); } daemonHost = splittedAddress[0]; try { daemonPort = boost::lexical_cast(splittedAddress[1]); } catch (std::exception&) { throw std::runtime_error("Wrong daemon address format"); } } } MiningConfig::MiningConfig(): help(false) { cmdOptions.add_options() ("help,h", "produce this help message and exit") ("address", po::value(), "Valid cryptonote miner's address") ("daemon-host", po::value()->default_value(DEFAULT_DAEMON_HOST), "Daemon host") ("daemon-rpc-port", po::value()->default_value(static_cast(RPC_DEFAULT_PORT)), "Daemon's RPC port") ("daemon-address", po::value(), "Daemon host:port. If you use this option you must not use --daemon-host and --daemon-port options") ("threads", po::value()->default_value(CONCURRENCY_LEVEL), "Mining threads count. Must not be greater than you concurrency level. Default value is your hardware concurrency level") ("scan-time", po::value()->default_value(DEFAULT_SCANT_PERIOD), "Blockchain polling interval (seconds). How often miner will check blockchain for updates") ("log-level", po::value()->default_value(1), "Log level. Must be 0..5") ("limit", po::value()->default_value(0), "Mine exact quantity of blocks. 0 means no limit") ("first-block-timestamp", po::value()->default_value(0), "Set timestamp to the first mined block. 0 means leave timestamp unchanged") ("block-timestamp-interval", po::value()->default_value(0), "Timestamp step for each subsequent block. May be set only if --first-block-timestamp has been set." " If not set blocks' timestamps remain unchanged"); } void MiningConfig::parse(int argc, char** argv) { po::variables_map options; po::store(po::parse_command_line(argc, argv, cmdOptions), options); po::notify(options); if (options.count("help") != 0) { help = true; return; } if (options.count("address") == 0) { throw std::runtime_error("Specify --address option"); } miningAddress = options["address"].as(); if (!options["daemon-address"].empty()) { if (!options["daemon-host"].defaulted() || !options["daemon-rpc-port"].defaulted()) { throw std::runtime_error("Either --daemon-host or --daemon-rpc-port is already specified. You must not specify --daemon-address"); } parseDaemonAddress(options["daemon-address"].as(), daemonHost, daemonPort); } else { daemonHost = options["daemon-host"].as(); daemonPort = options["daemon-rpc-port"].as(); } threadCount = options["threads"].as(); if (threadCount == 0 || threadCount > CONCURRENCY_LEVEL) { throw std::runtime_error("--threads option must be 1.." + std::to_string(CONCURRENCY_LEVEL)); } scanPeriod = options["scan-time"].as(); if (scanPeriod == 0) { throw std::runtime_error("--scan-time must not be zero"); } logLevel = static_cast(options["log-level"].as()); if (logLevel > static_cast(Logging::TRACE)) { throw std::runtime_error("--log-level value is too big"); } blocksLimit = options["limit"].as(); if (!options["block-timestamp-interval"].defaulted() && options["first-block-timestamp"].defaulted()) { throw std::runtime_error("If you specify --block-timestamp-interval you must specify --first-block-timestamp either"); } firstBlockTimestamp = options["first-block-timestamp"].as(); blockTimestampInterval = options["block-timestamp-interval"].as(); } void MiningConfig::printHelp() { std::cout << cmdOptions << std::endl; } }