Skip to content

Commit

Permalink
Enable deep equality in OrderedSet (#481)
Browse files Browse the repository at this point in the history
* Remove `DIDKey`; add `KeyComparable` trait

* Fix `OrderedSet::{replace, update}` methods

Co-authored-by: Craig Bester <craig.bester@iota.org>
  • Loading branch information
PhilippGackstatter and cycraig authored Nov 8, 2021
1 parent 8f90176 commit 7978f5f
Show file tree
Hide file tree
Showing 17 changed files with 299 additions and 355 deletions.
2 changes: 1 addition & 1 deletion identity-account/src/tests/lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ async fn test_lazy_updates() -> Result<()> {
assert_eq!(services.len(), 2);

for service in services.iter() {
let service_fragment = service.as_ref().id().fragment().unwrap();
let service_fragment = service.id().fragment().unwrap();
assert!(["my-service", "my-other-service"]
.iter()
.any(|fragment| *fragment == service_fragment));
Expand Down
6 changes: 6 additions & 0 deletions identity-did/src/did/did_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,12 @@ where
}
}

impl<T: DID> AsRef<DIDUrl<T>> for DIDUrl<T> {
fn as_ref(&self) -> &DIDUrl<T> {
self
}
}

impl<T> PartialEq for DIDUrl<T>
where
T: DID,
Expand Down
31 changes: 0 additions & 31 deletions identity-did/src/diff/did_key_diff.rs

This file was deleted.

97 changes: 61 additions & 36 deletions identity-did/src/diff/diff_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use identity_core::diff::Result;
use crate::did::CoreDID;
use crate::document::CoreDocument;
use crate::service::Service;
use crate::utils::DIDKey;
use crate::utils::OrderedSet;
use crate::verification::MethodRef;
use crate::verification::VerificationMethod;
Expand All @@ -35,19 +34,19 @@ where
#[serde(skip_serializing_if = "Option::is_none")]
also_known_as: Option<DiffVec<Url>>,
#[serde(skip_serializing_if = "Option::is_none")]
verification_method: Option<DiffVec<DIDKey<VerificationMethod<U>>>>,
verification_method: Option<DiffVec<VerificationMethod<U>>>,
#[serde(skip_serializing_if = "Option::is_none")]
authentication: Option<DiffVec<DIDKey<MethodRef<U>>>>,
authentication: Option<DiffVec<MethodRef<U>>>,
#[serde(skip_serializing_if = "Option::is_none")]
assertion_method: Option<DiffVec<DIDKey<MethodRef<U>>>>,
assertion_method: Option<DiffVec<MethodRef<U>>>,
#[serde(skip_serializing_if = "Option::is_none")]
key_agreement: Option<DiffVec<DIDKey<MethodRef<U>>>>,
key_agreement: Option<DiffVec<MethodRef<U>>>,
#[serde(skip_serializing_if = "Option::is_none")]
capability_delegation: Option<DiffVec<DIDKey<MethodRef<U>>>>,
capability_delegation: Option<DiffVec<MethodRef<U>>>,
#[serde(skip_serializing_if = "Option::is_none")]
capability_invocation: Option<DiffVec<DIDKey<MethodRef<U>>>>,
capability_invocation: Option<DiffVec<MethodRef<U>>>,
#[serde(skip_serializing_if = "Option::is_none")]
service: Option<DiffVec<DIDKey<Service<V>>>>,
service: Option<DiffVec<Service<V>>>,
#[serde(skip_serializing_if = "Option::is_none")]
properties: Option<<T as Diff>::Type>,
}
Expand Down Expand Up @@ -144,43 +143,43 @@ where
.transpose()?
.unwrap_or_else(|| self.also_known_as().to_vec());

let verification_method: OrderedSet<DIDKey<VerificationMethod<U>>> = diff
let verification_method: OrderedSet<VerificationMethod<U>> = diff
.verification_method
.map(|value| self.verification_method().merge(value))
.transpose()?
.unwrap_or_else(|| self.verification_method().clone());

let authentication: OrderedSet<DIDKey<MethodRef<U>>> = diff
let authentication: OrderedSet<MethodRef<U>> = diff
.authentication
.map(|value| self.authentication().merge(value))
.transpose()?
.unwrap_or_else(|| self.authentication().clone());

let assertion_method: OrderedSet<DIDKey<MethodRef<U>>> = diff
let assertion_method: OrderedSet<MethodRef<U>> = diff
.assertion_method
.map(|value| self.assertion_method().merge(value))
.transpose()?
.unwrap_or_else(|| self.assertion_method().clone());

let key_agreement: OrderedSet<DIDKey<MethodRef<U>>> = diff
let key_agreement: OrderedSet<MethodRef<U>> = diff
.key_agreement
.map(|value| self.key_agreement().merge(value))
.transpose()?
.unwrap_or_else(|| self.key_agreement().clone());

let capability_delegation: OrderedSet<DIDKey<MethodRef<U>>> = diff
let capability_delegation: OrderedSet<MethodRef<U>> = diff
.capability_delegation
.map(|value| self.capability_delegation().merge(value))
.transpose()?
.unwrap_or_else(|| self.capability_delegation().clone());

let capability_invocation: OrderedSet<DIDKey<MethodRef<U>>> = diff
let capability_invocation: OrderedSet<MethodRef<U>> = diff
.capability_invocation
.map(|value| self.capability_invocation().merge(value))
.transpose()?
.unwrap_or_else(|| self.capability_invocation().clone());

let service: OrderedSet<DIDKey<Service<V>>> = diff
let service: OrderedSet<Service<V>> = diff
.service
.map(|value| self.service().merge(value))
.transpose()?
Expand Down Expand Up @@ -229,43 +228,43 @@ where
.transpose()?
.ok_or_else(|| Error::convert("Missing field `document.also_known_as`"))?;

let verification_method: OrderedSet<DIDKey<VerificationMethod<U>>> = diff
let verification_method: OrderedSet<VerificationMethod<U>> = diff
.verification_method
.map(Diff::from_diff)
.transpose()?
.ok_or_else(|| Error::convert("Missing field `document.verification_method`"))?;

let authentication: OrderedSet<DIDKey<MethodRef<U>>> = diff
let authentication: OrderedSet<MethodRef<U>> = diff
.authentication
.map(Diff::from_diff)
.transpose()?
.ok_or_else(|| Error::convert("Missing field `document.authentication`"))?;

let assertion_method: OrderedSet<DIDKey<MethodRef<U>>> = diff
let assertion_method: OrderedSet<MethodRef<U>> = diff
.assertion_method
.map(Diff::from_diff)
.transpose()?
.ok_or_else(|| Error::convert("Missing field `document.assertion_method`"))?;

let key_agreement: OrderedSet<DIDKey<MethodRef<U>>> = diff
let key_agreement: OrderedSet<MethodRef<U>> = diff
.key_agreement
.map(Diff::from_diff)
.transpose()?
.ok_or_else(|| Error::convert("Missing field `document.key_agreement`"))?;

let capability_delegation: OrderedSet<DIDKey<MethodRef<U>>> = diff
let capability_delegation: OrderedSet<MethodRef<U>> = diff
.capability_delegation
.map(Diff::from_diff)
.transpose()?
.ok_or_else(|| Error::convert("Missing field `document.capability_delegation`"))?;

let capability_invocation: OrderedSet<DIDKey<MethodRef<U>>> = diff
let capability_invocation: OrderedSet<MethodRef<U>> = diff
.capability_invocation
.map(Diff::from_diff)
.transpose()?
.ok_or_else(|| Error::convert("Missing field `document.capability_invocation`"))?;

let service: OrderedSet<DIDKey<Service<V>>> = diff
let service: OrderedSet<Service<V>> = diff
.service
.map(Diff::from_diff)
.transpose()?
Expand Down Expand Up @@ -419,7 +418,7 @@ mod test {
// add new method
assert!(new
.verification_method_mut()
.append(method(&doc.clone().controller.unwrap(), "#key-diff").into()));
.append(method(&doc.clone().controller.unwrap(), "#key-diff")));
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand All @@ -435,7 +434,7 @@ mod test {
let first = new.verification_method().first().unwrap().clone();
new
.verification_method_mut()
.replace(&first, method(&"did:diff:1234".parse().unwrap(), "#key-diff").into());
.replace(&first, method(&"did:diff:1234".parse().unwrap(), "#key-diff"));
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand Down Expand Up @@ -463,7 +462,7 @@ mod test {

// add new method
let method_ref: MethodRef = method(&doc.clone().controller.unwrap(), "#key-diff").into();
assert!(new.authentication_mut().append(method_ref.into()));
assert!(new.authentication_mut().append(method_ref));
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand All @@ -478,7 +477,7 @@ mod test {
// update method
let method_ref: MethodRef = method(&doc.clone().controller.unwrap(), "#key-diff").into();
let first = new.authentication().first().unwrap().clone();
new.authentication_mut().replace(&first, method_ref.into());
new.authentication_mut().replace(&first, method_ref);
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand Down Expand Up @@ -506,7 +505,7 @@ mod test {

// add new method
let method_ref: MethodRef = method(&doc.clone().controller.unwrap(), "#key-diff").into();
assert!(new.assertion_method_mut().append(method_ref.into()));
assert!(new.assertion_method_mut().append(method_ref));
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand All @@ -521,7 +520,7 @@ mod test {
// update method
let method_ref: MethodRef = method(&doc.clone().controller.unwrap(), "#key-diff").into();
let first = new.assertion_method().first().unwrap().clone();
new.assertion_method_mut().replace(&first, method_ref.into());
new.assertion_method_mut().replace(&first, method_ref);
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand Down Expand Up @@ -549,7 +548,7 @@ mod test {

// add new method
let method_ref: MethodRef = method(&doc.clone().controller.unwrap(), "#key-diff").into();
assert!(new.key_agreement_mut().append(method_ref.into()));
assert!(new.key_agreement_mut().append(method_ref));
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand All @@ -564,7 +563,7 @@ mod test {
// update method
let method_ref: MethodRef = method(&doc.clone().controller.unwrap(), "#key-diff").into();
let first = new.key_agreement().first().unwrap().clone();
new.key_agreement_mut().replace(&first, method_ref.into());
new.key_agreement_mut().replace(&first, method_ref);
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand Down Expand Up @@ -592,7 +591,7 @@ mod test {

// add new method
let method_ref: MethodRef = method(&doc.clone().controller.unwrap(), "#key-diff").into();
assert!(new.capability_delegation_mut().append(method_ref.into()));
assert!(new.capability_delegation_mut().append(method_ref));
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand All @@ -607,7 +606,7 @@ mod test {
// update method
let method_ref: MethodRef = method(&doc.clone().controller.unwrap(), "#key-diff").into();
let first = new.capability_delegation().first().unwrap().clone();
new.capability_delegation_mut().replace(&first, method_ref.into());
new.capability_delegation_mut().replace(&first, method_ref);
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand Down Expand Up @@ -635,7 +634,7 @@ mod test {

// add new method
let method_ref: MethodRef = method(&doc.clone().controller.unwrap(), "#key-diff").into();
assert!(new.capability_invocation_mut().append(method_ref.into()));
assert!(new.capability_invocation_mut().append(method_ref));
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand All @@ -650,7 +649,7 @@ mod test {
// update method
let method_ref: MethodRef = method(&doc.clone().controller.unwrap(), "#key-diff").into();
let first = new.capability_invocation().first().unwrap().clone();
new.capability_invocation_mut().replace(&first, method_ref.into());
new.capability_invocation_mut().replace(&first, method_ref);
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand Down Expand Up @@ -678,7 +677,7 @@ mod test {

// Add new service
let service = service(doc.controller().cloned().unwrap().join("#key-diff").unwrap());
assert!(new.service_mut().append(service.into()));
assert!(new.service_mut().append(service));
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand All @@ -693,7 +692,7 @@ mod test {
// add new service
let service = service(doc.controller().cloned().unwrap().join("#key-diff").unwrap());
let first = new.service().first().unwrap().clone();
new.service_mut().replace(&first, service.into());
new.service_mut().replace(&first, service);
assert_ne!(doc, new);
let diff = doc.diff(&new).unwrap();
let merge = doc.merge(diff).unwrap();
Expand Down Expand Up @@ -753,4 +752,30 @@ mod test {
let new = CoreDocument::from_diff(diff).unwrap();
assert_eq!(doc, new);
}

#[test]
fn test_rotate_key_material_method() {
let doc = document();
let mut new = doc.clone();

let first: CoreDIDUrl = new.capability_invocation().first().unwrap().as_ref().clone();
new.capability_invocation_mut().remove(&first);

let method_ref: MethodRef = MethodBuilder::default()
.id(first)
.controller(new.controller.clone().unwrap())
.key_type(MethodType::Ed25519VerificationKey2018)
.key_data(MethodData::new_multibase(b"key_material"))
.build()
.unwrap()
.into();

assert!(new.capability_invocation_mut().append(method_ref));

assert_ne!(doc, new);

// Ensure overwriting the key material of a method with the same fragment produces a diff.
let diff = doc.diff(&new).unwrap();
assert!(diff.capability_invocation.is_some());
}
}
1 change: 0 additions & 1 deletion identity-did/src/diff/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2020-2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

mod did_key_diff;
mod diff_document;
mod diff_method;
mod diff_service;
Expand Down
3 changes: 2 additions & 1 deletion identity-did/src/diff/ordered_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ use identity_core::diff::Result;
use serde::Deserialize;
use serde::Serialize;

use crate::utils::KeyComparable;
use crate::utils::OrderedSet;

impl<T> Diff for OrderedSet<T>
where
T: Diff + Serialize + for<'de> Deserialize<'de>,
T: Diff + KeyComparable + Serialize + for<'de> Deserialize<'de>,
{
type Type = DiffVec<T>;

Expand Down
Loading

0 comments on commit 7978f5f

Please sign in to comment.