Skip to content
This repository has been archived by the owner on Oct 17, 2022. It is now read-only.

Update Ed25519Signature ser/de logic #756

Merged
merged 4 commits into from
Aug 15, 2022
Merged

Conversation

mwtian
Copy link
Member

@mwtian mwtian commented Aug 12, 2022

Implement struct ser/de logic for Ed25519Signature. The current ser/de logic of Ed25519Signature just returns a &[u8], making it being treated as [u8] by serde_reflection and causing ser/de failures.

I investigated if we can rely on serde annotations and avoid manual implementation of struct ser/de. But it seems there is no straightforward way unless we want to compromise on

  • Using cached bytes for ser/de.
  • And / or using base64 for readable serialization.

@mwtian
Copy link
Member Author

mwtian commented Aug 12, 2022

I figured out the reason of trace_value() failures: calling serialize_newtype_struct() makes serde-reflection think the type is just an alias, so it seems to not remember the type and value. Using serialize_struct() fixes the issue but it is a bit more complex. An alternative is to use the pattern we have for BLS12381Signature. Will update the PR later.

Copy link
Member Author

@mwtian mwtian left a comment

Choose a reason for hiding this comment

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

Should be ready now.

let bytes = if deserializer.is_human_readable() {
let s = String::deserialize(deserializer)?;
base64ct::Base64::decode_vec(&s).map_err(|e| de::Error::custom(e.to_string()))?
struct Ed25519SignatureVisitor {
Copy link
Member Author

Choose a reason for hiding this comment

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

If we just put #[derive(Deserialize, Serialize)] on top of Ed25519Signature and #[serde(skip)] on top of bytes, we can save the custom ser/de logic here. The downsides are:

  1. Human readable data is not base64, but something less compact.
  2. We will not be using the bytes once_cell "cache".

Copy link
Member Author

Choose a reason for hiding this comment

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

This is excellent!

I think that the only thing that is missing is a few lines of english in a comment of impl (De)Serialize summarizing what invariants the programmer should maintain when editing the inner representation of our types:

Here's why I think a comment about this is necessary: you're making specific choices here (e.g. the marker fields for disjunction between b64 and raw formats) that we may debate in the future. If someone was to make different ones, what shouldn't they break?

Thanks for the feedback. Added a comment with the information outlined above.

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.

This is excellent!

I think that the only thing that is missing is a few lines of english in a comment of impl (De)Serialize summarizing what invariants the programmer should maintain when editing the inner representation of our types:

Here's why I think a comment about this is necessary: you're making specific choices here (e.g. the marker fields for disjunction between b64 and raw formats) that we may debate in the future. If someone was to make different ones, what shouldn't they break?

@@ -51,6 +52,38 @@ fn serialize_deserialize() {
assert!(bincode::deserialize::<Ed25519PublicKey>(&bytes).is_err());
}

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

Choose a reason for hiding this comment

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

👍

@@ -126,18 +126,6 @@ fn get_registry() -> Result<Registry> {
tracer.trace_type::<HeaderDigest>(&samples)?;
tracer.trace_type::<CertificateDigest>(&samples)?;

// Caveat: the following (trace_type) won't work, but not because of generics.
Copy link
Contributor

Choose a reason for hiding this comment

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

Indeed, this is quite an antiquated comment.

ser::SerializeStruct,
Deserialize, Serialize,
};
use serde_bytes::{ByteBuf, Bytes};
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit (that you can ignore): we already use serde_with elsewhere, and it has analogous byte types. But that may be a bit too much OCD on my part.
https://docs.rs/serde_with/latest/serde_with/

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the suggestion. serde_with::Bytes seems to be missing some features compared to serde_bytes::Bytes, e.g. wrapping &[u8]. It is a bit hard to use it in the situation here.

@joyqvq
Copy link
Contributor

joyqvq commented Aug 15, 2022

lgtm! should we add similar tracer test to other serializer for Secp256k1 and BLS signatures (in a follow up PR)? or, port over the format tests from sui to narwhal as well?

@mwtian
Copy link
Member Author

mwtian commented Aug 15, 2022

lgtm! should we add similar tracer test to other serializer for Secp256k1 and BLS signatures (in a follow up PR)? or, port over the format tests from sui to narwhal as well?

Good idea, Narwhal does have a similar generate_format.rs test and I'm thinking of adding tests for structs containing signatures to it.

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.

Thanks @mwtian !

@mwtian mwtian merged commit 6a28e2f into MystenLabs:main Aug 15, 2022
@mwtian mwtian deleted the serde-key branch August 15, 2022 16:28
mwtian added a commit to mwtian/sui that referenced this pull request Sep 30, 2022
* Update signature serde

* fixup! Update signature serde

* fix Ed25519Signature ser/de

* add comment
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants