dpp/data_contract/config/v0/
mod.rs

1use crate::data_contract::config;
2use crate::data_contract::config::v1::DataContractConfigV1;
3use crate::data_contract::config::{
4    DataContractConfig, DEFAULT_CONTRACT_CAN_BE_DELETED, DEFAULT_CONTRACT_DOCUMENTS_CAN_BE_DELETED,
5    DEFAULT_CONTRACT_DOCUMENTS_KEEPS_HISTORY, DEFAULT_CONTRACT_DOCUMENT_MUTABILITY,
6    DEFAULT_CONTRACT_KEEPS_HISTORY, DEFAULT_CONTRACT_MUTABILITY,
7};
8use crate::data_contract::storage_requirements::keys_for_document_type::StorageKeyRequirements;
9#[cfg(feature = "json-conversion")]
10use crate::serialization::json_safe_fields;
11use crate::ProtocolError;
12use bincode::{Decode, Encode};
13use platform_value::btreemap_extensions::BTreeValueMapHelper;
14use platform_value::Value;
15use serde::{Deserialize, Serialize};
16use std::collections::BTreeMap;
17
18#[cfg_attr(feature = "json-conversion", json_safe_fields)]
19#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, Copy, PartialEq, Eq)]
20#[serde(rename_all = "camelCase", default)]
21pub struct DataContractConfigV0 {
22    /// Can the contract ever be deleted. If the contract is deleted, so should be all
23    /// documents associated with it. TODO: There should also be a way to "stop" the contract -
24    /// contract and documents are kept in the system, but no new documents can be added to it
25    pub can_be_deleted: bool,
26    /// Is the contract mutable. Means that the document definitions can be changed or new
27    /// document definitions can be added to the contract
28    pub readonly: bool,
29    /// Does the contract keep history when the contract itself changes
30    pub keeps_history: bool,
31    /// Do documents in the contract keep history. This is a default for all documents in
32    /// the contract, but can be overridden by the document itself
33    pub documents_keep_history_contract_default: bool,
34    /// Are documents in the contract mutable? This specifies whether the documents can be
35    /// changed. This is a default for all document types in the contract, but can be
36    /// overridden by the document type config.
37    pub documents_mutable_contract_default: bool,
38    /// Can documents in the contract be deleted? This specifies whether the documents can be
39    /// deleted. This is a default for all document types in the contract, but can be
40    /// overridden by the document types itself.
41    pub documents_can_be_deleted_contract_default: bool,
42    /// Encryption key storage requirements
43    pub requires_identity_encryption_bounded_key: Option<StorageKeyRequirements>,
44    /// Decryption key storage requirements
45    pub requires_identity_decryption_bounded_key: Option<StorageKeyRequirements>,
46}
47
48/// Trait representing getters for `DataContractConfigV0`
49pub trait DataContractConfigGettersV0 {
50    /// Returns whether the contract can be deleted.
51    fn can_be_deleted(&self) -> bool;
52
53    /// Returns whether the contract is read-only.
54    fn readonly(&self) -> bool;
55
56    /// Returns whether the contract keeps history.
57    fn keeps_history(&self) -> bool;
58
59    /// Returns whether documents in the contract keep history by default.
60    fn documents_keep_history_contract_default(&self) -> bool;
61
62    /// Returns whether documents in the contract are mutable by default.
63    fn documents_mutable_contract_default(&self) -> bool;
64    fn documents_can_be_deleted_contract_default(&self) -> bool;
65
66    /// Encryption key storage requirements
67    fn requires_identity_encryption_bounded_key(&self) -> Option<StorageKeyRequirements>;
68
69    /// Decryption key storage requirements
70    fn requires_identity_decryption_bounded_key(&self) -> Option<StorageKeyRequirements>;
71}
72
73/// Trait representing setters for `DataContractConfigV0`
74pub trait DataContractConfigSettersV0 {
75    /// Sets whether the contract can be deleted.
76    fn set_can_be_deleted(&mut self, value: bool);
77
78    /// Sets whether the contract is read-only.
79    fn set_readonly(&mut self, value: bool);
80
81    /// Sets whether the contract keeps history.
82    fn set_keeps_history(&mut self, value: bool);
83
84    /// Sets whether documents in the contract keep history by default.
85    fn set_documents_keep_history_contract_default(&mut self, value: bool);
86
87    /// Sets whether documents in the contract are mutable by default.
88    fn set_documents_mutable_contract_default(&mut self, value: bool);
89
90    /// Sets whether documents in the contract can be deleted by default.
91    fn set_documents_can_be_deleted_contract_default(&mut self, value: bool);
92
93    /// Sets Encryption key storage requirements.
94    fn set_requires_identity_encryption_bounded_key(
95        &mut self,
96        value: Option<StorageKeyRequirements>,
97    );
98
99    /// Sets Decryption key storage requirements.
100    fn set_requires_identity_decryption_bounded_key(
101        &mut self,
102        value: Option<StorageKeyRequirements>,
103    );
104}
105
106impl Default for DataContractConfigV0 {
107    fn default() -> Self {
108        DataContractConfigV0 {
109            can_be_deleted: DEFAULT_CONTRACT_CAN_BE_DELETED,
110            readonly: !DEFAULT_CONTRACT_MUTABILITY,
111            keeps_history: DEFAULT_CONTRACT_KEEPS_HISTORY,
112            documents_keep_history_contract_default: DEFAULT_CONTRACT_DOCUMENTS_KEEPS_HISTORY,
113            documents_mutable_contract_default: DEFAULT_CONTRACT_DOCUMENT_MUTABILITY,
114            documents_can_be_deleted_contract_default: DEFAULT_CONTRACT_DOCUMENTS_CAN_BE_DELETED,
115            requires_identity_encryption_bounded_key: None,
116            requires_identity_decryption_bounded_key: None,
117        }
118    }
119}
120
121impl DataContractConfigV0 {
122    pub fn from_value(value: Value) -> Result<Self, ProtocolError> {
123        platform_value::from_value(value).map_err(ProtocolError::ValueError)
124    }
125
126    pub fn default_with_version() -> DataContractConfig {
127        Self::default().into()
128    }
129}
130
131impl DataContractConfigV0 {
132    /// Retrieve contract configuration properties.
133    ///
134    /// This method takes a BTreeMap representing a contract and retrieves
135    /// the configuration properties based on the values found in the map.
136    ///
137    /// The process of retrieving contract configuration properties is versioned,
138    /// and the version is determined by the platform version parameter.
139    /// If the version is not supported, an error is returned.
140    ///
141    /// # Parameters
142    ///
143    /// * `contract`: BTreeMap representing the contract.
144    /// * `platform_version`: The platform version being used.
145    ///
146    /// # Returns
147    ///
148    /// * `Result<ContractConfig, ProtocolError>`: On success, a ContractConfig.
149    ///   On failure, a ProtocolError.
150    #[inline(always)]
151    pub(super) fn get_contract_configuration_properties_v0(
152        contract: &BTreeMap<String, Value>,
153    ) -> Result<DataContractConfigV0, ProtocolError> {
154        let keeps_history = contract
155            .get_optional_bool(config::property::KEEPS_HISTORY)?
156            .unwrap_or(DEFAULT_CONTRACT_KEEPS_HISTORY);
157        let can_be_deleted = contract
158            .get_optional_bool(config::property::CAN_BE_DELETED)?
159            .unwrap_or(DEFAULT_CONTRACT_CAN_BE_DELETED);
160
161        let readonly = contract
162            .get_optional_bool(config::property::READONLY)?
163            .unwrap_or(!DEFAULT_CONTRACT_MUTABILITY);
164
165        let documents_keep_history_contract_default = contract
166            .get_optional_bool(config::property::DOCUMENTS_KEEP_HISTORY_CONTRACT_DEFAULT)?
167            .unwrap_or(DEFAULT_CONTRACT_DOCUMENTS_KEEPS_HISTORY);
168
169        let documents_mutable_contract_default = contract
170            .get_optional_bool(config::property::DOCUMENTS_MUTABLE_CONTRACT_DEFAULT)?
171            .unwrap_or(DEFAULT_CONTRACT_DOCUMENT_MUTABILITY);
172
173        let documents_can_be_deleted_contract_default = contract
174            .get_optional_bool(config::property::DOCUMENTS_CAN_BE_DELETED_CONTRACT_DEFAULT)?
175            .unwrap_or(DEFAULT_CONTRACT_DOCUMENTS_CAN_BE_DELETED);
176
177        let requires_identity_encryption_bounded_key = contract
178            .get_optional_integer::<u8>(config::property::REQUIRES_IDENTITY_ENCRYPTION_BOUNDED_KEY)?
179            .map(|int| int.try_into())
180            .transpose()?;
181
182        let requires_identity_decryption_bounded_key = contract
183            .get_optional_integer::<u8>(config::property::REQUIRES_IDENTITY_ENCRYPTION_BOUNDED_KEY)?
184            .map(|int| int.try_into())
185            .transpose()?;
186
187        Ok(DataContractConfigV0 {
188            can_be_deleted,
189            readonly,
190            keeps_history,
191            documents_keep_history_contract_default,
192            documents_mutable_contract_default,
193            documents_can_be_deleted_contract_default,
194            requires_identity_encryption_bounded_key,
195            requires_identity_decryption_bounded_key,
196        })
197    }
198}
199
200impl From<DataContractConfigV1> for DataContractConfigV0 {
201    fn from(value: DataContractConfigV1) -> Self {
202        DataContractConfigV0 {
203            can_be_deleted: value.can_be_deleted,
204            readonly: value.readonly,
205            keeps_history: value.keeps_history,
206            documents_keep_history_contract_default: value.documents_keep_history_contract_default,
207            documents_mutable_contract_default: value.documents_mutable_contract_default,
208            documents_can_be_deleted_contract_default: value
209                .documents_can_be_deleted_contract_default,
210            requires_identity_encryption_bounded_key: value
211                .requires_identity_encryption_bounded_key,
212            requires_identity_decryption_bounded_key: value
213                .requires_identity_decryption_bounded_key,
214        }
215    }
216}