Remove background mining

This was a useless feature to begin with.  According to a Monero
insider, this was introduced at the time with an intention of making it
on-by-default on every monerod instance everywhere, but because that was
such an overwhelmingly stupid idea, it never happened yet all this code
(which is probably used by no one anywhere ever) remains in the code
base.

Even if the idea wasn't dumb to start with, this will also become even
more pointless with pulse, so just drop it (it is over 1000 lines of
code, not even counting the extra headers pulled in to do things like
querying CPU usage and battery status).
This commit is contained in:
Jason Rhinelander 2020-03-20 15:34:43 -03:00
parent b69316ec38
commit 5fd8939c6a
21 changed files with 25 additions and 1022 deletions

View File

@ -43,33 +43,6 @@
#include "string_coding.h"
#include "string_tools.h"
#include "storages/portable_storage_template_helper.h"
#include "boost/logic/tribool.hpp"
#ifdef __APPLE__
#include <sys/times.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/ps/IOPSKeys.h>
#include <IOKit/ps/IOPowerSources.h>
#include <mach/mach_host.h>
#include <AvailabilityMacros.h>
#include <TargetConditionals.h>
#elif defined(__linux__)
#include <unistd.h>
#include <sys/resource.h>
#include <sys/times.h>
#include <time.h>
#elif defined(__FreeBSD__)
#include <devstat.h>
#include <errno.h>
#include <fcntl.h>
#include <machine/apm_bios.h>
#include <stdio.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <sys/times.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#undef LOKI_DEFAULT_LOG_CATEGORY
#define LOKI_DEFAULT_LOG_CATEGORY "miner"
@ -92,11 +65,6 @@ namespace cryptonote
const command_line::arg_descriptor<std::string> arg_extra_messages = {"extra-messages-file", "Specify file for extra messages to include into coinbase transactions", "", true};
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<uint16_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<uint16_t> arg_bg_mining_miner_target_percentage = {"bg-mining-miner-target", "Specify maximum percentage cpu use by miner(s)", miner::BACKGROUND_MINING_DEFAULT_MINING_TARGET_PERCENTAGE, true};
}
@ -117,13 +85,7 @@ namespace cryptonote
m_total_hashes(0),
m_do_print_hashrate(false),
m_do_mining(false),
m_current_hash_rate(0),
m_is_background_mining_enabled(false),
m_min_idle_seconds(BACKGROUND_MINING_DEFAULT_MIN_IDLE_INTERVAL_IN_SECONDS),
m_idle_threshold(BACKGROUND_MINING_DEFAULT_IDLE_THRESHOLD_PERCENTAGE),
m_mining_target(BACKGROUND_MINING_DEFAULT_MINING_TARGET_PERCENTAGE),
m_miner_extra_sleep(BACKGROUND_MINING_DEFAULT_MINER_EXTRA_SLEEP_MILLIS),
m_block_reward(0)
m_current_hash_rate(0)
{
m_attrs.set_stack_size(THREAD_STACK_SIZE);
}
@ -134,13 +96,12 @@ namespace cryptonote
catch (...) { /* ignore */ }
}
//-----------------------------------------------------------------------------------------------------
bool miner::set_block_template(const block& bl, const difficulty_type& di, uint64_t height, uint64_t block_reward)
bool miner::set_block_template(const block& bl, const difficulty_type& di, uint64_t height)
{
CRITICAL_REGION_LOCAL(m_template_lock);
m_template = bl;
m_diffic = di;
m_height = height;
m_block_reward = block_reward;
++m_template_no;
m_starter_nonce = crypto::rand<uint32_t>();
return true;
@ -172,7 +133,7 @@ namespace cryptonote
LOG_ERROR("Failed to get_block_template(), stopping mining");
return false;
}
set_block_template(bl, di, height, expected_reward);
set_block_template(bl, di, height);
return true;
}
//-----------------------------------------------------------------------------------------------------
@ -282,11 +243,6 @@ namespace cryptonote
command_line::add_arg(desc, arg_extra_messages);
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);
}
//-----------------------------------------------------------------------------------------------------
bool miner::init(const boost::program_options::variables_map& vm, network_type nettype)
@ -332,19 +288,6 @@ namespace cryptonote
}
}
// Background mining parameters
// 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))
set_idle_threshold( command_line::get_arg(vm, arg_bg_mining_idle_threshold_percentage) );
if(command_line::has_arg(vm, arg_bg_mining_miner_target_percentage))
set_mining_target( command_line::get_arg(vm, arg_bg_mining_miner_target_percentage) );
return true;
}
//-----------------------------------------------------------------------------------------------------
@ -362,9 +305,8 @@ namespace cryptonote
return m_threads_total;
}
//-----------------------------------------------------------------------------------------------------
bool miner::start(const account_public_address& adr, size_t threads_count, bool do_background, bool ignore_battery, uint64_t stop_after, bool slow_mining)
bool miner::start(const account_public_address& adr, size_t threads_count, uint64_t stop_after, bool slow_mining)
{
m_block_reward = 0;
m_mine_address = adr;
m_threads_total = static_cast<uint32_t>(threads_count);
if (threads_count == 0)
@ -394,8 +336,6 @@ namespace cryptonote
m_stop_height = stop_after ? m_height + stop_after : std::numeric_limits<uint64_t>::max();
if (stop_after)
MGINFO("Mining until height " << m_stop_height);
set_is_background_mining_enabled(do_background);
set_ignore_battery(ignore_battery);
for(size_t i = 0; i != m_threads_total; i++)
{
@ -407,17 +347,6 @@ namespace cryptonote
else
MINFO("Mining has started with " << threads_count << " threads, good luck!" );
if( get_is_background_mining_enabled() )
{
m_background_mining_thread = boost::thread(m_attrs, boost::bind(&miner::background_worker_thread, this));
LOG_PRINT_L0("Background mining controller thread started" );
}
if(get_ignore_battery())
{
MINFO("Ignoring battery");
}
return true;
}
//-----------------------------------------------------------------------------------------------------
@ -451,20 +380,6 @@ namespace cryptonote
send_stop_signal();
// In case background mining was active and the miner threads are waiting
// on the background miner to signal start.
while (m_threads_active > 0)
{
m_is_background_mining_started_cond.notify_all();
misc_utils::sleep_no_w(100);
}
// The background mining thread could be sleeping for a long time, so we
// interrupt it just in case
m_background_mining_thread.interrupt();
m_background_mining_thread.join();
m_is_background_mining_enabled = false;
MINFO("Mining has been stopped, " << m_threads.size() << " finished" );
m_threads.clear();
m_threads_autodetect.clear();
@ -493,7 +408,7 @@ namespace cryptonote
{
if(m_do_mining)
{
start(m_mine_address, m_threads_total, get_is_background_mining_enabled(), get_ignore_battery());
start(m_mine_address, m_threads_total);
}
}
//-----------------------------------------------------------------------------------------------------
@ -544,19 +459,6 @@ namespace cryptonote
misc_utils::sleep_no_w(100);
continue;
}
else if( m_is_background_mining_enabled )
{
misc_utils::sleep_no_w(m_miner_extra_sleep);
while( !m_is_background_mining_started )
{
MGINFO("background mining is enabled, but not started, waiting until start triggers");
boost::unique_lock<boost::mutex> started_lock( m_is_background_mining_started_mutex );
m_is_background_mining_started_cond.wait( started_lock );
if( m_stop ) break;
}
if( m_stop ) continue;
}
if(local_template_ver != m_template_no)
{
@ -623,540 +525,4 @@ namespace cryptonote
stop();
return true;
}
//-----------------------------------------------------------------------------------------------------
bool miner::get_is_background_mining_enabled() const
{
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
*/
bool miner::set_is_background_mining_enabled(bool is_background_mining_enabled)
{
m_is_background_mining_enabled = is_background_mining_enabled;
// Extra logic will be required if we make this function public in the future
// and allow toggling smart mining without start/stop
//m_is_background_mining_enabled_cond.notify_one();
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;
}
//-----------------------------------------------------------------------------------------------------
bool miner::set_min_idle_seconds(uint64_t min_idle_seconds)
{
if(min_idle_seconds > BACKGROUND_MINING_MAX_MIN_IDLE_INTERVAL_IN_SECONDS) return false;
if(min_idle_seconds < BACKGROUND_MINING_MIN_MIN_IDLE_INTERVAL_IN_SECONDS) return false;
m_min_idle_seconds = min_idle_seconds;
return true;
}
//-----------------------------------------------------------------------------------------------------
uint8_t miner::get_idle_threshold() const
{
return m_idle_threshold;
}
//-----------------------------------------------------------------------------------------------------
bool miner::set_idle_threshold(uint8_t idle_threshold)
{
if(idle_threshold > BACKGROUND_MINING_MAX_IDLE_THRESHOLD_PERCENTAGE) return false;
if(idle_threshold < BACKGROUND_MINING_MIN_IDLE_THRESHOLD_PERCENTAGE) return false;
m_idle_threshold = idle_threshold;
return true;
}
//-----------------------------------------------------------------------------------------------------
uint8_t miner::get_mining_target() const
{
return m_mining_target;
}
//-----------------------------------------------------------------------------------------------------
bool miner::set_mining_target(uint8_t mining_target)
{
if(mining_target > BACKGROUND_MINING_MAX_MINING_TARGET_PERCENTAGE) return false;
if(mining_target < BACKGROUND_MINING_MIN_MINING_TARGET_PERCENTAGE) return false;
m_mining_target = mining_target;
return true;
}
//-----------------------------------------------------------------------------------------------------
bool miner::background_worker_thread()
{
uint64_t prev_total_time, current_total_time;
uint64_t prev_idle_time, current_idle_time;
uint64_t previous_process_time = 0, current_process_time = 0;
m_is_background_mining_started = false;
if(!get_system_times(prev_total_time, prev_idle_time))
{
LOG_ERROR("get_system_times call failed, background mining will NOT work!");
return false;
}
while(!m_stop)
{
try
{
// Commenting out the below since we're going with privatizing the bg mining enabled
// function, but I'll leave the code/comments here for anyone that wants to modify the
// patch in the future
// -------------------------------------------------------------------------------------
// All of this might be overkill if we just enforced some simple requirements
// about changing this variable before/after the miner starts, but I envision
// in the future a checkbox that you can tick on/off for background mining after
// you've clicked "start mining". There's still an issue here where if background
// mining is disabled when start is called, this thread is never created, and so
// enabling after does nothing, something I have to fix in the future. However,
// this should take care of the case where mining is started with bg-enabled,
// and then the user decides to un-check background mining, and just do
// regular full-speed mining. I might just be over-doing it and thinking up
// non-existant use-cases, so if the consensus is to simplify, we can remove all this fluff.
/*
while( !m_is_background_mining_enabled )
{
MGINFO("background mining is disabled, waiting until enabled!");
boost::unique_lock<boost::mutex> enabled_lock( m_is_background_mining_enabled_mutex );
m_is_background_mining_enabled_cond.wait( enabled_lock );
}
*/
// If we're already mining, then sleep for the miner monitor interval.
// If we're NOT mining, then sleep for the idle monitor interval
uint64_t sleep_for_seconds = BACKGROUND_MINING_MINER_MONITOR_INVERVAL_IN_SECONDS;
if( !m_is_background_mining_started ) sleep_for_seconds = get_min_idle_seconds();
boost::this_thread::sleep_for(boost::chrono::seconds(sleep_for_seconds));
}
catch(const boost::thread_interrupted&)
{
MDEBUG("background miner thread interrupted ");
continue; // if interrupted because stop called, loop should end ..
}
bool on_ac_power = m_ignore_battery;
if(!m_ignore_battery)
{
boost::tribool battery_powered(on_battery_power());
if(!indeterminate( battery_powered ))
{
on_ac_power = !(bool)battery_powered;
}
}
if( m_is_background_mining_started )
{
// figure out if we need to stop, and monitor mining usage
// If we get here, then previous values are initialized.
// Let's get some current data for comparison.
if(!get_system_times(current_total_time, current_idle_time))
{
MERROR("get_system_times call failed");
continue;
}
if(!get_process_time(current_process_time))
{
MERROR("get_process_time call failed!");
continue;
}
uint64_t total_diff = (current_total_time - prev_total_time);
uint64_t idle_diff = (current_idle_time - prev_idle_time);
uint64_t process_diff = (current_process_time - previous_process_time);
uint8_t idle_percentage = get_percent_of_total(idle_diff, total_diff);
uint8_t process_percentage = get_percent_of_total(process_diff, total_diff);
MDEBUG("idle percentage is " << unsigned(idle_percentage) << "\%, miner percentage is " << unsigned(process_percentage) << "\%, ac power : " << on_ac_power);
if( idle_percentage + process_percentage < get_idle_threshold() || !on_ac_power )
{
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!");
m_is_background_mining_started = false;
// reset process times
previous_process_time = 0;
current_process_time = 0;
}
else
{
previous_process_time = current_process_time;
// adjust the miner extra sleep variable
int64_t miner_extra_sleep_change = (-1 * (get_mining_target() - process_percentage) );
int64_t new_miner_extra_sleep = m_miner_extra_sleep + miner_extra_sleep_change;
// if you start the miner with few threads on a multicore system, this could
// fall below zero because all the time functions aggregate across all processors.
// I'm just hard limiting to 5 millis min sleep here, other options?
m_miner_extra_sleep = std::max( new_miner_extra_sleep , (int64_t)5 );
MDEBUG("m_miner_extra_sleep " << m_miner_extra_sleep);
}
prev_total_time = current_total_time;
prev_idle_time = current_idle_time;
}
else if( on_ac_power )
{
// figure out if we need to start
if(!get_system_times(current_total_time, current_idle_time))
{
MERROR("get_system_times call failed");
continue;
}
uint64_t total_diff = (current_total_time - prev_total_time);
uint64_t idle_diff = (current_idle_time - prev_idle_time);
uint8_t idle_percentage = get_percent_of_total(idle_diff, total_diff);
MDEBUG("idle percentage is " << unsigned(idle_percentage));
if( idle_percentage >= get_idle_threshold() && on_ac_power )
{
MINFO("cpu is " << unsigned(idle_percentage) << "% idle, idle threshold is " << unsigned(get_idle_threshold()) << "\%, ac power : " << on_ac_power << ", background mining started, good luck!");
m_is_background_mining_started = true;
m_is_background_mining_started_cond.notify_all();
// Wait for a little mining to happen ..
boost::this_thread::sleep_for(boost::chrono::seconds( 1 ));
// Starting data ...
if(!get_process_time(previous_process_time))
{
m_is_background_mining_started = false;
MERROR("get_process_time call failed!");
}
}
prev_total_time = current_total_time;
prev_idle_time = current_idle_time;
}
}
return true;
}
//-----------------------------------------------------------------------------------------------------
bool miner::get_system_times(uint64_t& total_time, uint64_t& idle_time)
{
#ifdef _WIN32
FILETIME idleTime;
FILETIME kernelTime;
FILETIME userTime;
if ( GetSystemTimes( &idleTime, &kernelTime, &userTime ) != -1 )
{
total_time =
( (((uint64_t)(kernelTime.dwHighDateTime)) << 32) | ((uint64_t)kernelTime.dwLowDateTime) )
+ ( (((uint64_t)(userTime.dwHighDateTime)) << 32) | ((uint64_t)userTime.dwLowDateTime) );
idle_time = ( (((uint64_t)(idleTime.dwHighDateTime)) << 32) | ((uint64_t)idleTime.dwLowDateTime) );
return true;
}
#elif defined(__linux__)
const std::string STAT_FILE_PATH = "/proc/stat";
if( !epee::file_io_utils::is_file_exist(STAT_FILE_PATH) )
{
LOG_ERROR("'" << STAT_FILE_PATH << "' file does not exist");
return false;
}
std::ifstream stat_file_stream(STAT_FILE_PATH);
if( stat_file_stream.fail() )
{
LOG_ERROR("failed to open '" << STAT_FILE_PATH << "'");
return false;
}
std::string line;
std::getline(stat_file_stream, line);
std::istringstream stat_file_iss(line);
stat_file_iss.ignore(65536, ' '); // skip cpu label ...
uint64_t utime, ntime, stime, itime;
if( !(stat_file_iss >> utime && stat_file_iss >> ntime && stat_file_iss >> stime && stat_file_iss >> itime) )
{
LOG_ERROR("failed to read '" << STAT_FILE_PATH << "'");
return false;
}
idle_time = itime;
total_time = utime + ntime + stime + itime;
return true;
#elif defined(__APPLE__)
mach_msg_type_number_t count;
kern_return_t status;
host_cpu_load_info_data_t stats;
count = HOST_CPU_LOAD_INFO_COUNT;
status = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&stats, &count);
if(status != KERN_SUCCESS)
{
return false;
}
idle_time = stats.cpu_ticks[CPU_STATE_IDLE];
total_time = idle_time + stats.cpu_ticks[CPU_STATE_USER] + stats.cpu_ticks[CPU_STATE_SYSTEM];
return true;
#elif defined(__FreeBSD__)
struct statinfo s;
size_t n = sizeof(s.cp_time);
if( sysctlbyname("kern.cp_time", s.cp_time, &n, NULL, 0) == -1 )
{
LOG_ERROR("sysctlbyname(\"kern.cp_time\"): " << strerror(errno));
return false;
}
if( n != sizeof(s.cp_time) )
{
LOG_ERROR("sysctlbyname(\"kern.cp_time\") output is unexpectedly "
<< n << " bytes instead of the expected " << sizeof(s.cp_time)
<< " bytes.");
return false;
}
idle_time = s.cp_time[CP_IDLE];
total_time =
s.cp_time[CP_USER] +
s.cp_time[CP_NICE] +
s.cp_time[CP_SYS] +
s.cp_time[CP_INTR] +
s.cp_time[CP_IDLE];
return true;
#endif
return false; // unsupported system
}
//-----------------------------------------------------------------------------------------------------
bool miner::get_process_time(uint64_t& total_time)
{
#ifdef _WIN32
FILETIME createTime;
FILETIME exitTime;
FILETIME kernelTime;
FILETIME userTime;
if ( GetProcessTimes( GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime ) != -1 )
{
total_time =
( (((uint64_t)(kernelTime.dwHighDateTime)) << 32) | ((uint64_t)kernelTime.dwLowDateTime) )
+ ( (((uint64_t)(userTime.dwHighDateTime)) << 32) | ((uint64_t)userTime.dwLowDateTime) );
return true;
}
#elif (defined(__linux__) && defined(_SC_CLK_TCK)) || defined(__APPLE__) || defined(__FreeBSD__)
struct tms tms;
if ( times(&tms) != (clock_t)-1 )
{
total_time = tms.tms_utime + tms.tms_stime;
return true;
}
#endif
return false; // unsupported system
}
//-----------------------------------------------------------------------------------------------------
uint8_t miner::get_percent_of_total(uint64_t other, uint64_t total)
{
return (uint8_t)( ceil( (other * 1.f / total * 1.f) * 100) );
}
//-----------------------------------------------------------------------------------------------------
boost::logic::tribool miner::on_battery_power()
{
#ifdef _WIN32
SYSTEM_POWER_STATUS power_status;
if ( GetSystemPowerStatus( &power_status ) != 0 )
{
return boost::logic::tribool(power_status.ACLineStatus != 1);
}
#elif defined(__APPLE__)
#if TARGET_OS_MAC && (!defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7)
return boost::logic::tribool(IOPSGetTimeRemainingEstimate() != kIOPSTimeRemainingUnlimited);
#else
// iOS or OSX <10.7
return boost::logic::tribool(boost::logic::indeterminate);
#endif
#elif defined(__linux__)
// Use the power_supply class http://lxr.linux.no/#linux+v4.10.1/Documentation/power/power_supply_class.txt
std::string power_supply_class_path = "/sys/class/power_supply";
boost::tribool on_battery = boost::logic::tribool(boost::logic::indeterminate);
if (boost::filesystem::is_directory(power_supply_class_path))
{
const boost::filesystem::directory_iterator end_itr;
for (boost::filesystem::directory_iterator iter(power_supply_class_path); iter != end_itr; ++iter)
{
const boost::filesystem::path& power_supply_path = iter->path();
if (boost::filesystem::is_directory(power_supply_path))
{
boost::filesystem::path power_supply_type_path = power_supply_path / "type";
if (boost::filesystem::is_regular_file(power_supply_type_path))
{
std::ifstream power_supply_type_stream(power_supply_type_path.string());
if (power_supply_type_stream.fail())
{
LOG_PRINT_L0("Unable to read from " << power_supply_type_path << " to check power supply type");
continue;
}
std::string power_supply_type;
std::getline(power_supply_type_stream, power_supply_type);
// If there is an AC adapter that's present and online we can break early
if (boost::starts_with(power_supply_type, "Mains"))
{
boost::filesystem::path power_supply_online_path = power_supply_path / "online";
if (boost::filesystem::is_regular_file(power_supply_online_path))
{
std::ifstream power_supply_online_stream(power_supply_online_path.string());
if (power_supply_online_stream.fail())
{
LOG_PRINT_L0("Unable to read from " << power_supply_online_path << " to check ac power supply status");
continue;
}
if (power_supply_online_stream.get() == '1')
{
return boost::logic::tribool(false);
}
}
}
else if (boost::starts_with(power_supply_type, "Battery") && boost::logic::indeterminate(on_battery))
{
boost::filesystem::path power_supply_status_path = power_supply_path / "status";
if (boost::filesystem::is_regular_file(power_supply_status_path))
{
std::ifstream power_supply_status_stream(power_supply_status_path.string());
if (power_supply_status_stream.fail())
{
LOG_PRINT_L0("Unable to read from " << power_supply_status_path << " to check battery power supply status");
continue;
}
// Possible status are Charging, Full, Discharging, Not Charging, and Unknown
// We are only need to handle negative states right now
std::string power_supply_status;
std::getline(power_supply_status_stream, power_supply_status);
if (boost::starts_with(power_supply_status, "Charging") || boost::starts_with(power_supply_status, "Full"))
{
on_battery = boost::logic::tribool(false);
}
if (boost::starts_with(power_supply_status, "Discharging"))
{
on_battery = boost::logic::tribool(true);
}
}
}
}
}
}
}
if (boost::logic::indeterminate(on_battery))
{
static bool error_shown = false;
if (!error_shown)
{
LOG_ERROR("couldn't query power status from " << power_supply_class_path);
error_shown = true;
}
}
return on_battery;
#elif defined(__FreeBSD__)
int ac;
size_t n = sizeof(ac);
if( sysctlbyname("hw.acpi.acline", &ac, &n, NULL, 0) == -1 )
{
if( errno != ENOENT )
{
LOG_ERROR("Cannot query battery status: "
<< "sysctlbyname(\"hw.acpi.acline\"): " << strerror(errno));
return boost::logic::tribool(boost::logic::indeterminate);
}
// If sysctl fails with ENOENT, then try querying /dev/apm.
static const char* dev_apm = "/dev/apm";
const int fd = open(dev_apm, O_RDONLY);
if( fd == -1 ) {
LOG_ERROR("Cannot query battery status: "
<< "open(): " << dev_apm << ": " << strerror(errno));
return boost::logic::tribool(boost::logic::indeterminate);
}
apm_info info;
if( ioctl(fd, APMIO_GETINFO, &info) == -1 ) {
close(fd);
LOG_ERROR("Cannot query battery status: "
<< "ioctl(" << dev_apm << ", APMIO_GETINFO): " << strerror(errno));
return boost::logic::tribool(boost::logic::indeterminate);
}
close(fd);
// See apm(8).
switch( info.ai_acline )
{
case 0: // off-line
case 2: // backup power
return boost::logic::tribool(true);
case 1: // on-line
return boost::logic::tribool(false);
}
switch( info.ai_batt_stat )
{
case 0: // high
case 1: // low
case 2: // critical
return boost::logic::tribool(true);
case 3: // charging
return boost::logic::tribool(false);
}
LOG_ERROR("Cannot query battery status: "
<< "sysctl hw.acpi.acline is not available and /dev/apm returns "
<< "unexpected ac-line status (" << info.ai_acline << ") and "
<< "battery status (" << info.ai_batt_stat << ").");
return boost::logic::tribool(boost::logic::indeterminate);
}
if( n != sizeof(ac) )
{
LOG_ERROR("sysctlbyname(\"hw.acpi.acline\") output is unexpectedly "
<< n << " bytes instead of the expected " << sizeof(ac) << " bytes.");
return boost::logic::tribool(boost::logic::indeterminate);
}
return boost::logic::tribool(ac == 0);
#endif
LOG_ERROR("couldn't query power status");
return boost::logic::tribool(boost::logic::indeterminate);
}
}

View File

@ -66,9 +66,9 @@ namespace cryptonote
~miner();
bool init(const boost::program_options::variables_map& vm, network_type nettype);
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);
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, bool do_background, bool ignore_battery, uint64_t stop_after = 0, bool slow_mining = false);
bool start(const account_public_address& adr, size_t threads_count, uint64_t stop_after = 0, bool slow_mining = false);
uint64_t get_speed() const;
uint32_t get_threads_count() const;
void send_stop_signal();
@ -82,41 +82,19 @@ namespace cryptonote
void pause();
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;
bool set_idle_threshold(uint8_t idle_threshold);
uint8_t get_mining_target() const;
bool set_mining_target(uint8_t mining_target);
uint64_t get_block_reward() const { return m_block_reward; }
#if defined(LOKI_ENABLE_INTEGRATION_TEST_HOOKS)
std::atomic<bool> m_debug_mine_singular_block;
bool debug_mine_singular_block(const account_public_address& adr)
{
m_debug_mine_singular_block = true;
bool result = start(adr, 1 /*thread_counts*/, false /*do_background*/, false /*ignore_battery*/);
bool result = start(adr, 1 /*thread_counts*/);
while(is_mining()) { }
return result;
}
#endif
static constexpr uint8_t BACKGROUND_MINING_DEFAULT_IDLE_THRESHOLD_PERCENTAGE = 90;
static constexpr uint8_t BACKGROUND_MINING_MIN_IDLE_THRESHOLD_PERCENTAGE = 50;
static constexpr uint8_t BACKGROUND_MINING_MAX_IDLE_THRESHOLD_PERCENTAGE = 99;
static constexpr uint16_t BACKGROUND_MINING_DEFAULT_MIN_IDLE_INTERVAL_IN_SECONDS = 10;
static constexpr uint16_t BACKGROUND_MINING_MIN_MIN_IDLE_INTERVAL_IN_SECONDS = 10;
static constexpr uint16_t BACKGROUND_MINING_MAX_MIN_IDLE_INTERVAL_IN_SECONDS = 3600;
static constexpr uint8_t BACKGROUND_MINING_DEFAULT_MINING_TARGET_PERCENTAGE = 40;
static constexpr uint8_t BACKGROUND_MINING_MIN_MINING_TARGET_PERCENTAGE = 5;
static constexpr uint8_t BACKGROUND_MINING_MAX_MINING_TARGET_PERCENTAGE = 50;
static constexpr uint8_t BACKGROUND_MINING_MINER_MONITOR_INVERVAL_IN_SECONDS = 10;
static constexpr uint64_t BACKGROUND_MINING_DEFAULT_MINER_EXTRA_SLEEP_MILLIS = 400; // ramp up
static constexpr uint64_t BACKGROUND_MINING_MIN_MINER_EXTRA_SLEEP_MILLIS = 5;
private:
bool worker_thread(bool slow_mining = false);
bool request_block_template();
@ -168,28 +146,5 @@ namespace cryptonote
bool m_do_mining;
std::vector<std::pair<uint64_t, uint64_t>> m_threads_autodetect;
boost::thread::attributes m_attrs;
// 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;
boost::mutex m_is_background_mining_started_mutex;
boost::condition_variable m_is_background_mining_started_cond;
boost::thread m_background_mining_thread;
uint64_t m_min_idle_seconds;
uint8_t m_idle_threshold;
uint8_t m_mining_target;
std::atomic<uint64_t> m_miner_extra_sleep;
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 boost::logic::tribool on_battery_power();
std::atomic<uint64_t> m_block_reward;
};
}

View File

@ -510,37 +510,11 @@ bool t_command_parser_executor::start_mining(const std::vector<std::string>& arg
if(nettype != cryptonote::MAINNET)
std::cout << "Mining to a " << (nettype == cryptonote::TESTNET ? "testnet" : "stagenet") << " address, make sure this is intentional!" << std::endl;
uint64_t threads_count = 1;
bool do_background_mining = false;
bool ignore_battery = false;
if(args.size() > 4)
if(args.size() > 2)
{
return false;
}
if(args.size() == 4)
{
if(args[3] == "true" || command_line::is_yes(args[3]) || args[3] == "1")
{
ignore_battery = true;
}
else if(args[3] != "false" && !command_line::is_no(args[3]) && args[3] != "0")
{
return false;
}
}
if(args.size() >= 3)
{
if(args[2] == "true" || command_line::is_yes(args[2]) || args[2] == "1")
{
do_background_mining = true;
}
else if(args[2] != "false" && !command_line::is_no(args[2]) && args[2] != "0")
{
return false;
}
}
if(args.size() >= 2)
{
if (args[1] == "auto" || args[1] == "autodetect")
@ -554,7 +528,7 @@ bool t_command_parser_executor::start_mining(const std::vector<std::string>& arg
}
}
m_executor.start_mining(info.address, threads_count, nettype, do_background_mining, ignore_battery);
m_executor.start_mining(info.address, threads_count, nettype);
return true;
}

View File

@ -149,8 +149,8 @@ t_command_server::t_command_server(
m_command_lookup.set_handler(
"start_mining"
, std::bind(&t_command_parser_executor::start_mining, &m_parser, p::_1)
, "start_mining <addr> [<threads>|auto] [do_background_mining] [ignore_battery]"
, "Start mining for specified address. Defaults to 1 thread and no background mining. Use \"auto\" to autodetect optimal number of threads."
, "start_mining <addr> [<threads>|auto]"
, "Start mining for specified address. Defaults to 1 thread; use \"auto\" to autodetect optimal number of threads."
);
m_command_lookup.set_handler(
"stop_mining"

View File

@ -720,7 +720,7 @@ bool t_rpc_command_executor::show_status() {
% get_sync_percentage(ires)
% (ires.testnet ? " ON TESTNET" : ires.stagenet ? " ON STAGENET" : ""/*mainnet*/)
% bootstrap_msg
% (!has_mining_info ? ", mining info unavailable" : mining_busy ? ", syncing" : mres.active ? ( ( mres.is_background_mining_enabled ? ", smart " : ", " ) + std::string("mining at ") + get_mining_speed(mres.speed)) : ""/*not mining*/)
% (!has_mining_info ? ", mining info unavailable" : mining_busy ? ", syncing" : mres.active ? ( ", mining at " + get_mining_speed(mres.speed)) : ""/*not mining*/)
% get_mining_speed(ires.difficulty / ires.target)
% (ires.version.empty() ? "?.?.?" : ires.version)
% (unsigned)hfres.version
@ -819,29 +819,16 @@ bool t_rpc_command_executor::mining_status() {
tools::msg_writer() << "Mining at " << get_mining_speed(mres.speed) << " with " << mres.threads_count << " threads";
}
if (mres.active || mres.is_background_mining_enabled)
if (mres.active)
{
tools::msg_writer() << "PoW algorithm: " << mres.pow_algorithm;
tools::msg_writer() << "Mining address: " << mres.address;
}
if (mres.is_background_mining_enabled)
{
tools::msg_writer() << "Smart mining enabled:";
tools::msg_writer() << " Target: " << (unsigned)mres.bg_target << "% CPU";
tools::msg_writer() << " Idle threshold: " << (unsigned)mres.bg_idle_threshold << "% CPU";
tools::msg_writer() << " Min idle time: " << (unsigned)mres.bg_min_idle_seconds << " seconds";
tools::msg_writer() << " Ignore battery: " << (mres.bg_ignore_battery ? "yes" : "no");
}
if (!mining_busy && mres.active && mres.speed > 0 && mres.block_target > 0 && mres.difficulty > 0)
{
double ratio = mres.speed * mres.block_target / (double)mres.difficulty;
uint64_t daily = 86400ull / mres.block_target * mres.block_reward * ratio;
uint64_t monthly = 86400ull / mres.block_target * 30.5 * mres.block_reward * ratio;
uint64_t yearly = 86400ull / mres.block_target * 356 * mres.block_reward * ratio;
tools::msg_writer() << "Expected: " << cryptonote::print_money(daily) << " LOKI daily, "
<< cryptonote::print_money(monthly) << " monthly, " << cryptonote::print_money(yearly) << " yearly";
uint64_t daily = 86400 / (double)mres.difficulty * mres.speed * mres.block_reward;
tools::msg_writer() << "Expected: " << cryptonote::print_money(daily) << " LOKI daily, " << cryptonote::print_money(7*daily) << " weekly";
}
return true;
@ -1549,13 +1536,11 @@ bool t_rpc_command_executor::print_transaction_pool_stats() {
return true;
}
bool t_rpc_command_executor::start_mining(cryptonote::account_public_address address, uint64_t num_threads, cryptonote::network_type nettype, bool do_background_mining, bool ignore_battery) {
bool t_rpc_command_executor::start_mining(cryptonote::account_public_address address, uint64_t num_threads, cryptonote::network_type nettype) {
cryptonote::COMMAND_RPC_START_MINING::request req;
cryptonote::COMMAND_RPC_START_MINING::response res;
req.miner_address = cryptonote::get_account_address_as_str(nettype, false, address);
req.threads_count = num_threads;
req.do_background_mining = do_background_mining;
req.ignore_battery = ignore_battery;
std::string fail_message = "Mining did not start";

View File

@ -114,7 +114,7 @@ public:
bool print_transaction_pool_stats();
bool start_mining(cryptonote::account_public_address address, uint64_t num_threads, cryptonote::network_type nettype, bool do_background_mining = false, bool ignore_battery = false);
bool start_mining(cryptonote::account_public_address address, uint64_t num_threads, cryptonote::network_type nettype);
bool stop_mining();

View File

@ -963,7 +963,7 @@ namespace cryptonote
res.status = "Already mining";
return true;
}
if(!miner.start(info.address, static_cast<size_t>(req.threads_count), req.do_background_mining, req.ignore_battery, req.num_blocks, req.slow_mining))
if(!miner.start(info.address, static_cast<size_t>(req.threads_count)))
{
res.status = "Failed, mining not started";
LOG_PRINT_L0(res.status);
@ -999,7 +999,6 @@ namespace cryptonote
const miner& lMiner = m_core.get_miner();
res.active = lMiner.is_mining();
res.is_background_mining_enabled = lMiner.get_is_background_mining_enabled();
res.block_target = DIFFICULTY_TARGET_V2;
res.difficulty = m_core.get_blockchain_storage().get_difficulty_for_next_block();
if ( lMiner.is_mining() ) {
@ -1016,14 +1015,6 @@ namespace cryptonote
major_version == network_version_11_infinite_staking ? "Cryptonight Turtle Light (Variant 2)" :
"Cryptonight Heavy (Variant 2)";
if (res.is_background_mining_enabled)
{
res.bg_idle_threshold = lMiner.get_idle_threshold();
res.bg_min_idle_seconds = lMiner.get_min_idle_seconds();
res.bg_ignore_battery = lMiner.get_ignore_battery();
res.bg_target = lMiner.get_mining_target();
}
res.status = CORE_RPC_STATUS_OK;
return true;
}

View File

@ -749,16 +749,12 @@ constexpr char const CORE_RPC_STATUS_TX_LONG_POLL_MAX_CONNECTIONS[] = "Daemon ma
{
std::string miner_address; // Account address to mine to.
uint64_t threads_count; // Number of mining thread to run.
bool do_background_mining; // States if the mining should run in background (`true`) or foreground (`false`).
bool ignore_battery; // States if battery state (on laptop) should be ignored (`true`) or not (`false`).
uint64_t num_blocks; // Mine until the blockchain has this many new blocks, then stop (no limit if 0, the default)
bool slow_mining; // Do slow mining (i.e. don't allocate RandomX cache); primarily intended for testing
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(miner_address)
KV_SERIALIZE(threads_count)
KV_SERIALIZE(do_background_mining)
KV_SERIALIZE(ignore_battery)
KV_SERIALIZE_OPT(num_blocks, uint64_t{0})
KV_SERIALIZE_OPT(slow_mining, false)
END_KV_SERIALIZE_MAP()
@ -946,11 +942,6 @@ constexpr char const CORE_RPC_STATUS_TX_LONG_POLL_MAX_CONNECTIONS[] = "Daemon ma
uint32_t threads_count; // Number of running mining threads.
std::string address; // Account address daemon is mining to. Empty if not mining.
std::string pow_algorithm; // Current hashing algorithm name
bool is_background_mining_enabled; // States if the mining is running in background (`true`) or foreground (`false`).
uint8_t bg_idle_threshold; // Background mining, the minimum amount of time in average the CPU should idle in percentage.
uint8_t bg_min_idle_seconds; // Background mining, how long the minimum amount of time is for the idle threshold.
bool bg_ignore_battery; // Background mining, if true mining does not adjust power depending on battery percentage remaining.
uint8_t bg_target; // Background mining, how much percentage of CPU(?) to consume, default 40%.
uint32_t block_target; // The expected time to solve per block, i.e. DIFFICULTY_TARGET_V2
uint64_t block_reward; // Block reward for the current block being mined.
uint64_t difficulty; // The difficulty for the current block being mined.
@ -962,11 +953,6 @@ constexpr char const CORE_RPC_STATUS_TX_LONG_POLL_MAX_CONNECTIONS[] = "Daemon ma
KV_SERIALIZE(threads_count)
KV_SERIALIZE(address)
KV_SERIALIZE(pow_algorithm)
KV_SERIALIZE(is_background_mining_enabled)
KV_SERIALIZE(bg_idle_threshold)
KV_SERIALIZE(bg_min_idle_seconds)
KV_SERIALIZE(bg_ignore_battery)
KV_SERIALIZE(bg_target)
KV_SERIALIZE(block_target)
KV_SERIALIZE(block_reward)
KV_SERIALIZE(difficulty)

View File

@ -428,7 +428,7 @@ namespace rpc
return;
}
if(!m_core.get_miner().start(info.address, static_cast<size_t>(req.threads_count), req.do_background_mining, req.ignore_battery))
if(!m_core.get_miner().start(info.address, static_cast<size_t>(req.threads_count)))
{
res.error_details = "Failed, mining not started";
LOG_PRINT_L0(res.error_details);
@ -502,7 +502,6 @@ namespace rpc
{
const cryptonote::miner& lMiner = m_core.get_miner();
res.active = lMiner.is_mining();
res.is_background_mining_enabled = lMiner.get_is_background_mining_enabled();
if ( lMiner.is_mining() ) {
res.speed = lMiner.get_speed();

View File

@ -315,8 +315,6 @@ rapidjson::Value StartMining::Request::toJson(rapidjson::Document& doc) const
INSERT_INTO_JSON_OBJECT(val, doc, miner_address, miner_address);
INSERT_INTO_JSON_OBJECT(val, doc, threads_count, threads_count);
INSERT_INTO_JSON_OBJECT(val, doc, do_background_mining, do_background_mining);
INSERT_INTO_JSON_OBJECT(val, doc, ignore_battery, ignore_battery);
return val;
}
@ -325,8 +323,6 @@ void StartMining::Request::fromJson(rapidjson::Value& val)
{
GET_FROM_JSON_OBJECT(val, miner_address, miner_address);
GET_FROM_JSON_OBJECT(val, threads_count, threads_count);
GET_FROM_JSON_OBJECT(val, do_background_mining, do_background_mining);
GET_FROM_JSON_OBJECT(val, ignore_battery, ignore_battery);
}
rapidjson::Value StartMining::Response::toJson(rapidjson::Document& doc) const
@ -375,7 +371,6 @@ rapidjson::Value MiningStatus::Response::toJson(rapidjson::Document& doc) const
INSERT_INTO_JSON_OBJECT(val, doc, speed, speed);
INSERT_INTO_JSON_OBJECT(val, doc, threads_count, threads_count);
INSERT_INTO_JSON_OBJECT(val, doc, address, address);
INSERT_INTO_JSON_OBJECT(val, doc, is_background_mining_enabled, is_background_mining_enabled);
return val;
}
@ -386,7 +381,6 @@ void MiningStatus::Response::fromJson(rapidjson::Value& val)
GET_FROM_JSON_OBJECT(val, speed, speed);
GET_FROM_JSON_OBJECT(val, threads_count, threads_count);
GET_FROM_JSON_OBJECT(val, address, address);
GET_FROM_JSON_OBJECT(val, is_background_mining_enabled, is_background_mining_enabled);
}

View File

@ -177,8 +177,6 @@ BEGIN_RPC_MESSAGE_CLASS(StartMining);
BEGIN_RPC_MESSAGE_REQUEST;
std::string miner_address;
uint64_t threads_count;
bool do_background_mining;
bool ignore_battery;
END_RPC_MESSAGE_REQUEST;
BEGIN_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_RESPONSE;
@ -207,7 +205,6 @@ BEGIN_RPC_MESSAGE_CLASS(MiningStatus);
uint64_t speed;
uint64_t threads_count;
std::string address;
bool is_background_mining_enabled;
END_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_CLASS;

View File

@ -171,7 +171,7 @@ namespace
const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""};
const char* USAGE_START_MINING("start_mining [<number_of_threads>] [bg_mining] [ignore_battery]");
const char* USAGE_START_MINING("start_mining [<number_of_threads>]");
const char* USAGE_SET_DAEMON("set_daemon <host>[:<port>] [trusted|untrusted]");
const char* USAGE_SHOW_BALANCE("balance [detail]");
const char* USAGE_INCOMING_TRANSFERS("incoming_transfers [available|unavailable] [verbose] [uses] [index=<N1>[,<N2>[,...]]]");
@ -2527,31 +2527,6 @@ bool simple_wallet::set_track_uses(const std::vector<std::string> &args/* = std:
return true;
}
bool simple_wallet::set_setup_background_mining(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
const auto pwd_container = get_and_verify_password();
if (pwd_container)
{
tools::wallet2::BackgroundMiningSetupType setup = tools::wallet2::BackgroundMiningMaybe;
if (args[1] == "yes" || args[1] == "1")
setup = tools::wallet2::BackgroundMiningYes;
else if (args[1] == "no" || args[1] == "0")
setup = tools::wallet2::BackgroundMiningNo;
else
{
fail_msg_writer() << tr("invalid argument: must be either 1/yes or 0/no");
return true;
}
m_wallet->setup_background_mining(setup);
m_wallet->rewrite(m_wallet_file, pwd_container->password());
if (setup == tools::wallet2::BackgroundMiningYes)
start_background_mining();
else
stop_background_mining();
}
return true;
}
bool simple_wallet::set_device_name(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
const auto pwd_container = get_and_verify_password();
@ -2610,7 +2585,7 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("start_mining",
boost::bind(&simple_wallet::start_mining, this, _1),
tr(USAGE_START_MINING),
tr("Start mining in the daemon (bg_mining and ignore_battery are optional booleans)."));
tr("Start mining in the daemon"));
m_cmd_binder.set_handler("stop_mining",
boost::bind(&simple_wallet::stop_mining, this, _1),
tr("Stop mining in the daemon."));
@ -3140,13 +3115,6 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
case tools::wallet2::AskPasswordOnAction: ask_password_string = "action"; break;
case tools::wallet2::AskPasswordToDecrypt: ask_password_string = "decrypt"; break;
}
std::string setup_background_mining_string = "invalid";
switch (m_wallet->setup_background_mining())
{
case tools::wallet2::BackgroundMiningMaybe: setup_background_mining_string = "maybe"; break;
case tools::wallet2::BackgroundMiningYes: setup_background_mining_string = "yes"; break;
case tools::wallet2::BackgroundMiningNo: setup_background_mining_string = "no"; break;
}
success_msg_writer() << "seed = " << seed_language;
success_msg_writer() << "always-confirm-transfers = " << m_wallet->always_confirm_transfers();
success_msg_writer() << "print-ring-members = " << m_wallet->print_ring_members();
@ -3168,7 +3136,6 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
success_msg_writer() << "segregation-height = " << m_wallet->segregation_height();
success_msg_writer() << "ignore-fractional-outputs = " << m_wallet->ignore_fractional_outputs();
success_msg_writer() << "track-uses = " << m_wallet->track_uses();
success_msg_writer() << "setup-background-mining = " << setup_background_mining_string + tr(" (set this to support the network and to get a chance to receive new Loki)");
success_msg_writer() << "device_name = " << m_wallet->device_name();
return true;
}
@ -3221,7 +3188,6 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
CHECK_SIMPLE_VARIABLE("segregation-height", set_segregation_height, tr("unsigned integer"));
CHECK_SIMPLE_VARIABLE("ignore-fractional-outputs", set_ignore_fractional_outputs, tr("0 or 1"));
CHECK_SIMPLE_VARIABLE("track-uses", set_track_uses, tr("0 or 1"));
CHECK_SIMPLE_VARIABLE("setup-background-mining", set_setup_background_mining, tr("1/yes or 0/no"));
CHECK_SIMPLE_VARIABLE("device-name", set_device_name, tr("<device_name[:device_spec]>"));
}
fail_msg_writer() << tr("set: unrecognized argument(s)");
@ -4558,118 +4524,6 @@ bool simple_wallet::save_watch_only(const std::vector<std::string> &args/* = std
return true;
}
//----------------------------------------------------------------------------------------------------
void simple_wallet::start_background_mining()
{
COMMAND_RPC_MINING_STATUS::request reqq;
COMMAND_RPC_MINING_STATUS::response resq;
bool r = m_wallet->invoke_http_json("/mining_status", reqq, resq);
std::string err = interpret_rpc_response(r, resq.status);
if (!r)
return;
if (!err.empty())
{
fail_msg_writer() << tr("Failed to query mining status: ") << err;
return;
}
if (!resq.is_background_mining_enabled)
{
COMMAND_RPC_START_MINING::request req;
COMMAND_RPC_START_MINING::response res;
req.miner_address = m_wallet->get_account().get_public_address_str(m_wallet->nettype());
req.threads_count = 1;
req.do_background_mining = true;
req.ignore_battery = false;
bool r = m_wallet->invoke_http_json("/start_mining", req, res);
std::string err = interpret_rpc_response(r, res.status);
if (!err.empty())
{
fail_msg_writer() << tr("Failed to setup background mining: ") << err;
return;
}
}
success_msg_writer() << tr("Background mining enabled. Thank you for supporting the Loki network.");
}
//----------------------------------------------------------------------------------------------------
void simple_wallet::stop_background_mining()
{
COMMAND_RPC_MINING_STATUS::request reqq;
COMMAND_RPC_MINING_STATUS::response resq;
bool r = m_wallet->invoke_http_json("/mining_status", reqq, resq);
if (!r)
return;
std::string err = interpret_rpc_response(r, resq.status);
if (!err.empty())
{
fail_msg_writer() << tr("Failed to query mining status: ") << err;
return;
}
if (resq.is_background_mining_enabled)
{
COMMAND_RPC_STOP_MINING::request req;
COMMAND_RPC_STOP_MINING::response res;
bool r = m_wallet->invoke_http_json("/stop_mining", req, res);
std::string err = interpret_rpc_response(r, res.status);
if (!err.empty())
{
fail_msg_writer() << tr("Failed to setup background mining: ") << err;
return;
}
}
message_writer(console_color_red, false) << tr("Background mining not enabled. Run \"set setup-background-mining 1\" to change.");
}
//----------------------------------------------------------------------------------------------------
void simple_wallet::check_background_mining(const epee::wipeable_string &password)
{
tools::wallet2::BackgroundMiningSetupType setup = m_wallet->setup_background_mining();
if (setup == tools::wallet2::BackgroundMiningNo)
{
message_writer(console_color_red, false) << tr("Background mining not enabled. Run \"set setup-background-mining 1\" to change.");
return;
}
if (!m_wallet->is_trusted_daemon())
{
message_writer() << tr("Using an untrusted daemon, skipping background mining check");
return;
}
COMMAND_RPC_MINING_STATUS::request req;
COMMAND_RPC_MINING_STATUS::response res;
bool r = m_wallet->invoke_http_json("/mining_status", req, res);
std::string err = interpret_rpc_response(r, res.status);
bool is_background_mining_enabled = false;
if (err.empty())
is_background_mining_enabled = res.is_background_mining_enabled;
if (is_background_mining_enabled)
{
// already active, nice
m_wallet->setup_background_mining(tools::wallet2::BackgroundMiningYes);
m_wallet->rewrite(m_wallet_file, password);
start_background_mining();
return;
}
if (res.active)
return;
if (setup == tools::wallet2::BackgroundMiningMaybe)
{
message_writer() << tr("The daemon is not set up to background mine.");
message_writer() << tr("With background mining enabled, the daemon will mine when idle and not on batttery.");
message_writer() << tr("Enabling this supports the network you are using, and makes you eligible for receiving new Loki");
std::string accepted = input_line(tr("Do you want to do it now? (Y/Yes/N/No)"));
if (std::cin.eof() || !command_line::is_yes(accepted)) {
m_wallet->setup_background_mining(tools::wallet2::BackgroundMiningNo);
m_wallet->rewrite(m_wallet_file, password);
message_writer(console_color_red, false) << tr("Background mining not enabled. Set setup-background-mining to 1 to change.");
return;
}
m_wallet->setup_background_mining(tools::wallet2::BackgroundMiningYes);
m_wallet->rewrite(m_wallet_file, password);
start_background_mining();
}
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::start_mining(const std::vector<std::string>& args)
{
if (!m_wallet->is_trusted_daemon())
@ -4691,16 +4545,6 @@ bool simple_wallet::start_mining(const std::vector<std::string>& args)
bool ok = true;
size_t arg_size = args.size();
if(arg_size >= 3)
{
if (!parse_bool_and_use(args[2], [&](bool r) { req.ignore_battery = r; }))
return true;
}
if(arg_size >= 2)
{
if (!parse_bool_and_use(args[1], [&](bool r) { req.do_background_mining = r; }))
return true;
}
if(arg_size >= 1)
{
uint16_t num = 1;

View File

@ -146,7 +146,6 @@ namespace cryptonote
bool set_segregation_height(const std::vector<std::string> &args = std::vector<std::string>());
bool set_ignore_fractional_outputs(const std::vector<std::string> &args = std::vector<std::string>());
bool set_track_uses(const std::vector<std::string> &args = std::vector<std::string>());
bool set_setup_background_mining(const std::vector<std::string> &args = std::vector<std::string>());
bool set_device_name(const std::vector<std::string> &args = std::vector<std::string>());
bool help(const std::vector<std::string> &args = std::vector<std::string>());
bool start_mining(const std::vector<std::string> &args);
@ -318,13 +317,6 @@ namespace cryptonote
*/
void commit_or_save(std::vector<tools::wallet2::pending_tx>& ptx_vector, bool do_not_relay, bool blink);
/*!
* \brief checks whether background mining is enabled, and asks to configure it if not
*/
void check_background_mining(const epee::wipeable_string &password);
void start_background_mining();
void stop_background_mining();
//----------------- i_wallet2_callback ---------------------
virtual void on_new_block(uint64_t height, const cryptonote::block& block);
virtual void on_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount, const cryptonote::subaddress_index& subaddr_index, uint64_t unlock_time, bool blink);

View File

@ -1245,7 +1245,7 @@ struct WalletManagerBase
virtual bool isMining() = 0;
//! starts mining with the set number of threads
virtual bool startMining(const std::string &address, uint32_t threads = 1, bool background_mining = false, bool ignore_battery = true) = 0;
virtual bool startMining(const std::string &address, uint32_t threads = 1) = 0;
//! stops mining
virtual bool stopMining() = 0;

View File

@ -308,15 +308,13 @@ bool WalletManagerImpl::isMining()
return mres.active;
}
bool WalletManagerImpl::startMining(const std::string &address, uint32_t threads, bool background_mining, bool ignore_battery)
bool WalletManagerImpl::startMining(const std::string &address, uint32_t threads)
{
cryptonote::COMMAND_RPC_START_MINING::request mreq;
cryptonote::COMMAND_RPC_START_MINING::response mres;
mreq.miner_address = address;
mreq.threads_count = threads;
mreq.ignore_battery = ignore_battery;
mreq.do_background_mining = background_mining;
if (!epee::net_utils::invoke_http_json("/start_mining", mreq, mres, m_http_client))
return false;

View File

@ -88,7 +88,7 @@ public:
double miningHashRate() override;
uint64_t blockTarget() override;
bool isMining() override;
bool startMining(const std::string &address, uint32_t threads = 1, bool background_mining = false, bool ignore_battery = true) override;
bool startMining(const std::string &address, uint32_t threads = 1) override;
bool stopMining() override;
std::string resolveOpenAlias(const std::string &address, bool &dnssec_valid) const override;

View File

@ -1067,7 +1067,6 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended):
m_segregation_height(0),
m_ignore_fractional_outputs(true),
m_track_uses(false),
m_setup_background_mining(BackgroundMiningMaybe),
m_is_initialized(false),
m_kdf_rounds(kdf_rounds),
is_old_file_format(false),
@ -3868,9 +3867,6 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
value2.SetInt(m_track_uses ? 1 : 0);
json.AddMember("track_uses", value2, json.GetAllocator());
value2.SetInt(m_setup_background_mining);
json.AddMember("setup_background_mining", value2, json.GetAllocator());
value2.SetUint(m_subaddress_lookahead_major);
json.AddMember("subaddress_lookahead_major", value2, json.GetAllocator());
@ -4018,7 +4014,6 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
m_segregation_height = 0;
m_ignore_fractional_outputs = true;
m_track_uses = false;
m_setup_background_mining = BackgroundMiningMaybe;
m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR;
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
m_original_keys_available = false;
@ -4167,8 +4162,6 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
m_ignore_fractional_outputs = field_ignore_fractional_outputs;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, track_uses, int, Int, false, false);
m_track_uses = field_track_uses;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, setup_background_mining, BackgroundMiningSetupType, Int, false, BackgroundMiningMaybe);
m_setup_background_mining = field_setup_background_mining;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_major, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MAJOR);
m_subaddress_lookahead_major = field_subaddress_lookahead_major;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_minor, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MINOR);

View File

@ -343,12 +343,6 @@ private:
AskPasswordToDecrypt = 2,
};
enum BackgroundMiningSetupType {
BackgroundMiningMaybe = 0,
BackgroundMiningYes = 1,
BackgroundMiningNo = 2,
};
static const char* tr(const char* str);
static bool has_testnet_option(const boost::program_options::variables_map& vm);
@ -1225,8 +1219,6 @@ private:
void confirm_non_default_ring_size(bool always) { m_confirm_non_default_ring_size = always; }
bool track_uses() const { return m_track_uses; }
void track_uses(bool value) { m_track_uses = value; }
BackgroundMiningSetupType setup_background_mining() const { return m_setup_background_mining; }
void setup_background_mining(BackgroundMiningSetupType value) { m_setup_background_mining = value; }
const std::string & device_name() const { return m_device_name; }
void device_name(const std::string & device_name) { m_device_name = device_name; }
const std::string & device_derivation_path() const { return m_device_derivation_path; }
@ -1775,7 +1767,6 @@ private:
uint64_t m_segregation_height;
bool m_ignore_fractional_outputs;
bool m_track_uses;
BackgroundMiningSetupType m_setup_background_mining;
bool m_is_initialized;
NodeRPCProxy m_node_rpc_proxy;
std::unordered_set<crypto::hash> m_scanned_pool_txs[2];

View File

@ -277,60 +277,6 @@ namespace tools
);
}
//------------------------------------------------------------------------------------------------------------------------------
void wallet_rpc_server::check_background_mining()
{
if (!m_wallet)
return;
tools::wallet2::BackgroundMiningSetupType setup = m_wallet->setup_background_mining();
if (setup == tools::wallet2::BackgroundMiningNo)
{
MLOG_RED(el::Level::Warning, "Background mining not enabled. Run \"set setup-background-mining 1\" in loki-wallet-cli to change.");
return;
}
if (!m_wallet->is_trusted_daemon())
{
MDEBUG("Using an untrusted daemon, skipping background mining check");
return;
}
cryptonote::COMMAND_RPC_MINING_STATUS::request req;
cryptonote::COMMAND_RPC_MINING_STATUS::response res;
bool r = m_wallet->invoke_http_json("/mining_status", req, res);
if (!r || res.status != CORE_RPC_STATUS_OK)
{
MERROR("Failed to query mining status: " << (r ? res.status : "No connection to daemon"));
return;
}
if (res.active || res.is_background_mining_enabled)
return;
if (setup == tools::wallet2::BackgroundMiningMaybe)
{
MINFO("The daemon is not set up to background mine.");
MINFO("With background mining enabled, the daemon will mine when idle and not on batttery.");
MINFO("Enabling this supports the network you are using, and makes you eligible for receiving new Loki");
MINFO("Set setup-background-mining to 1 in loki-wallet-cli to change.");
return;
}
cryptonote::COMMAND_RPC_START_MINING::request req2;
cryptonote::COMMAND_RPC_START_MINING::response res2;
req2.miner_address = m_wallet->get_account().get_public_address_str(m_wallet->nettype());
req2.threads_count = 1;
req2.do_background_mining = true;
req2.ignore_battery = false;
r = m_wallet->invoke_http_json("/start_mining", req2, res);
if (!r || res2.status != CORE_RPC_STATUS_OK)
{
MERROR("Failed to setup background mining: " << (r ? res.status : "No connection to daemon"));
return;
}
MINFO("Background mining enabled. The daemon will mine when idle and not on batttery.");
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::not_open(epee::json_rpc::error& er)
{
er.code = WALLET_RPC_ERROR_CODE_NOT_OPEN;
@ -2882,8 +2828,6 @@ namespace tools
cryptonote::COMMAND_RPC_START_MINING::request daemon_req{};
daemon_req.miner_address = m_wallet->get_account().get_public_address_str(m_wallet->nettype());
daemon_req.threads_count = req.threads_count;
daemon_req.do_background_mining = req.do_background_mining;
daemon_req.ignore_battery = req.ignore_battery;
cryptonote::COMMAND_RPC_START_MINING::response daemon_res;
bool r = m_wallet->invoke_http_json("/start_mining", daemon_req, daemon_res);

View File

@ -280,8 +280,6 @@ namespace tools
bool validate_transfer(const std::list<transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er);
void check_background_mining();
wallet2 *m_wallet;
std::string m_wallet_dir;
tools::private_file rpc_login_file;

View File

@ -2080,13 +2080,9 @@ namespace wallet_rpc
struct request_t
{
uint64_t threads_count; // Number of threads created for mining.
bool do_background_mining; // Allow to start the miner in smart mining mode.
bool ignore_battery; // Ignore battery status (for smart mining only).
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(threads_count)
KV_SERIALIZE(do_background_mining)
KV_SERIALIZE(ignore_battery)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;