-
Notifications
You must be signed in to change notification settings - Fork 809
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
[Merged by Bors] - add quoted serialization util for FixedVector
and VariableList
#1794
Conversation
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
@@ -617,6 +617,36 @@ impl<N: Unsigned + Clone> tree_hash::TreeHash for Bitfield<Fixed<N>> { | |||
} | |||
} | |||
|
|||
/// 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.
@@ -320,7 +320,8 @@ mod test { | |||
|
|||
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) |
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 :)
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 <[email protected]>
Pull request successfully merged into master. Build succeeded: |
FixedVector
and VariableList
FixedVector
and VariableList
Issue Addressed
This comment: #1776 (comment)
Proposed Changes
FixedVector
andVariableList
ssz_types
has onserde_utils
to avoid a circular dependency.Additional Info