diff --git a/sync/src/block_connector/write_block_chain.rs b/sync/src/block_connector/write_block_chain.rs index ce31253583..0bffbb0a48 100644 --- a/sync/src/block_connector/write_block_chain.rs +++ b/sync/src/block_connector/write_block_chain.rs @@ -307,47 +307,65 @@ where debug!("Repeat connect, current header is {} already.", block_id); return Ok(()); } - let (block_exist, fork) = self.find_or_fork(block.header())?; - match (block_exist, fork) { - //block has bean processed, so just trigger a head select. - (true, Some(branch)) => { - debug!( - "Block {} has bean processed, trigger head select, total_difficulty: {}", - block_id, - branch.get_total_difficulty()? - ); - WRITE_BLOCK_CHAIN_METRICS.duplicate_conn_count.inc(); - self.select_head(branch)?; - Ok(()) - } - (true, None) => { - self.main.update_chain_head(block.clone())?; + if self.main.current_header().id() == block.header().parent_hash() { + let connected = if execute { + self.main.apply(block.clone()) + } else { + self.main.apply_without_execute( + block.clone(), + remote_chain_state.expect("remote chain state not set"), + ) + }; + if connected.is_err() { + debug!("connected failed {:?}", block_id); + WRITE_BLOCK_CHAIN_METRICS.verify_fail_count.inc(); + } else { self.do_new_head(block.clone(), 1, vec![block], 0, vec![])?; - Ok(()) } - (false, Some(mut branch)) => { - let timer = WRITE_BLOCK_CHAIN_METRICS - .exe_block_time - .with_label_values(&["time"]) - .start_timer(); - let connected = if execute { - branch.apply(block) - } else { - branch.apply_without_execute( - block, - remote_chain_state.expect("remote chain state not set"), - ) - }; - timer.observe_duration(); - if connected.is_err() { - debug!("connected failed {:?}", block_id); - WRITE_BLOCK_CHAIN_METRICS.verify_fail_count.inc(); - } else { + connected + } else { + let (block_exist, fork) = self.find_or_fork(block.header())?; + match (block_exist, fork) { + //block has bean processed, so just trigger a head select. + (true, Some(branch)) => { + debug!( + "Block {} has bean processed, trigger head select, total_difficulty: {}", + block_id, + branch.get_total_difficulty()? + ); + WRITE_BLOCK_CHAIN_METRICS.duplicate_conn_count.inc(); self.select_head(branch)?; + Ok(()) + } + (true, None) => { + self.main.update_chain_head(block.clone())?; + self.do_new_head(block.clone(), 1, vec![block], 0, vec![])?; + Ok(()) + } + (false, Some(mut branch)) => { + let timer = WRITE_BLOCK_CHAIN_METRICS + .exe_block_time + .with_label_values(&["time"]) + .start_timer(); + let connected = if execute { + branch.apply(block) + } else { + branch.apply_without_execute( + block, + remote_chain_state.expect("remote chain state not set"), + ) + }; + timer.observe_duration(); + if connected.is_err() { + debug!("connected failed {:?}", block_id); + WRITE_BLOCK_CHAIN_METRICS.verify_fail_count.inc(); + } else { + self.select_head(branch)?; + } + connected } - connected + (_, None) => Err(ConnectBlockError::FutureBlock(Box::new(block)).into()), } - (_, None) => Err(ConnectBlockError::FutureBlock(Box::new(block)).into()), } } }