mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-18 22:35:39 +01:00
Merge pull request #5947
36cba8f Alert if it is very likely we are getting a bad chain (Gavin Andresen)
This commit is contained in:
59
src/main.cpp
59
src/main.cpp
@@ -28,6 +28,7 @@
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/math/distributions/poisson.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
using namespace std;
|
||||
@@ -1685,6 +1686,64 @@ void ThreadScriptCheck() {
|
||||
scriptcheckqueue.Thread();
|
||||
}
|
||||
|
||||
//
|
||||
// Called periodically asynchronously; alerts if it smells like
|
||||
// we're being fed a bad chain (blocks being generated much
|
||||
// too slowly or too quickly).
|
||||
//
|
||||
void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CChain& chain, int64_t nPowTargetSpacing)
|
||||
{
|
||||
if (initialDownloadCheck()) return;
|
||||
|
||||
static int64_t lastAlertTime = 0;
|
||||
int64_t now = GetAdjustedTime();
|
||||
if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
|
||||
|
||||
const int SPAN_HOURS=4;
|
||||
const int SPAN_SECONDS=SPAN_HOURS*60*60;
|
||||
int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing;
|
||||
|
||||
boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
|
||||
|
||||
std::string strWarning;
|
||||
int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
|
||||
|
||||
LOCK(cs);
|
||||
int h = chain.Height();
|
||||
while (h > 0 && chain[h]->GetBlockTime() >= startTime)
|
||||
--h;
|
||||
int nBlocks = chain.Height()-h;
|
||||
|
||||
// How likely is it to find that many by chance?
|
||||
double p = boost::math::pdf(poisson, nBlocks);
|
||||
|
||||
LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS);
|
||||
LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p);
|
||||
|
||||
// Aim for one false-positive about every fifty years of normal running:
|
||||
const int FIFTY_YEARS = 50*365*24*60*60;
|
||||
double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
|
||||
|
||||
if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED)
|
||||
{
|
||||
// Many fewer blocks than expected: alert!
|
||||
strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"),
|
||||
nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
|
||||
}
|
||||
else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED)
|
||||
{
|
||||
// Many more blocks than expected: alert!
|
||||
strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"),
|
||||
nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
|
||||
}
|
||||
if (!strWarning.empty())
|
||||
{
|
||||
strMiscWarning = strWarning;
|
||||
CAlert::Notify(strWarning, true);
|
||||
lastAlertTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t nTimeVerify = 0;
|
||||
static int64_t nTimeConnect = 0;
|
||||
static int64_t nTimeIndex = 0;
|
||||
|
||||
Reference in New Issue
Block a user