Skip to content
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

Fix off-by-one. #243

Merged
merged 2 commits into from
Oct 21, 2019
Merged

Fix off-by-one. #243

merged 2 commits into from
Oct 21, 2019

Conversation

tomusdrw
Copy link
Contributor

No description provided.

Copy link
Member

@ordian ordian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch!
I think in parity-ethereum we deny hex string of odd length before deserializing them.
The new behavior is to essentially pad it with leading 0 if it has an odd length, so e.g. 0x123 is treated as 0x0123. This seems reasonable to me, but should be documented somewhere.

@tomusdrw
Copy link
Contributor Author

@ordian Indeed Parity Ethereum is following the jsonrpc spec from here: https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding and it clearly states what values are valid and what not.
impl-serde though is a bit more relaxed in this.

@@ -105,7 +105,7 @@ pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error> where

let bytes_len = v.len() - 2;
let mut modulus = bytes_len % 2;
let mut bytes = vec![0u8; bytes_len / 2 + 1];
let mut bytes = vec![0u8; (bytes_len + 1) / 2];
Copy link
Member

@niklasad1 niklasad1 Oct 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why bother with this complex logic?
Isn't better to use Vec::new() / Vec::with_capacity() and Vec::push?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it's a performance optimization (hopefuly measureable), which is justified, since this code might be on a hot path.
Also this logic is not that complex imho, seems it was just untested properly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I for one kind of agree with Niklas here: it's a bit odd and I'm surprised to learn it's faster to init a vec with vec![0u8; 123] than Vec::with_capacity(123).

(No action needed here, I'm just curious)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm about to add benches for Bytes to be continued :P

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, thanks for making me realize this is actually a vec. I was pretty sure that we just allocate an array here (but obviously we don't cause it's not a constant size)
I'm really curious about the performance indeed, as just using push instead of direct access seems way less error prone, and with_capacity should ensure that there are no re-allocations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really hope there's no difference in performance! :)

@ordian ordian merged commit 31c67cf into master Oct 21, 2019
@ordian ordian deleted the td-ser branch October 21, 2019 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants