// ppcoin: synchronized checkpoint (centrally broadcasted)
uint256 hashSyncCheckpoint;
+ CSyncCheckpoint checkpointMessage;
+ CSyncCheckpoint checkpointMessagePending;
CCriticalSection cs_hashSyncCheckpoint;
- bool AcceptNewSyncCheckpoint(uint256 hashCheckpoint)
- {
- }
-
bool CSyncCheckpoint::ProcessSyncCheckpoint()
{
if (!CheckSignature())
return false;
CRITICAL_BLOCK(cs_hashSyncCheckpoint)
+ {
+ if (!mapBlockIndex.count(hashCheckpoint))
+ {
+ // TODO: we don't have this block yet, so ask for it
+ checkpointMessagePending = *this;
+ 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());
hashSyncCheckpoint = this->hashCheckpoint;
+ checkpointMessage = *this;
+ }
+ return true;
}
// ppcoin: automatic checkpoint (represented by height of checkpoint)
CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex);
// ppcoin: synchronized checkpoint
- extern uint256 hashSyncCheckpoint;
-
class CUnsignedSyncCheckpoint
{
public:
bool ProcessSyncCheckpoint();
};
+ extern uint256 hashSyncCheckpoint;
+ extern CSyncCheckpoint checkpointMessage;
+ extern CCriticalSection cs_hashSyncCheckpoint;
+
// ppcoin: automatic checkpoint
extern int nAutoCheckpoint;
extern int nBranchPoint;
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
item.second.RelayTo(pfrom);
+ // ppcoin: relay sync-checkpoint
+ CRITICAL_BLOCK(Checkpoints::cs_hashSyncCheckpoint)
+ if (!Checkpoints::checkpointMessage.IsNull())
+ Checkpoints::checkpointMessage.RelayTo(pfrom);
+
pfrom->fSuccessfullyConnected = true;
printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
}
}
+ else if (strCommand == "checkpoint")
+ {
+ Checkpoints::CSyncCheckpoint checkpoint;
+ vRecv >> checkpoint;
+
+ if (checkpoint.ProcessSyncCheckpoint())
+ {
+ // Relay
+ pfrom->hashCheckpointKnown = checkpoint.hashCheckpoint;
+ CRITICAL_BLOCK(cs_vNodes)
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ checkpoint.RelayTo(pnode);
+ }
+ }
else
{