chain difficulty_iter don't need a WriteTransaction batch (#1710)

This commit is contained in:
Gary Yu 2018-10-10 16:49:07 +08:00 committed by GitHub
parent 009baa1b91
commit fa656ca44a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 8 deletions

View file

@ -943,8 +943,8 @@ impl Chain {
/// difficulty calculation (timestamp and previous difficulties). /// difficulty calculation (timestamp and previous difficulties).
pub fn difficulty_iter(&self) -> store::DifficultyIter { pub fn difficulty_iter(&self) -> store::DifficultyIter {
let head = self.head().unwrap(); let head = self.head().unwrap();
let batch = self.store.batch().unwrap(); let store = self.store.clone();
store::DifficultyIter::from(head.last_block_h, batch) store::DifficultyIter::from(head.last_block_h, store)
} }
/// Check whether we have a block without reading it /// Check whether we have a block without reading it

View file

@ -434,7 +434,7 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E
// the _network_ difficulty of the previous block // the _network_ difficulty of the previous block
// (during testnet1 we use _block_ difficulty here) // (during testnet1 we use _block_ difficulty here)
let child_batch = ctx.batch.child()?; 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) let network_difficulty = consensus::next_difficulty(diff_iter)
.context(ErrorKind::Other("network difficulty".to_owned()))?; .context(ErrorKind::Other("network difficulty".to_owned()))?;
if target_difficulty != network_difficulty.clone() { if target_difficulty != network_difficulty.clone() {

View file

@ -575,7 +575,8 @@ impl<'a> Batch<'a> {
/// calculation. /// calculation.
pub struct DifficultyIter<'a> { pub struct DifficultyIter<'a> {
start: Hash, start: Hash,
batch: Batch<'a>, store: Option<Arc<ChainStore>>,
batch: Option<Batch<'a>>,
// maintain state for both the "next" header in this iteration // maintain state for both the "next" header in this iteration
// and its previous header in the chain ("next next" in the 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> { impl<'a> DifficultyIter<'a> {
/// Build a new iterator using the provided chain store and starting from /// Build a new iterator using the provided chain store and starting from
/// the provided block hash. /// the provided block hash.
pub fn from(start: Hash, batch: Batch) -> DifficultyIter { pub fn from<'b>(start: Hash, store: Arc<ChainStore>) -> DifficultyIter<'b> {
DifficultyIter { DifficultyIter {
start, 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, header: None,
prev_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. // Get both header and previous_header if this is the initial iteration.
// Otherwise move prev_header to header and get the next prev_header. // Otherwise move prev_header to header and get the next prev_header.
self.header = if self.header.is_none() { 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 { } else {
self.prev_header.clone() self.prev_header.clone()
}; };
@ -613,7 +635,15 @@ impl<'a> Iterator for DifficultyIter<'a> {
// If we have a header we can do this iteration. // If we have a header we can do this iteration.
// Otherwise we are done. // Otherwise we are done.
if let Some(header) = self.header.clone() { 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 let prev_difficulty = self
.prev_header .prev_header