return result;
}
-// ppcoin: send checkpoint
-Value sendcheckpoint(const Array& params, bool fHelp)
+// ppcoin: set checkpoint key
+Value setcheckpointkey(const Array& params, bool fHelp)
{
- if (fHelp || params.size() > 2 || params.size() < 1 )
+ if (fHelp || 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");
+ "setcheckpointkey <privatekey>\n"
+ "<privatekey> is hex string of checkpoint master private key\n");
CSyncCheckpoint checkpoint;
- CKey key;
-
- // 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");
- }
- else
- {
- checkpoint.hashCheckpoint = Checkpoints::AutoSelectSyncCheckpoint();
- if (checkpoint.hashCheckpoint == Checkpoints::hashSyncCheckpoint)
- throw runtime_error(
- "Unable to select a more recent sync-checkpoint");
- }
-
+ checkpoint.hashCheckpoint = hashGenesisBlock;
CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION);
sMsg << (CUnsignedSyncCheckpoint)checkpoint;
checkpoint.vchMsg = vector<unsigned char>(sMsg.begin(), sMsg.end());
vector<unsigned char> vchPrivKey = ParseHex(params[0].get_str());
+ 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))
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
- {
- LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
- checkpoint.RelayTo(pnode);
- }
+ CSyncCheckpoint::strMasterPrivKey = params[0].get_str();
- Object result;
- result.push_back(Pair("checkpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str()));
- result.push_back(Pair("height", mapBlockIndex[Checkpoints::hashSyncCheckpoint]->nHeight));
- result.push_back(Pair("timestamp", DateTimeStrFormat("%x %H:%M:%S", mapBlockIndex[Checkpoints::hashSyncCheckpoint]->GetBlockTime()).c_str()));
- return result;
+ return "checkpoint master key has been set.";
}
{ "repairwallet", &repairwallet, false},
{ "makekeypair", &makekeypair, false},
{ "sendalert", &sendalert, false},
- { "sendcheckpoint", &sendcheckpoint, false},
+ { "setcheckpointkey", &setcheckpointkey, false},
};
CRPCTable::CRPCTable()
return false;
}
- uint256 AutoSelectSyncCheckpoint()
- {
- // select a block some time ago
- CBlockIndex *pindex = mapBlockIndex[hashSyncCheckpoint];
- while (pindex->pnext && pindex->pnext->GetBlockTime() + CHECKPOINT_MIN_SPAN <= GetAdjustedTime())
- 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
if (pfrom && hashPendingCheckpoint != 0 && (!mapBlockIndex.count(hashPendingCheckpoint)) && (!mapOrphanBlocks.count(hashPendingCheckpoint)))
pfrom->AskFor(CInv(MSG_BLOCK, hashPendingCheckpoint));
}
+
+ bool SendSyncCheckpoint(uint256 hashCheckpoint)
+ {
+ CSyncCheckpoint checkpoint;
+ checkpoint.hashCheckpoint = hashCheckpoint;
+ CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION);
+ sMsg << (CUnsignedSyncCheckpoint)checkpoint;
+ checkpoint.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end());
+
+ if (CSyncCheckpoint::strMasterPrivKey.empty())
+ return error("SendSyncCheckpoint: Checkpoint master key unavailable.");
+ std::vector<unsigned char> vchPrivKey = ParseHex(CSyncCheckpoint::strMasterPrivKey);
+ 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 error("SendSyncCheckpoint: Unable to sign checkpoint, check private key?");
+
+ if(!checkpoint.ProcessSyncCheckpoint(NULL))
+ return error("SendSyncCheckpoint: Failed to process checkpoint.");
+ // Relay checkpoint
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ checkpoint.RelayTo(pnode);
+ }
+ return true;
+ }
}
// ppcoin: sync-checkpoint master key
const std::string CSyncCheckpoint::strMasterPubKey = "0424f20205e5da98ba632bbd278a11a6499585f62bfb2c782377ef59f0251daab8085fc31471bcb8180bc75ed0fa41bb50c7c084511d54015a3a5241d645c7268a";
+std::string CSyncCheckpoint::strMasterPrivKey = "";
+
// ppcoin: verify signature of sync-checkpoint message
bool CSyncCheckpoint::CheckSignature()
{
#include "util.h"
#define STAKE_MIN_AGE (60 * 60 * 24) // minimum age for coin age
-#define CHECKPOINT_MIN_SPAN (60 * 60 * 4) // 4 hours checkpoint
class uint256;
class CBlockIndex;
CBlockIndex* GetLastSyncCheckpoint();
bool WriteSyncCheckpoint(const uint256& hashCheckpoint);
bool AcceptPendingSyncCheckpoint();
- uint256 AutoSelectSyncCheckpoint();
bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev);
bool WantedByPendingSyncCheckpoint(uint256 hashBlock);
bool ResetSyncCheckpoint();
void AskForPendingSyncCheckpoint(CNode* pfrom);
+ bool SendSyncCheckpoint(uint256 hashCheckpoint);
}
// ppcoin: synchronized checkpoint
{
public:
static const std::string strMasterPubKey;
+ static std::string strMasterPrivKey;
std::vector<unsigned char> vchMsg;
std::vector<unsigned char> vchSig;
}
printf("ProcessBlock: ACCEPTED\n");
+
+ // ppcoin: if responsible for sync-checkpoint send it
+ if (pfrom && !CSyncCheckpoint::strMasterPrivKey.empty())
+ Checkpoints::SendSyncCheckpoint(hashBestChain);
+
return true;
}