| 4194 | } |
| 4195 | |
| 4196 | bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, CBlockIndex** ppindex, bool min_pow_checked) |
| 4197 | { |
| 4198 | AssertLockHeld(cs_main); |
| 4199 | |
| 4200 | // Check for duplicate |
| 4201 | uint256 hash = block.GetHash(); |
| 4202 | BlockMap::iterator miSelf{m_blockman.m_block_index.find(hash)}; |
| 4203 | if (hash != GetConsensus().hashGenesisBlock) { |
| 4204 | if (miSelf != m_blockman.m_block_index.end()) { |
| 4205 | // Block header is already known. |
| 4206 | CBlockIndex* pindex = &(miSelf->second); |
| 4207 | if (ppindex) |
| 4208 | *ppindex = pindex; |
| 4209 | if (pindex->nStatus & BLOCK_FAILED_VALID) { |
| 4210 | LogDebug(BCLog::VALIDATION, "%s: block %s is marked invalid\n", __func__, hash.ToString()); |
| 4211 | return state.Invalid(BlockValidationResult::BLOCK_CACHED_INVALID, "duplicate-invalid", |
| 4212 | strprintf("block %s was previously marked invalid", hash.ToString())); |
| 4213 | } |
| 4214 | return true; |
| 4215 | } |
| 4216 | |
| 4217 | if (!CheckBlockHeader(block, state, GetConsensus())) { |
| 4218 | LogDebug(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString()); |
| 4219 | return false; |
| 4220 | } |
| 4221 | |
| 4222 | // Get prev block index |
| 4223 | CBlockIndex* pindexPrev = nullptr; |
| 4224 | BlockMap::iterator mi{m_blockman.m_block_index.find(block.hashPrevBlock)}; |
| 4225 | if (mi == m_blockman.m_block_index.end()) { |
| 4226 | LogDebug(BCLog::VALIDATION, "header %s has prev block not found: %s\n", hash.ToString(), block.hashPrevBlock.ToString()); |
| 4227 | return state.Invalid(BlockValidationResult::BLOCK_MISSING_PREV, "prev-blk-not-found"); |
| 4228 | } |
| 4229 | pindexPrev = &((*mi).second); |
| 4230 | if (pindexPrev->nStatus & BLOCK_FAILED_VALID) { |
| 4231 | LogDebug(BCLog::VALIDATION, "header %s has prev block invalid: %s\n", hash.ToString(), block.hashPrevBlock.ToString()); |
| 4232 | return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk"); |
| 4233 | } |
| 4234 | if (!ContextualCheckBlockHeader(block, state, *this, pindexPrev)) { |
| 4235 | LogDebug(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString()); |
| 4236 | return false; |
| 4237 | } |
| 4238 | } |
| 4239 | if (!min_pow_checked) { |
| 4240 | LogDebug(BCLog::VALIDATION, "%s: not adding new block header %s, missing anti-dos proof-of-work validation\n", __func__, hash.ToString()); |
| 4241 | return state.Invalid(BlockValidationResult::BLOCK_HEADER_LOW_WORK, "too-little-chainwork"); |
| 4242 | } |
| 4243 | CBlockIndex* pindex{m_blockman.AddToBlockIndex(block, m_best_header)}; |
| 4244 | |
| 4245 | if (ppindex) |
| 4246 | *ppindex = pindex; |
| 4247 | |
| 4248 | return true; |
| 4249 | } |
| 4250 | |
| 4251 | // Exposed wrapper for AcceptBlockHeader |
| 4252 | bool ChainstateManager::ProcessNewBlockHeaders(std::span<const CBlockHeader> headers, bool min_pow_checked, BlockValidationState& state, const CBlockIndex** ppindex) |
nothing calls this directly
no test coverage detected