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

rpc: rework binary encoding. BREAKING CHANGE #11646

Merged
merged 5 commits into from
Aug 18, 2020
Merged

Conversation

mvines
Copy link
Member

@mvines mvines commented Aug 15, 2020

Problems:

  1. base58 is slow, not all RPC method have a base64 encoding option
  2. The usage of term "binary" for base58 is confusing
  3. The usage of term "binary64" for base64 makes it worse
  4. UiAccountData is not deserializable from Rust due to the untagged Binary(String) and Binary64(String) enums, requiring RpcClient hacks
  5. RPC binary results that don't include the encoding type will make it too difficult add new binary encodings in the future without breaking changes

Changes:

  1. Add base64 encoding support to getConfirmedTransaction/getConfirmedBlock
  2. "binary" encoding is no longer documented in the JSON RPC API (but still supported). A new "base58" encoding is added
  3. "binary64" encoding is renamed to "base64". <-- BREAKING CHANGE
  4. RPC endpoints that return a UiAccountData for the "base58"/"base64" encoding now return an array of two elements, ["encoded data", "encoding type"] instead of just "encoded data". This allows serde_json to work. <-- BREAKING CHANGE
  5. The binary format change to resolve 4 solves this problem as well.

TODO

  • Inform downstream users of binary64 that they need to adjust their RPC calls, or update web3.js

transaction-status/src/lib.rs Outdated Show resolved Hide resolved
@mvines mvines marked this pull request as draft August 15, 2020 15:50
@mvines mvines marked this pull request as ready for review August 16, 2020 01:02
@codecov
Copy link

codecov bot commented Aug 16, 2020

Codecov Report

Merging #11646 into master will decrease coverage by 0.0%.
The diff coverage is 60.3%.

@@            Coverage Diff            @@
##           master   #11646     +/-   ##
=========================================
- Coverage    82.1%    82.0%   -0.1%     
=========================================
  Files         330      330             
  Lines       76198    76222     +24     
=========================================
+ Hits        62560    62569      +9     
- Misses      13638    13653     +15     

@mvines mvines changed the title rpc: Add base64 (binary64) encoding for getConfirmedTransaction/getConfirmedBlock rpc: rework binary encoding. BREAKING CHANGE Aug 16, 2020
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub enum UiAccountEncoding {
Binary, // SLOW! Avoid this encoding
Binary, // Legacy. Retained for RPC backwards compatibility
Copy link
Member Author

Choose a reason for hiding this comment

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

One day we can remove "binary" when it starts getting in the way. It's no longer documented

Comment on lines -492 to -500
if let Some(ref mut account) = rpc_account {
if let Binary(_) = &account.data {
let tmp = Binary64(String::new());
match std::mem::replace(&mut account.data, tmp) {
Binary(new_data) => account.data = Binary64(new_data),
_ => panic!("should have gotten binary here."),
}
}
}
Copy link
Member Author

Choose a reason for hiding this comment

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

The problem with Binary(String) and Binary64(String) is visible here. Serde can't distinguish between the two on deserialization with the the untagged attribute, so this workaround was previously needed for Rust RPC clients.

@@ -3119,24 +3122,27 @@ pub mod tests {
bank.store_account(&address, &account);

let req = format!(
r#"{{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["{}", {{"encoding":"binary64"}}]}}"#,
r#"{{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["{}", {{"encoding":"base64"}}]}}"#,
Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, this feels so much nicer. "binary64"? What's that! "base64"? Oh, that's base64.

Copy link
Member

Choose a reason for hiding this comment

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

Yes yes yes!! 🙌

@mvines
Copy link
Member Author

mvines commented Aug 16, 2020

This PR escalated quickly! It's a breaking change mostly for the newly added binary64 encoding, so the downstream users should still be few and I think the long-term benefits outweigh the minor inconvenience of adapting to the slightly different RPC request/responses

Copy link
Contributor

@CriesofCarrots CriesofCarrots left a comment

Choose a reason for hiding this comment

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

Thanks for wrangling this one! lgtm

@mvines mvines merged commit e528115 into solana-labs:master Aug 18, 2020
mergify bot added a commit that referenced this pull request Aug 18, 2020
* Add base64 (binary64) encoding for getConfirmedTransaction/getConfirmedBlock

(cherry picked from commit b5f3ced)

* decode-transaction now supports binary64

(cherry picked from commit 2ebc68a)

# Conflicts:
#	cli/src/cli.rs

* Rework UiAccountData encode/decode such that it works from Rust

(cherry picked from commit 757e147)

# Conflicts:
#	account-decoder/src/lib.rs
#	cli/src/cli.rs

* Rename Binary64 to Base64.  Establish Base58 encoding

(cherry picked from commit adc984a)

# Conflicts:
#	account-decoder/src/lib.rs

* Remove "binary" encoding. Document "encoding" as required

(cherry picked from commit e528115)

* resolve conflicts

Co-authored-by: Michael Vines <mvines@gmail.com>
mergify bot added a commit that referenced this pull request Aug 18, 2020
* Add base64 (binary64) encoding for getConfirmedTransaction/getConfirmedBlock

(cherry picked from commit b5f3ced)

# Conflicts:
#	transaction-status/Cargo.toml

* decode-transaction now supports binary64

(cherry picked from commit 2ebc68a)

# Conflicts:
#	cli/src/cli.rs

* Rework UiAccountData encode/decode such that it works from Rust

(cherry picked from commit 757e147)

# Conflicts:
#	cli/src/cli.rs

* Rename Binary64 to Base64.  Establish Base58 encoding

(cherry picked from commit adc984a)

* Remove "binary" encoding. Document "encoding" as required

(cherry picked from commit e528115)

* resolve conflicts

Co-authored-by: Michael Vines <mvines@gmail.com>
mvines added a commit that referenced this pull request Aug 18, 2020
mvines added a commit to mvines/solana that referenced this pull request Aug 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants