-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ETCM-709] Improve ommers validations. #948
[ETCM-709] Improve ommers validations. #948
Conversation
416518a
to
932853b
Compare
src/main/scala/io/iohk/ethereum/consensus/validators/std/StdOmmersValidator.scala
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcher.scala
Outdated
Show resolved
Hide resolved
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.
Better errors and simpler code is better 👍
I have no opinion about the log level stuff. I think we might want to bump default log level for end users to warning anyway? There's room for a story to really think about what we want out of logging, I think.
src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcher.scala
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/consensus/validators/std/StdOmmersValidator.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/consensus/ethash/validators/OmmersValidator.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/consensus/validators/std/StdOmmersValidator.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/consensus/validators/std/StdOmmersValidator.scala
Show resolved
Hide resolved
src/test/scala/io/iohk/ethereum/consensus/validators/std/StdOmmersValidatorSpec.scala
Show resolved
Hide resolved
7e4cd10
to
31c4792
Compare
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.
Looks good! Some comments regarding the refactoring and log levels.
src/main/scala/io/iohk/ethereum/consensus/validators/std/StdOmmersValidator.scala
Outdated
Show resolved
Hide resolved
|
||
if (ommersThatAreAncestors.nonEmpty) Left(OmmerIsAncestorError) | ||
else if (!ommersParentsAreAllAncestors) Left(OmmerParentIsNotAncestorError) | ||
else Right(OmmersValid) |
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 wouldn't default to Right
in the validation.
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.
It's because no error was found, what would you return there then?
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 gave an example below why defaulting to Right
is problematic.
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.
Sorry, but where?
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.
Sorry, missed the comment. I was referring to #948 (comment)
In general I'd say the problem with defaulting to Right
is that it will also return Right for every unhandled/unexpected case while the other way around is more restrictive, making the errors more visible.
In this specific case I'd re-add at the very least the check that was removed in https://github.com/input-output-hk/mantis/pull/948/files#diff-4ffb3286be2984d1679ee76bbb2e5e404f64147f1d77ab0eb95f8031a1379635L160
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.
That is the same check that will be added in ETCM-776
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.
ETCM-776 was created after I wrote that comment.
...and I still think that defaulting to Right in validations is less secure.
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 understand the philosophy of what you are saying, but I also think that in this case it would really overcomplicate the code. The whole reason why I was not able to understand why a block validation failed in testnet was because those two separate errors OmmerIsAncestorError
and OmmerParentIsNotAncestorError
did not exist.
This code is only making these two specific validations otherwise there is no 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.
What I can propose is a bigger refactoring, than ETCM-776. GetNBlocksBack
should be part of the for
comprehension, inside the more generic validate
method and validateOmmersAncestors
could be divided into two method (each one returning only one 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.
I have rewritten ETCM-776
src/main/scala/io/iohk/ethereum/consensus/validators/std/StdOmmersValidator.scala
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/consensus/ethash/validators/OmmersValidator.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcher.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcher.scala
Outdated
Show resolved
Hide resolved
0c2d3b4
to
79a3f27
Compare
Tested FastSync and RegularSync once again in |
else { | ||
val ommersHeaderError = validationsResult | ||
.collect { case Left(error) => error } | ||
.map(error => OmmersHeaderError(List(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.
.map
and .reduce
are not needed...can be simplified to
val errors = validationsResult.collect { case Left(error) => error }.toList
Left(OmmersHeaderError(errors))
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.
You are right, I really overcomplicated that :)
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.
:)
79a3f27
to
8753c48
Compare
8753c48
to
5fb0381
Compare
Replaced OmmersAncestorsError by more specific OmmerIsAncestorError and OmmerParentIsNotAncestorError. Renamed OmmersNotValidError to OmmersHeaderError and added the underlying reason for failure Refactored validateOmmersAncestors method. Refactored validateOmmersHeaders method to not hide the underlying failing reason. Reorganized some packages because some classes were not in the correct package and/or the Spec was not in the correct package. Renamed some specs to better reflect the class being tested
5fb0381
to
2ac53c6
Compare
Description
In testnet we observed the following error message
Block import error BlockImportFailed(OmmersAncestorsError)
, but looking at the code it was not possible to know exactly why the validation failed.The goal of this PR is to allow for better debugging in case we observe the same error message again.
Proposed Solution
Replaced OmmersAncestorsError by more specific OmmerIsAncestorError and OmmerParentIsNotAncestorError.
Renamed OmmersNotValidError to OmmersHeaderError and added the underlying reason for failure
Refactored validateOmmersAncestors method.
Refactored validateOmmersHeaders method to not hide the underlying failing reason.
Reorganized some packages because some classes were not in the correct package and/or the Spec was not in the correct package. Renamed some specs to better reflect the class being tested
Raised the log level of some logs in BlockFetcher because there are barely any logs this actor when debug logs are disabled
Testing
Connected to Sagano with FastSync off and RegularSync is importing blocks properly