mirror of
https://git.wownero.com/wownero/wownero.git
synced 2024-08-15 01:03:23 +00:00
Fix bug in mempool get_transaction_stats histogram calculation
The 98th percentile position in the agebytes map was incorrectly calculated: it assumed the transactions in the mempool all have unique timestamps at second-granularity. This commit fixes this by correctly finding the right cumulative number of transactions in the map suffix. This bug could lead to an out-of-bounds write in the rare case that all transactions in the mempool were received (and added to the mempool) at a rate of at least 50 transactions per second. (More specifically, the number of *unique* receive_time values, which have second- granularity, must be at most 2% of the number of transactions in the mempool for this crash to trigger.) If this condition is satisfied, 'it' points to *before* the agebytes map, 'delta' gets a nonsense value, and the value of 'i' in the first stats.histo-filling loop will be out of bounds of stats.histo.
This commit is contained in:
parent
85014813cf
commit
6bbc646e6f
1 changed files with 10 additions and 3 deletions
|
@ -733,7 +733,7 @@ namespace cryptonote
|
||||||
if (meta.double_spend_seen)
|
if (meta.double_spend_seen)
|
||||||
++stats.num_double_spends;
|
++stats.num_double_spends;
|
||||||
return true;
|
return true;
|
||||||
}, false, include_unrelayed_txes);
|
}, false, include_unrelayed_txes);
|
||||||
stats.bytes_med = epee::misc_utils::median(weights);
|
stats.bytes_med = epee::misc_utils::median(weights);
|
||||||
if (stats.txs_total > 1)
|
if (stats.txs_total > 1)
|
||||||
{
|
{
|
||||||
|
@ -746,8 +746,15 @@ namespace cryptonote
|
||||||
/* If enough txs, spread the first 98% of results across
|
/* If enough txs, spread the first 98% of results across
|
||||||
* the first 9 bins, drop final 2% in last bin.
|
* the first 9 bins, drop final 2% in last bin.
|
||||||
*/
|
*/
|
||||||
it=agebytes.end();
|
it = agebytes.end();
|
||||||
for (size_t n=0; n <= end; n++, it--);
|
size_t cumulative_num = 0;
|
||||||
|
/* Since agebytes is not empty and end is nonzero, the
|
||||||
|
* below loop can always run at least once.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
--it;
|
||||||
|
cumulative_num += it->second.txs;
|
||||||
|
} while (it != agebytes.begin() && cumulative_num < end);
|
||||||
stats.histo_98pc = it->first;
|
stats.histo_98pc = it->first;
|
||||||
factor = 9;
|
factor = 9;
|
||||||
delta = it->first;
|
delta = it->first;
|
||||||
|
|
Loading…
Reference in a new issue