Rlp decode returns Result (#8527)

rlp::decode returns Result

Make a best effort to handle decoding errors gracefully throughout the code, using `expect` where the value is guaranteed to be valid (and in other places where it makes sense).
This commit is contained in:
David 2018-05-08 11:22:12 +02:00 committed by GitHub
parent a7a46f4253
commit 28c731881f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 108 additions and 91 deletions

View File

@ -228,7 +228,7 @@ impl HeaderChain {
let decoded_header = spec.genesis_header();
let chain = if let Some(current) = db.get(col, CURRENT_KEY)? {
let curr : BestAndLatest = ::rlp::decode(&current);
let curr : BestAndLatest = ::rlp::decode(&current).expect("decoding db value failed");
let mut cur_number = curr.latest_num;
let mut candidates = BTreeMap::new();
@ -236,7 +236,7 @@ impl HeaderChain {
// load all era entries, referenced headers within them,
// and live epoch proofs.
while let Some(entry) = db.get(col, era_key(cur_number).as_bytes())? {
let entry: Entry = ::rlp::decode(&entry);
let entry: Entry = ::rlp::decode(&entry).expect("decoding db value failed");
trace!(target: "chain", "loaded header chain entry for era {} with {} candidates",
cur_number, entry.candidates.len());
@ -524,7 +524,10 @@ impl HeaderChain {
None
}
Ok(None) => panic!("stored candidates always have corresponding headers; qed"),
Ok(Some(header)) => Some((epoch_transition, ::rlp::decode(&header))),
Ok(Some(header)) => Some((
epoch_transition,
::rlp::decode(&header).expect("decoding value from db failed")
)),
};
}
}
@ -591,7 +594,7 @@ impl HeaderChain {
in an inconsistent state", h_num);
ErrorKind::Database(msg.into())
})?;
::rlp::decode(&bytes)
::rlp::decode(&bytes).expect("decoding db value failed")
};
let total_difficulty = entry.candidates.iter()
@ -604,9 +607,9 @@ impl HeaderChain {
.total_difficulty;
break Ok(Some(SpecHardcodedSync {
header: header,
total_difficulty: total_difficulty,
chts: chts,
header,
total_difficulty,
chts,
}));
},
None => {
@ -742,7 +745,7 @@ impl HeaderChain {
/// so including it within a CHT would be redundant.
pub fn cht_root(&self, n: usize) -> Option<H256> {
match self.db.get(self.col, cht_key(n as u64).as_bytes()) {
Ok(val) => val.map(|x| ::rlp::decode(&x)),
Ok(db_fetch) => db_fetch.map(|bytes| ::rlp::decode(&bytes).expect("decoding value from db failed")),
Err(e) => {
warn!(target: "chain", "Error reading from database: {}", e);
None
@ -793,7 +796,7 @@ impl HeaderChain {
pub fn pending_transition(&self, hash: H256) -> Option<PendingEpochTransition> {
let key = pending_transition_key(hash);
match self.db.get(self.col, &*key) {
Ok(val) => val.map(|x| ::rlp::decode(&x)),
Ok(db_fetch) => db_fetch.map(|bytes| ::rlp::decode(&bytes).expect("decoding value from db failed")),
Err(e) => {
warn!(target: "chain", "Error reading from database: {}", e);
None
@ -1192,7 +1195,7 @@ mod tests {
let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::from_secs(6 * 3600))));
let chain = HeaderChain::new(db.clone(), None, &spec, cache, HardcodedSync::Allow).unwrap();
let chain = HeaderChain::new(db.clone(), None, &spec, cache, HardcodedSync::Allow).expect("failed to instantiate a new HeaderChain");
let mut parent_hash = genesis_header.hash();
let mut rolling_timestamp = genesis_header.timestamp();
@ -1211,14 +1214,14 @@ mod tests {
parent_hash = header.hash();
let mut tx = db.transaction();
let pending = chain.insert(&mut tx, header, None).unwrap();
let pending = chain.insert(&mut tx, header, None).expect("failed inserting a transaction");
db.write(tx).unwrap();
chain.apply_pending(pending);
rolling_timestamp += 10;
}
let hardcoded_sync = chain.read_hardcoded_sync().unwrap().unwrap();
let hardcoded_sync = chain.read_hardcoded_sync().expect("failed reading hardcoded sync").expect("failed unwrapping hardcoded sync");
assert_eq!(hardcoded_sync.chts.len(), 3);
assert_eq!(hardcoded_sync.total_difficulty, total_difficulty);
let decoded: Header = hardcoded_sync.header.decode();

View File

@ -407,7 +407,7 @@ mod tests {
let costs = CostTable::default();
let serialized = ::rlp::encode(&costs);
let new_costs: CostTable = ::rlp::decode(&*serialized);
let new_costs: CostTable = ::rlp::decode(&*serialized).unwrap();
assert_eq!(costs, new_costs);
}

View File

@ -1642,7 +1642,7 @@ mod tests {
{
// check as single value.
let bytes = ::rlp::encode(&val);
let new_val: T = ::rlp::decode(&bytes);
let new_val: T = ::rlp::decode(&bytes).unwrap();
assert_eq!(val, new_val);
// check as list containing single value.

View File

@ -438,7 +438,7 @@ impl<'a> Iterator for EpochTransitionIter<'a> {
return None
}
let transitions: EpochTransitions = ::rlp::decode(&val[..]);
let transitions: EpochTransitions = ::rlp::decode(&val[..]).expect("decode error: the db is corrupted or the data structure has changed");
// if there are multiple candidates, at most one will be on the
// canon chain.
@ -462,7 +462,7 @@ impl<'a> Iterator for EpochTransitionIter<'a> {
impl BlockChain {
/// Create new instance of blockchain from given Genesis.
pub fn new(config: Config, genesis: &[u8], db: Arc<KeyValueDB>) -> BlockChain {
// 400 is the avarage size of the key
// 400 is the average size of the key
let cache_man = CacheManager::new(config.pref_cache_size, config.max_cache_size, 400);
let mut bc = BlockChain {

View File

@ -218,15 +218,12 @@ impl Writable for DBTransaction {
}
impl<KVDB: KeyValueDB + ?Sized> Readable for KVDB {
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where T: rlp::Decodable, R: Deref<Target = [u8]> {
let result = self.get(col, &key.key());
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T>
where T: rlp::Decodable, R: Deref<Target = [u8]> {
self.get(col, &key.key())
.expect(&format!("db get failed, key: {:?}", &key.key() as &[u8]))
.map(|v| rlp::decode(&v).expect("decode db value failed") )
match result {
Ok(option) => option.map(|v| rlp::decode(&v)),
Err(err) => {
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}
}
}
fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: Deref<Target = [u8]> {

View File

@ -24,13 +24,12 @@
//! decoded object where parts like the hash can be saved.
use block::Block as FullBlock;
use header::{BlockNumber, Header as FullHeader};
use transaction::UnverifiedTransaction;
use hash::keccak;
use heapsize::HeapSizeOf;
use ethereum_types::{H256, Bloom, U256, Address};
use hash::keccak;
use header::{BlockNumber, Header as FullHeader};
use heapsize::HeapSizeOf;
use rlp::{Rlp, RlpStream};
use transaction::UnverifiedTransaction;
use views::{self, BlockView, HeaderView, BodyView};
/// Owning header view.
@ -48,7 +47,7 @@ impl Header {
pub fn new(encoded: Vec<u8>) -> Self { Header(encoded) }
/// Upgrade this encoded view to a fully owned `Header` object.
pub fn decode(&self) -> FullHeader { ::rlp::decode(&self.0) }
pub fn decode(&self) -> FullHeader { ::rlp::decode(&self.0).expect("decoding failure") }
/// Get a borrowed header view onto the data.
#[inline]
@ -205,7 +204,7 @@ impl Block {
pub fn header_view(&self) -> HeaderView { self.view().header_view() }
/// Decode to a full block.
pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0) }
pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0).expect("decoding failure") }
/// Decode the header.
pub fn decode_header(&self) -> FullHeader { self.view().rlp().val_at(0) }

View File

@ -143,8 +143,10 @@ impl <F> super::EpochVerifier<EthereumMachine> for EpochVerifier<F>
}
fn check_finality_proof(&self, proof: &[u8]) -> Option<Vec<H256>> {
let header: Header = ::rlp::decode(proof);
self.verify_light(&header).ok().map(|_| vec![header.hash()])
match ::rlp::decode(proof) {
Ok(header) => self.verify_light(&header).ok().map(|_| vec![header.hash()]),
Err(_) => None // REVIEW: log perhaps? Not sure what the policy is.
}
}
}

View File

@ -398,7 +398,7 @@ mod tests {
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
let nonce_decoded = "ab4e252a7e8c2a23".from_hex().unwrap();
let header: Header = rlp::decode(&header_rlp);
let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
let seal_fields = header.seal.clone();
assert_eq!(seal_fields.len(), 2);
assert_eq!(seal_fields[0], mix_hash);
@ -415,7 +415,7 @@ mod tests {
// that's rlp of block header created with ethash engine.
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
let header: Header = rlp::decode(&header_rlp);
let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
let encoded_header = rlp::encode(&header).into_vec();
assert_eq!(header_rlp, encoded_header);

View File

@ -236,7 +236,7 @@ mod tests {
};
let thin_rlp = ::rlp::encode(&account);
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp).unwrap(), account);
let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap();
let fat_rlp = Rlp::new(&fat_rlps[0]).at(1).unwrap();
@ -261,7 +261,7 @@ mod tests {
};
let thin_rlp = ::rlp::encode(&account);
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp).unwrap(), account);
let fat_rlp = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap();
let fat_rlp = Rlp::new(&fat_rlp[0]).at(1).unwrap();
@ -286,7 +286,7 @@ mod tests {
};
let thin_rlp = ::rlp::encode(&account);
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp).unwrap(), account);
let fat_rlps = to_fat_rlps(&keccak(addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), 500, 1000).unwrap();
let mut root = KECCAK_NULL_RLP;

View File

@ -281,7 +281,7 @@ pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: &Mutex<SnapshotWriter +
// account_key here is the address' hash.
for item in account_trie.iter()? {
let (account_key, account_data) = item?;
let account = ::rlp::decode(&*account_data);
let account = ::rlp::decode(&*account_data)?;
let account_key_hash = H256::from_slice(&account_key);
let account_db = AccountDB::from_hash(db, account_key_hash);
@ -467,10 +467,10 @@ fn rebuild_accounts(
*out = (hash, thin_rlp);
}
if let Some(&(ref hash, ref rlp)) = out_chunk.iter().last() {
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp).storage_root);
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp)?.storage_root);
}
if let Some(&(ref hash, ref rlp)) = out_chunk.iter().next() {
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp).storage_root);
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp)?.storage_root);
}
Ok(status)
}

View File

@ -75,7 +75,7 @@ impl StateProducer {
// sweep once to alter storage tries.
for &mut (ref mut address_hash, ref mut account_data) in &mut accounts_to_modify {
let mut account: BasicAccount = ::rlp::decode(&*account_data);
let mut account: BasicAccount = ::rlp::decode(&*account_data).expect("error decoding basic account");
let acct_db = AccountDBMut::from_hash(db, *address_hash);
fill_storage(acct_db, &mut account.storage_root, &mut self.storage_seed);
*account_data = DBValue::from_vec(::rlp::encode(&account).into_vec());

View File

@ -114,7 +114,7 @@ fn get_code_from_prev_chunk() {
// first one will have code inlined,
// second will just have its hash.
let thin_rlp = acc_stream.out();
let acc: BasicAccount = ::rlp::decode(&thin_rlp);
let acc: BasicAccount = ::rlp::decode(&thin_rlp).expect("error decoding basic account");
let mut make_chunk = |acc, hash| {
let mut db = MemoryDB::new();

View File

@ -21,6 +21,7 @@ use std::sync::Arc;
use std::collections::{HashMap, BTreeMap};
use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP, keccak};
use ethereum_types::{H256, U256, Address};
use error::Error;
use hashdb::HashDB;
use kvdb::DBValue;
use bytes::{Bytes, ToPretty};
@ -144,9 +145,10 @@ impl Account {
}
/// Create a new account from RLP.
pub fn from_rlp(rlp: &[u8]) -> Account {
let basic: BasicAccount = ::rlp::decode(rlp);
basic.into()
pub fn from_rlp(rlp: &[u8]) -> Result<Account, Error> {
::rlp::decode::<BasicAccount>(rlp)
.map(|ba| ba.into())
.map_err(|e| e.into())
}
/// Create a new contract account.
@ -202,8 +204,8 @@ impl Account {
return Ok(value);
}
let db = SecTrieDB::new(db, &self.storage_root)?;
let item: U256 = db.get_with(key, ::rlp::decode)?.unwrap_or_else(U256::zero);
let panicky_decoder = |bytes:&[u8]| ::rlp::decode(&bytes).expect("decoding db value failed");
let item: U256 = db.get_with(key, panicky_decoder)?.unwrap_or_else(U256::zero);
let value: H256 = item.into();
self.storage_cache.borrow_mut().insert(key.clone(), value.clone());
Ok(value)
@ -478,7 +480,8 @@ impl Account {
let trie = TrieDB::new(db, &self.storage_root)?;
let item: U256 = {
let query = (&mut recorder, ::rlp::decode);
let panicky_decoder = |bytes:&[u8]| ::rlp::decode(bytes).expect("decoding db value failed");
let query = (&mut recorder, panicky_decoder);
trie.get_with(&storage_key, query)?.unwrap_or_else(U256::zero)
};
@ -528,7 +531,7 @@ mod tests {
a.rlp()
};
let a = Account::from_rlp(&rlp);
let a = Account::from_rlp(&rlp).expect("decoding db value failed");
assert_eq!(*a.storage_root().unwrap(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into());
assert_eq!(a.storage_at(&db.immutable(), &0x00u64.into()).unwrap(), 0x1234u64.into());
assert_eq!(a.storage_at(&db.immutable(), &0x01u64.into()).unwrap(), H256::default());
@ -546,10 +549,10 @@ mod tests {
a.rlp()
};
let mut a = Account::from_rlp(&rlp);
let mut a = Account::from_rlp(&rlp).expect("decoding db value failed");
assert!(a.cache_code(&db.immutable()).is_some());
let mut a = Account::from_rlp(&rlp);
let mut a = Account::from_rlp(&rlp).expect("decoding db value failed");
assert_eq!(a.note_code(vec![0x55, 0x44, 0xffu8]), Ok(()));
}
@ -609,7 +612,7 @@ mod tests {
#[test]
fn rlpio() {
let a = Account::new(69u8.into(), 0u8.into(), HashMap::new(), Bytes::new());
let b = Account::from_rlp(&a.rlp());
let b = Account::from_rlp(&a.rlp()).unwrap();
assert_eq!(a.balance(), b.balance());
assert_eq!(a.nonce(), b.nonce());
assert_eq!(a.code_hash(), b.code_hash());

View File

@ -605,7 +605,8 @@ impl<B: Backend> State<B> {
// account is not found in the global cache, get from the DB and insert into local
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
let maybe_acc = db.get_with(address, Account::from_rlp)?;
let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed");
let maybe_acc = db.get_with(address, from_rlp)?;
let r = maybe_acc.as_ref().map_or(Ok(H256::new()), |a| {
let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), a.address_hash(address));
a.storage_at(account_db.as_hashdb(), key)
@ -983,7 +984,8 @@ impl<B: Backend> State<B> {
// not found in the global cache, get from the DB and insert into local
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?;
let mut maybe_acc = db.get_with(a, Account::from_rlp)?;
let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed");
let mut maybe_acc = db.get_with(a, from_rlp)?;
if let Some(ref mut account) = maybe_acc.as_mut() {
let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a));
Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb());
@ -1012,7 +1014,8 @@ impl<B: Backend> State<B> {
None => {
let maybe_acc = if !self.db.is_known_null(a) {
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?;
AccountEntry::new_clean(db.get_with(a, Account::from_rlp)?)
let from_rlp = |b:&[u8]| { Account::from_rlp(b).expect("decoding db value failed") };
AccountEntry::new_clean(db.get_with(a, from_rlp)?)
} else {
AccountEntry::new_clean(None)
};
@ -1064,7 +1067,10 @@ impl<B: Backend> State<B> {
let mut recorder = Recorder::new();
let trie = TrieDB::new(self.db.as_hashdb(), &self.root)?;
let maybe_account: Option<BasicAccount> = {
let query = (&mut recorder, ::rlp::decode);
let panicky_decoder = |bytes: &[u8]| {
::rlp::decode(bytes).expect(&format!("prove_account, could not query trie for account key={}", &account_key))
};
let query = (&mut recorder, panicky_decoder);
trie.get_with(&account_key, query)?
};
let account = maybe_account.unwrap_or_else(|| BasicAccount {
@ -1086,7 +1092,8 @@ impl<B: Backend> State<B> {
// TODO: probably could look into cache somehow but it's keyed by
// address, not keccak(address).
let trie = TrieDB::new(self.db.as_hashdb(), &self.root)?;
let acc = match trie.get_with(&account_key, Account::from_rlp)? {
let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed");
let acc = match trie.get_with(&account_key, from_rlp)? {
Some(acc) => acc,
None => return Ok((Vec::new(), H256::new())),
};

View File

@ -244,7 +244,7 @@ mod tests {
]);
let encoded = ::rlp::encode(&block_traces);
let decoded = ::rlp::decode(&encoded);
let decoded = ::rlp::decode(&encoded).expect("error decoding block traces");
assert_eq!(block_traces, decoded);
}
}

View File

@ -576,7 +576,8 @@ mod tests {
#[test]
fn sender_test() {
let t: UnverifiedTransaction = rlp::decode(&::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
let bytes = ::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap();
let t: UnverifiedTransaction = rlp::decode(&bytes).expect("decoding UnverifiedTransaction failed");
assert_eq!(t.data, b"");
assert_eq!(t.gas, U256::from(0x5208u64));
assert_eq!(t.gas_price, U256::from(0x01u64));
@ -645,7 +646,7 @@ mod tests {
use rustc_hex::FromHex;
let test_vector = |tx_data: &str, address: &'static str| {
let signed = rlp::decode(&FromHex::from_hex(tx_data).unwrap());
let signed = rlp::decode(&FromHex::from_hex(tx_data).unwrap()).expect("decoding tx data failed");
let signed = SignedTransaction::new(signed).unwrap();
assert_eq!(signed.sender(), address.into());
println!("chainid: {:?}", signed.chain_id());

View File

@ -193,7 +193,7 @@ mod tests {
);
let encoded = ::rlp::encode(&r);
assert_eq!(&encoded[..], &expected[..]);
let decoded: Receipt = ::rlp::decode(&encoded);
let decoded: Receipt = ::rlp::decode(&encoded).expect("decoding receipt failed");
assert_eq!(decoded, r);
}
@ -211,7 +211,7 @@ mod tests {
);
let encoded = ::rlp::encode(&r);
assert_eq!(&encoded[..], &expected[..]);
let decoded: Receipt = ::rlp::decode(&encoded);
let decoded: Receipt = ::rlp::decode(&encoded).expect("decoding receipt failed");
assert_eq!(decoded, r);
}
}

View File

@ -64,7 +64,7 @@ mod tests {
fn should_encode_and_decode_call_type() {
let original = CallType::Call;
let encoded = encode(&original);
let decoded = decode(&encoded);
let decoded = decode(&encoded).expect("failure decoding CallType");
assert_eq!(original, decoded);
}
}

View File

@ -566,7 +566,8 @@ fn rpc_eth_pending_transaction_by_hash() {
let tester = EthTester::default();
{
let tx = rlp::decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
let bytes = FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap();
let tx = rlp::decode(&bytes).expect("decoding failure");
let tx = SignedTransaction::new(tx).unwrap();
tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
}

View File

@ -45,14 +45,15 @@ pub struct ArchiveDB {
impl ArchiveDB {
/// Create a new instance from a key-value db.
pub fn new(backing: Arc<KeyValueDB>, col: Option<u32>) -> ArchiveDB {
let latest_era = backing.get(col, &LATEST_ERA_KEY).expect("Low-level database error.")
.map(|val| decode::<u64>(&val));
pub fn new(backing: Arc<KeyValueDB>, column: Option<u32>) -> ArchiveDB {
let latest_era = backing.get(column, &LATEST_ERA_KEY)
.expect("Low-level database error.")
.map(|val| decode::<u64>(&val).expect("decoding db value failed"));
ArchiveDB {
overlay: MemoryDB::new(),
backing: backing,
latest_era: latest_era,
column: col,
backing,
latest_era,
column,
}
}

View File

@ -263,7 +263,7 @@ impl EarlyMergeDB {
let mut refs = HashMap::new();
let mut latest_era = None;
if let Some(val) = db.get(col, &LATEST_ERA_KEY).expect("Low-level database error.") {
let mut era = decode::<u64>(&val);
let mut era = decode::<u64>(&val).expect("decoding db value failed");
latest_era = Some(era);
loop {
let mut db_key = DatabaseKey {

View File

@ -137,7 +137,7 @@ impl OverlayDB {
fn payload(&self, key: &H256) -> Option<Payload> {
self.backing.get(self.column, key)
.expect("Low-level database error. Some issue with your hard disk?")
.map(|d| decode(&d))
.map(|d| decode(&d).expect("decoding db value failed"))
}
/// Put the refs and value of the given key, possibly deleting it from the db.

View File

@ -186,7 +186,7 @@ impl OverlayRecentDB {
let mut earliest_era = None;
let mut cumulative_size = 0;
if let Some(val) = db.get(col, &LATEST_ERA_KEY).expect("Low-level database error.") {
let mut era = decode::<u64>(&val);
let mut era = decode::<u64>(&val).expect("decoding db value failed");
latest_era = Some(era);
loop {
let mut db_key = DatabaseKey {
@ -195,7 +195,7 @@ impl OverlayRecentDB {
};
while let Some(rlp_data) = db.get(col, &encode(&db_key)).expect("Low-level database error.") {
trace!("read_overlay: era={}, index={}", era, db_key.index);
let value = decode::<DatabaseValue>(&rlp_data);
let value = decode::<DatabaseValue>(&rlp_data).expect(&format!("read_overlay: Error decoding DatabaseValue era={}, index{}", era, db_key.index));
count += value.inserts.len();
let mut inserted_keys = Vec::new();
for (k, v) in value.inserts {

View File

@ -62,17 +62,18 @@ pub struct RefCountedDB {
impl RefCountedDB {
/// Create a new instance given a `backing` database.
pub fn new(backing: Arc<KeyValueDB>, col: Option<u32>) -> RefCountedDB {
let latest_era = backing.get(col, &LATEST_ERA_KEY).expect("Low-level database error.")
.map(|val| decode::<u64>(&val));
pub fn new(backing: Arc<KeyValueDB>, column: Option<u32>) -> RefCountedDB {
let latest_era = backing.get(column, &LATEST_ERA_KEY)
.expect("Low-level database error.")
.map(|v| decode::<u64>(&v).expect("decoding db value failed"));
RefCountedDB {
forward: OverlayDB::new(backing.clone(), col),
backing: backing,
forward: OverlayDB::new(backing.clone(), column),
backing,
inserts: vec![],
removes: vec![],
latest_era: latest_era,
column: col,
latest_era,
column,
}
}
}

View File

@ -63,13 +63,13 @@ pub const EMPTY_LIST_RLP: [u8; 1] = [0xC0; 1];
///
/// fn main () {
/// let data = vec![0x83, b'c', b'a', b't'];
/// let animal: String = rlp::decode(&data);
/// let animal: String = rlp::decode(&data).expect("could not decode");
/// assert_eq!(animal, "cat".to_owned());
/// }
/// ```
pub fn decode<T>(bytes: &[u8]) -> T where T: Decodable {
pub fn decode<T>(bytes: &[u8]) -> Result<T, DecoderError> where T: Decodable {
let rlp = Rlp::new(bytes);
rlp.as_val().expect("trusted rlp should be valid")
rlp.as_val()
}
pub fn decode_list<T>(bytes: &[u8]) -> Vec<T> where T: Decodable {

View File

@ -209,8 +209,10 @@ struct VDTestPair<T>(Vec<T>, Vec<u8>) where T: Decodable + fmt::Debug + cmp::Eq;
fn run_decode_tests<T>(tests: Vec<DTestPair<T>>) where T: Decodable + fmt::Debug + cmp::Eq {
for t in &tests {
let res: T = rlp::decode(&t.1);
assert_eq!(res, t.0);
let res : Result<T, DecoderError> = rlp::decode(&t.1);
assert!(res.is_ok());
let res = res.unwrap();
assert_eq!(&res, &t.0);
}
}

View File

@ -24,7 +24,7 @@ fn test_encode_foo() {
let out = encode(&foo).into_vec();
assert_eq!(out, expected);
let decoded = decode(&expected);
let decoded = decode(&expected).expect("decode failure");
assert_eq!(foo, decoded);
}
@ -38,7 +38,7 @@ fn test_encode_foo_wrapper() {
let out = encode(&foo).into_vec();
assert_eq!(out, expected);
let decoded = decode(&expected);
let decoded = decode(&expected).expect("decode failure");
assert_eq!(foo, decoded);
}

View File

@ -446,7 +446,7 @@ mod tests {
};
let encoded = ::rlp::encode(&envelope);
let decoded = ::rlp::decode(&encoded);
let decoded = ::rlp::decode(&encoded).expect("failure decoding Envelope");
assert_eq!(envelope, decoded)
}
@ -462,7 +462,7 @@ mod tests {
};
let encoded = ::rlp::encode(&envelope);
let decoded = ::rlp::decode(&encoded);
let decoded = ::rlp::decode(&encoded).expect("failure decoding Envelope");
assert_eq!(envelope, decoded)
}