From 167d06d727079450c5812924091eb955a350a251 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 20 Apr 2017 16:21:53 +0200 Subject: [PATCH] fix panickers in tree-route --- ethcore/src/blockchain/blockchain.rs | 48 ++++++++++++++++------------ ethcore/src/client/client.rs | 2 +- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 39c1039ca..feaf52a03 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -650,12 +650,19 @@ impl BlockChain { /// ```json /// { blocks: [B4, B3, A3, A4], ancestor: A2, index: 2 } /// ``` - pub fn tree_route(&self, from: H256, to: H256) -> TreeRoute { + /// + /// If the tree route verges into pruned or unknown blocks, + /// `None` is returned. + pub fn tree_route(&self, from: H256, to: H256) -> Option { + macro_rules! otry { + ($e:expr) => { match $e { Some(x) => x, None => return None } } + } + let mut from_branch = vec![]; let mut to_branch = vec![]; - let mut from_details = self.block_details(&from).unwrap_or_else(|| panic!("0. Expected to find details for block {:?}", from)); - let mut to_details = self.block_details(&to).unwrap_or_else(|| panic!("1. Expected to find details for block {:?}", to)); + let mut from_details = otry!(self.block_details(&from)); + let mut to_details = otry!(self.block_details(&to)); let mut current_from = from; let mut current_to = to; @@ -663,13 +670,13 @@ impl BlockChain { while from_details.number > to_details.number { from_branch.push(current_from); current_from = from_details.parent.clone(); - from_details = self.block_details(&from_details.parent).unwrap_or_else(|| panic!("2. Expected to find details for block {:?}", from_details.parent)); + from_details = otry!(self.block_details(&from_details.parent)); } while to_details.number > from_details.number { to_branch.push(current_to); current_to = to_details.parent.clone(); - to_details = self.block_details(&to_details.parent).unwrap_or_else(|| panic!("3. Expected to find details for block {:?}", to_details.parent)); + to_details = otry!(self.block_details(&to_details.parent)); } assert_eq!(from_details.number, to_details.number); @@ -678,22 +685,22 @@ impl BlockChain { while current_from != current_to { from_branch.push(current_from); current_from = from_details.parent.clone(); - from_details = self.block_details(&from_details.parent).unwrap_or_else(|| panic!("4. Expected to find details for block {:?}", from_details.parent)); + from_details = otry!(self.block_details(&from_details.parent)); to_branch.push(current_to); current_to = to_details.parent.clone(); - to_details = self.block_details(&to_details.parent).unwrap_or_else(|| panic!("5. Expected to find details for block {:?}", from_details.parent)); + to_details = otry!(self.block_details(&to_details.parent)); } let index = from_branch.len(); from_branch.extend(to_branch.into_iter().rev()); - TreeRoute { + Some(TreeRoute { blocks: from_branch, ancestor: current_from, index: index - } + }) } /// Inserts a verified, known block from the canonical chain. @@ -879,7 +886,8 @@ impl BlockChain { // 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); + let route = self.tree_route(best_hash, parent_hash) + .expect("blocks being imported always within recent history; qed"); assert_eq!(number, parent_details.number + 1); @@ -1711,52 +1719,52 @@ mod tests { assert_eq!(bc.block_hash(3).unwrap(), b3a_hash); // test trie route - let r0_1 = bc.tree_route(genesis_hash.clone(), b1_hash.clone()); + let r0_1 = bc.tree_route(genesis_hash.clone(), b1_hash.clone()).unwrap(); assert_eq!(r0_1.ancestor, genesis_hash); assert_eq!(r0_1.blocks, [b1_hash.clone()]); assert_eq!(r0_1.index, 0); - let r0_2 = bc.tree_route(genesis_hash.clone(), b2_hash.clone()); + let r0_2 = bc.tree_route(genesis_hash.clone(), b2_hash.clone()).unwrap(); assert_eq!(r0_2.ancestor, genesis_hash); assert_eq!(r0_2.blocks, [b1_hash.clone(), b2_hash.clone()]); assert_eq!(r0_2.index, 0); - let r1_3a = bc.tree_route(b1_hash.clone(), b3a_hash.clone()); + let r1_3a = bc.tree_route(b1_hash.clone(), b3a_hash.clone()).unwrap(); assert_eq!(r1_3a.ancestor, b1_hash); assert_eq!(r1_3a.blocks, [b2_hash.clone(), b3a_hash.clone()]); assert_eq!(r1_3a.index, 0); - let r1_3b = bc.tree_route(b1_hash.clone(), b3b_hash.clone()); + let r1_3b = bc.tree_route(b1_hash.clone(), b3b_hash.clone()).unwrap(); assert_eq!(r1_3b.ancestor, b1_hash); assert_eq!(r1_3b.blocks, [b2_hash.clone(), b3b_hash.clone()]); assert_eq!(r1_3b.index, 0); - let r3a_3b = bc.tree_route(b3a_hash.clone(), b3b_hash.clone()); + let r3a_3b = bc.tree_route(b3a_hash.clone(), b3b_hash.clone()).unwrap(); assert_eq!(r3a_3b.ancestor, b2_hash); assert_eq!(r3a_3b.blocks, [b3a_hash.clone(), b3b_hash.clone()]); assert_eq!(r3a_3b.index, 1); - let r1_0 = bc.tree_route(b1_hash.clone(), genesis_hash.clone()); + let r1_0 = bc.tree_route(b1_hash.clone(), genesis_hash.clone()).unwrap(); assert_eq!(r1_0.ancestor, genesis_hash); assert_eq!(r1_0.blocks, [b1_hash.clone()]); assert_eq!(r1_0.index, 1); - let r2_0 = bc.tree_route(b2_hash.clone(), genesis_hash.clone()); + let r2_0 = bc.tree_route(b2_hash.clone(), genesis_hash.clone()).unwrap(); assert_eq!(r2_0.ancestor, genesis_hash); assert_eq!(r2_0.blocks, [b2_hash.clone(), b1_hash.clone()]); assert_eq!(r2_0.index, 2); - let r3a_1 = bc.tree_route(b3a_hash.clone(), b1_hash.clone()); + let r3a_1 = bc.tree_route(b3a_hash.clone(), b1_hash.clone()).unwrap(); assert_eq!(r3a_1.ancestor, b1_hash); assert_eq!(r3a_1.blocks, [b3a_hash.clone(), b2_hash.clone()]); assert_eq!(r3a_1.index, 2); - let r3b_1 = bc.tree_route(b3b_hash.clone(), b1_hash.clone()); + let r3b_1 = bc.tree_route(b3b_hash.clone(), b1_hash.clone()).unwrap(); assert_eq!(r3b_1.ancestor, b1_hash); assert_eq!(r3b_1.blocks, [b3b_hash.clone(), b2_hash.clone()]); assert_eq!(r3b_1.index, 2); - let r3b_3a = bc.tree_route(b3b_hash.clone(), b3a_hash.clone()); + let r3b_3a = bc.tree_route(b3b_hash.clone(), b3a_hash.clone()).unwrap(); assert_eq!(r3b_3a.ancestor, b2_hash); assert_eq!(r3b_3a.blocks, [b3b_hash.clone(), b3a_hash.clone()]); assert_eq!(r3b_3a.index, 1); diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index e7755e4d0..0656480f6 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1270,7 +1270,7 @@ impl BlockChainClient for Client { fn tree_route(&self, from: &H256, to: &H256) -> Option { let chain = self.chain.read(); match chain.is_known(from) && chain.is_known(to) { - true => Some(chain.tree_route(from.clone(), to.clone())), + true => chain.tree_route(from.clone(), to.clone()), false => None } }