blockchain: cache difficulty for next block
Takes about 10 ms, which takes pretty much all of the get_info RPC, which is called pretty often from wallets. Also add a new lock so we don't need to lock the blockchain lock, which will avoid blocking for a long time when calling the getinfo RPC while syncing. Users of get_difficulty_for_next_block who need the lock will have locked it already.
This commit is contained in:
parent
5710edf040
commit
a6a54fa883
|
@ -156,7 +156,9 @@ static const struct {
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
Blockchain::Blockchain(tx_memory_pool& tx_pool) :
|
Blockchain::Blockchain(tx_memory_pool& tx_pool) :
|
||||||
m_db(), m_tx_pool(tx_pool), m_hardfork(NULL), m_timestamps_and_difficulties_height(0), m_current_block_cumul_sz_limit(0), m_current_block_cumul_sz_median(0),
|
m_db(), m_tx_pool(tx_pool), m_hardfork(NULL), m_timestamps_and_difficulties_height(0), m_current_block_cumul_sz_limit(0), m_current_block_cumul_sz_median(0),
|
||||||
m_enforce_dns_checkpoints(false), m_max_prepare_blocks_threads(4), m_db_blocks_per_sync(1), m_db_sync_mode(db_async), m_db_default_sync(false), m_fast_sync(true), m_show_time_stats(false), m_sync_counter(0), m_cancel(false)
|
m_enforce_dns_checkpoints(false), m_max_prepare_blocks_threads(4), m_db_blocks_per_sync(1), m_db_sync_mode(db_async), m_db_default_sync(false), m_fast_sync(true), m_show_time_stats(false), m_sync_counter(0), m_cancel(false),
|
||||||
|
m_difficulty_for_next_block_top_hash(crypto::null_hash),
|
||||||
|
m_difficulty_for_next_block(1)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||||
}
|
}
|
||||||
|
@ -751,7 +753,17 @@ bool Blockchain::get_block_by_hash(const crypto::hash &h, block &blk, bool *orph
|
||||||
difficulty_type Blockchain::get_difficulty_for_next_block()
|
difficulty_type Blockchain::get_difficulty_for_next_block()
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
|
||||||
|
CRITICAL_REGION_LOCAL(m_difficulty_lock);
|
||||||
|
// we can call this without the blockchain lock, it might just give us
|
||||||
|
// something a bit out of date, but that's fine since anything which
|
||||||
|
// requires the blockchain lock will have acquired it in the first place,
|
||||||
|
// and it will be unlocked only when called from the getinfo RPC
|
||||||
|
crypto::hash top_hash = get_tail_id();
|
||||||
|
if (top_hash == m_difficulty_for_next_block_top_hash)
|
||||||
|
return m_difficulty_for_next_block;
|
||||||
|
|
||||||
|
CRITICAL_REGION_LOCAL1(m_blockchain_lock);
|
||||||
std::vector<uint64_t> timestamps;
|
std::vector<uint64_t> timestamps;
|
||||||
std::vector<difficulty_type> difficulties;
|
std::vector<difficulty_type> difficulties;
|
||||||
auto height = m_db->height();
|
auto height = m_db->height();
|
||||||
|
@ -794,7 +806,10 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
|
||||||
m_difficulties = difficulties;
|
m_difficulties = difficulties;
|
||||||
}
|
}
|
||||||
size_t target = get_difficulty_target();
|
size_t target = get_difficulty_target();
|
||||||
return next_difficulty(timestamps, difficulties, target);
|
difficulty_type diff = next_difficulty(timestamps, difficulties, target);
|
||||||
|
m_difficulty_for_next_block_top_hash = top_hash;
|
||||||
|
m_difficulty_for_next_block = diff;
|
||||||
|
return diff;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// This function removes blocks from the blockchain until it gets to the
|
// This function removes blocks from the blockchain until it gets to the
|
||||||
|
|
|
@ -1006,6 +1006,10 @@ namespace cryptonote
|
||||||
std::vector<difficulty_type> m_difficulties;
|
std::vector<difficulty_type> m_difficulties;
|
||||||
uint64_t m_timestamps_and_difficulties_height;
|
uint64_t m_timestamps_and_difficulties_height;
|
||||||
|
|
||||||
|
epee::critical_section m_difficulty_lock;
|
||||||
|
crypto::hash m_difficulty_for_next_block_top_hash;
|
||||||
|
difficulty_type m_difficulty_for_next_block;
|
||||||
|
|
||||||
boost::asio::io_service m_async_service;
|
boost::asio::io_service m_async_service;
|
||||||
boost::thread_group m_async_pool;
|
boost::thread_group m_async_pool;
|
||||||
std::unique_ptr<boost::asio::io_service::work> m_async_work_idle;
|
std::unique_ptr<boost::asio::io_service::work> m_async_work_idle;
|
||||||
|
|
Loading…
Reference in New Issue