From cb7d8b7b5e5e33ebde37bdb0466d95af7207b655 Mon Sep 17 00:00:00 2001 From: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com> Date: Tue, 24 Oct 2023 23:35:24 +0100 Subject: [PATCH] fix cumulative diff calculations + sort timestamps before getting median we were not accounting for the genesis blocks difficulty of 1. --- consensus/src/context/difficulty.rs | 36 ++++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/consensus/src/context/difficulty.rs b/consensus/src/context/difficulty.rs index d3d90d1..6d28df5 100644 --- a/consensus/src/context/difficulty.rs +++ b/consensus/src/context/difficulty.rs @@ -170,28 +170,32 @@ impl DifficultyCache { /// /// Will return [`None`] if there aren't enough blocks. pub fn median_timestamp(&self, numb_blocks: usize) -> Option { - let timestamps = if self.last_accounted_height + 1 == u64::try_from(numb_blocks).unwrap() { - // if the chain height is equal to `numb_blocks` add the genesis block. - // otherwise if the chain height is less than `numb_blocks` None is returned - // and if its more than it would be excluded from calculations. - let mut timestamps = self.timestamps.clone(); - // all genesis blocks have a timestamp of 0. - // https://cuprate.github.io/monero-book/consensus_rules/genesis_block.html - timestamps.push_front(0); - timestamps.into() - } else { - self.timestamps - .range(self.timestamps.len().checked_sub(numb_blocks)?..) - .copied() - .collect::>() - }; + let mut timestamps = + if self.last_accounted_height + 1 == u64::try_from(numb_blocks).unwrap() { + // if the chain height is equal to `numb_blocks` add the genesis block. + // otherwise if the chain height is less than `numb_blocks` None is returned + // and if its more than it would be excluded from calculations. + let mut timestamps = self.timestamps.clone(); + // all genesis blocks have a timestamp of 0. + // https://cuprate.github.io/monero-book/consensus_rules/genesis_block.html + timestamps.push_front(0); + timestamps.into() + } else { + self.timestamps + .range(self.timestamps.len().checked_sub(numb_blocks)?..) + .copied() + .collect::>() + }; + timestamps.sort_unstable(); + debug_assert_eq!(timestamps.len(), numb_blocks); Some(median(×tamps)) } /// Returns the cumulative difficulty of the chain. pub fn cumulative_difficulty(&self) -> u128 { - self.cumulative_difficulties.back().copied().unwrap_or(0) + // the genesis block has a difficulty of 1 + self.cumulative_difficulties.back().copied().unwrap_or(1) } pub fn top_block_timestamp(&self) -> Option {