dpp/data_contract/v0/serialization/
mod.rs

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