Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit 28c7318

Browse files
authored
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).
1 parent a7a46f4 commit 28c7318

File tree

28 files changed

+107
-90
lines changed

28 files changed

+107
-90
lines changed

ethcore/light/src/client/header_chain.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,15 @@ impl HeaderChain {
228228
let decoded_header = spec.genesis_header();
229229

230230
let chain = if let Some(current) = db.get(col, CURRENT_KEY)? {
231-
let curr : BestAndLatest = ::rlp::decode(&current);
231+
let curr : BestAndLatest = ::rlp::decode(&current).expect("decoding db value failed");
232232

233233
let mut cur_number = curr.latest_num;
234234
let mut candidates = BTreeMap::new();
235235

236236
// load all era entries, referenced headers within them,
237237
// and live epoch proofs.
238238
while let Some(entry) = db.get(col, era_key(cur_number).as_bytes())? {
239-
let entry: Entry = ::rlp::decode(&entry);
239+
let entry: Entry = ::rlp::decode(&entry).expect("decoding db value failed");
240240
trace!(target: "chain", "loaded header chain entry for era {} with {} candidates",
241241
cur_number, entry.candidates.len());
242242

@@ -524,7 +524,10 @@ impl HeaderChain {
524524
None
525525
}
526526
Ok(None) => panic!("stored candidates always have corresponding headers; qed"),
527-
Ok(Some(header)) => Some((epoch_transition, ::rlp::decode(&header))),
527+
Ok(Some(header)) => Some((
528+
epoch_transition,
529+
::rlp::decode(&header).expect("decoding value from db failed")
530+
)),
528531
};
529532
}
530533
}
@@ -591,7 +594,7 @@ impl HeaderChain {
591594
in an inconsistent state", h_num);
592595
ErrorKind::Database(msg.into())
593596
})?;
594-
::rlp::decode(&bytes)
597+
::rlp::decode(&bytes).expect("decoding db value failed")
595598
};
596599

597600
let total_difficulty = entry.candidates.iter()
@@ -604,9 +607,9 @@ impl HeaderChain {
604607
.total_difficulty;
605608

606609
break Ok(Some(SpecHardcodedSync {
607-
header: header,
608-
total_difficulty: total_difficulty,
609-
chts: chts,
610+
header,
611+
total_difficulty,
612+
chts,
610613
}));
611614
},
612615
None => {
@@ -742,7 +745,7 @@ impl HeaderChain {
742745
/// so including it within a CHT would be redundant.
743746
pub fn cht_root(&self, n: usize) -> Option<H256> {
744747
match self.db.get(self.col, cht_key(n as u64).as_bytes()) {
745-
Ok(val) => val.map(|x| ::rlp::decode(&x)),
748+
Ok(db_fetch) => db_fetch.map(|bytes| ::rlp::decode(&bytes).expect("decoding value from db failed")),
746749
Err(e) => {
747750
warn!(target: "chain", "Error reading from database: {}", e);
748751
None
@@ -793,7 +796,7 @@ impl HeaderChain {
793796
pub fn pending_transition(&self, hash: H256) -> Option<PendingEpochTransition> {
794797
let key = pending_transition_key(hash);
795798
match self.db.get(self.col, &*key) {
796-
Ok(val) => val.map(|x| ::rlp::decode(&x)),
799+
Ok(db_fetch) => db_fetch.map(|bytes| ::rlp::decode(&bytes).expect("decoding value from db failed")),
797800
Err(e) => {
798801
warn!(target: "chain", "Error reading from database: {}", e);
799802
None
@@ -1192,7 +1195,7 @@ mod tests {
11921195

11931196
let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::from_secs(6 * 3600))));
11941197

1195-
let chain = HeaderChain::new(db.clone(), None, &spec, cache, HardcodedSync::Allow).unwrap();
1198+
let chain = HeaderChain::new(db.clone(), None, &spec, cache, HardcodedSync::Allow).expect("failed to instantiate a new HeaderChain");
11961199

11971200
let mut parent_hash = genesis_header.hash();
11981201
let mut rolling_timestamp = genesis_header.timestamp();
@@ -1211,14 +1214,14 @@ mod tests {
12111214
parent_hash = header.hash();
12121215

12131216
let mut tx = db.transaction();
1214-
let pending = chain.insert(&mut tx, header, None).unwrap();
1217+
let pending = chain.insert(&mut tx, header, None).expect("failed inserting a transaction");
12151218
db.write(tx).unwrap();
12161219
chain.apply_pending(pending);
12171220

12181221
rolling_timestamp += 10;
12191222
}
12201223

1221-
let hardcoded_sync = chain.read_hardcoded_sync().unwrap().unwrap();
1224+
let hardcoded_sync = chain.read_hardcoded_sync().expect("failed reading hardcoded sync").expect("failed unwrapping hardcoded sync");
12221225
assert_eq!(hardcoded_sync.chts.len(), 3);
12231226
assert_eq!(hardcoded_sync.total_difficulty, total_difficulty);
12241227
let decoded: Header = hardcoded_sync.header.decode();

ethcore/light/src/net/request_credits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ mod tests {
407407
let costs = CostTable::default();
408408
let serialized = ::rlp::encode(&costs);
409409

410-
let new_costs: CostTable = ::rlp::decode(&*serialized);
410+
let new_costs: CostTable = ::rlp::decode(&*serialized).unwrap();
411411

412412
assert_eq!(costs, new_costs);
413413
}

ethcore/light/src/types/request/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1642,7 +1642,7 @@ mod tests {
16421642
{
16431643
// check as single value.
16441644
let bytes = ::rlp::encode(&val);
1645-
let new_val: T = ::rlp::decode(&bytes);
1645+
let new_val: T = ::rlp::decode(&bytes).unwrap();
16461646
assert_eq!(val, new_val);
16471647

16481648
// check as list containing single value.

ethcore/src/blockchain/blockchain.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ impl<'a> Iterator for EpochTransitionIter<'a> {
438438
return None
439439
}
440440

441-
let transitions: EpochTransitions = ::rlp::decode(&val[..]);
441+
let transitions: EpochTransitions = ::rlp::decode(&val[..]).expect("decode error: the db is corrupted or the data structure has changed");
442442

443443
// if there are multiple candidates, at most one will be on the
444444
// canon chain.
@@ -462,7 +462,7 @@ impl<'a> Iterator for EpochTransitionIter<'a> {
462462
impl BlockChain {
463463
/// Create new instance of blockchain from given Genesis.
464464
pub fn new(config: Config, genesis: &[u8], db: Arc<KeyValueDB>) -> BlockChain {
465-
// 400 is the avarage size of the key
465+
// 400 is the average size of the key
466466
let cache_man = CacheManager::new(config.pref_cache_size, config.max_cache_size, 400);
467467

468468
let mut bc = BlockChain {

ethcore/src/db.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,12 @@ impl Writable for DBTransaction {
218218
}
219219

220220
impl<KVDB: KeyValueDB + ?Sized> Readable for KVDB {
221-
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where T: rlp::Decodable, R: Deref<Target = [u8]> {
222-
let result = self.get(col, &key.key());
221+
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T>
222+
where T: rlp::Decodable, R: Deref<Target = [u8]> {
223+
self.get(col, &key.key())
224+
.expect(&format!("db get failed, key: {:?}", &key.key() as &[u8]))
225+
.map(|v| rlp::decode(&v).expect("decode db value failed") )
223226

224-
match result {
225-
Ok(option) => option.map(|v| rlp::decode(&v)),
226-
Err(err) => {
227-
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
228-
}
229-
}
230227
}
231228

232229
fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: Deref<Target = [u8]> {

ethcore/src/encoded.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,12 @@
2424
//! decoded object where parts like the hash can be saved.
2525
2626
use block::Block as FullBlock;
27-
use header::{BlockNumber, Header as FullHeader};
28-
use transaction::UnverifiedTransaction;
29-
27+
use ethereum_types::{H256, Bloom, U256, Address};
3028
use hash::keccak;
29+
use header::{BlockNumber, Header as FullHeader};
3130
use heapsize::HeapSizeOf;
32-
use ethereum_types::{H256, Bloom, U256, Address};
3331
use rlp::{Rlp, RlpStream};
32+
use transaction::UnverifiedTransaction;
3433
use views::{self, BlockView, HeaderView, BodyView};
3534

3635
/// Owning header view.
@@ -48,7 +47,7 @@ impl Header {
4847
pub fn new(encoded: Vec<u8>) -> Self { Header(encoded) }
4948

5049
/// Upgrade this encoded view to a fully owned `Header` object.
51-
pub fn decode(&self) -> FullHeader { ::rlp::decode(&self.0) }
50+
pub fn decode(&self) -> FullHeader { ::rlp::decode(&self.0).expect("decoding failure") }
5251

5352
/// Get a borrowed header view onto the data.
5453
#[inline]
@@ -205,7 +204,7 @@ impl Block {
205204
pub fn header_view(&self) -> HeaderView { self.view().header_view() }
206205

207206
/// Decode to a full block.
208-
pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0) }
207+
pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0).expect("decoding failure") }
209208

210209
/// Decode the header.
211210
pub fn decode_header(&self) -> FullHeader { self.view().rlp().val_at(0) }

ethcore/src/engines/tendermint/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,10 @@ impl <F> super::EpochVerifier<EthereumMachine> for EpochVerifier<F>
143143
}
144144

145145
fn check_finality_proof(&self, proof: &[u8]) -> Option<Vec<H256>> {
146-
let header: Header = ::rlp::decode(proof);
147-
self.verify_light(&header).ok().map(|_| vec![header.hash()])
146+
match ::rlp::decode(proof) {
147+
Ok(header) => self.verify_light(&header).ok().map(|_| vec![header.hash()]),
148+
Err(_) => None // REVIEW: log perhaps? Not sure what the policy is.
149+
}
148150
}
149151
}
150152

ethcore/src/header.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ mod tests {
398398
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
399399
let nonce_decoded = "ab4e252a7e8c2a23".from_hex().unwrap();
400400

401-
let header: Header = rlp::decode(&header_rlp);
401+
let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
402402
let seal_fields = header.seal.clone();
403403
assert_eq!(seal_fields.len(), 2);
404404
assert_eq!(seal_fields[0], mix_hash);
@@ -415,7 +415,7 @@ mod tests {
415415
// that's rlp of block header created with ethash engine.
416416
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
417417

418-
let header: Header = rlp::decode(&header_rlp);
418+
let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
419419
let encoded_header = rlp::encode(&header).into_vec();
420420

421421
assert_eq!(header_rlp, encoded_header);

ethcore/src/snapshot/account.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ mod tests {
236236
};
237237

238238
let thin_rlp = ::rlp::encode(&account);
239-
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
239+
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp).unwrap(), account);
240240

241241
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();
242242
let fat_rlp = Rlp::new(&fat_rlps[0]).at(1).unwrap();
@@ -261,7 +261,7 @@ mod tests {
261261
};
262262

263263
let thin_rlp = ::rlp::encode(&account);
264-
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
264+
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp).unwrap(), account);
265265

266266
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();
267267
let fat_rlp = Rlp::new(&fat_rlp[0]).at(1).unwrap();
@@ -286,7 +286,7 @@ mod tests {
286286
};
287287

288288
let thin_rlp = ::rlp::encode(&account);
289-
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
289+
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp).unwrap(), account);
290290

291291
let fat_rlps = to_fat_rlps(&keccak(addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), 500, 1000).unwrap();
292292
let mut root = KECCAK_NULL_RLP;

ethcore/src/snapshot/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: &Mutex<SnapshotWriter +
281281
// account_key here is the address' hash.
282282
for item in account_trie.iter()? {
283283
let (account_key, account_data) = item?;
284-
let account = ::rlp::decode(&*account_data);
284+
let account = ::rlp::decode(&*account_data)?;
285285
let account_key_hash = H256::from_slice(&account_key);
286286

287287
let account_db = AccountDB::from_hash(db, account_key_hash);
@@ -467,10 +467,10 @@ fn rebuild_accounts(
467467
*out = (hash, thin_rlp);
468468
}
469469
if let Some(&(ref hash, ref rlp)) = out_chunk.iter().last() {
470-
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp).storage_root);
470+
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp)?.storage_root);
471471
}
472472
if let Some(&(ref hash, ref rlp)) = out_chunk.iter().next() {
473-
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp).storage_root);
473+
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp)?.storage_root);
474474
}
475475
Ok(status)
476476
}

0 commit comments

Comments
 (0)