| 222 | } |
| 223 | |
| 224 | CBlockIndex* BlockManager::AddToBlockIndex(const CBlockHeader& block, CBlockIndex*& best_header) |
| 225 | { |
| 226 | AssertLockHeld(cs_main); |
| 227 | |
| 228 | auto [mi, inserted] = m_block_index.try_emplace(block.GetHash(), block); |
| 229 | if (!inserted) { |
| 230 | return &mi->second; |
| 231 | } |
| 232 | CBlockIndex* pindexNew = &(*mi).second; |
| 233 | |
| 234 | // We assign the sequence id to blocks only when the full data is available, |
| 235 | // to avoid miners withholding blocks but broadcasting headers, to get a |
| 236 | // competitive advantage. |
| 237 | pindexNew->nSequenceId = SEQ_ID_INIT_FROM_DISK; |
| 238 | |
| 239 | pindexNew->phashBlock = &((*mi).first); |
| 240 | BlockMap::iterator miPrev = m_block_index.find(block.hashPrevBlock); |
| 241 | if (miPrev != m_block_index.end()) { |
| 242 | pindexNew->pprev = &(*miPrev).second; |
| 243 | pindexNew->nHeight = pindexNew->pprev->nHeight + 1; |
| 244 | pindexNew->BuildSkip(); |
| 245 | } |
| 246 | pindexNew->nTimeMax = (pindexNew->pprev ? std::max(pindexNew->pprev->nTimeMax, pindexNew->nTime) : pindexNew->nTime); |
| 247 | pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew); |
| 248 | pindexNew->RaiseValidity(BLOCK_VALID_TREE); |
| 249 | if (best_header == nullptr || best_header->nChainWork < pindexNew->nChainWork) { |
| 250 | best_header = pindexNew; |
| 251 | } |
| 252 | |
| 253 | m_dirty_blockindex.insert(pindexNew); |
| 254 | |
| 255 | return pindexNew; |
| 256 | } |
| 257 | |
| 258 | void BlockManager::AddUnlinkedBlock(CBlockIndex* block) |
| 259 | { |
no test coverage detected