34#include <boost/utility/value_init.hpp>
35#include <boost/interprocess/detail/atomic.hpp>
36#include <boost/algorithm/string.hpp>
37#include <boost/filesystem.hpp>
47#include "boost/logic/tribool.hpp"
50 #include <sys/times.h>
51 #include <IOKit/IOKitLib.h>
52 #include <IOKit/ps/IOPSKeys.h>
53 #include <IOKit/ps/IOPowerSources.h>
54 #include <mach/mach_host.h>
55 #include <AvailabilityMacros.h>
56 #include <TargetConditionals.h>
57#elif defined(__linux__)
59 #include <sys/resource.h>
60 #include <sys/times.h>
62#elif defined(__FreeBSD__)
66 #include <machine/apm_bios.h>
68 #include <sys/resource.h>
69 #include <sys/sysctl.h>
70 #include <sys/times.h>
71 #include <sys/types.h>
75#undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
76#define ELECTRONEUM_DEFAULT_LOG_CATEGORY "miner"
78#define AUTODETECT_WINDOW 10
79#define AUTODETECT_GAIN_THRESHOLD 1.02f
94 const command_line::arg_descriptor<std::string> arg_start_mining = {
"start-mining",
"Specify wallet address to mining for",
"",
true};
95 const command_line::arg_descriptor<uint32_t> arg_mining_threads = {
"mining-threads",
"Specify mining threads count", 0,
true};
96 const command_line::arg_descriptor<bool> arg_bg_mining_enable = {
"bg-mining-enable",
"enable/disable background mining",
true,
true};
97 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};
105 m_template(
boost::value_initialized<
block>()),
109 m_phandler(phandler),
115 m_last_hr_merge_time(0),
118 m_do_print_hashrate(
false),
120 m_current_hash_rate(0),
121 m_is_background_mining_enabled(
false),
143 m_block_reward = block_reward;
154 return request_block_template();
157 bool miner::request_block_template()
165 if(m_extra_messages.size() && m_config.current_extra_message_index < m_extra_messages.size())
167 extra_nonce = m_extra_messages[m_config.current_extra_message_index];
172 LOG_ERROR(
"Failed to get_block_template(), stopping mining");
181 m_update_block_template_interval.do_call([&](){
186 m_update_merge_hr_interval.do_call([&](){
191 m_autodetect_interval.do_call([&](){
192 update_autodetection();
201 m_do_print_hashrate = do_hr;
204 void miner::merge_hr()
210 m_last_hash_rates.push_back(m_current_hash_rate);
211 if(m_last_hash_rates.size() > 19)
212 m_last_hash_rates.pop_front();
213 if(m_do_print_hashrate)
215 uint64_t total_hr = std::accumulate(m_last_hash_rates.begin(), m_last_hash_rates.end(), 0);
216 float hr =
static_cast<float>(total_hr)/
static_cast<float>(m_last_hash_rates.size());
217 const auto flags = std::cout.flags();
218 const auto precision = std::cout.precision();
219 std::cout <<
"hashrate: " << std::setprecision(4) << std::fixed << hr << std::setiosflags(flags) << std::setprecision(precision) <<
ENDL;
226 void miner::update_autodetection()
228 if (m_threads_autodetect.empty())
232 uint64_t dt = now - m_threads_autodetect.back().first;
237 m_threads_autodetect.back().first = dt;
238 uint64_t dh = m_total_hashes - m_threads_autodetect.back().second;
239 m_threads_autodetect.back().second = dh;
240 float hs = dh / (dt / (float)1000000000);
241 MGINFO(
"Mining autodetection: " << m_threads_autodetect.size() <<
" threads: " << hs <<
" H/s");
246 if (m_threads_autodetect.size() > 1)
248 int previdx = m_threads_autodetect.size() - 2;
249 float previous_hs = m_threads_autodetect[previdx].second / (m_threads_autodetect[previdx].first / (float)1000000000);
252 m_threads_total = m_threads_autodetect.size() - 1;
253 m_threads_autodetect.clear();
254 MGINFO(
"Optimal number of threads seems to be " << m_threads_total);
262 m_threads_autodetect.push_back({now, m_total_hashes});
263 m_threads_total = m_threads_autodetect.size();
269 boost::interprocess::ipcdetail::atomic_write32(&m_stop, 1);
270 while (m_threads_active > 0)
274 boost::interprocess::ipcdetail::atomic_write32(&m_stop, 0);
275 boost::interprocess::ipcdetail::atomic_write32(&m_thread_index, 0);
276 for(
size_t i = 0; i != m_threads_total; i++)
277 m_threads.push_back(boost::thread(m_attrs, boost::bind(&miner::worker_thread,
this)));
299 std::vector<std::string> extra_vec;
300 boost::split(extra_vec, buff, boost::is_any_of(
"\n"), boost::token_compress_on );
301 m_extra_messages.resize(extra_vec.size());
302 for(
size_t i = 0; i != extra_vec.size(); i++)
305 if(!extra_vec[i].size())
309 m_extra_messages[i] = buff;
311 m_config_folder_path = boost::filesystem::path(
command_line::get_arg(vm, arg_extra_messages)).parent_path().string();
315 MINFO(
"Loaded " << m_extra_messages.size() <<
" extra messages, current index " << m_config.current_extra_message_index);
327 if(!(
command_line::get_arg(vm, arg_start_mining) ==
"etnkCys4uGhSi9h48ajL9vBDJTcn2s2ttXtXq3SXWPAbiMHNhHitu5fJ8QgRfFWTzmJ8QgRfFWTzmJ8QgRfFWTzm4t51HTfCtK"))
329 LOG_ERROR(
"Target account address " <<
command_line::get_arg(vm, arg_start_mining) <<
" isn't equal to the Aurelius legacy mining burn address etnkCys4uGhSi9h48ajL9vBDJTcn2s2ttXtXq3SXWPAbiMHNhHitu5fJ8QgRfFWTzmJ8QgRfFWTzmJ8QgRfFWTzm4t51HTfCtK");
332 m_mine_address =
info.address;
354 m_fallback_to_pow = fallback_to_pow;
366 return m_mine_address;
370 return m_threads_total;
376 m_mine_address = adr;
377 m_threads_total =
static_cast<uint32_t>(threads_count);
378 if (threads_count == 0)
380 m_threads_autodetect.clear();
388 LOG_ERROR(
"Starting miner but it's already started");
392 if(!m_threads.empty())
394 LOG_ERROR(
"Unable to start miner because there are active mining threads");
398 request_block_template();
400 boost::interprocess::ipcdetail::atomic_write32(&m_stop, 0);
401 boost::interprocess::ipcdetail::atomic_write32(&m_thread_index, 0);
402 set_is_background_mining_enabled(do_background);
403 set_ignore_battery(ignore_battery);
405 for(
size_t i = 0; i != m_threads_total; i++)
407 m_threads.push_back(boost::thread(m_attrs, boost::bind(&miner::worker_thread,
this)));
410 if (threads_count == 0)
411 MINFO(
"Mining has started, autodetecting optimal number of threads, good luck!" );
413 MINFO(
"Mining has started with " << threads_count <<
" threads, good luck!" );
417 m_background_mining_thread = boost::thread(m_attrs, boost::bind(&miner::background_worker_thread,
this));
418 LOG_PRINT_L0(
"Background mining controller thread started" );
423 MINFO(
"Ignoring battery");
432 return m_current_hash_rate;
441 boost::interprocess::ipcdetail::atomic_write32(&m_stop, 1);
446 MTRACE(
"Miner has received stop signal");
449 bool mining = !m_threads.empty();
452 MTRACE(
"Not mining - nothing to stop" );
460 while (m_threads_active > 0)
462 m_is_background_mining_started_cond.notify_all();
468 m_background_mining_thread.interrupt();
469 m_background_mining_thread.join();
470 m_is_background_mining_enabled =
false;
472 MINFO(
"Mining has been stopped, " << m_threads.size() <<
" finished" );
474 m_threads_autodetect.clear();
480 for(; bl.
nonce != std::numeric_limits<uint32_t>::max(); bl.
nonce++)
506 MDEBUG(
"miner::pause: " << m_pausers_count <<
" -> " << (m_pausers_count + 1));
515 MDEBUG(
"miner::resume: " << m_pausers_count <<
" -> " << (m_pausers_count - 1));
517 if(m_pausers_count < 0)
525 bool miner::worker_thread()
527 uint32_t th_local_index = boost::interprocess::ipcdetail::atomic_inc32(&m_thread_index);
529 MGINFO(
"Miner thread was started ["<< th_local_index <<
"]");
530 uint32_t nonce = m_starter_nonce + th_local_index;
544 else if( m_is_background_mining_enabled )
547 while( !m_is_background_mining_started )
549 MGINFO(
"background mining is enabled, but not started, waiting until start triggers");
550 boost::unique_lock<boost::mutex> started_lock( m_is_background_mining_started_mutex );
551 m_is_background_mining_started_cond.wait( started_lock );
555 if( m_stop )
continue;
558 if(local_template_ver != m_template_no)
567 local_diff = m_diffic;
570 local_template_ver = m_template_no;
571 nonce = m_starter_nonce + th_local_index;
574 if(!local_template_ver)
588 ++m_config.current_extra_message_index;
590 cryptonote::block_verification_context bvc;
593 --m_config.current_extra_message_index;
597 if (!m_config_folder_path.empty())
601 nonce+=m_threads_total;
606 MGINFO(
"Miner thread stopped ["<< th_local_index <<
"]");
613 return m_is_background_mining_enabled;
618 return m_ignore_battery;
625 bool miner::set_is_background_mining_enabled(
bool is_background_mining_enabled)
627 m_is_background_mining_enabled = is_background_mining_enabled;
634 void miner::set_ignore_battery(
bool ignore_battery)
636 m_ignore_battery = ignore_battery;
641 return m_min_idle_seconds;
648 m_min_idle_seconds = min_idle_seconds;
654 return m_idle_threshold;
661 m_idle_threshold = idle_threshold;
667 return m_mining_target;
674 m_mining_target = mining_target;
678 bool miner::background_worker_thread()
680 uint64_t prev_total_time, current_total_time;
681 uint64_t prev_idle_time, current_idle_time;
682 uint64_t previous_process_time = 0, current_process_time = 0;
683 m_is_background_mining_started =
false;
685 if(!get_system_times(prev_total_time, prev_idle_time))
687 LOG_ERROR(
"get_system_times call failed, background mining will NOT work!");
723 boost::this_thread::sleep_for(boost::chrono::seconds(sleep_for_seconds));
725 catch(
const boost::thread_interrupted&)
727 MDEBUG(
"background miner thread interrupted ");
731 bool on_ac_power = m_ignore_battery;
732 if(!m_ignore_battery)
734 boost::tribool battery_powered(on_battery_power());
735 if(!indeterminate( battery_powered ))
737 on_ac_power = !(
bool)battery_powered;
741 if( m_is_background_mining_started )
748 if(!get_system_times(current_total_time, current_idle_time))
750 MERROR(
"get_system_times call failed");
754 if(!get_process_time(current_process_time))
756 MERROR(
"get_process_time call failed!");
760 uint64_t total_diff = (current_total_time - prev_total_time);
761 uint64_t idle_diff = (current_idle_time - prev_idle_time);
762 uint64_t process_diff = (current_process_time - previous_process_time);
763 uint8_t idle_percentage = get_percent_of_total(idle_diff, total_diff);
764 uint8_t process_percentage = get_percent_of_total(process_diff, total_diff);
766 MDEBUG(
"idle percentage is " <<
unsigned(idle_percentage) <<
"\%, miner percentage is " <<
unsigned(process_percentage) <<
"\%, ac power : " << on_ac_power);
769 MINFO(
"cpu is " <<
unsigned(idle_percentage) <<
"% idle, idle threshold is " <<
unsigned(
get_idle_threshold()) <<
"\%, ac power : " << on_ac_power <<
", background mining stopping, thanks for your contribution!");
770 m_is_background_mining_started =
false;
773 previous_process_time = 0;
774 current_process_time = 0;
778 previous_process_time = current_process_time;
782 int64_t new_miner_extra_sleep = m_miner_extra_sleep + miner_extra_sleep_change;
786 m_miner_extra_sleep = std::max( new_miner_extra_sleep , (
int64_t)5 );
787 MDEBUG(
"m_miner_extra_sleep " << m_miner_extra_sleep);
790 prev_total_time = current_total_time;
791 prev_idle_time = current_idle_time;
793 else if( on_ac_power )
797 if(!get_system_times(current_total_time, current_idle_time))
799 MERROR(
"get_system_times call failed");
803 uint64_t total_diff = (current_total_time - prev_total_time);
804 uint64_t idle_diff = (current_idle_time - prev_idle_time);
805 uint8_t idle_percentage = get_percent_of_total(idle_diff, total_diff);
807 MDEBUG(
"idle percentage is " <<
unsigned(idle_percentage));
810 MINFO(
"cpu is " <<
unsigned(idle_percentage) <<
"% idle, idle threshold is " <<
unsigned(
get_idle_threshold()) <<
"\%, ac power : " << on_ac_power <<
", background mining started, good luck!");
811 m_is_background_mining_started =
true;
812 m_is_background_mining_started_cond.notify_all();
815 boost::this_thread::sleep_for(boost::chrono::seconds( 1 ));
818 if(!get_process_time(previous_process_time))
820 m_is_background_mining_started =
false;
821 MERROR(
"get_process_time call failed!");
825 prev_total_time = current_total_time;
826 prev_idle_time = current_idle_time;
840 if ( GetSystemTimes( &idleTime, &kernelTime, &userTime ) != -1 )
843 ( (((
uint64_t)(kernelTime.dwHighDateTime)) << 32) | ((
uint64_t)kernelTime.dwLowDateTime) )
844 + ( (((
uint64_t)(userTime.dwHighDateTime)) << 32) | ((
uint64_t)userTime.dwLowDateTime) );
846 idle_time = ( (((
uint64_t)(idleTime.dwHighDateTime)) << 32) | ((
uint64_t)idleTime.dwLowDateTime) );
851 #elif defined(__linux__)
853 const std::string STAT_FILE_PATH =
"/proc/stat";
857 LOG_ERROR(
"'" << STAT_FILE_PATH <<
"' file does not exist");
861 std::ifstream stat_file_stream(STAT_FILE_PATH);
862 if( stat_file_stream.fail() )
864 LOG_ERROR(
"failed to open '" << STAT_FILE_PATH <<
"'");
869 std::getline(stat_file_stream, line);
870 std::istringstream stat_file_iss(line);
871 stat_file_iss.ignore(65536,
' ');
872 uint64_t utime, ntime, stime, itime;
873 if( !(stat_file_iss >> utime && stat_file_iss >> ntime && stat_file_iss >> stime && stat_file_iss >> itime) )
875 LOG_ERROR(
"failed to read '" << STAT_FILE_PATH <<
"'");
880 total_time = utime + ntime + stime + itime;
884 #elif defined(__APPLE__)
886 mach_msg_type_number_t
count;
887 kern_return_t status;
888 host_cpu_load_info_data_t stats;
889 count = HOST_CPU_LOAD_INFO_COUNT;
890 status = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&stats, &count);
891 if(status != KERN_SUCCESS)
896 idle_time = stats.cpu_ticks[CPU_STATE_IDLE];
897 total_time = idle_time + stats.cpu_ticks[CPU_STATE_USER] + stats.cpu_ticks[CPU_STATE_SYSTEM];
901 #elif defined(__FreeBSD__)
904 size_t n =
sizeof(s.cp_time);
905 if( sysctlbyname(
"kern.cp_time", s.cp_time, &n, NULL, 0) == -1 )
907 LOG_ERROR(
"sysctlbyname(\"kern.cp_time\"): " << strerror(errno));
910 if( n !=
sizeof(s.cp_time) )
912 LOG_ERROR(
"sysctlbyname(\"kern.cp_time\") output is unexpectedly "
913 << n <<
" bytes instead of the expected " <<
sizeof(s.cp_time)
918 idle_time = s.cp_time[CP_IDLE];
933 bool miner::get_process_time(
uint64_t& total_time)
941 if ( GetProcessTimes( GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime ) != -1 )
944 ( (((
uint64_t)(kernelTime.dwHighDateTime)) << 32) | ((
uint64_t)kernelTime.dwLowDateTime) )
945 + ( (((
uint64_t)(userTime.dwHighDateTime)) << 32) | ((
uint64_t)userTime.dwLowDateTime) );
950 #elif (defined(__linux__) && defined(_SC_CLK_TCK)) || defined(__APPLE__) || defined(__FreeBSD__)
953 if ( times(&tms) != (clock_t)-1 )
955 total_time = tms.tms_utime + tms.tms_stime;
966 return (
uint8_t)( ceil( (other * 1.f / total * 1.f) * 100) );
969 boost::logic::tribool miner::on_battery_power()
973 SYSTEM_POWER_STATUS power_status;
974 if ( GetSystemPowerStatus( &power_status ) != 0 )
976 return boost::logic::tribool(power_status.ACLineStatus != 1);
979 #elif defined(__APPLE__)
981 #if TARGET_OS_MAC && (!defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7)
982 return boost::logic::tribool(IOPSGetTimeRemainingEstimate() != kIOPSTimeRemainingUnlimited);
985 return boost::logic::tribool(boost::logic::indeterminate);
988 #elif defined(__linux__)
991 std::string power_supply_class_path =
"/sys/class/power_supply";
993 boost::tribool on_battery = boost::logic::tribool(boost::logic::indeterminate);
994 if (boost::filesystem::is_directory(power_supply_class_path))
996 const boost::filesystem::directory_iterator end_itr;
997 for (boost::filesystem::directory_iterator iter(power_supply_class_path); iter != end_itr; ++iter)
999 const boost::filesystem::path& power_supply_path = iter->path();
1000 if (boost::filesystem::is_directory(power_supply_path))
1002 boost::filesystem::path power_supply_type_path = power_supply_path /
"type";
1003 if (boost::filesystem::is_regular_file(power_supply_type_path))
1005 std::ifstream power_supply_type_stream(power_supply_type_path.string());
1006 if (power_supply_type_stream.fail())
1008 LOG_PRINT_L0(
"Unable to read from " << power_supply_type_path <<
" to check power supply type");
1012 std::string power_supply_type;
1013 std::getline(power_supply_type_stream, power_supply_type);
1016 if (boost::starts_with(power_supply_type,
"Mains"))
1018 boost::filesystem::path power_supply_online_path = power_supply_path /
"online";
1019 if (boost::filesystem::is_regular_file(power_supply_online_path))
1021 std::ifstream power_supply_online_stream(power_supply_online_path.string());
1022 if (power_supply_online_stream.fail())
1024 LOG_PRINT_L0(
"Unable to read from " << power_supply_online_path <<
" to check ac power supply status");
1028 if (power_supply_online_stream.get() ==
'1')
1030 return boost::logic::tribool(
false);
1034 else if (boost::starts_with(power_supply_type,
"Battery") && boost::logic::indeterminate(on_battery))
1036 boost::filesystem::path power_supply_status_path = power_supply_path /
"status";
1037 if (boost::filesystem::is_regular_file(power_supply_status_path))
1039 std::ifstream power_supply_status_stream(power_supply_status_path.string());
1040 if (power_supply_status_stream.fail())
1042 LOG_PRINT_L0(
"Unable to read from " << power_supply_status_path <<
" to check battery power supply status");
1048 std::string power_supply_status;
1049 std::getline(power_supply_status_stream, power_supply_status);
1050 if (boost::starts_with(power_supply_status,
"Charging") || boost::starts_with(power_supply_status,
"Full"))
1052 on_battery = boost::logic::tribool(
false);
1055 if (boost::starts_with(power_supply_status,
"Discharging"))
1057 on_battery = boost::logic::tribool(
true);
1066 if (boost::logic::indeterminate(on_battery))
1068 static bool error_shown =
false;
1071 LOG_ERROR(
"couldn't query power status from " << power_supply_class_path);
1077 #elif defined(__FreeBSD__)
1079 size_t n =
sizeof(ac);
1080 if( sysctlbyname(
"hw.acpi.acline", &ac, &n, NULL, 0) == -1 )
1082 if( errno != ENOENT )
1084 LOG_ERROR(
"Cannot query battery status: "
1085 <<
"sysctlbyname(\"hw.acpi.acline\"): " << strerror(errno));
1086 return boost::logic::tribool(boost::logic::indeterminate);
1091 static const char* dev_apm =
"/dev/apm";
1092 const int fd = open(dev_apm, O_RDONLY);
1094 LOG_ERROR(
"Cannot query battery status: "
1095 <<
"open(): " << dev_apm <<
": " << strerror(errno));
1096 return boost::logic::tribool(boost::logic::indeterminate);
1100 if( ioctl(fd, APMIO_GETINFO, &
info) == -1 ) {
1102 LOG_ERROR(
"Cannot query battery status: "
1103 <<
"ioctl(" << dev_apm <<
", APMIO_GETINFO): " << strerror(errno));
1104 return boost::logic::tribool(boost::logic::indeterminate);
1110 switch(
info.ai_acline )
1114 return boost::logic::tribool(
true);
1116 return boost::logic::tribool(
false);
1118 switch(
info.ai_batt_stat )
1123 return boost::logic::tribool(
true);
1125 return boost::logic::tribool(
false);
1128 LOG_ERROR(
"Cannot query battery status: "
1129 <<
"sysctl hw.acpi.acline is not available and /dev/apm returns "
1130 <<
"unexpected ac-line status (" <<
info.ai_acline <<
") and "
1131 <<
"battery status (" <<
info.ai_batt_stat <<
").");
1132 return boost::logic::tribool(boost::logic::indeterminate);
1134 if( n !=
sizeof(ac) )
1136 LOG_ERROR(
"sysctlbyname(\"hw.acpi.acline\") output is unexpectedly "
1137 << n <<
" bytes instead of the expected " <<
sizeof(ac) <<
" bytes.");
1138 return boost::logic::tribool(boost::logic::indeterminate);
1140 return boost::logic::tribool(ac == 0);
1143 LOG_ERROR(
"couldn't query power status");
1144 return boost::logic::tribool(boost::logic::indeterminate);
const account_public_address & get_mining_address() const
static constexpr uint8_t BACKGROUND_MINING_MAX_IDLE_THRESHOLD_PERCENTAGE
static constexpr uint8_t BACKGROUND_MINING_DEFAULT_IDLE_THRESHOLD_PERCENTAGE
static constexpr uint16_t BACKGROUND_MINING_DEFAULT_MIN_IDLE_INTERVAL_IN_SECONDS
static constexpr uint8_t BACKGROUND_MINING_MIN_IDLE_THRESHOLD_PERCENTAGE
static constexpr uint8_t BACKGROUND_MINING_DEFAULT_MINING_TARGET_PERCENTAGE
uint64_t get_min_idle_seconds() const
static constexpr uint16_t BACKGROUND_MINING_MIN_MIN_IDLE_INTERVAL_IN_SECONDS
static constexpr uint8_t BACKGROUND_MINING_MINER_MONITOR_INVERVAL_IN_SECONDS
uint64_t get_speed() const
static void init_options(boost::program_options::options_description &desc)
bool set_block_template(const block &bl, const difficulty_type &diffic, uint64_t height, uint64_t block_reward)
uint32_t get_threads_count() const
static constexpr uint8_t BACKGROUND_MINING_MAX_MINING_TARGET_PERCENTAGE
miner(i_miner_handler *phandler)
bool get_ignore_battery() const
bool set_min_idle_seconds(uint64_t min_idle_seconds)
bool on_block_chain_update()
bool get_is_background_mining_enabled() const
bool init(const boost::program_options::variables_map &vm, network_type nettype, bool fallback_to_pow=false)
static bool find_nonce_for_given_block(block &bl, const difficulty_type &diffic, uint64_t height)
static constexpr uint16_t BACKGROUND_MINING_MAX_MIN_IDLE_INTERVAL_IN_SECONDS
uint8_t get_idle_threshold() const
bool start(const account_public_address &adr, size_t threads_count, bool do_background=false, bool ignore_battery=false)
void do_print_hashrate(bool do_hr)
static constexpr uint64_t BACKGROUND_MINING_DEFAULT_MINER_EXTRA_SLEEP_MILLIS
uint8_t get_mining_target() const
bool set_idle_threshold(uint8_t idle_threshold)
bool set_mining_target(uint8_t mining_target)
static constexpr uint8_t BACKGROUND_MINING_MIN_MINING_TARGET_PERCENTAGE
#define THREAD_STACK_SIZE
#define MINER_CONFIG_FILE_NAME
#define AUTODETECT_GAIN_THRESHOLD
#define AUTODETECT_WINDOW
void slow_hash_allocate_state()
void slow_hash_free_state()
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
#define MLOG_SET_THREAD_NAME(x)
void add_arg(boost::program_options::options_description &description, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg, bool unique=true)
std::enable_if<!std::is_same< T, bool >::value, bool >::type has_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)
T get_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, false, true > &arg)
std::enable_if< std::is_pod< T >::value, T >::type rand()
Holds cryptonote related classes and helpers.
boost::multiprecision::uint128_t difficulty_type
bool get_block_hash(const block &b, crypto::hash &res)
bool get_account_address_from_str(address_parse_info &info, network_type nettype, std::string const &str)
bool check_hash(const crypto::hash &hash, difficulty_type difficulty)
bool get_block_longhash(const block &b, crypto::hash &res, uint64_t height)
bool load_file_to_string(const std::string &path_to_file, std::string &target_str, size_t max_size=1000000000)
bool is_file_exist(const std::string &path)
uint64_t get_tick_count()
bool store_t_to_json_file(t_struct &str_in, const std::string &fpath)
bool load_t_from_json_file(t_struct &out, const std::string &json_file)
std::string base64_decode(std::string const &encoded_string)
mdb_size_t count(MDB_cursor *cur)
unsigned __int64 uint64_t
bool m_added_to_main_chain
std::vector< uint8_t > signature
virtual bool get_block_template(block &b, const account_public_address &adr, difficulty_type &diffic, uint64_t &height, uint64_t &expected_reward, const blobdata &ex_nonce)=0
#define CRITICAL_REGION_LOCAL(x)
#define CRITICAL_REGION_END()
#define CRITICAL_REGION_BEGIN(x)