Skip to main content

data_contracts/
lib.rs

1mod error;
2
3use serde_json::Value;
4
5use crate::error::Error;
6
7#[cfg(feature = "dashpay")]
8pub use dashpay_contract;
9
10#[cfg(feature = "dpns")]
11pub use dpns_contract;
12
13#[cfg(feature = "keyword-search")]
14pub use keyword_search_contract;
15
16#[cfg(feature = "masternode-rewards")]
17pub use masternode_reward_shares_contract;
18
19use platform_value::Identifier;
20use platform_version::version::PlatformVersion;
21
22#[cfg(feature = "document-history")]
23pub use document_history_contract;
24
25#[cfg(feature = "token-history")]
26pub use token_history_contract;
27
28#[cfg(feature = "wallet-utils")]
29pub use wallet_utils_contract;
30
31#[cfg(feature = "withdrawals")]
32pub use withdrawals_contract;
33
34#[repr(u8)]
35#[derive(PartialEq, Eq, Clone, Copy, Debug, Ord, PartialOrd, Hash)]
36pub enum SystemDataContract {
37    Withdrawals = 0,
38    MasternodeRewards = 1,
39    /// Reserved slot — the feature-flags contract was never deployed at genesis
40    /// and its implementation has been removed. The discriminant `2` is kept to
41    /// preserve the stable numbering of subsequent variants.
42    FeatureFlags = 2,
43    DPNS = 3,
44    Dashpay = 4,
45    WalletUtils = 5,
46    TokenHistory = 6,
47    KeywordSearch = 7,
48    DocumentHistory = 8,
49}
50
51pub struct DataContractSource {
52    pub id_bytes: [u8; 32],
53    pub owner_id_bytes: [u8; 32],
54    pub version: u32,
55    pub definitions: Option<Value>,
56    pub document_schemas: Value,
57}
58
59impl SystemDataContract {
60    /// Every system data contract, including the reserved `FeatureFlags` slot.
61    ///
62    /// Deliberately kept beside the enum so that adding a variant and adding it here are the
63    /// same edit. `assert_every_variant_is_listed` below makes that mechanical rather than
64    /// remembered: a new variant makes its match non-exhaustive and the crate stops compiling.
65    pub const ALL: [SystemDataContract; 9] = [
66        SystemDataContract::Withdrawals,
67        SystemDataContract::MasternodeRewards,
68        SystemDataContract::FeatureFlags,
69        SystemDataContract::DPNS,
70        SystemDataContract::Dashpay,
71        SystemDataContract::WalletUtils,
72        SystemDataContract::TokenHistory,
73        SystemDataContract::KeywordSearch,
74        SystemDataContract::DocumentHistory,
75    ];
76
77    /// A new variant must also be added to [`SystemDataContract::ALL`]; this match is where the
78    /// compiler stops you, but it cannot check that list for you.
79    pub fn id(&self) -> Identifier {
80        let bytes = match self {
81            #[cfg(feature = "withdrawals")]
82            SystemDataContract::Withdrawals => withdrawals_contract::ID_BYTES,
83            #[cfg(not(feature = "withdrawals"))]
84            SystemDataContract::Withdrawals => [
85                54, 98, 187, 97, 225, 127, 174, 62, 162, 148, 207, 96, 49, 151, 251, 10, 171, 109,
86                81, 24, 11, 216, 182, 16, 76, 73, 68, 166, 47, 226, 217, 127,
87            ],
88
89            #[cfg(feature = "masternode-rewards")]
90            SystemDataContract::MasternodeRewards => masternode_reward_shares_contract::ID_BYTES,
91            #[cfg(not(feature = "masternode-rewards"))]
92            SystemDataContract::MasternodeRewards => [
93                12, 172, 226, 5, 36, 102, 147, 167, 200, 21, 101, 35, 98, 13, 170, 147, 125, 47,
94                34, 71, 147, 68, 99, 238, 176, 31, 247, 33, 149, 144, 149, 140,
95            ],
96
97            // Reserved: feature-flags contract was removed but the ID is kept for
98            // discriminant stability and to prevent reuse of a potentially meaningful
99            // Identifier on-chain.
100            SystemDataContract::FeatureFlags => [
101                245, 172, 216, 200, 193, 110, 185, 172, 40, 110, 7, 132, 190, 86, 127, 80, 9, 244,
102                86, 26, 243, 212, 255, 2, 91, 7, 90, 243, 68, 55, 152, 34,
103            ],
104
105            #[cfg(feature = "dpns")]
106            SystemDataContract::DPNS => dpns_contract::ID_BYTES,
107            #[cfg(not(feature = "dpns"))]
108            SystemDataContract::DPNS => [
109                230, 104, 198, 89, 175, 102, 174, 225, 231, 44, 24, 109, 222, 123, 91, 126, 10, 29,
110                113, 42, 9, 196, 13, 87, 33, 246, 34, 191, 83, 197, 49, 85,
111            ],
112
113            #[cfg(feature = "dashpay")]
114            SystemDataContract::Dashpay => dashpay_contract::ID_BYTES,
115            #[cfg(not(feature = "dashpay"))]
116            SystemDataContract::Dashpay => [
117                162, 161, 180, 172, 111, 239, 34, 234, 42, 26, 104, 232, 18, 54, 68, 179, 87, 135,
118                95, 107, 65, 44, 24, 16, 146, 129, 193, 70, 231, 178, 113, 188,
119            ],
120
121            #[cfg(feature = "wallet-utils")]
122            SystemDataContract::WalletUtils => wallet_utils_contract::ID_BYTES,
123            #[cfg(not(feature = "wallet-utils"))]
124            SystemDataContract::WalletUtils => [
125                92, 20, 14, 101, 92, 2, 101, 187, 194, 168, 8, 113, 109, 225, 132, 121, 133, 19,
126                89, 24, 173, 81, 205, 253, 11, 118, 102, 75, 169, 91, 163, 124,
127            ],
128
129            #[cfg(feature = "token-history")]
130            SystemDataContract::TokenHistory => token_history_contract::ID_BYTES,
131            #[cfg(not(feature = "token-history"))]
132            SystemDataContract::TokenHistory => [
133                45, 67, 89, 21, 34, 216, 145, 78, 156, 243, 17, 58, 202, 190, 13, 92, 61, 40, 122,
134                201, 84, 99, 187, 110, 233, 128, 63, 48, 172, 29, 210, 108,
135            ],
136
137            #[cfg(feature = "keyword-search")]
138            SystemDataContract::KeywordSearch => keyword_search_contract::ID_BYTES,
139            #[cfg(not(feature = "keyword-search"))]
140            SystemDataContract::KeywordSearch => [
141                92, 20, 14, 101, 92, 2, 101, 187, 194, 168, 8, 113, 109, 225, 132, 121, 133, 19,
142                89, 24, 173, 81, 205, 253, 11, 118, 102, 75, 169, 91, 163, 124,
143            ],
144
145            #[cfg(feature = "document-history")]
146            SystemDataContract::DocumentHistory => document_history_contract::ID_BYTES,
147            #[cfg(not(feature = "document-history"))]
148            SystemDataContract::DocumentHistory => [
149                88, 18, 140, 208, 179, 231, 242, 57, 225, 203, 4, 210, 245, 95, 136, 92, 160, 167,
150                112, 118, 173, 238, 83, 62, 234, 230, 222, 16, 231, 30, 99, 98,
151            ],
152        };
153        Identifier::new(bytes)
154    }
155    /// Returns [DataContractSource]
156    pub fn source(self, platform_version: &PlatformVersion) -> Result<DataContractSource, Error> {
157        match self {
158            #[cfg(feature = "withdrawals")]
159            SystemDataContract::Withdrawals => Ok(DataContractSource {
160                id_bytes: withdrawals_contract::ID_BYTES,
161                owner_id_bytes: withdrawals_contract::OWNER_ID_BYTES,
162                version: platform_version.system_data_contracts.withdrawals as u32,
163                definitions: withdrawals_contract::load_definitions(platform_version)?,
164                document_schemas: withdrawals_contract::load_documents_schemas(platform_version)?,
165            }),
166            #[cfg(not(feature = "withdrawals"))]
167            SystemDataContract::Withdrawals => Err(Error::ContractNotIncluded("withdrawals")),
168
169            #[cfg(feature = "masternode-rewards")]
170            SystemDataContract::MasternodeRewards => Ok(DataContractSource {
171                id_bytes: masternode_reward_shares_contract::ID_BYTES,
172                owner_id_bytes: masternode_reward_shares_contract::OWNER_ID_BYTES,
173                version: platform_version
174                    .system_data_contracts
175                    .masternode_reward_shares as u32,
176                definitions: masternode_reward_shares_contract::load_definitions(platform_version)?,
177                document_schemas: masternode_reward_shares_contract::load_documents_schemas(
178                    platform_version,
179                )?,
180            }),
181            #[cfg(not(feature = "masternode-rewards"))]
182            SystemDataContract::MasternodeRewards => {
183                Err(Error::ContractNotIncluded("masternode-rewards"))
184            }
185
186            // Reserved: feature-flags contract was removed. The variant exists only
187            // to preserve discriminant stability; loading it is not supported.
188            SystemDataContract::FeatureFlags => Err(Error::ContractReserved("feature-flags")),
189
190            #[cfg(feature = "dpns")]
191            SystemDataContract::DPNS => Ok(DataContractSource {
192                id_bytes: dpns_contract::ID_BYTES,
193                owner_id_bytes: dpns_contract::OWNER_ID_BYTES,
194                version: platform_version.system_data_contracts.dpns as u32,
195                definitions: dpns_contract::load_definitions(platform_version)?,
196                document_schemas: dpns_contract::load_documents_schemas(platform_version)?,
197            }),
198            #[cfg(not(feature = "dpns"))]
199            SystemDataContract::DPNS => Err(Error::ContractNotIncluded("dpns")),
200
201            #[cfg(feature = "dashpay")]
202            SystemDataContract::Dashpay => Ok(DataContractSource {
203                id_bytes: dashpay_contract::ID_BYTES,
204                owner_id_bytes: dashpay_contract::OWNER_ID_BYTES,
205                version: platform_version.system_data_contracts.dashpay as u32,
206                definitions: dashpay_contract::load_definitions(platform_version)?,
207                document_schemas: dashpay_contract::load_documents_schemas(platform_version)?,
208            }),
209            #[cfg(not(feature = "dashpay"))]
210            SystemDataContract::Dashpay => Err(Error::ContractNotIncluded("dashpay")),
211
212            #[cfg(feature = "wallet-utils")]
213            SystemDataContract::WalletUtils => Ok(DataContractSource {
214                id_bytes: wallet_utils_contract::ID_BYTES,
215                owner_id_bytes: wallet_utils_contract::OWNER_ID_BYTES,
216                version: platform_version.system_data_contracts.wallet as u32,
217                definitions: wallet_utils_contract::load_definitions(platform_version)?,
218                document_schemas: wallet_utils_contract::load_documents_schemas(platform_version)?,
219            }),
220            #[cfg(not(feature = "wallet-utils"))]
221            SystemDataContract::WalletUtils => Err(Error::ContractNotIncluded("wallet-utils")),
222
223            #[cfg(feature = "token-history")]
224            SystemDataContract::TokenHistory => Ok(DataContractSource {
225                id_bytes: token_history_contract::ID_BYTES,
226                owner_id_bytes: token_history_contract::OWNER_ID_BYTES,
227                version: platform_version.system_data_contracts.token_history as u32,
228                definitions: token_history_contract::load_definitions(platform_version)?,
229                document_schemas: token_history_contract::load_documents_schemas(platform_version)?,
230            }),
231            #[cfg(not(feature = "token-history"))]
232            SystemDataContract::TokenHistory => Err(Error::ContractNotIncluded("token-history")),
233
234            #[cfg(feature = "keyword-search")]
235            SystemDataContract::KeywordSearch => Ok(DataContractSource {
236                id_bytes: keyword_search_contract::ID_BYTES,
237                owner_id_bytes: keyword_search_contract::OWNER_ID_BYTES,
238                version: platform_version.system_data_contracts.keyword_search as u32,
239                definitions: keyword_search_contract::load_definitions(platform_version)?,
240                document_schemas: keyword_search_contract::load_documents_schemas(
241                    platform_version,
242                )?,
243            }),
244            #[cfg(not(feature = "keyword-search"))]
245            SystemDataContract::KeywordSearch => Err(Error::ContractNotIncluded("keyword-search")),
246
247            #[cfg(feature = "document-history")]
248            SystemDataContract::DocumentHistory => Ok(DataContractSource {
249                id_bytes: document_history_contract::ID_BYTES,
250                owner_id_bytes: document_history_contract::OWNER_ID_BYTES,
251                version: platform_version.system_data_contracts.document_history as u32,
252                definitions: document_history_contract::load_definitions(platform_version)?,
253                document_schemas: document_history_contract::load_documents_schemas(
254                    platform_version,
255                )?,
256            }),
257            #[cfg(not(feature = "document-history"))]
258            SystemDataContract::DocumentHistory => {
259                Err(Error::ContractNotIncluded("document-history"))
260            }
261        }
262    }
263}