From 67e8b40c44f9f35033a73e435021878e2f05038c Mon Sep 17 00:00:00 2001 From: Scott Nadal Date: Mon, 30 Jul 2012 17:52:08 +0100 Subject: [PATCH] PPCoin: No safe mode when detecting longer invalid chain Enter safe mode when sync-checkpoint is too old Enter safe mode with high priority alert --- src/bitcoinrpc.cpp | 21 ++++++++++++--------- src/checkpoints.cpp | 18 ++++++++++++++++-- src/checkpoints.h | 1 + src/main.cpp | 20 +++++++++++++------- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index e650eb0..5763d34 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -2158,16 +2158,17 @@ extern map 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 [cancelupto]\n" + "sendalert [cancelupto]\n" " is the alert text message\n" " is hex string of alert master private key\n" - " is the minimum applicable client version\n" - " is the maximum applicable client version\n" + " is the minimum applicable internal client version\n" + " is the maximum applicable internal client version\n" + " is integer priority number\n" " 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(params[3]); if (strMethod == "sendalert" && n > 4) ConvertTo(params[4]); if (strMethod == "sendalert" && n > 5) ConvertTo(params[5]); + if (strMethod == "sendalert" && n > 6) ConvertTo(params[6]); if (strMethod == "sendmany" && n > 1) { string s = params[1].get_str(); diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 7de5883..45f1824 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -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 diff --git a/src/checkpoints.h b/src/checkpoints.h index f14e610..fb7ac4c 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -45,6 +45,7 @@ namespace Checkpoints void AskForPendingSyncCheckpoint(CNode* pfrom); bool SetCheckpointPrivKey(std::string strPrivKey); bool SendSyncCheckpoint(uint256 hashCheckpoint); + bool IsMatureSyncCheckpoint(); } // ppcoin: synchronized checkpoint diff --git a/src/main.cpp b/src/main.cpp index cb4dd17..44f48fc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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 } } } -- 1.7.1