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

short_vec::decode_len() returns wrong size for aliased values #11624

Merged
merged 3 commits into from
Aug 14, 2020

Conversation

t-nelson
Copy link
Contributor

@t-nelson t-nelson commented Aug 14, 2020

Problem

short_vec::decode_len() always returns the byte size of the most compact encoding, despite the existence of larger aliases. In conjunction with ShortVec this allows for interesting deserialization games to be played.

h/t @svenski123 ❤️

Summary of Changes

Add failing test
Factor byte visitation logic out of ShortU16 deserializer to a helper
Reimplement decode_len() using aforementioned helper

fixes #11628

@t-nelson t-nelson requested a review from garious August 14, 2020 04:26
Copy link
Contributor

@garious garious left a comment

Choose a reason for hiding this comment

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

.

garious
garious previously approved these changes Aug 14, 2020
@t-nelson t-nelson added the automerge Merge this Pull Request automatically once CI passes label Aug 14, 2020
@mergify mergify bot removed the automerge Merge this Pull Request automatically once CI passes label Aug 14, 2020
@mergify
Copy link
Contributor

mergify bot commented Aug 14, 2020

automerge label removed due to a CI failure

@t-nelson t-nelson added the automerge Merge this Pull Request automatically once CI passes label Aug 14, 2020
@mergify mergify bot dismissed garious’s stale review August 14, 2020 07:37

Pull request has been modified.

@codecov
Copy link

codecov bot commented Aug 14, 2020

Codecov Report

Merging #11624 into master will increase coverage by 0.0%.
The diff coverage is 90.4%.

@@           Coverage Diff           @@
##           master   #11624   +/-   ##
=======================================
  Coverage    82.0%    82.0%           
=======================================
  Files         330      330           
  Lines       76029    76059   +30     
=======================================
+ Hits        62405    62435   +30     
  Misses      13624    13624           

@svenski123
Copy link
Contributor

Given that the maximum size of a transaction on the wire is 1,232 bytes (PACKET_DATA_SIZE in sdk/src/packet.rs) and that the size of a Pubkey is 32 bytes, it's not possible to fit more than 38 account public keys into a transaction.

Along similar lines, it is not possible to fit more than 19 signatures in a single transaction.

Thus I would suggest defining the # number of signatures and # of accounts fields as a single unsigned byte, with the two high bits reserved and set to zero. This allows for values from 0 - 63 which is more than enough given the maximum transaction size, and allows for an easy to introduce / identify a new wire format in the future.

I do not think there would be any existing production transactions with a multi-byte ShortU16 encoding.

I would also suggest considering making a similar change to the number of instructions in Message and the number of account indicies and data bytes in CompiledInstruction.

Of course I note it is possible to encode more than 256 u8 account indices in one instruction and it is possible to encode more than 256 CompiledInstructions (provided they're short) in a Message. However I do not consider there is a reasonable need for more than 255 or (even 127) accounts per instruction. Similarly I would consider a limit of 127 instructions per transaction sufficient.

Replacing variable length encoded ShortU16's with single bytes makes for simpler encoding / decoding logic (especially non-Rust clients) and better security.

@garious
Copy link
Contributor

garious commented Aug 14, 2020

Good points! Always looking for opportunities to inch closer to a repr(C) format.

@t-nelson t-nelson merged commit 30dbe25 into solana-labs:master Aug 14, 2020
@t-nelson t-nelson deleted the shortu16_aliases branch August 14, 2020 14:17
mergify bot added a commit that referenced this pull request Aug 14, 2020
) (#11631)

* Add failing test for decoding ShortU16 alias values

(cherry picked from commit 338f66f)

* Factor out ShortU16 deser vistor logic to helper

(cherry picked from commit 6222fbc)

* Reimplement decode_len() with ShortU16 vistor helper

(cherry picked from commit 30dbe25)

Co-authored-by: Trent Nelson <trent@solana.com>
mergify bot added a commit that referenced this pull request Aug 14, 2020
) (#11630)

* Add failing test for decoding ShortU16 alias values

(cherry picked from commit 338f66f)

* Factor out ShortU16 deser vistor logic to helper

(cherry picked from commit 6222fbc)

* Reimplement decode_len() with ShortU16 vistor helper

(cherry picked from commit 30dbe25)

Co-authored-by: Trent Nelson <trent@solana.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge Merge this Pull Request automatically once CI passes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Hash / deserialized data mismatch
3 participants