PPCoin: RPC command 'sendcheckpoint'
authorScott Nadal <scott.nadal@gmail.com>
Mon, 11 Jun 2012 14:55:01 +0000 (15:55 +0100)
committerScott Nadal <scott.nadal@gmail.com>
Mon, 11 Jun 2012 14:55:01 +0000 (15:55 +0100)
src/bitcoinrpc.cpp
src/checkpoints.cpp
src/checkpoints.h

index 4836fe3..033250f 100644 (file)
@@ -1931,6 +1931,19 @@ Value repairwallet(const Array& params, bool fHelp)
     return result;
 }
 
+// ppcoin: make a public-private key pair
+Value makekeypair(const Array& params, bool fHelp)
+{
+    CKey key;
+    key.MakeNewKey();
+    CPrivKey vchPrivKey = key.GetPrivKey();
+
+    Object result;
+    result.push_back(Pair("PrivateKey", HexStr<CPrivKey::iterator>(vchPrivKey.begin(), vchPrivKey.end())));
+    result.push_back(Pair("PublicKey", HexStr(key.GetPubKey())));
+    return result;
+}
+
 extern CCriticalSection cs_mapAlerts;
 extern map<uint256, CAlert> mapAlerts;
 
@@ -1993,18 +2006,49 @@ Value sendalert(const Array& params, bool fHelp)
     return result;
 }
 
-Value makekeypair(const Array& params, bool fHelp)
+// ppcoin: send checkpoint
+Value sendcheckpoint(const Array& params, bool fHelp)
 {
+    if (fHelp || params.size() > 2 || params.size() < 1 )
+        throw runtime_error(
+            "sendcheckpoint <privatekey> [checkpointhash]\n"
+            "<privatekey> is hex string of checkpoint master private key\n"
+            "<checkpointhash> is the hash of checkpoint block\n");
+
+    CSyncCheckpoint checkpoint;
     CKey key;
-    key.MakeNewKey();
-    CPrivKey vchPrivKey = key.GetPrivKey();
 
-    Object result;
-    result.push_back(Pair("PrivateKey", HexStr<CPrivKey::iterator>(vchPrivKey.begin(), vchPrivKey.end())));
-    result.push_back(Pair("PublicKey", HexStr(key.GetPubKey())));
-    return result;
+    // TODO: omit checkpointhash parameter
+    if (params.size() > 1)
+    {
+        checkpoint.hashCheckpoint = uint256(params[1].get_str());
+        if (!mapBlockIndex.count(checkpoint.hashCheckpoint))
+            throw runtime_error(
+                "Provided checkpoint block is not on main chain\n");
+    }
+
+    CDataStream sMsg;
+    sMsg << (CUnsignedSyncCheckpoint)checkpoint;
+    checkpoint.vchMsg = vector<unsigned char>(sMsg.begin(), sMsg.end());
+
+    vector<unsigned char> vchPrivKey = ParseHex(params[0].get_str());
+    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))
+        throw runtime_error(
+            "Unable to sign checkpoint, check private key?\n");
+
+    if(!checkpoint.ProcessSyncCheckpoint(NULL))
+        throw runtime_error(
+            "Failed to process checkpoint.\n");
+    // Relay checkpoint
+    CRITICAL_BLOCK(cs_vNodes)
+        BOOST_FOREACH(CNode* pnode, vNodes)
+            checkpoint.RelayTo(pnode);
+
+    return Value::null;
 }
 
+
 //
 // Call Table
 //
@@ -2056,8 +2100,9 @@ pair<string, rpcfn_type> pCallTable[] =
     make_pair("reservebalance",         &reservebalance),
     make_pair("checkwallet",            &checkwallet),
     make_pair("repairwallet",           &repairwallet),
-    make_pair("sendalert",              &sendalert),
     make_pair("makekeypair",            &makekeypair),
+    make_pair("sendalert",              &sendalert),
+    make_pair("sendcheckpoint",         &sendcheckpoint),
 };
 map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
 
index 8ea198c..4afdab9 100644 (file)
@@ -99,6 +99,10 @@ namespace Checkpoints
                 hashSyncCheckpoint = checkpointMessagePending.hashCheckpoint;
                 checkpointMessage = checkpointMessagePending;
                 checkpointMessagePending.SetNull();
+                printf("AcceptPendingSyncCheckpoint : sync-checkpoint at %s\n", hashSyncCheckpoint.ToString().c_str());
+                // relay the checkpoint
+                BOOST_FOREACH(CNode* pnode, vNodes)
+                    checkpointMessage.RelayTo(pnode);
                 return true;
             }
 
@@ -235,6 +239,7 @@ bool CSyncCheckpoint::ProcessSyncCheckpoint(CNode* pfrom)
         {
             // We haven't accepted this block, keep the checkpoint as pending
             Checkpoints::checkpointMessagePending = *this;
+            printf("ProcessSyncCheckpoint : pending for sync-checkpoint %s\n", hashCheckpoint.ToString().c_str());
             // Ask this guy to fill in what we're missing
             if (pfrom)
                 pfrom->PushGetBlocks(pindexBest, hashCheckpoint);
@@ -245,6 +250,7 @@ bool CSyncCheckpoint::ProcessSyncCheckpoint(CNode* pfrom)
         Checkpoints::hashSyncCheckpoint = this->hashCheckpoint;
         Checkpoints::checkpointMessage = *this;
         Checkpoints::checkpointMessagePending.SetNull();
+        printf("ProcessSyncCheckpoint : sync-checkpoint at %s\n", Checkpoints::hashSyncCheckpoint.ToString().c_str());
     }
     return true;
 }
index d193a2a..8ea1ec7 100644 (file)
@@ -102,7 +102,7 @@ public:
     bool CheckSignature()
     {
         CKey key;
-        if (!key.SetPubKey(ParseHex("0487ca85b6ae9d311f996c7616d20d0c88a5b4f07d25e78f419019f35cce6522acf978b2d99f0e7a58db1f120439e5c1889266927854aa57c93956c2569188a539")))
+        if (!key.SetPubKey(ParseHex("04ea21daea8c15559870b5e93750ddc2f0c16bd0cb16636ba88c0746cfac07912ec7ad14111cc4aedda12c2687c920c7b7b62fd67ca14eed53f2d1704ec72362ce")))
             return error("CSyncCheckpoint::CheckSignature() : SetPubKey failed");
         if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
             return error("CSyncCheckpoint::CheckSignature() : verify signature failed");