diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2018-03-17 10:15:33 +0000 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2018-03-19 09:05:40 +0000 |
commit | a6a54fa883996b1bfb33e737b979add1a143324c (patch) | |
tree | e29d5fc04bf6cffd793848bdaa34fa4605f06dfa /src | |
parent | Merge pull request #3429 (diff) | |
download | monero-a6a54fa883996b1bfb33e737b979add1a143324c.tar.xz |
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.
Diffstat (limited to '')
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 21 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.h | 4 |
2 files changed, 22 insertions, 3 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 3db516847..0a1221a61 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -156,7 +156,9 @@ static const struct { //------------------------------------------------------------------ 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_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__); } @@ -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() { 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<difficulty_type> difficulties; auto height = m_db->height(); @@ -794,7 +806,10 @@ difficulty_type Blockchain::get_difficulty_for_next_block() m_difficulties = difficulties; } 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 diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 4423199de..70f616544 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -1006,6 +1006,10 @@ namespace cryptonote std::vector<difficulty_type> m_difficulties; 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::thread_group m_async_pool; std::unique_ptr<boost::asio::io_service::work> m_async_work_idle; |