dpp/data_contract/methods/validate_document/v0/
mod.rs1use crate::data_contract::accessors::v0::DataContractV0Getters;
2use crate::data_contract::document_type::accessors::DocumentTypeV0Getters;
3use crate::data_contract::document_type::DocumentType;
4
5use crate::consensus::basic::document::{
6 DocumentFieldMaxSizeExceededError, InvalidDocumentTypeError,
7};
8use crate::consensus::basic::BasicError;
9use crate::consensus::ConsensusError;
10use crate::data_contract::schema::DataContractSchemaMethodsV0;
11use crate::data_contract::DataContract;
12use crate::document::{Document, DocumentV0Getters};
13use crate::validation::SimpleConsensusValidationResult;
14use crate::ProtocolError;
15use platform_value::Value;
16use platform_version::version::PlatformVersion;
17use std::ops::Deref;
18
19pub trait DataContractDocumentValidationMethodsV0 {
20 fn validate_document(
21 &self,
22 name: &str,
23 document: &Document,
24 platform_version: &PlatformVersion,
25 ) -> Result<SimpleConsensusValidationResult, ProtocolError>;
26
27 fn validate_document_properties(
28 &self,
29 name: &str,
30 value: Value,
31 platform_version: &PlatformVersion,
32 ) -> Result<SimpleConsensusValidationResult, ProtocolError>;
33}
34
35impl DataContract {
36 #[inline(always)]
37 pub(super) fn validate_document_properties_v0(
38 &self,
39 name: &str,
40 value: Value,
41 platform_version: &PlatformVersion,
42 ) -> Result<SimpleConsensusValidationResult, ProtocolError> {
43 let Some(document_type) = self.document_type_optional_for_name(name) else {
44 return Ok(SimpleConsensusValidationResult::new_with_error(
45 InvalidDocumentTypeError::new(name.to_owned(), self.id()).into(),
46 ));
47 };
48
49 let validator = document_type.json_schema_validator_ref().deref();
50
51 if let Some((key, size)) =
52 value.has_data_larger_than(platform_version.system_limits.max_field_value_size)
53 {
54 let field = match key {
55 Some(Value::Text(field)) => field,
56 _ => "".to_string(),
57 };
58 return Ok(SimpleConsensusValidationResult::new_with_error(
59 ConsensusError::BasicError(BasicError::DocumentFieldMaxSizeExceededError(
60 DocumentFieldMaxSizeExceededError::new(
61 field,
62 size as u64,
63 platform_version.system_limits.max_field_value_size as u64,
64 ),
65 )),
66 ));
67 }
68
69 let json_value = match value.try_into_validating_json() {
70 Ok(json_value) => json_value,
71 Err(e) => {
72 return Ok(SimpleConsensusValidationResult::new_with_error(
73 ConsensusError::BasicError(BasicError::ValueError(e.into())),
74 ))
75 }
76 };
77
78 if !validator.is_compiled(platform_version)? {
80 let root_schema = DocumentType::enrich_with_base_schema(
83 document_type.schema().clone(),
86 self.schema_defs().map(|defs| Value::from(defs.clone())),
87 platform_version,
88 )?;
89
90 let root_json_schema = root_schema
91 .try_to_validating_json()
92 .map_err(ProtocolError::ValueError)?;
93
94 validator.compile_and_validate(&root_json_schema, &json_value, platform_version)
95 } else {
96 validator.validate(&json_value, platform_version)
97 }
98 }
99
100 #[inline(always)]
101 pub(super) fn validate_document_v0(
102 &self,
103 name: &str,
104 document: &Document,
105 platform_version: &PlatformVersion,
106 ) -> Result<SimpleConsensusValidationResult, ProtocolError> {
107 self.validate_document_properties_v0(name, document.properties().into(), platform_version)
109 }
110}