diff --git a/chain/src/chain.rs b/chain/src/chain.rs index c604125ec..b0311beba 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -943,8 +943,8 @@ impl Chain { /// difficulty calculation (timestamp and previous difficulties). pub fn difficulty_iter(&self) -> store::DifficultyIter { let head = self.head().unwrap(); - let batch = self.store.batch().unwrap(); - store::DifficultyIter::from(head.last_block_h, batch) + let store = self.store.clone(); + store::DifficultyIter::from(head.last_block_h, store) } /// Check whether we have a block without reading it diff --git a/chain/src/pipe.rs b/chain/src/pipe.rs index 517f1dccc..92839e894 100644 --- a/chain/src/pipe.rs +++ b/chain/src/pipe.rs @@ -434,7 +434,7 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E // the _network_ difficulty of the previous block // (during testnet1 we use _block_ difficulty here) let child_batch = ctx.batch.child()?; - let diff_iter = store::DifficultyIter::from(header.previous, child_batch); + let diff_iter = store::DifficultyIter::from_batch(header.previous, child_batch); let network_difficulty = consensus::next_difficulty(diff_iter) .context(ErrorKind::Other("network difficulty".to_owned()))?; if target_difficulty != network_difficulty.clone() { diff --git a/chain/src/store.rs b/chain/src/store.rs index ed697c7ca..15eaaa7dc 100644 --- a/chain/src/store.rs +++ b/chain/src/store.rs @@ -575,7 +575,8 @@ impl<'a> Batch<'a> { /// calculation. pub struct DifficultyIter<'a> { start: Hash, - batch: Batch<'a>, + store: Option>, + batch: Option>, // maintain state for both the "next" header in this iteration // and its previous header in the chain ("next next" in the iteration) @@ -588,10 +589,23 @@ pub struct DifficultyIter<'a> { impl<'a> DifficultyIter<'a> { /// Build a new iterator using the provided chain store and starting from /// the provided block hash. - pub fn from(start: Hash, batch: Batch) -> DifficultyIter { + pub fn from<'b>(start: Hash, store: Arc) -> DifficultyIter<'b> { DifficultyIter { start, - batch, + store: Some(store), + batch: None, + header: None, + prev_header: None, + } + } + + /// Build a new iterator using the provided chain store batch and starting from + /// the provided block hash. + pub fn from_batch(start: Hash, batch: Batch) -> DifficultyIter { + DifficultyIter { + start, + store: None, + batch: Some(batch), header: None, prev_header: None, } @@ -605,7 +619,15 @@ impl<'a> Iterator for DifficultyIter<'a> { // Get both header and previous_header if this is the initial iteration. // Otherwise move prev_header to header and get the next prev_header. self.header = if self.header.is_none() { - self.batch.get_block_header(&self.start).ok() + if let Some(ref batch) = self.batch { + batch.get_block_header(&self.start).ok() + } else { + if let Some(ref store) = self.store { + store.get_block_header(&self.start).ok() + } else { + None + } + } } else { self.prev_header.clone() }; @@ -613,7 +635,15 @@ impl<'a> Iterator for DifficultyIter<'a> { // If we have a header we can do this iteration. // Otherwise we are done. if let Some(header) = self.header.clone() { - self.prev_header = self.batch.get_block_header(&header.previous).ok(); + if let Some(ref batch) = self.batch { + self.prev_header = batch.get_block_header(&header.previous).ok(); + } else { + if let Some(ref store) = self.store { + self.prev_header = store.get_block_header(&header.previous).ok(); + } else { + self.prev_header = None; + } + } let prev_difficulty = self .prev_header