| 44 | } |
| 45 | |
| 46 | CBlockIndex* BlockManager::AddToBlockIndex(const CBlockHeader& block) |
| 47 | { |
| 48 | AssertLockHeld(cs_main); |
| 49 | |
| 50 | // Check for duplicate |
| 51 | uint256 hash = block.GetHash(); |
| 52 | BlockMap::iterator it = m_block_index.find(hash); |
| 53 | if (it != m_block_index.end()) { |
| 54 | return it->second; |
| 55 | } |
| 56 | |
| 57 | // Construct new block index object |
| 58 | CBlockIndex* pindexNew = new CBlockIndex(block); |
| 59 | // We assign the sequence id to blocks only when the full data is available, |
| 60 | // to avoid miners withholding blocks but broadcasting headers, to get a |
| 61 | // competitive advantage. |
| 62 | pindexNew->nSequenceId = 0; |
| 63 | BlockMap::iterator mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first; |
| 64 | pindexNew->phashBlock = &((*mi).first); |
| 65 | BlockMap::iterator miPrev = m_block_index.find(block.hashPrevBlock); |
| 66 | if (miPrev != m_block_index.end()) { |
| 67 | pindexNew->pprev = (*miPrev).second; |
| 68 | pindexNew->nHeight = pindexNew->pprev->nHeight + 1; |
| 69 | pindexNew->BuildSkip(); |
| 70 | } |
| 71 | pindexNew->nTimeMax = (pindexNew->pprev ? std::max(pindexNew->pprev->nTimeMax, pindexNew->nTime) : pindexNew->nTime); |
| 72 | pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew); |
| 73 | pindexNew->RaiseValidity(BLOCK_VALID_TREE); |
| 74 | if (pindexBestHeader == nullptr || pindexBestHeader->nChainWork < pindexNew->nChainWork) |
| 75 | pindexBestHeader = pindexNew; |
| 76 | |
| 77 | m_dirty_blockindex.insert(pindexNew); |
| 78 | |
| 79 | return pindexNew; |
| 80 | } |
| 81 | |
| 82 | void BlockManager::PruneOneBlockFile(const int fileNumber) |
| 83 | { |