diff --git a/chain/src/chain.rs b/chain/src/chain.rs index 33504d544..80906fe79 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -660,7 +660,7 @@ impl Chain { /// Return a merkle proof valid for the current output pmmr state at the /// given pos - pub fn get_merkle_proof_for_pos(&self, commit: Commitment) -> Result { + pub fn get_merkle_proof_for_pos(&self, commit: Commitment) -> Result { let mut txhashset = self.txhashset.write(); txhashset.merkle_proof(commit) } diff --git a/chain/src/error.rs b/chain/src/error.rs index 637540de7..b39404423 100644 --- a/chain/src/error.rs +++ b/chain/src/error.rs @@ -131,6 +131,9 @@ pub enum ErrorKind { /// We cannot process data once the Grin server has been stopped. #[fail(display = "Stopped (Grin Shutting Down)")] Stopped, + /// Internal Roaring Bitmap error + #[fail(display = "Roaring Bitmap error")] + Bitmap, } impl Display for Error { diff --git a/chain/src/txhashset/rewindable_kernel_view.rs b/chain/src/txhashset/rewindable_kernel_view.rs index c5de1751f..a1be9fc66 100644 --- a/chain/src/txhashset/rewindable_kernel_view.rs +++ b/chain/src/txhashset/rewindable_kernel_view.rs @@ -68,7 +68,8 @@ impl<'a> RewindableKernelView<'a> { /// fast sync where a reorg past the horizon could allow a whole rewrite of /// the kernel set. pub fn validate_root(&self) -> Result<(), Error> { - if self.pmmr.root() != self.header.kernel_root { + let root = self.pmmr.root().map_err(|_| ErrorKind::InvalidRoot)?; + if root != self.header.kernel_root { return Err(ErrorKind::InvalidTxHashSet(format!( "Kernel root at {} does not match", self.header.height diff --git a/chain/src/txhashset/txhashset.rs b/chain/src/txhashset/txhashset.rs index 1acf4b98d..342b7d346 100644 --- a/chain/src/txhashset/txhashset.rs +++ b/chain/src/txhashset/txhashset.rs @@ -272,9 +272,11 @@ impl TxHashSet { } /// build a new merkle proof for the given position. - pub fn merkle_proof(&mut self, commit: Commitment) -> Result { - let pos = self.commit_index.get_output_pos(&commit).unwrap(); - PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos).merkle_proof(pos) + pub fn merkle_proof(&mut self, commit: Commitment) -> Result { + let pos = self.commit_index.get_output_pos(&commit)?; + PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos) + .merkle_proof(pos) + .map_err(|_| ErrorKind::MerkleProof.into()) } /// Compact the MMR data files and flush the rm logs @@ -1590,6 +1592,5 @@ pub fn input_pos_to_rewind( current = batch.get_previous_header(¤t)?; } - let bitmap = bitmap_fast_or(None, &mut block_input_bitmaps).unwrap(); - Ok(bitmap) + bitmap_fast_or(None, &mut block_input_bitmaps).ok_or_else(|| ErrorKind::Bitmap.into()) } diff --git a/core/src/core/pmmr/rewindable_pmmr.rs b/core/src/core/pmmr/rewindable_pmmr.rs index 1eb395ece..e696d67af 100644 --- a/core/src/core/pmmr/rewindable_pmmr.rs +++ b/core/src/core/pmmr/rewindable_pmmr.rs @@ -95,9 +95,9 @@ where /// Computes the root of the MMR. Find all the peaks in the current /// tree and "bags" them to get a single peak. - pub fn root(&self) -> Hash { + pub fn root(&self) -> Result { if self.is_empty() { - return ZERO_HASH; + return Ok(ZERO_HASH); } let mut res = None; for peak in self.peaks().iter().rev() { @@ -106,7 +106,7 @@ where Some(rhash) => Some((*peak, rhash).hash_with_index(self.unpruned_size())), } } - res.expect("no root, invalid tree") + res.ok_or_else(|| "no root, invalid tree".to_owned()) } /// Returns a vec of the peaks of this MMR.