diff --git a/chain/src/pipe.rs b/chain/src/pipe.rs
index 3e253f565..99eba55e6 100644
--- a/chain/src/pipe.rs
+++ b/chain/src/pipe.rs
@@ -57,35 +57,19 @@ pub struct BlockContext<'a> {
}
/// Process a block header as part of processing a full block.
-/// We want to make sure the header is valid before we process the full block.
-fn process_header_for_block(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), Error> {
- let head = ctx.batch.head()?;
-
- // If we do not have the previous header then treat the block for this header
- // as an orphan.
- if ctx.batch.get_previous_header(header).is_err() {
- return Err(ErrorKind::Orphan.into());
- }
-
+/// We want to be sure the header is valid before processing the full block.
+fn process_header_for_block(
+ header: &BlockHeader,
+ is_fork: bool,
+ ctx: &mut BlockContext,
+) -> Result<(), Error> {
txhashset::header_extending(&mut ctx.txhashset, &mut ctx.batch, |extension| {
extension.force_rollback();
-
- let prev = extension.batch.get_previous_header(header)?;
- if prev.hash() == head.last_block_h {
- // Not a fork so we do not need to rewind or reapply any headers.
- } else {
- // Rewind and re-apply headers on the forked chain to
- // put the header extension in the correct forked state
- // (immediately prior to this new header).
+ if is_fork {
rewind_and_apply_header_fork(header, extension)?;
}
-
- // Check the current root is correct.
extension.validate_root(header)?;
-
- // Apply the new header to our header extension.
extension.apply_header(header)?;
-
Ok(())
})?;
@@ -96,6 +80,16 @@ fn process_header_for_block(header: &BlockHeader, ctx: &mut BlockContext) -> Res
Ok(())
}
+// Check if we already know about this block for various reasons
+// from cheapest to most expensive (delay hitting the db until last).
+fn check_known(block: &Block, ctx: &mut BlockContext) -> Result<(), Error> {
+ check_known_head(&block.header, ctx)?;
+ check_known_cache(&block.header, ctx)?;
+ check_known_orphans(&block.header, ctx)?;
+ check_known_store(&block.header, ctx)?;
+ Ok(())
+}
+
/// Runs the block processing pipeline, including validation and finding a
/// place for the new block in the chain.
/// Returns new head if chain head updated.
@@ -112,41 +106,29 @@ pub fn process_block(b: &Block, ctx: &mut BlockContext) -> Result