From ff6bc38826ea584061f7c575ab5de9a514eb4832 Mon Sep 17 00:00:00 2001 From: Denis Kolodin Date: Thu, 7 Oct 2021 18:37:41 +0300 Subject: [PATCH] fix: use intermediate u64 to calculate average (#3432) Description --- Calculates `AverageLatency` using `u64` intermediate state. Motivation and Context --- If the samples are large enough the average sum can overflow. Using `u64` makes this event less likely. How Has This Been Tested? --- Manually. Function only. --- base_layer/p2p/src/services/liveness/state.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/base_layer/p2p/src/services/liveness/state.rs b/base_layer/p2p/src/services/liveness/state.rs index a4d9c50928..383652a2ab 100644 --- a/base_layer/p2p/src/services/liveness/state.rs +++ b/base_layer/p2p/src/services/liveness/state.rs @@ -24,6 +24,7 @@ use crate::proto::liveness::MetadataKey; use chrono::{NaiveDateTime, Utc}; use std::{ collections::{hash_map::RandomState, HashMap}, + convert::TryInto, time::Duration, }; use tari_comms::peer_manager::NodeId; @@ -224,12 +225,14 @@ impl AverageLatency { /// Calculate the average of the recorded samples pub fn calc_average(&self) -> u32 { - let samples = &self.samples; - if samples.is_empty() { - return 0; - } - - samples.iter().fold(0, |sum, x| sum + *x) / samples.len() as u32 + self.samples + .iter() + .map(|x| u64::from(*x)) + .fold(0, u64::saturating_add) + .checked_div(self.samples.len() as u64) + .unwrap_or_default() + .try_into() + .unwrap_or(u32::MAX) } }