-
Notifications
You must be signed in to change notification settings - Fork 1.7k
spec: Validate required divisor fields are not 0 #7933
spec: Validate required divisor fields are not 0 #7933
Conversation
It's used to validate that a Spec's uint field used as a divisor is not zero.
Prevents panics due to divide-by-zero on the gas_limit_bound_divisor field.
Prevents panics due to divide-by-zero on the difficulty_bound_divisor field.
It looks like @asymmetric signed our Contributor License Agreement. 👍 Many thanks, Parity Technologies CLA Bot |
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.
thanks!
"maxCodeSize": "0x1000" | ||
}"#; | ||
|
||
let _deserialized: Params = serde_json::from_str(s).unwrap(); |
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.
how does printed error look like? Does it say describe which field is expected to have a non-zero value
?
Maybe instead of using should_panic
you could do:
assert_eq!(serde_json::from_str(s).unwrap_err().to_string(), "error message");
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 doesn't specify which field is failing, only it's position. The error message looks like this:
"invalid value: integer `0`, expected a non-zero value at line 3 column 39"
. I agree the test can be converted not to use should_panic
. It would be nice to show the field name but this is the same behavior we already have for other fields.
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.
Why is it better to avoid #[should_panic(expect)]
? I thought that using an attribute would make more sense, since it's available.
@paritytech/ci @General-Beck last commit - 555e0cb is not run by CI. Could you check why? |
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.
LGTM! 👍
@asymmetric I think the following will work for pub fn validate_opt_non_zero<'de, D>(d: D) -> Result<Option<Uint>, D::Error> where D: Deserializer<'de> {
let value: Option<Uint> = Option::deserialize(d)?;
if let Some(value) = value {
if value == Uint(U256::from(0)) {
return Err(Error::invalid_value(Unexpected::Unsigned(value.into()), &"a non-zero value"))
}
}
Ok(value)
} You then need to enable #[serde(rename="difficultyIncrementDivisor")]
#[serde(default, deserialize_with="uint::validate_opt_non_zero")]
pub difficulty_increment_divisor: Option<Uint>, |
@andresilva Thanks, that seems to have done the trick! I was declaring the validation function as pub fn validate_optional_non_zero<'de, D>(d: Option<D>) -> Result<Option<Uint>, D::Error> where D: Deserializer<'de> (i.e. the argument was an error[E0308]: mismatched types
--> json/src/spec/ethash.rs:23:35
|
23 | #[derive(Clone, Debug, PartialEq, Deserialize)]
| ^^^^^^^^^^^
| |
| expected enum `std::option::Option`, found type parameter
| help: try using a variant of the expected type: `serde::export::Some(__deserializer)`
|
= note: expected type `std::option::Option<_>`
found type `__D` By the way, it compiles even without |
Used to validate Option<Uint> divisor fields.
Tests fail :) |
@asymmetric I think when you use |
When using `#[serde(deserialize_with)]`, `#[serde(default)]` must be specified so that missing fields can be deserialized with the deserializer for `None`.
* Add validate_non_zero function It's used to validate that a Spec's uint field used as a divisor is not zero. * Add deserialize_with to gas_limit_bound_divisor Prevents panics due to divide-by-zero on the gas_limit_bound_divisor field. * Add deserialize_with to difficulty_bound_divisor Prevents panics due to divide-by-zero on the difficulty_bound_divisor field. * Add validate_optional_non_zero function Used to validate Option<Uint> divisor fields. * Use deserialize_with on optional divisor fields. * Add #[serde(default)] attribute to divisor fields When using `#[serde(deserialize_with)]`, `#[serde(default)]` must be specified so that missing fields can be deserialized with the deserializer for `None`.
* Add validate_non_zero function It's used to validate that a Spec's uint field used as a divisor is not zero. * Add deserialize_with to gas_limit_bound_divisor Prevents panics due to divide-by-zero on the gas_limit_bound_divisor field. * Add deserialize_with to difficulty_bound_divisor Prevents panics due to divide-by-zero on the difficulty_bound_divisor field. * Add validate_optional_non_zero function Used to validate Option<Uint> divisor fields. * Use deserialize_with on optional divisor fields. * Add #[serde(default)] attribute to divisor fields When using `#[serde(deserialize_with)]`, `#[serde(default)]` must be specified so that missing fields can be deserialized with the deserializer for `None`.
* ECIP 1041 - Remove Difficulty Bomb (#7905) Enable difficulty bomb defusion at block: - 5900000 on Ethereum Classic mainnet, - 2300000 on morden testnet. Reference: https://github.com/ethereumproject/ECIPs/blob/master/ECIPs/ECIP-1041.md * spec: Validate required divisor fields are not 0 (#7933) * Add validate_non_zero function It's used to validate that a Spec's uint field used as a divisor is not zero. * Add deserialize_with to gas_limit_bound_divisor Prevents panics due to divide-by-zero on the gas_limit_bound_divisor field. * Add deserialize_with to difficulty_bound_divisor Prevents panics due to divide-by-zero on the difficulty_bound_divisor field. * Add validate_optional_non_zero function Used to validate Option<Uint> divisor fields. * Use deserialize_with on optional divisor fields. * Add #[serde(default)] attribute to divisor fields When using `#[serde(deserialize_with)]`, `#[serde(default)]` must be specified so that missing fields can be deserialized with the deserializer for `None`. * Kovan WASM fork code (#7849) * kovan fork code * introduce ethcore level vm_factory and let it fail * fix json tests * wasmcosts as option * review changes * wasm costs in parser * fix evm tests * review fixes * fix test * remove redundant json field
This is a replacement for #7882, implementing the check at the the deserialization level with the addition of a
#[serde(deserialize_with)
attribute on the requiredUint
divisor fields.Optional<Uint>
divisor fields are not checked at the moment, since I was having trouble getting that to work./cc @AndreaSilva @rphmeier
Closes #7482.
Closes #7882.