@@ -2276,6 +2276,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp)
2276
2276
return state.DoS (100 , error (" AcceptBlock() : rejected by checkpoint lock-in at %d" , nHeight),
2277
2277
REJECT_CHECKPOINT, " checkpoint mismatch" );
2278
2278
2279
+ // Don't accept any forks from the main chain prior to last checkpoint
2280
+ CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint (mapBlockIndex);
2281
+ if (pcheckpoint && nHeight < pcheckpoint->nHeight )
2282
+ return state.DoS (100 , error (" AcceptBlock() : forked chain older than last checkpoint (height %d)" , nHeight));
2283
+
2279
2284
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
2280
2285
if (block.nVersion < 2 )
2281
2286
{
@@ -3133,10 +3138,28 @@ void static ProcessGetData(CNode* pfrom)
3133
3138
3134
3139
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
3135
3140
{
3136
- // Send block from disk
3141
+ bool send = false ;
3137
3142
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find (inv.hash );
3138
3143
if (mi != mapBlockIndex.end ())
3139
3144
{
3145
+ // If the requested block is at a height below our last
3146
+ // checkpoint, only serve it if it's in the checkpointed chain
3147
+ int nHeight = mi->second ->nHeight ;
3148
+ CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint (mapBlockIndex);
3149
+ if (pcheckpoint && nHeight < pcheckpoint->nHeight ) {
3150
+ if (!chainActive.Contains (mi->second ))
3151
+ {
3152
+ LogPrintf (" ProcessGetData(): ignoring request for old block that isn't in the main chain\n " );
3153
+ } else {
3154
+ send = true ;
3155
+ }
3156
+ } else {
3157
+ send = true ;
3158
+ }
3159
+ }
3160
+ if (send)
3161
+ {
3162
+ // Send block from disk
3140
3163
CBlock block;
3141
3164
ReadBlockFromDisk (block, (*mi).second );
3142
3165
if (inv.type == MSG_BLOCK)
0 commit comments