@@ -2154,6 +2154,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp)
21542154 return state.DoS (100 , error (" AcceptBlock() : rejected by checkpoint lock-in at %d" , nHeight),
21552155 REJECT_CHECKPOINT, " checkpoint mismatch" );
21562156
2157+ // Don't accept any forks from the main chain prior to last checkpoint
2158+ CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint (mapBlockIndex);
2159+ if (pcheckpoint && nHeight < pcheckpoint->nHeight )
2160+ return state.DoS (100 , error (" AcceptBlock() : forked chain older than last checkpoint (height %d)" , nHeight));
2161+
21572162 // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
21582163 if (block.nVersion < 2 )
21592164 {
@@ -3025,10 +3030,28 @@ void static ProcessGetData(CNode* pfrom)
30253030
30263031 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
30273032 {
3028- // Send block from disk
3033+ bool send = false ;
30293034 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find (inv.hash );
30303035 if (mi != mapBlockIndex.end ())
30313036 {
3037+ // If the requested block is at a height below our last
3038+ // checkpoint, only serve it if it's in the checkpointed chain
3039+ int nHeight = mi->second ->nHeight ;
3040+ CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint (mapBlockIndex);
3041+ if (pcheckpoint && nHeight < pcheckpoint->nHeight ) {
3042+ if (!chainActive.Contains (mi->second ))
3043+ {
3044+ LogPrintf (" ProcessGetData(): ignoring request for old block that isn't in the main chain\n " );
3045+ } else {
3046+ send = true ;
3047+ }
3048+ } else {
3049+ send = true ;
3050+ }
3051+ }
3052+ if (send)
3053+ {
3054+ // Send block from disk
30323055 CBlock block;
30333056 ReadBlockFromDisk (block, (*mi).second );
30343057 if (inv.type == MSG_BLOCK)
0 commit comments