Skip to content

Conversation

@chenyan-dfinity
Copy link
Contributor

@chenyan-dfinity chenyan-dfinity commented Sep 20, 2019

TODO:

  • deserialize multiple arguments
  • lifetime problem for deserialize_str
  • newtype support (this requires changes to ser.rs)
  • test cases for missing/extra fields
  • limit recursion depth

@hansl
Copy link
Contributor

hansl commented Sep 23, 2019

We end up not using serde, since serde cannot derive type information, and we cannot easily sort the field index in struct and enum by the idl_hash.

I'm using a simple state machine in my Request ID hasher for this. It makes things very easy. I don't think deriving type information is necessary for this. It doesn't seem like a good enough reason to not support serde serialization/deserialization.

@chenyan-dfinity
Copy link
Contributor Author

Let's sync on this. I would be very interested to learn how we can get around this without custom derive. I would love to live in the serde ecosystem if at all possible!

@hansl
Copy link
Contributor

hansl commented Sep 23, 2019

#42 is my PR for calculating Request ID with Serde Serialization. It uses a basic state machine (as most serializer have to) for keeping the fields then sorting them once the structure is done.

It would be trivial to add types to it. And it would be trivial to do recursive embedded structures (using a stack instead of an Option<_>).

@chenyan-dfinity
Copy link
Contributor Author

You skipped enum. Yes, everything is possible under serde if you don't support enum.

@nomeata
Copy link
Contributor

nomeata commented Sep 23, 2019

I managed to use this library in my unofficial experiments of building canisters using rust: https://github.com/dfinity-lab/dev/pull/1114. :-)

@hansl
Copy link
Contributor

hansl commented Sep 23, 2019

@chenyan-dfinity I don't have to explicitly support enums in my use case, but I thought serialize_unit_variant would cover that case.

@hansl
Copy link
Contributor

hansl commented Sep 23, 2019

We should not merge this PR (and should not have merged the preceding one) without cargo fmt and cargo clippy passing. We also need CI.

@chenyan-dfinity
Copy link
Contributor Author

@chenyan-dfinity I don't have to explicitly support enums in my use case, but I thought serialize_unit_variant would cover that case.

In enum, you can only get the type of the current variant, and the index cannot be sorted beforehand either. Let's consider a simpler example: serialize None of type Option<i32>. In serde, you get dispatched to serialize_none, which takes no arguments. How do you know this None is of type Option<i32>?

@hansl
Copy link
Contributor

hansl commented Sep 23, 2019

How do you know this None is of type Option?

Serde's own implementation says that you know this during deserialization (here). I haven't faced a wire format that made a difference between None of i32 and None of str.

@chenyan-dfinity
Copy link
Contributor Author

I haven't faced a wire format that made a difference between None of i32 and None of str.

hmm, this is a good point. If the Some variant never appears, we can safely assign it as an arbitrary Option<T> type. Not sure if this will cause problems in the deserialization. Let me finish this "precise" type approach first, hopefully we will have a more clear picture by then.

@paulyoung
Copy link
Contributor

The doc comment for the deserialize_option function at the link above says this though:

// As commented in `Serializer` implementation, this is a lossy
// representation. For example the values `Some(())` and `None` both
// serialize as just `null`. Unfortunately this is typically what people
// expect when working with JSON. Other formats are encouraged to behave
// more intelligently if possible.

@hansl
Copy link
Contributor

hansl commented Sep 24, 2019

You can get the type when deserializing Some(), you just can't get it from None. ⊥ has no type, so its serialization probably shouldn't have any type.

JSON is very limited. For example, there is no difference between f32, u8 or i64, or Some(()) and None. But serde itself do support differentiating those two, so it's a limit of the wire format, not the serializer (you could serialize to JSON with something like { type: "()", value: {} } and deserialize properly).

@hansl
Copy link
Contributor

hansl commented Sep 27, 2019

Please merge master when you have time to. There has been a lot of changes with CI and Rust.

@matthewhammer
Copy link
Contributor

Not sure what's the best way to return multiple values. I plan to return them in a tuple. Any other suggestions?

Yeah, that seems right: Use a tuple.

BTW: I'm looking at this PR now, and will try it shortly myself.

@hansl
Copy link
Contributor

hansl commented Oct 1, 2019

@chenyan-dfinity Is this ready for review?

  1. Could you separate this in commits that make sense? Seems you're changing a lot of code across libraries. I know this is not "normal" practice at DFINITY but it makes the review faster, easier, and the intent and documentation clearer (commit messages are documentation too)
  2. The TODO in the description of this PR is still empty. What's done and what's still to finish?
  3. The PR is in Draft mode. If this is ready to review and merge then please open up the PR. It's a simple button at the bottom.

I'm looking at the code right now but these would help.

Copy link
Contributor

@hansl hansl left a comment

Choose a reason for hiding this comment

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

Initial comments.

@matthewhammer
Copy link
Contributor

Update: I want to understand all of this code eventually, but admittedly, I'm currently just trying to understand how to use it for now.

On that front, I was able to write some simple unit tests that exercise both the serialization and deserialization support, and check that in each case they agree. Those tests all work as expected.

@hansl
Copy link
Contributor

hansl commented Oct 1, 2019

Can we add a fuzzy test for this? I feel it is something we should do; generate random structured and typed data, serialize and deserialize it, then verify it's equal to original data.

I'm okay making this a separate PR.

@chenyan-dfinity
Copy link
Contributor Author

chenyan-dfinity commented Oct 1, 2019

@chenyan-dfinity Is this ready for review?

Ready for early feedback and use for CLI, not ready for merging to master

  1. Could you separate this in commits that make sense? Seems you're changing a lot of code across libraries. I know this is not "normal" practice at DFINITY but it makes the review faster, easier, and the intent and documentation clearer (commit messages are documentation too)

I will address the TODOs before split the PR.

  1. The TODO in the description of this PR is still empty. What's done and what's still to finish?

TODOs listed in the PR description is not done.

@chenyan-dfinity
Copy link
Contributor Author

Can we add a fuzzy test for this? I feel it is something we should do; generate random structured and typed data, serialize and deserialize it, then verify it's equal to original data.

Of course! Not this PR though. Let's do it one at a time :)

@chenyan-dfinity chenyan-dfinity marked this pull request as ready for review October 2, 2019 21:29
@chenyan-dfinity chenyan-dfinity requested a review from a team as a code owner October 2, 2019 21:29
@chenyan-dfinity chenyan-dfinity requested a review from hansl October 2, 2019 21:29
@hansl
Copy link
Contributor

hansl commented Oct 2, 2019

@chenyan-dfinity Please fix CI's issues and we'll merge. Looks good to me.

@chenyan-dfinity
Copy link
Contributor Author

CI fixed. PTAL

@hansl hansl merged commit c6c0941 into master Oct 3, 2019
@hansl hansl deleted the serde branch October 3, 2019 02:24
@matthewhammer
Copy link
Contributor

👍

hansl added a commit that referenced this pull request Nov 9, 2020
commit 7c5e71488df430b89de637a15b56814db196e752
Author: Islam El-Ashi <ielashi@users.noreply.github.com>
Date:   Sat Nov 7 00:30:05 2020 +0100

    feat: DER-encode public key and principal ID when using Plain Authentication. (#48)

    BREAKING CHANGE

    If a developer relies on the inner work of SenderPubKey or manually instanciate Principal, the API changed.

commit a254861ae4bfe608734c8c190e4033cfe39f047b
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Fri Nov 6 15:17:32 2020 -0800

    chore(deps): bump node-fetch from 2.6.0 to 2.6.1 in /e2e/node (#49)

    Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
    - [Release notes](https://github.com/bitinn/node-fetch/releases)
    - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
    - [Commits](node-fetch/node-fetch@v2.6.0...v2.6.1)

    Signed-off-by: dependabot[bot] <support@github.com>

    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit 694849109bc28fea80119388504127e889b36d15
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Fri Nov 6 15:17:14 2020 -0800

    chore(deps-dev): bump node-fetch from 2.6.0 to 2.6.1 in /packages/agent (#50)

    Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
    - [Release notes](https://github.com/bitinn/node-fetch/releases)
    - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
    - [Commits](node-fetch/node-fetch@v2.6.0...v2.6.1)

    Signed-off-by: dependabot[bot] <support@github.com>

    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit 88af47f79b5e9f3a5e08abbf0ce03b3140357fc0
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Fri Nov 6 15:16:53 2020 -0800

    chore(deps-dev): bump node-fetch in /packages/bootstrap (#51)

    Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
    - [Release notes](https://github.com/bitinn/node-fetch/releases)
    - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
    - [Commits](node-fetch/node-fetch@v2.6.0...v2.6.1)

    Signed-off-by: dependabot[bot] <support@github.com>

    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit ba4b082e5795150176f7adad989c3613edceb85f
Author: Hans <hans@larsen.online>
Date:   Thu Nov 5 12:49:59 2020 -0800

    test: add ic-ref, ci e2e and lerna support to repo (#47)

    This refactors the repository to use lerna to manage its monorepo's packages. It also adds the e2e tests from the SDK repo that we previously had to remove. More e2e tests will be added later, but this unblocks working with DER and Identity work as we can now at least run some e2e tests now (instead of mocking the http connection).

commit 8baa1cfc227d003c2806df1057b92009159df250
Author: Hans <hans@larsen.online>
Date:   Tue Nov 3 11:04:36 2020 -0800

    feat: use anonymous principal by default in HttpAgent (#46)

    If the auth transform is missing and the principal is anonymous, use an
    anonymous auth transform. Otherwise, use the auth transform as normal.

    # BREAKING CHANGE
    Before, an auth transform would not be called if it was missing, now it
    results as an error if the principal is not anonymous. This was because
    just using the packet as is without putting it in an envelope was a bug
    and should never be sent to a replica anyway. Now this is explicit.

commit 1a714e6c53f5e467112b964b71204b6d2eb545ef
Author: Hans <hans@larsen.online>
Date:   Tue Nov 3 11:04:15 2020 -0800

    feat: add a getPrincipal() method to Agents (#40)

commit 324e856944adb7f79a2afa2cffbdb6d144b35ab4
Author: Hans <hans@larsen.online>
Date:   Tue Nov 3 08:49:44 2020 -0800

    feat: add the canister ID to the window.ic object (#41)

    This can be useful to know the canister ID of the current frontend.

commit 8680a2cf4994b45c6e00ffb0b5a12b379f5ff919
Author: Hans <hans@larsen.online>
Date:   Mon Nov 2 21:57:21 2020 -0800

    feat: add a cache bust hash at the end of javascript output (#39)

commit 9f2ed968b7cc9f4b854af5e23edca19d34124909
Author: Benjamin Goering <benjamin.goering@dfinity.org>
Date:   Tue Sep 22 15:28:49 2020 -0700

    docs: polish docs/npm-publish.md per @hansl feedback (#37)

    via: pr feedback on dfinity/icp-js-core#36
mergify bot pushed a commit that referenced this pull request Nov 10, 2020
commit 19c28008db5fa1582da573088b17d0bdee9e8bc2
Author: Hans <hans@larsen.online>
Date:   Mon Nov 9 14:47:25 2020 -0800

    revert: Remove lerna (PR #47) (#59)
    
    This removes lerna, but attempt to not remove the e2e tests and the
    new packages/files that were added after the last PR.

commit 426a94f356bc4e27f50c8bec55071b82105adbd1
Author: Hans <hans@larsen.online>
Date:   Mon Nov 9 13:54:04 2020 -0800

    feat: use anonymous for the first retrieve (#53)
    
    Also include some cleanup of the scripts that arent used, and add a diagram for the
    bootstrapping process.
    
    This does not affect the worker yet. Only the first retrieve of the index.js on
    localhost.
    
    BREAKING CHANGE
    
    If a canister has a retrieve() method that relies on Principal, the principal used
    will change.
    
    Co-authored-by: Benjamin Goering <benjamin.goering@dfinity.org>

commit b795d8b34ce38dd35e1bcf2b80e33108cf74161d
Author: Andrew Wylde <2126677+codelemur@users.noreply.github.com>
Date:   Mon Nov 9 09:41:13 2020 -0800

    feat(idp): add identity-provider package to repository (#52)
    
    adds plain HTML/ts and test setup for project

commit 7c5e71488df430b89de637a15b56814db196e752
Author: Islam El-Ashi <ielashi@users.noreply.github.com>
Date:   Sat Nov 7 00:30:05 2020 +0100

    feat: DER-encode public key and principal ID when using Plain Authentication. (#48)
    
    BREAKING CHANGE
    
    If a developer relies on the inner work of SenderPubKey or manually instanciate Principal, the API changed.

commit a254861ae4bfe608734c8c190e4033cfe39f047b
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Fri Nov 6 15:17:32 2020 -0800

    chore(deps): bump node-fetch from 2.6.0 to 2.6.1 in /e2e/node (#49)
    
    Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
    - [Release notes](https://github.com/bitinn/node-fetch/releases)
    - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
    - [Commits](node-fetch/node-fetch@v2.6.0...v2.6.1)
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit 694849109bc28fea80119388504127e889b36d15
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Fri Nov 6 15:17:14 2020 -0800

    chore(deps-dev): bump node-fetch from 2.6.0 to 2.6.1 in /packages/agent (#50)
    
    Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
    - [Release notes](https://github.com/bitinn/node-fetch/releases)
    - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
    - [Commits](node-fetch/node-fetch@v2.6.0...v2.6.1)
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit 88af47f79b5e9f3a5e08abbf0ce03b3140357fc0
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Fri Nov 6 15:16:53 2020 -0800

    chore(deps-dev): bump node-fetch in /packages/bootstrap (#51)
    
    Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
    - [Release notes](https://github.com/bitinn/node-fetch/releases)
    - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
    - [Commits](node-fetch/node-fetch@v2.6.0...v2.6.1)
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit ba4b082e5795150176f7adad989c3613edceb85f
Author: Hans <hans@larsen.online>
Date:   Thu Nov 5 12:49:59 2020 -0800

    test: add ic-ref, ci e2e and lerna support to repo (#47)
    
    This refactors the repository to use lerna to manage its monorepo's packages. It also adds the e2e tests from the SDK repo that we previously had to remove. More e2e tests will be added later, but this unblocks working with DER and Identity work as we can now at least run some e2e tests now (instead of mocking the http connection).

commit 8baa1cfc227d003c2806df1057b92009159df250
Author: Hans <hans@larsen.online>
Date:   Tue Nov 3 11:04:36 2020 -0800

    feat: use anonymous principal by default in HttpAgent (#46)
    
    If the auth transform is missing and the principal is anonymous, use an
    anonymous auth transform. Otherwise, use the auth transform as normal.
    
    # BREAKING CHANGE
    Before, an auth transform would not be called if it was missing, now it
    results as an error if the principal is not anonymous. This was because
    just using the packet as is without putting it in an envelope was a bug
    and should never be sent to a replica anyway. Now this is explicit.

commit 1a714e6c53f5e467112b964b71204b6d2eb545ef
Author: Hans <hans@larsen.online>
Date:   Tue Nov 3 11:04:15 2020 -0800

    feat: add a getPrincipal() method to Agents (#40)

commit 324e856944adb7f79a2afa2cffbdb6d144b35ab4
Author: Hans <hans@larsen.online>
Date:   Tue Nov 3 08:49:44 2020 -0800

    feat: add the canister ID to the window.ic object (#41)
    
    This can be useful to know the canister ID of the current frontend.

commit 8680a2cf4994b45c6e00ffb0b5a12b379f5ff919
Author: Hans <hans@larsen.online>
Date:   Mon Nov 2 21:57:21 2020 -0800

    feat: add a cache bust hash at the end of javascript output (#39)

commit 9f2ed968b7cc9f4b854af5e23edca19d34124909
Author: Benjamin Goering <benjamin.goering@dfinity.org>
Date:   Tue Sep 22 15:28:49 2020 -0700

    docs: polish docs/npm-publish.md per @hansl feedback (#37)
    
    via: pr feedback on dfinity/icp-js-core#36
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.

5 participants