From d56fde1346ccd32ca6a6e98d9a0a84c8fa9939e7 Mon Sep 17 00:00:00 2001 From: Scott Nadal Date: Mon, 11 Jun 2012 15:55:01 +0100 Subject: [PATCH] PPCoin: RPC command 'sendcheckpoint' --- src/bitcoinrpc.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++------ src/checkpoints.cpp | 6 +++++ src/checkpoints.h | 2 +- 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 4836fe3..033250f 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -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(vchPrivKey.begin(), vchPrivKey.end()))); + result.push_back(Pair("PublicKey", HexStr(key.GetPubKey()))); + return result; +} + extern CCriticalSection cs_mapAlerts; extern map 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 [checkpointhash]\n" + " is hex string of checkpoint master private key\n" + " 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(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(sMsg.begin(), sMsg.end()); + + vector 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 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 mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 8ea198c..4afdab9 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -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; } diff --git a/src/checkpoints.h b/src/checkpoints.h index d193a2a..8ea1ec7 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -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"); -- 1.7.1