@@ -2154,6 +2154,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp)
2154
2154
return state.DoS (100 , error (" AcceptBlock() : rejected by checkpoint lock-in at %d" , nHeight),
2155
2155
REJECT_CHECKPOINT, " checkpoint mismatch" );
2156
2156
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
+
2157
2162
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
2158
2163
if (block.nVersion < 2 )
2159
2164
{
@@ -3025,10 +3030,28 @@ void static ProcessGetData(CNode* pfrom)
3025
3030
3026
3031
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
3027
3032
{
3028
- // Send block from disk
3033
+ bool send = false ;
3029
3034
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find (inv.hash );
3030
3035
if (mi != mapBlockIndex.end ())
3031
3036
{
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
3032
3055
CBlock block;
3033
3056
ReadBlockFromDisk (block, (*mi).second );
3034
3057
if (inv.type == MSG_BLOCK)
0 commit comments