diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index ad4cd562..b8586bf1 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -551,6 +551,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("get_tx_key", boost::bind(&simple_wallet::get_tx_key, this, _1), tr("Get transaction key (r) for a given ")); m_cmd_binder.set_handler("check_tx_key", boost::bind(&simple_wallet::check_tx_key, this, _1), tr("Check amount going to
in ")); m_cmd_binder.set_handler("show_transfers", boost::bind(&simple_wallet::show_transfers, this, _1), tr("show_transfers [in|out] [ []] - Show incoming/outgoing transfers within an optional height range")); + m_cmd_binder.set_handler("rescan_bc", boost::bind(&simple_wallet::rescan_blockchain, this, _1), tr("Rescan blockchain from scratch")); m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), tr("Show this help")); } //---------------------------------------------------------------------------------------------------- @@ -1324,7 +1325,7 @@ void simple_wallet::on_skip_transaction(uint64_t height, const cryptonote::trans m_refresh_progress_reporter.update(height, true); } //---------------------------------------------------------------------------------------------------- -bool simple_wallet::refresh(const std::vector& args) +bool simple_wallet::refresh_main(uint64_t start_height, bool reset) { if (!try_connect_to_daemon()) return true; @@ -1336,21 +1337,12 @@ bool simple_wallet::refresh(const std::vector& args) std::unique_lock lock(m_auto_refresh_mutex); m_auto_refresh_cond.notify_one(); + if (reset) + m_wallet->rescan_blockchain(false); + message_writer() << tr("Starting refresh..."); uint64_t fetched_blocks = 0; - uint64_t start_height = 0; - if(!args.empty()){ - try - { - start_height = boost::lexical_cast( args[0] ); - } - catch(const boost::bad_lexical_cast &) - { - start_height = 0; - } - } - bool ok = false; std::ostringstream ss; try @@ -1408,6 +1400,22 @@ bool simple_wallet::refresh(const std::vector& args) return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::refresh(const std::vector& args) +{ + uint64_t start_height = 0; + if(!args.empty()){ + try + { + start_height = boost::lexical_cast( args[0] ); + } + catch(const boost::bad_lexical_cast &) + { + start_height = 0; + } + } + return refresh_main(start_height, false); +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::show_balance(const std::vector& args/* = std::vector()*/) { success_msg_writer() << tr("Balance: ") << print_money(m_wallet->balance()) << ", " @@ -2276,6 +2284,11 @@ bool simple_wallet::show_transfers(const std::vector &args_) return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::rescan_blockchain(const std::vector &args_) +{ + return refresh_main(0, true); +} +//---------------------------------------------------------------------------------------------------- void simple_wallet::wallet_refresh_thread() { while (true) diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index ef44d537..486e197a 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -132,6 +132,8 @@ namespace cryptonote bool get_tx_key(const std::vector &args); bool check_tx_key(const std::vector &args); bool show_transfers(const std::vector &args); + bool rescan_blockchain(const std::vector &args); + bool refresh_main(uint64_t start_height, bool reset = false); uint64_t get_daemon_blockchain_height(std::string& err); bool try_connect_to_daemon(); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 19b598af..e58629da 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -801,6 +801,7 @@ bool wallet2::clear() { m_blockchain.clear(); m_transfers.clear(); + m_key_images.clear(); m_local_bc_height = 1; return true; } @@ -1431,6 +1432,20 @@ void wallet2::rescan_spent() } } //---------------------------------------------------------------------------------------------------- +void wallet2::rescan_blockchain(bool refresh) +{ + clear(); + + cryptonote::block genesis; + generate_genesis(genesis); + crypto::hash genesis_hash = get_block_hash(genesis); + m_blockchain.push_back(genesis_hash); + m_local_bc_height = 1; + + if (refresh) + this->refresh(); +} +//---------------------------------------------------------------------------------------------------- bool wallet2::is_transfer_unlocked(const transfer_details& td) const { if(!is_tx_spendtime_unlocked(td.m_tx.unlock_time)) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 77a9fd18..88a5268b 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -280,6 +280,7 @@ namespace tools void get_unconfirmed_payments_out(std::list>& unconfirmed_payments) const; uint64_t get_blockchain_current_height() const { return m_local_bc_height; } void rescan_spent(); + void rescan_blockchain(bool refresh = true); template inline void serialize(t_archive &a, const unsigned int ver) { diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 0c1ea48c..9f23908f 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -646,6 +646,29 @@ namespace tools return true; } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_rescan_blockchain(const wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::request& req, wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::response& res, epee::json_rpc::error& er) + { + if (m_wallet.restricted()) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + + try + { + m_wallet.rescan_blockchain(); + } + catch (std::exception& e) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = e.what(); + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_stop_wallet(const wallet_rpc::COMMAND_RPC_STOP_WALLET::request& req, wallet_rpc::COMMAND_RPC_STOP_WALLET::response& res, epee::json_rpc::error& er) { if (m_wallet.restricted()) diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 97b84fcb..fbc2c29c 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -75,6 +75,7 @@ namespace tools MAP_JON_RPC_WE("make_integrated_address", on_make_integrated_address, wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS) MAP_JON_RPC_WE("split_integrated_address", on_split_integrated_address, wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS) MAP_JON_RPC_WE("stop_wallet", on_stop_wallet, wallet_rpc::COMMAND_RPC_STOP_WALLET) + MAP_JON_RPC_WE("rescan_blockchain", on_rescan_blockchain, wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN) END_JSON_RPC_MAP() END_URI_MAP2() @@ -93,6 +94,7 @@ namespace tools bool on_get_bulk_payments(const wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::response& res, epee::json_rpc::error& er); bool on_incoming_transfers(const wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::response& res, epee::json_rpc::error& er); bool on_stop_wallet(const wallet_rpc::COMMAND_RPC_STOP_WALLET::request& req, wallet_rpc::COMMAND_RPC_STOP_WALLET::response& res, epee::json_rpc::error& er); + bool on_rescan_blockchain(const wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::request& req, wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::response& res, epee::json_rpc::error& er); bool handle_command_line(const boost::program_options::variables_map& vm); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index a20c8b96..1e1482c1 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -391,6 +391,21 @@ namespace wallet_rpc }; }; + struct COMMAND_RPC_RESCAN_BLOCKCHAIN + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + }; + } }