blockstorage: Make m_block_index own CBlockIndex's

Instead of having CBlockIndex's live on the heap, which requires manual
memory management, have them be owned by m_block_index. This means that
they will live and die with BlockManager.

A change to BlockManager::LookupBlockIndex:
- Previously, it was a const member function returning a non-const CBlockIndex*
- Now, there's are const and non-const versions of
  BlockManager::LookupBlockIndex returning a CBlockIndex with the same
  const-ness as the member function:
    (e.g. const CBlockIndex* LookupBlockIndex(...) const)

See next commit for some weirdness that this eliminates.

The range based for-loops are modernize (using auto + destructuring) in
a future commit.
This commit is contained in:
Carl Dong
2021-01-08 18:56:48 -05:00
parent c44e734dca
commit bec86ae326
5 changed files with 58 additions and 47 deletions

View File

@@ -32,11 +32,18 @@ static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false);
static FlatFileSeq BlockFileSeq();
static FlatFileSeq UndoFileSeq();
CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash) const
CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash)
{
AssertLockHeld(cs_main);
BlockMap::iterator it = m_block_index.find(hash);
return it == m_block_index.end() ? nullptr : &it->second;
}
const CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash) const
{
AssertLockHeld(cs_main);
BlockMap::const_iterator it = m_block_index.find(hash);
return it == m_block_index.end() ? nullptr : it->second;
return it == m_block_index.end() ? nullptr : &it->second;
}
CBlockIndex* BlockManager::AddToBlockIndex(const CBlockHeader& block)
@@ -47,20 +54,22 @@ CBlockIndex* BlockManager::AddToBlockIndex(const CBlockHeader& block)
uint256 hash = block.GetHash();
BlockMap::iterator it = m_block_index.find(hash);
if (it != m_block_index.end()) {
return it->second;
return &it->second;
}
// Construct new block index object
CBlockIndex* pindexNew = new CBlockIndex(block);
CBlockIndex new_index{block};
// We assign the sequence id to blocks only when the full data is available,
// to avoid miners withholding blocks but broadcasting headers, to get a
// competitive advantage.
pindexNew->nSequenceId = 0;
BlockMap::iterator mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
new_index.nSequenceId = 0;
BlockMap::iterator mi = m_block_index.insert(std::make_pair(hash, std::move(new_index))).first;
CBlockIndex* pindexNew = &(*mi).second;
pindexNew->phashBlock = &((*mi).first);
BlockMap::iterator miPrev = m_block_index.find(block.hashPrevBlock);
if (miPrev != m_block_index.end()) {
pindexNew->pprev = (*miPrev).second;
pindexNew->pprev = &(*miPrev).second;
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
pindexNew->BuildSkip();
}
@@ -80,8 +89,8 @@ void BlockManager::PruneOneBlockFile(const int fileNumber)
AssertLockHeld(cs_main);
LOCK(cs_LastBlockFile);
for (const auto& entry : m_block_index) {
CBlockIndex* pindex = entry.second;
for (auto& entry : m_block_index) {
CBlockIndex* pindex = &entry.second;
if (pindex->nFile == fileNumber) {
pindex->nStatus &= ~BLOCK_HAVE_DATA;
pindex->nStatus &= ~BLOCK_HAVE_UNDO;
@@ -202,12 +211,13 @@ CBlockIndex* BlockManager::InsertBlockIndex(const uint256& hash)
// Return existing
BlockMap::iterator mi = m_block_index.find(hash);
if (mi != m_block_index.end()) {
return (*mi).second;
return &(*mi).second;
}
// Create new
CBlockIndex* pindexNew = new CBlockIndex();
mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
CBlockIndex new_index{};
mi = m_block_index.insert(std::make_pair(hash, std::move(new_index))).first;
CBlockIndex* pindexNew = &(*mi).second;
pindexNew->phashBlock = &((*mi).first);
return pindexNew;
@@ -224,8 +234,8 @@ bool BlockManager::LoadBlockIndex(
// Calculate nChainWork
std::vector<std::pair<int, CBlockIndex*>> vSortedByHeight;
vSortedByHeight.reserve(m_block_index.size());
for (const std::pair<const uint256, CBlockIndex*>& item : m_block_index) {
CBlockIndex* pindex = item.second;
for (std::pair<const uint256, CBlockIndex>& item : m_block_index) {
CBlockIndex* pindex = &item.second;
vSortedByHeight.push_back(std::make_pair(pindex->nHeight, pindex));
}
sort(vSortedByHeight.begin(), vSortedByHeight.end());
@@ -327,10 +337,6 @@ void BlockManager::Unload()
{
m_blocks_unlinked.clear();
for (const BlockMap::value_type& entry : m_block_index) {
delete entry.second;
}
m_block_index.clear();
m_blockfile_info.clear();
@@ -386,8 +392,8 @@ bool BlockManager::LoadBlockIndexDB(ChainstateManager& chainman)
// Check presence of blk files
LogPrintf("Checking all blk files are present...\n");
std::set<int> setBlkDataFiles;
for (const std::pair<const uint256, CBlockIndex*>& item : m_block_index) {
CBlockIndex* pindex = item.second;
for (const std::pair<const uint256, CBlockIndex>& item : m_block_index) {
const CBlockIndex* pindex = &item.second;
if (pindex->nStatus & BLOCK_HAVE_DATA) {
setBlkDataFiles.insert(pindex->nFile);
}