MCPcopy Create free account
hub / github.com/bitcoinxt/bitcoinxt / PartitionCheck

Function PartitionCheck

src/main.cpp:2171–2236  ·  view source on GitHub ↗

Called periodically asynchronously; alerts if it smells like we're being fed a bad chain (blocks being generated much too slowly or too quickly). Always returns the constant interval at which it should be scheduled.

Source from the content-addressed store, hash-verified

2169// Always returns the constant interval at which it should be scheduled.
2170//
2171int PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
2172 int64_t nPowTargetSpacing)
2173{
2174 // Aim for one false-positive about every fifty years of normal running:
2175 // The sample interval SPAN_SECONDS is chosen as the smallest multiple of target spacing expected
2176 // to trigger a too-few-blocks alert only once in fifty years (this will be when 0 blocks are seen):
2177 // blocks cdf(blocks, 0) alertThreshold
2178 // 11 1.67017e-5 4.18569e-6
2179 // 12 6.14421e-6 4.56621e-6
2180 // 13 2.26033e-6 4.94673e-6 <--- min such that (cdf < threshold)
2181 // 14 8.31529e-7 5.32725e-6
2182 // 15 3.05902e-7 5.70776e-6
2183 //TODO find BLOCKS_EXPECTED dynamically, for correct timing of non-10-minute intervals
2184 const int FIFTY_YEARS = 50*365*24*60*60;
2185 const int BLOCKS_EXPECTED = 13;
2186 const int SPAN_SECONDS = BLOCKS_EXPECTED * nPowTargetSpacing;
2187 double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
2188
2189 if (bestHeader == NULL || initialDownloadCheck()) return SPAN_SECONDS;
2190
2191 static int64_t lastAlertTime = 0;
2192 int64_t now = GetAdjustedTime();
2193 if (lastAlertTime > now-60*60*24) return SPAN_SECONDS; // Alert at most once per day
2194
2195 boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
2196
2197 std::string strWarning;
2198 int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
2199
2200 LOCK(cs);
2201 const CBlockIndex* i = bestHeader;
2202 int nBlocks = 0;
2203 while (i->GetBlockTime() >= startTime) {
2204 ++nBlocks;
2205 i = i->pprev;
2206 if (i == NULL) return SPAN_SECONDS; // Ran out of chain, we must not be fully sync'ed
2207 }
2208
2209 // How likely is it to find at least that many by chance?
2210 double pHigh = 1.0 - boost::math::cdf(poisson, std::max(0, nBlocks - 1));
2211 // How likely is it to find at most that few by chance?
2212 double pLow = boost::math::cdf(poisson, nBlocks);
2213
2214 LogPrint("partitioncheck", "%s: Found %d blocks in the last %d seconds\n", __func__, nBlocks, SPAN_SECONDS);
2215 LogPrint("partitioncheck", "%s: likelihood that many: %g, that few: %g\n", __func__, pHigh, pLow);
2216
2217 if (pLow <= alertThreshold)
2218 {
2219 // Many fewer blocks than expected: alert!
2220 strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d seconds (%d expected)"),
2221 nBlocks, SPAN_SECONDS, BLOCKS_EXPECTED);
2222 }
2223 else if (pHigh <= alertThreshold)
2224 {
2225 // Many more blocks than expected: alert!
2226 strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d seconds (%d expected)"),
2227 nBlocks, SPAN_SECONDS, BLOCKS_EXPECTED);
2228 }

Callers 2

AppInit2Function · 0.85
BOOST_AUTO_TEST_CASEFunction · 0.85

Calls 5

GetAdjustedTimeFunction · 0.85
_Function · 0.85
AlertNotifyFunction · 0.85
GetBlockTimeMethod · 0.45
emptyMethod · 0.45

Tested by 1

BOOST_AUTO_TEST_CASEFunction · 0.68