aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cryptonote_basic/miner.cpp77
-rw-r--r--src/cryptonote_basic/miner.h8
-rw-r--r--src/daemon/command_parser_executor.cpp12
-rw-r--r--src/daemon/command_server.cpp2
-rw-r--r--src/daemon/rpc_command_executor.cpp5
-rw-r--r--src/daemon/rpc_command_executor.h2
-rw-r--r--src/rpc/core_rpc_server.cpp2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h2
-rw-r--r--src/wallet/wallet2.cpp10
9 files changed, 86 insertions, 34 deletions
diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp
index 117c81878..bf1b057ee 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;
@@ -575,7 +591,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 )
{
@@ -763,45 +793,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();
};
}
diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
index 8ed529737..e5fa5fece 100644
--- a/src/daemon/command_parser_executor.cpp
+++ b/src/daemon/command_parser_executor.cpp
@@ -272,12 +272,18 @@ bool t_command_parser_executor::start_mining(const std::vector<std::string>& arg
std::cout << "Mining to a testnet address, make sure this is intentional!" << std::endl;
uint64_t threads_count = 1;
bool do_background_mining = false;
- if(args.size() > 3)
+ bool ignore_battery = false;
+ if(args.size() > 4)
{
return false;
}
- if(args.size() == 3)
+ if(args.size() == 4)
+ {
+ ignore_battery = args[3] == "true";
+ }
+
+ if(args.size() >= 3)
{
do_background_mining = args[2] == "true";
}
@@ -288,7 +294,7 @@ bool t_command_parser_executor::start_mining(const std::vector<std::string>& arg
threads_count = (ok && 0 < threads_count) ? threads_count : 1;
}
- m_executor.start_mining(adr, threads_count, testnet, do_background_mining);
+ m_executor.start_mining(adr, threads_count, testnet, do_background_mining, ignore_battery);
return true;
}
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index 4133b90d9..365a7d03b 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -96,7 +96,7 @@ 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 for specified address, start_mining <addr> [<threads>] [do_background_mining], default 1 thread, no background mining"
+ , "Start mining for specified address, start_mining <addr> [<threads>] [do_background_mining] [ignore_battery], default 1 thread, no background mining"
);
m_command_lookup.set_handler(
"stop_mining"
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index 00b349b15..219a7a1c4 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -929,13 +929,14 @@ 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, bool testnet, bool do_background_mining = false) {
+bool t_rpc_command_executor::start_mining(cryptonote::account_public_address address, uint64_t num_threads, bool testnet, bool do_background_mining, bool ignore_battery) {
cryptonote::COMMAND_RPC_START_MINING::request req;
cryptonote::COMMAND_RPC_START_MINING::response res;
req.miner_address = cryptonote::get_account_address_as_str(testnet, 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";
if (m_is_rpc)
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
index 5b7b76448..d9e874767 100644
--- a/src/daemon/rpc_command_executor.h
+++ b/src/daemon/rpc_command_executor.h
@@ -106,7 +106,7 @@ public:
bool print_transaction_pool_stats();
- bool start_mining(cryptonote::account_public_address address, uint64_t num_threads, bool testnet, bool do_background_mining);
+ bool start_mining(cryptonote::account_public_address address, uint64_t num_threads, bool testnet, bool do_background_mining = false, bool ignore_battery = false);
bool stop_mining();
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 2906e6433..157076e82 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -635,7 +635,7 @@ namespace cryptonote
boost::thread::attributes attrs;
attrs.set_stack_size(THREAD_STACK_SIZE);
- if(!m_core.get_miner().start(adr, static_cast<size_t>(req.threads_count), attrs, req.do_background_mining))
+ if(!m_core.get_miner().start(adr, static_cast<size_t>(req.threads_count), attrs, req.do_background_mining, req.ignore_battery))
{
res.status = "Failed, mining not started";
LOG_PRINT_L0(res.status);
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 3ab1ea175..8b744c26a 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -501,11 +501,13 @@ namespace cryptonote
std::string miner_address;
uint64_t threads_count;
bool do_background_mining;
+ bool ignore_battery;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(miner_address)
KV_SERIALIZE(threads_count)
KV_SERIALIZE(do_background_mining)
+ KV_SERIALIZE(ignore_battery)
END_KV_SERIALIZE_MAP()
};
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 250210cb0..56eee6ecf 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -4217,13 +4217,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// get a random unspent output and use it to pay part (or all) of the current destination (and maybe next one, etc)
// This could be more clever, but maybe at the cost of making probabilistic inferences easier
size_t idx;
- if ((dsts.empty() || dsts[0].amount == 0) && !adding_fee)
+ if ((dsts.empty() || dsts[0].amount == 0) && !adding_fee) {
// the "make rct txes 2/2" case - we pick a small value output to "clean up" the wallet too
idx = pop_best_value(unused_dust_indices.empty() ? unused_transfers_indices : unused_dust_indices, tx.selected_transfers, true);
- else if (!prefered_inputs.empty()) {
- idx = pop_back(prefered_inputs);
- pop_if_present(unused_transfers_indices, idx);
- pop_if_present(unused_dust_indices, idx);
// since we're trying to add a second output which is not strictly needed,
// we only add it if it's unrelated enough to the first one
@@ -4233,6 +4229,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
LOG_PRINT_L2("Second outout was not strictly needed, and relatedness " << relatedness << ", not adding");
break;
}
+ } else if (!prefered_inputs.empty()) {
+ idx = pop_back(prefered_inputs);
+ pop_if_present(unused_transfers_indices, idx);
+ pop_if_present(unused_dust_indices, idx);
} else
idx = pop_best_value(unused_transfers_indices.empty() ? unused_dust_indices : unused_transfers_indices, tx.selected_transfers);