diff options
Diffstat (limited to 'src/cryptonote_basic')
-rw-r--r-- | src/cryptonote_basic/checkpoints.cpp | 109 | ||||
-rw-r--r-- | src/cryptonote_basic/miner.cpp | 77 | ||||
-rw-r--r-- | src/cryptonote_basic/miner.h | 8 |
3 files changed, 69 insertions, 125 deletions
diff --git a/src/cryptonote_basic/checkpoints.cpp b/src/cryptonote_basic/checkpoints.cpp index 3cf804ede..1e7754886 100644 --- a/src/cryptonote_basic/checkpoints.cpp +++ b/src/cryptonote_basic/checkpoints.cpp @@ -42,30 +42,6 @@ using namespace epee; #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "checkpoints" -namespace -{ - bool dns_records_match(const std::vector<std::string>& a, const std::vector<std::string>& b) - { - if (a.size() != b.size()) return false; - - for (const auto& record_in_a : a) - { - bool ok = false; - for (const auto& record_in_b : b) - { - if (record_in_a == record_in_b) - { - ok = true; - break; - } - } - if (!ok) return false; - } - - return true; - } -} // anonymous namespace - namespace cryptonote { //--------------------------------------------------------------------------- @@ -230,6 +206,8 @@ namespace cryptonote bool checkpoints::load_checkpoints_from_dns(bool testnet) { + std::vector<std::string> records; + // All four MoneroPulse domains have DNSSEC on and valid static const std::vector<std::string> dns_urls = { "checkpoints.moneropulse.se" , "checkpoints.moneropulse.org" @@ -243,87 +221,10 @@ namespace cryptonote , "testpoints.moneropulse.co" }; - std::vector<std::vector<std::string> > records; - records.resize(dns_urls.size()); - - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<int> dis(0, dns_urls.size() - 1); - size_t first_index = dis(gen); - - bool avail, valid; - size_t cur_index = first_index; - do - { - std::string url; - if (testnet) - { - url = testnet_dns_urls[cur_index]; - } - else - { - url = dns_urls[cur_index]; - } - - records[cur_index] = tools::DNSResolver::instance().get_txt_record(url, avail, valid); - if (!avail) - { - records[cur_index].clear(); - LOG_PRINT_L2("DNSSEC not available for checkpoint update at URL: " << url << ", skipping."); - } - if (!valid) - { - records[cur_index].clear(); - LOG_PRINT_L2("DNSSEC validation failed for checkpoint update at URL: " << url << ", skipping."); - } - - cur_index++; - if (cur_index == dns_urls.size()) - { - cur_index = 0; - } - records[cur_index].clear(); - } while (cur_index != first_index); - - size_t num_valid_records = 0; - - for( const auto& record_set : records) - { - if (record_set.size() != 0) - { - num_valid_records++; - } - } - - if (num_valid_records < 2) - { - LOG_PRINT_L0("WARNING: no two valid MoneroPulse DNS checkpoint records were received"); - return true; - } - - int good_records_index = -1; - for (size_t i = 0; i < records.size() - 1; ++i) - { - if (records[i].size() == 0) continue; - - for (size_t j = i + 1; j < records.size(); ++j) - { - if (dns_records_match(records[i], records[j])) - { - good_records_index = i; - break; - } - } - if (good_records_index >= 0) break; - } - - if (good_records_index < 0) - { - LOG_PRINT_L0("WARNING: no two MoneroPulse DNS checkpoint records matched"); - return true; - } + if (!tools::dns_utils::load_txt_records_from_dns(records, testnet ? testnet_dns_urls : dns_urls)) + return true; // why true ? - for (auto& record : records[good_records_index]) + for (const auto& record : records) { auto pos = record.find(":"); if (pos != std::string::npos) diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 9a982ca9f..70389f917 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -41,6 +41,7 @@ #include "common/command_line.h" #include "string_coding.h" #include "storages/portable_storage_template_helper.h" +#include "boost/logic/tribool.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "miner" @@ -61,6 +62,7 @@ namespace cryptonote const command_line::arg_descriptor<std::string> arg_start_mining = {"start-mining", "Specify wallet address to mining for", "", true}; const command_line::arg_descriptor<uint32_t> arg_mining_threads = {"mining-threads", "Specify mining threads count", 0, true}; const command_line::arg_descriptor<bool> arg_bg_mining_enable = {"bg-mining-enable", "enable/disable background mining", true, true}; + const command_line::arg_descriptor<bool> arg_bg_mining_ignore_battery = {"bg-mining-ignore-battery", "if true, assumes plugged in when unable to query system power status", false, true}; const command_line::arg_descriptor<uint64_t> arg_bg_mining_min_idle_interval_seconds = {"bg-mining-min-idle-interval", "Specify min lookback interval in seconds for determining idle state", miner::BACKGROUND_MINING_DEFAULT_MIN_IDLE_INTERVAL_IN_SECONDS, true}; const command_line::arg_descriptor<uint8_t> arg_bg_mining_idle_threshold_percentage = {"bg-mining-idle-threshold", "Specify minimum avg idle percentage over lookback interval", miner::BACKGROUND_MINING_DEFAULT_IDLE_THRESHOLD_PERCENTAGE, true}; const command_line::arg_descriptor<uint8_t> arg_bg_mining_miner_target_percentage = {"bg-mining-miner-target", "Specificy maximum percentage cpu use by miner(s)", miner::BACKGROUND_MINING_DEFAULT_MINING_TARGET_PERCENTAGE, true}; @@ -181,6 +183,7 @@ namespace cryptonote command_line::add_arg(desc, arg_start_mining); command_line::add_arg(desc, arg_mining_threads); command_line::add_arg(desc, arg_bg_mining_enable); + command_line::add_arg(desc, arg_bg_mining_ignore_battery); command_line::add_arg(desc, arg_bg_mining_min_idle_interval_seconds); command_line::add_arg(desc, arg_bg_mining_idle_threshold_percentage); command_line::add_arg(desc, arg_bg_mining_miner_target_percentage); @@ -230,6 +233,8 @@ namespace cryptonote // Let init set all parameters even if background mining is not enabled, they can start later with params set if(command_line::has_arg(vm, arg_bg_mining_enable)) set_is_background_mining_enabled( command_line::get_arg(vm, arg_bg_mining_enable) ); + if(command_line::has_arg(vm, arg_bg_mining_ignore_battery)) + set_ignore_battery( command_line::get_arg(vm, arg_bg_mining_ignore_battery) ); if(command_line::has_arg(vm, arg_bg_mining_min_idle_interval_seconds)) set_min_idle_seconds( command_line::get_arg(vm, arg_bg_mining_min_idle_interval_seconds) ); if(command_line::has_arg(vm, arg_bg_mining_idle_threshold_percentage)) @@ -254,7 +259,7 @@ namespace cryptonote return m_threads_total; } //----------------------------------------------------------------------------------------------------- - bool miner::start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs, bool do_background) + bool miner::start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs, bool do_background, bool ignore_battery) { m_mine_address = adr; m_threads_total = static_cast<uint32_t>(threads_count); @@ -278,6 +283,7 @@ namespace cryptonote boost::interprocess::ipcdetail::atomic_write32(&m_stop, 0); boost::interprocess::ipcdetail::atomic_write32(&m_thread_index, 0); set_is_background_mining_enabled(do_background); + set_ignore_battery(ignore_battery); for(size_t i = 0; i != threads_count; i++) { @@ -469,6 +475,11 @@ namespace cryptonote return m_is_background_mining_enabled; } //----------------------------------------------------------------------------------------------------- + bool miner::get_ignore_battery() const + { + return m_ignore_battery; + } + //----------------------------------------------------------------------------------------------------- /** * This has differing behaviour depending on if mining has been started/etc. * Note: add documentation @@ -482,6 +493,11 @@ namespace cryptonote return true; } //----------------------------------------------------------------------------------------------------- + void miner::set_ignore_battery(bool ignore_battery) + { + m_ignore_battery = ignore_battery; + } + //----------------------------------------------------------------------------------------------------- uint64_t miner::get_min_idle_seconds() const { return m_min_idle_seconds; @@ -574,7 +590,21 @@ namespace cryptonote continue; // if interrupted because stop called, loop should end .. } - bool on_ac_power = !on_battery_power(); + boost::tribool battery_powered(on_battery_power()); + bool on_ac_power = false; + if(indeterminate( battery_powered )) + { + // name could be better, only ignores battery requirement if we failed + // to get the status of the system + if( m_ignore_battery ) + { + on_ac_power = true; + } + } + else + { + on_ac_power = !battery_powered; + } if( m_is_background_mining_started ) { @@ -762,45 +792,54 @@ namespace cryptonote return (uint8_t)( ceil( (other * 1.f / total * 1.f) * 100) ); } //----------------------------------------------------------------------------------------------------- - bool miner::on_battery_power() + boost::logic::tribool miner::on_battery_power() { #ifdef _WIN32 SYSTEM_POWER_STATUS power_status; if ( GetSystemPowerStatus( &power_status ) != 0 ) { - return power_status.ACLineStatus != 1; + return boost::logic::tribool(power_status.ACLineStatus != 1); } #elif defined(__linux__) // i've only tested on UBUNTU, these paths might be different on other systems // need to figure out a way to make this more flexible - const std::string POWER_SUPPLY_STATUS_PATH = "/sys/class/power_supply/ACAD/online"; - - if( !epee::file_io_utils::is_file_exist(POWER_SUPPLY_STATUS_PATH) ) + std::string power_supply_path = ""; + const std::string POWER_SUPPLY_STATUS_PATHS[] = { - LOG_ERROR("'" << POWER_SUPPLY_STATUS_PATH << "' file does not exist, can't determine if on AC power"); - return false; + "/sys/class/power_supply/ACAD/online", + "/sys/class/power_supply/AC/online" + }; + + for(const std::string& path : POWER_SUPPLY_STATUS_PATHS) + { + if( epee::file_io_utils::is_file_exist(path) ) + { + power_supply_path = path; + break; + } + } + + if( power_supply_path.empty() ) + { + LOG_ERROR("Couldn't find battery/power status file, can't determine if plugged in!"); + return boost::logic::tribool(boost::logic::indeterminate);; } - std::ifstream power_stream(POWER_SUPPLY_STATUS_PATH); + std::ifstream power_stream(power_supply_path); if( power_stream.fail() ) { - LOG_ERROR("failed to open '" << POWER_SUPPLY_STATUS_PATH << "'"); - return false; + LOG_ERROR("failed to open '" << power_supply_path << "'"); + return boost::logic::tribool(boost::logic::indeterminate);; } - return power_stream.get() != '1'; + return boost::logic::tribool( (power_stream.get() != '1') ); #endif LOG_ERROR("couldn't query power status"); - return false; // shouldn't get here unless no support for querying battery status - // TODO: return enum with ability to signify failure in querying for power status - // and change bg-mining logic so that it stops. As @vtnerd states, with the current - // setup "If someone enabled background mining on a system that fails to grab ac - // status, it will just continually check with little hope of ever being resolved - // automagically". This is also the case for time/idle stats functions. + return boost::logic::tribool(boost::logic::indeterminate); } } diff --git a/src/cryptonote_basic/miner.h b/src/cryptonote_basic/miner.h index a66083ead..02987b9d9 100644 --- a/src/cryptonote_basic/miner.h +++ b/src/cryptonote_basic/miner.h @@ -31,6 +31,7 @@ #pragma once #include <boost/program_options.hpp> +#include <boost/logic/tribool_fwd.hpp> #include <atomic> #include "cryptonote_basic.h" #include "difficulty.h" @@ -67,7 +68,7 @@ namespace cryptonote static void init_options(boost::program_options::options_description& desc); bool set_block_template(const block& bl, const difficulty_type& diffic, uint64_t height); bool on_block_chain_update(); - bool start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs, bool do_background = false); + bool start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs, bool do_background = false, bool ignore_battery = false); uint64_t get_speed() const; uint32_t get_threads_count() const; void send_stop_signal(); @@ -82,6 +83,7 @@ namespace cryptonote void resume(); void do_print_hashrate(bool do_hr); bool get_is_background_mining_enabled() const; + bool get_ignore_battery() const; uint64_t get_min_idle_seconds() const; bool set_min_idle_seconds(uint64_t min_idle_seconds); uint8_t get_idle_threshold() const; @@ -149,8 +151,10 @@ namespace cryptonote // background mining stuffs .. bool set_is_background_mining_enabled(bool is_background_mining_enabled); + void set_ignore_battery(bool ignore_battery); bool background_worker_thread(); std::atomic<bool> m_is_background_mining_enabled; + bool m_ignore_battery; boost::mutex m_is_background_mining_enabled_mutex; boost::condition_variable m_is_background_mining_enabled_cond; std::atomic<bool> m_is_background_mining_started; @@ -164,6 +168,6 @@ namespace cryptonote static bool get_system_times(uint64_t& total_time, uint64_t& idle_time); static bool get_process_time(uint64_t& total_time); static uint8_t get_percent_of_total(uint64_t some_time, uint64_t total_time); - static bool on_battery_power(); + static boost::logic::tribool on_battery_power(); }; } |