diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-06-12 16:41:21 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-06-12 16:44:36 +0200 |
commit | 8ccc07c077d338bbfc673afd1a9a188038df70d3 (patch) | |
tree | a48c9b586b8b59e08586b934e867ea40bc167854 /src | |
parent | ebab5d3c59558000f0e0fd18b7f26ed6f31ac21a (diff) | |
parent | 65b94545036ae6e38e79e9c7166a3ba1ddb83f66 (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.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 16 | ||||
-rw-r--r-- | src/main.h | 2 | ||||
-rw-r--r-- | src/test/alert_tests.cpp | 10 |
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 = ""; |