diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2015-08-11 15:14:44 +0100 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2015-08-11 15:55:08 +0100 |
commit | aa5bc351d422fd31e66e01a46b166952ef91e958 (patch) | |
tree | fb9c68c64665c1a37075ac8f34e70ef8ff6fb826 /src/wallet | |
parent | Merge pull request #365 (diff) | |
download | monero-aa5bc351d422fd31e66e01a46b166952ef91e958.tar.xz |
wallet: new rescan_spent command to update outputs' spent status
This obsoletes the need for a lengthy blockchain rescan when
a transaction doesn't end up in the chain after being accepted
by the daemon, or any other reason why the wallet's idea of
spent and unspent outputs gets out of sync from the blockchain's.
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/wallet2.cpp | 41 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 1 | ||||
-rw-r--r-- | src/wallet/wallet_errors.h | 9 |
3 files changed, 51 insertions, 0 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 3d3f1e4de..11ea4678a 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -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 { if(!is_tx_spendtime_unlocked(td.m_tx.unlock_time)) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index eee6aa58c..ffe9ad0e5 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -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(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; } + void rescan_spent(); template <class t_archive> inline void serialize(t_archive &a, const unsigned int ver) { diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index bf520c36c..94518e691 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -73,6 +73,7 @@ namespace tools // wallet_rpc_error * // daemon_busy // no_connection_to_daemon + // is_key_image_spent_error // wallet_files_doesnt_correspond // // * - 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 { explicit wallet_files_doesnt_correspond(std::string&& loc, const std::string& keys_file, const std::string& wallet_file) |