MCPcopy Create free account
hub / github.com/ElementsProject/elements / AcceptBlock

Method AcceptBlock

src/validation.cpp:4076–4158  ·  view source on GitHub ↗

Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */

Source from the content-addressed store, hash-verified

4074
4075/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
4076bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock)
4077{
4078 const CBlock& block = *pblock;
4079
4080 if (fNewBlock) *fNewBlock = false;
4081 AssertLockHeld(cs_main);
4082
4083 CBlockIndex *pindexDummy = nullptr;
4084 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
4085
4086 bool accepted_header{m_chainman.AcceptBlockHeader(block, state, m_params, &pindex)};
4087 CheckBlockIndex();
4088
4089 if (!accepted_header)
4090 return false;
4091
4092 // Try to process all requested blocks that we don't have, but only
4093 // process an unrequested block if it's new and has enough work to
4094 // advance our tip, and isn't too many blocks ahead.
4095 bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
4096 bool fHasMoreOrSameWork = (m_chain.Tip() ? pindex->nChainWork >= m_chain.Tip()->nChainWork : true);
4097 // Blocks that are too out-of-order needlessly limit the effectiveness of
4098 // pruning, because pruning will not delete block files that contain any
4099 // blocks which are too close in height to the tip. Apply this test
4100 // regardless of whether pruning is enabled; it should generally be safe to
4101 // not process unrequested blocks.
4102 bool fTooFarAhead{pindex->nHeight > m_chain.Height() + int(MIN_BLOCKS_TO_KEEP)};
4103
4104 // TODO: Decouple this function from the block download logic by removing fRequested
4105 // This requires some new chain data structure to efficiently look up if a
4106 // block is in a chain leading to a candidate for best tip, despite not
4107 // being such a candidate itself.
4108 // Note that this would break the getblockfrompeer RPC
4109
4110 // TODO: deal better with return value and error conditions for duplicate
4111 // and unrequested blocks.
4112 if (fAlreadyHave) return true;
4113 if (!fRequested) { // If we didn't ask for it:
4114 if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
4115 if (!fHasMoreOrSameWork) return true; // Don't process less-work chains
4116 if (fTooFarAhead) return true; // Block height is too high
4117
4118 // Protect against DoS attacks from low-work chains.
4119 // If our tip is behind, a peer could try to send us
4120 // low-work blocks on a fake chain that we would never
4121 // request; don't process these.
4122 if (pindex->nChainWork < nMinimumChainWork) return true;
4123 }
4124
4125 if (m_params.GetConsensus().hashGenesisBlock != block.GetHash() &&
4126 (!CheckBlock(block, state, m_params.GetConsensus()) ||
4127 !ContextualCheckBlock(block, state, m_params.GetConsensus(), pindex->pprev))) {
4128 if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
4129 pindex->nStatus |= BLOCK_FAILED_VALID;
4130 m_blockman.m_dirty_blockindex.insert(pindex);
4131 }
4132 return error("%s: %s", __func__, state.ToString());
4133 }

Callers 2

ProcessNewBlockMethod · 0.80
BOOST_FIXTURE_TEST_CASEFunction · 0.80

Calls 15

CheckBlockFunction · 0.85
ContextualCheckBlockFunction · 0.85
errorFunction · 0.85
AcceptBlockHeaderMethod · 0.80
HeightMethod · 0.80
IsInvalidMethod · 0.80
GetResultMethod · 0.80
SaveBlockToDiskMethod · 0.80
ErrorMethod · 0.80
AbortNodeFunction · 0.70
TipMethod · 0.45
GetHashMethod · 0.45

Tested by 1

BOOST_FIXTURE_TEST_CASEFunction · 0.64