mirror of
https://github.com/monero-project/monero.git
synced 2024-11-18 00:37:43 +00:00
wallet2: fix hash chain trimming when the inner chain becomes empty
It'd prevent further syncing. Recovery of empty hash chains is automatic, but requires a running daemon
This commit is contained in:
parent
5f7cddeb53
commit
37c12119ab
2 changed files with 30 additions and 2 deletions
|
@ -1100,7 +1100,10 @@ void wallet2::get_short_chain_history(std::list<crypto::hash>& ids) const
|
||||||
size_t current_multiplier = 1;
|
size_t current_multiplier = 1;
|
||||||
size_t sz = m_blockchain.size() - m_blockchain.offset();
|
size_t sz = m_blockchain.size() - m_blockchain.offset();
|
||||||
if(!sz)
|
if(!sz)
|
||||||
|
{
|
||||||
|
ids.push_back(m_blockchain.genesis());
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
size_t current_back_offset = 1;
|
size_t current_back_offset = 1;
|
||||||
bool base_included = false;
|
bool base_included = false;
|
||||||
while(current_back_offset < sz)
|
while(current_back_offset < sz)
|
||||||
|
@ -1205,6 +1208,7 @@ void wallet2::process_blocks(uint64_t start_height, const std::list<cryptonote::
|
||||||
size_t tx_o_indices_idx = 0;
|
size_t tx_o_indices_idx = 0;
|
||||||
|
|
||||||
THROW_WALLET_EXCEPTION_IF(blocks.size() != o_indices.size(), error::wallet_internal_error, "size mismatch");
|
THROW_WALLET_EXCEPTION_IF(blocks.size() != o_indices.size(), error::wallet_internal_error, "size mismatch");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(!m_blockchain.is_in_bounds(current_index), error::wallet_internal_error, "Index out of bounds of hashchain");
|
||||||
|
|
||||||
tools::threadpool& tpool = tools::threadpool::getInstance();
|
tools::threadpool& tpool = tools::threadpool::getInstance();
|
||||||
int threads = tpool.get_max_concurrency();
|
int threads = tpool.get_max_concurrency();
|
||||||
|
@ -2547,7 +2551,30 @@ void wallet2::load(const std::string& wallet_, const std::string& password)
|
||||||
void wallet2::trim_hashchain()
|
void wallet2::trim_hashchain()
|
||||||
{
|
{
|
||||||
uint64_t height = m_checkpoints.get_max_height();
|
uint64_t height = m_checkpoints.get_max_height();
|
||||||
if (height > 0)
|
if (!m_blockchain.empty() && m_blockchain.size() == m_blockchain.offset())
|
||||||
|
{
|
||||||
|
MINFO("Fixing empty hashchain");
|
||||||
|
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request> req = AUTO_VAL_INIT(req);
|
||||||
|
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response, std::string> res = AUTO_VAL_INIT(res);
|
||||||
|
m_daemon_rpc_mutex.lock();
|
||||||
|
req.jsonrpc = "2.0";
|
||||||
|
req.id = epee::serialization::storage_entry(0);
|
||||||
|
req.method = "getblockheaderbyheight";
|
||||||
|
req.params.height = m_blockchain.size() - 1;
|
||||||
|
bool r = net_utils::invoke_http_json("/json_rpc", req, res, m_http_client, rpc_timeout);
|
||||||
|
m_daemon_rpc_mutex.unlock();
|
||||||
|
if (r && res.result.status == CORE_RPC_STATUS_OK)
|
||||||
|
{
|
||||||
|
crypto::hash hash;
|
||||||
|
epee::string_tools::hex_to_pod(res.result.block_header.hash, hash);
|
||||||
|
m_blockchain.refill(hash);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MERROR("Failed to request block header from daemon, hash chain may be unable to sync till the wallet is loaded with a usable daemon");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (height > 0 && m_blockchain.size() > height)
|
||||||
{
|
{
|
||||||
--height;
|
--height;
|
||||||
MDEBUG("trimming to " << height << ", offset " << m_blockchain.offset());
|
MDEBUG("trimming to " << height << ", offset " << m_blockchain.offset());
|
||||||
|
|
|
@ -108,7 +108,8 @@ namespace tools
|
||||||
void crop(size_t height) { m_blockchain.resize(height - m_offset); }
|
void crop(size_t height) { m_blockchain.resize(height - m_offset); }
|
||||||
void clear() { m_offset = 0; m_blockchain.clear(); }
|
void clear() { m_offset = 0; m_blockchain.clear(); }
|
||||||
bool empty() const { return m_blockchain.empty() && m_offset == 0; }
|
bool empty() const { return m_blockchain.empty() && m_offset == 0; }
|
||||||
void trim(size_t height) { while (height > m_offset && !m_blockchain.empty()) { m_blockchain.pop_front(); ++m_offset; } m_blockchain.shrink_to_fit(); }
|
void trim(size_t height) { while (height > m_offset+1 && m_blockchain.size() > 1) { m_blockchain.pop_front(); ++m_offset; } m_blockchain.shrink_to_fit(); }
|
||||||
|
void refill(const crypto::hash &hash) { m_blockchain.push_back(hash); --m_offset; }
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Reference in a new issue