This repository has been archived by the owner on Nov 6, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Decoding headers can fail #8570
Merged
Merged
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
70db4f5
rlp::decode returns Result
dvdplm 3b6f5c9
Fix journaldb to handle rlp::decode Result
dvdplm f2f47a4
Fix ethcore to work with rlp::decode returning Result
dvdplm ae8483d
Light client handles rlp::decode returning Result
dvdplm af4970a
Fix tests in rlp_derive
dvdplm ffd7a65
Fix tests
dvdplm 6eac3a2
Cleanup
dvdplm 23f4597
cleanup
dvdplm 40eed16
Allow panic rather than breaking out of iterator
dvdplm c8b5c16
Let decoding failures when reading from disk blow up
dvdplm ea4a6d2
syntax
dvdplm ea17bd7
Fix the trivial grumbles
dvdplm 7b07b69
Fix failing tests
dvdplm 0930b0a
Make Account::from_rlp return Result
dvdplm 245ed85
Syntx, sigh
dvdplm 9cdad30
Temp-fix for decoding failures
dvdplm c2afc3c
Header::decode returns Result
dvdplm b7d7d55
Do not continue reading from the DB when a value could not be read
dvdplm dc3269a
Merge branch 'fix/rlp-decode-returns-result-issue-8033' into fix/deco…
dvdplm 9ca99dd
Fix tests
dvdplm 9ecd8c9
Merge branch 'master' into fix/decoding-headers-can-fail-#8553
dvdplm b252fc1
Handle header decoding in light_sync
dvdplm 25491ff
Handling header decoding errors
dvdplm 97906c3
Let the DecodeError bubble up unchanged
dvdplm eaf6ed2
Remove redundant error conversion
dvdplm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -290,6 +290,12 @@ error_chain! { | |
description("Unknown engine name") | ||
display("Unknown engine name ({})", name) | ||
} | ||
|
||
#[doc = "RLP decoding errors"] | ||
Decoder(err: ::rlp::DecoderError) { | ||
description("decoding value failed") | ||
display("decoding value failed with error: {}", err) | ||
} | ||
} | ||
} | ||
|
||
|
@@ -310,11 +316,12 @@ impl From<AccountsError> for Error { | |
fn from(err: AccountsError) -> Error { | ||
ErrorKind::AccountProvider(err).into() | ||
} | ||
} | ||
} | ||
|
||
// REVIEW: I changed this from `UtilError::from(err).into()` to this because I could not get it to work and I couldn't find anything using it. Ok? | ||
impl From<::rlp::DecoderError> for Error { | ||
fn from(err: ::rlp::DecoderError) -> Error { | ||
UtilError::from(err).into() | ||
ErrorKind::Decoder(err).into() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 imo |
||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,13 +16,11 @@ | |
|
||
//! Helpers for decoding and verifying responses for headers. | ||
|
||
use std::fmt; | ||
|
||
use ethcore::encoded; | ||
use ethcore::header::Header; | ||
use ethcore::{self, encoded, header::Header}; | ||
use ethereum_types::H256; | ||
use light::request::{HashOrNumber, CompleteHeadersRequest as HeadersRequest}; | ||
use rlp::DecoderError; | ||
use ethereum_types::H256; | ||
use std::fmt; | ||
|
||
/// Errors found when decoding headers and verifying with basic constraints. | ||
#[derive(Debug, PartialEq)] | ||
|
@@ -45,6 +43,18 @@ impl From<DecoderError> for BasicError { | |
} | ||
} | ||
|
||
impl From<ethcore::error::Error> for BasicError { | ||
fn from(err: ethcore::error::Error) -> BasicError { | ||
match err { | ||
ethcore::error::Error(ethcore::error::ErrorKind::Decoder(dec_err), _) => { | ||
BasicError::Decoder(dec_err) | ||
}, | ||
_ => panic!("unhandled ethcore error in light_sync") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and this will be redundant |
||
} | ||
|
||
} | ||
} | ||
|
||
impl fmt::Display for BasicError { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
write!(f, "Header response verification error: ")?; | ||
|
@@ -74,19 +84,23 @@ pub trait Constraint { | |
|
||
/// Do basic verification of provided headers against a request. | ||
pub fn verify(headers: &[encoded::Header], request: &HeadersRequest) -> Result<Vec<Header>, BasicError> { | ||
let headers: Vec<_> = headers.iter().map(|h| h.decode()).collect(); | ||
let headers: Result<Vec<_>, _> = headers.iter().map(|h| h.decode() ).collect(); | ||
match headers { | ||
Ok(headers) => { | ||
let reverse = request.reverse; | ||
|
||
Max(request.max as usize).verify(&headers, reverse)?; | ||
match request.start { | ||
HashOrNumber::Number(ref num) => StartsAtNumber(*num).verify(&headers, reverse)?, | ||
HashOrNumber::Hash(ref hash) => StartsAtHash(*hash).verify(&headers, reverse)?, | ||
} | ||
|
||
let reverse = request.reverse; | ||
SkipsBetween(request.skip).verify(&headers, reverse)?; | ||
|
||
Max(request.max as usize).verify(&headers, reverse)?; | ||
match request.start { | ||
HashOrNumber::Number(ref num) => StartsAtNumber(*num).verify(&headers, reverse)?, | ||
HashOrNumber::Hash(ref hash) => StartsAtHash(*hash).verify(&headers, reverse)?, | ||
Ok(headers) | ||
}, | ||
Err(e) => Err(e.into()) | ||
} | ||
|
||
SkipsBetween(request.skip).verify(&headers, reverse)?; | ||
|
||
Ok(headers) | ||
} | ||
|
||
struct StartsAtNumber(u64); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -395,7 +395,7 @@ impl Parity for ParityClient { | |
|
||
let engine = self.light_dispatch.client.engine().clone(); | ||
let from_encoded = move |encoded: encoded::Header| { | ||
let header = encoded.decode(); | ||
let header = encoded.decode().expect("decoding error"); // REVIEW: not sure what to do here; what is a decent return value for the error case here? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe it should be if |
||
let extra_info = engine.extra_info(&header); | ||
RichHeader { | ||
inner: Header { | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it's better to return
rlp::Error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using the same
Error
type for all ethcore crate is one of the biggest anti patterns that we have in our codebase. Unfortunately when this code was written, we didn't know thatThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean changing the signature from
…to:
?
Doing that works and surprisingly (to me) did not break a lot of code. There was one instance of having to
map_err
arlp::DecoderError
into anethcore::error::Error
to makeand_then
work, and that's a little awkward.