|
|
@ -2185,6 +2185,11 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp) |
|
|
|
if (!Checkpoints::CheckBlock(nHeight, hash)) |
|
|
|
if (!Checkpoints::CheckBlock(nHeight, hash)) |
|
|
|
return state.DoS(100, error("AcceptBlock() : rejected by checkpoint lock-in at %d", nHeight)); |
|
|
|
return state.DoS(100, error("AcceptBlock() : rejected by checkpoint lock-in at %d", nHeight)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Don't accept any forks from the main chain prior to last checkpoint
|
|
|
|
|
|
|
|
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); |
|
|
|
|
|
|
|
if (pcheckpoint && nHeight < pcheckpoint->nHeight) |
|
|
|
|
|
|
|
return state.DoS(100, error("AcceptBlock() : forked chain older than last checkpoint (height %d)", nHeight)); |
|
|
|
|
|
|
|
|
|
|
|
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
|
|
|
|
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
|
|
|
|
if (nVersion < 2) |
|
|
|
if (nVersion < 2) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -3087,11 +3092,28 @@ void static ProcessGetData(CNode* pfrom) |
|
|
|
|
|
|
|
|
|
|
|
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK) |
|
|
|
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Send block from disk
|
|
|
|
bool send = true; |
|
|
|
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash); |
|
|
|
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash); |
|
|
|
pfrom->nBlocksRequested++; |
|
|
|
pfrom->nBlocksRequested++; |
|
|
|
if (mi != mapBlockIndex.end()) |
|
|
|
if (mi != mapBlockIndex.end()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
// If the requested block is at a height below our last
|
|
|
|
|
|
|
|
// checkpoint, only serve it if it's in the checkpointed chain
|
|
|
|
|
|
|
|
int nHeight = ((*mi).second)->nHeight; |
|
|
|
|
|
|
|
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); |
|
|
|
|
|
|
|
if (pcheckpoint && nHeight < pcheckpoint->nHeight) { |
|
|
|
|
|
|
|
if (!((*mi).second)->IsInMainChain()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
printf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n"); |
|
|
|
|
|
|
|
send = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
send = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (send) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Send block from disk
|
|
|
|
CBlock block; |
|
|
|
CBlock block; |
|
|
|
block.ReadFromDisk((*mi).second); |
|
|
|
block.ReadFromDisk((*mi).second); |
|
|
|
if (inv.type == MSG_BLOCK) |
|
|
|
if (inv.type == MSG_BLOCK) |
|
|
|