diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp old mode 100644 new mode 100755 index edb0ec82f4..354efbcd42 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -4,14 +4,13 @@ #include // for 'map_list_of()' #include + #include "checkpoints.h" + #include "txdb.h" #include "main.h" #include "uint256.h" -double GetGridcoinBalance(std::string SendersGRCAddress); -void SetAdvisory(); -bool InAdvisory(); static const int nCheckpointSpan = 10; @@ -26,8 +25,6 @@ namespace Checkpoints // timestamp before) // + Contains no strange transactions // - - static MapCheckpoints mapCheckpoints = boost::assign::map_list_of ( 0, hashGenesisBlock ) @@ -42,7 +39,7 @@ namespace Checkpoints ( 71000, uint256("0x708c3319912b19c3547fd9a9a2aa6426c3a4543e84f972b3070a24200bd4fcd3") ) ( 85000, uint256("0x928f0669b1f036561a2d53b7588b10c5ea2fcb9e2960a9be593b508a7fcceec1") ) ( 91000, uint256("0x8ed361fa50f6c16fbda4f2c7454dd818f2278151987324825bc1ec1eacfa9be2") ) - (101000, uint256("0x578efd18f7cd5191be3463a2b0db985375f48ee6e8a8940cc6b91d6847fa3614") ) + (101000, uint256("0x578efd18f7cd5191be3463a2b0db985375f48ee6e8a8940cc6b91d6847fa3614") ) (118000, uint256("0x8f8ea6eaeae707ab935b517f1c334e6324df75ad8e5f9fbc4d9fb3cc7aa2e69f") ) (120000, uint256("0xe64d19e39d564cc66e931e88c03207c19e4c9a873ca68ccef16ad712830da726") ) (122000, uint256("0xb35d4f385bba3c3cb3f9b6914edd6621bde8f78c8c42f58ec47131ed6aac82a9") ) @@ -53,15 +50,14 @@ namespace Checkpoints (500000, uint256("0x3916b53eaa0eb392ce5d7e4eaf7db4f745187743f167539ffa4dc1a30c06acbd") ) (700000, uint256("0x2e45c8a834675b505b96792d198c2dc970f560429c635479c347204044acc59b") ) (770000, uint256("0xfc13a63162bc0a5a09acc3f284cf959d6812a027bb54b342a0e1ccaaca8627ce") ) - (850000, uint256("0xc78b15f25ad990d02256907fab92ab37301d129eaea177fd04acacd56c0cbd22") ) - (950000, uint256("0x4be0afdb9273d232de0bc75b572d8bcfaa146d9efdbe4a4f1ab775334f175b0f") ) + (850000, uint256("0xc78b15f25ad990d02256907fab92ab37301d129eaea177fd04acacd56c0cbd22") ) + (950000, uint256("0x4be0afdb9273d232de0bc75b572d8bcfaa146d9efdbe4a4f1ab775334f175b0f") ) ; // TestNet has no checkpoints static MapCheckpoints mapCheckpointsTestnet = - boost::assign::map_list_of - ( 0, hashGenesisBlockTestNet ) - ; + boost::assign::map_list_of + ( 0, hashGenesisBlockTestNet ); bool CheckHardened(int nHeight, const uint256& hash) { @@ -76,6 +72,8 @@ namespace Checkpoints { MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints); + if (checkpoints.empty()) + return 0; return checkpoints.rbegin()->first; } @@ -93,456 +91,23 @@ namespace Checkpoints return NULL; } - // ppcoin: synchronized checkpoint (centrally broadcasted) - uint256 hashSyncCheckpoint = 0; - uint256 hashPendingCheckpoint = 0; - CSyncCheckpoint checkpointMessage; - CSyncCheckpoint checkpointMessagePending; - uint256 hashInvalidCheckpoint = 0; - CCriticalSection cs_hashSyncCheckpoint; - - // ppcoin: get last synchronized checkpoint - CBlockIndex* GetLastSyncCheckpoint() - { - LOCK(cs_hashSyncCheckpoint); - if (!mapBlockIndex.count(hashSyncCheckpoint)) - error("GetSyncCheckpoint: block index missing for current sync-checkpoint %s", hashSyncCheckpoint.ToString().c_str()); - else - return mapBlockIndex[hashSyncCheckpoint]; - return NULL; - } - - // ppcoin: only descendant of current sync-checkpoint is allowed - bool ValidateSyncCheckpoint(uint256 hashCheckpoint) - { - if (!mapBlockIndex.count(hashSyncCheckpoint)) - return error("ValidateSyncCheckpoint: block index missing for current sync-checkpoint %s", hashSyncCheckpoint.ToString().c_str()); - if (!mapBlockIndex.count(hashCheckpoint)) - return error("ValidateSyncCheckpoint: block index missing for received sync-checkpoint %s", hashCheckpoint.ToString().c_str()); - - CBlockIndex* pindexSyncCheckpoint = mapBlockIndex[hashSyncCheckpoint]; - CBlockIndex* pindexCheckpointRecv = mapBlockIndex[hashCheckpoint]; - - if (pindexCheckpointRecv->nHeight <= pindexSyncCheckpoint->nHeight) - { - // Received an older checkpoint, trace back from current checkpoint - // to the same height of the received checkpoint to verify - // that current checkpoint should be a descendant block - CBlockIndex* pindex = pindexSyncCheckpoint; - while (pindex->nHeight > pindexCheckpointRecv->nHeight) - if (!(pindex = pindex->pprev)) - return error("ValidateSyncCheckpoint: pprev null - block index structure failure"); - if (pindex->GetBlockHash() != hashCheckpoint) - { - if (CHECKPOINT_DISTRIBUTED_MODE==1) SetAdvisory(); - hashInvalidCheckpoint = hashCheckpoint; - return error("ValidateSyncCheckpoint: new sync-checkpoint %s is conflicting with current sync-checkpoint %s", hashCheckpoint.ToString().c_str(), hashSyncCheckpoint.ToString().c_str()); - } - return false; // ignore older checkpoint - } - - // Received checkpoint should be a descendant block of the current - // checkpoint. Trace back to the same height of current checkpoint - // to verify. - CBlockIndex* pindex = pindexCheckpointRecv; - while (pindex->nHeight > pindexSyncCheckpoint->nHeight) - if (!(pindex = pindex->pprev)) - return error("ValidateSyncCheckpoint: pprev2 null - block index structure failure"); - if (pindex->GetBlockHash() != hashSyncCheckpoint) - { - hashInvalidCheckpoint = hashCheckpoint; - if (CHECKPOINT_DISTRIBUTED_MODE==1) SetAdvisory(); - return error("ValidateSyncCheckpoint: new sync-checkpoint %s is not a descendant of current sync-checkpoint %s", hashCheckpoint.ToString().c_str(), hashSyncCheckpoint.ToString().c_str()); - } - return true; - } - - bool WriteSyncCheckpoint(const uint256& hashCheckpoint) - { - CTxDB txdb; - txdb.TxnBegin(); - if (!txdb.WriteSyncCheckpoint(hashCheckpoint)) - { - txdb.TxnAbort(); - return error("WriteSyncCheckpoint(): failed to write to db sync checkpoint %s", hashCheckpoint.ToString().c_str()); - } - if (!txdb.TxnCommit()) - return error("WriteSyncCheckpoint(): failed to commit to db sync checkpoint %s", hashCheckpoint.ToString().c_str()); - - Checkpoints::hashSyncCheckpoint = hashCheckpoint; - return true; - } - - bool AcceptPendingSyncCheckpoint() - { - LOCK(cs_hashSyncCheckpoint); - if (hashPendingCheckpoint != 0 && mapBlockIndex.count(hashPendingCheckpoint)) - { - if (!ValidateSyncCheckpoint(hashPendingCheckpoint)) - { - hashPendingCheckpoint = 0; - checkpointMessagePending.SetNull(); - return false; - } - - CTxDB txdb; - CBlockIndex* pindexCheckpoint = mapBlockIndex[hashPendingCheckpoint]; - if (!pindexCheckpoint->IsInMainChain()) - { - CBlock block; - if (!block.ReadFromDisk(pindexCheckpoint)) - return error("AcceptPendingSyncCheckpoint: ReadFromDisk failed for sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); - if (!block.SetBestChain(txdb, pindexCheckpoint)) - { - hashInvalidCheckpoint = hashPendingCheckpoint; - //SetAdvisory(); - //if (!InAdvisory()) - //{ - return error("AcceptPendingSyncCheckpoint: SetBestChain failed for sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); - //} - } - } - - if (!WriteSyncCheckpoint(hashPendingCheckpoint)) - return error("AcceptPendingSyncCheckpoint(): failed to write sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); - hashPendingCheckpoint = 0; - checkpointMessage = checkpointMessagePending; - checkpointMessagePending.SetNull(); - printf("AcceptPendingSyncCheckpoint : sync-checkpoint at %s\n", hashSyncCheckpoint.ToString().c_str()); - // relay the checkpoint - if (!checkpointMessage.IsNull()) - { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - checkpointMessage.RelayTo(pnode); - } - return true; - } - return false; - } - // Automatically select a suitable sync-checkpoint - uint256 AutoSelectSyncCheckpoint() + const CBlockIndex* AutoSelectSyncCheckpoint() { const CBlockIndex *pindex = pindexBest; // Search backward for a block within max span and maturity window - while (pindex->pprev && (pindex->GetBlockTime() + nCheckpointSpan * GetTargetSpacing(nBestHeight) > pindexBest->GetBlockTime() || pindex->nHeight + nCheckpointSpan > pindexBest->nHeight)) + while (pindex->pprev && pindex->nHeight + nCheckpointSpan > pindexBest->nHeight) pindex = pindex->pprev; - return pindex->GetBlockHash(); + return pindex; } // Check against synchronized checkpoint - bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev) - { - if (fTestNet) return true; // Testnet has no checkpoints - int nHeight = pindexPrev->nHeight + 1; - - LOCK(cs_hashSyncCheckpoint); - // sync-checkpoint should always be accepted block - assert(mapBlockIndex.count(hashSyncCheckpoint)); - const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint]; - - if (nHeight > pindexSync->nHeight) - { - // trace back to same height as sync-checkpoint - const CBlockIndex* pindex = pindexPrev; - while (pindex->nHeight > pindexSync->nHeight) - if (!(pindex = pindex->pprev)) - return error("CheckSync: pprev null - block index structure failure"); - if (pindex->nHeight < pindexSync->nHeight || pindex->GetBlockHash() != hashSyncCheckpoint) - return false; // only descendant of sync-checkpoint can pass check - } - if (nHeight == pindexSync->nHeight && hashBlock != hashSyncCheckpoint) - return false; // same height with sync-checkpoint - if (nHeight < pindexSync->nHeight && !mapBlockIndex.count(hashBlock)) - return false; // lower height than sync-checkpoint - return true; - } - - bool WantedByPendingSyncCheckpoint(uint256 hashBlock) - { - LOCK(cs_hashSyncCheckpoint); - if (hashPendingCheckpoint == 0) - return false; - if (hashBlock == hashPendingCheckpoint) - return true; - if (mapOrphanBlocks.count(hashPendingCheckpoint) - && hashBlock == WantedByOrphan(mapOrphanBlocks[hashPendingCheckpoint])) - return true; - return false; - } - - // ppcoin: reset synchronized checkpoint to last hardened checkpoint - bool ResetSyncCheckpoint() - { - LOCK(cs_hashSyncCheckpoint); - const uint256& hash = mapCheckpoints.rbegin()->second; - if (mapBlockIndex.count(hash) && !mapBlockIndex[hash]->IsInMainChain()) - { - // checkpoint block accepted but not yet in main chain - printf("ResetSyncCheckpoint: SetBestChain to hardened checkpoint %s\n", hash.ToString().c_str()); - CTxDB txdb; - CBlock block; - if (!block.ReadFromDisk(mapBlockIndex[hash])) - return error("ResetSyncCheckpoint: ReadFromDisk failed for hardened checkpoint %s", hash.ToString().c_str()); - if (!block.SetBestChain(txdb, mapBlockIndex[hash])) - { - return error("ResetSyncCheckpoint: SetBestChain failed for hardened checkpoint %s", hash.ToString().c_str()); - } - } - else if(!mapBlockIndex.count(hash)) - { - // checkpoint block not yet accepted - hashPendingCheckpoint = hash; - checkpointMessagePending.SetNull(); - printf("ResetSyncCheckpoint: pending for sync-checkpoint %s\n", hashPendingCheckpoint.ToString().c_str()); - } - - for (auto const& i : boost::adaptors::reverse(mapCheckpoints)) - { - const uint256& hash = i.second; - if (mapBlockIndex.count(hash) && mapBlockIndex[hash]->IsInMainChain()) - { - if (!WriteSyncCheckpoint(hash)) - return error("ResetSyncCheckpoint: failed to write sync checkpoint %s", hash.ToString().c_str()); - printf("ResetSyncCheckpoint: sync-checkpoint reset to %s\n", hashSyncCheckpoint.ToString().c_str()); - return true; - } - } - - return false; - } - - void AskForPendingSyncCheckpoint(CNode* pfrom) - { - LOCK(cs_hashSyncCheckpoint); - if (pfrom && hashPendingCheckpoint != 0 && (!mapBlockIndex.count(hashPendingCheckpoint)) && (!mapOrphanBlocks.count(hashPendingCheckpoint))) - pfrom->AskFor(CInv(MSG_BLOCK, hashPendingCheckpoint)); - } - - bool SetCheckpointPrivKey(std::string strPrivKey) - { - // Test signing a sync-checkpoint with genesis block - CSyncCheckpoint checkpoint; - printf("Signing Genesis...."); - - checkpoint.hashCheckpoint = !fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet; - CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); - sMsg << (CUnsignedSyncCheckpoint)checkpoint; - checkpoint.vchMsg = std::vector(sMsg.begin(), sMsg.end()); - - std::vector 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; - printf("Signing succeeded\r\n"); - return true; - } - - - bool SendSyncCheckpointWithBalance(uint256 hashCheckpoint, double nBalance, std::string SendingWalletAddress) + bool CheckSync(int nHeight) { - CSyncCheckpoint checkpoint; - checkpoint.hashCheckpoint = hashCheckpoint; - checkpoint.balance = nBalance; - checkpoint.SendingWalletAddress=SendingWalletAddress; - CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); - sMsg << (CUnsignedSyncCheckpoint)checkpoint; - checkpoint.vchMsg = std::vector(sMsg.begin(), sMsg.end()); - if (nBalance < MINIMUM_CHECKPOINT_TRANSMISSION_BALANCE) - { - printf("SendSyncCheckpoint: Balance < 1mil"); - return error("SendSyncCheckpoint: Balance < 1 mil"); - } + const CBlockIndex* pindexSync = AutoSelectSyncCheckpoint(); - if(!checkpoint.ProcessSyncCheckpoint(NULL)) - { - printf("WARNING: SendSyncCheckpoint: Failed to process checkpoint.\n"); + if (nHeight <= pindexSync->nHeight) return false; - } - - // Relay checkpoint - { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - checkpoint.RelayTo(pnode); - } - return true; - } - - - - bool SendSyncHashCheckpoint(uint256 hash1, std::string SendingWalletAddress) - { - //11-23-2014 - R HALFORD - Relay Global Checkpoint to all nodes - CSyncCheckpoint checkpoint; - checkpoint.hashCheckpointGlobal = hash1; - checkpoint.hashCheckpoint = hash1; - checkpoint.balance = 0; - checkpoint.SendingWalletAddress=SendingWalletAddress; - CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); - sMsg << (CUnsignedSyncCheckpoint)checkpoint; - checkpoint.vchMsg = std::vector(sMsg.begin(), sMsg.end()); - // Relay checkpoint - { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - checkpoint.RelayTo(pnode); - } - printf("Global Sync checkpoint broadcast successfully %s\r\n",checkpoint.hashCheckpointGlobal.GetHex().c_str()); return true; } - - - - bool SendSyncCheckpoint(uint256 hashCheckpoint) - { - CSyncCheckpoint checkpoint; - checkpoint.hashCheckpoint = hashCheckpoint; - CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); - sMsg << (CUnsignedSyncCheckpoint)checkpoint; - checkpoint.vchMsg = std::vector(sMsg.begin(), sMsg.end()); - - if (CSyncCheckpoint::strMasterPrivKey.empty()) - { - printf("SendSyncCheckpoint: Checkpoint Key Unavailable"); - return error("SendSyncCheckpoint: Checkpoint master key unavailable."); - } - - std::vector 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)) - { - printf("WARNING: SendSyncCheckpoint: Failed to process checkpoint.\n"); - return false; - } - - // Relay checkpoint - { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - checkpoint.RelayTo(pnode); - } - return true; - } - - // Is the sync-checkpoint outside maturity window? - bool IsMatureSyncCheckpoint() - { - LOCK(cs_hashSyncCheckpoint); - // sync-checkpoint should always be accepted block - assert(mapBlockIndex.count(hashSyncCheckpoint)); - const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint]; - return (nBestHeight >= pindexSync->nHeight + nCoinbaseMaturity || - pindexSync->GetBlockTime() + nStakeMinAge < GetAdjustedTime()); - } -} - - // Gridcoin: sync-checkpoint master key - - const std::string CSyncCheckpoint::strMasterPubKey = "04c858f58b8231219db37e0f714e9884e78ad996ea9ac5d9f72ea969a53e37701374b6348956f3df36fdc10c1e5e4a2a6bded85894ac2f7494700a2d63a4fff772"; - std::string CSyncCheckpoint::strMasterPrivKey = ""; - - - -// ppcoin: verify signature of sync-checkpoint message -bool CSyncCheckpoint::CheckSignature() -{ - CKey key; - if (!key.SetPubKey(ParseHex(CSyncCheckpoint::strMasterPubKey))) - return error("CSyncCheckpoint::CheckSignature() : SetPubKey failed"); - if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) - return error("CSyncCheckpoint::CheckSignature() : verify signature failed"); - - // Now unserialize the data - CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); - sMsg >> *(CUnsignedSyncCheckpoint*)this; - return true; -} - - - // Gridcoin: verify signature of sync-checkpoint message by balance - bool CSyncCheckpoint::CheckSignatureWithBalance() - { - // Verify Senders Balance: - //double senders_balance = GetGridcoinBalance(SendersWalletAddress); - if (balance < 1000000) - { - CKey key; - if (!key.SetPubKey(ParseHex(CSyncCheckpoint::strMasterPubKey))) - return error("CSyncCheckpoint::CheckSignature() : SetPubKey failed"); - if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) - return error("CSyncCheckpoint::CheckSignature() : verify signature failed"); - } - - // Now unserialize the data - CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); - sMsg >> *(CUnsignedSyncCheckpoint*)this; - return true; - } - - -// ppcoin: process synchronized checkpoint -bool CSyncCheckpoint::ProcessSyncCheckpoint(CNode* pfrom) -{ - if (!CheckSignature()) - { - printf("SyncCheckpoint::ProcessSyncCheckpoint::SignatureFailed"); - return false; - } - - LOCK(Checkpoints::cs_hashSyncCheckpoint); - if (!mapBlockIndex.count(hashCheckpoint)) - { - // We haven't received the checkpoint chain, keep the checkpoint as pending - Checkpoints::hashPendingCheckpoint = hashCheckpoint; - 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, true); - // ask directly as well in case rejected earlier by duplicate - // proof-of-stake because getblocks may not get it this time - pfrom->AskFor(CInv(MSG_BLOCK, mapOrphanBlocks.count(hashCheckpoint)? WantedByOrphan(mapOrphanBlocks[hashCheckpoint]) : hashCheckpoint)); - } - return false; - } - - if (!Checkpoints::ValidateSyncCheckpoint(hashCheckpoint)) - return false; - - CTxDB txdb; - CBlockIndex* pindexCheckpoint = mapBlockIndex[hashCheckpoint]; - if (!pindexCheckpoint->IsInMainChain()) - { - // checkpoint chain received but not yet main chain - CBlock block; - if (!block.ReadFromDisk(pindexCheckpoint)) - return error("ProcessSyncCheckpoint: ReadFromDisk failed for sync checkpoint %s", hashCheckpoint.ToString().c_str()); - if (!block.SetBestChain(txdb, pindexCheckpoint)) - { - Checkpoints::hashInvalidCheckpoint = hashCheckpoint; - if (CHECKPOINT_DISTRIBUTED_MODE==1) SetAdvisory(); - return error("ProcessSyncCheckpoint: SetBestChain failed for sync checkpoint %s", hashCheckpoint.ToString().c_str()); - - } - } - - if (!Checkpoints::WriteSyncCheckpoint(hashCheckpoint)) - return error("ProcessSyncCheckpoint(): failed to write sync checkpoint %s", hashCheckpoint.ToString().c_str()); - Checkpoints::checkpointMessage = *this; - Checkpoints::hashPendingCheckpoint = 0; - Checkpoints::checkpointMessagePending.SetNull(); - printf("ProcessSyncCheckpoint: sync-checkpoint at %s\n", hashCheckpoint.ToString().c_str()); - return true; } diff --git a/src/checkpoints.h b/src/checkpoints.h index a2771384d3..33563074ea 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -8,33 +8,14 @@ #include "net.h" #include "util.h" -#ifdef WIN32 -#undef STRICT -#undef PERMISSIVE -#undef ADVISORY -#endif - class uint256; class CBlockIndex; -class CSyncCheckpoint; - /** Block-chain checkpoints are compiled-in sanity checks. * They are updated every release or three. */ namespace Checkpoints { - /** Checkpointing mode */ - enum CPMode - { - // Scrict checkpoints policy, perform conflicts verification and resolve conflicts - STRICT = 0, - // Advisory checkpoints policy, perform conflicts verification but don't try to resolve them - ADVISORY = 1, - // Permissive checkpoints policy, don't perform any checking - PERMISSIVE = 2 - }; - // Returns true if block passes checkpoint checks bool CheckHardened(int nHeight, const uint256& hash); @@ -44,126 +25,8 @@ namespace Checkpoints // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint CBlockIndex* GetLastCheckpoint(const std::map& mapBlockIndex); - extern uint256 hashSyncCheckpoint; - extern CSyncCheckpoint checkpointMessage; - extern uint256 hashInvalidCheckpoint; - extern CCriticalSection cs_hashSyncCheckpoint; - - 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 SetCheckpointPrivKey(std::string strPrivKey); - bool SendSyncCheckpoint(uint256 hashCheckpoint); - bool SendSyncCheckpointWithBalance(uint256 hashCheckpoint, double nBalance, std::string SendingWalletAddress); - bool SendSyncHashCheckpoint(uint256 hash1, std::string SendingWalletAddress); - - bool IsMatureSyncCheckpoint(); + const CBlockIndex* AutoSelectSyncCheckpoint(); + bool CheckSync(int nHeight); } -// ppcoin: synchronized checkpoint -class CUnsignedSyncCheckpoint -{ -public: - int nVersion; - uint256 hashCheckpoint; // checkpoint block - double balance; - std::string SendingWalletAddress; - std::string SendersWalletAddress; - uint256 hashCheckpointGlobal; - - IMPLEMENT_SERIALIZE - ( - READWRITE(this->nVersion); - nVersion = this->nVersion; - READWRITE(hashCheckpoint); - READWRITE(balance); - READWRITE(SendingWalletAddress); - READWRITE(hashCheckpointGlobal); - ) - - void SetNull() - { - nVersion = 1; - hashCheckpoint = 0; - } - - std::string ToString() const - { - return strprintf( - "CSyncCheckpoint(\n" - " nVersion = %d\n" - " hashCheckpoint = %s\n" - ")\n", - nVersion, - hashCheckpoint.ToString().c_str()); - } - - void print() const - { - printf("%s", ToString().c_str()); - } -}; - -class CSyncCheckpoint : public CUnsignedSyncCheckpoint -{ -public: - static const std::string strMasterPubKey; - static std::string strMasterPrivKey; - - std::vector vchMsg; - std::vector vchSig; - - CSyncCheckpoint() - { - SetNull(); - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(vchMsg); - READWRITE(vchSig); - READWRITE(balance); - READWRITE(SendingWalletAddress); - READWRITE(hashCheckpointGlobal); - ) - - void SetNull() - { - CUnsignedSyncCheckpoint::SetNull(); - vchMsg.clear(); - vchSig.clear(); - } - - bool IsNull() const - { - return (hashCheckpoint == 0); - } - - uint256 GetHash() const - { - return SerializeHash(*this); - } - - bool RelayTo(CNode* pnode) const - { - // returns true if wasn't already sent - if (pnode->hashCheckpointKnown != hashCheckpoint) - { - pnode->hashCheckpointKnown = hashCheckpoint; - pnode->PushMessage("checkpoint", *this); - return true; - } - return false; - } - - bool CheckSignature(); - bool CheckSignatureWithBalance(); - bool ProcessSyncCheckpoint(CNode* pfrom); -}; - #endif diff --git a/src/init.cpp b/src/init.cpp old mode 100644 new mode 100755 index 7bea3e58ff..01b62fb726 --- a/src/init.cpp +++ b/src/init.cpp @@ -9,7 +9,6 @@ #include "init.h" #include "util.h" #include "ui_interface.h" -#include "checkpoints.h" #include #include #include @@ -46,7 +45,6 @@ extern unsigned int nNodeLifespan; extern unsigned int nDerivationMethodIndex; extern unsigned int nMinerSleep; extern bool fUseFastIndex; -extern enum Checkpoints::CPMode CheckpointsMode; void InitializeBoincProjects(); @@ -335,7 +333,6 @@ std::string HelpMessage() " -bind= " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" + " -dnsseed " + _("Find peers using DNS lookup (default: 1)") + "\n" + " -synctime " + _("Sync time with other nodes. Disable if time on your system is precise e.g. syncing with NTP (default: 1)") + "\n" + - " -cppolicy " + _("Sync checkpoints policy (default: strict)") + "\n" + " -banscore= " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" + " -bantime= " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" + " -maxreceivebuffer= " + _("Maximum per-connection receive buffer, *1000 bytes (default: 5000)") + "\n" + @@ -506,21 +503,6 @@ bool AppInit2(boost::shared_ptr threads) fUseFastIndex = GetBoolArg("-fastindex", false); nMinerSleep = GetArg("-minersleep", 8000); - - CheckpointsMode = Checkpoints::STRICT; - //CheckpointsMode = Checkpoints::ADVISORY; - - std::string strCpMode = GetArg("-cppolicy", "strict"); - - if(strCpMode == "strict") - CheckpointsMode = Checkpoints::STRICT; - - if(strCpMode == "advisory") - CheckpointsMode = Checkpoints::ADVISORY; - - if(strCpMode == "permissive") - CheckpointsMode = Checkpoints::PERMISSIVE; - nDerivationMethodIndex = 0; fTestNet = GetBoolArg("-testnet"); @@ -845,12 +827,6 @@ bool AppInit2(boost::shared_ptr threads) } } - if (mapArgs.count("-checkpointkey")) // ppcoin: checkpoint master priv key - { - if (!Checkpoints::SetCheckpointPrivKey(GetArg("-checkpointkey", ""))) - InitError(_("Unable to sign checkpoint, wrong checkpointkey?\n")); - } - for (auto const& strDest : mapMultiArgs["-seednode"]) AddOneShot(strDest); diff --git a/src/main.cpp b/src/main.cpp old mode 100644 new mode 100755 index 0b41f8b6cd..99fcdd5480 --- a/src/main.cpp +++ b/src/main.cpp @@ -149,9 +149,7 @@ extern std::string ExtractHTML(std::string HTMLdata, std::string tagstartprefix, CTxMemPool mempool; unsigned int nTransactionsUpdated = 0; unsigned int REORGANIZE_FAILED = 0; - unsigned int WHITELISTED_PROJECTS = 0; -unsigned int CHECKPOINT_VIOLATIONS = 0; int64_t nLastTallied = 0; int64_t nLastPing = 0; int64_t nLastPeek = 0; @@ -189,8 +187,6 @@ json_spirit::Array MagnitudeReportCSV(bool detail); int64_t nLastBlockSolved = 0; //Future timestamp int64_t nLastBlockSubmitted = 0; -uint256 muGlobalCheckpointHash = 0; -uint256 muGlobalCheckpointHashRelayed = 0; ///////////////////////MINOR VERSION//////////////////////////////// std::string msMasterProjectPublicKey = "049ac003b3318d9fe28b2830f6a95a2624ce2a69fb0c0c7ac0b513efcc1e93a6a6e8eba84481155dd82f2f1104e0ff62c69d662b0094639b7106abc5d84f948c0a"; // The Private Key is revealed by design, for public messages only: @@ -262,7 +258,6 @@ std::map mvDPORCopy; std::map mvResearchAge; std::map mvCPIDBlockHashes; -enum Checkpoints::CPMode CheckpointsMode; BlockFinder blockFinder; // Gridcoin - Rob Halford @@ -3506,19 +3501,6 @@ bool ForceReorganizeToHash(uint256 NewHash) return true; } - - -void SetAdvisory() -{ - CheckpointsMode = Checkpoints::ADVISORY; - -} - -bool InAdvisory() -{ - return (CheckpointsMode == Checkpoints::ADVISORY); -} - // Called from inside SetBestChain: attaches a block to the new best chain being built bool CBlock::SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew, bool fReorganizing) { @@ -4119,39 +4101,14 @@ bool CBlock::AcceptBlock(bool generated_by_me) //Grandfather if (nHeight > nGrandfather) { - bool cpSatisfies = Checkpoints::CheckSync(hash, pindexPrev); - // Check that the block satisfies synchronized checkpoint - if (CheckpointsMode == Checkpoints::STRICT && !cpSatisfies) - { - if (CHECKPOINT_DISTRIBUTED_MODE==1) - { - CHECKPOINT_VIOLATIONS++; - if (CHECKPOINT_VIOLATIONS > 3) - { - //For stability, move the client into ADVISORY MODE: - printf("Moving Gridcoin into Checkpoint ADVISORY mode.\r\n"); - CheckpointsMode = Checkpoints::ADVISORY; - } - } - return error("AcceptBlock() : rejected by synchronized checkpoint"); - } - - if (CheckpointsMode == Checkpoints::ADVISORY && !cpSatisfies) - strMiscWarning = _("WARNING: synchronized checkpoint violation detected, but skipped!"); - - if (CheckpointsMode == Checkpoints::ADVISORY && cpSatisfies && CHECKPOINT_DISTRIBUTED_MODE==1) - { - ///Move the client back into STRICT mode - CHECKPOINT_VIOLATIONS = 0; - printf("Moving Gridcoin into Checkpoint STRICT mode.\r\n"); - strMiscWarning = ""; - CheckpointsMode = Checkpoints::STRICT; - } + // Check that the block chain matches the known block chain up to a checkpoint + if (!Checkpoints::CheckHardened(nHeight, hash)) + return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lock-in at %d", nHeight)); // Enforce rule that the coinbase starts with serialized block height CScript expect = CScript() << nHeight; if (vtx[0].vin[0].scriptSig.size() < expect.size() || - !std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) + !std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) return DoS(100, error("AcceptBlock() : block height mismatch in coinbase")); } @@ -4175,8 +4132,6 @@ bool CBlock::AcceptBlock(bool generated_by_me) pnode->PushInventory(CInv(MSG_BLOCK, hash)); } - // ppcoin: check pending sync-checkpoint - Checkpoints::AcceptPendingSyncCheckpoint(); if (fDebug) printf("{ACC}"); nLastAskedForBlocks=GetAdjustedTime(); ResetTimerMain("OrphanBarrage"); @@ -4611,35 +4566,28 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock, bool generated_by_me) // ppcoin: check proof-of-stake // Limited duplicity on stake: prevents block flood attack // Duplicate stake allowed only when there is orphan child block - if (pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash) && !Checkpoints::WantedByPendingSyncCheckpoint(hash)) + if (pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash)) return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str()); - CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint(); - if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash)) + if (pblock->hashPrevBlock != hashBestChain) { // Extra checks to prevent "fill up memory by spamming with bogus blocks" + const CBlockIndex* pcheckpoint = Checkpoints::AutoSelectSyncCheckpoint(); int64_t deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime; - if (deltaTime < -10*60) + if (deltaTime < 0) { if (pfrom) pfrom->Misbehaving(1); return error("ProcessBlock() : block with timestamp before last checkpoint"); } - - } // Preliminary checks if (!pblock->CheckBlock("ProcessBlock", pindexBest->nHeight, 100*COIN)) return error("ProcessBlock() : CheckBlock FAILED"); - // ppcoin: ask for pending sync-checkpoint if any - if (!IsInitialBlockDownload()) - Checkpoints::AskForPendingSyncCheckpoint(pfrom); - - // If don't already have its previous block, shunt it off to holding area until we get it if (!mapBlockIndex.count(pblock->hashPrevBlock)) { @@ -4677,8 +4625,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock, bool generated_by_me) // Limited duplicity on stake: prevents block flood attack // Duplicate stake allowed only when there is orphan child block if (setStakeSeenOrphan.count(pblock->GetProofOfStake()) && - !mapOrphanBlocksByPrev.count(hash) && - !Checkpoints::WantedByPendingSyncCheckpoint(hash)) + !mapOrphanBlocksByPrev.count(hash)) return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for orphan block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, @@ -4730,9 +4677,6 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock, bool generated_by_me) } - - // if responsible for sync-checkpoint send it - if (false && pfrom && !CSyncCheckpoint::strMasterPrivKey.empty()) Checkpoints::SendSyncCheckpoint(Checkpoints::AutoSelectSyncCheckpoint()); printf("{PB}: ACC; \r\n"); GridcoinServices(); return true; @@ -4959,25 +4903,6 @@ bool LoadBlockIndex(bool fAllowNew) return error("LoadBlockIndex() : writing genesis block to disk failed"); if (!block.AddToBlockIndex(nFile, nBlockPos, hashGenesisBlock)) return error("LoadBlockIndex() : genesis block not accepted"); - - // ppcoin: initialize synchronized checkpoint - if (!Checkpoints::WriteSyncCheckpoint((!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet))) - return error("LoadBlockIndex() : failed to init sync checkpoint"); - } - - string strPubKey = ""; - - // if checkpoint master key changed must reset sync-checkpoint - if (!txdb.ReadCheckpointPubKey(strPubKey) || strPubKey != CSyncCheckpoint::strMasterPubKey) - { - // write checkpoint master key to db - txdb.TxnBegin(); - if (!txdb.WriteCheckpointPubKey(CSyncCheckpoint::strMasterPubKey)) - return error("LoadBlockIndex() : failed to write new checkpoint master key to db"); - if (!txdb.TxnCommit()) - return error("LoadBlockIndex() : failed to commit new checkpoint master key to db"); - if ((!fTestNet) && !Checkpoints::ResetSyncCheckpoint()) - return error("LoadBlockIndex() : failed to reset sync-checkpoint"); } return true; @@ -5935,23 +5860,6 @@ string GetWarnings(string strFor) strStatusBar = strMiscWarning; } - // if detected invalid checkpoint enter safe mode - if (Checkpoints::hashInvalidCheckpoint != 0) - { - if (CHECKPOINT_DISTRIBUTED_MODE==1) - { - //10-18-2014-Halford- If invalid checkpoint found, reboot the node: - printf("Moving Gridcoin into Checkpoint ADVISORY mode.\r\n"); - CheckpointsMode = Checkpoints::ADVISORY; - } - else - { - nPriority = 3000; - strStatusBar = strRPC = _("WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or notify developers."); - printf("WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or notify developers."); - } - } - // Alerts { LOCK(cs_mapAlerts); @@ -6400,23 +6308,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, item.second.RelayTo(pfrom); } - // Relay sync-checkpoint - { - LOCK(Checkpoints::cs_hashSyncCheckpoint); - if (!Checkpoints::checkpointMessage.IsNull()) - Checkpoints::checkpointMessage.RelayTo(pfrom); - } - pfrom->fSuccessfullyConnected = true; if (fDebug10) printf("receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str()); cPeerBlockCounts.input(pfrom->nStartingHeight); - - // ppcoin: ask for pending sync-checkpoint if any - if (!IsInitialBlockDownload()) - Checkpoints::AskForPendingSyncCheckpoint(pfrom); } else if (pfrom->nVersion == 0) { @@ -6669,40 +6566,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } } - else if (strCommand == "checkpoint") - { - CSyncCheckpoint checkpoint; - vRecv >> checkpoint; - //Checkpoint received from node with more than 1 Million GRC: - if (CHECKPOINT_DISTRIBUTED_MODE==0 || CHECKPOINT_DISTRIBUTED_MODE==1) - { - if (checkpoint.ProcessSyncCheckpoint(pfrom)) - { - // Relay - pfrom->hashCheckpointKnown = checkpoint.hashCheckpoint; - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - checkpoint.RelayTo(pnode); - } - } - else if (CHECKPOINT_DISTRIBUTED_MODE == 2) - { - // R HALFORD: One of our global GRC nodes solved a PoR block, store the last blockhash in memory - muGlobalCheckpointHash = checkpoint.hashCheckpointGlobal; - // Relay - pfrom->hashCheckpointKnown = checkpoint.hashCheckpointGlobal; - //Prevent broadcast storm: If not broadcast yet, relay the checkpoint globally: - if (muGlobalCheckpointHashRelayed != checkpoint.hashCheckpointGlobal && checkpoint.hashCheckpointGlobal != 0) - { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - { - checkpoint.RelayTo(pnode); - } - } - } - } - else if (strCommand == "getheaders") { CBlockLocator locator; diff --git a/src/main.h b/src/main.h index 29e4f3dcc1..c65bbcf08f 100755 --- a/src/main.h +++ b/src/main.h @@ -29,10 +29,6 @@ class CTxMemPool; static const int LAST_POW_BLOCK = 2050; extern unsigned int REORGANIZE_FAILED; extern unsigned int WHITELISTED_PROJECTS; -extern unsigned int CHECKPOINT_VIOLATIONS; -static const int MAX_NEWBIE_BLOCKS = 200; -static const int MAX_NEWBIE_BLOCKS_LEVEL2 = 500; -static const int CHECKPOINT_DISTRIBUTED_MODE = 50; static const int CONSENSUS_LOOKBACK = 5; //Amount of blocks to go back from best block, to avoid counting forked blocks static const int BLOCK_GRANULARITY = 10; //Consensus block divisor @@ -41,7 +37,6 @@ static const double NeuralNetworkMultiplier = 115000; extern int64_t nLastBlockSolved; extern int64_t nLastBlockSubmitted; -extern uint256 muGlobalCheckpointHashRelayed; extern std::string msMasterProjectPublicKey; extern std::string msMasterMessagePublicKey; extern std::string msMasterMessagePrivateKey; @@ -71,7 +66,6 @@ static const int64_t MAX_MONEY = 2000000000 * COIN; inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } /** Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. */ static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC -static const unsigned int MINIMUM_CHECKPOINT_TRANSMISSION_BALANCE = 4000000; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index d33275e208..2e4e7fa229 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -138,7 +138,6 @@ double CoinToDouble(double surrogate); int64_t GetRSAWeightByCPID(std::string cpid); double GetUntrustedMagnitude(std::string cpid, double& out_owed); extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry); -extern enum Checkpoints::CPMode CheckpointsMode; int ReindexWallet(); extern Array MagnitudeReportCSV(bool detail); std::string getfilecontents(std::string filename); @@ -4383,25 +4382,12 @@ Value getcheckpoint(const Array& params, bool fHelp) "Show info of synchronized checkpoint.\n"); Object result; - CBlockIndex* pindexCheckpoint; + const CBlockIndex* pindexCheckpoint = Checkpoints::AutoSelectSyncCheckpoint(); - result.push_back(Pair("synccheckpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str())); - pindexCheckpoint = mapBlockIndex[Checkpoints::hashSyncCheckpoint]; + result.push_back(Pair("synccheckpoint", pindexCheckpoint->GetBlockHash().ToString().c_str())); result.push_back(Pair("height", pindexCheckpoint->nHeight)); result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str())); - - // Check that the block satisfies synchronized checkpoint - if (CheckpointsMode == Checkpoints::STRICT) - result.push_back(Pair("policy", "strict")); - - if (CheckpointsMode == Checkpoints::ADVISORY) - result.push_back(Pair("policy", "advisory")); - - if (CheckpointsMode == Checkpoints::PERMISSIVE) - result.push_back(Pair("policy", "permissive")); - - if (mapArgs.count("-checkpointkey")) - result.push_back(Pair("checkpointmaster", true)); + result.push_back(Pair("policy", "rolling")); return result; } diff --git a/src/txdb-leveldb.cpp b/src/txdb-leveldb.cpp old mode 100644 new mode 100755 index 251a4b5b96..bcdace9c70 --- a/src/txdb-leveldb.cpp +++ b/src/txdb-leveldb.cpp @@ -14,7 +14,6 @@ #include #include "kernel.h" -#include "checkpoints.h" #include "txdb.h" #include "util.h" #include "main.h" @@ -279,26 +278,6 @@ bool CTxDB::WriteBestInvalidTrust(CBigNum bnBestInvalidTrust) return Write(string("bnBestInvalidTrust"), bnBestInvalidTrust); } -bool CTxDB::ReadSyncCheckpoint(uint256& hashCheckpoint) -{ - return Read(string("hashSyncCheckpoint"), hashCheckpoint); -} - -bool CTxDB::WriteSyncCheckpoint(uint256 hashCheckpoint) -{ - return Write(string("hashSyncCheckpoint"), hashCheckpoint); -} - -bool CTxDB::ReadCheckpointPubKey(string& strPubKey) -{ - return Read(string("strCheckpointPubKey"), strPubKey); -} - -bool CTxDB::WriteCheckpointPubKey(const string& strPubKey) -{ - return Write(string("strCheckpointPubKey"), strPubKey); -} - bool CTxDB::ReadGenericData(std::string KeyName, std::string& strValue) { return Read(string(KeyName.c_str()), strValue); @@ -478,11 +457,6 @@ bool CTxDB::LoadBlockIndex() hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, CBigNum(nBestChainTrust).ToString().c_str(), DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); - // NovaCoin: load hashSyncCheckpoint - if (!ReadSyncCheckpoint(Checkpoints::hashSyncCheckpoint)) - return error("CTxDB::LoadBlockIndex() : hashSyncCheckpoint not loaded"); - printf("LoadBlockIndex(): synchronized checkpoint %s\n", Checkpoints::hashSyncCheckpoint.ToString().c_str()); - // Load bnBestInvalidTrust, OK if it doesn't exist CBigNum bnBestInvalidTrust; ReadBestInvalidTrust(bnBestInvalidTrust);