From 4f2b5be34f9643b5419fbcc4a9b15583a6d65a00 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Tue, 15 Nov 2016 15:14:25 +0300 Subject: [PATCH] split logic errors in separate enum --- db/src/storage.rs | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/db/src/storage.rs b/db/src/storage.rs index 7346f7ee..f0871cbf 100644 --- a/db/src/storage.rs +++ b/db/src/storage.rs @@ -92,8 +92,32 @@ pub enum Error { DB(String), /// Io error Io(std::io::Error), - /// Invalid meta info + /// Invalid meta info (while opening the database) Meta(MetaError), + /// Database blockchain consistency error + Consistency(ConsitencyError), +} + +impl Error { + fn unknown_hash(h: &H256) -> Self { + Error::Consistency(ConsitencyError::Unknown(h.clone())) + } + + fn unknown_number(n: u32) -> Self { + Error::Consistency(ConsitencyError::UnknownNumber(n)) + } + + fn double_spend(h: &H256) -> Self { + Error::Consistency(ConsitencyError::DoubleSpend(h.clone())) + } + + fn not_main(h: &H256) -> Self { + Error::Consistency(ConsitencyError::NotMain(h.clone())) + } +} + +#[derive(Debug)] +pub enum ConsitencyError { /// Unknown hash Unknown(H256), /// Unknown number @@ -307,7 +331,7 @@ impl Storage { if !match context.meta.get_mut(&input.previous_output.hash) { Some(ref mut meta) => { if meta.is_spent(input.previous_output.index as usize) { - return Err(Error::DoubleSpend(input.previous_output.hash.clone())); + return Err(Error::double_spend(&input.previous_output.hash)); } meta.note_used(input.previous_output.index as usize); @@ -318,11 +342,11 @@ impl Storage { let mut meta = try!( self.transaction_meta(&input.previous_output.hash) - .ok_or(Error::UnknownSpending(input.previous_output.hash.clone())) + .ok_or(Error::Consistency(ConsitencyError::UnknownSpending(input.previous_output.hash.clone()))) ); if meta.is_spent(input.previous_output.index as usize) { - return Err(Error::DoubleSpend(input.previous_output.hash.clone())); + return Err(Error::double_spend(&input.previous_output.hash)); } meta.note_used(input.previous_output.index as usize); @@ -345,7 +369,7 @@ impl Storage { trace!(target: "reorg", "Decanonizing block {}", hash); // ensure that block is of the main chain - try!(self.block_number(hash).ok_or(Error::NotMain(hash.clone()))); + try!(self.block_number(hash).ok_or(Error::not_main(hash))); // only canonical blocks have numbers, so remove this number entry for the hash context.db_transaction.delete(Some(COL_BLOCK_NUMBERS), &**hash); @@ -392,7 +416,7 @@ impl Storage { /// Returns the height where the fork occurred and chain up to this place (not including last canonical hash) fn fork_route(&self, max_route: usize, hash: &H256) -> Result<(u32, Vec), Error> { - let header = try!(self.block_header_by_hash(hash).ok_or(Error::Unknown(hash.clone()))); + let header = try!(self.block_header_by_hash(hash).ok_or(Error::unknown_hash(hash))); // only main chain blocks has block numbers // so if it has, it is not a fork and we return empty route @@ -408,10 +432,10 @@ impl Storage { return Ok((number, result)); } result.push(next_hash.clone()); - next_hash = try!(self.block_header_by_hash(&next_hash).ok_or(Error::Unknown(hash.clone()))) + next_hash = try!(self.block_header_by_hash(&next_hash).ok_or(Error::unknown_hash(hash))) .previous_header_hash; } - Err(Error::ForkTooLong) + Err(Error::Consistency(ConsitencyError::ForkTooLong)) } fn best_number(&self) -> Option { @@ -463,11 +487,11 @@ impl Storage { return Ok(None); } - let mut now_best = try!(self.best_number().ok_or(Error::NoBestBlock)); + let mut now_best = try!(self.best_number().ok_or(Error::Consistency(ConsitencyError::NoBestBlock))); // decanonizing main chain to the split point loop { - let next_decanonize = try!(self.block_hash(now_best).ok_or(Error::UnknownNumber(now_best))); + let next_decanonize = try!(self.block_hash(now_best).ok_or(Error::unknown_number(now_best))); try!(self.decanonize_block(context, &next_decanonize)); now_best -= 1;