CBlockIndex* pindex = pindexCheckpointRecv;
while (pindex->nHeight > pindexSyncCheckpoint->nHeight)
- pindex = pindex->pprev;
+ if (!(pindex = pindex->pprev))
+ return error("ValidateSyncCheckpoint: pprev null - block index structure failure");
if (pindex->GetBlockHash() != hashSyncCheckpoint)
return error("ValidateSyncCheckpoint: new sync-checkpoint %s is not a descendant of current sync-checkpoint %s", hashCheckpoint.ToString().c_str(), hashSyncCheckpoint.ToString().c_str());
return true;
}
// Check against synchronized checkpoint
- bool CheckSync(int nHeight, const uint256& hashBlock)
+ bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev)
{
if (fTestNet) return true; // Testnet has no checkpoints
+ int nHeight = pindexPrev->nHeight + 1;
CRITICAL_BLOCK(cs_hashSyncCheckpoint)
{
- CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint];
+ // sync-checkpoint should always be accepted block
+ assert(mapBlockIndex.count(hashSyncCheckpoint));
+ const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint];
+
+ if (nHeight > pindexSync->nHeight)
+ {
+ // trace back to same height as sync-checkpoint
+ const CBlockIndex* pindex = pindexPrev;
+ while (pindex->nHeight > pindexSync->nHeight)
+ if (!(pindex = pindex->pprev))
+ return error("CheckSync: pprev null - block index structure failure");
+ if (pindex->nHeight < pindexSync->nHeight || pindex->GetBlockHash() != hashSyncCheckpoint)
+ return false; // only descendant of sync-checkpoint can pass check
+ }
if (nHeight == pindexSync->nHeight && hashBlock != hashSyncCheckpoint)
return false; // same height with sync-checkpoint
if (nHeight < pindexSync->nHeight && !mapBlockIndex.count(hashBlock))
bool AcceptPendingSyncCheckpoint();
uint256 AutoSelectSyncCheckpoint();
- bool CheckSync(int nHeight, const uint256& hashBlock);
+ bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev);
// ppcoin: automatic checkpoint
extern int nAutoCheckpoint;
return DoS(100, error("AcceptBlock() : rejected by automatic checkpoint at %d", Checkpoints::nAutoCheckpoint));
// ppcoin: check that the block satisfies synchronized checkpoint
- if (!Checkpoints::CheckSync(nHeight, hash))
- return DoS(100, error("AcceptBlock() : rejected by synchronized checkpoint"));
+ if (!Checkpoints::CheckSync(hash, pindexPrev))
+ return error("AcceptBlock() : rejected by synchronized checkpoint");
// Write block to history file
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))