core: improve block rate monitor trigger probabilities

The original intent of one false positive a week on average
was not met, since what we really want is not the probability
of having N blocks in T seconds, but either N blocks of fewer
in T seconds, or N blocks or more in T seconds.

Some of this could be cached since it calculates the same fairly
complex floating point values, but it seems pretty fast already.
This commit is contained in:
moneromooo-monero 2019-03-19 16:30:17 +00:00
parent e4b049da05
commit 1730a44f90
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3

View file

@ -1784,12 +1784,28 @@ namespace cryptonote
return f; return f;
} }
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------
static double probability(unsigned int blocks, unsigned int expected) static double probability1(unsigned int blocks, unsigned int expected)
{ {
// https://www.umass.edu/wsp/resources/poisson/#computing // https://www.umass.edu/wsp/resources/poisson/#computing
return pow(expected, blocks) / (factorial(blocks) * exp(expected)); return pow(expected, blocks) / (factorial(blocks) * exp(expected));
} }
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------
static double probability(unsigned int blocks, unsigned int expected)
{
double p = 0.0;
if (blocks <= expected)
{
for (unsigned int b = 0; b <= blocks; ++b)
p += probability1(b, expected);
}
else if (blocks > expected)
{
for (unsigned int b = blocks; b <= expected * 3 /* close enough */; ++b)
p += probability1(b, expected);
}
return p;
}
//-----------------------------------------------------------------------------------------------
bool core::check_block_rate() bool core::check_block_rate()
{ {
if (m_offline || m_target_blockchain_height > get_current_blockchain_height()) if (m_offline || m_target_blockchain_height > get_current_blockchain_height())