Skip to content

Commit 8a83981

Browse files
shumkovQuantumExplorerclaude
authored
feat(platform): document count index (#2516)
Co-authored-by: Quantum Explorer <quantum@dash.org> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 40f1e8b commit 8a83981

11 files changed

Lines changed: 566 additions & 5 deletions

File tree

packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,10 @@
426426
"resolution"
427427
],
428428
"additionalProperties": false
429+
},
430+
"countable": {
431+
"type": "boolean",
432+
"description": "Enables countable operations on the index. Adds extra costs for documents storage"
429433
}
430434
},
431435
"required": [

packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ use crate::consensus::basic::document::MissingPositionsInDocumentTypePropertiesE
3838
use crate::consensus::basic::token::InvalidTokenPositionError;
3939
#[cfg(feature = "validation")]
4040
use crate::consensus::basic::BasicError;
41+
#[cfg(feature = "validation")]
42+
use crate::consensus::basic::UnsupportedFeatureError;
4143
use crate::data_contract::config::v0::DataContractConfigGettersV0;
4244
use crate::data_contract::config::DataContractConfig;
4345
use crate::data_contract::document_type::class_methods::try_from_schema::{
@@ -319,6 +321,17 @@ impl DocumentTypeV1 {
319321

320322
#[cfg(feature = "validation")]
321323
if full_validation {
324+
// Countable indices are only supported starting from protocol version 12
325+
if index.countable && platform_version.protocol_version < 12 {
326+
return Err(ProtocolError::ConsensusError(Box::new(
327+
UnsupportedFeatureError::new(
328+
"count index".to_string(),
329+
platform_version.protocol_version,
330+
)
331+
.into(),
332+
)));
333+
}
334+
322335
validation_operations.extend(std::iter::once(
323336
ProtocolValidationOperation::DocumentTypeSchemaIndexValidation(
324337
index.properties.len() as u64,

packages/rs-dpp/src/data_contract/document_type/index/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ pub struct Index {
295295
pub null_searchable: bool,
296296
/// Contested indexes are useful when a resource is considered valuable
297297
pub contested_index: Option<ContestedIndexInformation>,
298+
/// Enables countable operations on the index
299+
pub countable: bool,
298300
}
299301

300302
impl Index {
@@ -469,6 +471,7 @@ impl TryFrom<&[(Value, Value)]> for Index {
469471
let mut name = None;
470472
let mut contested_index = None;
471473
let mut index_properties: Vec<IndexProperty> = Vec::new();
474+
let mut countable = false;
472475

473476
for (key_value, value_value) in index_type_value_map {
474477
let key = key_value.to_str()?;
@@ -585,6 +588,13 @@ impl TryFrom<&[(Value, Value)]> for Index {
585588
}
586589
contested_index = Some(contested_index_information);
587590
}
591+
"countable" => {
592+
countable = value_value
593+
.as_bool()
594+
.ok_or(DataContractError::ValueWrongType(
595+
"countable value must be a boolean".to_string(),
596+
))?;
597+
}
588598
"properties" => {
589599
let properties =
590600
value_value
@@ -627,6 +637,7 @@ impl TryFrom<&[(Value, Value)]> for Index {
627637
unique,
628638
null_searchable,
629639
contested_index,
640+
countable,
630641
})
631642
}
632643
}
@@ -680,6 +691,7 @@ mod tests {
680691
unique,
681692
null_searchable: true,
682693
contested_index: None,
694+
countable: false,
683695
}
684696
}
685697

packages/rs-dpp/src/data_contract/document_type/index/random_index.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ impl Index {
6060
unique,
6161
null_searchable: true,
6262
contested_index: None,
63+
countable: false,
6364
})
6465
}
6566
}

0 commit comments

Comments
 (0)