mirror of
https://codeberg.org/anoncontributorxmr/monero.git
synced 2024-11-14 07:03:29 +01:00
Merge pull request #366
aa5bc35
wallet: new rescan_spent command to update outputs' spent status (moneromooo-monero)
This commit is contained in:
commit
5e68f97371
@ -364,6 +364,7 @@ simple_wallet::simple_wallet()
|
|||||||
m_cmd_binder.set_handler("spendkey", boost::bind(&simple_wallet::spendkey, this, _1), tr("Get spendkey"));
|
m_cmd_binder.set_handler("spendkey", boost::bind(&simple_wallet::spendkey, this, _1), tr("Get spendkey"));
|
||||||
m_cmd_binder.set_handler("seed", boost::bind(&simple_wallet::seed, this, _1), tr("Get deterministic seed"));
|
m_cmd_binder.set_handler("seed", boost::bind(&simple_wallet::seed, this, _1), tr("Get deterministic seed"));
|
||||||
m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), tr("available options: seed language - Set wallet seed langage; always-confirm-transfers <1|0> - whether to confirm unsplit txes"));
|
m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), tr("available options: seed language - Set wallet seed langage; always-confirm-transfers <1|0> - whether to confirm unsplit txes"));
|
||||||
|
m_cmd_binder.set_handler("rescan_spent", boost::bind(&simple_wallet::rescan_spent, this, _1), tr("Rescan blockchain for spent outputs"));
|
||||||
m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), tr("Show this help"));
|
m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), tr("Show this help"));
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
@ -1253,7 +1254,46 @@ bool simple_wallet::show_blockchain_height(const std::vector<std::string>& args)
|
|||||||
fail_msg_writer() << tr("failed to get blockchain height: ") << err;
|
fail_msg_writer() << tr("failed to get blockchain height: ") << err;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
bool simple_wallet::rescan_spent(const std::vector<std::string> &args)
|
||||||
|
{
|
||||||
|
if (!try_connect_to_daemon())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_wallet->rescan_spent();
|
||||||
|
}
|
||||||
|
catch (const tools::error::daemon_busy&)
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("daemon is busy. Please try later");
|
||||||
|
}
|
||||||
|
catch (const tools::error::no_connection_to_daemon&)
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("no connection to daemon. Please, make sure daemon is running.");
|
||||||
|
}
|
||||||
|
catch (const tools::error::is_key_image_spent_error&)
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("failed to get spent status");
|
||||||
|
}
|
||||||
|
catch (const tools::error::wallet_rpc_error& e)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Unknown RPC error: " << e.to_string());
|
||||||
|
fail_msg_writer() << tr("RPC error: ") << e.what();
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
LOG_ERROR("unexpected error: " << e.what());
|
||||||
|
fail_msg_writer() << tr("unexpected error: ") << e.what();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Unknown error");
|
||||||
|
fail_msg_writer() << tr("unknown error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool simple_wallet::transfer_main(bool new_algorithm, const std::vector<std::string> &args_)
|
bool simple_wallet::transfer_main(bool new_algorithm, const std::vector<std::string> &args_)
|
||||||
{
|
{
|
||||||
|
@ -120,6 +120,7 @@ namespace cryptonote
|
|||||||
bool save(const std::vector<std::string> &args);
|
bool save(const std::vector<std::string> &args);
|
||||||
bool save_watch_only(const std::vector<std::string> &args);
|
bool save_watch_only(const std::vector<std::string> &args);
|
||||||
bool set_variable(const std::vector<std::string> &args);
|
bool set_variable(const std::vector<std::string> &args);
|
||||||
|
bool rescan_spent(const std::vector<std::string> &args);
|
||||||
bool set_log(const std::vector<std::string> &args);
|
bool set_log(const std::vector<std::string> &args);
|
||||||
|
|
||||||
uint64_t get_daemon_blockchain_height(std::string& err);
|
uint64_t get_daemon_blockchain_height(std::string& err);
|
||||||
|
@ -961,6 +961,47 @@ void wallet2::get_payments(std::list<std::pair<crypto::hash,wallet2::payment_det
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
void wallet2::rescan_spent()
|
||||||
|
{
|
||||||
|
std::vector<std::string> key_images;
|
||||||
|
|
||||||
|
// make a list of key images for all our outputs
|
||||||
|
for (size_t i = 0; i < m_transfers.size(); ++i)
|
||||||
|
{
|
||||||
|
const transfer_details& td = m_transfers[i];
|
||||||
|
key_images.push_back(string_tools::pod_to_hex(td.m_key_image));
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMAND_RPC_IS_KEY_IMAGE_SPENT::request req = AUTO_VAL_INIT(req);
|
||||||
|
COMMAND_RPC_IS_KEY_IMAGE_SPENT::response daemon_resp = AUTO_VAL_INIT(daemon_resp);
|
||||||
|
req.key_images = key_images;
|
||||||
|
bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/is_key_image_spent", req, daemon_resp, m_http_client, 200000);
|
||||||
|
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "is_key_image_spent");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "is_key_image_spent");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(daemon_resp.status != CORE_RPC_STATUS_OK, error::is_key_image_spent_error, daemon_resp.status);
|
||||||
|
THROW_WALLET_EXCEPTION_IF(daemon_resp.spent_status.size() != key_images.size(), error::wallet_internal_error,
|
||||||
|
"daemon returned wrong response for is_key_image_spent, wrong amounts count = " +
|
||||||
|
std::to_string(daemon_resp.spent_status.size()) + ", expected " + std::to_string(key_images.size()));
|
||||||
|
|
||||||
|
// update spent status
|
||||||
|
for (size_t i = 0; i < m_transfers.size(); ++i)
|
||||||
|
{
|
||||||
|
transfer_details& td = m_transfers[i];
|
||||||
|
if (td.m_spent != daemon_resp.spent_status[i])
|
||||||
|
{
|
||||||
|
if (td.m_spent)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L1("Marking output " << i << " as unspent, it was marked as spent");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L1("Marking output " << i << " as spent, it was marked as unspent");
|
||||||
|
}
|
||||||
|
td.m_spent = daemon_resp.spent_status[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool wallet2::is_transfer_unlocked(const transfer_details& td) const
|
bool wallet2::is_transfer_unlocked(const transfer_details& td) const
|
||||||
{
|
{
|
||||||
if(!is_tx_spendtime_unlocked(td.m_tx.unlock_time))
|
if(!is_tx_spendtime_unlocked(td.m_tx.unlock_time))
|
||||||
|
@ -235,6 +235,7 @@ namespace tools
|
|||||||
void get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments, uint64_t min_height = 0) const;
|
void get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments, uint64_t min_height = 0) const;
|
||||||
void get_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& payments, uint64_t min_height) const;
|
void get_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& payments, uint64_t min_height) const;
|
||||||
uint64_t get_blockchain_current_height() const { return m_local_bc_height; }
|
uint64_t get_blockchain_current_height() const { return m_local_bc_height; }
|
||||||
|
void rescan_spent();
|
||||||
template <class t_archive>
|
template <class t_archive>
|
||||||
inline void serialize(t_archive &a, const unsigned int ver)
|
inline void serialize(t_archive &a, const unsigned int ver)
|
||||||
{
|
{
|
||||||
|
@ -73,6 +73,7 @@ namespace tools
|
|||||||
// wallet_rpc_error *
|
// wallet_rpc_error *
|
||||||
// daemon_busy
|
// daemon_busy
|
||||||
// no_connection_to_daemon
|
// no_connection_to_daemon
|
||||||
|
// is_key_image_spent_error
|
||||||
// wallet_files_doesnt_correspond
|
// wallet_files_doesnt_correspond
|
||||||
//
|
//
|
||||||
// * - class with protected ctor
|
// * - class with protected ctor
|
||||||
@ -574,6 +575,14 @@ namespace tools
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
struct is_key_image_spent_error : public wallet_rpc_error
|
||||||
|
{
|
||||||
|
explicit is_key_image_spent_error(std::string&& loc, const std::string& request)
|
||||||
|
: wallet_rpc_error(std::move(loc), "error from is_key_image_spent call", request)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
struct wallet_files_doesnt_correspond : public wallet_logic_error
|
struct wallet_files_doesnt_correspond : public wallet_logic_error
|
||||||
{
|
{
|
||||||
explicit wallet_files_doesnt_correspond(std::string&& loc, const std::string& keys_file, const std::string& wallet_file)
|
explicit wallet_files_doesnt_correspond(std::string&& loc, const std::string& keys_file, const std::string& wallet_file)
|
||||||
|
Loading…
Reference in New Issue
Block a user