Skip to content

Commit 8ccc07c

Browse files
committed
Merge pull request #6256
65b9454 Use best header chain timestamps to detect partitioning (Gavin Andresen)
2 parents ebab5d3 + 65b9454 commit 8ccc07c

File tree

4 files changed

+16
-14
lines changed

4 files changed

+16
-14
lines changed

src/init.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
14251425
// Monitor the chain, and alert if we get blocks much quicker or slower than expected
14261426
int64_t nPowTargetSpacing = Params().GetConsensus().nPowTargetSpacing;
14271427
CScheduler::Function f = boost::bind(&PartitionCheck, &IsInitialBlockDownload,
1428-
boost::ref(cs_main), boost::cref(chainActive), nPowTargetSpacing);
1428+
boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
14291429
scheduler.scheduleEvery(f, nPowTargetSpacing);
14301430

14311431
#ifdef ENABLE_WALLET

src/main.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,9 +1723,10 @@ void ThreadScriptCheck() {
17231723
// we're being fed a bad chain (blocks being generated much
17241724
// too slowly or too quickly).
17251725
//
1726-
void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CChain& chain, int64_t nPowTargetSpacing)
1726+
void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
1727+
int64_t nPowTargetSpacing)
17271728
{
1728-
if (initialDownloadCheck()) return;
1729+
if (bestHeader == NULL || initialDownloadCheck()) return;
17291730

17301731
static int64_t lastAlertTime = 0;
17311732
int64_t now = GetAdjustedTime();
@@ -1741,10 +1742,13 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const
17411742
int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
17421743

17431744
LOCK(cs);
1744-
int h = chain.Height();
1745-
while (h > 0 && chain[h]->GetBlockTime() >= startTime)
1746-
--h;
1747-
int nBlocks = chain.Height()-h;
1745+
const CBlockIndex* i = bestHeader;
1746+
int nBlocks = 0;
1747+
while (i->GetBlockTime() >= startTime) {
1748+
++nBlocks;
1749+
i = i->pprev;
1750+
if (i == NULL) return; // Ran out of chain, we must not be fully sync'ed
1751+
}
17481752

17491753
// How likely is it to find that many by chance?
17501754
double p = boost::math::pdf(poisson, nBlocks);

src/main.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle);
186186
/** Run an instance of the script checking thread */
187187
void ThreadScriptCheck();
188188
/** Try to detect Partition (network isolation) attacks against us */
189-
void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CChain& chain, int64_t nPowTargetSpacing);
189+
void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, int64_t nPowTargetSpacing);
190190
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
191191
bool IsInitialBlockDownload();
192192
/** Format a string that describes several potential problems detected by the core */

src/test/alert_tests.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ BOOST_AUTO_TEST_CASE(PartitionAlert)
201201
{
202202
// Test PartitionCheck
203203
CCriticalSection csDummy;
204-
CChain chainDummy;
205204
CBlockIndex indexDummy[100];
206205
CChainParams& params = Params(CBaseChainParams::MAIN);
207206
int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing;
@@ -220,17 +219,16 @@ BOOST_AUTO_TEST_CASE(PartitionAlert)
220219
// Other members don't matter, the partition check code doesn't
221220
// use them
222221
}
223-
chainDummy.SetTip(&indexDummy[99]);
224222

225223
// Test 1: chain with blocks every nPowTargetSpacing seconds,
226224
// as normal, no worries:
227-
PartitionCheck(falseFunc, csDummy, chainDummy, nPowTargetSpacing);
225+
PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
228226
BOOST_CHECK(strMiscWarning.empty());
229227

230228
// Test 2: go 3.5 hours without a block, expect a warning:
231229
now += 3*60*60+30*60;
232230
SetMockTime(now);
233-
PartitionCheck(falseFunc, csDummy, chainDummy, nPowTargetSpacing);
231+
PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
234232
BOOST_CHECK(!strMiscWarning.empty());
235233
BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
236234
strMiscWarning = "";
@@ -239,7 +237,7 @@ BOOST_AUTO_TEST_CASE(PartitionAlert)
239237
// code:
240238
now += 60*10;
241239
SetMockTime(now);
242-
PartitionCheck(falseFunc, csDummy, chainDummy, nPowTargetSpacing);
240+
PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
243241
BOOST_CHECK(strMiscWarning.empty());
244242

245243
// Test 4: get 2.5 times as many blocks as expected:
@@ -248,7 +246,7 @@ BOOST_AUTO_TEST_CASE(PartitionAlert)
248246
int64_t quickSpacing = nPowTargetSpacing*2/5;
249247
for (int i = 0; i < 100; i++) // Tweak chain timestamps:
250248
indexDummy[i].nTime = now - (100-i)*quickSpacing;
251-
PartitionCheck(falseFunc, csDummy, chainDummy, nPowTargetSpacing);
249+
PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
252250
BOOST_CHECK(!strMiscWarning.empty());
253251
BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
254252
strMiscWarning = "";

0 commit comments

Comments
 (0)