| 3942 | } |
| 3943 | |
| 3944 | bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool* duplicate) |
| 3945 | { |
| 3946 | AssertLockHeld(cs_main); |
| 3947 | // Check for duplicate |
| 3948 | uint256 hash = block.GetHash(); |
| 3949 | BlockMap::iterator miSelf{m_blockman.m_block_index.find(hash)}; |
| 3950 | if (duplicate) { |
| 3951 | *duplicate = false; |
| 3952 | } |
| 3953 | if (hash != chainparams.GetConsensus().hashGenesisBlock) { |
| 3954 | if (miSelf != m_blockman.m_block_index.end()) { |
| 3955 | // Block header is already known. |
| 3956 | CBlockIndex* pindex = miSelf->second; |
| 3957 | if (duplicate) { |
| 3958 | *duplicate = true; |
| 3959 | } |
| 3960 | if (ppindex) |
| 3961 | *ppindex = pindex; |
| 3962 | if (pindex->nStatus & BLOCK_FAILED_MASK) { |
| 3963 | LogPrint(BCLog::VALIDATION, "%s: block %s is marked invalid\n", __func__, hash.ToString()); |
| 3964 | return state.Invalid(BlockValidationResult::BLOCK_CACHED_INVALID, "duplicate"); |
| 3965 | } |
| 3966 | return true; |
| 3967 | } |
| 3968 | |
| 3969 | if (!CheckBlockHeader(block, state, chainparams.GetConsensus())) { |
| 3970 | LogPrint(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString()); |
| 3971 | return false; |
| 3972 | } |
| 3973 | |
| 3974 | // Get prev block index |
| 3975 | CBlockIndex* pindexPrev = nullptr; |
| 3976 | BlockMap::iterator mi{m_blockman.m_block_index.find(block.hashPrevBlock)}; |
| 3977 | if (mi == m_blockman.m_block_index.end()) { |
| 3978 | LogPrint(BCLog::VALIDATION, "%s: %s prev block not found\n", __func__, hash.ToString()); |
| 3979 | return state.Invalid(BlockValidationResult::BLOCK_MISSING_PREV, "prev-blk-not-found"); |
| 3980 | } |
| 3981 | pindexPrev = (*mi).second; |
| 3982 | if (pindexPrev->nStatus & BLOCK_FAILED_MASK) { |
| 3983 | LogPrint(BCLog::VALIDATION, "%s: %s prev block invalid\n", __func__, hash.ToString()); |
| 3984 | return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk"); |
| 3985 | } |
| 3986 | if (!ContextualCheckBlockHeader(block, state, m_blockman, chainparams, pindexPrev, GetAdjustedTime())) { |
| 3987 | LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString()); |
| 3988 | return false; |
| 3989 | } |
| 3990 | |
| 3991 | /* Determine if this block descends from any block which has been found |
| 3992 | * invalid (m_failed_blocks), then mark pindexPrev and any blocks between |
| 3993 | * them as failed. For example: |
| 3994 | * |
| 3995 | * D3 |
| 3996 | * / |
| 3997 | * B2 - C2 |
| 3998 | * / \ |
| 3999 | * A D2 - E2 - F2 |
| 4000 | * \ |
| 4001 | * B1 - C1 - D1 - E1 |
no test coverage detected