core: faster find_blockchain_supplement

Since this queries block heights for blocks that may or may not
exist, queries for non existing blocks would throw an exception,
and that would slow down the loop a lot. 7 seconds to go through
a 30 hash list.

Fix this by adding an optional return block height to block_exists
and using this instead. Actual errors will still throw an
exception.

This also cuts down on log exception spam.
This commit is contained in:
moneromooo-monero 2016-08-30 16:39:33 +01:00
parent c3ba844f03
commit 6cf8ca2a7f
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
7 changed files with 19 additions and 12 deletions

View file

@ -1235,7 +1235,7 @@ void BlockchainBDB::unlock()
check_open(); check_open();
} }
bool BlockchainBDB::block_exists(const crypto::hash& h) const bool BlockchainBDB::block_exists(const crypto::hash& h, uint64_t *height) const
{ {
LOG_PRINT_L3("BlockchainBDB::" << __func__); LOG_PRINT_L3("BlockchainBDB::" << __func__);
check_open(); check_open();
@ -1251,6 +1251,9 @@ bool BlockchainBDB::block_exists(const crypto::hash& h) const
else if (get_result) else if (get_result)
throw0(DB_ERROR("DB error attempting to fetch block index from hash")); throw0(DB_ERROR("DB error attempting to fetch block index from hash"));
if (height)
*height = get_result - 1;
return true; return true;
} }

View file

@ -250,7 +250,7 @@ public:
virtual void unlock(); virtual void unlock();
virtual bool block_exists(const crypto::hash& h) const; virtual bool block_exists(const crypto::hash& h, uint64_t *height = NULL) const;
virtual block get_block(const crypto::hash& h) const; virtual block get_block(const crypto::hash& h) const;

View file

@ -736,10 +736,11 @@ public:
* @brief checks if a block exists * @brief checks if a block exists
* *
* @param h the hash of the requested block * @param h the hash of the requested block
* @param height if non NULL, returns the block's height if found
* *
* @return true of the block exists, otherwise false * @return true of the block exists, otherwise false
*/ */
virtual bool block_exists(const crypto::hash& h) const = 0; virtual bool block_exists(const crypto::hash& h, uint64_t *height = NULL) const = 0;
/** /**
* @brief fetches the block with the given hash * @brief fetches the block with the given hash

View file

@ -1387,7 +1387,7 @@ void BlockchainLMDB::unlock()
auto_txn.commit(); \ auto_txn.commit(); \
} while(0) } while(0)
bool BlockchainLMDB::block_exists(const crypto::hash& h) const bool BlockchainLMDB::block_exists(const crypto::hash& h, uint64_t *height) const
{ {
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open(); check_open();
@ -1405,7 +1405,14 @@ bool BlockchainLMDB::block_exists(const crypto::hash& h) const
else if (get_result) else if (get_result)
throw0(DB_ERROR(lmdb_error("DB error attempting to fetch block index from hash", get_result).c_str())); throw0(DB_ERROR(lmdb_error("DB error attempting to fetch block index from hash", get_result).c_str()));
else else
{
if (height)
{
const blk_height *bhp = (const blk_height *)key.mv_data;
*height = bhp->bh_height;
}
ret = true; ret = true;
}
TXN_POSTFIX_RDONLY(); TXN_POSTFIX_RDONLY();
return ret; return ret;

View file

@ -168,7 +168,7 @@ public:
virtual void unlock(); virtual void unlock();
virtual bool block_exists(const crypto::hash& h) const; virtual bool block_exists(const crypto::hash& h, uint64_t *height = NULL) const;
virtual block get_block(const crypto::hash& h) const; virtual block get_block(const crypto::hash& h) const;

View file

@ -1801,12 +1801,8 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc
{ {
try try
{ {
split_height = m_db->get_block_height(*bl_it); if (m_db->block_exists(*bl_it, &split_height))
break; break;
}
catch (const BLOCK_DNE& e)
{
continue;
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {

View file

@ -58,7 +58,7 @@ public:
virtual void block_txn_stop() {} virtual void block_txn_stop() {}
virtual void block_txn_abort() {} virtual void block_txn_abort() {}
virtual void drop_hard_fork_info() {} virtual void drop_hard_fork_info() {}
virtual bool block_exists(const crypto::hash& h) const { return false; } virtual bool block_exists(const crypto::hash& h, uint64_t *height) const { return false; }
virtual block get_block(const crypto::hash& h) const { return block(); } virtual block get_block(const crypto::hash& h) const { return block(); }
virtual uint64_t get_block_height(const crypto::hash& h) const { return 0; } virtual uint64_t get_block_height(const crypto::hash& h) const { return 0; }
virtual block_header get_block_header(const crypto::hash& h) const { return block_header(); } virtual block_header get_block_header(const crypto::hash& h) const { return block_header(); }