From 42535b58bd40e14ea489dd595474c57ca73e52ea Mon Sep 17 00:00:00 2001 From: Scott Nadal Date: Fri, 8 Jun 2012 16:21:54 +0100 Subject: [PATCH] PPCoin: Accept pending synchronized checkpoint --- src/checkpoints.cpp | 60 +++++++++++++++++++++++++++++++++++++++------------ src/checkpoints.h | 2 + src/main.cpp | 3 ++ 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index ac86c95..aeb0be7 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -62,6 +62,27 @@ namespace Checkpoints CSyncCheckpoint checkpointMessagePending; CCriticalSection cs_hashSyncCheckpoint; + // ppcoin: only descendant of current sync-checkpoint is allowed + bool ValidateSyncCheckpoint(uint256 hashCheckpoint) + { + if (!mapBlockIndex.count(hashSyncCheckpoint)) + return error("ValidateSyncCheckpoint: block index missing for current sync-checkpoint %s", hashSyncCheckpoint.ToString().c_str()); + if (!mapBlockIndex.count(hashCheckpoint)) + return error("ValidateSyncCheckpoint: block index missing for received sync-checkpoint %s", hashCheckpoint.ToString().c_str()); + + CBlockIndex* pindexSyncCheckpoint = mapBlockIndex[hashSyncCheckpoint]; + CBlockIndex* pindexCheckpointRecv = mapBlockIndex[hashCheckpoint]; + if (pindexCheckpointRecv->nHeight <= pindexSyncCheckpoint->nHeight) + return false; // this is an older checkpoint, ignore + + CBlockIndex* pindex = pindexCheckpointRecv; + while (pindex->nHeight > pindexSyncCheckpoint->nHeight) + pindex = pindex->pprev; + 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; + } + bool CSyncCheckpoint::ProcessSyncCheckpoint(CNode* pfrom) { if (!CheckSignature()) @@ -78,26 +99,37 @@ namespace Checkpoints pfrom->PushGetBlocks(pindexBest, hashCheckpoint); return false; } - - if (!mapBlockIndex.count(hashSyncCheckpoint)) - return error("ProcessSyncCheckpoint: block index missing for synchronized checkpoint %s", hashSyncCheckpoint.ToString().c_str()); - - CBlockIndex* pindexSyncCheckpoint = mapBlockIndex[hashSyncCheckpoint]; - CBlockIndex* pindexCheckpointPending = mapBlockIndex[hashCheckpoint]; - if (pindexCheckpointPending->nHeight <= pindexSyncCheckpoint->nHeight) - return false; // this is an older checkpoint, ignore - - CBlockIndex* pindex = pindexCheckpointPending; - while (pindex->nHeight > pindexSyncCheckpoint->nHeight) - pindex = pindex->pprev; - if (pindex->GetBlockHash() != hashSyncCheckpoint) - return error("ProcessSyncCheckpoint: new sync-checkpoint %s is not a descendant of current sync-checkpoint %s", hashCheckpoint.ToString().c_str(), hashSyncCheckpoint.ToString().c_str()); + if (!ValidateSyncCheckpoint(hashCheckpoint)) + return false; hashSyncCheckpoint = this->hashCheckpoint; checkpointMessage = *this; + checkpointMessagePending.SetNull(); } return true; } + bool AcceptPendingSyncCheckpoint(uint256 hashAcceptedBlock) + { + if (!mapBlockIndex.count(hashAcceptedBlock)) + return false; + + CRITICAL_BLOCK(cs_hashSyncCheckpoint) + if ((!checkpointMessagePending.IsNull()) && checkpointMessagePending.hashCheckpoint == hashAcceptedBlock) + { + if (!ValidateSyncCheckpoint(checkpointMessagePending.hashCheckpoint)) + { + checkpointMessagePending.SetNull(); + return false; + } + hashSyncCheckpoint = checkpointMessagePending.hashCheckpoint; + checkpointMessage = checkpointMessagePending; + checkpointMessagePending.SetNull(); + return true; + } + + return false; + } + // ppcoin: automatic checkpoint (represented by height of checkpoint) int nAutoCheckpoint = 0; int nBranchPoint = 0; // branch point to alternative branch diff --git a/src/checkpoints.h b/src/checkpoints.h index 372f32b..92c14b7 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -135,6 +135,8 @@ namespace Checkpoints extern CSyncCheckpoint checkpointMessage; extern CCriticalSection cs_hashSyncCheckpoint; + bool AcceptPendingSyncCheckpoint(uint256 hashAcceptedBlock); + // ppcoin: automatic checkpoint extern int nAutoCheckpoint; extern int nBranchPoint; diff --git a/src/main.cpp b/src/main.cpp index 6839725..d6c10a4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1595,6 +1595,9 @@ bool CBlock::AcceptBlock() if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700)) pnode->PushInventory(CInv(MSG_BLOCK, hash)); + // ppcoin: check pending sync-checkpoint + Checkpoints::AcceptPendingSyncCheckpoint(hash); + return true; } -- 1.7.1