dpp/data_contract/v1/serialization/
mod.rs1use crate::data_contract::document_type::DocumentType;
2use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0;
3use crate::data_contract::serialized_version::DataContractInSerializationFormat;
4use crate::data_contract::{DataContract, DataContractV1};
5use crate::version::{PlatformVersion, PlatformVersionCurrentVersion};
6use crate::ProtocolError;
7use std::collections::BTreeMap;
8
9use crate::data_contract::serialized_version::v1::DataContractInSerializationFormatV1;
10use crate::validation::operations::ProtocolValidationOperation;
11use serde::{Deserialize, Deserializer, Serialize, Serializer};
12
13impl Serialize for DataContractV1 {
14 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
15 where
16 S: Serializer,
17 {
18 let data_contract: DataContract = self.clone().into();
19 let serialization_format = DataContractInSerializationFormatV1::from(data_contract);
20 serialization_format.serialize(serializer)
21 }
22}
23
24impl<'de> Deserialize<'de> for DataContractV1 {
25 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
26 where
27 D: Deserializer<'de>,
28 {
29 let serialization_format = DataContractInSerializationFormatV1::deserialize(deserializer)?;
30 let current_version = PlatformVersion::get_current().map_err(|e| {
31 serde::de::Error::custom(format!(
32 "expected to be able to get current platform version: {}",
33 e
34 ))
35 })?;
36 DataContractV1::try_from_platform_versioned_v1(
38 serialization_format,
39 true,
40 &mut vec![],
41 current_version,
42 )
43 .map_err(serde::de::Error::custom)
44 }
45}
46
47impl DataContractV1 {
48 pub(in crate::data_contract) fn try_from_platform_versioned(
49 value: DataContractInSerializationFormat,
50 full_validation: bool,
51 validation_operations: &mut Vec<ProtocolValidationOperation>,
52 platform_version: &PlatformVersion,
53 ) -> Result<Self, ProtocolError> {
54 match value {
55 DataContractInSerializationFormat::V0(serialization_format_v0) => {
56 let data_contract = DataContractV1::try_from_platform_versioned_v0(
57 serialization_format_v0,
58 full_validation,
59 validation_operations,
60 platform_version,
61 )?;
62
63 Ok(data_contract)
64 }
65 DataContractInSerializationFormat::V1(serialization_format_v1) => {
66 let data_contract = DataContractV1::try_from_platform_versioned_v1(
67 serialization_format_v1,
68 full_validation,
69 validation_operations,
70 platform_version,
71 )?;
72
73 Ok(data_contract)
74 }
75 }
76 }
77
78 pub(in crate::data_contract) fn try_from_platform_versioned_v0(
79 data_contract_data: DataContractInSerializationFormatV0,
80 full_validation: bool,
81 validation_operations: &mut Vec<ProtocolValidationOperation>,
82 platform_version: &PlatformVersion,
83 ) -> Result<Self, ProtocolError> {
84 let DataContractInSerializationFormatV0 {
85 id,
86 config,
87 version,
88 owner_id,
89 document_schemas,
90 schema_defs,
91 } = data_contract_data;
92
93 let document_types = DocumentType::create_document_types_from_document_schemas(
94 id,
95 1,
96 data_contract_data.config.version(),
97 document_schemas,
98 schema_defs.as_ref(),
99 &BTreeMap::new(),
100 &config,
101 full_validation,
102 false,
103 validation_operations,
104 platform_version,
105 )?;
106
107 let data_contract = DataContractV1 {
108 id,
109 version,
110 owner_id,
111 document_types,
112 config,
113 schema_defs,
114 created_at: None,
115 updated_at: None,
116 created_at_block_height: None,
117 updated_at_block_height: None,
118 created_at_epoch: None,
119 updated_at_epoch: None,
120 groups: Default::default(),
121 tokens: Default::default(),
122 keywords: Default::default(),
123 description: None,
124 };
125
126 Ok(data_contract)
127 }
128
129 pub(in crate::data_contract) fn try_from_platform_versioned_v1(
130 data_contract_data: DataContractInSerializationFormatV1,
131 full_validation: bool,
132 validation_operations: &mut Vec<ProtocolValidationOperation>,
133 platform_version: &PlatformVersion,
134 ) -> Result<Self, ProtocolError> {
135 let DataContractInSerializationFormatV1 {
136 id,
137 config,
138 version,
139 owner_id,
140 document_schemas,
141 schema_defs,
142 created_at,
143 updated_at,
144 created_at_block_height,
145 updated_at_block_height,
146 created_at_epoch,
147 updated_at_epoch,
148 groups,
149 tokens,
150 keywords,
151 description,
152 } = data_contract_data;
153
154 let document_types = DocumentType::create_document_types_from_document_schemas(
155 id,
156 1,
157 data_contract_data.config.version(),
158 document_schemas,
159 schema_defs.as_ref(),
160 &tokens,
161 &config,
162 full_validation,
163 !tokens.is_empty(),
164 validation_operations,
165 platform_version,
166 )?;
167
168 let data_contract = DataContractV1 {
169 id,
170 version,
171 owner_id,
172 document_types,
173 config,
174 schema_defs,
175 created_at,
176 updated_at,
177 created_at_block_height,
178 updated_at_block_height,
179 created_at_epoch,
180 updated_at_epoch,
181 groups,
182 tokens,
183 keywords: keywords
184 .into_iter()
185 .map(|keyword| keyword.to_lowercase())
186 .collect(),
187 description,
188 };
189
190 Ok(data_contract)
191 }
192}
193
194#[cfg(test)]
195mod tests {
196 use crate::data_contract::DataContract;
197 use crate::identity::accessors::IdentityGettersV0;
198 use crate::identity::Identity;
199 use crate::serialization::{
200 PlatformDeserializableWithPotentialValidationFromVersionedStructure,
201 PlatformSerializableWithPlatformVersion,
202 };
203 use crate::tests::fixtures::get_data_contract_fixture;
204 use crate::version::PlatformVersion;
205 use platform_version::version::LATEST_PLATFORM_VERSION;
206
207 #[test]
208 #[cfg(feature = "random-identities")]
209 fn data_contract_ser_de() {
210 let platform_version = PlatformVersion::get(7).expect("expected protocol version 7");
212 let identity = Identity::random_identity(5, Some(5), platform_version)
213 .expect("expected a random identity");
214 let contract =
215 get_data_contract_fixture(Some(identity.id()), 0, platform_version.protocol_version)
216 .data_contract_owned();
217 let bytes = contract
218 .serialize_to_bytes_with_platform_version(LATEST_PLATFORM_VERSION)
219 .expect("expected to serialize");
220 let recovered_contract =
221 DataContract::versioned_deserialize(&bytes, false, platform_version)
222 .expect("expected to deserialize state transition");
223 assert_eq!(contract, recovered_contract);
224 }
225}