dpp/
system_data_contracts.rs1use crate::data_contract::DataContractFactory;
2use crate::prelude::*;
3use crate::ProtocolError;
4use std::collections::{BTreeMap, BTreeSet};
5
6use crate::data_contract::accessors::v0::DataContractV0Setters;
7use crate::data_contract::config::v1::DataContractConfigSettersV1;
8use crate::data_contract::config::DataContractConfig;
9pub use data_contracts::*;
10use platform_version::version::PlatformVersion;
11
12pub trait ConfigurationForSystemContract {
13 fn configuration_in_platform_version(
14 &self,
15 version: &PlatformVersion,
16 ) -> Result<DataContractConfig, ProtocolError>;
17}
18
19impl ConfigurationForSystemContract for SystemDataContract {
20 fn configuration_in_platform_version(
21 &self,
22 platform_version: &PlatformVersion,
23 ) -> Result<DataContractConfig, ProtocolError> {
24 match self {
25 SystemDataContract::Withdrawals => {
26 let mut config = DataContractConfig::default_for_version(platform_version)?;
27 config.set_sized_integer_types_enabled(false);
28 Ok(config)
29 }
30 SystemDataContract::MasternodeRewards => {
31 let mut config = DataContractConfig::default_for_version(platform_version)?;
32 config.set_sized_integer_types_enabled(false);
33 Ok(config)
34 }
35 SystemDataContract::FeatureFlags => {
40 DataContractConfig::default_for_version(platform_version)
41 }
42 SystemDataContract::DPNS => {
43 let mut config = DataContractConfig::default_for_version(platform_version)?;
44 config.set_sized_integer_types_enabled(false);
45 Ok(config)
46 }
47 SystemDataContract::Dashpay => {
48 let mut config = DataContractConfig::default_for_version(platform_version)?;
49 config.set_sized_integer_types_enabled(false);
50 Ok(config)
51 }
52 SystemDataContract::WalletUtils => {
53 let mut config = DataContractConfig::default_for_version(platform_version)?;
54 config.set_sized_integer_types_enabled(false);
55 Ok(config)
56 }
57 SystemDataContract::TokenHistory => {
58 let mut config = DataContractConfig::default_for_version(platform_version)?;
59 config.set_sized_integer_types_enabled(true);
60 Ok(config)
61 }
62 SystemDataContract::KeywordSearch => {
63 let mut config = DataContractConfig::default_for_version(platform_version)?;
64 config.set_sized_integer_types_enabled(true);
65 Ok(config)
66 }
67 SystemDataContract::DocumentHistory => {
68 let mut config = DataContractConfig::default_for_version(platform_version)?;
69 config.set_sized_integer_types_enabled(true);
70 Ok(config)
71 }
72 }
73 }
74}
75
76fn create_data_contract(
77 factory: &DataContractFactory,
78 system_contract: SystemDataContract,
79 platform_version: &PlatformVersion,
80) -> Result<DataContract, ProtocolError> {
81 let DataContractSource {
82 id_bytes,
83 owner_id_bytes,
84 version,
85 definitions,
86 document_schemas,
87 } = system_contract
88 .source(platform_version)
89 .map_err(|e| ProtocolError::Generic(e.to_string()))?;
90
91 let id = Identifier::from(id_bytes);
92 let owner_id = Identifier::from(owner_id_bytes);
93
94 let mut data_contract = factory.create(
95 owner_id,
96 0,
97 document_schemas.into(),
98 Some(system_contract.configuration_in_platform_version(platform_version)?),
99 definitions.map(|def| def.into()),
100 )?;
101
102 data_contract.data_contract_mut().set_id(id);
103 data_contract.data_contract_mut().set_version(version);
104
105 Ok(data_contract.data_contract_owned())
106}
107
108pub fn load_system_data_contract(
109 system_contract: SystemDataContract,
110 platform_version: &PlatformVersion,
111) -> Result<DataContract, ProtocolError> {
112 let factory = DataContractFactory::new(platform_version.protocol_version)?;
113
114 create_data_contract(&factory, system_contract, platform_version)
115}
116
117pub fn load_system_data_contracts(
118 system_contracts: BTreeSet<SystemDataContract>,
119 platform_version: &PlatformVersion,
120) -> Result<BTreeMap<SystemDataContract, DataContract>, ProtocolError> {
121 let factory = DataContractFactory::new(platform_version.protocol_version)?;
122
123 system_contracts
124 .into_iter()
125 .map(|system_contract| {
126 let data_contract = create_data_contract(&factory, system_contract, platform_version)?;
127
128 Ok((system_contract, data_contract))
129 })
130 .collect()
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136 use crate::data_contract::serialized_version::DataContractInSerializationFormat;
137 use crate::serialization::PlatformSerializableWithPlatformVersion;
138 use platform_version::TryIntoPlatformVersioned;
139 #[test]
140 fn test_load_system_data_contract_v8_vs_v9() {
141 let contract_1 = load_system_data_contract(
142 SystemDataContract::TokenHistory,
143 PlatformVersion::get(8).unwrap(),
144 )
145 .expect("data_contract");
146 let contract_2 = load_system_data_contract(
147 SystemDataContract::TokenHistory,
148 PlatformVersion::get(9).unwrap(),
149 )
150 .expect("data_contract");
151 assert_ne!(contract_1, contract_2);
152 }
153
154 #[test]
155 fn serialize_withdrawal_contract_v1_vs_v9() {
156 let contract_1 = load_system_data_contract(
157 SystemDataContract::Withdrawals,
158 PlatformVersion::get(1).unwrap(),
159 )
160 .expect("data_contract");
161 let contract_2 = load_system_data_contract(
162 SystemDataContract::Withdrawals,
163 PlatformVersion::get(9).unwrap(),
164 )
165 .expect("data_contract");
166
167 assert_ne!(contract_1, contract_2);
168 let v1_ser: DataContractInSerializationFormat = contract_1
169 .clone()
170 .try_into_platform_versioned(PlatformVersion::get(1).unwrap())
171 .expect("expected to serialize");
172 let v2_ser: DataContractInSerializationFormat = contract_2
173 .clone()
174 .try_into_platform_versioned(PlatformVersion::get(1).unwrap())
175 .expect("expected to serialize");
176 assert_eq!(v1_ser, v2_ser);
177
178 let v1_bytes = contract_1
179 .serialize_to_bytes_with_platform_version(PlatformVersion::get(1).unwrap())
180 .expect("expected to serialize");
181 let v8_bytes = contract_1
182 .serialize_to_bytes_with_platform_version(PlatformVersion::get(8).unwrap())
183 .expect("expected to serialize");
184 let v9_bytes = contract_1
185 .serialize_to_bytes_with_platform_version(PlatformVersion::get(9).unwrap())
186 .expect("expected to serialize");
187 assert_eq!(v1_bytes.len(), 1747);
188 assert_eq!(v8_bytes.len(), 1747);
189 assert_eq!(v9_bytes.len(), 1757); let v1_bytes = contract_2
192 .serialize_to_bytes_with_platform_version(PlatformVersion::get(8).unwrap())
193 .expect("expected to serialize");
194 let v8_bytes = contract_2
195 .serialize_to_bytes_with_platform_version(PlatformVersion::get(8).unwrap())
196 .expect("expected to serialize");
197 let v9_bytes = contract_2
198 .serialize_to_bytes_with_platform_version(PlatformVersion::get(9).unwrap())
199 .expect("expected to serialize");
200 assert_eq!(v1_bytes.len(), 1747);
201 assert_eq!(v8_bytes.len(), 1747);
202 assert_eq!(v9_bytes.len(), 1758); }
204}