Fixed pruning logic

- Erase an element from m_blocksByHeight only if it's empty
- Remove blocks from unconnected alternative chains too when they get old enough (4xPPLNS window)
pull/5/head
SChernykh 3 years ago
parent d4388bf9c0
commit e4be4c1a66

@ -52,6 +52,7 @@ PoolBlock::PoolBlock()
, m_invalid(false) , m_invalid(false)
, m_broadcasted(false) , m_broadcasted(false)
, m_wantBroadcast(false) , m_wantBroadcast(false)
, m_localTimestamp(time(nullptr))
{ {
uv_mutex_init_checked(&m_lock); uv_mutex_init_checked(&m_lock);
@ -114,6 +115,8 @@ PoolBlock& PoolBlock::operator=(const PoolBlock& b)
m_broadcasted = b.m_broadcasted; m_broadcasted = b.m_broadcasted;
m_wantBroadcast = b.m_wantBroadcast; m_wantBroadcast = b.m_wantBroadcast;
m_localTimestamp = time(nullptr);
if (lock_result == 0) { if (lock_result == 0) {
uv_mutex_unlock(&b.m_lock); uv_mutex_unlock(&b.m_lock);
} }

@ -131,6 +131,8 @@ struct PoolBlock
bool m_broadcasted; bool m_broadcasted;
bool m_wantBroadcast; bool m_wantBroadcast;
time_t m_localTimestamp;
void serialize_mainchain_data(uint32_t nonce, uint32_t extra_nonce, const hash& sidechain_hash); void serialize_mainchain_data(uint32_t nonce, uint32_t extra_nonce, const hash& sidechain_hash);
void serialize_sidechain_data(); void serialize_sidechain_data();

@ -343,6 +343,8 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, SideChain& sidechai
m_broadcasted = false; m_broadcasted = false;
m_wantBroadcast = false; m_wantBroadcast = false;
m_localTimestamp = time(nullptr);
return 0; return 0;
} }

@ -1368,6 +1368,9 @@ void SideChain::prune_old_blocks()
// Leave 2 minutes worth of spare blocks in addition to 2xPPLNS window for lagging nodes which need to sync // Leave 2 minutes worth of spare blocks in addition to 2xPPLNS window for lagging nodes which need to sync
const uint64_t prune_distance = m_chainWindowSize * 2 + 120 / m_targetBlockTime; const uint64_t prune_distance = m_chainWindowSize * 2 + 120 / m_targetBlockTime;
// Remove old blocks from alternative unconnected chains after long enough time
const time_t prune_time = time(nullptr) - m_chainWindowSize * 4 * m_targetBlockTime;
if (m_chainTip->m_sidechainHeight < prune_distance) { if (m_chainTip->m_sidechainHeight < prune_distance) {
return; return;
} }
@ -1377,24 +1380,35 @@ void SideChain::prune_old_blocks()
uint64_t num_blocks_pruned = 0; uint64_t num_blocks_pruned = 0;
for (auto it = m_blocksByHeight.begin(); (it != m_blocksByHeight.end()) && (it->first <= h);) { for (auto it = m_blocksByHeight.begin(); (it != m_blocksByHeight.end()) && (it->first <= h);) {
for (PoolBlock* block : it->second) { const uint64_t height = it->first;
if (block->m_depth < prune_distance) { std::vector<PoolBlock*>& v = it->second;
continue;
} v.erase(std::remove_if(v.begin(), v.end(),
auto it2 = m_blocksById.find(block->m_sidechainId); [this, prune_distance, prune_time, &num_blocks_pruned, height](PoolBlock* block)
if (it2 != m_blocksById.end()) { {
m_blocksById.erase(it2); if ((block->m_depth >= prune_distance) || (block->m_localTimestamp <= prune_time)) {
delete block; auto it2 = m_blocksById.find(block->m_sidechainId);
++num_blocks_pruned; if (it2 != m_blocksById.end()) {
} m_blocksById.erase(it2);
else { delete block;
LOGERR(1, "m_blocksByHeight and m_blocksById are inconsistent at height " << it->first << ". Fix the code!"); ++num_blocks_pruned;
} }
} else {
LOGERR(1, "m_blocksByHeight and m_blocksById are inconsistent at height " << height << ". Fix the code!");
}
return true;
}
return false;
}), v.end());
auto old_it = it; if (v.empty()) {
++it; auto old_it = it;
m_blocksByHeight.erase(old_it); ++it;
m_blocksByHeight.erase(old_it);
}
else {
++it;
}
} }
if (num_blocks_pruned) { if (num_blocks_pruned) {

Loading…
Cancel
Save