fix panickers in tree-route
This commit is contained in:
		
							parent
							
								
									0d40df937b
								
							
						
					
					
						commit
						167d06d727
					
				| @ -650,12 +650,19 @@ impl BlockChain { | |||||||
| 	///   ```json
 | 	///   ```json
 | ||||||
| 	///   { blocks: [B4, B3, A3, A4], ancestor: A2, index: 2 }
 | 	///   { 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<TreeRoute> { | ||||||
|  | 		macro_rules! otry { | ||||||
|  | 			($e:expr) => { match $e { Some(x) => x, None => return None } } | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		let mut from_branch = vec![]; | 		let mut from_branch = vec![]; | ||||||
| 		let mut to_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 from_details = otry!(self.block_details(&from)); | ||||||
| 		let mut to_details = self.block_details(&to).unwrap_or_else(|| panic!("1. Expected to find details for block {:?}", to)); | 		let mut to_details = otry!(self.block_details(&to)); | ||||||
| 		let mut current_from = from; | 		let mut current_from = from; | ||||||
| 		let mut current_to = to; | 		let mut current_to = to; | ||||||
| 
 | 
 | ||||||
| @ -663,13 +670,13 @@ impl BlockChain { | |||||||
| 		while from_details.number > to_details.number { | 		while from_details.number > to_details.number { | ||||||
| 			from_branch.push(current_from); | 			from_branch.push(current_from); | ||||||
| 			current_from = from_details.parent.clone(); | 			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 { | 		while to_details.number > from_details.number { | ||||||
| 			to_branch.push(current_to); | 			to_branch.push(current_to); | ||||||
| 			current_to = to_details.parent.clone(); | 			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); | 		assert_eq!(from_details.number, to_details.number); | ||||||
| @ -678,22 +685,22 @@ impl BlockChain { | |||||||
| 		while current_from != current_to { | 		while current_from != current_to { | ||||||
| 			from_branch.push(current_from); | 			from_branch.push(current_from); | ||||||
| 			current_from = from_details.parent.clone(); | 			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); | 			to_branch.push(current_to); | ||||||
| 			current_to = to_details.parent.clone(); | 			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(); | 		let index = from_branch.len(); | ||||||
| 
 | 
 | ||||||
| 		from_branch.extend(to_branch.into_iter().rev()); | 		from_branch.extend(to_branch.into_iter().rev()); | ||||||
| 
 | 
 | ||||||
| 		TreeRoute { | 		Some(TreeRoute { | ||||||
| 			blocks: from_branch, | 			blocks: from_branch, | ||||||
| 			ancestor: current_from, | 			ancestor: current_from, | ||||||
| 			index: index | 			index: index | ||||||
| 		} | 		}) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/// Inserts a verified, known block from the canonical chain.
 | 	/// Inserts a verified, known block from the canonical chain.
 | ||||||
| @ -879,7 +886,8 @@ impl BlockChain { | |||||||
| 				// are moved to "canon chain"
 | 				// are moved to "canon chain"
 | ||||||
| 				// find the route between old best block and the new one
 | 				// find the route between old best block and the new one
 | ||||||
| 				let best_hash = self.best_block_hash(); | 				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); | 				assert_eq!(number, parent_details.number + 1); | ||||||
| 
 | 
 | ||||||
| @ -1711,52 +1719,52 @@ mod tests { | |||||||
| 		assert_eq!(bc.block_hash(3).unwrap(), b3a_hash); | 		assert_eq!(bc.block_hash(3).unwrap(), b3a_hash); | ||||||
| 
 | 
 | ||||||
| 		// test trie route
 | 		// 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.ancestor, genesis_hash); | ||||||
| 		assert_eq!(r0_1.blocks, [b1_hash.clone()]); | 		assert_eq!(r0_1.blocks, [b1_hash.clone()]); | ||||||
| 		assert_eq!(r0_1.index, 0); | 		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.ancestor, genesis_hash); | ||||||
| 		assert_eq!(r0_2.blocks, [b1_hash.clone(), b2_hash.clone()]); | 		assert_eq!(r0_2.blocks, [b1_hash.clone(), b2_hash.clone()]); | ||||||
| 		assert_eq!(r0_2.index, 0); | 		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.ancestor, b1_hash); | ||||||
| 		assert_eq!(r1_3a.blocks, [b2_hash.clone(), b3a_hash.clone()]); | 		assert_eq!(r1_3a.blocks, [b2_hash.clone(), b3a_hash.clone()]); | ||||||
| 		assert_eq!(r1_3a.index, 0); | 		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.ancestor, b1_hash); | ||||||
| 		assert_eq!(r1_3b.blocks, [b2_hash.clone(), b3b_hash.clone()]); | 		assert_eq!(r1_3b.blocks, [b2_hash.clone(), b3b_hash.clone()]); | ||||||
| 		assert_eq!(r1_3b.index, 0); | 		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.ancestor, b2_hash); | ||||||
| 		assert_eq!(r3a_3b.blocks, [b3a_hash.clone(), b3b_hash.clone()]); | 		assert_eq!(r3a_3b.blocks, [b3a_hash.clone(), b3b_hash.clone()]); | ||||||
| 		assert_eq!(r3a_3b.index, 1); | 		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.ancestor, genesis_hash); | ||||||
| 		assert_eq!(r1_0.blocks, [b1_hash.clone()]); | 		assert_eq!(r1_0.blocks, [b1_hash.clone()]); | ||||||
| 		assert_eq!(r1_0.index, 1); | 		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.ancestor, genesis_hash); | ||||||
| 		assert_eq!(r2_0.blocks, [b2_hash.clone(), b1_hash.clone()]); | 		assert_eq!(r2_0.blocks, [b2_hash.clone(), b1_hash.clone()]); | ||||||
| 		assert_eq!(r2_0.index, 2); | 		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.ancestor, b1_hash); | ||||||
| 		assert_eq!(r3a_1.blocks, [b3a_hash.clone(), b2_hash.clone()]); | 		assert_eq!(r3a_1.blocks, [b3a_hash.clone(), b2_hash.clone()]); | ||||||
| 		assert_eq!(r3a_1.index, 2); | 		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.ancestor, b1_hash); | ||||||
| 		assert_eq!(r3b_1.blocks, [b3b_hash.clone(), b2_hash.clone()]); | 		assert_eq!(r3b_1.blocks, [b3b_hash.clone(), b2_hash.clone()]); | ||||||
| 		assert_eq!(r3b_1.index, 2); | 		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.ancestor, b2_hash); | ||||||
| 		assert_eq!(r3b_3a.blocks, [b3b_hash.clone(), b3a_hash.clone()]); | 		assert_eq!(r3b_3a.blocks, [b3b_hash.clone(), b3a_hash.clone()]); | ||||||
| 		assert_eq!(r3b_3a.index, 1); | 		assert_eq!(r3b_3a.index, 1); | ||||||
|  | |||||||
| @ -1270,7 +1270,7 @@ impl BlockChainClient for Client { | |||||||
| 	fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute> { | 	fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute> { | ||||||
| 		let chain = self.chain.read(); | 		let chain = self.chain.read(); | ||||||
| 		match chain.is_known(from) && chain.is_known(to) { | 		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 | 			false => None | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user