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

Credentials crate & PresentationDefinitionV2 struct definition #18

Merged
merged 3 commits into from
Nov 29, 2023

Conversation

amika-sq
Copy link
Contributor

PresentationDefinitionV2 is needed for a tbDEX Offering.

This PR adds a PresentationDefinitionV2 definition to a new credentials crate in this repository, which will be consumed in the tbdex-rs repository to define an Offering.

I primarily followed what is currently in the Kotlin repository here as an example, and re-used the comments / tests from there.

Comment on lines 179 to 180
assert!(serialized_pd.contains("input_descriptors"));
assert!(serialized_pd.contains("123"));
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'm not really convinced that this test fully tests serialization, but it's currently what we're doing in the web5-kt test suite.

We could really use some test vectors here to have a more robust test of this functionality.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree. I think most is already tested in the idempotency test.

Copy link
Member

@decentralgabe decentralgabe left a comment

Choose a reason for hiding this comment

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

lgtm

[package]
name = "credentials"
version = "0.1.0"
edition = "2021"
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious why 2021?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's editions. More info here:
#17 (comment)

crates/credentials/src/presentation_definition_v2.rs Outdated Show resolved Hide resolved
Comment on lines 179 to 180
assert!(serialized_pd.contains("input_descriptors"));
assert!(serialized_pd.contains("123"));
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree. I think most is already tested in the idempotency test.

Comment on lines 214 to 222
let pd_string = load_json("tests/resources/pd_sanctions.json");
let deserialized_pd: PresentationDefinitionV2 = serde_json::from_str(&pd_string).unwrap();

assert_eq!(deserialized_pd.id, expected_id);
assert_eq!(deserialized_pd.format, Some(expected_format));
assert_eq!(
deserialized_pd.input_descriptors,
expected_input_descriptors
);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is the most powerful test. In kt, it checks that JSON is equal (see serialize / deserialize idempotency). Would it make sense to compare the the actual JSON outputs from the pre-serialization JSON vs the serialized and then deserialized JSON?

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 couldn't find a canonicalizer written in Rust that behaves the same way as the Kotlin test. Whitespace differences caused issues when comparing the json strings.

That said, I did vastly improve the deserialize test to ensure that the JSON is parsed into the expected format here, whereas Kotlin is just testing that it doesn't throw when deserializing. It should be testing the same thing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Curious if you took a look into https://docs.rs/serde_jcs/latest/serde_jcs/ ?

Choose a reason for hiding this comment

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

Yes. Multiple times. Works well, but I couldn't get it to match white space between json of just the string vs deserialized jcs. I don't know why yet. In all honesty, I don't think it's worth fretting over yet. I'll make a task in the backlog to figure it out.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds good! I'd love to take a look at that as a first stab at rust!

/// See [Presentation Definition](https://identity.foundation/presentation-exchange/#presentation-definition)
/// for more information.
#[skip_serializing_none]
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious why the Debug, Default, PartialEq are needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

derive is generating additional code at compile time for this struct:

  • Debug so I can print out the values and get a debug description of the struct & all of its fields
  • Default so I can create this struct with pre-populated default values (used in tests)
  • PartialEq so I can use the == operator in tests

/// can use to articulate proof requirements, and a Presentation Submission data format Holders can
/// use to describe proofs submitted in accordance with them.
///
/// See [Presentation Definition](https://identity.foundation/presentation-exchange/#presentation-definition)
Copy link
Contributor

Choose a reason for hiding this comment

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

I appreciate the links to spec docs 👍

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// See [Presentation Definition](https://identity.foundation/presentation-exchange/#presentation-definition)
/// See [Presentation Definition](https://identity.foundation/presentation-exchange/spec/v2.0.0/#presentation-definition)

///
/// See [Presentation Definition](https://identity.foundation/presentation-exchange/#presentation-definition)
/// for more information.
#[skip_serializing_none]
Copy link
Contributor

Choose a reason for hiding this comment

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

So what's the intent of skip_serialization_none?

Is it such that serialization/deserialization doesn't throw exceptions in the event of optional fields missing?

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe it makes it so that when serializing a struct to JSON, fields who's value is set to Option::None will be skipped. If this isn't set, then the fields woulb be serialized as null.

A more explicit example below.

Without the skip_serializing_none macro

{
  "foo": 1
  "bar": null
}

With the macro

{
  "foo": 1
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Yup that makes sense, thanks!

.as_ref()
.map(|json| {
JSONSchema::options()
.with_draft(Draft::Draft7)
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the concept of a "draft" here?

Copy link
Member

Choose a reason for hiding this comment

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

it's a revision for json schema itself...unfortunately they're still using quite an old draft

@amika-sq amika-sq merged commit 694db64 into main Nov 29, 2023
@amika-sq amika-sq deleted the credentials-crate branch November 29, 2023 16:15
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