| 4822 | } |
| 4823 | |
| 4824 | bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, CDiskBlockPos* dbp) |
| 4825 | { |
| 4826 | AssertLockHeld(cs_main); |
| 4827 | |
| 4828 | CBlockIndex*& pindex = *ppindex; |
| 4829 | |
| 4830 | // Get prev block index |
| 4831 | CBlockIndex* pindexPrev = NULL; |
| 4832 | //Genesis block's hash cannot be calculated using PHI2, so no need to check PHI2 block hash |
| 4833 | if (block.GetHash() != chainparams.GetConsensus().hashGenesisBlock) { |
| 4834 | pindexPrev = LookupBlockIndex(block.hashPrevBlock); |
| 4835 | if (!pindexPrev) |
| 4836 | return state.DoS(0, error("%s : prev block %s not found", __func__, block.hashPrevBlock.GetHex()), 0, "bad-prevblk"); |
| 4837 | // if (pindexPrev->nStatus & BLOCK_FAILED_MASK) |
| 4838 | // return state.DoS(100, error("%s : prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); |
| 4839 | } |
| 4840 | |
| 4841 | if (block.GetHash() != chainparams.GetConsensus().hashGenesisBlock && !CheckWork(block, pindexPrev)) |
| 4842 | return false; |
| 4843 | |
| 4844 | if (!AcceptBlockHeader(block, state, chainparams, &pindex)) |
| 4845 | return false; |
| 4846 | |
| 4847 | if (pindex->nStatus & BLOCK_HAVE_DATA) { |
| 4848 | // TODO: deal better with duplicate blocks. |
| 4849 | // return state.DoS(20, error("AcceptBlock() : already have block %d %s", pindex->nHeight, pindex->GetBlockHash().GetHex()), REJECT_DUPLICATE, "duplicate"); |
| 4850 | return true; |
| 4851 | } |
| 4852 | |
| 4853 | if ((!CheckBlock(block, state, chainparams.GetConsensus())) || !ContextualCheckBlock(block, state, pindex->pprev)) { |
| 4854 | if (state.IsInvalid() && !state.CorruptionPossible()) { |
| 4855 | pindex->nStatus |= BLOCK_FAILED_VALID; |
| 4856 | setDirtyBlockIndex.insert(pindex); |
| 4857 | } |
| 4858 | return error("%s: %s", __func__, FormatStateMessage(state)); |
| 4859 | } |
| 4860 | |
| 4861 | int nHeight = pindex->nHeight; |
| 4862 | |
| 4863 | // Write block to history file |
| 4864 | try { |
| 4865 | unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); |
| 4866 | CDiskBlockPos blockPos; |
| 4867 | if (dbp != NULL) |
| 4868 | blockPos = *dbp; |
| 4869 | if (!FindBlockPos(state, blockPos, nBlockSize + 8, nHeight, block.GetBlockTime(), dbp != NULL)) |
| 4870 | return error("%s: FindBlockPos failed", __func__); |
| 4871 | if (dbp == NULL && !WriteBlockToDisk(block, blockPos)) |
| 4872 | return state.Error("Failed to write block"); |
| 4873 | if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) |
| 4874 | return error("%s: ReceivedBlockTransactions failed", __func__); |
| 4875 | } catch (std::runtime_error& e) { |
| 4876 | return state.Error(std::string("System error: ") + e.what()); |
| 4877 | } |
| 4878 | |
| 4879 | if (fCheckForPruning) |
| 4880 | FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files |
| 4881 |
no test coverage detected