-
Notifications
You must be signed in to change notification settings - Fork 945
[Merged by Bors] - add quoted serialization util for FixedVector and VariableList
#1794
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
Conversation
paulhauner
left a comment
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.
Nice, will be great to fix this up for users.
I had a few small comments, should be easy.
Had to remove the dependency that ssz_types has on serde_utils to avoid a circular dependency.
Perhaps we could remove this circular dep (and duplication of hex_decode and PrefixedHexVisitor) by defining the quoted_u64_fixed_vec and quoted_u64_var_list in the ssz_types crate, instead of serde_utils. I can't imagine these definitions being used anywhere else than in the ssz_types crate, so I think it makes sense structurally.
|
|
||
| #[derive(Serialize, Deserialize)] | ||
| #[serde(transparent)] | ||
| pub struct QuotedIntWrapper { |
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 pretty minor, but perhaps we could import this from crate::quoted_u64_vec?
|
|
||
| #[derive(Serialize, Deserialize)] | ||
| #[serde(transparent)] | ||
| pub struct QuotedIntWrapper { |
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.
As above, regarding importing existing definition.
| let val: QuotedIntWrapper = val; | ||
| vec.push(val.int); | ||
| } | ||
| let fix: FixedVector<u64, N> = FixedVector::from(vec); |
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 can see it's subjective, but I think it would be safest if we reject anything that doesn't match the N length. This is what we do in ssz, so it seems fitting here.
Ideally, we would want to avoid reading any more than N elements from seq (as to prevent unnecessary allocations).
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.
Yes, I think you're totally right. It's even explicit in the API spec: https://github.com/ethereum/eth2.0-APIs/blob/master/types/state.yaml#L71
| where | ||
| S: Serializer, | ||
| { | ||
| let mut seq = serializer.serialize_seq(Some(value.len()))?; |
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.
IMO, no need to check the len against N here. We can rely on the upstream type (FixedVector).
No change requested.
| let val: QuotedIntWrapper = val; | ||
| vec.push(val.int); | ||
| } | ||
| let fix: VariableList<u64, N> = VariableList::from(vec); |
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.
As per previous comment, I think it would be safest to check we don't exceed the N length.
consensus/ssz_types/src/bitfield.rs
Outdated
| } | ||
| } | ||
|
|
||
| /// Encode `data` as a 0x-prefixed hex string. |
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.
See primary review comment regarding code duplication.
| let vec = vec![]; | ||
| let fixed: VariableList<u64, U4> = VariableList::from(vec); | ||
| assert_eq!(&fixed[..], &vec![][..]); | ||
| let expected: Vec<u64> = vec![]; |
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.
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.
Can you use &[] instead of &vec![][..]?
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 is weird that the modules caused the change tho.
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.
updated 👍
| let val: QuotedIntWrapper = val; | ||
| vec.push(val.int); | ||
| } | ||
| let fix: VariableList<u64, N> = VariableList::new(vec) |
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.
| let fix: VariableList<u64, N> = VariableList::new(vec) | |
| let list: VariableList<u64, N> = VariableList::new(vec) |
| } | ||
| let fix: VariableList<u64, N> = VariableList::new(vec) | ||
| .map_err(|e| serde::de::Error::custom(format!("VariableList: {:?}", e)))?; | ||
| Ok(fix) |
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.
| Ok(fix) | |
| Ok(list) |
paulhauner
left a comment
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.
Only a couple of more suggestions, if you don't mind?
| { | ||
| let mut vec = vec![]; | ||
|
|
||
| while let Some(val) = seq.next_element()? { |
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 wasn't clear on this before, but I think we should add a safe-guard against growing vec greater than N::to_usize(). I was tempted to just leave it as is, but some of the vulnerabilities observed in ssz have made me weary of over-allocating.
E.g., (I'm not sure if this compiles)
/// Returns a `Vec` of no more than `max_items` length.
fn deser_max(mut seq: A, max_items: usize) -> Result<Vec<QuotedIntWrapper>, A::Error>
where
A: serde::de::SeqAccess<'a>,
{
let mut vec = vec![];
let mut counter = 0;
while let Some(val) = seq.next_element()? {
counter += 1;
if counter > max_items {
return Err(Something)
}
vec.push(val.int);
}
Ok(vec)
}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.
Yeah, makes sense. Updated 👍
| { | ||
| let mut vec = vec![]; | ||
|
|
||
| while let Some(val) = seq.next_element()? { |
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 fn deser_max function should work here too :)
paulhauner
left a comment
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.
Nice!
bors r+
…1794) ## Issue Addressed This comment: #1776 (comment) ## Proposed Changes - Add quoted serde utils for `FixedVector` and `VariableList` - Had to remove the dependency that `ssz_types` has on `serde_utils` to avoid a circular dependency. ## Additional Info Co-authored-by: realbigsean <seananderson33@gmail.com>
|
Pull request successfully merged into master. Build succeeded: |
FixedVector and VariableListFixedVector and VariableList

Issue Addressed
This comment: #1776 (comment)
Proposed Changes
FixedVectorandVariableListssz_typeshas onserde_utilsto avoid a circular dependency.Additional Info