Skip to main content

dpp/identity/v0/
mod.rs

1mod conversion;
2#[cfg(feature = "random-identities")]
3pub mod random;
4
5#[cfg(feature = "json-conversion")]
6use crate::serialization::json_safe_fields;
7#[cfg(feature = "json-conversion")]
8use crate::serialization::JsonConvertible;
9#[cfg(feature = "value-conversion")]
10use crate::serialization::ValueConvertible;
11use std::collections::BTreeMap;
12#[cfg(feature = "value-conversion")]
13use std::convert::TryFrom;
14use std::hash::{Hash, Hasher};
15
16use crate::identity::{IdentityPublicKey, KeyID, PartialIdentity};
17use crate::prelude::Revision;
18#[cfg(feature = "value-conversion")]
19use platform_value::Value;
20
21#[cfg(feature = "value-conversion")]
22use crate::errors::ProtocolError;
23use crate::identifier::Identifier;
24#[cfg(feature = "identity-serialization")]
25use bincode::{Decode, DecodeUntrusted, Encode};
26
27/// Implement the Identity. Identity is a low-level construct that provides the foundation
28/// for user-facing functionality on the platform
29#[cfg_attr(feature = "json-conversion", json_safe_fields)]
30#[derive(Default, Debug, Clone, Eq, PartialEq)]
31#[cfg_attr(
32    feature = "identity-serialization",
33    derive(Encode, Decode, DecodeUntrusted)
34)]
35#[cfg_attr(
36    feature = "serde-conversion",
37    derive(serde::Serialize, serde::Deserialize),
38    serde(rename_all = "camelCase")
39)]
40#[cfg_attr(feature = "value-conversion", derive(ValueConvertible))]
41pub struct IdentityV0 {
42    pub id: Identifier,
43    #[cfg_attr(feature = "serde-conversion", serde(with = "public_key_serialization"))]
44    pub public_keys: BTreeMap<KeyID, IdentityPublicKey>,
45    pub balance: u64,
46    pub revision: Revision,
47}
48
49impl Hash for IdentityV0 {
50    fn hash<H: Hasher>(&self, state: &mut H) {
51        self.id.hash(state);
52    }
53}
54
55#[cfg(all(feature = "json-conversion", feature = "serde-conversion"))]
56impl JsonConvertible for IdentityV0 {}
57
58mod public_key_serialization {
59    use crate::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0;
60    use crate::identity::{IdentityPublicKey, KeyID};
61    use serde::ser::SerializeSeq;
62    use serde::{Deserialize, Serializer};
63    use std::collections::BTreeMap;
64
65    /// deserialize_public_keys deserializes public keys from a vector
66    pub fn deserialize<'de, D>(
67        deserializer: D,
68    ) -> Result<BTreeMap<KeyID, IdentityPublicKey>, D::Error>
69    where
70        D: serde::Deserializer<'de>,
71    {
72        let public_key_vec: Vec<IdentityPublicKey> = Deserialize::deserialize(deserializer)?;
73        Ok(public_key_vec.into_iter().map(|k| (k.id(), k)).collect())
74    }
75
76    pub fn serialize<S>(
77        public_keys: &BTreeMap<KeyID, IdentityPublicKey>,
78        serializer: S,
79    ) -> Result<S::Ok, S::Error>
80    where
81        S: Serializer,
82    {
83        let mut seq = serializer.serialize_seq(Some(public_keys.len()))?;
84        for element in public_keys.values() {
85            seq.serialize_element(element)?;
86        }
87        seq.end()
88    }
89}
90
91impl IdentityV0 {
92    /// Get Identity protocol version
93    pub fn get_feature_version(&self) -> u16 {
94        0
95    }
96
97    /// Convenience method to get Partial Identity Info
98    pub fn into_partial_identity_info(self) -> PartialIdentity {
99        let Self {
100            id,
101            public_keys,
102            balance,
103            revision,
104            ..
105        } = self;
106        PartialIdentity {
107            id,
108            loaded_public_keys: public_keys,
109            balance: Some(balance),
110            revision: Some(revision),
111            not_found_public_keys: Default::default(),
112        }
113    }
114
115    /// Convenience method to get Partial Identity Info
116    pub fn into_partial_identity_info_no_balance(self) -> PartialIdentity {
117        let Self {
118            id,
119            public_keys,
120            revision,
121            ..
122        } = self;
123        PartialIdentity {
124            id,
125            loaded_public_keys: public_keys,
126            balance: None,
127            revision: Some(revision),
128            not_found_public_keys: Default::default(),
129        }
130    }
131}
132
133#[cfg(feature = "value-conversion")]
134impl TryFrom<Value> for IdentityV0 {
135    type Error = ProtocolError;
136
137    fn try_from(value: Value) -> Result<Self, Self::Error> {
138        platform_value::from_value(value).map_err(ProtocolError::ValueError)
139    }
140}
141
142#[cfg(feature = "value-conversion")]
143impl TryFrom<&Value> for IdentityV0 {
144    type Error = ProtocolError;
145
146    fn try_from(value: &Value) -> Result<Self, Self::Error> {
147        platform_value::from_value(value.clone()).map_err(ProtocolError::ValueError)
148    }
149}
150
151#[cfg(all(
152    test,
153    feature = "json-conversion",
154    feature = "value-conversion",
155    feature = "serde-conversion"
156))]
157mod json_convertible_tests_identityv0 {
158    use super::*;
159
160    #[test]
161    fn json_round_trip_identityv0() {
162        use crate::serialization::JsonConvertible;
163        let original = IdentityV0::default();
164        let json = original.to_json().expect("to_json");
165        let recovered = IdentityV0::from_json(json).expect("from_json");
166        assert_eq!(original, recovered);
167    }
168
169    #[test]
170    fn value_round_trip_identityv0() {
171        use crate::serialization::ValueConvertible;
172        let original = IdentityV0::default();
173        let value = original.to_object().expect("to_object");
174        let recovered = IdentityV0::from_object(value).expect("from_object");
175        assert_eq!(original, recovered);
176    }
177}