aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2015-06-12 16:41:21 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2015-06-12 16:44:36 +0200
commit8ccc07c077d338bbfc673afd1a9a188038df70d3 (patch)
treea48c9b586b8b59e08586b934e867ea40bc167854 /src
parentebab5d3c59558000f0e0fd18b7f26ed6f31ac21a (diff)
parent65b94545036ae6e38e79e9c7166a3ba1ddb83f66 (diff)
Merge pull request #6256
65b9454 Use best header chain timestamps to detect partitioning (Gavin Andresen)
Diffstat (limited to 'src')
-rw-r--r--src/init.cpp2
-rw-r--r--src/main.cpp16
-rw-r--r--src/main.h2
-rw-r--r--src/test/alert_tests.cpp10
4 files changed, 16 insertions, 14 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 326cdf5205..b5f9a0310f 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1425,7 +1425,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& 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(chainActive), nPowTargetSpacing);
+ boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
scheduler.scheduleEvery(f, nPowTargetSpacing);
#ifdef ENABLE_WALLET
diff --git a/src/main.cpp b/src/main.cpp
index 69c972a79f..082ef6b6b2 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1723,9 +1723,10 @@ void ThreadScriptCheck() {
// 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)
+void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
+ int64_t nPowTargetSpacing)
{
- if (initialDownloadCheck()) return;
+ if (bestHeader == NULL || initialDownloadCheck()) return;
static int64_t lastAlertTime = 0;
int64_t now = GetAdjustedTime();
@@ -1741,10 +1742,13 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const
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;
+ 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);
diff --git a/src/main.h b/src/main.h
index 7eaf58d716..d87fec7868 100644
--- a/src/main.h
+++ b/src/main.h
@@ -186,7 +186,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle);
/** Run an instance of the script checking thread */
void ThreadScriptCheck();
/** Try to detect Partition (network isolation) attacks against us */
-void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CChain& chain, int64_t nPowTargetSpacing);
+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) */
bool IsInitialBlockDownload();
/** Format a string that describes several potential problems detected by the core */
diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp
index 22cb475e02..38dcc6023c 100644
--- a/src/test/alert_tests.cpp
+++ b/src/test/alert_tests.cpp
@@ -201,7 +201,6 @@ BOOST_AUTO_TEST_CASE(PartitionAlert)
{
// Test PartitionCheck
CCriticalSection csDummy;
- CChain chainDummy;
CBlockIndex indexDummy[100];
CChainParams& params = Params(CBaseChainParams::MAIN);
int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing;
@@ -220,17 +219,16 @@ BOOST_AUTO_TEST_CASE(PartitionAlert)
// Other members don't matter, the partition check code doesn't
// use them
}
- chainDummy.SetTip(&indexDummy[99]);
// Test 1: chain with blocks every nPowTargetSpacing seconds,
// as normal, no worries:
- PartitionCheck(falseFunc, csDummy, chainDummy, nPowTargetSpacing);
+ PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
BOOST_CHECK(strMiscWarning.empty());
// Test 2: go 3.5 hours without a block, expect a warning:
now += 3*60*60+30*60;
SetMockTime(now);
- PartitionCheck(falseFunc, csDummy, chainDummy, nPowTargetSpacing);
+ PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
BOOST_CHECK(!strMiscWarning.empty());
BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
strMiscWarning = "";
@@ -239,7 +237,7 @@ BOOST_AUTO_TEST_CASE(PartitionAlert)
// code:
now += 60*10;
SetMockTime(now);
- PartitionCheck(falseFunc, csDummy, chainDummy, nPowTargetSpacing);
+ PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
BOOST_CHECK(strMiscWarning.empty());
// Test 4: get 2.5 times as many blocks as expected:
@@ -248,7 +246,7 @@ BOOST_AUTO_TEST_CASE(PartitionAlert)
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, chainDummy, nPowTargetSpacing);
+ PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
BOOST_CHECK(!strMiscWarning.empty());
BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
strMiscWarning = "";