wallet: add a non destructive blockchain rescan
This commit is contained in:
parent
1e74586ee9
commit
f26ce08c8a
|
@ -2491,6 +2491,7 @@ simple_wallet::simple_wallet()
|
||||||
tr("Show the unspent outputs of a specified address within an optional amount range."));
|
tr("Show the unspent outputs of a specified address within an optional amount range."));
|
||||||
m_cmd_binder.set_handler("rescan_bc",
|
m_cmd_binder.set_handler("rescan_bc",
|
||||||
boost::bind(&simple_wallet::rescan_blockchain, this, _1),
|
boost::bind(&simple_wallet::rescan_blockchain, this, _1),
|
||||||
|
tr("rescan_bc [hard]"),
|
||||||
tr("Rescan the blockchain from scratch, losing any information which can not be recovered from the blockchain itself."));
|
tr("Rescan the blockchain from scratch, losing any information which can not be recovered from the blockchain itself."));
|
||||||
m_cmd_binder.set_handler("set_tx_note",
|
m_cmd_binder.set_handler("set_tx_note",
|
||||||
boost::bind(&simple_wallet::set_tx_note, this, _1),
|
boost::bind(&simple_wallet::set_tx_note, this, _1),
|
||||||
|
@ -4237,15 +4238,15 @@ boost::optional<epee::wipeable_string> simple_wallet::on_get_password(const char
|
||||||
return pwd_container->password();
|
return pwd_container->password();
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool simple_wallet::refresh_main(uint64_t start_height, bool reset, bool is_init)
|
bool simple_wallet::refresh_main(uint64_t start_height, enum ResetType reset, bool is_init)
|
||||||
{
|
{
|
||||||
if (!try_connect_to_daemon(is_init))
|
if (!try_connect_to_daemon(is_init))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
LOCK_IDLE_SCOPE();
|
LOCK_IDLE_SCOPE();
|
||||||
|
|
||||||
if (reset)
|
if (reset != ResetNone)
|
||||||
m_wallet->rescan_blockchain(false);
|
m_wallet->rescan_blockchain(reset == ResetHard, false);
|
||||||
|
|
||||||
#ifdef HAVE_READLINE
|
#ifdef HAVE_READLINE
|
||||||
rdln::suspend_readline pause_readline;
|
rdln::suspend_readline pause_readline;
|
||||||
|
@ -4324,7 +4325,7 @@ bool simple_wallet::refresh(const std::vector<std::string>& args)
|
||||||
start_height = 0;
|
start_height = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return refresh_main(start_height, false);
|
return refresh_main(start_height, ResetNone);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool simple_wallet::show_balance_unlocked(bool detailed)
|
bool simple_wallet::show_balance_unlocked(bool detailed)
|
||||||
|
@ -6982,15 +6983,29 @@ bool simple_wallet::unspent_outputs(const std::vector<std::string> &args_)
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool simple_wallet::rescan_blockchain(const std::vector<std::string> &args_)
|
bool simple_wallet::rescan_blockchain(const std::vector<std::string> &args_)
|
||||||
{
|
{
|
||||||
message_writer() << tr("Warning: this will lose any information which can not be recovered from the blockchain.");
|
bool hard = false;
|
||||||
message_writer() << tr("This includes destination addresses, tx secret keys, tx notes, etc");
|
if (!args_.empty())
|
||||||
std::string confirm = input_line(tr("Rescan anyway ? (Y/Yes/N/No): "));
|
|
||||||
if(!std::cin.eof())
|
|
||||||
{
|
{
|
||||||
if (!command_line::is_yes(confirm))
|
if (args_[0] != "hard")
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("usage: rescan_bc [hard]");
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
hard = true;
|
||||||
}
|
}
|
||||||
return refresh_main(0, true);
|
|
||||||
|
if (hard)
|
||||||
|
{
|
||||||
|
message_writer() << tr("Warning: this will lose any information which can not be recovered from the blockchain.");
|
||||||
|
message_writer() << tr("This includes destination addresses, tx secret keys, tx notes, etc");
|
||||||
|
std::string confirm = input_line(tr("Rescan anyway ? (Y/Yes/N/No): "));
|
||||||
|
if(!std::cin.eof())
|
||||||
|
{
|
||||||
|
if (!command_line::is_yes(confirm))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return refresh_main(0, hard ? ResetHard : ResetSoft, true);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void simple_wallet::wallet_idle_thread()
|
void simple_wallet::wallet_idle_thread()
|
||||||
|
@ -7038,7 +7053,7 @@ bool simple_wallet::run()
|
||||||
// check and display warning, but go on anyway
|
// check and display warning, but go on anyway
|
||||||
try_connect_to_daemon();
|
try_connect_to_daemon();
|
||||||
|
|
||||||
refresh_main(0, false, true);
|
refresh_main(0, ResetNone, true);
|
||||||
|
|
||||||
m_auto_refresh_enabled = m_wallet->auto_refresh();
|
m_auto_refresh_enabled = m_wallet->auto_refresh();
|
||||||
m_idle_thread = boost::thread([&]{wallet_idle_thread();});
|
m_idle_thread = boost::thread([&]{wallet_idle_thread();});
|
||||||
|
|
|
@ -83,6 +83,9 @@ namespace cryptonote
|
||||||
std::string get_commands_str();
|
std::string get_commands_str();
|
||||||
std::string get_command_usage(const std::vector<std::string> &args);
|
std::string get_command_usage(const std::vector<std::string> &args);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
enum ResetType { ResetNone, ResetSoft, ResetHard };
|
||||||
|
|
||||||
bool handle_command_line(const boost::program_options::variables_map& vm);
|
bool handle_command_line(const boost::program_options::variables_map& vm);
|
||||||
|
|
||||||
bool run_console_handler();
|
bool run_console_handler();
|
||||||
|
@ -188,7 +191,7 @@ namespace cryptonote
|
||||||
bool show_transfers(const std::vector<std::string> &args);
|
bool show_transfers(const std::vector<std::string> &args);
|
||||||
bool unspent_outputs(const std::vector<std::string> &args);
|
bool unspent_outputs(const std::vector<std::string> &args);
|
||||||
bool rescan_blockchain(const std::vector<std::string> &args);
|
bool rescan_blockchain(const std::vector<std::string> &args);
|
||||||
bool refresh_main(uint64_t start_height, bool reset = false, bool is_init = false);
|
bool refresh_main(uint64_t start_height, ResetType reset, bool is_init = false);
|
||||||
bool set_tx_note(const std::vector<std::string> &args);
|
bool set_tx_note(const std::vector<std::string> &args);
|
||||||
bool get_tx_note(const std::vector<std::string> &args);
|
bool get_tx_note(const std::vector<std::string> &args);
|
||||||
bool set_description(const std::vector<std::string> &args);
|
bool set_description(const std::vector<std::string> &args);
|
||||||
|
|
|
@ -5073,11 +5073,27 @@ void wallet2::rescan_spent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::rescan_blockchain(bool refresh)
|
void wallet2::rescan_blockchain(bool hard, bool refresh)
|
||||||
{
|
{
|
||||||
clear();
|
if(hard)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
setup_new_blockchain();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_blockchain.clear();
|
||||||
|
m_transfers.clear();
|
||||||
|
m_key_images.clear();
|
||||||
|
m_pub_keys.clear();
|
||||||
|
m_scanned_pool_txs[0].clear();
|
||||||
|
m_scanned_pool_txs[1].clear();
|
||||||
|
|
||||||
setup_new_blockchain();
|
cryptonote::block b;
|
||||||
|
generate_genesis(b);
|
||||||
|
m_blockchain.push_back(get_block_hash(b));
|
||||||
|
m_last_block_reward = cryptonote::get_outs_money_amount(b.miner_tx);
|
||||||
|
}
|
||||||
|
|
||||||
if (refresh)
|
if (refresh)
|
||||||
this->refresh(false);
|
this->refresh(false);
|
||||||
|
|
|
@ -782,7 +782,7 @@ namespace tools
|
||||||
|
|
||||||
uint64_t get_blockchain_current_height() const { return m_light_wallet_blockchain_height ? m_light_wallet_blockchain_height : m_blockchain.size(); }
|
uint64_t get_blockchain_current_height() const { return m_light_wallet_blockchain_height ? m_light_wallet_blockchain_height : m_blockchain.size(); }
|
||||||
void rescan_spent();
|
void rescan_spent();
|
||||||
void rescan_blockchain(bool refresh = true);
|
void rescan_blockchain(bool hard, bool refresh = true);
|
||||||
bool is_transfer_unlocked(const transfer_details& td) const;
|
bool is_transfer_unlocked(const transfer_details& td) const;
|
||||||
bool is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height) const;
|
bool is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height) const;
|
||||||
|
|
||||||
|
|
|
@ -1613,7 +1613,7 @@ namespace tools
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_wallet->rescan_blockchain();
|
m_wallet->rescan_blockchain(req.hard);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -992,7 +992,10 @@ namespace wallet_rpc
|
||||||
{
|
{
|
||||||
struct request
|
struct request
|
||||||
{
|
{
|
||||||
|
bool hard;
|
||||||
|
|
||||||
BEGIN_KV_SERIALIZE_MAP()
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
|
KV_SERIALIZE_OPT(hard, false);
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue