@@ -3702,6 +3702,11 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
37023702 // not process unrequested blocks.
37033703 bool fTooFarAhead = (pindex->nHeight > int (chainActive.Height () + MIN_BLOCKS_TO_KEEP));
37043704
3705+ // TODO: Decouple this function from the block download logic by removing fRequested
3706+ // This requires some new chain datastructure to efficiently look up if a
3707+ // block is in a chain leading to a candidate for best tip, despite not
3708+ // being such a candidate itself.
3709+
37053710 // TODO: deal better with return value and error conditions for duplicate
37063711 // and unrequested blocks.
37073712 if (fAlreadyHave ) return true ;
@@ -3750,13 +3755,11 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, C
37503755{
37513756 {
37523757 LOCK (cs_main);
3753- bool fRequested = MarkBlockAsReceived (pblock->GetHash ());
3754- fRequested |= fForceProcessing ;
37553758
37563759 // Store to disk
37573760 CBlockIndex *pindex = NULL ;
37583761 bool fNewBlock = false ;
3759- bool ret = AcceptBlock (*pblock, state, chainparams, &pindex, fRequested , dbp, &fNewBlock );
3762+ bool ret = AcceptBlock (*pblock, state, chainparams, &pindex, fForceProcessing , dbp, &fNewBlock );
37603763 if (pindex && pfrom) {
37613764 mapBlockSource[pindex->GetBlockHash ()] = pfrom->GetId ();
37623765 if (fNewBlock ) pfrom->nLastBlockTime = GetTime ();
@@ -5858,12 +5861,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
58585861 std::vector<CInv> invs;
58595862 invs.push_back (CInv (MSG_BLOCK | GetFetchFlags (pfrom, chainActive.Tip (), chainparams.GetConsensus ()), resp.blockhash ));
58605863 pfrom->PushMessage (NetMsgType::GETDATA, invs);
5861- } else
5864+ } else {
5865+ MarkBlockAsReceived (resp.blockhash ); // it is now an empty pointer
58625866 fBlockRead = true ;
5867+ }
58635868 } // Don't hold cs_main when we call into ProcessNewBlock
58645869 if (fBlockRead ) {
58655870 CValidationState state;
5866- ProcessNewBlock (state, chainparams, pfrom, &block, false , NULL );
5871+ // Since we requested this block (it was in mapBlocksInFlight), force it to be processed,
5872+ // even if it would not be a candidate for new tip (missing previous block, chain not long enough, etc)
5873+ ProcessNewBlock (state, chainparams, pfrom, &block, true , NULL );
58675874 int nDoS;
58685875 if (state.IsInvalid (nDoS)) {
58695876 assert (state.GetRejectCode () < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
@@ -6039,6 +6046,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
60396046 // Such an unrequested block may still be processed, subject to the
60406047 // conditions in AcceptBlock().
60416048 bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload ();
6049+ {
6050+ LOCK (cs_main);
6051+ // Also always process if we requested the block explicitly, as we may
6052+ // need it even though it is not a candidate for a new best tip.
6053+ forceProcessing |= MarkBlockAsReceived (block.GetHash ());
6054+ }
60426055 ProcessNewBlock (state, chainparams, pfrom, &block, forceProcessing, NULL );
60436056 int nDoS;
60446057 if (state.IsInvalid (nDoS)) {
0 commit comments