blockchain: fix deadlock with the difficulty cache

This commit is contained in:
moneromooo-monero 2018-06-06 10:37:26 +01:00
parent 8a7b3ff138
commit f24cbc5245
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3

View file

@ -807,16 +807,18 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
{ {
LOG_PRINT_L3("Blockchain::" << __func__); LOG_PRINT_L3("Blockchain::" << __func__);
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(); 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_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
if (top_hash == m_difficulty_for_next_block_top_hash)
return m_difficulty_for_next_block;
}
CRITICAL_REGION_LOCAL1(m_blockchain_lock); CRITICAL_REGION_LOCAL(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();
@ -860,6 +862,8 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
} }
size_t target = get_difficulty_target(); size_t target = get_difficulty_target();
difficulty_type diff = next_difficulty(timestamps, difficulties, target); difficulty_type diff = next_difficulty(timestamps, difficulties, target);
CRITICAL_REGION_LOCAL1(m_difficulty_lock);
m_difficulty_for_next_block_top_hash = top_hash; m_difficulty_for_next_block_top_hash = top_hash;
m_difficulty_for_next_block = diff; m_difficulty_for_next_block = diff;
return diff; return diff;