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

View File

@@ -807,16 +807,18 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
{
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();
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<difficulty_type> difficulties;
auto height = m_db->height();
@@ -860,6 +862,8 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
}
size_t target = get_difficulty_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 = diff;
return diff;