Skip to main content

dpp/data_contract/factory/
mod.rs

1mod v0;
2
3use crate::data_contract::created_data_contract::CreatedDataContract;
4use crate::data_contract::DataContract;
5
6use crate::version::PlatformVersion;
7use crate::ProtocolError;
8use derive_more::From;
9use platform_value::{Identifier, Value};
10
11use crate::data_contract::config::DataContractConfig;
12use crate::prelude::IdentityNonce;
13#[cfg(all(feature = "state-transitions", feature = "client"))]
14use crate::state_transition::data_contract_create_transition::DataContractCreateTransition;
15#[cfg(all(feature = "state-transitions", feature = "client"))]
16use crate::state_transition::data_contract_update_transition::DataContractUpdateTransition;
17pub use v0::DataContractFactoryV0;
18
19/// # Data Contract Factory
20///
21/// This module is responsible for creating instances of data contracts.
22///
23/// ## Versioning
24///
25/// The factory is versioned because the process of creating data contracts
26/// can change over time. Changes may be due to modifications in contract
27/// requirements, alterations in the contract structure, or evolution in the
28/// dependencies of the contract. Versioning allows for these changes to be
29/// tracked and managed effectively, providing flexibility to handle different
30/// versions of data contracts as needed.
31#[derive(From)]
32pub enum DataContractFactory {
33    /// The version 0 implementation of the data contract factory.
34    V0(DataContractFactoryV0),
35}
36
37impl DataContractFactory {
38    /// Create a new data contract factory knowing versions
39    pub fn new(protocol_version: u32) -> Result<Self, ProtocolError> {
40        let platform_version = PlatformVersion::get(protocol_version)?;
41        match platform_version
42            .dpp
43            .factory_versions
44            .data_contract_factory_structure_version
45        {
46            0 => Ok(DataContractFactoryV0::new(protocol_version).into()),
47            version => Err(ProtocolError::UnknownVersionMismatch {
48                method: "DataContractFactory::new".to_string(),
49                known_versions: vec![0],
50                received: version,
51            }),
52        }
53    }
54
55    /// Create a DataContract using a
56    pub fn create_with_value_config(
57        &self,
58        owner_id: Identifier,
59        identity_nonce: IdentityNonce,
60        documents: Value,
61        config: Option<Value>,
62        definitions: Option<Value>,
63    ) -> Result<CreatedDataContract, ProtocolError> {
64        match self {
65            DataContractFactory::V0(v0) => v0.create_with_value_config(
66                owner_id,
67                identity_nonce,
68                documents,
69                config,
70                definitions,
71            ),
72        }
73    }
74
75    /// Create a DataContract
76    pub fn create(
77        &self,
78        owner_id: Identifier,
79        identity_nonce: IdentityNonce,
80        documents: Value,
81        config: Option<DataContractConfig>,
82        definitions: Option<Value>,
83    ) -> Result<CreatedDataContract, ProtocolError> {
84        match self {
85            DataContractFactory::V0(v0) => {
86                v0.create(owner_id, identity_nonce, documents, config, definitions)
87            }
88        }
89    }
90
91    /// Create a DataContract under a given id instead of the one derived from the owner and
92    /// the nonce, for the system contracts whose ids are published constants.
93    pub fn create_with_id(
94        &self,
95        data_contract_id: Identifier,
96        owner_id: Identifier,
97        identity_nonce: IdentityNonce,
98        documents: Value,
99        config: Option<DataContractConfig>,
100        definitions: Option<Value>,
101    ) -> Result<CreatedDataContract, ProtocolError> {
102        match self {
103            DataContractFactory::V0(v0) => v0.create_with_id(
104                data_contract_id,
105                owner_id,
106                identity_nonce,
107                documents,
108                config,
109                definitions,
110            ),
111        }
112    }
113
114    #[cfg(feature = "value-conversion")]
115    /// Create a DataContract from a plain object
116    pub fn create_from_object(
117        &self,
118        data_contract_object: Value,
119        #[cfg(feature = "validation")] skip_validation: bool,
120    ) -> Result<DataContract, ProtocolError> {
121        match self {
122            DataContractFactory::V0(v0) => {
123                #[cfg(feature = "validation")]
124                {
125                    v0.create_from_object(data_contract_object, skip_validation)
126                }
127                #[cfg(not(feature = "validation"))]
128                {
129                    v0.create_from_object(data_contract_object, true)
130                }
131            }
132        }
133    }
134
135    /// Create a DataContract from a buffer
136    pub fn create_from_buffer(
137        &self,
138        buffer: Vec<u8>,
139        #[cfg(feature = "validation")] skip_validation: bool,
140    ) -> Result<DataContract, ProtocolError> {
141        match self {
142            DataContractFactory::V0(v0) => {
143                #[cfg(feature = "validation")]
144                {
145                    v0.create_from_buffer(buffer, skip_validation)
146                }
147                #[cfg(not(feature = "validation"))]
148                {
149                    v0.create_from_buffer(buffer)
150                }
151            }
152        }
153    }
154
155    #[cfg(all(feature = "state-transitions", feature = "client"))]
156    /// Create a DataContractCreateTransition
157    pub fn create_data_contract_create_transition(
158        &self,
159        created_data_contract: CreatedDataContract,
160    ) -> Result<DataContractCreateTransition, ProtocolError> {
161        match self {
162            DataContractFactory::V0(v0) => {
163                v0.create_unsigned_data_contract_create_transition(created_data_contract)
164            }
165        }
166    }
167
168    #[cfg(all(feature = "state-transitions", feature = "client"))]
169    /// Create a DataContractUpdateTransition
170    pub fn create_data_contract_update_transition(
171        &self,
172        data_contract: DataContract,
173        identity_contract_nonce: IdentityNonce,
174    ) -> Result<DataContractUpdateTransition, ProtocolError> {
175        match self {
176            DataContractFactory::V0(v0) => v0.create_unsigned_data_contract_update_transition(
177                data_contract,
178                identity_contract_nonce,
179            ),
180        }
181    }
182}