Remove expect (#8536)

* Remove expect and propagate rlp::DecoderErrors as TrieErrors
This commit is contained in:
David 2018-05-04 10:06:54 +02:00 committed by GitHub
parent 66c0638f3b
commit f0c6d17ad8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 2 deletions

View File

@ -67,6 +67,8 @@ pub enum TrieError {
InvalidStateRoot(H256), InvalidStateRoot(H256),
/// Trie item not found in the database, /// Trie item not found in the database,
IncompleteDatabase(H256), IncompleteDatabase(H256),
/// Corrupt Trie item
DecoderError(rlp::DecoderError),
} }
impl fmt::Display for TrieError { impl fmt::Display for TrieError {
@ -75,6 +77,7 @@ impl fmt::Display for TrieError {
TrieError::InvalidStateRoot(ref root) => write!(f, "Invalid state root: {}", root), TrieError::InvalidStateRoot(ref root) => write!(f, "Invalid state root: {}", root),
TrieError::IncompleteDatabase(ref missing) => TrieError::IncompleteDatabase(ref missing) =>
write!(f, "Database missing expected key: {}", missing), write!(f, "Database missing expected key: {}", missing),
TrieError::DecoderError(ref err) => write!(f, "Decoding failed with {}", err),
} }
} }
} }
@ -84,10 +87,15 @@ impl error::Error for TrieError {
match *self { match *self {
TrieError::InvalidStateRoot(_) => "Invalid state root", TrieError::InvalidStateRoot(_) => "Invalid state root",
TrieError::IncompleteDatabase(_) => "Incomplete database", TrieError::IncompleteDatabase(_) => "Incomplete database",
TrieError::DecoderError(ref e) => e.description(),
} }
} }
} }
impl From<rlp::DecoderError> for Box<TrieError> {
fn from(e: rlp::DecoderError) -> Self { Box::new(TrieError::DecoderError(e)) }
}
/// Trie result type. Boxed to avoid copying around extra space for `H256`s on successful queries. /// Trie result type. Boxed to avoid copying around extra space for `H256`s on successful queries.
pub type Result<T> = ::std::result::Result<T, Box<TrieError>>; pub type Result<T> = ::std::result::Result<T, Box<TrieError>>;

View File

@ -55,7 +55,7 @@ impl<'a, Q: Query> Lookup<'a, Q> {
// without incrementing the depth. // without incrementing the depth.
let mut node_data = &node_data[..]; let mut node_data = &node_data[..];
loop { loop {
match Node::decoded(node_data).expect("rlp read from db; qed") { match Node::decoded(node_data)? {
Node::Leaf(slice, value) => { Node::Leaf(slice, value) => {
return Ok(match slice == key { return Ok(match slice == key {
true => Some(self.query.decode(value)), true => Some(self.query.decode(value)),

View File

@ -493,3 +493,30 @@ fn get_len() {
assert_eq!(t.get_with(b"B", |x: &[u8]| x.len()), Ok(Some(5))); assert_eq!(t.get_with(b"B", |x: &[u8]| x.len()), Ok(Some(5)));
assert_eq!(t.get_with(b"C", |x: &[u8]| x.len()), Ok(None)); assert_eq!(t.get_with(b"C", |x: &[u8]| x.len()), Ok(None));
} }
// Test will work once https://github.com/paritytech/parity/pull/8527 is merged and rlp::decode returns Result instead of panicking
//#[test]
//fn test_lookup_with_corrupt_data_returns_decoder_error() {
// use memorydb::*;
// use super::TrieMut;
// use super::triedbmut::*;
// use rlp;
// use ethereum_types::H512;
//
// let mut memdb = MemoryDB::new();
// let mut root = H256::new();
// {
// let mut t = TrieDBMut::new(&mut memdb, &mut root);
// t.insert(b"A", b"ABC").unwrap();
// t.insert(b"B", b"ABCBA").unwrap();
// }
//
// let t = TrieDB::new(&memdb, &root).unwrap();
//
// // query for an invalid data type to trigger an error
// let q = rlp::decode::<H512>;
// let lookup = Lookup{ db: t.db, query: q, hash: root };
// let query_result = lookup.look_up(NibbleSlice::new(b"A"));
// let expected = Box::new(TrieError::DecoderError(::rlp::DecoderError::RlpIsTooShort));
// assert_eq!(query_result.unwrap_err(), expected);
//}

View File

@ -9,7 +9,7 @@
use std::fmt; use std::fmt;
use std::error::Error as StdError; use std::error::Error as StdError;
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq, Clone)]
/// Error concerning the RLP decoder. /// Error concerning the RLP decoder.
pub enum DecoderError { pub enum DecoderError {
/// Data has additional bytes at the end of the valid RLP fragment. /// Data has additional bytes at the end of the valid RLP fragment.