PPCoin: Replace RPC command 'setcheckpointkey' with option '-checkpointkey'
[novacoin.git] / src / checkpoints.cpp
index bd4eba7..7de5883 100644 (file)
@@ -163,7 +163,7 @@ namespace Checkpoints
                 {
                     txdb.TxnAbort();
                     hashInvalidCheckpoint = hashPendingCheckpoint;
-                    return error("ProcessSyncCheckpoint: Reorganize failed for sync checkpoint %s", hashPendingCheckpoint.ToString().c_str());
+                    return error("AcceptPendingSyncCheckpoint: Reorganize failed for sync checkpoint %s", hashPendingCheckpoint.ToString().c_str());
                 }
             }
             txdb.Close();
@@ -185,6 +185,21 @@ namespace Checkpoints
         return false;
     }
 
+    // Automatically select a suitable sync-checkpoint 
+    uint256 AutoSelectSyncCheckpoint()
+    {
+        // Proof-of-work blocks are immediately checkpointed
+        // to defend against 51% attack which rejects other miners block 
+
+        // Select the last proof-of-work block
+        const CBlockIndex *pindex = GetLastBlockIndex(pindexBest, false);
+        // Search forward for a block within max span and maturity window
+        while (pindex->pnext && (pindex->GetBlockTime() + CHECKPOINT_MAX_SPAN <= pindexBest->GetBlockTime() || pindex->nHeight + COINBASE_MATURITY <= pindexBest->nHeight))
+            pindex = pindex->pnext;
+        return pindex->GetBlockHash();
+    }
+
+    // Check against synchronized checkpoint
     bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev)
     {
         if (fTestNet) return true; // Testnet has no checkpoints
@@ -273,6 +288,26 @@ namespace Checkpoints
             pfrom->AskFor(CInv(MSG_BLOCK, hashPendingCheckpoint));
     }
 
+    bool SetCheckpointPrivKey(std::string strPrivKey)
+    {
+        // Test signing a sync-checkpoint with genesis block
+        CSyncCheckpoint checkpoint;
+        checkpoint.hashCheckpoint = hashGenesisBlock;
+        CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION);
+        sMsg << (CUnsignedSyncCheckpoint)checkpoint;
+        checkpoint.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end());
+
+        std::vector<unsigned char> vchPrivKey = ParseHex(strPrivKey);
+        CKey key;
+        key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash
+        if (!key.Sign(Hash(checkpoint.vchMsg.begin(), checkpoint.vchMsg.end()), checkpoint.vchSig))
+            return false;
+
+        // Test signing successful, proceed
+        CSyncCheckpoint::strMasterPrivKey = strPrivKey;
+        return true;
+    }
+
     bool SendSyncCheckpoint(uint256 hashCheckpoint)
     {
         CSyncCheckpoint checkpoint;