PPCoin: Process and relay synchronized checkpoint
authorScott Nadal <scott.nadal@gmail.com>
Tue, 5 Jun 2012 15:07:36 +0000 (16:07 +0100)
committerScott Nadal <scott.nadal@gmail.com>
Tue, 5 Jun 2012 15:07:36 +0000 (16:07 +0100)
src/checkpoints.cpp
src/checkpoints.h
src/main.cpp

index 9c4ef34..4560240 100644 (file)
@@ -58,19 +58,41 @@ namespace Checkpoints
 
     // 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)
index f06f81c..6ef2c14 100644 (file)
@@ -32,8 +32,6 @@ namespace Checkpoints
     CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex);
 
     // ppcoin: synchronized checkpoint
-    extern uint256 hashSyncCheckpoint;
-
     class CUnsignedSyncCheckpoint
     {
     public:
@@ -133,6 +131,10 @@ namespace Checkpoints
         bool ProcessSyncCheckpoint();
     };
 
+    extern uint256 hashSyncCheckpoint;
+    extern CSyncCheckpoint checkpointMessage;
+    extern CCriticalSection cs_hashSyncCheckpoint;
+
     // ppcoin: automatic checkpoint
     extern int nAutoCheckpoint;
     extern int nBranchPoint;
index 803cd79..0dca0ae 100644 (file)
@@ -2165,6 +2165,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
             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);
@@ -2578,6 +2583,20 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
         }
     }
 
+    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
     {