Merge pull request #5374

a2561653 wallet: new option to start background mining (moneromooo-monero)
This commit is contained in:
Riccardo Spagni 2019-04-11 13:01:30 +02:00
commit 3a4008f0fc
No known key found for this signature in database
GPG Key ID: 55432DF31CCD4FCD
10 changed files with 264 additions and 20 deletions

View File

@ -456,6 +456,7 @@ namespace cryptonote
// interrupt it just in case // interrupt it just in case
m_background_mining_thread.interrupt(); m_background_mining_thread.interrupt();
m_background_mining_thread.join(); m_background_mining_thread.join();
m_is_background_mining_enabled = false;
MINFO("Mining has been stopped, " << m_threads.size() << " finished" ); MINFO("Mining has been stopped, " << m_threads.size() << " finished" );
m_threads.clear(); m_threads.clear();
@ -747,10 +748,10 @@ namespace cryptonote
uint8_t idle_percentage = get_percent_of_total(idle_diff, total_diff); uint8_t idle_percentage = get_percent_of_total(idle_diff, total_diff);
uint8_t process_percentage = get_percent_of_total(process_diff, total_diff); uint8_t process_percentage = get_percent_of_total(process_diff, total_diff);
MGINFO("idle percentage is " << unsigned(idle_percentage) << "\%, miner percentage is " << unsigned(process_percentage) << "\%, ac power : " << on_ac_power); 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 ) if( idle_percentage + process_percentage < get_idle_threshold() || !on_ac_power )
{ {
MGINFO("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!"); 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; m_is_background_mining_started = false;
// reset process times // reset process times
@ -788,10 +789,10 @@ namespace cryptonote
uint64_t idle_diff = (current_idle_time - prev_idle_time); uint64_t idle_diff = (current_idle_time - prev_idle_time);
uint8_t idle_percentage = get_percent_of_total(idle_diff, total_diff); uint8_t idle_percentage = get_percent_of_total(idle_diff, total_diff);
MGINFO("idle percentage is " << unsigned(idle_percentage)); MDEBUG("idle percentage is " << unsigned(idle_percentage));
if( idle_percentage >= get_idle_threshold() && on_ac_power ) if( idle_percentage >= get_idle_threshold() && on_ac_power )
{ {
MGINFO("cpu is " << unsigned(idle_percentage) << "% idle, idle threshold is " << unsigned(get_idle_threshold()) << "\%, ac power : " << on_ac_power << ", background mining started, good luck!"); 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 = true;
m_is_background_mining_started_cond.notify_all(); m_is_background_mining_started_cond.notify_all();
@ -1049,7 +1050,12 @@ namespace cryptonote
if (boost::logic::indeterminate(on_battery)) if (boost::logic::indeterminate(on_battery))
{ {
LOG_ERROR("couldn't query power status from " << power_supply_class_path); 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; return on_battery;

View File

@ -551,11 +551,12 @@ bool t_rpc_command_executor::mining_status() {
tools::msg_writer() << " Ignore battery: " << (mres.bg_ignore_battery ? "yes" : "no"); tools::msg_writer() << " Ignore battery: " << (mres.bg_ignore_battery ? "yes" : "no");
} }
if (!mining_busy && mres.active) if (!mining_busy && mres.active && mres.speed > 0 && mres.block_target > 0 && mres.difficulty > 0)
{ {
uint64_t daily = 86400ull / mres.block_target * mres.block_reward; double ratio = mres.speed * mres.block_target / mres.difficulty;
uint64_t monthly = 86400ull / mres.block_target * 30.5 * mres.block_reward; uint64_t daily = 86400ull / mres.block_target * mres.block_reward * ratio;
uint64_t yearly = 86400ull / mres.block_target * 356 * mres.block_reward; 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) << " monero daily, " tools::msg_writer() << "Expected: " << cryptonote::print_money(daily) << " monero daily, "
<< cryptonote::print_money(monthly) << " monero monthly, " << cryptonote::print_money(yearly) << " yearly"; << cryptonote::print_money(monthly) << " monero monthly, " << cryptonote::print_money(yearly) << " yearly";
} }

View File

@ -973,6 +973,7 @@ namespace cryptonote
const miner& lMiner = m_core.get_miner(); const miner& lMiner = m_core.get_miner();
res.active = lMiner.is_mining(); res.active = lMiner.is_mining();
res.is_background_mining_enabled = lMiner.get_is_background_mining_enabled(); res.is_background_mining_enabled = lMiner.get_is_background_mining_enabled();
store_difficulty(m_core.get_blockchain_storage().get_difficulty_for_next_block(), res.difficulty, res.wide_difficulty, res.difficulty_top64);
res.block_target = m_core.get_blockchain_storage().get_current_hard_fork_version() < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2; res.block_target = m_core.get_blockchain_storage().get_current_hard_fork_version() < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
if ( lMiner.is_mining() ) { if ( lMiner.is_mining() ) {

View File

@ -821,6 +821,9 @@ namespace cryptonote
uint8_t bg_target; uint8_t bg_target;
uint32_t block_target; uint32_t block_target;
uint64_t block_reward; uint64_t block_reward;
uint64_t difficulty;
std::string wide_difficulty;
uint64_t difficulty_top64;
BEGIN_KV_SERIALIZE_MAP() BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status) KV_SERIALIZE(status)
@ -836,6 +839,9 @@ namespace cryptonote
KV_SERIALIZE(bg_target) KV_SERIALIZE(bg_target)
KV_SERIALIZE(block_target) KV_SERIALIZE(block_target)
KV_SERIALIZE(block_reward) KV_SERIALIZE(block_reward)
KV_SERIALIZE(difficulty)
KV_SERIALIZE(wide_difficulty)
KV_SERIALIZE(difficulty_top64)
END_KV_SERIALIZE_MAP() END_KV_SERIALIZE_MAP()
}; };
typedef epee::misc_utils::struct_init<response_t> response; typedef epee::misc_utils::struct_init<response_t> response;

View File

@ -2600,6 +2600,31 @@ bool simple_wallet::set_track_uses(const std::vector<std::string> &args/* = std:
return true; 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>()*/) bool simple_wallet::set_device_name(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{ {
const auto pwd_container = get_and_verify_password(); const auto pwd_container = get_and_verify_password();
@ -3137,6 +3162,13 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
case tools::wallet2::AskPasswordOnAction: ask_password_string = "action"; break; case tools::wallet2::AskPasswordOnAction: ask_password_string = "action"; break;
case tools::wallet2::AskPasswordToDecrypt: ask_password_string = "decrypt"; 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() << "seed = " << seed_language;
success_msg_writer() << "always-confirm-transfers = " << m_wallet->always_confirm_transfers(); success_msg_writer() << "always-confirm-transfers = " << m_wallet->always_confirm_transfers();
success_msg_writer() << "print-ring-members = " << m_wallet->print_ring_members(); success_msg_writer() << "print-ring-members = " << m_wallet->print_ring_members();
@ -3163,6 +3195,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
success_msg_writer() << "segregation-height = " << m_wallet->segregation_height(); success_msg_writer() << "segregation-height = " << m_wallet->segregation_height();
success_msg_writer() << "ignore-fractional-outputs = " << m_wallet->ignore_fractional_outputs(); success_msg_writer() << "ignore-fractional-outputs = " << m_wallet->ignore_fractional_outputs();
success_msg_writer() << "track-uses = " << m_wallet->track_uses(); 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 monero)");
success_msg_writer() << "device_name = " << m_wallet->device_name(); success_msg_writer() << "device_name = " << m_wallet->device_name();
return true; return true;
} }
@ -3220,6 +3253,7 @@ 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("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("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("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]>")); CHECK_SIMPLE_VARIABLE("device-name", set_device_name, tr("<device_name[:device_spec]>"));
} }
fail_msg_writer() << tr("set: unrecognized argument(s)"); fail_msg_writer() << tr("set: unrecognized argument(s)");
@ -3415,6 +3449,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
const network_type nettype = testnet ? TESTNET : stagenet ? STAGENET : MAINNET; const network_type nettype = testnet ? TESTNET : stagenet ? STAGENET : MAINNET;
epee::wipeable_string multisig_keys; epee::wipeable_string multisig_keys;
epee::wipeable_string password;
if (!handle_command_line(vm)) if (!handle_command_line(vm))
return false; return false;
@ -3522,7 +3557,6 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
m_recovery_key = cryptonote::decrypt_key(m_recovery_key, seed_pass); m_recovery_key = cryptonote::decrypt_key(m_recovery_key, seed_pass);
} }
} }
epee::wipeable_string password;
if (!m_generate_from_view_key.empty()) if (!m_generate_from_view_key.empty())
{ {
m_wallet_file = m_generate_from_view_key; m_wallet_file = m_generate_from_view_key;
@ -3967,8 +4001,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
fail_msg_writer() << tr("can't specify --subaddress-lookahead and --wallet-file at the same time"); fail_msg_writer() << tr("can't specify --subaddress-lookahead and --wallet-file at the same time");
return false; return false;
} }
bool r = open_wallet(vm); auto r = open_wallet(vm);
CHECK_AND_ASSERT_MES(r, false, tr("failed to open account")); CHECK_AND_ASSERT_MES(r, false, tr("failed to open account"));
password = *r;
} }
if (!m_wallet) if (!m_wallet)
{ {
@ -3984,6 +4019,8 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
m_wallet->callback(this); m_wallet->callback(this);
check_background_mining(password);
return true; return true;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
@ -4353,12 +4390,12 @@ boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::pr
return std::move(password); return std::move(password);
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm) boost::optional<epee::wipeable_string> simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
{ {
if (!tools::wallet2::wallet_valid_path_format(m_wallet_file)) if (!tools::wallet2::wallet_valid_path_format(m_wallet_file))
{ {
fail_msg_writer() << tr("wallet file path not valid: ") << m_wallet_file; fail_msg_writer() << tr("wallet file path not valid: ") << m_wallet_file;
return false; return {};
} }
bool keys_file_exists; bool keys_file_exists;
@ -4368,7 +4405,7 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
if(!keys_file_exists) if(!keys_file_exists)
{ {
fail_msg_writer() << tr("Key file not found. Failed to open wallet"); fail_msg_writer() << tr("Key file not found. Failed to open wallet");
return false; return {};
} }
epee::wipeable_string password; epee::wipeable_string password;
@ -4379,7 +4416,7 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
password = std::move(std::move(rc.second).password()); password = std::move(std::move(rc.second).password());
if (!m_wallet) if (!m_wallet)
{ {
return false; return {};
} }
m_wallet->callback(this); m_wallet->callback(this);
@ -4405,7 +4442,7 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
{ {
bool is_deterministic; bool is_deterministic;
{ {
SCOPED_WALLET_UNLOCK(); SCOPED_WALLET_UNLOCK_ON_BAD_PASSWORD(return {};);
is_deterministic = m_wallet->is_deterministic(); is_deterministic = m_wallet->is_deterministic();
} }
if (is_deterministic) if (is_deterministic)
@ -4414,7 +4451,7 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
"a deprecated version of the wallet. Please proceed to upgrade your wallet.\n"); "a deprecated version of the wallet. Please proceed to upgrade your wallet.\n");
std::string mnemonic_language = get_mnemonic_language(); std::string mnemonic_language = get_mnemonic_language();
if (mnemonic_language.empty()) if (mnemonic_language.empty())
return false; return {};
m_wallet->set_seed_language(mnemonic_language); m_wallet->set_seed_language(mnemonic_language);
m_wallet->rewrite(m_wallet_file, password); m_wallet->rewrite(m_wallet_file, password);
@ -4446,14 +4483,14 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
if (password_is_correct) if (password_is_correct)
fail_msg_writer() << boost::format(tr("You may want to remove the file \"%s\" and try again")) % m_wallet_file; fail_msg_writer() << boost::format(tr("You may want to remove the file \"%s\" and try again")) % m_wallet_file;
} }
return false; return {};
} }
success_msg_writer() << success_msg_writer() <<
"**********************************************************************\n" << "**********************************************************************\n" <<
tr("Use the \"help\" command to see the list of available commands.\n") << tr("Use the \"help\" command to see the list of available commands.\n") <<
tr("Use \"help <command>\" to see a command's documentation.\n") << tr("Use \"help <command>\" to see a command's documentation.\n") <<
"**********************************************************************"; "**********************************************************************";
return true; return std::move(password);
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
bool simple_wallet::close_wallet() bool simple_wallet::close_wallet()
@ -4534,7 +4571,118 @@ bool simple_wallet::save_watch_only(const std::vector<std::string> &args/* = std
} }
return true; 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 Monero 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 monero");
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) bool simple_wallet::start_mining(const std::vector<std::string>& args)
{ {

View File

@ -102,7 +102,7 @@ namespace cryptonote
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm, boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm,
const epee::wipeable_string &multisig_keys, const std::string &old_language); const epee::wipeable_string &multisig_keys, const std::string &old_language);
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm); boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm);
bool open_wallet(const boost::program_options::variables_map& vm); boost::optional<epee::wipeable_string> open_wallet(const boost::program_options::variables_map& vm);
bool close_wallet(); bool close_wallet();
bool viewkey(const std::vector<std::string> &args = std::vector<std::string>()); bool viewkey(const std::vector<std::string> &args = std::vector<std::string>());
@ -143,6 +143,7 @@ namespace cryptonote
bool set_segregation_height(const std::vector<std::string> &args = std::vector<std::string>()); 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_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_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 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 help(const std::vector<std::string> &args = std::vector<std::string>());
bool start_mining(const std::vector<std::string> &args); bool start_mining(const std::vector<std::string> &args);
@ -298,6 +299,13 @@ namespace cryptonote
*/ */
void commit_or_save(std::vector<tools::wallet2::pending_tx>& ptx_vector, bool do_not_relay); void commit_or_save(std::vector<tools::wallet2::pending_tx>& ptx_vector, bool do_not_relay);
/*!
* \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 --------------------- //----------------- i_wallet2_callback ---------------------
virtual void on_new_block(uint64_t height, const cryptonote::block& block); 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); 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);

View File

@ -1046,6 +1046,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended):
m_segregation_height(0), m_segregation_height(0),
m_ignore_fractional_outputs(true), m_ignore_fractional_outputs(true),
m_track_uses(false), m_track_uses(false),
m_setup_background_mining(BackgroundMiningMaybe),
m_is_initialized(false), m_is_initialized(false),
m_kdf_rounds(kdf_rounds), m_kdf_rounds(kdf_rounds),
is_old_file_format(false), is_old_file_format(false),
@ -3552,6 +3553,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
value2.SetInt(m_track_uses ? 1 : 0); value2.SetInt(m_track_uses ? 1 : 0);
json.AddMember("track_uses", value2, json.GetAllocator()); 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); value2.SetUint(m_subaddress_lookahead_major);
json.AddMember("subaddress_lookahead_major", value2, json.GetAllocator()); json.AddMember("subaddress_lookahead_major", value2, json.GetAllocator());
@ -3703,6 +3707,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
m_segregation_height = 0; m_segregation_height = 0;
m_ignore_fractional_outputs = true; m_ignore_fractional_outputs = true;
m_track_uses = false; m_track_uses = false;
m_setup_background_mining = BackgroundMiningMaybe;
m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR; m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR;
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR; m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
m_original_keys_available = false; m_original_keys_available = false;
@ -3857,6 +3862,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
m_ignore_fractional_outputs = field_ignore_fractional_outputs; m_ignore_fractional_outputs = field_ignore_fractional_outputs;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, track_uses, int, Int, false, false); GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, track_uses, int, Int, false, false);
m_track_uses = field_track_uses; 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); 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; 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); GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_minor, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MINOR);

View File

@ -194,6 +194,12 @@ namespace tools
AskPasswordToDecrypt = 2, AskPasswordToDecrypt = 2,
}; };
enum BackgroundMiningSetupType {
BackgroundMiningMaybe = 0,
BackgroundMiningYes = 1,
BackgroundMiningNo = 2,
};
static const char* tr(const char* str); static const char* tr(const char* str);
static bool has_testnet_option(const boost::program_options::variables_map& vm); static bool has_testnet_option(const boost::program_options::variables_map& vm);
@ -1010,6 +1016,8 @@ namespace tools
void confirm_non_default_ring_size(bool always) { m_confirm_non_default_ring_size = always; } void confirm_non_default_ring_size(bool always) { m_confirm_non_default_ring_size = always; }
bool track_uses() const { return m_track_uses; } bool track_uses() const { return m_track_uses; }
void track_uses(bool value) { m_track_uses = value; } 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; } const std::string & device_name() const { return m_device_name; }
void device_name(const std::string & device_name) { m_device_name = 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; } const std::string & device_derivation_path() const { return m_device_derivation_path; }
@ -1451,6 +1459,7 @@ namespace tools
uint64_t m_segregation_height; uint64_t m_segregation_height;
bool m_ignore_fractional_outputs; bool m_ignore_fractional_outputs;
bool m_track_uses; bool m_track_uses;
BackgroundMiningSetupType m_setup_background_mining;
bool m_is_initialized; bool m_is_initialized;
NodeRPCProxy m_node_rpc_proxy; NodeRPCProxy m_node_rpc_proxy;
std::unordered_set<crypto::hash> m_scanned_pool_txs[2]; std::unordered_set<crypto::hash> m_scanned_pool_txs[2];

View File

@ -279,6 +279,8 @@ namespace tools
m_auto_refresh_period = DEFAULT_AUTO_REFRESH_PERIOD; m_auto_refresh_period = DEFAULT_AUTO_REFRESH_PERIOD;
m_last_auto_refresh_time = boost::posix_time::min_date_time; m_last_auto_refresh_time = boost::posix_time::min_date_time;
check_background_mining();
m_net_server.set_threads_prefix("RPC"); m_net_server.set_threads_prefix("RPC");
auto rng = [](size_t len, uint8_t *ptr) { return crypto::rand(len, ptr); }; auto rng = [](size_t len, uint8_t *ptr) { return crypto::rand(len, ptr); };
return epee::http_server_impl_base<wallet_rpc_server, connection_context>::init( return epee::http_server_impl_base<wallet_rpc_server, connection_context>::init(
@ -287,6 +289,60 @@ 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 monero-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 monero");
MINFO("Set setup-background-mining to 1 in monero-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) bool wallet_rpc_server::not_open(epee::json_rpc::error& er)
{ {
er.code = WALLET_RPC_ERROR_CODE_NOT_OPEN; er.code = WALLET_RPC_ERROR_CODE_NOT_OPEN;

View File

@ -254,6 +254,8 @@ namespace tools
bool validate_transfer(const std::list<wallet_rpc::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); bool validate_transfer(const std::list<wallet_rpc::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; wallet2 *m_wallet;
std::string m_wallet_dir; std::string m_wallet_dir;
tools::private_file rpc_login_file; tools::private_file rpc_login_file;