From 78c9794d30c21d40a24f255c411e04f3eab5d512 Mon Sep 17 00:00:00 2001 From: Yeastplume Date: Fri, 7 Jan 2022 14:23:58 +0000 Subject: [PATCH] TUI Freeze Fix - Add manually maintained hash to difficulty iterator (#3684) * add manually managed hash to difficulty iterator * text fix * fix for hash-of-hash, review feedback --- chain/src/store.rs | 24 +++++++++++++++++++----- core/src/consensus.rs | 7 +++++++ core/tests/consensus_automated.rs | 1 + servers/src/grin/server.rs | 14 +------------- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/chain/src/store.rs b/chain/src/store.rs index 1cb471198..59c014d4a 100644 --- a/chain/src/store.rs +++ b/chain/src/store.rs @@ -441,6 +441,7 @@ pub struct DifficultyIter<'a> { // toward the genesis block (while maintaining current state) header: Option, prev_header: Option, + prev_header_hash: Option, } impl<'a> DifficultyIter<'a> { @@ -453,6 +454,7 @@ impl<'a> DifficultyIter<'a> { batch: None, header: None, prev_header: None, + prev_header_hash: None, } } @@ -465,6 +467,7 @@ impl<'a> DifficultyIter<'a> { batch: Some(batch), header: None, prev_header: None, + prev_header_hash: None, } } } @@ -479,18 +482,26 @@ impl<'a> Iterator for DifficultyIter<'a> { // Items returned by this iterator cannot be expected to correctly // calculate their own hash - This iterator is purely for iterating through // difficulty information - self.header = if self.header.is_none() { + let (cur_header, cur_header_hash) = if self.header.is_none() { if let Some(ref batch) = self.batch { - batch.get_block_header_skip_proof(&self.start).ok() + ( + batch.get_block_header_skip_proof(&self.start).ok(), + Some(self.start), + ) } else if let Some(ref store) = self.store { - store.get_block_header_skip_proof(&self.start).ok() + ( + store.get_block_header_skip_proof(&self.start).ok(), + Some(self.start), + ) } else { - None + (None, None) } } else { - self.prev_header.clone() + (self.prev_header.clone(), self.prev_header_hash) }; + self.header = cur_header; + // If we have a header we can do this iteration. // Otherwise we are done. if let Some(header) = self.header.clone() { @@ -502,6 +513,8 @@ impl<'a> Iterator for DifficultyIter<'a> { self.prev_header = None; } + self.prev_header_hash = Some(header.prev_hash); + let prev_difficulty = self .prev_header .clone() @@ -510,6 +523,7 @@ impl<'a> Iterator for DifficultyIter<'a> { let scaling = header.pow.secondary_scaling; Some(HeaderDifficultyInfo::new( + cur_header_hash, header.timestamp.timestamp() as u64, difficulty, scaling, diff --git a/core/src/consensus.rs b/core/src/consensus.rs index 7a1554ba3..0c4b2af0d 100644 --- a/core/src/consensus.rs +++ b/core/src/consensus.rs @@ -19,6 +19,7 @@ //! here. use crate::core::block::HeaderVersion; +use crate::core::hash::Hash; use crate::global; use crate::pow::Difficulty; use std::cmp::{max, min}; @@ -231,6 +232,8 @@ pub const INITIAL_DIFFICULTY: u64 = 1_000_000 * UNIT_DIFFICULTY; /// the header's PoW proof nonces from being deserialized on read #[derive(Clone, Debug, Eq, PartialEq)] pub struct HeaderDifficultyInfo { + /// Hash of this block + pub hash: Option, /// Timestamp of the header, 1 when not used (returned info) pub timestamp: u64, /// Network difficulty or next difficulty to use @@ -244,12 +247,14 @@ pub struct HeaderDifficultyInfo { impl HeaderDifficultyInfo { /// Default constructor pub fn new( + hash: Option, timestamp: u64, difficulty: Difficulty, secondary_scaling: u32, is_secondary: bool, ) -> HeaderDifficultyInfo { HeaderDifficultyInfo { + hash, timestamp, difficulty, secondary_scaling, @@ -261,6 +266,7 @@ impl HeaderDifficultyInfo { /// PoW factor pub fn from_ts_diff(timestamp: u64, difficulty: Difficulty) -> HeaderDifficultyInfo { HeaderDifficultyInfo { + hash: None, timestamp, difficulty, secondary_scaling: global::initial_graph_weight(), @@ -276,6 +282,7 @@ impl HeaderDifficultyInfo { secondary_scaling: u32, ) -> HeaderDifficultyInfo { HeaderDifficultyInfo { + hash: None, timestamp: 1, difficulty, secondary_scaling, diff --git a/core/tests/consensus_automated.rs b/core/tests/consensus_automated.rs index fd600ed82..a183c465a 100644 --- a/core/tests/consensus_automated.rs +++ b/core/tests/consensus_automated.rs @@ -213,6 +213,7 @@ fn repeat( pairs .map(|(t, d)| { HeaderDifficultyInfo::new( + None, cur_time + t as u64, *d, diff.secondary_scaling, diff --git a/servers/src/grin/server.rs b/servers/src/grin/server.rs index 89ba2a8da..5cfd92c10 100644 --- a/servers/src/grin/server.rs +++ b/servers/src/grin/server.rs @@ -463,19 +463,7 @@ impl Server { height += 1; - // We need to query again for the actual block hash, as - // the difficulty iterator doesn't contain enough info to - // create a hash - // The diff iterator returns 59 block headers 'before' 0 to give callers - // enough detail to calculate initial block difficulties. Ignore these. - let block_hash = if height < 0 { - ZERO_HASH - } else { - match self.chain.get_header_by_height(height as u64) { - Ok(h) => h.hash(), - Err(_) => ZERO_HASH, - } - }; + let block_hash = next.hash.unwrap_or(ZERO_HASH); DiffBlock { block_height: height,