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 => {
36 let mut config = DataContractConfig::default_for_version(platform_version)?;
37 config.set_sized_integer_types_enabled(false);
38 Ok(config)
39 }
40 SystemDataContract::DPNS => {
41 let mut config = DataContractConfig::default_for_version(platform_version)?;
42 config.set_sized_integer_types_enabled(false);
43 Ok(config)
44 }
45 SystemDataContract::Dashpay => {
46 let mut config = DataContractConfig::default_for_version(platform_version)?;
47 config.set_sized_integer_types_enabled(false);
48 Ok(config)
49 }
50 SystemDataContract::WalletUtils => {
51 let mut config = DataContractConfig::default_for_version(platform_version)?;
52 config.set_sized_integer_types_enabled(false);
53 Ok(config)
54 }
55 SystemDataContract::TokenHistory => {
56 let mut config = DataContractConfig::default_for_version(platform_version)?;
57 config.set_sized_integer_types_enabled(true);
58 Ok(config)
59 }
60 SystemDataContract::KeywordSearch => {
61 let mut config = DataContractConfig::default_for_version(platform_version)?;
62 config.set_sized_integer_types_enabled(true);
63 Ok(config)
64 }
65 }
66 }
67}
68
69fn create_data_contract(
70 factory: &DataContractFactory,
71 system_contract: SystemDataContract,
72 platform_version: &PlatformVersion,
73) -> Result<DataContract, ProtocolError> {
74 let DataContractSource {
75 id_bytes,
76 owner_id_bytes,
77 version,
78 definitions,
79 document_schemas,
80 } = system_contract
81 .source(platform_version)
82 .map_err(|e| ProtocolError::Generic(e.to_string()))?;
83
84 let id = Identifier::from(id_bytes);
85 let owner_id = Identifier::from(owner_id_bytes);
86
87 let mut data_contract = factory.create(
88 owner_id,
89 0,
90 document_schemas.into(),
91 Some(system_contract.configuration_in_platform_version(platform_version)?),
92 definitions.map(|def| def.into()),
93 )?;
94
95 data_contract.data_contract_mut().set_id(id);
96 data_contract.data_contract_mut().set_version(version);
97
98 Ok(data_contract.data_contract_owned())
99}
100
101pub fn load_system_data_contract(
102 system_contract: SystemDataContract,
103 platform_version: &PlatformVersion,
104) -> Result<DataContract, ProtocolError> {
105 let factory = DataContractFactory::new(platform_version.protocol_version)?;
106
107 create_data_contract(&factory, system_contract, platform_version)
108}
109
110pub fn load_system_data_contracts(
111 system_contracts: BTreeSet<SystemDataContract>,
112 platform_version: &PlatformVersion,
113) -> Result<BTreeMap<SystemDataContract, DataContract>, ProtocolError> {
114 let factory = DataContractFactory::new(platform_version.protocol_version)?;
115
116 system_contracts
117 .into_iter()
118 .map(|system_contract| {
119 let data_contract = create_data_contract(&factory, system_contract, platform_version)?;
120
121 Ok((system_contract, data_contract))
122 })
123 .collect()
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129 use crate::data_contract::serialized_version::DataContractInSerializationFormat;
130 use crate::serialization::PlatformSerializableWithPlatformVersion;
131 use platform_version::TryIntoPlatformVersioned;
132 #[test]
133 fn test_load_system_data_contract_v8_vs_v9() {
134 let contract_1 = load_system_data_contract(
135 SystemDataContract::TokenHistory,
136 PlatformVersion::get(8).unwrap(),
137 )
138 .expect("data_contract");
139 let contract_2 = load_system_data_contract(
140 SystemDataContract::TokenHistory,
141 PlatformVersion::get(9).unwrap(),
142 )
143 .expect("data_contract");
144 assert_ne!(contract_1, contract_2);
145 }
146
147 #[test]
148 fn serialize_withdrawal_contract_v1_vs_v9() {
149 let contract_1 = load_system_data_contract(
150 SystemDataContract::Withdrawals,
151 PlatformVersion::get(1).unwrap(),
152 )
153 .expect("data_contract");
154 let contract_2 = load_system_data_contract(
155 SystemDataContract::Withdrawals,
156 PlatformVersion::get(9).unwrap(),
157 )
158 .expect("data_contract");
159
160 assert_ne!(contract_1, contract_2);
161 let v1_ser: DataContractInSerializationFormat = contract_1
162 .clone()
163 .try_into_platform_versioned(PlatformVersion::get(1).unwrap())
164 .expect("expected to serialize");
165 let v2_ser: DataContractInSerializationFormat = contract_2
166 .clone()
167 .try_into_platform_versioned(PlatformVersion::get(1).unwrap())
168 .expect("expected to serialize");
169 assert_eq!(v1_ser, v2_ser);
170
171 let v1_bytes = contract_1
172 .serialize_to_bytes_with_platform_version(PlatformVersion::get(1).unwrap())
173 .expect("expected to serialize");
174 let v8_bytes = contract_1
175 .serialize_to_bytes_with_platform_version(PlatformVersion::get(8).unwrap())
176 .expect("expected to serialize");
177 let v9_bytes = contract_1
178 .serialize_to_bytes_with_platform_version(PlatformVersion::get(9).unwrap())
179 .expect("expected to serialize");
180 assert_eq!(v1_bytes.len(), 1747);
181 assert_eq!(v8_bytes.len(), 1747);
182 assert_eq!(v9_bytes.len(), 1757); let v1_bytes = contract_2
185 .serialize_to_bytes_with_platform_version(PlatformVersion::get(8).unwrap())
186 .expect("expected to serialize");
187 let v8_bytes = contract_2
188 .serialize_to_bytes_with_platform_version(PlatformVersion::get(8).unwrap())
189 .expect("expected to serialize");
190 let v9_bytes = contract_2
191 .serialize_to_bytes_with_platform_version(PlatformVersion::get(9).unwrap())
192 .expect("expected to serialize");
193 assert_eq!(v1_bytes.len(), 1747);
194 assert_eq!(v8_bytes.len(), 1747);
195 assert_eq!(v9_bytes.len(), 1758); }
197}