@@ -3702,6 +3702,11 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
3702
3702
// not process unrequested blocks.
3703
3703
bool fTooFarAhead = (pindex->nHeight > int (chainActive.Height () + MIN_BLOCKS_TO_KEEP));
3704
3704
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
+
3705
3710
// TODO: deal better with return value and error conditions for duplicate
3706
3711
// and unrequested blocks.
3707
3712
if (fAlreadyHave ) return true ;
@@ -3750,13 +3755,11 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, C
3750
3755
{
3751
3756
{
3752
3757
LOCK (cs_main);
3753
- bool fRequested = MarkBlockAsReceived (pblock->GetHash ());
3754
- fRequested |= fForceProcessing ;
3755
3758
3756
3759
// Store to disk
3757
3760
CBlockIndex *pindex = NULL ;
3758
3761
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 );
3760
3763
if (pindex && pfrom) {
3761
3764
mapBlockSource[pindex->GetBlockHash ()] = pfrom->GetId ();
3762
3765
if (fNewBlock ) pfrom->nLastBlockTime = GetTime ();
@@ -5858,12 +5861,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
5858
5861
std::vector<CInv> invs;
5859
5862
invs.push_back (CInv (MSG_BLOCK | GetFetchFlags (pfrom, chainActive.Tip (), chainparams.GetConsensus ()), resp.blockhash ));
5860
5863
pfrom->PushMessage (NetMsgType::GETDATA, invs);
5861
- } else
5864
+ } else {
5865
+ MarkBlockAsReceived (resp.blockhash ); // it is now an empty pointer
5862
5866
fBlockRead = true ;
5867
+ }
5863
5868
} // Don't hold cs_main when we call into ProcessNewBlock
5864
5869
if (fBlockRead ) {
5865
5870
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 );
5867
5874
int nDoS;
5868
5875
if (state.IsInvalid (nDoS)) {
5869
5876
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,
6039
6046
// Such an unrequested block may still be processed, subject to the
6040
6047
// conditions in AcceptBlock().
6041
6048
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
+ }
6042
6055
ProcessNewBlock (state, chainparams, pfrom, &block, forceProcessing, NULL );
6043
6056
int nDoS;
6044
6057
if (state.IsInvalid (nDoS)) {
0 commit comments