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

Encode data using base64, encode ids using Hex for human readable serialisation #1304

Merged
merged 7 commits into from
Apr 12, 2022

Conversation

patrickkuo
Copy link
Contributor

@patrickkuo patrickkuo commented Apr 9, 2022

This PR created 2 custom de/serialiser BytesOrHex, BytesOrBase64 for : SuiAddress, ObjectDigest, PublicKeyBytes, Signature, TransactionDigest, and AuthoritySignature, data will be serialised as Bytes for non-human readable serialiser and encoded with base64/Hex for human readable serialiser.

Here are the json output of a transfer transaction after the changes:

patrick@Patricks-MBPMax release % ./wallet transfer --to 66595B3DE05980BE6CEE212EF55BB027AFDDF6C3 --object-id 388AEE712653AC793B04B00644CC47A9C95AEC89 --gas 54886B969591DA3ED8E4E95E2343EB8A4303C9F0 --gas-budget 1000 --json --no-shell | json_pp
[
   {
      "signatures" : [
         [
            "ixE/aWAYHYJouMulwi3VkvMX6WyVhaVfUwPntfjFoGw=",
            "Hir4XDhlLSWIstOOKil1xEt878eBhX9qcoctGYKsrFK+kpJYuaWzGvuVV0hfJEI9xgZt68FP5nQ9zhti+ZFNBQ=="
         ],
         [
            "toYwLGGvZ6mbI/WNDG0WHQskZ8ErTg2sJzToPPT9rZc=",
            "7oqmIBm+Mtdc8WqaCRyY6D3SvqunpO5XyVZjma9yFQBvhAzZX7VOW3VzrhmAMA42vPAf+xpX5RGmEZfUdvWbBg=="
         ],
         [
            "kgxikutUsshbqcwR/r9kfTw9sjgbLN2dv0MgA+51iuY=",
            "IqpNUB2CgMJja+iVBgUyrnmrxtbxm8gcDxVwLGtIkT8Mxo1PZUOEpLA5Nr6VJUEXmvij7Df8vw/01YfSD0kmCw=="
         ]
      ],
      "transaction" : {
         "auth_signature" : {},
         "data" : {
            "gas_budget" : 1000,
            "gas_payment" : [
               "54886b969591da3ed8e4e95e2343eb8a4303c9f0",
               3,
               "Ad7N808R/tCoI/MJBe985uxbLmWw0ewQgIh1MnhPEvE="
            ],
            "kind" : {
               "Single" : {
                  "Transfer" : {
                     "object_ref" : [
                        "388aee712653ac793b04b00644cc47a9c95aec89",
                        3,
                        "NoOzanRSFJ3WirXdBfb5IsoyW2qSHbX7vNelo6RuHCQ="
                     ],
                     "recipient" : "66595b3de05980be6cee212ef55bb027afddf6c3"
                  }
               }
            },
            "sender" : "66595b3de05980be6cee212ef55bb027afddf6c3"
         },
         "tx_signature" : "1pgheoIOqhUNcXVvAjBycSD2dOoI2e+5GtAXwHI+2UlAIu0QFJOm/pHsj3elA5ifNBO6HRXyezffXiTOWVCVDyAkrab7imXC+eeNo4ng92YxAmvNZtBOWZJhc/tn1hYF"
      }
   },
   {
      "created" : [],
      "deleted" : [],
      "dependencies" : [
         "txeL/KsZasQkUVG2/iCdsiqRr0JzIILUL7Ql32qYPVo="
      ],
      "events" : [],
      "gas_object" : [
         [
            "54886b969591da3ed8e4e95e2343eb8a4303c9f0",
            4,
            "EUGTXkztRb2/r35kXWibe267HQnsDZqiUTxiZXitKVA="
         ],
         {
            "AddressOwner" : "66595b3de05980be6cee212ef55bb027afddf6c3"
         }
      ],
      "mutated" : [
         [
            [
               "388aee712653ac793b04b00644cc47a9c95aec89",
               4,
               "Bwv3XBe2ctx3pGJWcKP6HBM0XEDRl5seQQbPPqeBDD0="
            ],
            {
               "AddressOwner" : "66595b3de05980be6cee212ef55bb027afddf6c3"
            }
         ],
         [
            [
               "54886b969591da3ed8e4e95e2343eb8a4303c9f0",
               4,
               "EUGTXkztRb2/r35kXWibe267HQnsDZqiUTxiZXitKVA="
            ],
            {
               "AddressOwner" : "66595b3de05980be6cee212ef55bb027afddf6c3"
            }
         ]
      ],
      "status" : {
         "Success" : {
            "gas_cost" : {
               "computation_cost" : 17,
               "storage_cost" : 0,
               "storage_rebate" : 0
            },
            "results" : []
         }
      },
      "transaction_digest" : "68+AJwrDCS/ELpsOyRVdCF1hW5xLsSv9CoxSp02h3xE=",
      "unwrapped" : [],
      "wrapped" : []
   }
]

@codecov
Copy link

codecov bot commented Apr 9, 2022

Codecov Report

Merging #1304 (db3b2e1) into main (e615cda) will increase coverage by 0.24%.
The diff coverage is 93.90%.

❗ Current head db3b2e1 differs from pull request most recent head a5f5385. Consider uploading reports for the commit a5f5385 to get more accurate results

@@            Coverage Diff             @@
##             main    #1304      +/-   ##
==========================================
+ Coverage   81.70%   81.94%   +0.24%     
==========================================
  Files          99      100       +1     
  Lines       20766    20927     +161     
==========================================
+ Hits        16966    17148     +182     
+ Misses       3800     3779      -21     
Impacted Files Coverage Δ
sui/src/wallet.rs 0.98% <0.00%> (ø)
sui/src/wallet_commands.rs 83.00% <0.00%> (-0.22%) ⬇️
sui_types/src/base_types.rs 77.74% <ø> (ø)
sui_types/src/crypto.rs 85.01% <ø> (+0.97%) ⬆️
sui_types/src/lib.rs 16.66% <ø> (ø)
sui_types/src/readable_serde.rs 92.55% <92.55%> (ø)
sui_types/src/unit_tests/base_types_tests.rs 100.00% <100.00%> (ø)
...ammability/adapter/src/unit_tests/adapter_tests.rs 98.55% <0.00%> (+0.10%) ⬆️
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 777bf73...a5f5385. Read the comment docs.

@patrickkuo patrickkuo force-pushed the pat/human_readable_serialization branch 2 times, most recently from c5dc349 to d5eb5cf Compare April 10, 2022 15:27
@patrickkuo patrickkuo linked an issue Apr 11, 2022 that may be closed by this pull request
@awelc awelc requested a review from Clay-Mysten April 11, 2022 01:30
@awelc
Copy link
Contributor

awelc commented Apr 11, 2022

Added @Clay-Mysten to track required doc changes.

let s = String::deserialize(deserializer)?;
encoding
.decode(s)
.map_err(|_| D::Error::custom("byte deserialization failed"))
Copy link
Contributor

Choose a reason for hiding this comment

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

Whats the reason for throwing away the error from decoding, wouldn't it be useful to include that in the error message (via the error's Display impl) so that a user can get a better idea of why the deserialization failed? Eg from this error I don't know why it failed, did i give it hex when it wanted base64 or vice versa

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍thanks for pointing this out, I will add more info to the error

@patrickkuo patrickkuo force-pushed the pat/human_readable_serialization branch from cc68395 to 89dc1ac Compare April 11, 2022 10:33
@patrickkuo patrickkuo requested a review from oxade April 11, 2022 11:37
@Clay-Mysten
Copy link
Contributor

Added @Clay-Mysten to track required doc changes.

I edited the code comments in readable_serde.rs directly. I assume you mean this will affect a bunch of examples/output in our existing docs.

Let's talk first when done with this then so I do the right thing. Hit me up in chat.

Copy link
Contributor

@666lcz 666lcz left a comment

Choose a reason for hiding this comment

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

Great work! Is it accurate to say everything will be serialized/deserialized using Base64 except SuiAddress?

Comment on lines 164 to 165
byte_or_hex!(20,);
byte_or_base64!(32, 96,);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: can we use Constants(e.g., OBJECT_DIGEST_LENGTH) from other files to improve readability?

@@ -169,6 +169,80 @@ fn test_object_id_serde_json() {
assert_eq!(obj_id, json_obj_id);
}

#[test]
fn test_object_id_serde_not_human_readable() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Currently object id is passed in the rest server in hex:

/// Required; Hex code as string representing Move module location
. Are we changing this behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not changing ObjectID in this PR, ObjectID already have it's own serialiser implemented earlier and it's doing similar things : Hex for human-readable, and tuple array (which doesn't contain array length compare to Bytes) for non-human-readable serialisation, we might want to do a refactoring in the future though to make them consistent.

@patrickkuo
Copy link
Contributor Author

Great work! Is it accurate to say everything will be serialized/deserialized using Base64 except SuiAddress?

Thanks!

The rules is Hex for IDs, so we can preserve the ordering, and base64 for data/signature/digest
so SuiAddress and ObjectID will be encoded to Hex

@velvia
Copy link
Contributor

velvia commented Apr 11, 2022

@patrickkuo hey this is a great PR, it does allow a way to serialize to human readable and bytes at the same time. The only ting I don't like, and this is not meant to be a discouragement, is that the API of is_human_readable really isn't very good, because it only offers ONE choice of what "human readable" means. What if we want to support, for example (this is I know a bit contrived, but) both base64 and base58? It seems over time this might become more and more common.

@bmwill I think implementing base64 and hex as specific methods to_base64 to_hex etc is much more flexible than shoehorning this into the SerDe mechanism. Base64 and hex aren't so much "serializations" as just different representations.

@patrickkuo patrickkuo force-pushed the pat/human_readable_serialization branch from 66695fe to db3b2e1 Compare April 11, 2022 18:22
@patrickkuo
Copy link
Contributor Author

@patrickkuo hey this is a great PR, it does allow a way to serialize to human readable and bytes at the same time. The only ting I don't like, and this is not meant to be a discouragement, is that the API of is_human_readable really isn't very good, because it only offers ONE choice of what "human readable" means. What if we want to support, for example (this is I know a bit contrived, but) both base64 and base58? It seems over time this might become more and more common.

@bmwill I think implementing base64 and hex as specific methods to_base64 to_hex etc is much more flexible than shoehorning this into the SerDe mechanism. Base64 and hex aren't so much "serializations" as just different representations.

One reason of shoehorning the encoding to serde is to avoid having to do the conversion manually in the RPC layer; we can achieve the same result by create a different set of all the return types and convert them in the RPC layer, but that's quite a bit of work as our return objects are quite complex.

@velvia
Copy link
Contributor

velvia commented Apr 11, 2022

@patrickkuo

One reason of shoehorning the encoding to serde is to avoid having to do the conversion manually in the RPC layer

Would you mind pointing out where the RPC code is? Just want to have a look and see how much impact this would be...

@patrickkuo
Copy link
Contributor Author

@patrickkuo

One reason of shoehorning the encoding to serde is to avoid having to do the conversion manually in the RPC layer

Would you mind pointing out where the RPC code is? Just want to have a look and see how much impact this would be...

For example in execute_transaction function, we will need to handle/convert the TransactionResponse manually to JSON without the original serde.
https://github.com/MystenLabs/sui/blob/35d7ce0352531bd873a929036db8d0f71c90fd78/sui/src/rpc_gateway.rs#L92-L98

Also for other functions we will need to convert the input SuiAddress/ObjectID manually.

Copy link
Contributor

@huitseeker huitseeker left a comment

Choose a reason for hiding this comment

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

Ack on direction, I pointed at a couple issues in the PR.

Comment on lines 153 to 160
Encoding::Base64 => base64::decode(s)?,
Encoding::Hex => hex::decode(s)?,
})
}

fn encode<T: AsRef<[u8]>>(&self, data: T) -> String {
match self {
Encoding::Base64 => base64::encode(data),
Copy link
Contributor

Choose a reason for hiding this comment

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

There are issues with the base64 crate in cryptographic contexts (I don't think you're serializing private keys, but you're serializing public ones at least). Please make sure you contact @kchalkias for advice.
base64ct does not have those issues, you may want to use it instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have replaced base64 with base64ct

* replace base64 with base64ct
@patrickkuo patrickkuo merged commit f7aa79c into main Apr 12, 2022
@patrickkuo patrickkuo deleted the pat/human_readable_serialization branch April 12, 2022 15:38
@Clay-Mysten
Copy link
Contributor

@awelc and @patrickkuo Please help me understand the docs needing updating as a result of this change.

I am happy to take it from there. Thanks!

@patrickkuo
Copy link
Contributor Author

patrickkuo commented Apr 13, 2022

The changes here mainly impacting the JSON output, I had a quick look it seems like we do not include JSON output in our docs? @Clay-Mysten

@Clay-Mysten
Copy link
Contributor

The changes here mainly impacting the JSON output, I had a quick look it seems like we do not include JSON output in our docs? @Clay-Mysten

What about here?
https://docs.sui.io/build/rest-api#get-apiobjects
https://docs.sui.io/build/rest-api#post-apipublish

Thanks, Patrick!

@Clay-Mysten
Copy link
Contributor

@patrickkuo
Copy link
Contributor Author

patrickkuo commented Apr 14, 2022

@Clay-Mysten sorry for late reply, I skimmed through the docs and seems like we didn't include JSON output samples in them, so nothing to update.... @awelc to confirm

@Clay-Mysten
Copy link
Contributor

No worries, @patrickkuo! Thanks for double checking.

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.

[wallet CLI] Display Owner and TransactionDigest as hex
7 participants