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