Log a chain-reorg. (#1715)
* Log a chain-reorg. * Nicer output * Use imported rather than enacted. Enacted can include previously imported blocks which makes the info incorrect.
This commit is contained in:
parent
431ba5e260
commit
856657e39a
@ -514,6 +514,13 @@ impl BlockChain {
|
||||
|
||||
let info = self.block_info(bytes);
|
||||
|
||||
if let BlockLocation::BranchBecomingCanonChain(ref d) = info.location {
|
||||
info!(target: "reorg", "{} Using {} (#{})", Colour::Yellow.bold().paint("Switching fork to a new branch."), info.hash, info.number);
|
||||
info!(target: "reorg", "{}{}", Colour::Red.bold().paint("Retracting"), d.retracted.iter().fold(String::new(), |acc, h| format!("{} {}", acc, h)));
|
||||
info!(target: "reorg", "{} {} (#{})", Colour::Blue.bold().paint("Leaving"), d.ancestor, self.block_details(&d.ancestor).expect("`ancestor` is in the route; qed").number);
|
||||
info!(target: "reorg", "{}{}", Colour::Green.bold().paint("Enacting"), d.enacted.iter().fold(String::new(), |acc, h| format!("{} {}", acc, h)));
|
||||
}
|
||||
|
||||
self.apply_update(ExtrasUpdate {
|
||||
block_hashes: self.prepare_block_hashes_update(bytes, &info),
|
||||
block_details: self.prepare_block_details_update(bytes, &info),
|
||||
@ -526,6 +533,48 @@ impl BlockChain {
|
||||
ImportRoute::from(info)
|
||||
}
|
||||
|
||||
/// Get inserted block info which is critical to prepare extras updates.
|
||||
fn block_info(&self, block_bytes: &[u8]) -> BlockInfo {
|
||||
let block = BlockView::new(block_bytes);
|
||||
let header = block.header_view();
|
||||
let hash = block.sha3();
|
||||
let number = header.number();
|
||||
let parent_hash = header.parent_hash();
|
||||
let parent_details = self.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash));
|
||||
let total_difficulty = parent_details.total_difficulty + header.difficulty();
|
||||
let is_new_best = total_difficulty > self.best_block_total_difficulty();
|
||||
|
||||
BlockInfo {
|
||||
hash: hash,
|
||||
number: number,
|
||||
total_difficulty: total_difficulty,
|
||||
location: if is_new_best {
|
||||
// on new best block we need to make sure that all ancestors
|
||||
// are moved to "canon chain"
|
||||
// find the route between old best block and the new one
|
||||
let best_hash = self.best_block_hash();
|
||||
let route = self.tree_route(best_hash, parent_hash);
|
||||
|
||||
assert_eq!(number, parent_details.number + 1);
|
||||
|
||||
match route.blocks.len() {
|
||||
0 => BlockLocation::CanonChain,
|
||||
_ => {
|
||||
let retracted = route.blocks.iter().take(route.index).cloned().collect::<Vec<_>>().into_iter().collect::<Vec<_>>();
|
||||
let enacted = route.blocks.into_iter().skip(route.index).collect::<Vec<_>>();
|
||||
BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData {
|
||||
ancestor: route.ancestor,
|
||||
enacted: enacted,
|
||||
retracted: retracted,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BlockLocation::Branch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies extras update.
|
||||
fn apply_update(&self, update: ExtrasUpdate) {
|
||||
let batch = DBTransaction::new();
|
||||
@ -613,48 +662,6 @@ impl BlockChain {
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
/// Get inserted block info which is critical to prepare extras updates.
|
||||
fn block_info(&self, block_bytes: &[u8]) -> BlockInfo {
|
||||
let block = BlockView::new(block_bytes);
|
||||
let header = block.header_view();
|
||||
let hash = block.sha3();
|
||||
let number = header.number();
|
||||
let parent_hash = header.parent_hash();
|
||||
let parent_details = self.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash));
|
||||
let total_difficulty = parent_details.total_difficulty + header.difficulty();
|
||||
let is_new_best = total_difficulty > self.best_block_total_difficulty();
|
||||
|
||||
BlockInfo {
|
||||
hash: hash,
|
||||
number: number,
|
||||
total_difficulty: total_difficulty,
|
||||
location: if is_new_best {
|
||||
// on new best block we need to make sure that all ancestors
|
||||
// are moved to "canon chain"
|
||||
// find the route between old best block and the new one
|
||||
let best_hash = self.best_block_hash();
|
||||
let route = self.tree_route(best_hash, parent_hash);
|
||||
|
||||
assert_eq!(number, parent_details.number + 1);
|
||||
|
||||
match route.blocks.len() {
|
||||
0 => BlockLocation::CanonChain,
|
||||
_ => {
|
||||
let retracted = route.blocks.iter().take(route.index).cloned().collect::<Vec<H256>>();
|
||||
|
||||
BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData {
|
||||
ancestor: route.ancestor,
|
||||
enacted: route.blocks.into_iter().skip(route.index).collect(),
|
||||
retracted: retracted.into_iter().rev().collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BlockLocation::Branch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This function returns modified block hashes.
|
||||
fn prepare_block_hashes_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap<BlockNumber, H256> {
|
||||
let mut block_hashes = HashMap::new();
|
||||
|
@ -154,13 +154,13 @@ impl Informant {
|
||||
}
|
||||
|
||||
impl ChainNotify for Informant {
|
||||
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, enacted: Vec<H256>, _retracted: Vec<H256>, _sealed: Vec<H256>, duration: u64) {
|
||||
fn new_blocks(&self, imported: Vec<H256>, _invalid: Vec<H256>, _enacted: Vec<H256>, _retracted: Vec<H256>, _sealed: Vec<H256>, duration: u64) {
|
||||
let mut last_import = self.last_import.lock();
|
||||
let queue_info = self.client.queue_info();
|
||||
let importing = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3
|
||||
|| self.sync.as_ref().map_or(false, |s| s.status().is_major_syncing());
|
||||
if Instant::now() > *last_import + Duration::from_secs(1) && !importing {
|
||||
if let Some(block) = enacted.last().and_then(|h| self.client.block(BlockID::Hash(h.clone()))) {
|
||||
if let Some(block) = imported.last().and_then(|h| self.client.block(BlockID::Hash(h.clone()))) {
|
||||
let view = BlockView::new(&block);
|
||||
let header = view.header();
|
||||
let tx_count = view.transactions_count();
|
||||
@ -179,7 +179,7 @@ impl ChainNotify for Informant {
|
||||
}
|
||||
self.skipped.store(0, AtomicOrdering::Relaxed);
|
||||
} else {
|
||||
self.skipped.fetch_add(enacted.len(), AtomicOrdering::Relaxed);
|
||||
self.skipped.fetch_add(imported.len(), AtomicOrdering::Relaxed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user