Don't panic in import_block if invalid rlp (#8522)

* Don't panic in import_block if invalid rlp

* Remove redundant type annotation

* Replace RLP header view usage with safe decoding

Using the view will panic with invalid RLP. Here we use Rlp decoding directly which will return a `Result<_, DecoderError>`. While this path currently should not have any invalid RLP - it makes it safer if ever called with invalid RLP from other code paths.
This commit is contained in:
Andrew Jones
2018-05-03 08:01:13 +01:00
committed by Marek Kotewicz
parent eec7364760
commit 66c0638f3b
5 changed files with 46 additions and 22 deletions

View File

@@ -734,6 +734,7 @@ mod tests {
use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block};
use error::*;
use views::BlockView;
use bytes::Bytes;
// create a test block queue.
// auto_scaling enables verifier adjustment.
@@ -746,6 +747,10 @@ mod tests {
BlockQueue::new(config, engine, IoChannel::disconnected(), true)
}
fn new_unverified(bytes: Bytes) -> Unverified {
Unverified::from_rlp(bytes).expect("Should be valid rlp")
}
#[test]
fn can_be_created() {
// TODO better test
@@ -757,7 +762,7 @@ mod tests {
#[test]
fn can_import_blocks() {
let queue = get_test_queue(false);
if let Err(e) = queue.import(Unverified::new(get_good_dummy_block())) {
if let Err(e) = queue.import(new_unverified(get_good_dummy_block())) {
panic!("error importing block that is valid by definition({:?})", e);
}
}
@@ -765,11 +770,11 @@ mod tests {
#[test]
fn returns_error_for_duplicates() {
let queue = get_test_queue(false);
if let Err(e) = queue.import(Unverified::new(get_good_dummy_block())) {
if let Err(e) = queue.import(new_unverified(get_good_dummy_block())) {
panic!("error importing block that is valid by definition({:?})", e);
}
let duplicate_import = queue.import(Unverified::new(get_good_dummy_block()));
let duplicate_import = queue.import(new_unverified(get_good_dummy_block()));
match duplicate_import {
Err(e) => {
match e {
@@ -786,7 +791,7 @@ mod tests {
let queue = get_test_queue(false);
let block = get_good_dummy_block();
let hash = view!(BlockView, &block).header().hash().clone();
if let Err(e) = queue.import(Unverified::new(block)) {
if let Err(e) = queue.import(new_unverified(block)) {
panic!("error importing block that is valid by definition({:?})", e);
}
queue.flush();
@@ -802,14 +807,14 @@ mod tests {
let queue = get_test_queue(false);
let block = get_good_dummy_block();
let hash = view!(BlockView, &block).header().hash().clone();
if let Err(e) = queue.import(Unverified::new(block)) {
if let Err(e) = queue.import(new_unverified(block)) {
panic!("error importing block that is valid by definition({:?})", e);
}
queue.flush();
queue.drain(10);
queue.mark_as_good(&[ hash ]);
if let Err(e) = queue.import(Unverified::new(get_good_dummy_block())) {
if let Err(e) = queue.import(new_unverified(get_good_dummy_block())) {
panic!("error importing block that has already been drained ({:?})", e);
}
}
@@ -817,7 +822,7 @@ mod tests {
#[test]
fn returns_empty_once_finished() {
let queue = get_test_queue(false);
queue.import(Unverified::new(get_good_dummy_block()))
queue.import(new_unverified(get_good_dummy_block()))
.expect("error importing block that is valid by definition");
queue.flush();
queue.drain(1);
@@ -835,7 +840,7 @@ mod tests {
assert!(!queue.queue_info().is_full());
let mut blocks = get_good_dummy_block_seq(50);
for b in blocks.drain(..) {
queue.import(Unverified::new(b)).unwrap();
queue.import(new_unverified(b)).unwrap();
}
assert!(queue.queue_info().is_full());
}
@@ -863,7 +868,7 @@ mod tests {
*queue.state.0.lock() = State::Work(0);
for block in get_good_dummy_block_seq(5000) {
queue.import(Unverified::new(block)).expect("Block good by definition; qed");
queue.import(new_unverified(block)).expect("Block good by definition; qed");
}
// almost all unverified == bump verifier count.