PPCoin: No safe mode when detecting longer invalid chain
authorScott Nadal <scott.nadal@gmail.com>
Mon, 30 Jul 2012 16:52:08 +0000 (17:52 +0100)
committerScott Nadal <scott.nadal@gmail.com>
Mon, 30 Jul 2012 16:52:08 +0000 (17:52 +0100)
        Enter safe mode when sync-checkpoint is too old
        Enter safe mode with high priority alert

src/bitcoinrpc.cpp
src/checkpoints.cpp
src/checkpoints.h
src/main.cpp

index e650eb0..5763d34 100644 (file)
@@ -2158,16 +2158,17 @@ extern map<uint256, CAlert> mapAlerts;
 // ThreadRPCServer: holds cs_main and acquiring cs_vSend in alert.RelayTo()/PushMessage()/BeginMessage()
 Value sendalert(const Array& params, bool fHelp)
 {
-    if (fHelp || params.size() < 5)
+    if (fHelp || params.size() < 6)
        throw runtime_error(
-            "sendalert <message> <privatekey> <minver> <maxver> <id> [cancelupto]\n"
+            "sendalert <message> <privatekey> <minver> <maxver> <priority> <id> [cancelupto]\n"
             "<message> is the alert text message\n"
             "<privatekey> is hex string of alert master private key\n"
-            "<minver> is the minimum applicable client version\n"
-            "<maxver> is the maximum applicable client version\n"
+            "<minver> is the minimum applicable internal client version\n"
+            "<maxver> is the maximum applicable internal client version\n"
+            "<priority> is integer priority number\n"
             "<id> is the alert id\n"
             "[cancelupto] cancels all alert id's up to this number\n"
-            "Returns true or false.");    
+            "Returns true or false.");
 
     CAlert alert;
     CKey key;
@@ -2175,13 +2176,13 @@ Value sendalert(const Array& params, bool fHelp)
     alert.strStatusBar = params[0].get_str();
     alert.nMinVer = params[2].get_int();
     alert.nMaxVer = params[3].get_int();
-    alert.nID = params[4].get_int();
-    if (params.size() > 5)
-        alert.nCancel = params[5].get_int();
+    alert.nPriority = params[4].get_int();
+    alert.nID = params[5].get_int();
+    if (params.size() > 6)
+        alert.nCancel = params[6].get_int();
     alert.nVersion = PROTOCOL_VERSION;
     alert.nRelayUntil = GetAdjustedTime() + 365*24*60*60;
     alert.nExpiration = GetAdjustedTime() + 365*24*60*60;
-    alert.nPriority = 1;
 
     CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION);
     sMsg << (CUnsignedAlert)alert;
@@ -2207,6 +2208,7 @@ Value sendalert(const Array& params, bool fHelp)
     result.push_back(Pair("nVersion", alert.nVersion));
     result.push_back(Pair("nMinVer", alert.nMinVer));
     result.push_back(Pair("nMaxVer", alert.nMaxVer));
+    result.push_back(Pair("nPriority", alert.nPriority));
     result.push_back(Pair("nID", alert.nID));
     if (alert.nCancel > 0)
         result.push_back(Pair("nCancel", alert.nCancel));
@@ -2892,6 +2894,7 @@ int CommandLineRPC(int argc, char *argv[])
         if (strMethod == "sendalert"              && n > 3) ConvertTo<boost::int64_t>(params[3]);
         if (strMethod == "sendalert"              && n > 4) ConvertTo<boost::int64_t>(params[4]);
         if (strMethod == "sendalert"              && n > 5) ConvertTo<boost::int64_t>(params[5]);
+        if (strMethod == "sendalert"              && n > 6) ConvertTo<boost::int64_t>(params[6]);
         if (strMethod == "sendmany"               && n > 1)
         {
             string s = params[1].get_str();
index 7de5883..45f1824 100644 (file)
@@ -194,7 +194,7 @@ namespace Checkpoints
         // 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))
+        while (pindex->pnext && (pindex->GetBlockTime() + CHECKPOINT_MAX_SPAN <= pindexBest->GetBlockTime() || pindex->nHeight + COINBASE_MATURITY - 20 <= pindexBest->nHeight))
             pindex = pindex->pnext;
         return pindex->GetBlockHash();
     }
@@ -325,7 +325,11 @@ namespace Checkpoints
             return error("SendSyncCheckpoint: Unable to sign checkpoint, check private key?");
 
         if(!checkpoint.ProcessSyncCheckpoint(NULL))
-            return error("SendSyncCheckpoint: Failed to process checkpoint.");
+        {
+            printf("WARNING: SendSyncCheckpoint: Failed to process checkpoint.\n");
+            return false;
+        }
+
         // Relay checkpoint
         {
             LOCK(cs_vNodes);
@@ -334,6 +338,16 @@ namespace Checkpoints
         }
         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 + COINBASE_MATURITY);
+    }
 }
 
 // ppcoin: sync-checkpoint master key
index f14e610..fb7ac4c 100644 (file)
@@ -45,6 +45,7 @@ namespace Checkpoints
     void AskForPendingSyncCheckpoint(CNode* pfrom);
     bool SetCheckpointPrivKey(std::string strPrivKey);
     bool SendSyncCheckpoint(uint256 hashCheckpoint);
+    bool IsMatureSyncCheckpoint();
 }
 
 // ppcoin: synchronized checkpoint
index cb4dd17..44f48fc 100644 (file)
@@ -971,8 +971,7 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
     }
     printf("InvalidChainFound: invalid block=%s  height=%d  trust=%s\n", pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, CBigNum(pindexNew->nChainTrust).ToString().c_str());
     printf("InvalidChainFound:  current best=%s  height=%d  trust=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, CBigNum(nBestChainTrust).ToString().c_str());
-    if (pindexBest && nBestInvalidTrust > nBestChainTrust + pindexBest->GetBlockTrust() * 6)
-        printf("InvalidChainFound: WARNING: Displayed transactions may not be correct!  You may need to upgrade, or other nodes may need to upgrade.\n");
+    // ppcoin: should not enter safe mode for longer invalid chain
 }
 
 void CBlock::UpdateTime(const CBlockIndex* pindexPrev)
@@ -2013,7 +2012,10 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
 
     // ppcoin: verify hash target and signature of coinstake tx
     if (pblock->IsProofOfStake() && !pblock->vtx[1].CheckProofOfStake(pblock->nBits))
-        return error("ProcessBlock() : check proof-of-stake failed for block %s", hash.ToString().c_str());
+    {
+        printf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str());
+        return false; // do not error here as we expect this during initial block download
+    }
 
     CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint();
     if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash))
@@ -2420,17 +2422,19 @@ string GetWarnings(string strFor)
         strStatusBar = strMiscWarning;
     }
 
-    // Longer invalid proof-of-work chain
-    if (pindexBest && nBestInvalidTrust > nBestChainTrust + pindexBest->GetBlockTrust() * 6)
+    // ppcoin: should not enter safe mode for longer invalid chain
+    // ppcoin: if sync-checkpoint too old enter safe mode
+    if (Checkpoints::IsMatureSyncCheckpoint())
     {
         nPriority = 2000;
-        strStatusBar = strRPC = "WARNING: Displayed transactions may not be correct!  You may need to upgrade, or other nodes may need to upgrade.";
+        strStatusBar = strRPC = "WARNING: Checkpoint is too old. Wait for block chain to download, or notify developers of the issue.";
     }
 
+    // ppcoin: if detected invalid checkpoint enter safe mode
     if (Checkpoints::hashInvalidCheckpoint != 0)
     {
         nPriority = 3000;
-        strStatusBar = strRPC = "WARNING: Invalid checkpoint found!  Displayed transactions may not be correct!  You may need to upgrade, or other nodes may need to upgrade.";
+        strStatusBar = strRPC = "WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or notify developers of the issue.";
     }
 
     // Alerts
@@ -2443,6 +2447,8 @@ string GetWarnings(string strFor)
             {
                 nPriority = alert.nPriority;
                 strStatusBar = alert.strStatusBar;
+                if (nPriority > 1000)
+                    strRPC = strStatusBar;  // ppcoin: safe mode for high alert
             }
         }
     }