Remove bad chain alert partition check
As per meeting 2016-03-31 https://bitcoincore.org/en/meetings/2016/03/31/#bad-chain-alerts The partition checker was producing huge number of false-positives and was disabled in 0.12.1 on the understanding it would either be fixed in 0.13 or removed entirely from master if not.
This commit is contained in:
parent
520161480e
commit
ab8be98fdb
5 changed files with 0 additions and 150 deletions
|
@ -38,7 +38,6 @@ BITCOIN_TESTS =\
|
||||||
test/arith_uint256_tests.cpp \
|
test/arith_uint256_tests.cpp \
|
||||||
test/scriptnum10.h \
|
test/scriptnum10.h \
|
||||||
test/addrman_tests.cpp \
|
test/addrman_tests.cpp \
|
||||||
test/alert_tests.cpp \
|
|
||||||
test/amount_tests.cpp \
|
test/amount_tests.cpp \
|
||||||
test/allocator_tests.cpp \
|
test/allocator_tests.cpp \
|
||||||
test/base32_tests.cpp \
|
test/base32_tests.cpp \
|
||||||
|
|
|
@ -1416,12 +1416,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
|
|
||||||
StartNode(threadGroup, scheduler);
|
StartNode(threadGroup, scheduler);
|
||||||
|
|
||||||
// Monitor the chain, and alert if we get blocks much quicker or slower than expected
|
|
||||||
int64_t nPowTargetSpacing = Params().GetConsensus().nPowTargetSpacing;
|
|
||||||
CScheduler::Function f = boost::bind(&PartitionCheck, &IsInitialBlockDownload,
|
|
||||||
boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
|
|
||||||
scheduler.scheduleEvery(f, nPowTargetSpacing);
|
|
||||||
|
|
||||||
// ********************************************************* Step 12: finished
|
// ********************************************************* Step 12: finished
|
||||||
|
|
||||||
SetRPCWarmupFinished();
|
SetRPCWarmupFinished();
|
||||||
|
|
62
src/main.cpp
62
src/main.cpp
|
@ -2118,68 +2118,6 @@ void ThreadScriptCheck() {
|
||||||
scriptcheckqueue.Thread();
|
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 CBlockIndex *const &bestHeader,
|
|
||||||
int64_t nPowTargetSpacing)
|
|
||||||
{
|
|
||||||
if (bestHeader == NULL || 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);
|
|
||||||
const CBlockIndex* i = bestHeader;
|
|
||||||
int nBlocks = 0;
|
|
||||||
while (i->GetBlockTime() >= startTime) {
|
|
||||||
++nBlocks;
|
|
||||||
i = i->pprev;
|
|
||||||
if (i == NULL) return; // Ran out of chain, we must not be fully sync'ed
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
AlertNotify(strWarning);
|
|
||||||
lastAlertTime = now;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Protected by cs_main
|
// Protected by cs_main
|
||||||
VersionBitsCache versionbitscache;
|
VersionBitsCache versionbitscache;
|
||||||
|
|
||||||
|
|
|
@ -242,8 +242,6 @@ bool ProcessMessages(CNode* pfrom);
|
||||||
bool SendMessages(CNode* pto);
|
bool SendMessages(CNode* pto);
|
||||||
/** Run an instance of the script checking thread */
|
/** Run an instance of the script checking thread */
|
||||||
void ThreadScriptCheck();
|
void ThreadScriptCheck();
|
||||||
/** Try to detect Partition (network isolation) attacks against us */
|
|
||||||
void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, int64_t nPowTargetSpacing);
|
|
||||||
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
||||||
bool IsInitialBlockDownload();
|
bool IsInitialBlockDownload();
|
||||||
/** Format a string that describes several potential problems detected by the core.
|
/** Format a string that describes several potential problems detected by the core.
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
// Copyright (c) 2013-2015 The Bitcoin Core developers
|
|
||||||
// Distributed under the MIT software license, see the accompanying
|
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
||||||
|
|
||||||
// Unit tests for alert system
|
|
||||||
|
|
||||||
#include "chainparams.h"
|
|
||||||
#include "main.h" // For PartitionCheck
|
|
||||||
|
|
||||||
#include "test/testutil.h"
|
|
||||||
#include "test/test_bitcoin.h"
|
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(Alert_tests, TestingSetup)
|
|
||||||
|
|
||||||
|
|
||||||
static bool falseFunc() { return false; }
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(PartitionAlert)
|
|
||||||
{
|
|
||||||
// Test PartitionCheck
|
|
||||||
CCriticalSection csDummy;
|
|
||||||
CBlockIndex indexDummy[100];
|
|
||||||
CChainParams& params = Params(CBaseChainParams::MAIN);
|
|
||||||
int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing;
|
|
||||||
|
|
||||||
// Generate fake blockchain timestamps relative to
|
|
||||||
// an arbitrary time:
|
|
||||||
int64_t now = 1427379054;
|
|
||||||
SetMockTime(now);
|
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
indexDummy[i].phashBlock = NULL;
|
|
||||||
if (i == 0) indexDummy[i].pprev = NULL;
|
|
||||||
else indexDummy[i].pprev = &indexDummy[i-1];
|
|
||||||
indexDummy[i].nHeight = i;
|
|
||||||
indexDummy[i].nTime = now - (100-i)*nPowTargetSpacing;
|
|
||||||
// Other members don't matter, the partition check code doesn't
|
|
||||||
// use them
|
|
||||||
}
|
|
||||||
|
|
||||||
strMiscWarning = "";
|
|
||||||
|
|
||||||
// Test 1: chain with blocks every nPowTargetSpacing seconds,
|
|
||||||
// as normal, no worries:
|
|
||||||
PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
|
|
||||||
BOOST_CHECK_MESSAGE(strMiscWarning.empty(), strMiscWarning);
|
|
||||||
|
|
||||||
// Test 2: go 3.5 hours without a block, expect a warning:
|
|
||||||
now += 3*60*60+30*60;
|
|
||||||
SetMockTime(now);
|
|
||||||
PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
|
|
||||||
BOOST_CHECK(!strMiscWarning.empty());
|
|
||||||
BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
|
|
||||||
strMiscWarning = "";
|
|
||||||
|
|
||||||
// Test 3: test the "partition alerts only go off once per day"
|
|
||||||
// code:
|
|
||||||
now += 60*10;
|
|
||||||
SetMockTime(now);
|
|
||||||
PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
|
|
||||||
BOOST_CHECK(strMiscWarning.empty());
|
|
||||||
|
|
||||||
// Test 4: get 2.5 times as many blocks as expected:
|
|
||||||
now += 60*60*24; // Pretend it is a day later
|
|
||||||
SetMockTime(now);
|
|
||||||
int64_t quickSpacing = nPowTargetSpacing*2/5;
|
|
||||||
for (int i = 0; i < 100; i++) // Tweak chain timestamps:
|
|
||||||
indexDummy[i].nTime = now - (100-i)*quickSpacing;
|
|
||||||
PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
|
|
||||||
BOOST_CHECK(!strMiscWarning.empty());
|
|
||||||
BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
|
|
||||||
strMiscWarning = "";
|
|
||||||
|
|
||||||
SetMockTime(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
|
Loading…
Reference in a new issue